Merge "Update constructor of NetworkMonitor"
diff --git a/Android.bp b/Android.bp
index 75274eb..c9ae9ba 100644
--- a/Android.bp
+++ b/Android.bp
@@ -294,6 +294,17 @@
     ]
 }
 
+java_library {
+    name: "framework-updatable-stubs-module_libs_api",
+    static_libs: [
+        "framework-sdkextensions-stubs-module_libs_api",
+        "framework-tethering-stubs-module_libs_api",
+        "updatable_media_stubs",
+    ],
+    sdk_version: "module_current",
+    visibility: [":__pkg__"],
+}
+
 filegroup {
     name: "framework-all-sources",
     srcs: [
@@ -324,9 +335,11 @@
             "rs/java",
             "sax/java",
             "telecomm/java",
-            "telephony/java",
             "wifi/java",
             "wifi/aidl-export",
+
+            // TODO(b/147699819): remove this
+            "telephony/java",
         ],
     },
 }
@@ -396,7 +409,6 @@
         "app-compat-annotations",
         "ext",
         "unsupportedappusage",
-        "updatable_media_stubs",
     ],
 
     jarjar_rules: ":framework-jarjar-rules",
@@ -455,9 +467,6 @@
     name: "framework-minus-apex",
     defaults: ["framework-defaults"],
     srcs: [":framework-non-updatable-sources"],
-    libs: [
-        "framework-tethering-stubs",
-    ],
     installable: true,
     javac_shard_size: 150,
     required: [
@@ -465,6 +474,7 @@
         "libcore-platform-compat-config",
         "services-platform-compat-config",
     ],
+    libs: ["framework-updatable-stubs-module_libs_api"],
     static_libs: [
         // If MimeMap ever becomes its own APEX, then this dependency would need to be removed
         // in favor of an API stubs dependency in java_library "framework" below.
@@ -494,9 +504,7 @@
     installable: false, // this lib is a build-only library
     static_libs: [
         "framework-minus-apex",
-        "updatable_media_stubs",
-        "framework-sdkextensions-stubs-systemapi",
-        "framework-tethering-stubs",
+        "framework-updatable-stubs-module_libs_api",
     ],
     sdk_version: "core_platform",
     apex_available: ["//apex_available:platform"],
@@ -511,48 +519,14 @@
     visibility: [
         // DO NOT ADD ANY MORE ENTRIES TO THIS LIST
         "//external/robolectric-shadows:__subpackages__",
-        "//frameworks/base/packages/Tethering/common/TetheringLib:__subpackages__",
+        "//frameworks/base",
         "//frameworks/layoutlib:__subpackages__",
-        "//frameworks/opt/net/ike:__subpackages__",
-    ],
-}
-
-java_library {
-    name: "framework-annotation-proc",
-    defaults: ["framework-defaults"],
-    srcs: [":framework-all-sources"],
-    libs: [
-        "app-compat-annotations",
-        "unsupportedappusage",
-    ],
-    installable: false,
-    plugins: [
-        "compat-changeid-annotation-processor",
     ],
 }
 
 platform_compat_config {
-    name: "framework-platform-compat-config",
-    src: ":framework-annotation-proc",
-}
-
-// A library including just UnsupportedAppUsage.java classes.
-//
-// Provided for target so that libraries can use it without depending on
-// the whole of framework or the core platform API.
-//
-// Built for host so that the annotation processor can also use this annotation.
-java_library {
-    name: "unsupportedappusage-annotation",
-    host_supported: true,
-    srcs: [
-        "core/java/android/annotation/IntDef.java",
-    ],
-    static_libs: [
-        "art.module.api.annotations",
-    ],
-
-    sdk_version: "core_current",
+   name: "framework-platform-compat-config",
+   src: ":framework-minus-apex",
 }
 
 // A temporary build target that is conditionally included on the bootclasspath if
@@ -614,6 +588,7 @@
 filegroup {
     name: "framework-annotations",
     srcs: [
+        "core/java/android/annotation/Hide.java",
         "core/java/android/annotation/NonNull.java",
         "core/java/android/annotation/Nullable.java",
         "core/java/android/annotation/IntDef.java",
@@ -638,6 +613,7 @@
     srcs: [
         "core/java/android/annotation/StringDef.java",
         "core/java/android/net/annotations/PolicyDirection.java",
+        "core/java/com/android/internal/util/HexDump.java",
         "core/java/com/android/internal/util/IState.java",
         "core/java/com/android/internal/util/State.java",
         "core/java/com/android/internal/util/StateMachine.java",
@@ -667,6 +643,18 @@
     ],
 }
 
+filegroup {
+    name: "framework-services-net-module-wifi-shared-srcs",
+    srcs: [
+        "core/java/android/net/DhcpResults.java",
+        "core/java/android/net/shared/Inet4AddressUtils.java",
+        "core/java/android/net/shared/InetAddressUtils.java",
+        "core/java/android/net/util/IpUtils.java",
+        "core/java/android/util/LocalLog.java",
+        "core/java/com/android/internal/util/Preconditions.java",
+    ],
+}
+
 // keep these files in sync with the package/Tethering/jarjar-rules.txt for the tethering module.
 filegroup {
     name: "framework-tethering-shared-srcs",
@@ -1001,16 +989,6 @@
     output: "framework-aidl-mappings.txt",
 }
 
-genrule {
-    name: "framework-annotation-proc-index",
-    srcs: [":framework-annotation-proc"],
-    cmd: "unzip -qp $(in) unsupportedappusage/unsupportedappusage_index.csv > $(out)",
-    out: ["unsupportedappusage_index.csv"],
-    dist: {
-        targets: ["droidcore"],
-    },
-}
-
 filegroup {
     name: "framework-cellbroadcast-shared-srcs",
     srcs: [
diff --git a/Android.mk b/Android.mk
index 09f2c40..aea0c95 100644
--- a/Android.mk
+++ b/Android.mk
@@ -42,6 +42,8 @@
 $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_API_FILE):apistubs/android/public/api/android.txt)
 $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_SYSTEM_API_FILE):apistubs/android/system/api/android.txt)
 $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_TEST_API_FILE):apistubs/android/test/api/android.txt)
+$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_MODULE_LIB_API_FILE):apistubs/android/module-lib/api/android.txt)
+$(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_SYSTEM_SERVER_API_FILE):apistubs/android/system-server/api/android.txt)
 
 # 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
diff --git a/ApiDocs.bp b/ApiDocs.bp
index b7e3646..7fd1168 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -65,8 +65,9 @@
         "test-base/src/**/*.java",
         ":opt-telephony-srcs",
         ":opt-net-voip-srcs",
-        ":core-current-stubs-source",
-        ":core_public_api_files",
+        ":art-module-public-api-stubs-source",
+        ":conscrypt-module-public-api-stubs-source",
+        ":android_icu4j_public_api_files",
         "test-mock/src/**/*.java",
         "test-runner/src/**/*.java",
     ],
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 84b3625..f081071 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -41,14 +41,15 @@
 ]
 
 stubs_defaults {
-    name: "metalava-non-updatable-api-stubs-default",
+    name: "metalava-base-api-stubs-default",
     srcs: [
         ":framework-non-updatable-sources",
         "core/java/**/*.logtags",
         ":opt-telephony-srcs",
         ":opt-net-voip-srcs",
-        ":core-current-stubs-source",
-        ":core_public_api_files",
+        ":art-module-public-api-stubs-source",
+        ":conscrypt-module-public-api-stubs-source",
+        ":android_icu4j_public_api_files",
     ],
     libs: ["framework-internal-utils"],
     installable: false,
@@ -57,21 +58,24 @@
     merge_annotations_dirs: [
         "metalava-manual",
     ],
-    api_levels_annotations_enabled: true,
-    api_levels_annotations_dirs: [
-        "sdk-dir",
-        "api-versions-jars-dir",
-    ],
+    api_levels_annotations_enabled: false,
     filter_packages: packages_to_document,
 }
 
 stubs_defaults {
-    name: "metalava-api-stubs-default",
-    defaults: ["metalava-non-updatable-api-stubs-default"],
+    name: "metalava-full-api-stubs-default",
+    defaults: ["metalava-base-api-stubs-default"],
     srcs: [":framework-updatable-sources"],
     sdk_version: "core_platform",
 }
 
+stubs_defaults {
+    name: "metalava-non-updatable-api-stubs-default",
+    defaults: ["metalava-base-api-stubs-default"],
+    sdk_version: "core_platform",
+    libs: ["framework-all"],
+}
+
 /////////////////////////////////////////////////////////////////////
 // *-api-stubs-docs modules providing source files for the stub libraries
 /////////////////////////////////////////////////////////////////////
@@ -81,7 +85,7 @@
 // modules
 droidstubs {
     name: "api-stubs-docs",
-    defaults: ["metalava-api-stubs-default"],
+    defaults: ["metalava-full-api-stubs-default"],
     api_filename: "public_api.txt",
     private_api_filename: "private.txt",
     removed_api_filename: "removed.txt",
@@ -120,11 +124,10 @@
 
 droidstubs {
     name: "system-api-stubs-docs",
-    defaults: ["metalava-api-stubs-default"],
+    defaults: ["metalava-full-api-stubs-default"],
     api_tag_name: "SYSTEM",
     api_filename: "system-api.txt",
     private_api_filename: "system-private.txt",
-    private_dex_api_filename: "system-private-dex.txt",
     removed_api_filename: "system-removed.txt",
     arg_files: [
         "core/res/AndroidManifest.xml",
@@ -151,7 +154,7 @@
 
 droidstubs {
     name: "test-api-stubs-docs",
-    defaults: ["metalava-api-stubs-default"],
+    defaults: ["metalava-full-api-stubs-default"],
     api_tag_name: "TEST",
     api_filename: "test-api.txt",
     removed_api_filename: "test-removed.txt",
@@ -184,7 +187,8 @@
 
 droidstubs {
     name: "module-lib-api",
-    defaults: ["metalava-api-stubs-default"],
+    defaults: ["metalava-full-api-stubs-default"],
+    api_tag_name: "MODULE_LIB",
     arg_files: ["core/res/AndroidManifest.xml"],
     args: metalava_framework_docs_args + module_libs,
     check_api: {
@@ -212,7 +216,7 @@
 
 droidstubs {
     name: "module-lib-api-stubs-docs",
-    defaults: ["metalava-api-stubs-default"],
+    defaults: ["metalava-non-updatable-api-stubs-default"],
     arg_files: ["core/res/AndroidManifest.xml"],
     args: metalava_framework_docs_args + priv_apps + module_libs,
 }
@@ -225,16 +229,18 @@
 java_defaults {
     name: "framework-stubs-default",
     libs: [ "stub-annotations" ],
-    static_libs: [ "private-stub-annotations-jar" ],
+    static_libs: [
+        "private-stub-annotations-jar",
+
+        // License notices from art module
+        "art-notices-for-framework-stubs-jar",
+    ],
     sdk_version: "core_current",
     errorprone: {
         javacflags: [
             "-XepDisableAllChecks",
         ],
     },
-    java_resources: [
-        ":notices-for-framework-stubs",
-    ],
     system_modules: "none",
     java_version: "1.8",
     compile_dex: true,
@@ -262,6 +268,7 @@
     name: "android_module_lib_stubs_current",
     srcs: [ ":module-lib-api-stubs-docs" ],
     defaults: ["framework-stubs-default"],
+    libs: ["android_system_stubs_current"],
 }
 
 /////////////////////////////////////////////////////////////////////
@@ -313,12 +320,10 @@
 
 droidstubs {
     name: "hiddenapi-lists-docs",
-    defaults: ["metalava-api-stubs-default"],
+    defaults: ["metalava-full-api-stubs-default"],
     arg_files: [
         "core/res/AndroidManifest.xml",
     ],
-    dex_api_filename: "public-dex.txt",
-    private_dex_api_filename: "private-dex.txt",
     removed_dex_api_filename: "removed-dex.txt",
     args: metalava_framework_docs_args +
         " --show-unannotated " +
@@ -328,7 +333,7 @@
 
 droidstubs {
     name: "hiddenapi-mappings",
-    defaults: ["metalava-api-stubs-default"],
+    defaults: ["metalava-full-api-stubs-default"],
     srcs: [
         ":opt-telephony-common-srcs",
     ],
diff --git a/apex/Android.bp b/apex/Android.bp
index 051986e..a6461f3 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -43,13 +43,45 @@
     name: "framework-module-stubs-defaults-publicapi",
     args: mainline_stubs_args,
     installable: false,
+    sdk_version: "current",
+    check_api: {
+        current: {
+            api_file: "api/current.txt",
+            removed_api_file: "api/removed.txt",
+        },
+    },
 }
 
 stubs_defaults {
     name: "framework-module-stubs-defaults-systemapi",
     args: mainline_stubs_args + priv_apps,
-    srcs: [":framework-annotations"],
+    libs: ["framework-annotations-lib"],
     installable: false,
+    sdk_version: "system_current",
+    check_api: {
+        current: {
+            api_file: "api/system-current.txt",
+            removed_api_file: "api/system-removed.txt",
+        },
+    },
+}
+
+java_defaults {
+    name: "framework-module-stubs-lib-defaults-publicapi",
+    installable: false,
+    sdk_version: "module_current",
+}
+
+java_defaults {
+    name: "framework-module-stubs-lib-defaults-systemapi",
+    installable: false,
+    sdk_version: "module_current",
+}
+
+java_defaults {
+    name: "framework-module-stubs-lib-defaults-module_libs_api",
+    installable: false,
+    sdk_version: "module_current",
 }
 
 // The defaults for module_libs comes in two parts - defaults for API checks
@@ -60,13 +92,21 @@
 stubs_defaults {
     name: "framework-module-api-defaults-module_libs_api",
     args: mainline_stubs_args + module_libs,
-    srcs: [":framework-annotations"],
+    libs: ["framework-annotations-lib"],
     installable: false,
+    sdk_version: "module_current",
+    check_api: {
+        current: {
+            api_file: "api/module-lib-current.txt",
+            removed_api_file: "api/module-lib-removed.txt",
+        },
+    },
 }
 
 stubs_defaults {
     name: "framework-module-stubs-defaults-module_libs_api",
     args: mainline_stubs_args + module_libs + priv_apps,
-    srcs: [":framework-annotations"],
+    libs: ["framework-annotations-lib"],
     installable: false,
+    sdk_version: "module_current",
 }
diff --git a/apex/sdkextensions/framework/Android.bp b/apex/sdkextensions/framework/Android.bp
index 86f4ab7..707113b 100644
--- a/apex/sdkextensions/framework/Android.bp
+++ b/apex/sdkextensions/framework/Android.bp
@@ -86,7 +86,7 @@
 java_library {
     name: "framework-sdkextensions-stubs-publicapi",
     srcs: [":framework-sdkextensions-stubs-srcs-publicapi"],
-    sdk_version: "current",
+    defaults: ["framework-module-stubs-lib-defaults-publicapi"],
     visibility: [
         "//frameworks/base", // Framework
         "//frameworks/base/apex/sdkextensions", // sdkextensions SDK
@@ -96,7 +96,7 @@
 java_library {
     name: "framework-sdkextensions-stubs-systemapi",
     srcs: [":framework-sdkextensions-stubs-srcs-systemapi"],
-    sdk_version: "system_current",
+    defaults: ["framework-module-stubs-lib-defaults-systemapi"],
     visibility: [
         "//frameworks/base", // Framework
         "//frameworks/base/apex/sdkextensions", // sdkextensions SDK
@@ -106,7 +106,7 @@
 java_library {
     name: "framework-sdkextensions-stubs-module_libs_api",
     srcs: [":framework-sdkextensions-stubs-srcs-module_libs_api"],
-    sdk_version: "system_current",
+    defaults: ["framework-module-stubs-lib-defaults-module_libs_api"],
     visibility: [
         "//frameworks/base", // Framework
         "//frameworks/base/apex/sdkextensions", // sdkextensions SDK
diff --git a/apex/sdkextensions/framework/api/current.txt b/apex/sdkextensions/framework/api/current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/sdkextensions/framework/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/sdkextensions/framework/api/module-lib-current.txt b/apex/sdkextensions/framework/api/module-lib-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/sdkextensions/framework/api/module-lib-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/sdkextensions/framework/api/module-lib-removed.txt b/apex/sdkextensions/framework/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/sdkextensions/framework/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/sdkextensions/framework/api/removed.txt b/apex/sdkextensions/framework/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/sdkextensions/framework/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/sdkextensions/framework/api/system-current.txt b/apex/sdkextensions/framework/api/system-current.txt
new file mode 100644
index 0000000..bbff4c5
--- /dev/null
+++ b/apex/sdkextensions/framework/api/system-current.txt
@@ -0,0 +1,9 @@
+// Signature format: 2.0
+package android.os.ext {
+
+  public class SdkExtensions {
+    method public static int getExtensionVersion(int);
+  }
+
+}
+
diff --git a/apex/sdkextensions/framework/api/system-removed.txt b/apex/sdkextensions/framework/api/system-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/apex/sdkextensions/framework/api/system-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/api/current.txt b/api/current.txt
index 0f37db2..a5b88b3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11405,7 +11405,8 @@
   public class PackageInstaller {
     method public void abandonSession(int);
     method public int createSession(@NonNull android.content.pm.PackageInstaller.SessionParams) throws java.io.IOException;
-    method @Nullable public android.content.pm.PackageInstaller.SessionInfo getActiveStagedSession();
+    method @Deprecated @Nullable public android.content.pm.PackageInstaller.SessionInfo getActiveStagedSession();
+    method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getActiveStagedSessions();
     method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getAllSessions();
     method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getMySessions();
     method @Nullable public android.content.pm.PackageInstaller.SessionInfo getSessionInfo(int);
@@ -11490,11 +11491,13 @@
     method @NonNull public String getStagedSessionErrorMessage();
     method public long getUpdatedMillis();
     method @NonNull public android.os.UserHandle getUser();
+    method public boolean hasParentSessionId();
     method public boolean isActive();
     method public boolean isCommitted();
     method public boolean isMultiPackage();
     method public boolean isSealed();
     method public boolean isStaged();
+    method public boolean isStagedSessionActive();
     method public boolean isStagedSessionApplied();
     method public boolean isStagedSessionFailed();
     method public boolean isStagedSessionReady();
@@ -19555,8 +19558,7 @@
     method public T numberFormatterSecond(android.icu.number.UnlocalizedNumberFormatter);
   }
 
-  public abstract class Precision implements java.lang.Cloneable {
-    method public Object clone();
+  public abstract class Precision {
     method public static android.icu.number.CurrencyPrecision currency(android.icu.util.Currency.CurrencyUsage);
     method public static android.icu.number.FractionPrecision fixedFraction(int);
     method public static android.icu.number.Precision fixedSignificantDigits(int);
@@ -19579,8 +19581,7 @@
     method public static android.icu.number.Scale powerOfTen(int);
   }
 
-  public class ScientificNotation extends android.icu.number.Notation implements java.lang.Cloneable {
-    method public Object clone();
+  public class ScientificNotation extends android.icu.number.Notation {
     method public android.icu.number.ScientificNotation withExponentSignDisplay(android.icu.number.NumberFormatter.SignDisplay);
     method public android.icu.number.ScientificNotation withMinExponentDigits(int);
   }
@@ -28708,7 +28709,7 @@
 
   public abstract static class ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback {
     ctor public ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback();
-    method public void onConnectivityReport(@NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityReport);
+    method public void onConnectivityReportAvailable(@NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityReport);
     method public void onDataStallSuspected(@NonNull android.net.ConnectivityDiagnosticsManager.DataStallReport);
     method public void onNetworkConnectivityReported(@NonNull android.net.Network, boolean);
   }
@@ -29145,9 +29146,6 @@
   public final class NetworkCapabilities implements android.os.Parcelable {
     ctor public NetworkCapabilities();
     ctor public NetworkCapabilities(android.net.NetworkCapabilities);
-    method @NonNull public android.net.NetworkCapabilities addCapability(int);
-    method @NonNull public android.net.NetworkCapabilities addTransportType(int);
-    method public void clearAll();
     method public int describeContents();
     method public int getLinkDownstreamBandwidthKbps();
     method public int getLinkUpstreamBandwidthKbps();
@@ -29157,13 +29155,6 @@
     method @Nullable public android.net.TransportInfo getTransportInfo();
     method public boolean hasCapability(int);
     method public boolean hasTransport(int);
-    method @NonNull public android.net.NetworkCapabilities removeCapability(int);
-    method @NonNull public android.net.NetworkCapabilities setCapability(int, boolean);
-    method @NonNull public android.net.NetworkCapabilities setLinkDownstreamBandwidthKbps(int);
-    method @NonNull public android.net.NetworkCapabilities setLinkUpstreamBandwidthKbps(int);
-    method @NonNull public android.net.NetworkCapabilities setNetworkSpecifier(@NonNull android.net.NetworkSpecifier);
-    method @NonNull public android.net.NetworkCapabilities setOwnerUid(int);
-    method @NonNull public android.net.NetworkCapabilities setSignalStrength(int);
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkCapabilities> CREATOR;
     field public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; // 0x11
@@ -44682,6 +44673,38 @@
     field public static final int PRIORITY_MED = 2; // 0x2
   }
 
+  public final class BarringInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.telephony.BarringInfo.BarringServiceInfo getBarringServiceInfo(int);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int BARRING_SERVICE_TYPE_CS_FALLBACK = 5; // 0x5
+    field public static final int BARRING_SERVICE_TYPE_CS_SERVICE = 0; // 0x0
+    field public static final int BARRING_SERVICE_TYPE_CS_VOICE = 2; // 0x2
+    field public static final int BARRING_SERVICE_TYPE_EMERGENCY = 8; // 0x8
+    field public static final int BARRING_SERVICE_TYPE_MMTEL_VIDEO = 7; // 0x7
+    field public static final int BARRING_SERVICE_TYPE_MMTEL_VOICE = 6; // 0x6
+    field public static final int BARRING_SERVICE_TYPE_MO_DATA = 4; // 0x4
+    field public static final int BARRING_SERVICE_TYPE_MO_SIGNALLING = 3; // 0x3
+    field public static final int BARRING_SERVICE_TYPE_PS_SERVICE = 1; // 0x1
+    field public static final int BARRING_SERVICE_TYPE_SMS = 9; // 0x9
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.BarringInfo> CREATOR;
+  }
+
+  public static final class BarringInfo.BarringServiceInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getBarringType();
+    method public int getConditionalBarringFactor();
+    method public int getConditionalBarringTimeSeconds();
+    method public boolean isBarred();
+    method public boolean isConditionallyBarred();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int BARRING_TYPE_CONDITIONAL = 1; // 0x1
+    field public static final int BARRING_TYPE_NONE = 0; // 0x0
+    field public static final int BARRING_TYPE_UNCONDITIONAL = 2; // 0x2
+    field public static final int BARRING_TYPE_UNKNOWN = -1; // 0xffffffff
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.BarringInfo.BarringServiceInfo> CREATOR;
+  }
+
   public class CarrierConfigManager {
     method @Nullable public android.os.PersistableBundle getConfig();
     method @Nullable public android.os.PersistableBundle getConfigByComponentForSubId(@NonNull String, int);
@@ -44694,12 +44717,9 @@
     field public static final String EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX";
     field public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX";
     field public static final String IMSI_KEY_AVAILABILITY_INT = "imsi_key_availability_int";
-    field public static final String KEY_5G_ICON_CONFIGURATION_STRING = "5g_icon_configuration_string";
-    field public static final String KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT = "5g_icon_display_grace_period_sec_int";
     field public static final String KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrp_thresholds_int_array";
     field public static final String KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrq_thresholds_int_array";
     field public static final String KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY = "5g_nr_sssinr_thresholds_int_array";
-    field public static final String KEY_5G_WATCHDOG_TIME_MS_LONG = "5g_watchdog_time_long";
     field public static final String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
     field public static final String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
     field public static final String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL = "allow_add_call_during_video_call";
@@ -44892,7 +44912,6 @@
     field public static final String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
     field public static final String KEY_SHOW_BLOCKING_PAY_PHONE_OPTION_BOOL = "show_blocking_pay_phone_option_bool";
     field public static final String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL = "show_call_blocking_disabled_notification_always_bool";
-    field public static final String KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING = "show_carrier_data_icon_pattern_string";
     field public static final String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
     field public static final String KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL = "show_iccid_in_sim_status_bool";
     field public static final String KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL = "show_ims_registration_status_bool";
@@ -44967,7 +44986,7 @@
   }
 
   public final class CellIdentityGsm extends android.telephony.CellIdentity {
-    method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns();
+    method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns();
     method public int getArfcn();
     method public int getBsic();
     method public int getCid();
@@ -44983,8 +45002,8 @@
   }
 
   public final class CellIdentityLte extends android.telephony.CellIdentity {
-    method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns();
-    method @NonNull public java.util.List<java.lang.Integer> getBands();
+    method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns();
+    method @NonNull public int[] getBands();
     method public int getBandwidth();
     method public int getCi();
     method @Nullable public android.telephony.ClosedSubscriberGroupInfo getClosedSubscriberGroupInfo();
@@ -45001,8 +45020,8 @@
   }
 
   public final class CellIdentityNr extends android.telephony.CellIdentity {
-    method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns();
-    method @NonNull public java.util.List<java.lang.Integer> getBands();
+    method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns();
+    method @NonNull public int[] getBands();
     method @Nullable public String getMccString();
     method @Nullable public String getMncString();
     method public long getNci();
@@ -45014,7 +45033,7 @@
   }
 
   public final class CellIdentityTdscdma extends android.telephony.CellIdentity {
-    method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns();
+    method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns();
     method public int getCid();
     method @Nullable public android.telephony.ClosedSubscriberGroupInfo getClosedSubscriberGroupInfo();
     method public int getCpid();
@@ -45028,7 +45047,7 @@
   }
 
   public final class CellIdentityWcdma extends android.telephony.CellIdentity {
-    method @NonNull public java.util.List<java.lang.String> getAdditionalPlmns();
+    method @NonNull public java.util.Set<java.lang.String> getAdditionalPlmns();
     method public int getCid();
     method @Nullable public android.telephony.ClosedSubscriberGroupInfo getClosedSubscriberGroupInfo();
     method public int getLac();
@@ -45317,7 +45336,7 @@
     method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
     method @Nullable public android.telephony.CellIdentity getCellIdentity();
     method public int getDomain();
-    method public int getNrState();
+    method @Nullable public String getRegisteredPlmn();
     method public int getTransportType();
     method public boolean isRegistered();
     method public boolean isRoaming();
@@ -45444,6 +45463,7 @@
     ctor public PhoneStateListener();
     ctor public PhoneStateListener(@NonNull java.util.concurrent.Executor);
     method public void onActiveDataSubscriptionIdChanged(int);
+    method public void onBarringInfoChanged(@NonNull android.telephony.BarringInfo);
     method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onCallDisconnectCauseChanged(int, int);
     method public void onCallForwardingIndicatorChanged(boolean);
     method public void onCallStateChanged(int, String);
@@ -45462,6 +45482,7 @@
     method public void onSignalStrengthsChanged(android.telephony.SignalStrength);
     method public void onUserMobileDataStateChanged(boolean);
     field public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 4194304; // 0x400000
+    field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int LISTEN_BARRING_INFO = -2147483648; // 0x80000000
     field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_DISCONNECT_CAUSES = 33554432; // 0x2000000
     field public static final int LISTEN_CALL_FORWARDING_INDICATOR = 8; // 0x8
     field public static final int LISTEN_CALL_STATE = 32; // 0x20
@@ -45484,6 +45505,7 @@
 
   public final class PreciseDataConnectionState implements android.os.Parcelable {
     method public int describeContents();
+    method @Nullable public android.telephony.data.ApnSetting getApnSetting();
     method public int getLastCauseCode();
     method @Nullable public android.net.LinkProperties getLinkProperties();
     method public int getNetworkType();
@@ -45840,7 +45862,7 @@
     method public long getDataLimitBytes();
     method public long getDataUsageBytes();
     method public long getDataUsageTime();
-    method @Nullable public int[] getNetworkTypes();
+    method @NonNull public int[] getNetworkTypes();
     method @Nullable public CharSequence getSummary();
     method @Nullable public CharSequence getTitle();
     method public void writeToParcel(android.os.Parcel, int);
@@ -45860,7 +45882,7 @@
     method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period);
     method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
     method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
-    method @NonNull public android.telephony.SubscriptionPlan.Builder setNetworkTypes(@Nullable int[]);
+    method @NonNull public android.telephony.SubscriptionPlan.Builder setNetworkTypes(@NonNull int[]);
     method public android.telephony.SubscriptionPlan.Builder setSummary(@Nullable CharSequence);
     method public android.telephony.SubscriptionPlan.Builder setTitle(@Nullable CharSequence);
   }
@@ -45900,6 +45922,7 @@
     method public String getMmsUserAgent();
     method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getNai();
     method public String getNetworkCountryIso();
+    method @NonNull public String getNetworkCountryIso(int);
     method public String getNetworkOperator();
     method public String getNetworkOperatorName();
     method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public int getNetworkSelectionMode();
@@ -45965,6 +45988,7 @@
     method public boolean setLine1NumberForDisplay(String, String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setNetworkSelectionModeAutomatic();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setNetworkSelectionModeManual(String, boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setNetworkSelectionModeManual(@NonNull String, boolean, int);
     method public boolean setOperatorBrandOverride(String);
     method public boolean setPreferredNetworkTypeToGlobal();
     method public void setPreferredOpportunisticDataSubscription(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
@@ -46010,6 +46034,7 @@
     field public static final int DATA_DISCONNECTING = 4; // 0x4
     field public static final int DATA_SUSPENDED = 3; // 0x3
     field public static final int DATA_UNKNOWN = -1; // 0xffffffff
+    field public static final String EXTRA_ACTIVE_SIM_SUPPORTED_COUNT = "android.telephony.extra.ACTIVE_SIM_SUPPORTED_COUNT";
     field public static final String EXTRA_CALL_VOICEMAIL_INTENT = "android.telephony.extra.CALL_VOICEMAIL_INTENT";
     field public static final String EXTRA_CARRIER_ID = "android.telephony.extra.CARRIER_ID";
     field public static final String EXTRA_CARRIER_NAME = "android.telephony.extra.CARRIER_NAME";
@@ -46019,7 +46044,6 @@
     field public static final String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT";
     field public static final String EXTRA_NETWORK_COUNTRY = "android.telephony.extra.NETWORK_COUNTRY";
     field public static final String EXTRA_NOTIFICATION_COUNT = "android.telephony.extra.NOTIFICATION_COUNT";
-    field public static final String EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED = "android.telephony.extra.NUM_OF_ACTIVE_SIM_SUPPORTED";
     field public static final String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telephony.extra.PHONE_ACCOUNT_HANDLE";
     field public static final String EXTRA_SPECIFIC_CARRIER_ID = "android.telephony.extra.SPECIFIC_CARRIER_ID";
     field public static final String EXTRA_SPECIFIC_CARRIER_NAME = "android.telephony.extra.SPECIFIC_CARRIER_NAME";
@@ -46062,7 +46086,6 @@
     field public static final int NETWORK_TYPE_UNKNOWN = 0; // 0x0
     field public static final int PHONE_TYPE_CDMA = 2; // 0x2
     field public static final int PHONE_TYPE_GSM = 1; // 0x1
-    field public static final int PHONE_TYPE_IMS = 5; // 0x5
     field public static final int PHONE_TYPE_NONE = 0; // 0x0
     field public static final int PHONE_TYPE_SIP = 3; // 0x3
     field public static final int SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION = 2; // 0x2
@@ -46354,10 +46377,42 @@
     field public static final int EMBEDDED_SUBSCRIPTION_RESULT_ERROR = 2; // 0x2
     field public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0; // 0x0
     field public static final int EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR = 1; // 0x1
+    field public static final int ERROR_ADDRESS_MISSING = 10011; // 0x271b
+    field public static final int ERROR_CARRIER_LOCKED = 10000; // 0x2710
+    field public static final int ERROR_CERTIFICATE_ERROR = 10012; // 0x271c
+    field public static final int ERROR_CONNECTION_ERROR = 10014; // 0x271e
+    field public static final int ERROR_DISALLOWED_BY_PPR = 10010; // 0x271a
+    field public static final int ERROR_EUICC_INSUFFICIENT_MEMORY = 10004; // 0x2714
+    field public static final int ERROR_EUICC_MISSING = 10006; // 0x2716
+    field public static final int ERROR_INCOMPATIBLE_CARRIER = 10003; // 0x2713
+    field public static final int ERROR_INSTALL_PROFILE = 10009; // 0x2719
+    field public static final int ERROR_INVALID_ACTIVATION_CODE = 10001; // 0x2711
+    field public static final int ERROR_INVALID_CONFIRMATION_CODE = 10002; // 0x2712
+    field public static final int ERROR_INVALID_RESPONSE = 10015; // 0x271f
+    field public static final int ERROR_NO_PROFILES_AVAILABLE = 10013; // 0x271d
+    field public static final int ERROR_OPERATION_BUSY = 10016; // 0x2720
+    field public static final int ERROR_SIM_MISSING = 10008; // 0x2718
+    field public static final int ERROR_TIME_OUT = 10005; // 0x2715
+    field public static final int ERROR_UNSUPPORTED_VERSION = 10007; // 0x2717
     field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE";
     field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
+    field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_ERROR_CODE";
+    field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_OPERATION_CODE";
+    field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE";
+    field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE";
     field public static final String EXTRA_USE_QR_SCANNER = "android.telephony.euicc.extra.USE_QR_SCANNER";
     field public static final String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon";
+    field public static final int OPERATION_APDU = 8; // 0x8
+    field public static final int OPERATION_DOWNLOAD = 5; // 0x5
+    field public static final int OPERATION_EUICC_CARD = 3; // 0x3
+    field public static final int OPERATION_EUICC_GSMA = 7; // 0x7
+    field public static final int OPERATION_HTTP = 11; // 0xb
+    field public static final int OPERATION_METADATA = 6; // 0x6
+    field public static final int OPERATION_SIM_SLOT = 2; // 0x2
+    field public static final int OPERATION_SMDX = 9; // 0x9
+    field public static final int OPERATION_SMDX_SUBJECT_REASON_CODE = 10; // 0xa
+    field public static final int OPERATION_SWITCH = 4; // 0x4
+    field public static final int OPERATION_SYSTEM = 1; // 0x1
   }
 
 }
@@ -46461,6 +46516,7 @@
 
   public class ImsManager {
     method @NonNull public android.telephony.ims.ImsMmTelManager getImsMmTelManager(int);
+    method @NonNull public android.telephony.ims.ImsRcsManager getImsRcsManager(int);
     field public static final String ACTION_WFC_IMS_REGISTRATION_ERROR = "android.telephony.ims.action.WFC_IMS_REGISTRATION_ERROR";
     field public static final String EXTRA_WFC_REGISTRATION_FAILURE_MESSAGE = "android.telephony.ims.extra.WFC_REGISTRATION_FAILURE_MESSAGE";
     field public static final String EXTRA_WFC_REGISTRATION_FAILURE_TITLE = "android.telephony.ims.extra.WFC_REGISTRATION_FAILURE_TITLE";
@@ -46489,6 +46545,15 @@
     method public void onCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
   }
 
+  public class ImsRcsManager implements android.telephony.ims.RegistrationManager {
+    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method @NonNull public android.telephony.ims.RcsUceAdapter getUceAdapter();
+    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RegistrationManager.RegistrationCallback) throws android.telephony.ims.ImsException;
+    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
+    field public static final String ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN = "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN";
+  }
+
   public final class ImsReasonInfo implements android.os.Parcelable {
     ctor public ImsReasonInfo(int, int, @Nullable String);
     method public int describeContents();
@@ -46672,6 +46737,10 @@
     field public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; // 0x2
   }
 
+  public class RcsUceAdapter {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isUceSettingEnabled() throws android.telephony.ims.ImsException;
+  }
+
   public interface RegistrationManager {
     method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
@@ -46686,8 +46755,8 @@
     ctor public RegistrationManager.RegistrationCallback();
     method public void onRegistered(int);
     method public void onRegistering(int);
-    method public void onTechnologyChangeFailed(int, @Nullable android.telephony.ims.ImsReasonInfo);
-    method public void onUnregistered(@Nullable android.telephony.ims.ImsReasonInfo);
+    method public void onTechnologyChangeFailed(int, @NonNull android.telephony.ims.ImsReasonInfo);
+    method public void onUnregistered(@NonNull android.telephony.ims.ImsReasonInfo);
   }
 
 }
diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt
index 1d646d4..355fa18 100644
--- a/api/module-lib-current.txt
+++ b/api/module-lib-current.txt
@@ -29,7 +29,7 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR;
   }
 
-  public class TetheringConstants {
+  public final class TetheringConstants {
     field public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
     field public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback";
     field public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType";
@@ -72,19 +72,20 @@
     field public static final int TETHERING_WIFI = 0; // 0x0
     field public static final int TETHERING_WIFI_P2P = 3; // 0x3
     field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc
-    field public static final int TETHER_ERROR_DISABLE_NAT_ERROR = 9; // 0x9
-    field public static final int TETHER_ERROR_ENABLE_NAT_ERROR = 8; // 0x8
+    field public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; // 0x9
+    field public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; // 0x8
     field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd
     field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa
-    field public static final int TETHER_ERROR_MASTER_ERROR = 5; // 0x5
+    field public static final int TETHER_ERROR_INTERNAL_ERROR = 5; // 0x5
     field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf
     field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe
     field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
-    field public static final int TETHER_ERROR_PROVISION_FAILED = 11; // 0xb
+    field public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; // 0xb
     field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2
     field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6
     field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4
     field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1
+    field public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; // 0x10
     field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3
     field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7
     field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2
@@ -96,40 +97,42 @@
     method public void onTetheringEntitlementResult(int);
   }
 
-  public abstract static class TetheringManager.StartTetheringCallback {
-    ctor public TetheringManager.StartTetheringCallback();
-    method public void onTetheringFailed(int);
-    method public void onTetheringStarted();
+  public static interface TetheringManager.StartTetheringCallback {
+    method public default void onTetheringFailed(int);
+    method public default void onTetheringStarted();
   }
 
-  public abstract static class TetheringManager.TetheringEventCallback {
-    ctor public TetheringManager.TetheringEventCallback();
-    method public void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
-    method public void onError(@NonNull String, int);
-    method public void onOffloadStatusChanged(int);
-    method @Deprecated public void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps);
-    method public void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
-    method public void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>);
-    method public void onTetheringSupported(boolean);
-    method public void onUpstreamChanged(@Nullable android.net.Network);
+  public static interface TetheringManager.TetheringEventCallback {
+    method public default void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
+    method public default void onError(@NonNull String, int);
+    method public default void onOffloadStatusChanged(int);
+    method public default void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps);
+    method public default void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+    method public default void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+    method public default void onTetheringSupported(boolean);
+    method public default void onUpstreamChanged(@Nullable android.net.Network);
   }
 
-  @Deprecated public static class TetheringManager.TetheringInterfaceRegexps {
-    ctor @Deprecated public TetheringManager.TetheringInterfaceRegexps(@NonNull String[], @NonNull String[], @NonNull String[]);
-    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs();
-    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs();
-    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs();
+  public static class TetheringManager.TetheringInterfaceRegexps {
+    method @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs();
+    method @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs();
+    method @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs();
   }
 
   public static class TetheringManager.TetheringRequest {
+    method @Nullable public android.net.LinkAddress getClientStaticIpv4Address();
+    method @Nullable public android.net.LinkAddress getLocalIpv4Address();
+    method public boolean getShouldShowEntitlementUi();
+    method public int getTetheringType();
+    method public boolean isExemptFromEntitlementCheck();
   }
 
   public static class TetheringManager.TetheringRequest.Builder {
     ctor public TetheringManager.TetheringRequest.Builder(int);
     method @NonNull public android.net.TetheringManager.TetheringRequest build();
     method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean);
-    method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setSilentProvisioning(boolean);
-    method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder useStaticIpv4Addresses(@NonNull android.net.LinkAddress);
+    method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean);
+    method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress);
   }
 
 }
diff --git a/api/system-current.txt b/api/system-current.txt
index 4191c55..6ab5b1e 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -134,6 +134,7 @@
     field public static final String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD";
     field public static final String NETWORK_SIGNAL_STRENGTH_WAKEUP = "android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP";
     field public static final String NETWORK_STACK = "android.permission.NETWORK_STACK";
+    field public static final String NETWORK_STATS_PROVIDER = "android.permission.NETWORK_STATS_PROVIDER";
     field public static final String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP";
     field public static final String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS";
     field public static final String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE";
@@ -186,7 +187,7 @@
     field public static final String REVIEW_ACCESSIBILITY_SERVICES = "android.permission.REVIEW_ACCESSIBILITY_SERVICES";
     field public static final String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS";
     field public static final String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS";
-    field public static final String SECURE_ELEMENT_PRIVILEGED = "android.permission.SECURE_ELEMENT_PRIVILEGED";
+    field public static final String SECURE_ELEMENT_PRIVILEGED_OPERATION = "android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION";
     field public static final String SEND_DEVICE_CUSTOMIZATION_READY = "android.permission.SEND_DEVICE_CUSTOMIZATION_READY";
     field public static final String SEND_SHOW_SUSPENDED_APP_DETAILS = "android.permission.SEND_SHOW_SUSPENDED_APP_DETAILS";
     field public static final String SEND_SMS_NO_CONFIRMATION = "android.permission.SEND_SMS_NO_CONFIRMATION";
@@ -228,9 +229,6 @@
 
   public static final class R.array {
     field public static final int config_keySystemUuidMapping = 17235973; // 0x1070005
-    field public static final int config_restrictedPreinstalledCarrierApps = 17235975; // 0x1070007
-    field public static final int config_sms_enabled_locking_shift_tables = 17235977; // 0x1070009
-    field public static final int config_sms_enabled_single_shift_tables = 17235976; // 0x1070008
     field public static final int simColors = 17235974; // 0x1070006
   }
 
@@ -278,7 +276,6 @@
     field public static final int config_helpIntentNameKey = 17039390; // 0x104001e
     field public static final int config_helpPackageNameKey = 17039387; // 0x104001b
     field public static final int config_helpPackageNameValue = 17039388; // 0x104001c
-    field public static final int low_memory = 17039397; // 0x1040025
   }
 
   public static final class R.style {
@@ -323,7 +320,6 @@
     method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public static void setPersistentVrThread(int);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean switchUser(@NonNull android.os.UserHandle);
     method public void unregisterHomeVisibilityObserver(@NonNull android.app.HomeVisibilityObserver);
-    method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String);
   }
 
   public static interface ActivityManager.OnUidImportanceListener {
@@ -998,8 +994,8 @@
 
   public final class CompatChanges {
     method public static boolean isChangeEnabled(long);
-    method public static boolean isChangeEnabled(long, @NonNull String, @NonNull android.os.UserHandle);
-    method public static boolean isChangeEnabled(long, int);
+    method @RequiresPermission(allOf={"android.permission.READ_COMPAT_CHANGE_CONFIG", "android.permission.LOG_COMPAT_CHANGE"}) public static boolean isChangeEnabled(long, @NonNull String, @NonNull android.os.UserHandle);
+    method @RequiresPermission(allOf={"android.permission.READ_COMPAT_CHANGE_CONFIG", "android.permission.LOG_COMPAT_CHANGE"}) public static boolean isChangeEnabled(long, int);
   }
 
 }
@@ -1239,7 +1235,8 @@
   }
 
   public class NetworkStatsManager {
-    method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.net.netstats.provider.NetworkStatsProviderCallback registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.AbstractNetworkStatsProvider);
+    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.NetworkStatsProvider);
+    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void unregisterNetworkStatsProvider(@NonNull android.net.netstats.provider.NetworkStatsProvider);
   }
 
   public static final class UsageEvents.Event {
@@ -1290,16 +1287,8 @@
 package android.bluetooth {
 
   public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void disableOptionalCodecs(@Nullable android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void enableOptionalCodecs(@Nullable android.bluetooth.BluetoothDevice);
-    method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothDevice getActiveDevice();
-    method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothCodecStatus getCodecStatus(@Nullable android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public int getOptionalCodecsEnabled(@Nullable android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setCodecConfigPreference(@Nullable android.bluetooth.BluetoothDevice, @Nullable android.bluetooth.BluetoothCodecConfig);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setOptionalCodecsEnabled(@Nullable android.bluetooth.BluetoothDevice, int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public int supportsOptionalCodecs(@Nullable android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
     field public static final int OPTIONAL_CODECS_NOT_SUPPORTED = 0; // 0x0
     field public static final int OPTIONAL_CODECS_PREF_DISABLED = 0; // 0x0
     field public static final int OPTIONAL_CODECS_PREF_ENABLED = 1; // 0x1
@@ -1310,28 +1299,23 @@
 
   public final class BluetoothA2dpSink implements android.bluetooth.BluetoothProfile {
     method public void finalize();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isAudioPlaying(@Nullable android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice, int);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isAudioPlaying(@NonNull android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
     field @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED";
   }
 
   public final class BluetoothAdapter {
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean addOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean connectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice);
     method public boolean disableBLE();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean disconnectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice);
     method public boolean enableBLE();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean enableNoAutoConnect();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean factoryReset();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public long getDiscoveryEndMillis();
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public long getDiscoveryEndMillis();
     method public boolean isBleScanAlwaysAvailable();
     method public boolean isLeEnabled();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean removeActiveDevice(int);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean removeOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setActiveDevice(@NonNull android.bluetooth.BluetoothDevice, int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setScanMode(int, long);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setScanMode(int);
     field public static final String ACTION_BLE_STATE_CHANGED = "android.bluetooth.adapter.action.BLE_STATE_CHANGED";
     field public static final String ACTION_REQUEST_BLE_SCAN_ALWAYS_AVAILABLE = "android.bluetooth.adapter.action.REQUEST_BLE_SCAN_ALWAYS_AVAILABLE";
     field public static final int ACTIVE_DEVICE_ALL = 2; // 0x2
@@ -1343,70 +1327,17 @@
     method public void onMetadataChanged(@NonNull android.bluetooth.BluetoothDevice, int, @Nullable byte[]);
   }
 
-  public final class BluetoothCodecConfig implements android.os.Parcelable {
-    ctor public BluetoothCodecConfig(int, int, int, int, int, long, long, long, long);
-    ctor public BluetoothCodecConfig(int);
-    method public int getBitsPerSample();
-    method @NonNull public String getCodecName();
-    method public int getCodecPriority();
-    method public long getCodecSpecific1();
-    method public int getCodecType();
-    method public int getSampleRate();
-    method public boolean isMandatoryCodec();
-    field public static final int BITS_PER_SAMPLE_16 = 1; // 0x1
-    field public static final int BITS_PER_SAMPLE_24 = 2; // 0x2
-    field public static final int BITS_PER_SAMPLE_32 = 4; // 0x4
-    field public static final int BITS_PER_SAMPLE_NONE = 0; // 0x0
-    field public static final int CHANNEL_MODE_MONO = 1; // 0x1
-    field public static final int CHANNEL_MODE_NONE = 0; // 0x0
-    field public static final int CHANNEL_MODE_STEREO = 2; // 0x2
-    field public static final int CODEC_PRIORITY_DEFAULT = 0; // 0x0
-    field public static final int CODEC_PRIORITY_DISABLED = -1; // 0xffffffff
-    field public static final int CODEC_PRIORITY_HIGHEST = 1000000; // 0xf4240
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothCodecConfig> CREATOR;
-    field public static final int SAMPLE_RATE_176400 = 16; // 0x10
-    field public static final int SAMPLE_RATE_192000 = 32; // 0x20
-    field public static final int SAMPLE_RATE_44100 = 1; // 0x1
-    field public static final int SAMPLE_RATE_48000 = 2; // 0x2
-    field public static final int SAMPLE_RATE_88200 = 4; // 0x4
-    field public static final int SAMPLE_RATE_96000 = 8; // 0x8
-    field public static final int SAMPLE_RATE_NONE = 0; // 0x0
-    field public static final int SOURCE_CODEC_TYPE_AAC = 1; // 0x1
-    field public static final int SOURCE_CODEC_TYPE_APTX = 2; // 0x2
-    field public static final int SOURCE_CODEC_TYPE_APTX_HD = 3; // 0x3
-    field public static final int SOURCE_CODEC_TYPE_INVALID = 1000000; // 0xf4240
-    field public static final int SOURCE_CODEC_TYPE_LDAC = 4; // 0x4
-    field public static final int SOURCE_CODEC_TYPE_MAX = 5; // 0x5
-    field public static final int SOURCE_CODEC_TYPE_SBC = 0; // 0x0
-  }
-
-  public final class BluetoothCodecStatus implements android.os.Parcelable {
-    ctor public BluetoothCodecStatus(@Nullable android.bluetooth.BluetoothCodecConfig, @Nullable android.bluetooth.BluetoothCodecConfig[], @Nullable android.bluetooth.BluetoothCodecConfig[]);
-    method @Nullable public android.bluetooth.BluetoothCodecConfig getCodecConfig();
-    method @Nullable public android.bluetooth.BluetoothCodecConfig[] getCodecsLocalCapabilities();
-    method @Nullable public android.bluetooth.BluetoothCodecConfig[] getCodecsSelectableCapabilities();
-    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothCodecStatus> CREATOR;
-    field public static final String EXTRA_CODEC_STATUS = "android.bluetooth.extra.CODEC_STATUS";
-  }
-
   public final class BluetoothDevice implements android.os.Parcelable {
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean cancelBondProcess();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean cancelPairing();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getBatteryLevel();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getMessageAccessPermission();
     method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public byte[] getMetadata(int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getPhonebookAccessPermission();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getSimAccessPermission();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isBondingInitiatedLocally();
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getSimAccessPermission();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isConnected();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isEncrypted();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInSilenceMode();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean removeBond();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setAlias(@NonNull String);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMessageAccessPermission(int);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMetadata(int, @NonNull byte[]);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPhonebookAccessPermission(int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setPin(@NonNull String);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setSilenceMode(boolean);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setSimAccessPermission(int);
     field public static final int ACCESS_ALLOWED = 1; // 0x1
@@ -1436,17 +1367,15 @@
   public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean connect(android.bluetooth.BluetoothDevice);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean disconnect(android.bluetooth.BluetoothDevice);
-    method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothDevice getActiveDevice();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
     method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setPriority(android.bluetooth.BluetoothDevice, int);
   }
 
   public final class BluetoothHearingAid implements android.bluetooth.BluetoothProfile {
-    method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH) public java.util.List<android.bluetooth.BluetoothDevice> getActiveDevices();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public long getHiSyncId(@Nullable android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public long getHiSyncId(@NonNull android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
   }
 
   public final class BluetoothHidDevice implements android.bluetooth.BluetoothProfile {
@@ -1455,9 +1384,9 @@
 
   public final class BluetoothHidHost implements android.bluetooth.BluetoothProfile {
     method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
     field public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
   }
 
@@ -1465,14 +1394,14 @@
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void close();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) protected void finalize();
     method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice, int);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
     field public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED";
   }
 
-  public final class BluetoothPan implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
+  public final class BluetoothPan implements android.bluetooth.BluetoothProfile {
     method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionState(@Nullable android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isTetheringOn();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setBluetoothTethering(boolean);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
@@ -1486,7 +1415,7 @@
   }
 
   public class BluetoothPbap implements android.bluetooth.BluetoothProfile {
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionState(@Nullable android.bluetooth.BluetoothDevice);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
     field @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED";
   }
@@ -1608,9 +1537,7 @@
     field public static final String EUICC_CARD_SERVICE = "euicc_card";
     field public static final String HDMI_CONTROL_SERVICE = "hdmi_control";
     field public static final String NETD_SERVICE = "netd";
-    field public static final String NETWORK_POLICY_SERVICE = "netpolicy";
     field public static final String NETWORK_SCORE_SERVICE = "network_score";
-    field public static final String NETWORK_STACK_SERVICE = "network_stack";
     field public static final String OEM_LOCK_SERVICE = "oem_lock";
     field public static final String PERMISSION_SERVICE = "permission";
     field public static final String PERSISTENT_DATA_BLOCK_SERVICE = "persistent_data_block";
@@ -1669,7 +1596,6 @@
     field public static final String ACTION_UPGRADE_SETUP = "android.intent.action.UPGRADE_SETUP";
     field public static final String ACTION_USER_ADDED = "android.intent.action.USER_ADDED";
     field public static final String ACTION_USER_REMOVED = "android.intent.action.USER_REMOVED";
-    field @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public static final String ACTION_USER_SWITCHED = "android.intent.action.USER_SWITCHED";
     field public static final String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST";
     field public static final String CATEGORY_LEANBACK_SETTINGS = "android.intent.category.LEANBACK_SETTINGS";
     field public static final String EXTRA_CALLING_PACKAGE = "android.intent.extra.CALLING_PACKAGE";
@@ -4422,7 +4348,7 @@
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public int registerNetworkProvider(@NonNull android.net.NetworkProvider);
     method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
-    method @Deprecated public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, int, int, @NonNull android.os.Handler);
+    method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void requestNetwork(@NonNull android.net.NetworkRequest, int, int, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
     method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean);
     method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public boolean shouldAvoidBadWifi();
     method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle);
@@ -4473,10 +4399,10 @@
 
   public class InvalidPacketException extends java.lang.Exception {
     ctor public InvalidPacketException(int);
+    method public int getError();
     field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb
     field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9
     field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea
-    field public final int error;
   }
 
   public final class IpConfiguration implements android.os.Parcelable {
@@ -4530,12 +4456,12 @@
   }
 
   public class KeepalivePacketData {
-    ctor protected KeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[]) throws android.net.InvalidPacketException;
+    ctor protected KeepalivePacketData(@NonNull java.net.InetAddress, @IntRange(from=0, to=65535) int, @NonNull java.net.InetAddress, @IntRange(from=0, to=65535) int, @NonNull byte[]) throws android.net.InvalidPacketException;
+    method @NonNull public java.net.InetAddress getDstAddress();
+    method public int getDstPort();
     method @NonNull public byte[] getPacket();
-    field @NonNull public final java.net.InetAddress dstAddress;
-    field public final int dstPort;
-    field @NonNull public final java.net.InetAddress srcAddress;
-    field public final int srcPort;
+    method @NonNull public java.net.InetAddress getSrcAddress();
+    method public int getSrcPort();
   }
 
   public class LinkAddress implements android.os.Parcelable {
@@ -4556,6 +4482,7 @@
 
   public final class LinkProperties implements android.os.Parcelable {
     ctor public LinkProperties(@Nullable android.net.LinkProperties);
+    ctor public LinkProperties(@Nullable android.net.LinkProperties, boolean);
     method public boolean addDnsServer(@NonNull java.net.InetAddress);
     method public boolean addLinkAddress(@NonNull android.net.LinkAddress);
     method public boolean addPcscfServer(@NonNull java.net.InetAddress);
@@ -4578,7 +4505,6 @@
     method public boolean isIpv6Provisioned();
     method public boolean isProvisioned();
     method public boolean isReachable(@NonNull java.net.InetAddress);
-    method @NonNull public android.net.LinkProperties makeSensitiveFieldsParcelingCopy();
     method public boolean removeDnsServer(@NonNull java.net.InetAddress);
     method public boolean removeLinkAddress(@NonNull android.net.LinkAddress);
     method public boolean removeRoute(@NonNull android.net.RouteInfo);
@@ -4608,8 +4534,8 @@
 
   public class Network implements android.os.Parcelable {
     ctor public Network(@NonNull android.net.Network);
+    method public int getNetId();
     method @NonNull public android.net.Network getPrivateDnsBypassingCopy();
-    field public final int netId;
   }
 
   public abstract class NetworkAgent {
@@ -4617,7 +4543,6 @@
     method @Nullable public android.net.Network getNetwork();
     method public void onAddKeepalivePacketFilter(int, @NonNull android.net.KeepalivePacketData);
     method public void onAutomaticReconnectDisabled();
-    method public void onBandwidthUpdateRequested();
     method public void onNetworkUnwanted();
     method public void onRemoveKeepalivePacketFilter(int);
     method public void onSaveAcceptUnvalidated(boolean);
@@ -4631,23 +4556,17 @@
     method public void sendNetworkScore(int);
     method public void sendSocketKeepaliveEvent(int, int);
     method public void setConnected();
-    method @Deprecated public void setLegacyExtraInfo(@Nullable String);
-    method @Deprecated public void setLegacySubtype(int, @NonNull String);
     method public void unregister();
     field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2
     field public static final int VALIDATION_STATUS_VALID = 1; // 0x1
-    field public final int providerId;
   }
 
   public final class NetworkAgentConfig implements android.os.Parcelable {
     method public int describeContents();
     method public int getLegacyType();
     method @NonNull public String getLegacyTypeName();
-    method @Nullable public String getSubscriberId();
     method public boolean isExplicitlySelected();
-    method public boolean isNat64DetectionEnabled();
     method public boolean isPartialConnectivityAcceptable();
-    method public boolean isProvisioningNotificationEnabled();
     method public boolean isUnvalidatedConnectivityAcceptable();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkAgentConfig> CREATOR;
@@ -4656,31 +4575,42 @@
   public static class NetworkAgentConfig.Builder {
     ctor public NetworkAgentConfig.Builder();
     method @NonNull public android.net.NetworkAgentConfig build();
-    method @NonNull public android.net.NetworkAgentConfig.Builder disableNat64Detection();
-    method @NonNull public android.net.NetworkAgentConfig.Builder disableProvisioningNotification();
     method @NonNull public android.net.NetworkAgentConfig.Builder setExplicitlySelected(boolean);
     method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyType(int);
     method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyTypeName(@NonNull String);
     method @NonNull public android.net.NetworkAgentConfig.Builder setPartialConnectivityAcceptable(boolean);
-    method @NonNull public android.net.NetworkAgentConfig.Builder setSubscriberId(@Nullable String);
     method @NonNull public android.net.NetworkAgentConfig.Builder setUnvalidatedConnectivityAcceptable(boolean);
   }
 
   public final class NetworkCapabilities implements android.os.Parcelable {
-    method public boolean deduceRestrictedCapability();
-    method @NonNull public java.util.List<java.lang.Integer> getAdministratorUids();
-    method @Nullable public String getSSID();
+    method @NonNull public int[] getAdministratorUids();
+    method @Nullable public String getSsid();
     method @NonNull public int[] getTransportTypes();
     method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
-    method @NonNull public android.net.NetworkCapabilities setAdministratorUids(@NonNull java.util.List<java.lang.Integer>);
-    method @NonNull public android.net.NetworkCapabilities setRequestorPackageName(@NonNull String);
-    method @NonNull public android.net.NetworkCapabilities setRequestorUid(int);
-    method @NonNull public android.net.NetworkCapabilities setSSID(@Nullable String);
-    method @NonNull public android.net.NetworkCapabilities setTransportInfo(@NonNull android.net.TransportInfo);
     field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16
     field public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24; // 0x18
   }
 
+  public static class NetworkCapabilities.Builder {
+    ctor public NetworkCapabilities.Builder();
+    ctor public NetworkCapabilities.Builder(@NonNull android.net.NetworkCapabilities);
+    method @NonNull public android.net.NetworkCapabilities.Builder addCapability(int);
+    method @NonNull public android.net.NetworkCapabilities.Builder addTransportType(int);
+    method @NonNull public android.net.NetworkCapabilities build();
+    method @NonNull public android.net.NetworkCapabilities.Builder removeCapability(int);
+    method @NonNull public android.net.NetworkCapabilities.Builder removeTransportType(int);
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setAdministratorUids(@NonNull int[]);
+    method @NonNull public android.net.NetworkCapabilities.Builder setLinkDownstreamBandwidthKbps(int);
+    method @NonNull public android.net.NetworkCapabilities.Builder setLinkUpstreamBandwidthKbps(int);
+    method @NonNull public android.net.NetworkCapabilities.Builder setNetworkSpecifier(@Nullable android.net.NetworkSpecifier);
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setOwnerUid(int);
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorPackageName(@Nullable String);
+    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 setTransportInfo(@Nullable android.net.TransportInfo);
+  }
+
   public class NetworkKey implements android.os.Parcelable {
     ctor public NetworkKey(android.net.WifiKey);
     method @Nullable public static android.net.NetworkKey createFromScanResult(@Nullable android.net.wifi.ScanResult);
@@ -4692,27 +4622,9 @@
     field public final android.net.WifiKey wifiKey;
   }
 
-  public class NetworkPolicyManager {
-    method @NonNull public android.telephony.SubscriptionPlan[] getSubscriptionPlans(int, @NonNull String);
-    method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void registerSubscriptionCallback(@NonNull android.net.NetworkPolicyManager.SubscriptionCallback);
-    method public void setSubscriptionOverride(int, int, int, long, @NonNull String);
-    method public void setSubscriptionPlans(int, @NonNull android.telephony.SubscriptionPlan[], @NonNull String);
-    method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public void unregisterSubscriptionCallback(@NonNull android.net.NetworkPolicyManager.SubscriptionCallback);
-    field public static final int SUBSCRIPTION_OVERRIDE_CONGESTED = 2; // 0x2
-    field public static final int SUBSCRIPTION_OVERRIDE_UNMETERED = 1; // 0x1
-  }
-
-  public static class NetworkPolicyManager.SubscriptionCallback {
-    ctor public NetworkPolicyManager.SubscriptionCallback();
-    method public void onSubscriptionOverride(int, int, int);
-    method public void onSubscriptionPlansChanged(int, @NonNull android.telephony.SubscriptionPlan[]);
-  }
-
   public class NetworkProvider {
     ctor public NetworkProvider(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull android.net.NetworkRequest);
-    method @Nullable public android.os.Messenger getMessenger();
-    method @NonNull public String getName();
     method public int getProviderId();
     method public void onNetworkRequested(@NonNull android.net.NetworkRequest, int, int);
     method public void onRequestWithdrawn(@NonNull android.net.NetworkRequest);
@@ -4767,20 +4679,20 @@
   }
 
   public class NetworkStack {
+    method @Nullable public static android.os.IBinder getService();
     field public static final String PERMISSION_MAINLINE_NETWORK_STACK = "android.permission.MAINLINE_NETWORK_STACK";
   }
 
   public final class NetworkStats implements android.os.Parcelable {
     ctor public NetworkStats(long, int);
     method @NonNull public android.net.NetworkStats add(@NonNull android.net.NetworkStats);
-    method @NonNull public android.net.NetworkStats addValues(@NonNull android.net.NetworkStats.Entry);
+    method @NonNull public android.net.NetworkStats addEntry(@NonNull android.net.NetworkStats.Entry);
     method public int describeContents();
     method @NonNull public android.net.NetworkStats subtract(@NonNull android.net.NetworkStats);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStats> CREATOR;
     field public static final int DEFAULT_NETWORK_NO = 0; // 0x0
     field public static final int DEFAULT_NETWORK_YES = 1; // 0x1
-    field @Nullable public static final String IFACE_ALL;
     field public static final String IFACE_VT = "vt_data0";
     field public static final int METERED_NO = 0; // 0x0
     field public static final int METERED_YES = 1; // 0x1
@@ -4892,7 +4804,6 @@
     method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
     method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
     method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
-    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
     method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
     method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
     method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
@@ -4909,19 +4820,20 @@
     field public static final int TETHERING_WIFI = 0; // 0x0
     field public static final int TETHERING_WIFI_P2P = 3; // 0x3
     field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc
-    field public static final int TETHER_ERROR_DISABLE_NAT_ERROR = 9; // 0x9
-    field public static final int TETHER_ERROR_ENABLE_NAT_ERROR = 8; // 0x8
+    field public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; // 0x9
+    field public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; // 0x8
     field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd
     field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa
-    field public static final int TETHER_ERROR_MASTER_ERROR = 5; // 0x5
+    field public static final int TETHER_ERROR_INTERNAL_ERROR = 5; // 0x5
     field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf
     field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe
     field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
-    field public static final int TETHER_ERROR_PROVISION_FAILED = 11; // 0xb
+    field public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; // 0xb
     field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2
     field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6
     field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4
     field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1
+    field public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; // 0x10
     field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3
     field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7
     field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2
@@ -4933,40 +4845,35 @@
     method public void onTetheringEntitlementResult(int);
   }
 
-  public abstract static class TetheringManager.StartTetheringCallback {
-    ctor public TetheringManager.StartTetheringCallback();
-    method public void onTetheringFailed(int);
-    method public void onTetheringStarted();
+  public static interface TetheringManager.StartTetheringCallback {
+    method public default void onTetheringFailed(int);
+    method public default void onTetheringStarted();
   }
 
-  public abstract static class TetheringManager.TetheringEventCallback {
-    ctor public TetheringManager.TetheringEventCallback();
-    method public void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
-    method public void onError(@NonNull String, int);
-    method public void onOffloadStatusChanged(int);
-    method @Deprecated public void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps);
-    method public void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
-    method public void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>);
-    method public void onTetheringSupported(boolean);
-    method public void onUpstreamChanged(@Nullable android.net.Network);
-  }
-
-  @Deprecated public static class TetheringManager.TetheringInterfaceRegexps {
-    ctor @Deprecated public TetheringManager.TetheringInterfaceRegexps(@NonNull String[], @NonNull String[], @NonNull String[]);
-    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs();
-    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs();
-    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs();
+  public static interface TetheringManager.TetheringEventCallback {
+    method public default void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
+    method public default void onError(@NonNull String, int);
+    method public default void onOffloadStatusChanged(int);
+    method public default void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+    method public default void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+    method public default void onTetheringSupported(boolean);
+    method public default void onUpstreamChanged(@Nullable android.net.Network);
   }
 
   public static class TetheringManager.TetheringRequest {
+    method @Nullable public android.net.LinkAddress getClientStaticIpv4Address();
+    method @Nullable public android.net.LinkAddress getLocalIpv4Address();
+    method public boolean getShouldShowEntitlementUi();
+    method public int getTetheringType();
+    method public boolean isExemptFromEntitlementCheck();
   }
 
   public static class TetheringManager.TetheringRequest.Builder {
     ctor public TetheringManager.TetheringRequest.Builder(int);
     method @NonNull public android.net.TetheringManager.TetheringRequest build();
     method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean);
-    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setSilentProvisioning(boolean);
-    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder useStaticIpv4Addresses(@NonNull android.net.LinkAddress);
+    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress);
   }
 
   public class TrafficStats {
@@ -5180,21 +5087,17 @@
 
 package android.net.netstats.provider {
 
-  public abstract class AbstractNetworkStatsProvider {
-    ctor public AbstractNetworkStatsProvider();
-    method public abstract void requestStatsUpdate(int);
-    method public abstract void setAlert(long);
-    method public abstract void setLimit(@NonNull String, long);
+  public abstract class NetworkStatsProvider {
+    ctor public NetworkStatsProvider();
+    method public void notifyAlertReached();
+    method public void notifyLimitReached();
+    method public void notifyStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats);
+    method public abstract void onRequestStatsUpdate(int);
+    method public abstract void onSetAlert(long);
+    method public abstract void onSetLimit(@NonNull String, long);
     field public static final int QUOTA_UNLIMITED = -1; // 0xffffffff
   }
 
-  public class NetworkStatsProviderCallback {
-    method public void onAlertReached();
-    method public void onLimitReached();
-    method public void onStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats);
-    method public void unregister();
-  }
-
 }
 
 package android.net.sip {
@@ -5983,13 +5886,15 @@
     field public static final String ACTION_UPDATE_CARRIER_PROVISIONING_URLS = "android.intent.action.UPDATE_CARRIER_PROVISIONING_URLS";
     field public static final String ACTION_UPDATE_CONVERSATION_ACTIONS = "android.intent.action.UPDATE_CONVERSATION_ACTIONS";
     field public static final String ACTION_UPDATE_CT_LOGS = "android.intent.action.UPDATE_CT_LOGS";
-    field public static final String ACTION_UPDATE_EMERGENCY_NUMBER_DB = "android.os.action.UPDATE_EMERGENCY_NUMBER_DB";
+    field @RequiresPermission("android.permission.UPDATE_CONFIG") public static final String ACTION_UPDATE_EMERGENCY_NUMBER_DB = "android.os.action.UPDATE_EMERGENCY_NUMBER_DB";
     field public static final String ACTION_UPDATE_INTENT_FIREWALL = "android.intent.action.UPDATE_INTENT_FIREWALL";
     field public static final String ACTION_UPDATE_LANG_ID = "android.intent.action.UPDATE_LANG_ID";
     field public static final String ACTION_UPDATE_NETWORK_WATCHLIST = "android.intent.action.UPDATE_NETWORK_WATCHLIST";
     field public static final String ACTION_UPDATE_PINS = "android.intent.action.UPDATE_PINS";
     field public static final String ACTION_UPDATE_SMART_SELECTION = "android.intent.action.UPDATE_SMART_SELECTION";
     field public static final String ACTION_UPDATE_SMS_SHORT_CODES = "android.intent.action.UPDATE_SMS_SHORT_CODES";
+    field public static final String EXTRA_REQUIRED_HASH = "android.os.extra.REQUIRED_HASH";
+    field public static final String EXTRA_VERSION = "android.os.extra.VERSION";
   }
 
   public class Environment {
@@ -6645,18 +6550,6 @@
 
 package android.provider {
 
-  public class BlockedNumberContract {
-    field public static final String METHOD_NOTIFY_EMERGENCY_CONTACT = "notify_emergency_contact";
-    field public static final String METHOD_SHOULD_SYSTEM_BLOCK_NUMBER = "should_system_block_number";
-    field public static final String RES_BLOCK_STATUS = "block_status";
-    field public static final int STATUS_BLOCKED_IN_LIST = 1; // 0x1
-    field public static final int STATUS_BLOCKED_NOT_IN_CONTACTS = 5; // 0x5
-    field public static final int STATUS_BLOCKED_PAYPHONE = 4; // 0x4
-    field public static final int STATUS_BLOCKED_RESTRICTED = 2; // 0x2
-    field public static final int STATUS_BLOCKED_UNKNOWN_NUMBER = 3; // 0x3
-    field public static final int STATUS_NOT_BLOCKED = 0; // 0x0
-  }
-
   public static final class ContactsContract.MetadataSync implements android.provider.BaseColumns android.provider.ContactsContract.MetadataSyncColumns {
     field public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact_metadata";
     field public static final String CONTENT_TYPE = "vnd.android.cursor.dir/contact_metadata";
@@ -6938,32 +6831,6 @@
     field public static final int VOLUME_HUSH_VIBRATE = 1; // 0x1
   }
 
-  public static interface Telephony.CarrierColumns extends android.provider.BaseColumns {
-    field @NonNull public static final android.net.Uri CONTENT_URI;
-    field public static final String EXPIRATION_TIME = "expiration_time";
-    field public static final String KEY_IDENTIFIER = "key_identifier";
-    field public static final String KEY_TYPE = "key_type";
-    field public static final String LAST_MODIFIED = "last_modified";
-    field public static final String MCC = "mcc";
-    field public static final String MNC = "mnc";
-    field public static final String MVNO_MATCH_DATA = "mvno_match_data";
-    field public static final String MVNO_TYPE = "mvno_type";
-    field public static final String PUBLIC_KEY = "public_key";
-  }
-
-  public static final class Telephony.CarrierId.All implements android.provider.BaseColumns {
-    field public static final String APN = "apn";
-    field @NonNull public static final android.net.Uri CONTENT_URI;
-    field public static final String GID1 = "gid1";
-    field public static final String GID2 = "gid2";
-    field public static final String ICCID_PREFIX = "iccid_prefix";
-    field public static final String IMSI_PREFIX_XPATTERN = "imsi_prefix_xpattern";
-    field public static final String MCCMNC = "mccmnc";
-    field public static final String PLMN = "plmn";
-    field public static final String PRIVILEGE_ACCESS_RULE = "privilege_access_rule";
-    field public static final String SPN = "spn";
-  }
-
   public static final class Telephony.Carriers implements android.provider.BaseColumns {
     field public static final String APN_SET_ID = "apn_set_id";
     field public static final int CARRIER_EDITED = 4; // 0x4
@@ -7034,76 +6901,6 @@
     field @NonNull public static final String ENABLE_TEST_ALERT_PREF = "enable_test_alerts";
   }
 
-  public static final class Telephony.SimInfo {
-    field public static final String ACCESS_RULES = "access_rules";
-    field public static final String ACCESS_RULES_FROM_CARRIER_CONFIGS = "access_rules_from_carrier_configs";
-    field public static final String ALLOWED_NETWORK_TYPES = "allowed_network_types";
-    field public static final String CARD_ID = "card_id";
-    field public static final String CARRIER_ID = "carrier_id";
-    field public static final String CARRIER_NAME = "carrier_name";
-    field public static final String CB_ALERT_REMINDER_INTERVAL = "alert_reminder_interval";
-    field public static final String CB_ALERT_SOUND_DURATION = "alert_sound_duration";
-    field public static final String CB_ALERT_SPEECH = "enable_alert_speech";
-    field public static final String CB_ALERT_VIBRATE = "enable_alert_vibrate";
-    field public static final String CB_AMBER_ALERT = "enable_cmas_amber_alerts";
-    field public static final String CB_CHANNEL_50_ALERT = "enable_channel_50_alerts";
-    field public static final String CB_CMAS_TEST_ALERT = "enable_cmas_test_alerts";
-    field public static final String CB_EMERGENCY_ALERT = "enable_emergency_alerts";
-    field public static final String CB_ETWS_TEST_ALERT = "enable_etws_test_alerts";
-    field public static final String CB_EXTREME_THREAT_ALERT = "enable_cmas_extreme_threat_alerts";
-    field public static final String CB_OPT_OUT_DIALOG = "show_cmas_opt_out_dialog";
-    field public static final String CB_SEVERE_THREAT_ALERT = "enable_cmas_severe_threat_alerts";
-    field public static final String COLOR = "color";
-    field @NonNull public static final android.net.Uri CONTENT_URI;
-    field public static final String DATA_ENABLED_OVERRIDE_RULES = "data_enabled_override_rules";
-    field public static final String DATA_ROAMING = "data_roaming";
-    field public static final int DATA_ROAMING_DEFAULT = 0; // 0x0
-    field public static final int DATA_ROAMING_DISABLE = 0; // 0x0
-    field public static final int DATA_ROAMING_ENABLE = 1; // 0x1
-    field public static final String DISPLAY_NAME = "display_name";
-    field public static final String EHPLMNS = "ehplmns";
-    field public static final String ENHANCED_4G_MODE_ENABLED = "volte_vt_enabled";
-    field public static final String GROUP_OWNER = "group_owner";
-    field public static final String GROUP_UUID = "group_uuid";
-    field public static final String HPLMNS = "hplmns";
-    field public static final String ICC_ID = "icc_id";
-    field public static final String IMSI = "imsi";
-    field public static final String IMS_RCS_UCE_ENABLED = "ims_rcs_uce_enabled";
-    field public static final String ISO_COUNTRY_CODE = "iso_country_code";
-    field public static final String IS_EMBEDDED = "is_embedded";
-    field public static final String IS_OPPORTUNISTIC = "is_opportunistic";
-    field public static final String IS_REMOVABLE = "is_removable";
-    field public static final String MCC = "mcc";
-    field public static final String MCC_STRING = "mcc_string";
-    field public static final String MNC = "mnc";
-    field public static final String MNC_STRING = "mnc_string";
-    field public static final String NAME_SOURCE = "name_source";
-    field public static final int NAME_SOURCE_CARRIER = 3; // 0x3
-    field public static final int NAME_SOURCE_DEFAULT = 0; // 0x0
-    field public static final int NAME_SOURCE_SIM_PNN = 4; // 0x4
-    field public static final int NAME_SOURCE_SIM_SPN = 1; // 0x1
-    field public static final int NAME_SOURCE_USER_INPUT = 2; // 0x2
-    field public static final String NUMBER = "number";
-    field public static final String PROFILE_CLASS = "profile_class";
-    field public static final int PROFILE_CLASS_DEFAULT = -1; // 0xffffffff
-    field public static final int PROFILE_CLASS_OPERATIONAL = 2; // 0x2
-    field public static final int PROFILE_CLASS_PROVISIONING = 1; // 0x1
-    field public static final int PROFILE_CLASS_TESTING = 0; // 0x0
-    field public static final int PROFILE_CLASS_UNSET = -1; // 0xffffffff
-    field public static final int SIM_NOT_INSERTED = -1; // 0xffffffff
-    field public static final String SIM_SLOT_INDEX = "sim_id";
-    field public static final String SUBSCRIPTION_TYPE = "subscription_type";
-    field public static final int SUBSCRIPTION_TYPE_LOCAL_SIM = 0; // 0x0
-    field public static final int SUBSCRIPTION_TYPE_REMOTE_SIM = 1; // 0x1
-    field public static final String UICC_APPLICATIONS_ENABLED = "uicc_applications_enabled";
-    field public static final String UNIQUE_KEY_SUBSCRIPTION_ID = "_id";
-    field public static final String VT_IMS_ENABLED = "vt_ims_enabled";
-    field public static final String WFC_IMS_ENABLED = "wfc_ims_enabled";
-    field public static final String WFC_IMS_MODE = "wfc_ims_mode";
-    field public static final String WFC_IMS_ROAMING_ENABLED = "wfc_ims_roaming_enabled";
-    field public static final String WFC_IMS_ROAMING_MODE = "wfc_ims_roaming_mode";
-  }
-
   public static final class Telephony.Sms.Intents {
     field public static final String ACTION_SMS_EMERGENCY_CB_RECEIVED = "android.provider.action.SMS_EMERGENCY_CB_RECEIVED";
   }
@@ -7129,7 +6926,7 @@
 package android.se.omapi {
 
   public final class Reader {
-    method @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED) public boolean reset();
+    method @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION) public boolean reset();
   }
 
 }
@@ -7509,6 +7306,7 @@
   public abstract class EuiccService extends android.app.Service {
     ctor public EuiccService();
     method public void dump(@NonNull java.io.PrintWriter);
+    method public int encodeSmdxSubjectAndReasonCode(@NonNull String, @NonNull String);
     method @CallSuper public android.os.IBinder onBind(android.content.Intent);
     method public abstract int onDeleteSubscription(int, String);
     method public android.service.euicc.DownloadSubscriptionResult onDownloadSubscription(int, @NonNull android.telephony.euicc.DownloadableSubscription, boolean, boolean, @Nullable android.os.Bundle);
@@ -8209,6 +8007,11 @@
     field public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0; // 0x0
   }
 
+  public final class BarringInfo implements android.os.Parcelable {
+    ctor public BarringInfo();
+    method @NonNull public android.telephony.BarringInfo createLocationInfoSanitizedCopy();
+  }
+
   public final class CallAttributes implements android.os.Parcelable {
     ctor public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality);
     method public int describeContents();
@@ -8219,27 +8022,6 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
   }
 
-  public final class CallForwardingInfo implements android.os.Parcelable {
-    ctor public CallForwardingInfo(int, int, @Nullable String, int);
-    method public int describeContents();
-    method @Nullable public String getNumber();
-    method public int getReason();
-    method public int getStatus();
-    method public int getTimeoutSeconds();
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallForwardingInfo> CREATOR;
-    field public static final int REASON_ALL = 4; // 0x4
-    field public static final int REASON_ALL_CONDITIONAL = 5; // 0x5
-    field public static final int REASON_BUSY = 1; // 0x1
-    field public static final int REASON_NOT_REACHABLE = 3; // 0x3
-    field public static final int REASON_NO_REPLY = 2; // 0x2
-    field public static final int REASON_UNCONDITIONAL = 0; // 0x0
-    field public static final int STATUS_ACTIVE = 1; // 0x1
-    field public static final int STATUS_FDN_CHECK_FAILURE = 2; // 0x2
-    field public static final int STATUS_INACTIVE = 0; // 0x0
-    field public static final int STATUS_NOT_SUPPORTED = 4; // 0x4
-    field public static final int STATUS_UNKNOWN_ERROR = 3; // 0x3
-  }
-
   public final class CallQuality implements android.os.Parcelable {
     ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int);
     ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int, boolean, boolean, boolean);
@@ -8727,7 +8509,6 @@
   public final class DataSpecificRegistrationInfo implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
-    method public boolean isUsingCarrierAggregation();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
   }
@@ -8884,6 +8665,7 @@
     method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
     method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int);
     method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String);
     method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int);
     method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int);
     method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int);
@@ -8948,7 +8730,6 @@
     method public void onRadioPowerStateChanged(int);
     method public void onSrvccStateChanged(int);
     method public void onVoiceActivationStateChanged(int);
-    field @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) public static final int LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH = 512; // 0x200
     field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000
     field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
     field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
@@ -8958,19 +8739,6 @@
     field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000
   }
 
-  public final class PinResult implements android.os.Parcelable {
-    ctor public PinResult(int, int);
-    method public int describeContents();
-    method public int getAttemptsRemaining();
-    method @NonNull public static android.telephony.PinResult getDefaultFailedResult();
-    method public int getType();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PinResult> CREATOR;
-    field public static final int PIN_RESULT_TYPE_FAILURE = 2; // 0x2
-    field public static final int PIN_RESULT_TYPE_INCORRECT = 1; // 0x1
-    field public static final int PIN_RESULT_TYPE_SUCCESS = 0; // 0x0
-  }
-
   public final class PreciseCallState implements android.os.Parcelable {
     ctor public PreciseCallState(int, int, int, int, int);
     method public int describeContents();
@@ -8992,7 +8760,6 @@
   }
 
   public final class PreciseDataConnectionState implements android.os.Parcelable {
-    ctor public PreciseDataConnectionState(int, int, int, @NonNull String, @Nullable android.net.LinkProperties, int, @Nullable android.telephony.data.ApnSetting);
     method @Deprecated @NonNull public String getDataConnectionApn();
     method @Deprecated public int getDataConnectionApnTypeBitMask();
     method @Deprecated public int getDataConnectionFailCause();
@@ -9099,15 +8866,12 @@
   }
 
   public class ServiceState implements android.os.Parcelable {
-    method @NonNull public android.telephony.ServiceState createLocationInfoSanitizedCopy(boolean);
     method public void fillInNotifierBundle(@NonNull android.os.Bundle);
     method public int getDataNetworkType();
-    method public int getDataRegistrationState();
     method public boolean getDataRoamingFromRegistration();
     method @Nullable public android.telephony.NetworkRegistrationInfo getNetworkRegistrationInfo(int, int);
     method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int);
     method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int);
-    method public int getNrFrequencyRange();
     method @Nullable public String getOperatorAlphaLongRaw();
     method @Nullable public String getOperatorAlphaShortRaw();
     method @NonNull public static android.telephony.ServiceState newFromBundle(@NonNull android.os.Bundle);
@@ -9251,7 +9015,8 @@
     method public boolean enableCellBroadcastRange(int, int, int);
     method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public java.util.List<android.telephony.SmsMessage> getMessagesFromIcc();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSmsCapacityOnIcc();
-    method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
+    method @Deprecated public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
+    method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String, @Nullable String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>);
   }
 
@@ -9269,7 +9034,7 @@
 
   public class SubscriptionManager {
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean canDisablePhysicalSubscription();
-    method public boolean canManageSubscription(@Nullable android.telephony.SubscriptionInfo, @Nullable String);
+    method public boolean canManageSubscription(@NonNull android.telephony.SubscriptionInfo, @NonNull String);
     method @NonNull public int[] getActiveAndHiddenSubscriptionIdList();
     method @NonNull public int[] getActiveSubscriptionIdList();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String);
@@ -9284,10 +9049,10 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSubscriptionEnabled(int, boolean);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUiccApplicationsEnabled(boolean, int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUiccApplicationsEnabled(int, boolean);
     field @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS) public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED";
     field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI;
-    field public static final int PROFILE_CLASS_DEFAULT = -1; // 0xffffffff
+    field @Deprecated public static final int PROFILE_CLASS_DEFAULT = -1; // 0xffffffff
     field public static final int PROFILE_CLASS_OPERATIONAL = 2; // 0x2
     field public static final int PROFILE_CLASS_PROVISIONING = 1; // 0x1
     field public static final int PROFILE_CLASS_TESTING = 0; // 0x0
@@ -9328,7 +9093,6 @@
   public class TelephonyManager {
     method public int addDevicePolicyOverrideApn(@NonNull android.content.Context, @NonNull android.telephony.data.ApnSetting);
     method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int changeIccLockPassword(@NonNull String, @NonNull String);
     method public int checkCarrierPrivilegesForPackage(String);
     method public int checkCarrierPrivilegesForPackageAnyPhone(String);
     method public void dial(String);
@@ -9339,8 +9103,6 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getAidForAppType(int);
     method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getAllowedNetworkTypes();
-    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CallForwardingInfo getCallForwarding(int);
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCallWaitingStatus();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
@@ -9352,7 +9114,6 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(int);
     method public String getCdmaPrlVersion();
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaRoamingMode();
     method public int getCurrentPhoneType();
     method public int getCurrentPhoneType(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getDataActivationState();
@@ -9362,14 +9123,13 @@
     method @NonNull public java.util.List<android.telephony.data.ApnSetting> getDevicePolicyOverrideApns(@NonNull android.content.Context);
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
-    method public int getEmergencyNumberDbVersion();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String[] getIsimImpu();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping();
     method public int getMaxNumberOfSimultaneouslyActiveSims();
     method public static long getMaxNumberVerificationTimeoutMillis();
-    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getNetworkCountryIso(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getPreferredNetworkTypeBitmask();
     method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public int getRadioPowerState();
     method public int getSimApplicationState();
@@ -9391,13 +9151,11 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAnyRadioPoweredOn();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int);
     method public boolean isCurrentSimOperator(@NonNull String, int, @Nullable String);
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataAllowedInVoiceCall();
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataConnectionEnabled();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataConnectionAllowed();
     method public boolean isDataConnectivityPossible();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isGlobalModeEnabled();
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean isIccLockEnabled();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isInEmergencySmsMode();
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isManualNetworkSelectionAllowed();
@@ -9421,25 +9179,18 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetAllCarrierActions();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void resetIms(int);
+    method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void resetOtaEmergencyNumberDbFilePath();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig();
     method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void resetSettings();
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAllowedNetworkTypes(long);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAlwaysAllowMmsData(boolean);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAlwaysReportSignalStrength(boolean);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallForwarding(@NonNull android.telephony.CallForwardingInfo);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallWaitingStatus(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCdmaRoamingMode(int);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCdmaSubscriptionMode(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setDataAllowedDuringVoiceCall(boolean);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setIccLockEnabled(boolean, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setNetworkSelectionModeManual(@NonNull String, int, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
@@ -9453,15 +9204,13 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoiceActivationState(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void shutdownAllRadios();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPin(String);
-    method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult supplyPinReportPinResult(@NonNull String);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPinReportResult(String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPuk(String, String);
-    method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult supplyPukReportPinResult(@NonNull String, @NonNull String);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff();
+    method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor);
     method public void updateServiceLocation();
-    method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateTestOtaEmergencyNumberDbFilePath(@NonNull String);
     field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_ANOMALY_REPORTED = "android.telephony.action.ANOMALY_REPORTED";
     field public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE";
     field public static final String ACTION_CARRIER_SIGNAL_PCO_VALUE = "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE";
@@ -9475,10 +9224,6 @@
     field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED";
     field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED";
     field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED";
-    field public static final int CALL_WAITING_STATUS_ACTIVE = 1; // 0x1
-    field public static final int CALL_WAITING_STATUS_INACTIVE = 2; // 0x2
-    field public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4; // 0x4
-    field public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3; // 0x3
     field public static final int CARD_POWER_DOWN = 0; // 0x0
     field public static final int CARD_POWER_UP = 1; // 0x1
     field public static final int CARD_POWER_UP_PASS_THROUGH = 2; // 0x2
@@ -9486,10 +9231,6 @@
     field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
     field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
     field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff
-    field public static final int CDMA_SUBSCRIPTION_NV = 1; // 0x1
-    field public static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // 0x0
-    field public static final int CDMA_SUBSCRIPTION_UNKNOWN = -1; // 0xffffffff
-    field public static final int CHANGE_ICC_LOCK_SUCCESS = 2147483647; // 0x7fffffff
     field public static final String EXTRA_ANOMALY_DESCRIPTION = "android.telephony.extra.ANOMALY_DESCRIPTION";
     field public static final String EXTRA_ANOMALY_ID = "android.telephony.extra.ANOMALY_ID";
     field @Deprecated public static final String EXTRA_APN_PROTOCOL = "apnProto";
@@ -9545,7 +9286,6 @@
     field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L
     field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L
     field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L
-    field public static final int PHONE_TYPE_THIRD_PARTY = 4; // 0x4
     field public static final int RADIO_POWER_OFF = 0; // 0x0
     field public static final int RADIO_POWER_ON = 1; // 0x1
     field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2
@@ -9625,23 +9365,6 @@
 
 package android.telephony.data {
 
-  public class ApnSetting implements android.os.Parcelable {
-    method @NonNull public static String getApnTypesStringFromBitmask(int);
-    field public static final String TYPE_ALL_STRING = "*";
-    field public static final String TYPE_CBS_STRING = "cbs";
-    field public static final String TYPE_DEFAULT_STRING = "default";
-    field public static final String TYPE_DUN_STRING = "dun";
-    field public static final String TYPE_EMERGENCY_STRING = "emergency";
-    field public static final String TYPE_FOTA_STRING = "fota";
-    field public static final String TYPE_HIPRI_STRING = "hipri";
-    field public static final String TYPE_IA_STRING = "ia";
-    field public static final String TYPE_IMS_STRING = "ims";
-    field public static final String TYPE_MCX_STRING = "mcx";
-    field public static final String TYPE_MMS_STRING = "mms";
-    field public static final String TYPE_SUPL_STRING = "supl";
-    field public static final String TYPE_XCAP_STRING = "xcap";
-  }
-
   public final class DataCallResponse implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public java.util.List<android.net.LinkAddress> getAddresses();
@@ -9967,7 +9690,7 @@
     method public int getEmergencyServiceCategories();
     method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
     method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
-    method @Nullable public android.os.Bundle getProprietaryCallExtras();
+    method @NonNull public android.os.Bundle getProprietaryCallExtras();
     method public int getRestrictCause();
     method public int getServiceType();
     method public static int getVideoStateFromCallType(int);
@@ -10128,7 +9851,6 @@
   }
 
   public class ImsManager {
-    method @NonNull public android.telephony.ims.ImsRcsManager getImsRcsManager(int);
     field public static final String ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION = "com.android.internal.intent.action.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION";
   }
 
@@ -10156,10 +9878,6 @@
     ctor @Deprecated public ImsMmTelManager.RegistrationCallback();
   }
 
-  public class ImsRcsManager implements android.telephony.ims.RegistrationManager {
-    method @NonNull public android.telephony.ims.RcsUceAdapter getUceAdapter();
-  }
-
   public final class ImsReasonInfo implements android.os.Parcelable {
     field public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED = "Forbidden. Not Authorized for Service";
   }
@@ -10428,8 +10146,8 @@
     field public static final int KEY_RCS_CAPABILITY_DISCOVERY_ENABLED = 17; // 0x11
     field public static final int KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC = 23; // 0x17
     field public static final int KEY_RCS_MAX_NUM_ENTRIES_IN_RCL = 22; // 0x16
+    field public static final int KEY_RCS_PUBLISH_OFFLINE_AVAILABILITY_TIMER_SEC = 16; // 0x10
     field public static final int KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS = 21; // 0x15
-    field public static final int KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC = 16; // 0x10
     field public static final int KEY_RCS_PUBLISH_TIMER_SEC = 15; // 0xf
     field public static final int KEY_REGISTRATION_DOMAIN_NAME = 12; // 0xc
     field public static final int KEY_REGISTRATION_RETRY_BASE_TIME_SEC = 33; // 0x21
@@ -10536,7 +10254,6 @@
   }
 
   public class RcsUceAdapter {
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isUceSettingEnabled() throws android.telephony.ims.ImsException;
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
   }
 
diff --git a/api/system-lint-baseline.txt b/api/system-lint-baseline.txt
index d2b3a64..306b8af 100644
--- a/api/system-lint-baseline.txt
+++ b/api/system-lint-baseline.txt
@@ -165,12 +165,6 @@
 PublicTypedef: android.content.integrity.Rule.Effect: Don't expose @IntDef: @Effect must be hidden.
 
 
-ResourceValueFieldName: android.R.array#config_sms_enabled_locking_shift_tables:
-    Expected resource name in `android.R.array` to be in the `fooBarBaz` style, was `config_sms_enabled_locking_shift_tables`
-ResourceValueFieldName: android.R.array#config_sms_enabled_single_shift_tables:
-    Expected resource name in `android.R.array` to be in the `fooBarBaz` style, was `config_sms_enabled_single_shift_tables`
-
-
 SamShouldBeLast: android.accounts.AccountManager#addAccount(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
     
 SamShouldBeLast: android.accounts.AccountManager#addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean):
diff --git a/api/test-current.txt b/api/test-current.txt
index 0c7db06..9ed451c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -657,7 +657,6 @@
     field public static final String BUGREPORT_SERVICE = "bugreport";
     field public static final String CONTENT_CAPTURE_MANAGER_SERVICE = "content_capture";
     field public static final String ETHERNET_SERVICE = "ethernet";
-    field public static final String NETWORK_STACK_SERVICE = "network_stack";
     field public static final String PERMISSION_SERVICE = "permission";
     field public static final String ROLLBACK_SERVICE = "rollback";
     field public static final String STATUS_BAR_SERVICE = "statusbar";
@@ -1441,6 +1440,7 @@
 
   public class EthernetManager {
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public android.net.EthernetManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.TetheredInterfaceCallback);
+    method public void setIncludeTestInterfaces(boolean);
   }
 
   public static interface EthernetManager.TetheredInterfaceCallback {
@@ -1477,6 +1477,7 @@
 
   public final class LinkProperties implements android.os.Parcelable {
     ctor public LinkProperties(@Nullable android.net.LinkProperties);
+    ctor public LinkProperties(@Nullable android.net.LinkProperties, boolean);
     method public boolean addDnsServer(@NonNull java.net.InetAddress);
     method public boolean addLinkAddress(@NonNull android.net.LinkAddress);
     method @Nullable public android.net.Uri getCaptivePortalApiUrl();
@@ -1491,7 +1492,6 @@
     method public boolean isIpv6Provisioned();
     method public boolean isProvisioned();
     method public boolean isReachable(@NonNull java.net.InetAddress);
-    method @NonNull public android.net.LinkProperties makeSensitiveFieldsParcelingCopy();
     method public boolean removeDnsServer(@NonNull java.net.InetAddress);
     method public boolean removeLinkAddress(@NonNull android.net.LinkAddress);
     method public boolean removeRoute(@NonNull android.net.RouteInfo);
@@ -1506,17 +1506,42 @@
 
   public class Network implements android.os.Parcelable {
     ctor public Network(@NonNull android.net.Network);
+    method public int getNetId();
     method @NonNull public android.net.Network getPrivateDnsBypassingCopy();
   }
 
   public final class NetworkCapabilities implements android.os.Parcelable {
+    method @NonNull public int[] getAdministratorUids();
     method public int[] getCapabilities();
+    method @Nullable public String getSsid();
     method @NonNull public int[] getTransportTypes();
     method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
     field public static final int TRANSPORT_TEST = 7; // 0x7
   }
 
+  public static class NetworkCapabilities.Builder {
+    ctor public NetworkCapabilities.Builder();
+    ctor public NetworkCapabilities.Builder(@NonNull android.net.NetworkCapabilities);
+    method @NonNull public android.net.NetworkCapabilities.Builder addCapability(int);
+    method @NonNull public android.net.NetworkCapabilities.Builder addTransportType(int);
+    method @NonNull public android.net.NetworkCapabilities build();
+    method @NonNull public android.net.NetworkCapabilities.Builder removeCapability(int);
+    method @NonNull public android.net.NetworkCapabilities.Builder removeTransportType(int);
+    method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setAdministratorUids(@NonNull int[]);
+    method @NonNull public android.net.NetworkCapabilities.Builder setLinkDownstreamBandwidthKbps(int);
+    method @NonNull public android.net.NetworkCapabilities.Builder setLinkUpstreamBandwidthKbps(int);
+    method @NonNull public android.net.NetworkCapabilities.Builder setNetworkSpecifier(@Nullable android.net.NetworkSpecifier);
+    method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setOwnerUid(int);
+    method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setRequestorPackageName(@Nullable String);
+    method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setRequestorUid(int);
+    method @NonNull @RequiresPermission("android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP") public android.net.NetworkCapabilities.Builder setSignalStrength(int);
+    method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setSsid(@Nullable String);
+    method @NonNull public android.net.NetworkCapabilities.Builder setTransportInfo(@Nullable android.net.TransportInfo);
+  }
+
   public class NetworkStack {
+    method @Nullable public static android.os.IBinder getService();
+    method public static void setServiceForTest(@Nullable android.os.IBinder);
     field public static final String PERMISSION_MAINLINE_NETWORK_STACK = "android.permission.MAINLINE_NETWORK_STACK";
   }
 
@@ -1590,7 +1615,6 @@
     method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
     method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
     method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
-    method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
     method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
     method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
     method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
@@ -1607,19 +1631,20 @@
     field public static final int TETHERING_WIFI = 0; // 0x0
     field public static final int TETHERING_WIFI_P2P = 3; // 0x3
     field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc
-    field public static final int TETHER_ERROR_DISABLE_NAT_ERROR = 9; // 0x9
-    field public static final int TETHER_ERROR_ENABLE_NAT_ERROR = 8; // 0x8
+    field public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; // 0x9
+    field public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; // 0x8
     field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd
     field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa
-    field public static final int TETHER_ERROR_MASTER_ERROR = 5; // 0x5
+    field public static final int TETHER_ERROR_INTERNAL_ERROR = 5; // 0x5
     field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf
     field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe
     field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
-    field public static final int TETHER_ERROR_PROVISION_FAILED = 11; // 0xb
+    field public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; // 0xb
     field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2
     field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6
     field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4
     field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1
+    field public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; // 0x10
     field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3
     field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7
     field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2
@@ -1631,40 +1656,35 @@
     method public void onTetheringEntitlementResult(int);
   }
 
-  public abstract static class TetheringManager.StartTetheringCallback {
-    ctor public TetheringManager.StartTetheringCallback();
-    method public void onTetheringFailed(int);
-    method public void onTetheringStarted();
+  public static interface TetheringManager.StartTetheringCallback {
+    method public default void onTetheringFailed(int);
+    method public default void onTetheringStarted();
   }
 
-  public abstract static class TetheringManager.TetheringEventCallback {
-    ctor public TetheringManager.TetheringEventCallback();
-    method public void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
-    method public void onError(@NonNull String, int);
-    method public void onOffloadStatusChanged(int);
-    method @Deprecated public void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps);
-    method public void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
-    method public void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>);
-    method public void onTetheringSupported(boolean);
-    method public void onUpstreamChanged(@Nullable android.net.Network);
-  }
-
-  @Deprecated public static class TetheringManager.TetheringInterfaceRegexps {
-    ctor @Deprecated public TetheringManager.TetheringInterfaceRegexps(@NonNull String[], @NonNull String[], @NonNull String[]);
-    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs();
-    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs();
-    method @Deprecated @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs();
+  public static interface TetheringManager.TetheringEventCallback {
+    method public default void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
+    method public default void onError(@NonNull String, int);
+    method public default void onOffloadStatusChanged(int);
+    method public default void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+    method public default void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+    method public default void onTetheringSupported(boolean);
+    method public default void onUpstreamChanged(@Nullable android.net.Network);
   }
 
   public static class TetheringManager.TetheringRequest {
+    method @Nullable public android.net.LinkAddress getClientStaticIpv4Address();
+    method @Nullable public android.net.LinkAddress getLocalIpv4Address();
+    method public boolean getShouldShowEntitlementUi();
+    method public int getTetheringType();
+    method public boolean isExemptFromEntitlementCheck();
   }
 
   public static class TetheringManager.TetheringRequest.Builder {
     ctor public TetheringManager.TetheringRequest.Builder(int);
     method @NonNull public android.net.TetheringManager.TetheringRequest build();
     method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean);
-    method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setSilentProvisioning(boolean);
-    method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder useStaticIpv4Addresses(@NonNull android.net.LinkAddress);
+    method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean);
+    method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress);
   }
 
   public class TrafficStats {
@@ -3095,6 +3115,15 @@
     field public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0; // 0x0
   }
 
+  public final class BarringInfo implements android.os.Parcelable {
+    ctor public BarringInfo();
+    ctor public BarringInfo(@Nullable android.telephony.CellIdentity, @NonNull android.util.SparseArray<android.telephony.BarringInfo.BarringServiceInfo>);
+  }
+
+  public static final class BarringInfo.BarringServiceInfo implements android.os.Parcelable {
+    ctor public BarringInfo.BarringServiceInfo(int, boolean, int, int);
+  }
+
   public final class CallQuality implements android.os.Parcelable {
     ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int);
     ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int, boolean, boolean, boolean);
@@ -3181,6 +3210,7 @@
     method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
     method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int);
     method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String);
     method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int);
     method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int);
     method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int);
@@ -3219,7 +3249,8 @@
 
   public final class SmsManager {
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int checkSmsShortCodeDestination(String, String);
-    method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
+    method @Deprecated public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
+    method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String, @Nullable String);
     field public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1; // 0x1
     field public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0; // 0x0
     field public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3; // 0x3
@@ -3244,17 +3275,17 @@
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
     method @Nullable public static android.content.ComponentName getDefaultRespondViaMessageApplication(@NonNull android.content.Context, boolean);
     method @NonNull public java.util.List<android.telephony.data.ApnSetting> getDevicePolicyOverrideApns(@NonNull android.content.Context);
-    method public int getEmergencyNumberDbVersion();
+    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getEmergencyNumberDbVersion();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getLine1AlphaTag();
-    method @NonNull @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getNetworkCountryIso(int);
     method public android.util.Pair<java.lang.Integer,java.lang.Integer> getRadioHalVersion();
     method public boolean modifyDevicePolicyOverrideApn(@NonNull android.content.Context, int, @NonNull android.telephony.data.ApnSetting);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void refreshUiccProfile();
+    method @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public void resetOtaEmergencyNumberDbFilePath();
     method @Deprecated public void setCarrierTestOverride(String, String, String, String, String, String, String);
     method public void setCarrierTestOverride(String, String, String, String, String, String, String, String, String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>);
-    method @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public void updateTestOtaEmergencyNumberDbFilePath(@NonNull String);
+    method @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor);
     field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
     field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
     field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
@@ -3318,7 +3349,7 @@
     method public int getEmergencyServiceCategories();
     method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
     method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
-    method @Nullable public android.os.Bundle getProprietaryCallExtras();
+    method @NonNull public android.os.Bundle getProprietaryCallExtras();
     method public int getRestrictCause();
     method public int getServiceType();
     method public static int getVideoStateFromCallType(int);
@@ -3480,7 +3511,6 @@
   }
 
   public class ImsManager {
-    method @NonNull public android.telephony.ims.ImsRcsManager getImsRcsManager(int);
     field public static final String ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION = "com.android.internal.intent.action.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION";
   }
 
@@ -3508,10 +3538,6 @@
     ctor @Deprecated public ImsMmTelManager.RegistrationCallback();
   }
 
-  public class ImsRcsManager implements android.telephony.ims.RegistrationManager {
-    method @NonNull public android.telephony.ims.RcsUceAdapter getUceAdapter();
-  }
-
   public class ImsService extends android.app.Service {
     ctor public ImsService();
     method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int);
@@ -3776,8 +3802,8 @@
     field public static final int KEY_RCS_CAPABILITY_DISCOVERY_ENABLED = 17; // 0x11
     field public static final int KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC = 23; // 0x17
     field public static final int KEY_RCS_MAX_NUM_ENTRIES_IN_RCL = 22; // 0x16
+    field public static final int KEY_RCS_PUBLISH_OFFLINE_AVAILABILITY_TIMER_SEC = 16; // 0x10
     field public static final int KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS = 21; // 0x15
-    field public static final int KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC = 16; // 0x10
     field public static final int KEY_RCS_PUBLISH_TIMER_SEC = 15; // 0xf
     field public static final int KEY_REGISTRATION_DOMAIN_NAME = 12; // 0xc
     field public static final int KEY_REGISTRATION_RETRY_BASE_TIME_SEC = 33; // 0x21
@@ -3884,7 +3910,6 @@
   }
 
   public class RcsUceAdapter {
-    method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isUceSettingEnabled() throws android.telephony.ims.ImsException;
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
   }
 
diff --git a/cmds/idmap2/idmap2/Create.cpp b/cmds/idmap2/idmap2/Create.cpp
index bb8d927..f482191 100644
--- a/cmds/idmap2/idmap2/Create.cpp
+++ b/cmds/idmap2/idmap2/Create.cpp
@@ -50,7 +50,7 @@
   std::string overlay_apk_path;
   std::string idmap_path;
   std::vector<std::string> policies;
-  bool ignore_overlayable;
+  bool ignore_overlayable = false;
 
   const CommandLineOptions opts =
       CommandLineOptions("idmap2 create")
diff --git a/cmds/idmap2/idmap2/Dump.cpp b/cmds/idmap2/idmap2/Dump.cpp
index 8716bf3..47f442a 100644
--- a/cmds/idmap2/idmap2/Dump.cpp
+++ b/cmds/idmap2/idmap2/Dump.cpp
@@ -39,7 +39,7 @@
 Result<Unit> Dump(const std::vector<std::string>& args) {
   SYSTRACE << "Dump " << args;
   std::string idmap_path;
-  bool verbose;
+  bool verbose = false;
 
   const CommandLineOptions opts =
       CommandLineOptions("idmap2 dump")
diff --git a/cmds/idmap2/tests/Idmap2BinaryTests.cpp b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
index 8a48f4b..499eb99 100644
--- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp
+++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
@@ -131,7 +131,6 @@
   ASSERT_NE(result->stdout.find("0x7f02000c -> 0x7f020000 string/str1"), std::string::npos);
   ASSERT_NE(result->stdout.find("0x7f02000e -> 0x7f020001 string/str3"), std::string::npos);
   ASSERT_NE(result->stdout.find("0x7f02000f -> 0x7f020002 string/str4"), std::string::npos);
-  ASSERT_EQ(result->stdout.find("00000210:     007f  target package id"), std::string::npos);
 
   // clang-format off
   result = ExecuteBinary({"idmap2",
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index f476fcf..1cc761f 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -512,8 +512,8 @@
     // Open log buffer and getting logs since last retrieved time if any.
     unique_ptr<logger_list, void (*)(logger_list*)> loggers(
             gLastLogsRetrieved.find(mLogID) == gLastLogsRetrieved.end()
-                    ? android_logger_list_alloc(ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, 0)
-                    : android_logger_list_alloc_time(ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
+                    ? android_logger_list_alloc(ANDROID_LOG_NONBLOCK, 0, 0)
+                    : android_logger_list_alloc_time(ANDROID_LOG_NONBLOCK,
                                                      gLastLogsRetrieved[mLogID], 0),
             android_logger_list_free);
 
diff --git a/config/preloaded-classes b/config/preloaded-classes
index eb3879f..b05d02c 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -7438,6 +7438,7 @@
 sun.nio.fs.NativeBuffer$Deallocator
 sun.nio.fs.NativeBuffer
 sun.nio.fs.NativeBuffers
+sun.nio.fs.UnixChannelFactory
 sun.nio.fs.UnixChannelFactory$Flags
 sun.nio.fs.UnixConstants
 sun.nio.fs.UnixException
diff --git a/config/preloaded-classes-blacklist b/config/preloaded-classes-blacklist
index 7cfde8a..5e54559 100644
--- a/config/preloaded-classes-blacklist
+++ b/config/preloaded-classes-blacklist
@@ -4,4 +4,4 @@
 android.os.FileObserver
 android.speech.tts.TextToSpeech$Connection$SetupConnectionAsyncTask
 android.widget.Magnifier
-sun.nio.fs.UnixChannelFactory
+
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index ae1b0cc..9d63bc2 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -3880,7 +3880,6 @@
      *         {@code false} otherwise.
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION)
     public boolean updateMccMncConfiguration(@NonNull String mcc, @NonNull String mnc) {
         if (mcc == null || mnc == null) {
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 2a72d43..71b2773 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -797,6 +797,11 @@
         makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths);
 
         String libraryPermittedPath = mDataDir;
+        if (mActivityThread == null) {
+            // In a zygote context where mActivityThread is null we can't access the app data dir
+            // and including this in libraryPermittedPath would cause SELinux denials.
+            libraryPermittedPath = "";
+        }
 
         if (isBundledApp) {
             // For bundled apps, add the base directory of the app (e.g.,
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 7a736d6..4d972b1 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -347,14 +347,6 @@
             }
         });
 
-        registerService(Context.NETWORK_STACK_SERVICE, IBinder.class,
-                new StaticServiceFetcher<IBinder>() {
-                    @Override
-                    public IBinder createService() {
-                        return ServiceManager.getService(Context.NETWORK_STACK_SERVICE);
-                    }
-                });
-
         registerService(Context.TETHERING_SERVICE, TetheringManager.class,
                 new CachedServiceFetcher<TetheringManager>() {
             @Override
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 5afd82f..dee013c 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -5311,6 +5311,10 @@
         throwIfParentInstance("isAlwaysOnVpnLockdownEnabled");
         if (mService != null) {
             try {
+                // Starting from Android R, the caller can pass the permission check in
+                // DevicePolicyManagerService if it holds android.permission.MAINLINE_NETWORK_STACK.
+                // Note that the android.permission.MAINLINE_NETWORK_STACK is a signature permission
+                // which is used by the NetworkStack mainline module.
                 return mService.isAlwaysOnVpnLockdownEnabled(admin);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
diff --git a/core/java/android/app/compat/CompatChanges.java b/core/java/android/app/compat/CompatChanges.java
index e289a27..6689507 100644
--- a/core/java/android/app/compat/CompatChanges.java
+++ b/core/java/android/app/compat/CompatChanges.java
@@ -17,6 +17,7 @@
 package android.app.compat;
 
 import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.compat.Compatibility;
 import android.content.Context;
@@ -59,14 +60,13 @@
      * <p> Note that this involves a binder call to the system server (unless running in the system
      * server). If the binder call fails, a {@code RuntimeException} will be thrown.
      *
-     * <p> Caller must have android.permission.READ_COMPAT_CHANGE_CONFIG permission. If it
-     * doesn't, a {@code RuntimeException} will be thrown.
-     *
      * @param changeId    The ID of the compatibility change in question.
      * @param packageName The package name of the app in question.
      * @param user        The user that the operation is done for.
      * @return {@code true} if the change is enabled for the current app.
      */
+    @RequiresPermission(allOf = {android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG,
+            android.Manifest.permission.LOG_COMPAT_CHANGE})
     public static boolean isChangeEnabled(long changeId, @NonNull String packageName,
             @NonNull UserHandle user) {
         IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
@@ -89,9 +89,6 @@
      * <p> Note that this involves a binder call to the system server (unless running in the system
      * server). If the binder call fails, {@code RuntimeException}  will be thrown.
      *
-     * <p> Caller must have android.permission.READ_COMPAT_CHANGE_CONFIG permission. If it
-     * doesn't, a {@code RuntimeException} will be thrown.
-     *
      * <p> Returns {@code true} if there are no installed packages for the required UID, or if the
      * change is enabled for ALL of the installed packages associated with the provided UID. Please
      * use a more specific API if you want a different behaviour for multi-package UIDs.
@@ -100,6 +97,8 @@
      * @param uid      The UID of the app in question.
      * @return {@code true} if the change is enabled for the current app.
      */
+    @RequiresPermission(allOf = {android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG,
+            android.Manifest.permission.LOG_COMPAT_CHANGE})
     public static boolean isChangeEnabled(long changeId, int uid) {
         IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
                 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
diff --git a/core/java/android/app/role/OWNERS b/core/java/android/app/role/OWNERS
new file mode 100644
index 0000000..b94d988
--- /dev/null
+++ b/core/java/android/app/role/OWNERS
@@ -0,0 +1,6 @@
+svetoslavganov@google.com
+moltmann@google.com
+zhanghai@google.com
+evanseverson@google.com
+eugenesusla@google.com
+ntmyren@google.com
diff --git a/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java b/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java
index 22e2efb..002c663 100644
--- a/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java
+++ b/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java
@@ -30,7 +30,7 @@
 import java.util.Objects;
 
 /**
- * A time signal from a manual (user provided) source.
+ * A time zone suggestion from a manual (user provided) source.
  *
  * <p>{@code zoneId} contains the suggested time zone ID, e.g. "America/Los_Angeles".
  *
@@ -124,7 +124,7 @@
 
     @Override
     public String toString() {
-        return "ManualTimeSuggestion{"
+        return "ManualTimeZoneSuggestion{"
                 + "mZoneId=" + mZoneId
                 + ", mDebugInfo=" + mDebugInfo
                 + '}';
diff --git a/core/java/android/app/timezonedetector/TimeZoneDetector.java b/core/java/android/app/timezonedetector/TimeZoneDetector.java
index 20761ad..34a7586 100644
--- a/core/java/android/app/timezonedetector/TimeZoneDetector.java
+++ b/core/java/android/app/timezonedetector/TimeZoneDetector.java
@@ -41,6 +41,15 @@
     }
 
     /**
+     * Suggests the current time zone, determined using the user's manually entered information, to
+     * the detector. The detector may ignore the signal based on system settings.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE)
+    void suggestManualTimeZone(@NonNull ManualTimeZoneSuggestion timeZoneSuggestion);
+
+    /**
      * Suggests the current time zone, determined using telephony signals, to the detector. The
      * detector may ignore the signal based on system settings, whether better information is
      * available, and so on.
@@ -49,13 +58,4 @@
      */
     @RequiresPermission(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE)
     void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion timeZoneSuggestion);
-
-    /**
-     * Suggests the current time zone, determined for the user's manually information, to the
-     * detector. The detector may ignore the signal based on system settings.
-     *
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE)
-    void suggestManualTimeZone(@NonNull ManualTimeZoneSuggestion timeZoneSuggestion);
 }
diff --git a/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java b/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java
index 0ada885..54cf1f3 100644
--- a/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java
+++ b/core/java/android/app/timezonedetector/TimeZoneDetectorImpl.java
@@ -40,18 +40,6 @@
     }
 
     @Override
-    public void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion timeZoneSuggestion) {
-        if (DEBUG) {
-            Log.d(TAG, "suggestTelephonyTimeZone called: " + timeZoneSuggestion);
-        }
-        try {
-            mITimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    @Override
     public void suggestManualTimeZone(@NonNull ManualTimeZoneSuggestion timeZoneSuggestion) {
         if (DEBUG) {
             Log.d(TAG, "suggestManualTimeZone called: " + timeZoneSuggestion);
@@ -62,4 +50,16 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    @Override
+    public void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion timeZoneSuggestion) {
+        if (DEBUG) {
+            Log.d(TAG, "suggestTelephonyTimeZone called: " + timeZoneSuggestion);
+        }
+        try {
+            mITimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index 5b98188..d6e7762 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -29,10 +29,10 @@
 import android.net.DataUsageRequest;
 import android.net.INetworkStatsService;
 import android.net.NetworkIdentity;
+import android.net.NetworkStack;
 import android.net.NetworkTemplate;
-import android.net.netstats.provider.AbstractNetworkStatsProvider;
-import android.net.netstats.provider.NetworkStatsProviderCallback;
-import android.net.netstats.provider.NetworkStatsProviderWrapper;
+import android.net.netstats.provider.INetworkStatsProviderCallback;
+import android.net.netstats.provider.NetworkStatsProvider;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.Looper;
@@ -527,32 +527,53 @@
 
     /**
      * Registers a custom provider of {@link android.net.NetworkStats} to provide network statistics
-     * to the system. To unregister, invoke {@link NetworkStatsProviderCallback#unregister()}.
+     * to the system. To unregister, invoke {@link #unregisterNetworkStatsProvider}.
      * Note that no de-duplication of statistics between providers is performed, so each provider
-     * must only report network traffic that is not being reported by any other provider.
+     * must only report network traffic that is not being reported by any other provider. Also note
+     * that the provider cannot be re-registered after unregistering.
      *
      * @param tag a human readable identifier of the custom network stats provider. This is only
      *            used for debugging.
-     * @param provider the subclass of {@link AbstractNetworkStatsProvider} that needs to be
+     * @param provider the subclass of {@link NetworkStatsProvider} that needs to be
      *                 registered to the system.
-     * @return a {@link NetworkStatsProviderCallback}, which can be used to report events to the
-     *         system or unregister the provider.
      * @hide
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
-    @NonNull public NetworkStatsProviderCallback registerNetworkStatsProvider(
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_STATS_PROVIDER,
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK})
+    @NonNull public void registerNetworkStatsProvider(
             @NonNull String tag,
-            @NonNull AbstractNetworkStatsProvider provider) {
+            @NonNull NetworkStatsProvider provider) {
         try {
-            final NetworkStatsProviderWrapper wrapper = new NetworkStatsProviderWrapper(provider);
-            return new NetworkStatsProviderCallback(
-                    mService.registerNetworkStatsProvider(tag, wrapper));
+            if (provider.getProviderCallbackBinder() != null) {
+                throw new IllegalArgumentException("provider is already registered");
+            }
+            final INetworkStatsProviderCallback cbBinder =
+                    mService.registerNetworkStatsProvider(tag, provider.getProviderBinder());
+            provider.setProviderCallbackBinder(cbBinder);
         } catch (RemoteException e) {
             e.rethrowAsRuntimeException();
         }
-        // Unreachable code, but compiler doesn't know about it.
-        return null;
+    }
+
+    /**
+     * Unregisters an instance of {@link NetworkStatsProvider}.
+     *
+     * @param provider the subclass of {@link NetworkStatsProvider} that needs to be
+     *                 unregistered to the system.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_STATS_PROVIDER,
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK})
+    @NonNull public void unregisterNetworkStatsProvider(@NonNull NetworkStatsProvider provider) {
+        try {
+            provider.getProviderCallbackBinderOrThrow().unregister();
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
     }
 
     private static NetworkTemplate createTemplate(int networkType, String subscriberId) {
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index d8c653c6..5374d6d 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -433,7 +433,7 @@
      * is active
      * @hide
      */
-    @SystemApi
+    @UnsupportedAppUsage
     @Nullable
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public BluetoothDevice getActiveDevice() {
@@ -462,7 +462,7 @@
      * @return true if priority is set, false on error
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
         return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
@@ -481,7 +481,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
             @ConnectionPolicy int connectionPolicy) {
         if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
@@ -517,7 +517,18 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public int getPriority(BluetoothDevice device) {
         if (VDBG) log("getPriority(" + device + ")");
-        return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
+        try {
+            final IBluetoothA2dp service = getService();
+            if (service != null && isEnabled()
+                    && isValidDevice(device)) {
+                return BluetoothAdapter.connectionPolicyToPriority(service.getPriority(device));
+            }
+            if (service == null) Log.w(TAG, "Proxy not attached to service");
+            return BluetoothProfile.PRIORITY_OFF;
+        } catch (RemoteException e) {
+            Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+            return BluetoothProfile.PRIORITY_OFF;
+        }
     }
 
     /**
@@ -532,7 +543,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
         if (VDBG) log("getConnectionPolicy(" + device + ")");
         try {
@@ -640,11 +651,12 @@
      * @return the current codec status
      * @hide
      */
-    @SystemApi
+    @UnsupportedAppUsage
     @Nullable
     @RequiresPermission(Manifest.permission.BLUETOOTH)
-    public BluetoothCodecStatus getCodecStatus(@Nullable BluetoothDevice device) {
+    public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
         if (DBG) Log.d(TAG, "getCodecStatus(" + device + ")");
+        verifyDeviceNotNull(device, "getCodecStatus");
         try {
             final IBluetoothA2dp service = getService();
             if (service != null && isEnabled()) {
@@ -668,11 +680,16 @@
      * @param codecConfig the codec configuration preference
      * @hide
      */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public void setCodecConfigPreference(@Nullable BluetoothDevice device,
-                                         @Nullable BluetoothCodecConfig codecConfig) {
+    @UnsupportedAppUsage
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    public void setCodecConfigPreference(@NonNull BluetoothDevice device,
+                                         @NonNull BluetoothCodecConfig codecConfig) {
         if (DBG) Log.d(TAG, "setCodecConfigPreference(" + device + ")");
+        verifyDeviceNotNull(device, "setCodecConfigPreference");
+        if (codecConfig == null) {
+            Log.e(TAG, "setCodecConfigPreference: Codec config can't be null");
+            throw new IllegalArgumentException("codecConfig cannot be null");
+        }
         try {
             final IBluetoothA2dp service = getService();
             if (service != null && isEnabled()) {
@@ -693,10 +710,11 @@
      * active A2DP Bluetooth device.
      * @hide
      */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public void enableOptionalCodecs(@Nullable BluetoothDevice device) {
+    @UnsupportedAppUsage
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    public void enableOptionalCodecs(@NonNull BluetoothDevice device) {
         if (DBG) Log.d(TAG, "enableOptionalCodecs(" + device + ")");
+        verifyDeviceNotNull(device, "enableOptionalCodecs");
         enableDisableOptionalCodecs(device, true);
     }
 
@@ -707,10 +725,11 @@
      * active A2DP Bluetooth device.
      * @hide
      */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public void disableOptionalCodecs(@Nullable BluetoothDevice device) {
+    @UnsupportedAppUsage
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    public void disableOptionalCodecs(@NonNull BluetoothDevice device) {
         if (DBG) Log.d(TAG, "disableOptionalCodecs(" + device + ")");
+        verifyDeviceNotNull(device, "disableOptionalCodecs");
         enableDisableOptionalCodecs(device, false);
     }
 
@@ -747,10 +766,11 @@
      * OPTIONAL_CODECS_SUPPORTED.
      * @hide
      */
-    @SystemApi
+    @UnsupportedAppUsage
     @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
     @OptionalCodecsSupportStatus
-    public int supportsOptionalCodecs(@Nullable BluetoothDevice device) {
+    public int isOptionalCodecsSupported(@NonNull BluetoothDevice device) {
+        verifyDeviceNotNull(device, "isOptionalCodecsSupported");
         try {
             final IBluetoothA2dp service = getService();
             if (service != null && isEnabled() && isValidDevice(device)) {
@@ -772,10 +792,11 @@
      * OPTIONAL_CODECS_PREF_DISABLED.
      * @hide
      */
-    @SystemApi
+    @UnsupportedAppUsage
     @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
     @OptionalCodecsPreferenceStatus
-    public int getOptionalCodecsEnabled(@Nullable BluetoothDevice device) {
+    public int isOptionalCodecsEnabled(@NonNull BluetoothDevice device) {
+        verifyDeviceNotNull(device, "isOptionalCodecsEnabled");
         try {
             final IBluetoothA2dp service = getService();
             if (service != null && isEnabled() && isValidDevice(device)) {
@@ -798,10 +819,11 @@
      * OPTIONAL_CODECS_PREF_DISABLED.
      * @hide
      */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public void setOptionalCodecsEnabled(@Nullable BluetoothDevice device,
+    @UnsupportedAppUsage
+    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    public void setOptionalCodecsEnabled(@NonNull BluetoothDevice device,
             @OptionalCodecsPreferenceStatus int value) {
+        verifyDeviceNotNull(device, "setOptionalCodecsEnabled");
         try {
             if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN
                     && value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED
@@ -854,6 +876,13 @@
         return false;
     }
 
+    private void verifyDeviceNotNull(BluetoothDevice device, String methodName) {
+        if (device == null) {
+            Log.e(TAG, methodName + ": device param is null");
+            throw new IllegalArgumentException("Device cannot be null");
+        }
+    }
+
     private boolean isValidDevice(BluetoothDevice device) {
         if (device == null) return false;
 
diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java
index ab49230..53f87e6 100755
--- a/core/java/android/bluetooth/BluetoothA2dpSink.java
+++ b/core/java/android/bluetooth/BluetoothA2dpSink.java
@@ -17,7 +17,7 @@
 package android.bluetooth;
 
 import android.Manifest;
-import android.annotation.Nullable;
+import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
@@ -120,7 +120,7 @@
      * @return false on immediate error, true otherwise
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean connect(BluetoothDevice device) {
         if (DBG) log("connect(" + device + ")");
         final IBluetoothA2dpSink service = getService();
@@ -277,7 +277,7 @@
      * @return true if priority is set, false on error
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
         return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
@@ -297,7 +297,7 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public boolean setConnectionPolicy(@Nullable BluetoothDevice device,
+    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
             @ConnectionPolicy int connectionPolicy) {
         if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
         final IBluetoothA2dpSink service = getService();
@@ -327,7 +327,7 @@
      * @return priority of the device
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public int getPriority(BluetoothDevice device) {
         if (VDBG) log("getPriority(" + device + ")");
         return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
@@ -346,7 +346,7 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public @ConnectionPolicy int getConnectionPolicy(@Nullable BluetoothDevice device) {
+    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
         if (VDBG) log("getConnectionPolicy(" + device + ")");
         final IBluetoothA2dpSink service = getService();
         if (service != null && isEnabled() && isValidDevice(device)) {
@@ -371,7 +371,7 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public boolean isAudioPlaying(@Nullable BluetoothDevice device) {
+    public boolean isAudioPlaying(@NonNull BluetoothDevice device) {
         final IBluetoothA2dpSink service = getService();
         if (service != null && isEnabled() && isValidDevice(device)) {
             try {
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 0a9dbb6..1508a65 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -916,23 +916,11 @@
         if (!isBleScanAlwaysAvailable()) {
             return false;
         }
-
-        int state = getLeState();
-        if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_BLE_ON) {
-            String packageName = ActivityThread.currentPackageName();
-            if (DBG) {
-                Log.d(TAG, "disableBLE(): de-registering " + packageName);
-            }
-            try {
-                mManagerService.updateBleAppCount(mToken, false, packageName);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-            }
-            return true;
-        }
-
-        if (DBG) {
-            Log.d(TAG, "disableBLE(): Already disabled");
+        String packageName = ActivityThread.currentPackageName();
+        try {
+            return mManagerService.disableBle(packageName, mToken);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
         }
         return false;
     }
@@ -973,20 +961,9 @@
         if (!isBleScanAlwaysAvailable()) {
             return false;
         }
-
+        String packageName = ActivityThread.currentPackageName();
         try {
-            String packageName = ActivityThread.currentPackageName();
-            mManagerService.updateBleAppCount(mToken, true, packageName);
-            if (isLeEnabled()) {
-                if (DBG) {
-                    Log.d(TAG, "enableBLE(): Bluetooth already enabled");
-                }
-                return true;
-            }
-            if (DBG) {
-                Log.d(TAG, "enableBLE(): Calling enable");
-            }
-            return mManagerService.enable(packageName);
+            return mManagerService.enableBle(packageName, mToken);
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
         }
@@ -1214,7 +1191,7 @@
      * @return true to indicate that the config file was successfully cleared
      * @hide
      */
-    @SystemApi
+    @UnsupportedAppUsage
     @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean factoryReset() {
         try {
@@ -1506,8 +1483,9 @@
      * @return true if the scan mode was set, false otherwise
      * @hide
      */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    @UnsupportedAppUsage(publicAlternatives = "Use {@link #ACTION_REQUEST_DISCOVERABLE}, which "
+            + "shows UI that confirms the user wants to go into discoverable mode.")
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
     public boolean setScanMode(@ScanMode int mode, long durationMillis) {
         if (getState() != STATE_ON) {
             return false;
@@ -1555,8 +1533,8 @@
      * @return true if the scan mode was set, false otherwise
      * @hide
      */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    @UnsupportedAppUsage
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
     public boolean setScanMode(@ScanMode int mode) {
         if (getState() != STATE_ON) {
             return false;
@@ -1620,7 +1598,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public long getDiscoveryEndMillis() {
         try {
             mServiceLock.readLock().lock();
@@ -1872,7 +1850,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean connectAllEnabledProfiles(@NonNull BluetoothDevice device) {
         try {
@@ -1901,7 +1878,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean disconnectAllEnabledProfiles(@NonNull BluetoothDevice device) {
         try {
diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java
index 93e76fa..d2a1535 100644
--- a/core/java/android/bluetooth/BluetoothCodecConfig.java
+++ b/core/java/android/bluetooth/BluetoothCodecConfig.java
@@ -18,7 +18,6 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -34,7 +33,6 @@
  *
  * {@hide}
  */
-@SystemApi
 public final class BluetoothCodecConfig implements Parcelable {
     // Add an entry for each source codec here.
     // NOTE: The values should be same as those listed in the following file:
diff --git a/core/java/android/bluetooth/BluetoothCodecStatus.java b/core/java/android/bluetooth/BluetoothCodecStatus.java
index b6e7739..1e394b8 100644
--- a/core/java/android/bluetooth/BluetoothCodecStatus.java
+++ b/core/java/android/bluetooth/BluetoothCodecStatus.java
@@ -17,7 +17,6 @@
 package android.bluetooth;
 
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -32,7 +31,6 @@
  *
  * {@hide}
  */
-@SystemApi
 public final class BluetoothCodecStatus implements Parcelable {
     /**
      * Extra for the codec configuration intents of the individual profiles.
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 2a3f2be..a2cf7d9 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -35,8 +35,6 @@
 import android.os.RemoteException;
 import android.util.Log;
 
-import com.android.internal.annotations.VisibleForTesting;
-
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.lang.annotation.Retention;
@@ -1103,8 +1101,8 @@
      * @return true on success, false on error
      * @hide
      */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    @UnsupportedAppUsage
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
     public boolean setAlias(@NonNull String alias) {
         final IBluetooth service = sService;
         if (service == null) {
@@ -1145,8 +1143,8 @@
      * not have any battery reporting service, or return value is invalid
      * @hide
      */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    @UnsupportedAppUsage
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
     public int getBatteryLevel() {
         final IBluetooth service = sService;
         if (service == null) {
@@ -1236,8 +1234,8 @@
      *
      * @hide
      */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    @UnsupportedAppUsage
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
     public boolean isBondingInitiatedLocally() {
         final IBluetooth service = sService;
         if (service == null) {
@@ -1531,7 +1529,7 @@
      * @return true pin has been set false for error
      * @hide
      */
-    @SystemApi
+    @UnsupportedAppUsage
     @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
     public boolean setPin(@NonNull String pin) {
         byte[] pinBytes = convertPinToBytes(pin);
@@ -1568,8 +1566,8 @@
      *
      * @hide
      */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    @UnsupportedAppUsage
+    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
     public boolean cancelPairing() {
         final IBluetooth service = sService;
         if (service == null) {
@@ -1600,8 +1598,8 @@
      * #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
      * @hide
      */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    @UnsupportedAppUsage
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
     public @AccessPermission int getPhonebookAccessPermission() {
         final IBluetooth service = sService;
         if (service == null) {
@@ -1708,8 +1706,8 @@
      * @return Whether the message access is allowed to this device.
      * @hide
      */
-    @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    @UnsupportedAppUsage
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
     public @AccessPermission int getMessageAccessPermission() {
         final IBluetooth service = sService;
         if (service == null) {
@@ -1758,7 +1756,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
     public @AccessPermission int getSimAccessPermission() {
         final IBluetooth service = sService;
         if (service == null) {
@@ -2013,7 +2011,7 @@
      * @return the pin code as a UTF-8 byte array, or null if it is an invalid Bluetooth pin.
      * @hide
      */
-    @VisibleForTesting
+    @UnsupportedAppUsage
     public static byte[] convertPinToBytes(String pin) {
         if (pin == null) {
             return null;
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 1ba2bb5..6ce05f9 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -572,7 +572,22 @@
     @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN)
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            if (priority != BluetoothProfile.PRIORITY_OFF
+                    && priority != BluetoothProfile.PRIORITY_ON) {
+                return false;
+            }
+            try {
+                return service.setPriority(
+                        device, BluetoothAdapter.priorityToConnectionPolicy(priority));
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
     }
 
     /**
@@ -588,7 +603,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
             @ConnectionPolicy int connectionPolicy) {
         if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
@@ -624,7 +639,17 @@
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public int getPriority(BluetoothDevice device) {
         if (VDBG) log("getPriority(" + device + ")");
-        return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
+        final IBluetoothHeadset service = mService;
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return BluetoothAdapter.connectionPolicyToPriority(service.getPriority(device));
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return BluetoothProfile.PRIORITY_OFF;
+            }
+        }
+        if (service == null) Log.w(TAG, "Proxy not attached to service");
+        return BluetoothProfile.PRIORITY_OFF;
     }
 
     /**
@@ -639,7 +664,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
         if (VDBG) log("getConnectionPolicy(" + device + ")");
         final IBluetoothHeadset service = mService;
@@ -1126,16 +1151,13 @@
     /**
      * Get the connected device that is active.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
-     * permission.
-     *
      * @return the connected device that is active or null if no device
      * is active.
      * @hide
      */
-    @SystemApi
+    @UnsupportedAppUsage
     @Nullable
-    @RequiresPermission(android.Manifest.permission.BLUETOOTH)
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
     public BluetoothDevice getActiveDevice() {
         if (VDBG) {
             Log.d(TAG, "getActiveDevice");
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index fbda9e9..85e0e08 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -17,6 +17,7 @@
 package android.bluetooth;
 
 import android.Manifest;
+import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -442,6 +443,8 @@
      * @param device a remote device we want connect to
      * @return <code>true</code> if command has been issued successfully; <code>false</code>
      * otherwise; upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED} intent.
+     *
+     * @hide
      */
     @UnsupportedAppUsage
     public boolean connect(BluetoothDevice device) {
@@ -466,6 +469,8 @@
      * @param device a remote device we want disconnect
      * @return <code>true</code> if command has been issued successfully; <code>false</code>
      * otherwise; upon completion HFP sends {@link #ACTION_CONNECTION_STATE_CHANGED} intent.
+     *
+     * @hide
      */
     @UnsupportedAppUsage
     public boolean disconnect(BluetoothDevice device) {
@@ -564,7 +569,7 @@
      * @return true if priority is set, false on error
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
         return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
@@ -583,8 +588,8 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
-    public boolean setConnectionPolicy(BluetoothDevice device,
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
             @ConnectionPolicy int connectionPolicy) {
         if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
         final IBluetoothHeadsetClient service =
@@ -634,7 +639,7 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.BLUETOOTH)
-    public @ConnectionPolicy int getConnectionPolicy(BluetoothDevice device) {
+    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
         if (VDBG) log("getConnectionPolicy(" + device + ")");
         final IBluetoothHeadsetClient service =
                 getService();
diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java
index 38498bc..fa62a02 100644
--- a/core/java/android/bluetooth/BluetoothHearingAid.java
+++ b/core/java/android/bluetooth/BluetoothHearingAid.java
@@ -162,13 +162,11 @@
      * the state. Users can get the connection state of the profile
      * from this intent.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission.
-     *
      * @param device Remote Bluetooth Device
      * @return false on immediate error, true otherwise
      * @hide
      */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean connect(BluetoothDevice device) {
         if (DBG) log("connect(" + device + ")");
         final IBluetoothHearingAid service = getService();
@@ -202,13 +200,11 @@
      * {@link #STATE_DISCONNECTING} can be used to distinguish between the
      * two scenarios.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission.
-     *
      * @param device Remote Bluetooth Device
      * @return false on immediate error, true otherwise
      * @hide
      */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) log("disconnect(" + device + ")");
         final IBluetoothHearingAid service = getService();
@@ -327,15 +323,12 @@
     /**
      * Get the connected physical Hearing Aid devices that are active
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
-     * permission.
-     *
      * @return the list of active devices. The first element is the left active
      * device; the second element is the right active device. If either or both side
      * is not active, it will be null on that position. Returns empty list on error.
      * @hide
      */
-    @SystemApi
+    @UnsupportedAppUsage
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public @NonNull List<BluetoothDevice> getActiveDevices() {
         if (VDBG) log("getActiveDevices()");
@@ -363,7 +356,7 @@
      * @return true if priority is set, false on error
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
         return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
@@ -382,10 +375,11 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
             @ConnectionPolicy int connectionPolicy) {
         if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
+        verifyDeviceNotNull(device, "setConnectionPolicy");
         final IBluetoothHearingAid service = getService();
         try {
             if (service != null && isEnabled()
@@ -414,7 +408,7 @@
      * @return priority of the device
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public int getPriority(BluetoothDevice device) {
         if (VDBG) log("getPriority(" + device + ")");
         return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
@@ -432,9 +426,10 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
         if (VDBG) log("getConnectionPolicy(" + device + ")");
+        verifyDeviceNotNull(device, "getConnectionPolicy");
         final IBluetoothHearingAid service = getService();
         try {
             if (service != null && isEnabled()
@@ -496,18 +491,22 @@
     }
 
     /**
-     * Get the CustomerId of the device.
+     * Get the HiSyncId (unique hearing aid device identifier) of the device.
+     *
+     * <a href=https://source.android.com/devices/bluetooth/asha#hisyncid>HiSyncId documentation
+     * can be found here</a>
      *
      * @param device Bluetooth device
-     * @return the CustomerId of the device
+     * @return the HiSyncId of the device
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
-    public long getHiSyncId(@Nullable BluetoothDevice device) {
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    public long getHiSyncId(@NonNull BluetoothDevice device) {
         if (VDBG) {
-            log("getCustomerId(" + device + ")");
+            log("getHiSyncId(" + device + ")");
         }
+        verifyDeviceNotNull(device, "getConnectionPolicy");
         final IBluetoothHearingAid service = getService();
         try {
             if (service == null) {
@@ -581,6 +580,13 @@
         return false;
     }
 
+    private void verifyDeviceNotNull(BluetoothDevice device, String methodName) {
+        if (device == null) {
+            Log.e(TAG, methodName + ": device param is null");
+            throw new IllegalArgumentException("Device cannot be null");
+        }
+    }
+
     private boolean isValidDevice(BluetoothDevice device) {
         if (device == null) return false;
 
diff --git a/core/java/android/bluetooth/BluetoothHidHost.java b/core/java/android/bluetooth/BluetoothHidHost.java
index e9e1f68..9561d93 100644
--- a/core/java/android/bluetooth/BluetoothHidHost.java
+++ b/core/java/android/bluetooth/BluetoothHidHost.java
@@ -263,13 +263,11 @@
      * the state. Users can get the connection state of the profile
      * from this intent.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission.
-     *
      * @param device Remote Bluetooth Device
      * @return false on immediate error, true otherwise
      * @hide
      */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean connect(BluetoothDevice device) {
         if (DBG) log("connect(" + device + ")");
         final IBluetoothHidHost service = getService();
@@ -303,13 +301,11 @@
      * {@link #STATE_DISCONNECTING} can be used to distinguish between the
      * two scenarios.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission.
-     *
      * @param device Remote Bluetooth Device
      * @return false on immediate error, true otherwise
      * @hide
      */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) log("disconnect(" + device + ")");
         final IBluetoothHidHost service = getService();
@@ -327,7 +323,10 @@
 
     /**
      * {@inheritDoc}
+     *
+     * @hide
      */
+    @SystemApi
     @Override
     @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public @NonNull List<BluetoothDevice> getConnectedDevices() {
@@ -368,7 +367,10 @@
 
     /**
      * {@inheritDoc}
+     *
+     * @hide
      */
+    @SystemApi
     @Override
     @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public int getConnectionState(@NonNull BluetoothDevice device) {
@@ -400,7 +402,7 @@
      * @return true if priority is set, false on error
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
         return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
@@ -419,7 +421,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
             @ConnectionPolicy int connectionPolicy) {
         if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
@@ -453,7 +455,7 @@
      * @return priority of the device
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public int getPriority(BluetoothDevice device) {
         if (VDBG) log("getPriority(" + device + ")");
         return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
@@ -471,7 +473,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
         if (VDBG) log("getConnectionPolicy(" + device + ")");
         if (device == null) {
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
index cc2b615..14a71c4 100644
--- a/core/java/android/bluetooth/BluetoothMap.java
+++ b/core/java/android/bluetooth/BluetoothMap.java
@@ -18,7 +18,6 @@
 
 import android.Manifest;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
@@ -328,7 +327,7 @@
      * @return true if priority is set, false on error
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
         return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
@@ -347,8 +346,8 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
-    public boolean setConnectionPolicy(@Nullable BluetoothDevice device,
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
             @ConnectionPolicy int connectionPolicy) {
         if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
         final IBluetoothMap service = getService();
@@ -378,7 +377,7 @@
      * @return priority of the device
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public int getPriority(BluetoothDevice device) {
         if (VDBG) log("getPriority(" + device + ")");
         return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
@@ -396,8 +395,8 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
-    public @ConnectionPolicy int getConnectionPolicy(@Nullable BluetoothDevice device) {
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
         if (VDBG) log("getConnectionPolicy(" + device + ")");
         final IBluetoothMap service = getService();
         if (service != null && isEnabled() && isValidDevice(device)) {
diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java
index 8d2aadd..19240dc 100644
--- a/core/java/android/bluetooth/BluetoothMapClient.java
+++ b/core/java/android/bluetooth/BluetoothMapClient.java
@@ -17,6 +17,7 @@
 package android.bluetooth;
 
 import android.Manifest;
+import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.app.PendingIntent;
@@ -140,7 +141,10 @@
     /**
      * Initiate connection. Initiation of outgoing connections is not
      * supported for MAP server.
+     *
+     * @hide
      */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean connect(BluetoothDevice device) {
         if (DBG) Log.d(TAG, "connect(" + device + ")" + "for MAPS MCE");
         final IBluetoothMapClient service = getService();
@@ -162,7 +166,10 @@
      *
      * @param device Remote Bluetooth Device
      * @return false on error, true otherwise
+     *
+     * @hide
      */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) Log.d(TAG, "disconnect(" + device + ")");
         final IBluetoothMapClient service = getService();
@@ -251,7 +258,7 @@
      * @return true if priority is set, false on error
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) Log.d(TAG, "setPriority(" + device + ", " + priority + ")");
         return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
@@ -270,8 +277,8 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
-    public boolean setConnectionPolicy(BluetoothDevice device,
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
             @ConnectionPolicy int connectionPolicy) {
         if (DBG) Log.d(TAG, "setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
         final IBluetoothMapClient service = getService();
@@ -301,7 +308,7 @@
      * @return priority of the device
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public int getPriority(BluetoothDevice device) {
         if (VDBG) Log.d(TAG, "getPriority(" + device + ")");
         return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
@@ -319,8 +326,8 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
-    public @ConnectionPolicy int getConnectionPolicy(BluetoothDevice device) {
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
         if (VDBG) Log.d(TAG, "getConnectionPolicy(" + device + ")");
         final IBluetoothMapClient service = getService();
         if (service != null && isEnabled() && isValidDevice(device)) {
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 7af770e..a80f5b7 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -19,7 +19,6 @@
 import android.Manifest;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
@@ -30,7 +29,6 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.util.CloseGuard;
 import android.util.Log;
 
 import java.lang.annotation.Retention;
@@ -51,11 +49,10 @@
  * @hide
  */
 @SystemApi
-public final class BluetoothPan implements BluetoothProfile, AutoCloseable {
+public final class BluetoothPan implements BluetoothProfile {
     private static final String TAG = "BluetoothPan";
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
-    private CloseGuard mCloseGuard;
 
     /**
      * Intent used to broadcast the change in connection state of the Pan
@@ -168,16 +165,13 @@
         mAdapter = BluetoothAdapter.getDefaultAdapter();
         mContext = context;
         mProfileConnector.connect(context, listener);
-        mCloseGuard = new CloseGuard();
-        mCloseGuard.open("close");
     }
 
     /**
      * Closes the connection to the service and unregisters callbacks
-     *
-     * @hide
      */
-    public void close() {
+    @UnsupportedAppUsage
+    void close() {
         if (VDBG) log("close()");
         mProfileConnector.disconnect();
     }
@@ -188,9 +182,6 @@
 
     /** @hide */
     protected void finalize() {
-        if (mCloseGuard != null) {
-            mCloseGuard.warnIfOpen();
-        }
         close();
     }
 
@@ -204,9 +195,6 @@
      * the state. Users can get the connection state of the profile
      * from this intent.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission.
-     *
      * @param device Remote Bluetooth Device
      * @return false on immediate error, true otherwise
      * @hide
@@ -245,9 +233,6 @@
      * {@link #STATE_DISCONNECTING} can be used to distinguish between the
      * two scenarios.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission.
-     *
      * @param device Remote Bluetooth Device
      * @return false on immediate error, true otherwise
      * @hide
@@ -353,7 +338,7 @@
     @SystemApi
     @Override
     @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public int getConnectionState(@Nullable BluetoothDevice device) {
+    public int getConnectionState(@NonNull BluetoothDevice device) {
         if (VDBG) log("getState(" + device + ")");
         final IBluetoothPan service = getService();
         if (service != null && isEnabled() && isValidDevice(device)) {
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index 277a5a8..d58a893 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -18,7 +18,6 @@
 
 import android.Manifest;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SuppressLint;
@@ -239,7 +238,7 @@
     @SystemApi
     @Override
     @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public @BtProfileState int getConnectionState(@Nullable BluetoothDevice device) {
+    public @BtProfileState int getConnectionState(@NonNull BluetoothDevice device) {
         log("getConnectionState: device=" + device);
         try {
             final IBluetoothPbap service = mService;
diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java
index 9563c68..d3452ff 100644
--- a/core/java/android/bluetooth/BluetoothPbapClient.java
+++ b/core/java/android/bluetooth/BluetoothPbapClient.java
@@ -17,6 +17,7 @@
 package android.bluetooth;
 
 import android.Manifest;
+import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.content.Context;
@@ -101,7 +102,10 @@
      * @param device a remote device we want connect to
      * @return <code>true</code> if command has been issued successfully; <code>false</code>
      * otherwise;
+     *
+     * @hide
      */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean connect(BluetoothDevice device) {
         if (DBG) {
             log("connect(" + device + ") for PBAP Client.");
@@ -126,7 +130,10 @@
      *
      * @param device Remote Bluetooth Device
      * @return false on error, true otherwise
+     *
+     * @hide
      */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) {
             log("disconnect(" + device + ")" + new Exception());
@@ -251,7 +258,7 @@
      * @return true if priority is set, false on error
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
         return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
@@ -270,8 +277,8 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
-    public boolean setConnectionPolicy(BluetoothDevice device,
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
             @ConnectionPolicy int connectionPolicy) {
         if (DBG) {
             log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
@@ -305,7 +312,7 @@
      * @return priority of the device
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public int getPriority(BluetoothDevice device) {
         if (VDBG) log("getPriority(" + device + ")");
         return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
@@ -323,8 +330,8 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
-    public @ConnectionPolicy int getConnectionPolicy(BluetoothDevice device) {
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
         if (VDBG) {
             log("getConnectionPolicy(" + device + ")");
         }
diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java
index bfc3a4d..6e03481 100644
--- a/core/java/android/bluetooth/BluetoothSap.java
+++ b/core/java/android/bluetooth/BluetoothSap.java
@@ -310,7 +310,7 @@
      * @return true if priority is set, false on error
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
         return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
@@ -329,7 +329,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setConnectionPolicy(BluetoothDevice device,
             @ConnectionPolicy int connectionPolicy) {
         if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
@@ -360,7 +360,7 @@
      * @return priority of the device
      * @hide
      */
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public int getPriority(BluetoothDevice device) {
         if (VDBG) log("getPriority(" + device + ")");
         return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
@@ -378,7 +378,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public @ConnectionPolicy int getConnectionPolicy(BluetoothDevice device) {
         if (VDBG) log("getConnectionPolicy(" + device + ")");
         final IBluetoothSap service = getService();
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index c19c284..b79965e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3864,15 +3864,13 @@
      * @hide
      * @see NetworkStackClient
      */
-    @SystemApi
-    @TestApi
     public static final String NETWORK_STACK_SERVICE = "network_stack";
 
     /**
-     * Use with {@link android.os.ServiceManager.getService()} to retrieve a
-     * {@link ITetheringConnector} IBinder for communicating with the tethering service
+     * Use with {@link #getSystemService(String)} to retrieve a {@link android.net.TetheringManager}
+     * for managing tethering functions.
      * @hide
-     * @see TetheringClient
+     * @see android.net.TetheringManager
      */
     @SystemApi
     public static final String TETHERING_SERVICE = "tethering";
@@ -3947,8 +3945,6 @@
      */
     public static final String NETWORK_STATS_SERVICE = "netstats";
     /** {@hide} */
-    @SystemApi
-    @SuppressLint("ServiceName")
     public static final String NETWORK_POLICY_SERVICE = "netpolicy";
     /** {@hide} */
     public static final String NETWORK_WATCHLIST_SERVICE = "network_watchlist";
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index ba91014..467aa15 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3622,9 +3622,7 @@
      * {@link android.Manifest.permission#MANAGE_USERS} to receive this broadcast.
      * @hide
      */
-    @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @SystemApi
+    @UnsupportedAppUsage
     public static final String ACTION_USER_SWITCHED =
             "android.intent.action.USER_SWITCHED";
 
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 2217807..2914e4c 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -68,6 +68,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.Executor;
+import java.util.stream.Collectors;
 
 /**
  * Offers the ability to install, upgrade, and remove applications on the
@@ -486,35 +487,30 @@
     }
 
     /**
-     * Returns an active staged session, or {@code null} if there is none.
+     * Returns first active staged session, or {@code null} if there is none.
      *
-     * <p>Staged session is active iff:
-     * <ul>
-     *     <li>It is committed, i.e. {@link SessionInfo#isCommitted()} is {@code true}, and
-     *     <li>it is not applied, i.e. {@link SessionInfo#isStagedSessionApplied()} is {@code
-     *     false}, and
-     *     <li>it is not failed, i.e. {@link SessionInfo#isStagedSessionFailed()} is {@code false}.
-     * </ul>
+     * <p>For more information on what sessions are considered active see
+     * {@link SessionInfo#isStagedSessionActive()}.
      *
-     * <p>In case of a multi-apk session, reasoning above is applied to the parent session, since
-     * that is the one that should been {@link Session#commit committed}.
+     * @deprecated Use {@link #getActiveStagedSessions} as there can be more than one active staged
+     * session
      */
+    @Deprecated
     public @Nullable SessionInfo getActiveStagedSession() {
-        final List<SessionInfo> stagedSessions = getStagedSessions();
-        for (SessionInfo s : stagedSessions) {
-            if (s.isStagedSessionApplied() || s.isStagedSessionFailed()) {
-                // Finalized session.
-                continue;
-            }
-            if (s.getParentSessionId() != SessionInfo.INVALID_ID) {
-                // Child session.
-                continue;
-            }
-            if (s.isCommitted()) {
-                return s;
-            }
-        }
-        return null;
+        List<SessionInfo> activeSessions = getActiveStagedSessions();
+        return activeSessions.isEmpty() ? null : activeSessions.get(0);
+    }
+
+    /**
+     * Returns list of active staged sessions. Returns empty list if there is none.
+     *
+     * <p>For more information on what sessions are considered active see
+     *      * {@link SessionInfo#isStagedSessionActive()}.
+     */
+    public @NonNull List<SessionInfo> getActiveStagedSessions() {
+        return getStagedSessions().stream()
+                .filter(s -> s.isStagedSessionActive())
+                .collect(Collectors.toList());
     }
 
     /**
@@ -2234,13 +2230,36 @@
         }
 
         /**
-         * Returns true if this session is a staged session which will be applied at next reboot.
+         * Returns true if this session is a staged session.
          */
         public boolean isStaged() {
             return isStaged;
         }
 
         /**
+         * Returns {@code true} if this session is an active staged session.
+         *
+         * We consider a session active if it has been committed and it is either pending
+         * verification, or will be applied at next reboot.
+         *
+         * <p>Staged session is active iff:
+         * <ul>
+         *     <li>It is committed, i.e. {@link SessionInfo#isCommitted()} is {@code true}, and
+         *     <li>it is not applied, i.e. {@link SessionInfo#isStagedSessionApplied()} is {@code
+         *     false}, and
+         *     <li>it is not failed, i.e. {@link SessionInfo#isStagedSessionFailed()} is
+         *     {@code false}.
+         * </ul>
+         *
+         * <p>In case of a multi-package session, reasoning above is applied to the parent session,
+         * since that is the one that should have been {@link Session#commit committed}.
+         */
+        public boolean isStagedSessionActive() {
+            return isStaged && isCommitted && !isStagedSessionApplied && !isStagedSessionFailed
+                    && !hasParentSessionId();
+        }
+
+        /**
          * Returns the parent multi-package session ID if this session belongs to one,
          * {@link #INVALID_ID} otherwise.
          */
@@ -2249,6 +2268,13 @@
         }
 
         /**
+         * Returns true if session has a valid parent session, otherwise false.
+         */
+        public boolean hasParentSessionId() {
+            return parentSessionId != INVALID_ID;
+        }
+
+        /**
          * Returns the set of session IDs that will be committed when this session is commited if
          * this session is a multi-package session.
          */
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 2db661d..66f9ac0 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1424,7 +1424,7 @@
 
     /**
      * Installation failed return code: a new staged session was attempted to be committed while
-     * there is already one in-progress.
+     * there is already one in-progress or new session has package that is already staged.
      *
      * @hide
      */
diff --git a/core/java/android/hardware/usb/OWNERS b/core/java/android/hardware/usb/OWNERS
new file mode 100644
index 0000000..8ee72b5
--- /dev/null
+++ b/core/java/android/hardware/usb/OWNERS
@@ -0,0 +1,6 @@
+badhri@google.com
+elaurent@google.com
+moltmann@google.com
+albertccwang@google.com
+jameswei@google.com
+howardyen@google.com
\ No newline at end of file
diff --git a/core/java/android/inputmethodservice/OWNERS b/core/java/android/inputmethodservice/OWNERS
new file mode 100644
index 0000000..4447197
--- /dev/null
+++ b/core/java/android/inputmethodservice/OWNERS
@@ -0,0 +1,3 @@
+set noparent
+
+include ../../../../services/core/java/com/android/server/inputmethod/OWNERS
diff --git a/core/java/android/net/ConnectivityDiagnosticsManager.java b/core/java/android/net/ConnectivityDiagnosticsManager.java
index d0091440..6f0a4f9 100644
--- a/core/java/android/net/ConnectivityDiagnosticsManager.java
+++ b/core/java/android/net/ConnectivityDiagnosticsManager.java
@@ -136,7 +136,7 @@
          * {@link #NETWORK_VALIDATION_RESULT_PARTIALLY_VALID},
          * {@link #NETWORK_VALIDATION_RESULT_SKIPPED}.
          *
-         * @see android.net.NetworkCapabilities#CAPABILITY_VALIDATED
+         * @see android.net.NetworkCapabilities#NET_CAPABILITY_VALIDATED
          */
         @NetworkValidationResult
         public static final String KEY_NETWORK_VALIDATION_RESULT = "networkValidationResult";
@@ -233,8 +233,8 @@
          * Constructor for ConnectivityReport.
          *
          * <p>Apps should obtain instances through {@link
-         * ConnectivityDiagnosticsCallback#onConnectivityReport} instead of instantiating their own
-         * instances (unless for testing purposes).
+         * ConnectivityDiagnosticsCallback#onConnectivityReportAvailable} instead of instantiating
+         * their own instances (unless for testing purposes).
          *
          * @param network The Network for which this ConnectivityReport applies
          * @param reportTimestamp The timestamp for the report
@@ -368,7 +368,14 @@
 
     /** Class that includes information for a suspected data stall on a specific Network */
     public static final class DataStallReport implements Parcelable {
+        /**
+         * Indicates that the Data Stall was detected using DNS events.
+         */
         public static final int DETECTION_METHOD_DNS_EVENTS = 1;
+
+        /**
+         * Indicates that the Data Stall was detected using TCP metrics.
+         */
         public static final int DETECTION_METHOD_TCP_METRICS = 2;
 
         /** @hide */
@@ -615,10 +622,10 @@
 
         /** @hide */
         @VisibleForTesting
-        public void onConnectivityReport(@NonNull ConnectivityReport report) {
+        public void onConnectivityReportAvailable(@NonNull ConnectivityReport report) {
             Binder.withCleanCallingIdentity(() -> {
                 mExecutor.execute(() -> {
-                    mCb.onConnectivityReport(report);
+                    mCb.onConnectivityReportAvailable(report);
                 });
             });
         }
@@ -659,7 +666,7 @@
          *
          * @param report The ConnectivityReport containing information about a connectivity check
          */
-        public void onConnectivityReport(@NonNull ConnectivityReport report) {}
+        public void onConnectivityReportAvailable(@NonNull ConnectivityReport report) {}
 
         /**
          * Called when the platform suspects a data stall on some Network.
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index d8a97de..0f48ac2 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -145,16 +145,6 @@
     public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
 
     /**
-     * A temporary hack until SUPL system can get off the legacy APIS.
-     * They do too many network requests and the long list of apps listening
-     * and waking due to the CONNECTIVITY_ACTION broadcast makes it expensive.
-     * Use this broadcast intent instead for SUPL requests.
-     * @hide
-     */
-    public static final String CONNECTIVITY_ACTION_SUPL =
-            "android.net.conn.CONNECTIVITY_CHANGE_SUPL";
-
-    /**
      * The device has connected to a network that has presented a captive
      * portal, which is blocking Internet connectivity. The user was presented
      * with a notification that network sign in is required,
@@ -1517,84 +1507,6 @@
         return null;
     }
 
-    /**
-     * Guess what the network request was trying to say so that the resulting
-     * network is accessible via the legacy (deprecated) API such as
-     * requestRouteToHost.
-     *
-     * This means we should try to be fairly precise about transport and
-     * capability but ignore things such as networkSpecifier.
-     * If the request has more than one transport or capability it doesn't
-     * match the old legacy requests (they selected only single transport/capability)
-     * so this function cannot map the request to a single legacy type and
-     * the resulting network will not be available to the legacy APIs.
-     *
-     * This code is only called from the requestNetwork API (L and above).
-     *
-     * Setting a legacy type causes CONNECTIVITY_ACTION broadcasts, which are expensive
-     * because they wake up lots of apps - see http://b/23350688 . So we currently only
-     * do this for SUPL requests, which are the only ones that we know need it. If
-     * omitting these broadcasts causes unacceptable app breakage, then for backwards
-     * compatibility we can send them:
-     *
-     * if (targetSdkVersion < Build.VERSION_CODES.M) &&        // legacy API unsupported >= M
-     *     targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP))  // requestNetwork not present < L
-     *
-     * TODO - This should be removed when the legacy APIs are removed.
-     */
-    private int inferLegacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
-        if (netCap == null) {
-            return TYPE_NONE;
-        }
-
-        if (!netCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
-            return TYPE_NONE;
-        }
-
-        // Do this only for SUPL, until GnssLocationProvider is fixed. http://b/25876485 .
-        if (!netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
-            // NOTE: if this causes app breakage, we should not just comment out this early return;
-            // instead, we should make this early return conditional on the requesting app's target
-            // SDK version, as described in the comment above.
-            return TYPE_NONE;
-        }
-
-        String type = null;
-        int result = TYPE_NONE;
-
-        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
-            type = "enableCBS";
-            result = TYPE_MOBILE_CBS;
-        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
-            type = "enableIMS";
-            result = TYPE_MOBILE_IMS;
-        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
-            type = "enableFOTA";
-            result = TYPE_MOBILE_FOTA;
-        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
-            type = "enableDUN";
-            result = TYPE_MOBILE_DUN;
-        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
-            type = "enableSUPL";
-            result = TYPE_MOBILE_SUPL;
-        // back out this hack for mms as they no longer need this and it's causing
-        // device slowdowns - b/23350688 (note, supl still needs this)
-        //} else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
-        //    type = "enableMMS";
-        //    result = TYPE_MOBILE_MMS;
-        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
-            type = "enableHIPRI";
-            result = TYPE_MOBILE_HIPRI;
-        }
-        if (type != null) {
-            NetworkCapabilities testCap = networkCapabilitiesForFeature(TYPE_MOBILE, type);
-            if (testCap.equalsNetCapabilities(netCap) && testCap.equalsTransportTypes(netCap)) {
-                return result;
-            }
-        }
-        return TYPE_NONE;
-    }
-
     private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
         if (netCap == null) return TYPE_NONE;
         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
@@ -2576,13 +2488,13 @@
             }
 
             @Override
-            public void onTetheringFailed(final int resultCode) {
+            public void onTetheringFailed(final int error) {
                 callback.onTetheringFailed();
             }
         };
 
         final TetheringRequest request = new TetheringRequest.Builder(type)
-                .setSilentProvisioning(!showProvisioningUi).build();
+                .setShouldShowEntitlementUi(showProvisioningUi).build();
 
         mTetheringManager.startTethering(request, executor, tetheringCallback);
     }
@@ -2802,11 +2714,12 @@
     public static final int TETHER_ERROR_UNAVAIL_IFACE =
             TetheringManager.TETHER_ERROR_UNAVAIL_IFACE;
     /**
-     * @deprecated Use {@link TetheringManager#TETHER_ERROR_MASTER_ERROR}.
+     * @deprecated Use {@link TetheringManager#TETHER_ERROR_INTERNAL_ERROR}.
      * {@hide}
      */
     @Deprecated
-    public static final int TETHER_ERROR_MASTER_ERROR = TetheringManager.TETHER_ERROR_MASTER_ERROR;
+    public static final int TETHER_ERROR_MASTER_ERROR =
+            TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
     /**
      * @deprecated Use {@link TetheringManager#TETHER_ERROR_TETHER_IFACE_ERROR}.
      * {@hide}
@@ -2822,19 +2735,19 @@
     public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR =
             TetheringManager.TETHER_ERROR_UNTETHER_IFACE_ERROR;
     /**
-     * @deprecated Use {@link TetheringManager#TETHER_ERROR_ENABLE_NAT_ERROR}.
+     * @deprecated Use {@link TetheringManager#TETHER_ERROR_ENABLE_FORWARDING_ERROR}.
      * {@hide}
      */
     @Deprecated
     public static final int TETHER_ERROR_ENABLE_NAT_ERROR =
-            TetheringManager.TETHER_ERROR_ENABLE_NAT_ERROR;
+            TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR;
     /**
-     * @deprecated Use {@link TetheringManager#TETHER_ERROR_DISABLE_NAT_ERROR}.
+     * @deprecated Use {@link TetheringManager#TETHER_ERROR_DISABLE_FORWARDING_ERROR}.
      * {@hide}
      */
     @Deprecated
     public static final int TETHER_ERROR_DISABLE_NAT_ERROR =
-            TetheringManager.TETHER_ERROR_DISABLE_NAT_ERROR;
+            TetheringManager.TETHER_ERROR_DISABLE_FORWARDING_ERROR;
     /**
      * @deprecated Use {@link TetheringManager#TETHER_ERROR_IFACE_CFG_ERROR}.
      * {@hide}
@@ -2843,13 +2756,13 @@
     public static final int TETHER_ERROR_IFACE_CFG_ERROR =
             TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR;
     /**
-     * @deprecated Use {@link TetheringManager#TETHER_ERROR_PROVISION_FAILED}.
+     * @deprecated Use {@link TetheringManager#TETHER_ERROR_PROVISIONING_FAILED}.
      * {@hide}
      */
     @SystemApi
     @Deprecated
     public static final int TETHER_ERROR_PROVISION_FAILED =
-            TetheringManager.TETHER_ERROR_PROVISION_FAILED;
+            TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
     /**
      * @deprecated Use {@link TetheringManager#TETHER_ERROR_DHCPSERVER_ERROR}.
      * {@hide}
@@ -2881,7 +2794,14 @@
     @UnsupportedAppUsage
     @Deprecated
     public int getLastTetherError(String iface) {
-        return mTetheringManager.getLastTetherError(iface);
+        int error = mTetheringManager.getLastTetherError(iface);
+        if (error == TetheringManager.TETHER_ERROR_UNKNOWN_TYPE) {
+            // TETHER_ERROR_UNKNOWN_TYPE was introduced with TetheringManager and has never been
+            // returned by ConnectivityManager. Convert it to the legacy TETHER_ERROR_UNKNOWN_IFACE
+            // instead.
+            error = TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
+        }
+        return error;
     }
 
     /** @hide */
@@ -3774,29 +3694,29 @@
     /**
      * Helper function to request a network with a particular legacy type.
      *
-     * @deprecated This is temporarily public for tethering to backwards compatibility that uses
-     * the NetworkRequest API to request networks with legacy type and relies on
-     * CONNECTIVITY_ACTION broadcasts instead of NetworkCallbacks. New caller should use
+     * This API is only for use in internal system code that requests networks with legacy type and
+     * relies on CONNECTIVITY_ACTION broadcasts instead of NetworkCallbacks. New caller should use
      * {@link #requestNetwork(NetworkRequest, NetworkCallback, Handler)} instead.
      *
-     * TODO: update said system code to rely on NetworkCallbacks and make this method private.
-
      * @param request {@link NetworkRequest} describing this request.
-     * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
-     *                        the callback must not be shared - it uniquely specifies this request.
      * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
      *                  before {@link NetworkCallback#onUnavailable()} is called. The timeout must
      *                  be a positive value (i.e. >0).
      * @param legacyType to specify the network type(#TYPE_*).
      * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
+     * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
+     *                        the callback must not be shared - it uniquely specifies this request.
      *
      * @hide
      */
     @SystemApi
-    @Deprecated
+    @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
     public void requestNetwork(@NonNull NetworkRequest request,
-            @NonNull NetworkCallback networkCallback, int timeoutMs, int legacyType,
-            @NonNull Handler handler) {
+            int timeoutMs, int legacyType, @NonNull Handler handler,
+            @NonNull NetworkCallback networkCallback) {
+        if (legacyType == TYPE_NONE) {
+            throw new IllegalArgumentException("TYPE_NONE is meaningless legacy type");
+        }
         CallbackHandler cbHandler = new CallbackHandler(handler);
         NetworkCapabilities nc = request.networkCapabilities;
         sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, legacyType, cbHandler);
@@ -3894,9 +3814,9 @@
      */
     public void requestNetwork(@NonNull NetworkRequest request,
             @NonNull NetworkCallback networkCallback, @NonNull Handler handler) {
-        int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
         CallbackHandler cbHandler = new CallbackHandler(handler);
-        requestNetwork(request, networkCallback, 0, legacyType, cbHandler);
+        NetworkCapabilities nc = request.networkCapabilities;
+        sendRequestForNetwork(nc, networkCallback, 0, REQUEST, TYPE_NONE, cbHandler);
     }
 
     /**
@@ -3929,8 +3849,9 @@
     public void requestNetwork(@NonNull NetworkRequest request,
             @NonNull NetworkCallback networkCallback, int timeoutMs) {
         checkTimeout(timeoutMs);
-        int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
-        requestNetwork(request, networkCallback, timeoutMs, legacyType, getDefaultHandler());
+        NetworkCapabilities nc = request.networkCapabilities;
+        sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, TYPE_NONE,
+                getDefaultHandler());
     }
 
     /**
@@ -3955,9 +3876,9 @@
     public void requestNetwork(@NonNull NetworkRequest request,
             @NonNull NetworkCallback networkCallback, @NonNull Handler handler, int timeoutMs) {
         checkTimeout(timeoutMs);
-        int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
         CallbackHandler cbHandler = new CallbackHandler(handler);
-        requestNetwork(request, networkCallback, timeoutMs, legacyType, cbHandler);
+        NetworkCapabilities nc = request.networkCapabilities;
+        sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, TYPE_NONE, cbHandler);
     }
 
     /**
diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java
index 83b5f63..d975017 100644
--- a/core/java/android/net/EthernetManager.java
+++ b/core/java/android/net/EthernetManager.java
@@ -200,6 +200,21 @@
     }
 
     /**
+     * Whether to treat interfaces created by {@link TestNetworkManager#createTapInterface}
+     * as Ethernet interfaces. The effects of this method apply to any test interfaces that are
+     * already present on the system.
+     * @hide
+     */
+    @TestApi
+    public void setIncludeTestInterfaces(boolean include) {
+        try {
+            mService.setIncludeTestInterfaces(include);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * A request for a tethered interface.
      */
     public static class TetheredInterfaceRequest {
diff --git a/core/java/android/net/IConnectivityDiagnosticsCallback.aidl b/core/java/android/net/IConnectivityDiagnosticsCallback.aidl
index 3a161bf..82b64a9 100644
--- a/core/java/android/net/IConnectivityDiagnosticsCallback.aidl
+++ b/core/java/android/net/IConnectivityDiagnosticsCallback.aidl
@@ -22,7 +22,7 @@
 
 /** @hide */
 oneway interface IConnectivityDiagnosticsCallback {
-    void onConnectivityReport(in ConnectivityDiagnosticsManager.ConnectivityReport report);
+    void onConnectivityReportAvailable(in ConnectivityDiagnosticsManager.ConnectivityReport report);
     void onDataStallSuspected(in ConnectivityDiagnosticsManager.DataStallReport report);
     void onNetworkConnectivityReported(in Network n, boolean hasConnectivity);
 }
\ No newline at end of file
diff --git a/core/java/android/net/IEthernetManager.aidl b/core/java/android/net/IEthernetManager.aidl
index ccc6e35..e058e5a 100644
--- a/core/java/android/net/IEthernetManager.aidl
+++ b/core/java/android/net/IEthernetManager.aidl
@@ -33,6 +33,7 @@
     boolean isAvailable(String iface);
     void addListener(in IEthernetServiceListener listener);
     void removeListener(in IEthernetServiceListener listener);
+    void setIncludeTestInterfaces(boolean include);
     void requestTetheredInterface(in ITetheredInterfaceCallback callback);
     void releaseTetheredInterface(in ITetheredInterfaceCallback callback);
 }
diff --git a/core/java/android/net/ITestNetworkManager.aidl b/core/java/android/net/ITestNetworkManager.aidl
index d586038..2a863ad 100644
--- a/core/java/android/net/ITestNetworkManager.aidl
+++ b/core/java/android/net/ITestNetworkManager.aidl
@@ -33,7 +33,7 @@
     TestNetworkInterface createTapInterface();
 
     void setupTestNetwork(in String iface, in LinkProperties lp, in boolean isMetered,
-            in IBinder binder);
+            in int[] administratorUids, in IBinder binder);
 
     void teardownTestNetwork(int netId);
 }
diff --git a/core/java/android/net/InvalidPacketException.java b/core/java/android/net/InvalidPacketException.java
index 909998d..b3b0f11 100644
--- a/core/java/android/net/InvalidPacketException.java
+++ b/core/java/android/net/InvalidPacketException.java
@@ -28,7 +28,7 @@
  */
 @SystemApi
 public class InvalidPacketException extends Exception {
-    public final int error;
+    private final int mError;
 
     // Must match SocketKeepalive#ERROR_INVALID_IP_ADDRESS.
     /** Invalid IP address. */
@@ -56,6 +56,11 @@
      * See the error code for details.
      */
     public InvalidPacketException(@ErrorCode final int error) {
-        this.error = error;
+        this.mError = error;
+    }
+
+    /** Get error code. */
+    public int getError() {
+        return mError;
     }
 }
diff --git a/core/java/android/net/KeepalivePacketData.java b/core/java/android/net/KeepalivePacketData.java
index 2b8b7e6..e21cb44 100644
--- a/core/java/android/net/KeepalivePacketData.java
+++ b/core/java/android/net/KeepalivePacketData.java
@@ -19,10 +19,10 @@
 import static android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS;
 import static android.net.InvalidPacketException.ERROR_INVALID_PORT;
 
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.net.util.IpUtils;
-import android.os.Parcel;
 import android.util.Log;
 
 import java.net.InetAddress;
@@ -30,7 +30,6 @@
 /**
  * Represents the actual packets that are sent by the
  * {@link android.net.SocketKeepalive} API.
- *
  * @hide
  */
 @SystemApi
@@ -39,33 +38,37 @@
 
     /** Source IP address */
     @NonNull
-    public final InetAddress srcAddress;
+    private final InetAddress mSrcAddress;
 
     /** Destination IP address */
     @NonNull
-    public final InetAddress dstAddress;
+    private final InetAddress mDstAddress;
 
     /** Source port */
-    public final int srcPort;
+    private final int mSrcPort;
 
     /** Destination port */
-    public final int dstPort;
+    private final int mDstPort;
 
     /** Packet data. A raw byte string of packet data, not including the link-layer header. */
     private final byte[] mPacket;
 
+    // Note: If you add new fields, please modify the parcelling code in the child classes.
+
+
     // This should only be constructed via static factory methods, such as
     // nattKeepalivePacket.
     /**
      * A holding class for data necessary to build a keepalive packet.
      */
-    protected KeepalivePacketData(@NonNull InetAddress srcAddress, int srcPort,
-            @NonNull InetAddress dstAddress, int dstPort,
-                    @NonNull byte[] data) throws InvalidPacketException {
-        this.srcAddress = srcAddress;
-        this.dstAddress = dstAddress;
-        this.srcPort = srcPort;
-        this.dstPort = dstPort;
+    protected KeepalivePacketData(@NonNull InetAddress srcAddress,
+            @IntRange(from = 0, to = 65535) int srcPort, @NonNull InetAddress dstAddress,
+            @IntRange(from = 0, to = 65535) int dstPort,
+            @NonNull byte[] data) throws InvalidPacketException {
+        this.mSrcAddress = srcAddress;
+        this.mDstAddress = dstAddress;
+        this.mSrcPort = srcPort;
+        this.mDstPort = dstPort;
         this.mPacket = data;
 
         // Check we have two IP addresses of the same family.
@@ -82,26 +85,34 @@
         }
     }
 
+    /** Get source IP address. */
+    @NonNull
+    public InetAddress getSrcAddress() {
+        return mSrcAddress;
+    }
+
+    /** Get destination IP address. */
+    @NonNull
+    public InetAddress getDstAddress() {
+        return mDstAddress;
+    }
+
+    /** Get source port number. */
+    public int getSrcPort() {
+        return mSrcPort;
+    }
+
+    /** Get destination port number. */
+    public int getDstPort() {
+        return mDstPort;
+    }
+
+    /**
+     * Returns a byte array of the given packet data.
+     */
     @NonNull
     public byte[] getPacket() {
         return mPacket.clone();
     }
 
-    /** @hide */
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(srcAddress.getHostAddress());
-        out.writeString(dstAddress.getHostAddress());
-        out.writeInt(srcPort);
-        out.writeInt(dstPort);
-        out.writeByteArray(mPacket);
-    }
-
-    /** @hide */
-    protected KeepalivePacketData(Parcel in) {
-        srcAddress = NetworkUtils.numericToInetAddress(in.readString());
-        dstAddress = NetworkUtils.numericToInetAddress(in.readString());
-        srcPort = in.readInt();
-        dstPort = in.readInt();
-        mPacket = in.createByteArray();
-    }
 }
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 732ceb5..7ff954b 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -167,7 +167,19 @@
         this(source, false /* parcelSensitiveFields */);
     }
 
-    private LinkProperties(@Nullable LinkProperties source, boolean parcelSensitiveFields) {
+    /**
+     * Create a copy of a {@link LinkProperties} that may preserve fields that were set
+     * based on the permissions of the process that originally received it.
+     *
+     * <p>By default {@link LinkProperties} does not preserve such fields during parceling, as
+     * they should not be shared outside of the process that receives them without appropriate
+     * checks.
+     * @param parcelSensitiveFields Whether the sensitive fields should be kept when parceling
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    public LinkProperties(@Nullable LinkProperties source, boolean parcelSensitiveFields) {
         mParcelSensitiveFields = parcelSensitiveFields;
         if (source == null) return;
         mIfaceName = source.mIfaceName;
@@ -674,17 +686,29 @@
             route.getDestination(),
             route.getGateway(),
             mIfaceName,
-            route.getType());
+            route.getType(),
+            route.getMtu());
+    }
+
+    private int findRouteIndexByRouteKey(RouteInfo route) {
+        for (int i = 0; i < mRoutes.size(); i++) {
+            if (mRoutes.get(i).getRouteKey().equals(route.getRouteKey())) {
+                return i;
+            }
+        }
+        return -1;
     }
 
     /**
-     * Adds a {@link RouteInfo} to this {@code LinkProperties}, if not present. If the
-     * {@link RouteInfo} had an interface name set and that differs from the interface set for this
-     * {@code LinkProperties} an {@link IllegalArgumentException} will be thrown.  The proper
-     * course is to add either un-named or properly named {@link RouteInfo}.
+     * Adds a {@link RouteInfo} to this {@code LinkProperties}, if a {@link RouteInfo}
+     * with the same {@link RouteInfo.RouteKey} with different properties
+     * (e.g., different MTU), it will be updated. If the {@link RouteInfo} had an
+     * interface name set and that differs from the interface set for this
+     * {@code LinkProperties} an {@link IllegalArgumentException} will be thrown.
+     * The proper course is to add either un-named or properly named {@link RouteInfo}.
      *
      * @param route A {@link RouteInfo} to add to this object.
-     * @return {@code false} if the route was already present, {@code true} if it was added.
+     * @return {@code true} was added or updated, false otherwise.
      */
     public boolean addRoute(@NonNull RouteInfo route) {
         String routeIface = route.getInterface();
@@ -694,11 +718,20 @@
                             + " vs. " + mIfaceName);
         }
         route = routeWithInterface(route);
-        if (!mRoutes.contains(route)) {
+
+        int i = findRouteIndexByRouteKey(route);
+        if (i == -1) {
+            // Route was not present. Add it.
             mRoutes.add(route);
             return true;
+        } else if (mRoutes.get(i).equals(route)) {
+            // Route was present and has same properties. Do nothing.
+            return false;
+        } else {
+            // Route was present and has different properties. Update it.
+            mRoutes.set(i, route);
+            return true;
         }
-        return false;
     }
 
     /**
@@ -706,6 +739,7 @@
      * specify an interface and the interface must match the interface of this
      * {@code LinkProperties}, or it will not be removed.
      *
+     * @param route A {@link RouteInfo} specifying the route to remove.
      * @return {@code true} if the route was removed, {@code false} if it was not present.
      *
      * @hide
@@ -1561,22 +1595,6 @@
     }
 
     /**
-     * Create a copy of this {@link LinkProperties} that will preserve fields that were set
-     * based on the permissions of the process that received this {@link LinkProperties}.
-     *
-     * <p>By default {@link LinkProperties} does not preserve such fields during parceling, as
-     * they should not be shared outside of the process that receives them without appropriate
-     * checks.
-     * @hide
-     */
-    @SystemApi
-    @TestApi
-    @NonNull
-    public LinkProperties makeSensitiveFieldsParcelingCopy() {
-        return new LinkProperties(this, true /* parcelSensitiveFields */);
-    }
-
-    /**
      * Compares this {@code LinkProperties} instance against the target
      * LinkProperties in {@code obj}. Two LinkPropertieses are equal if
      * all their fields are equal in values.
diff --git a/core/java/android/net/NattKeepalivePacketData.java b/core/java/android/net/NattKeepalivePacketData.java
index 29da495..22288b6 100644
--- a/core/java/android/net/NattKeepalivePacketData.java
+++ b/core/java/android/net/NattKeepalivePacketData.java
@@ -94,10 +94,10 @@
 
     /** Write to parcel */
     public void writeToParcel(@NonNull Parcel out, int flags) {
-        out.writeString(srcAddress.getHostAddress());
-        out.writeString(dstAddress.getHostAddress());
-        out.writeInt(srcPort);
-        out.writeInt(dstPort);
+        out.writeString(getSrcAddress().getHostAddress());
+        out.writeString(getDstAddress().getHostAddress());
+        out.writeInt(getSrcPort());
+        out.writeInt(getDstPort());
     }
 
     /** Parcelable Creator */
@@ -115,7 +115,7 @@
                                     dstAddress, dstPort);
                     } catch (InvalidPacketException e) {
                         throw new IllegalArgumentException(
-                                "Invalid NAT-T keepalive data: " + e.error);
+                                "Invalid NAT-T keepalive data: " + e.getError());
                     }
                 }
 
@@ -128,14 +128,16 @@
     public boolean equals(@Nullable final Object o) {
         if (!(o instanceof NattKeepalivePacketData)) return false;
         final NattKeepalivePacketData other = (NattKeepalivePacketData) o;
-        return this.srcAddress.equals(other.srcAddress)
-            && this.dstAddress.equals(other.dstAddress)
-            && this.srcPort == other.srcPort
-            && this.dstPort == other.dstPort;
+        final InetAddress srcAddress = getSrcAddress();
+        final InetAddress dstAddress = getDstAddress();
+        return srcAddress.equals(other.getSrcAddress())
+            && dstAddress.equals(other.getDstAddress())
+            && getSrcPort() == other.getSrcPort()
+            && getDstPort() == other.getDstPort();
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(srcAddress, dstAddress, srcPort, dstPort);
+        return Objects.hash(getSrcAddress(), getDstAddress(), getSrcPort(), getDstPort());
     }
 }
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 8d1ab33..3d641f5 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -27,6 +27,7 @@
 import android.system.OsConstants;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.okhttp.internalandroidapi.Dns;
 import com.android.okhttp.internalandroidapi.HttpURLConnectionFactory;
 
@@ -61,17 +62,18 @@
 public class Network implements Parcelable {
 
     /**
+     * The unique id of the network.
      * @hide
      */
-    @SystemApi
+    @UnsupportedAppUsage
     public final int netId;
 
     // Objects used to perform per-network operations such as getSocketFactory
     // and openConnection, and a lock to protect access to them.
     private volatile NetworkBoundSocketFactory mNetworkBoundSocketFactory = null;
-    // mLock should be used to control write access to mUrlConnectionFactory.
-    // maybeInitUrlConnectionFactory() must be called prior to reading this field.
-    private volatile HttpURLConnectionFactory mUrlConnectionFactory;
+    // mUrlConnectionFactory is initialized lazily when it is first needed.
+    @GuardedBy("mLock")
+    private HttpURLConnectionFactory mUrlConnectionFactory;
     private final Object mLock = new Object();
 
     // Default connection pool values. These are evaluated at startup, just
@@ -169,6 +171,17 @@
     }
 
     /**
+     * Get the unique id of the network.
+     *
+     * @hide
+     */
+    @TestApi
+    @SystemApi
+    public int getNetId() {
+        return netId;
+    }
+
+    /**
      * Returns a netid marked with the Private DNS bypass flag.
      *
      * This flag must be kept in sync with the NETID_USE_LOCAL_NAMESERVERS flag
@@ -283,36 +296,16 @@
         return mNetworkBoundSocketFactory;
     }
 
-    // TODO: This creates a connection pool and host resolver for
-    // every Network object, instead of one for every NetId. This is
-    // suboptimal, because an app could potentially have more than one
-    // Network object for the same NetId, causing increased memory footprint
-    // and performance penalties due to lack of connection reuse (connection
-    // setup time, congestion window growth time, etc.).
-    //
-    // Instead, investigate only having one connection pool and host resolver
-    // for every NetId, perhaps by using a static HashMap of NetIds to
-    // connection pools and host resolvers. The tricky part is deciding when
-    // to remove a map entry; a WeakHashMap shouldn't be used because whether
-    // a Network is referenced doesn't correlate with whether a new Network
-    // will be instantiated in the near future with the same NetID. A good
-    // solution would involve purging empty (or when all connections are timed
-    // out) ConnectionPools.
-    private void maybeInitUrlConnectionFactory() {
-        synchronized (mLock) {
-            if (mUrlConnectionFactory == null) {
-                // Set configuration on the HttpURLConnectionFactory that will be good for all
-                // connections created by this Network. Configuration that might vary is left
-                // until openConnection() and passed as arguments.
-                Dns dnsLookup = hostname -> Arrays.asList(Network.this.getAllByName(hostname));
-                HttpURLConnectionFactory urlConnectionFactory = new HttpURLConnectionFactory();
-                urlConnectionFactory.setDns(dnsLookup); // Let traffic go via dnsLookup
-                // A private connection pool just for this Network.
-                urlConnectionFactory.setNewConnectionPool(httpMaxConnections,
-                        httpKeepAliveDurationMs, TimeUnit.MILLISECONDS);
-                mUrlConnectionFactory = urlConnectionFactory;
-            }
-        }
+    private static HttpURLConnectionFactory createUrlConnectionFactory(Dns dnsLookup) {
+        // Set configuration on the HttpURLConnectionFactory that will be good for all
+        // connections created by this Network. Configuration that might vary is left
+        // until openConnection() and passed as arguments.
+        HttpURLConnectionFactory urlConnectionFactory = new HttpURLConnectionFactory();
+        urlConnectionFactory.setDns(dnsLookup); // Let traffic go via dnsLookup
+        // A private connection pool just for this Network.
+        urlConnectionFactory.setNewConnectionPool(httpMaxConnections,
+                httpKeepAliveDurationMs, TimeUnit.MILLISECONDS);
+        return urlConnectionFactory;
     }
 
     /**
@@ -353,9 +346,31 @@
      */
     public URLConnection openConnection(URL url, java.net.Proxy proxy) throws IOException {
         if (proxy == null) throw new IllegalArgumentException("proxy is null");
-        maybeInitUrlConnectionFactory();
+        // TODO: This creates a connection pool and host resolver for
+        // every Network object, instead of one for every NetId. This is
+        // suboptimal, because an app could potentially have more than one
+        // Network object for the same NetId, causing increased memory footprint
+        // and performance penalties due to lack of connection reuse (connection
+        // setup time, congestion window growth time, etc.).
+        //
+        // Instead, investigate only having one connection pool and host resolver
+        // for every NetId, perhaps by using a static HashMap of NetIds to
+        // connection pools and host resolvers. The tricky part is deciding when
+        // to remove a map entry; a WeakHashMap shouldn't be used because whether
+        // a Network is referenced doesn't correlate with whether a new Network
+        // will be instantiated in the near future with the same NetID. A good
+        // solution would involve purging empty (or when all connections are timed
+        // out) ConnectionPools.
+        final HttpURLConnectionFactory urlConnectionFactory;
+        synchronized (mLock) {
+            if (mUrlConnectionFactory == null) {
+                Dns dnsLookup = hostname -> Arrays.asList(getAllByName(hostname));
+                mUrlConnectionFactory = createUrlConnectionFactory(dnsLookup);
+            }
+            urlConnectionFactory = mUrlConnectionFactory;
+        }
         SocketFactory socketFactory = getSocketFactory();
-        return mUrlConnectionFactory.openConnection(url, socketFactory, proxy);
+        return urlConnectionFactory.openConnection(url, socketFactory, proxy);
     }
 
     /**
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index fef353f..5c754a1 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -78,6 +78,7 @@
     /**
      * The ID of the {@link NetworkProvider} that created this object, or
      * {@link NetworkProvider#ID_NONE} if unknown.
+     * @hide
      */
     public final int providerId;
 
@@ -584,6 +585,7 @@
      *
      * @deprecated this is for backward compatibility only.
      * @param legacySubtype the legacy subtype.
+     * @hide
      */
     @Deprecated
     public void setLegacySubtype(final int legacySubtype, @NonNull final String legacySubtypeName) {
@@ -608,6 +610,7 @@
      *
      * @deprecated this is for backward compatibility only.
      * @param extraInfo the ExtraInfo.
+     * @hide
      */
     @Deprecated
     public void setLegacyExtraInfo(@Nullable final String extraInfo) {
@@ -711,6 +714,7 @@
     /**
      * Called when ConnectivityService request a bandwidth update. The parent factory
      * shall try to overwrite this method and produce a bandwidth update if capable.
+     * @hide
      */
     public void onBandwidthUpdateRequested() {
         pollLceData();
diff --git a/core/java/android/net/NetworkAgentConfig.java b/core/java/android/net/NetworkAgentConfig.java
index 7e2db4a..ca9328a 100644
--- a/core/java/android/net/NetworkAgentConfig.java
+++ b/core/java/android/net/NetworkAgentConfig.java
@@ -108,6 +108,7 @@
     /**
      *
      * @return whether the sign in to network notification is enabled by this configuration.
+     * @hide
      */
     public boolean isProvisioningNotificationEnabled() {
         return !provisioningNotificationDisabled;
@@ -122,6 +123,7 @@
 
     /**
      * @return the subscriber ID, or null if none.
+     * @hide
      */
     @Nullable
     public String getSubscriberId() {
@@ -138,6 +140,7 @@
 
     /**
      * @return whether NAT64 prefix detection is enabled.
+     * @hide
      */
     public boolean isNat64DetectionEnabled() {
         return !skip464xlat;
@@ -247,6 +250,7 @@
          * Sets the subscriber ID for this network.
          *
          * @return this builder, to facilitate chaining.
+         * @hide
          */
         @NonNull
         public Builder setSubscriberId(@Nullable String subscriberId) {
@@ -259,6 +263,7 @@
          * and reduce idle traffic on networks that are known to be IPv6-only without a NAT64.
          *
          * @return this builder, to facilitate chaining.
+         * @hide
          */
         @NonNull
         public Builder disableNat64Detection() {
@@ -271,6 +276,7 @@
          * perform its own carrier-specific provisioning procedure.
          *
          * @return this builder, to facilitate chaining.
+         * @hide
          */
         @NonNull
         public Builder disableProvisioningNotification() {
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 873d6e914..ad1e501 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -19,6 +19,7 @@
 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;
@@ -32,14 +33,13 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.BitUtils;
 import com.android.internal.util.Preconditions;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.Arrays;
 import java.util.Objects;
 import java.util.Set;
 import java.util.StringJoiner;
@@ -88,6 +88,7 @@
     /**
      * Completely clears the contents of this object, removing even the capabilities that are set
      * by default when the object is constructed.
+     * @hide
      */
     public void clearAll() {
         mNetworkCapabilities = mTransportTypes = mUnwantedNetworkCapabilities = 0;
@@ -96,7 +97,7 @@
         mTransportInfo = null;
         mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
         mUids = null;
-        mAdministratorUids.clear();
+        mAdministratorUids = new int[0];
         mOwnerUid = Process.INVALID_UID;
         mSSID = null;
         mPrivateDnsBroken = false;
@@ -414,12 +415,27 @@
             | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY);
 
     /**
+     * Capabilities that are allowed for test networks. This list must be set so that it is safe
+     * for an unprivileged user to create a network with these capabilities via shell. As such,
+     * it must never contain capabilities that are generally useful to the system, such as
+     * INTERNET, IMS, SUPL, etc.
+     */
+    private static final long TEST_NETWORKS_ALLOWED_CAPABILITIES =
+            (1 << NET_CAPABILITY_NOT_METERED)
+            | (1 << NET_CAPABILITY_NOT_RESTRICTED)
+            | (1 << NET_CAPABILITY_NOT_VPN)
+            | (1 << NET_CAPABILITY_NOT_ROAMING)
+            | (1 << NET_CAPABILITY_NOT_CONGESTED)
+            | (1 << NET_CAPABILITY_NOT_SUSPENDED);
+
+    /**
      * Adds the given capability to this {@code NetworkCapability} instance.
-     * Multiple capabilities may be applied sequentially.  Note that when searching
-     * for a network to satisfy a request, all capabilities requested must be satisfied.
+     * Note that when searching for a network to satisfy a request, all capabilities
+     * requested must be satisfied.
      *
      * @param capability the capability to be added.
      * @return This NetworkCapabilities instance, to facilitate chaining.
+     * @hide
      */
     public @NonNull NetworkCapabilities addCapability(@NetCapability int capability) {
         // If the given capability was previously added to the list of unwanted capabilities
@@ -434,9 +450,9 @@
 
     /**
      * Adds the given capability to the list of unwanted capabilities of this
-     * {@code NetworkCapability} instance.  Multiple unwanted capabilities may be applied
-     * sequentially.  Note that when searching for a network to satisfy a request, the network
-     * must not contain any capability from unwanted capability list.
+     * {@code NetworkCapability} instance. Note that when searching for a network to
+     * satisfy a request, the network must not contain any capability from unwanted capability
+     * list.
      * <p>
      * If the capability was previously added to the list of required capabilities (for
      * example, it was there by default or added using {@link #addCapability(int)} method), then
@@ -456,6 +472,7 @@
      *
      * @param capability the capability to be removed.
      * @return This NetworkCapabilities instance, to facilitate chaining.
+     * @hide
      */
     public @NonNull NetworkCapabilities removeCapability(@NetCapability int capability) {
         // Note that this method removes capabilities that were added via addCapability(int),
@@ -470,7 +487,7 @@
     /**
      * Sets (or clears) the given capability on this {@link NetworkCapabilities}
      * instance.
-     *
+     * @hide
      */
     public @NonNull NetworkCapabilities setCapability(@NetCapability int capability,
             boolean value) {
@@ -613,7 +630,6 @@
      * @return {@code true} if the network should be restricted.
      * @hide
      */
-    @SystemApi
     public boolean deduceRestrictedCapability() {
         // Check if we have any capability that forces the network to be restricted.
         final boolean forceRestrictedCapability =
@@ -644,6 +660,21 @@
     }
 
     /**
+     * Test networks have strong restrictions on what capabilities they can have. Enforce these
+     * restrictions.
+     * @hide
+     */
+    public void restrictCapabilitesForTestNetwork() {
+        final long originalCapabilities = mNetworkCapabilities;
+        final NetworkSpecifier originalSpecifier = mNetworkSpecifier;
+        clearAll();
+        // Reset the transports to only contain TRANSPORT_TEST.
+        mTransportTypes = (1 << TRANSPORT_TEST);
+        mNetworkCapabilities = originalCapabilities & TEST_NETWORKS_ALLOWED_CAPABILITIES;
+        mNetworkSpecifier = originalSpecifier;
+    }
+
+    /**
      * Representing the transport type.  Apps should generally not care about transport.  A
      * request for a fast internet connection could be satisfied by a number of different
      * transports.  If any are specified here it will be satisfied a Network that matches
@@ -731,7 +762,7 @@
 
     /**
      * Adds the given transport type to this {@code NetworkCapability} instance.
-     * Multiple transports may be applied sequentially.  Note that when searching
+     * Multiple transports may be applied.  Note that when searching
      * for a network to satisfy a request, any listed in the request will satisfy the request.
      * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
      * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
@@ -740,6 +771,7 @@
      *
      * @param transportType the transport type to be added.
      * @return This NetworkCapabilities instance, to facilitate chaining.
+     * @hide
      */
     public @NonNull NetworkCapabilities addTransportType(@Transport int transportType) {
         checkValidTransportType(transportType);
@@ -852,6 +884,7 @@
 
     /**
      * Set the UID of the owner app.
+     * @hide
      */
     public @NonNull NetworkCapabilities setOwnerUid(final int uid) {
         mOwnerUid = uid;
@@ -869,6 +902,8 @@
      *   <li>The user's location toggle is on
      * </ol>
      *
+     * Instances of NetworkCapabilities sent to apps without the appropriate permissions will
+     * have this field cleared out.
      */
     public int getOwnerUid() {
         return mOwnerUid;
@@ -885,10 +920,10 @@
      * empty unless the destination is 1) the System Server, or 2) Telephony. In either case, the
      * receiving entity must have the ACCESS_FINE_LOCATION permission and target R+.
      */
-    private final List<Integer> mAdministratorUids = new ArrayList<>();
+    private int[] mAdministratorUids = new int[0];
 
     /**
-     * Sets the list of UIDs that are administrators of this network.
+     * Sets the int[] of UIDs that are administrators of this network.
      *
      * <p>UIDs included in administratorUids gain administrator privileges over this Network.
      * Examples of UIDs that should be included in administratorUids are:
@@ -907,24 +942,22 @@
      * @hide
      */
     @NonNull
-    @SystemApi
-    public NetworkCapabilities setAdministratorUids(
-            @NonNull final List<Integer> administratorUids) {
-        mAdministratorUids.clear();
-        mAdministratorUids.addAll(administratorUids);
+    public NetworkCapabilities setAdministratorUids(@NonNull final int[] administratorUids) {
+        mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length);
         return this;
     }
 
     /**
-     * Retrieves the list of UIDs that are administrators of this Network.
+     * Retrieves the UIDs that are administrators of this Network.
      *
-     * @return the List of UIDs that are administrators of this Network
+     * @return the int[] of UIDs that are administrators of this Network
      * @hide
      */
     @NonNull
     @SystemApi
-    public List<Integer> getAdministratorUids() {
-        return Collections.unmodifiableList(mAdministratorUids);
+    @TestApi
+    public int[] getAdministratorUids() {
+        return Arrays.copyOf(mAdministratorUids, mAdministratorUids.length);
     }
 
     /**
@@ -945,15 +978,10 @@
      * Sets the upstream bandwidth for this network in Kbps.  This always only refers to
      * the estimated first hop transport bandwidth.
      * <p>
-     * Note that when used to request a network, this specifies the minimum acceptable.
-     * When received as the state of an existing network this specifies the typical
-     * first hop bandwidth expected.  This is never measured, but rather is inferred
-     * from technology type and other link parameters.  It could be used to differentiate
-     * between very slow 1xRTT cellular links and other faster networks or even between
-     * 802.11b vs 802.11AC wifi technologies.  It should not be used to differentiate between
-     * fast backhauls and slow backhauls.
+     * {@see Builder#setLinkUpstreamBandwidthKbps}
      *
      * @param upKbps the estimated first hop upstream (device to network) bandwidth.
+     * @hide
      */
     public @NonNull NetworkCapabilities setLinkUpstreamBandwidthKbps(int upKbps) {
         mLinkUpBandwidthKbps = upKbps;
@@ -974,15 +1002,10 @@
      * Sets the downstream bandwidth for this network in Kbps.  This always only refers to
      * the estimated first hop transport bandwidth.
      * <p>
-     * Note that when used to request a network, this specifies the minimum acceptable.
-     * When received as the state of an existing network this specifies the typical
-     * first hop bandwidth expected.  This is never measured, but rather is inferred
-     * from technology type and other link parameters.  It could be used to differentiate
-     * between very slow 1xRTT cellular links and other faster networks or even between
-     * 802.11b vs 802.11AC wifi technologies.  It should not be used to differentiate between
-     * fast backhauls and slow backhauls.
+     * {@see Builder#setLinkUpstreamBandwidthKbps}
      *
      * @param downKbps the estimated first hop downstream (network to device) bandwidth.
+     * @hide
      */
     public @NonNull NetworkCapabilities setLinkDownstreamBandwidthKbps(int downKbps) {
         mLinkDownBandwidthKbps = downKbps;
@@ -1041,6 +1064,7 @@
      * @param networkSpecifier A concrete, parcelable framework class that extends
      *                         NetworkSpecifier.
      * @return This NetworkCapabilities instance, to facilitate chaining.
+     * @hide
      */
     public @NonNull NetworkCapabilities setNetworkSpecifier(
             @NonNull NetworkSpecifier networkSpecifier) {
@@ -1062,7 +1086,6 @@
      * @return This NetworkCapabilities instance, to facilitate chaining.
      * @hide
      */
-    @SystemApi
     public @NonNull NetworkCapabilities setTransportInfo(@NonNull TransportInfo transportInfo) {
         mTransportInfo = transportInfo;
         return this;
@@ -1072,7 +1095,7 @@
      * Gets the optional bearer specific network specifier. May be {@code null} if not set.
      *
      * @return The optional {@link NetworkSpecifier} specifying the bearer specific network
-     *         specifier or {@code null}. See {@link #setNetworkSpecifier}.
+     *         specifier or {@code null}.
      */
     public @Nullable NetworkSpecifier getNetworkSpecifier() {
         return mNetworkSpecifier;
@@ -1142,6 +1165,7 @@
      * effect when requesting a callback.
      *
      * @param signalStrength the bearer-specific signal strength.
+     * @hide
      */
     public @NonNull NetworkCapabilities setSignalStrength(int signalStrength) {
         mSignalStrength = signalStrength;
@@ -1368,7 +1392,6 @@
      * Sets the SSID of this network.
      * @hide
      */
-    @SystemApi
     public @NonNull NetworkCapabilities setSSID(@Nullable String ssid) {
         mSSID = ssid;
         return this;
@@ -1379,7 +1402,8 @@
      * @hide
      */
     @SystemApi
-    public @Nullable String getSSID() {
+    @TestApi
+    public @Nullable String getSsid() {
         return mSSID;
     }
 
@@ -1585,7 +1609,7 @@
         dest.writeArraySet(mUids);
         dest.writeString(mSSID);
         dest.writeBoolean(mPrivateDnsBroken);
-        dest.writeList(mAdministratorUids);
+        dest.writeIntArray(mAdministratorUids);
         dest.writeInt(mOwnerUid);
         dest.writeInt(mRequestorUid);
         dest.writeString(mRequestorPackageName);
@@ -1609,7 +1633,7 @@
                         null /* ClassLoader, null for default */);
                 netCap.mSSID = in.readString();
                 netCap.mPrivateDnsBroken = in.readBoolean();
-                netCap.setAdministratorUids(in.readArrayList(null));
+                netCap.setAdministratorUids(in.createIntArray());
                 netCap.mOwnerUid = in.readInt();
                 netCap.mRequestorUid = in.readInt();
                 netCap.mRequestorPackageName = in.readString();
@@ -1666,8 +1690,8 @@
             sb.append(" OwnerUid: ").append(mOwnerUid);
         }
 
-        if (!mAdministratorUids.isEmpty()) {
-            sb.append(" AdministratorUids: ").append(mAdministratorUids);
+        if (mAdministratorUids.length == 0) {
+            sb.append(" AdministratorUids: ").append(Arrays.toString(mAdministratorUids));
         }
 
         if (null != mSSID) {
@@ -1859,25 +1883,32 @@
     }
 
     /**
-     * Set the uid of the app making the request.
+     * Set the UID of the app making the request.
      *
-     * Note: This works only for {@link NetworkAgent} instances. Any capabilities passed in
-     * via the public {@link ConnectivityManager} API's will have this field overwritten.
+     * For instances of NetworkCapabilities representing a request, sets the
+     * UID of the app making the request. For a network created by the system,
+     * sets the UID of the only app whose requests can match this network.
+     * This can be set to {@link Process#INVALID_UID} if there is no such app,
+     * or if this instance of NetworkCapabilities is about to be sent to a
+     * party that should not learn about this.
      *
      * @param uid UID of the app.
      * @hide
      */
-    @SystemApi
     public @NonNull NetworkCapabilities setRequestorUid(int uid) {
         mRequestorUid = uid;
         return this;
     }
 
     /**
-     * @return the uid of the app making the request.
+     * Returns the UID of the app making the request.
      *
-     * Note: This could return {@link Process#INVALID_UID} if the {@link NetworkRequest}
-     * object was not obtained from {@link ConnectivityManager}.
+     * For a NetworkRequest being made by an app, contains the app's UID. For a network
+     * created by the system, contains the UID of the only app whose requests can match
+     * this network, or {@link Process#INVALID_UID} if none or if the
+     * caller does not have permission to learn about this.
+     *
+     * @return the uid of the app making the request.
      * @hide
      */
     public int getRequestorUid() {
@@ -1887,23 +1918,29 @@
     /**
      * Set the package name of the app making the request.
      *
-     * Note: This works only for {@link NetworkAgent} instances. Any capabilities passed in
-     * via the public {@link ConnectivityManager} API's will have this field overwritten.
+     * For instances of NetworkCapabilities representing a request, sets the
+     * package name of the app making the request. For a network created by the system,
+     * sets the package name of the only app whose requests can match this network.
+     * This can be set to null if there is no such app, or if this instance of
+     * NetworkCapabilities is about to be sent to a party that should not learn about this.
      *
      * @param packageName package name of the app.
      * @hide
      */
-    @SystemApi
     public @NonNull NetworkCapabilities setRequestorPackageName(@NonNull String packageName) {
         mRequestorPackageName = packageName;
         return this;
     }
 
     /**
-     * @return the package name of the app making the request.
+     * Returns the package name of the app making the request.
      *
-     * Note: This could return {@code null} if the {@link NetworkRequest} object was not obtained
-     * from {@link ConnectivityManager}.
+     * For a NetworkRequest being made by an app, contains the app's package name. For a
+     * network created by the system, contains the package name of the only app whose
+     * requests can match this network, or null if none or if the caller does not have
+     * permission to learn about this.
+     *
+     * @return the package name of the app making the request.
      * @hide
      */
     @Nullable
@@ -1912,9 +1949,9 @@
     }
 
     /**
-     * Set the uid and package name of the app making the request.
+     * Set the uid and package name of the app causing this network to exist.
      *
-     * Note: This is intended to be only invoked from within connectivitiy service.
+     * {@see #setRequestorUid} and {@link #setRequestorPackageName}
      *
      * @param uid UID of the app.
      * @param packageName package name of the app.
@@ -1973,4 +2010,316 @@
         return mRequestorUid == nc.mRequestorUid
                 && TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName);
     }
+
+    /**
+     * Builder class for NetworkCapabilities.
+     *
+     * This class is mainly for for {@link NetworkAgent} instances to use. Many fields in
+     * the built class require holding a signature permission to use - mostly
+     * {@link android.Manifest.permission.NETWORK_FACTORY}, but refer to the specific
+     * description of each setter. As this class lives entirely in app space it does not
+     * enforce these restrictions itself but the system server clears out the relevant
+     * fields when receiving a NetworkCapabilities object from a caller without the
+     * appropriate permission.
+     *
+     * Apps don't use this builder directly. Instead, they use {@link NetworkRequest} via
+     * its builder object.
+     *
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    public static class Builder {
+        private final NetworkCapabilities mCaps;
+
+        /**
+         * Creates a new Builder to construct NetworkCapabilities objects.
+         */
+        public Builder() {
+            mCaps = new NetworkCapabilities();
+        }
+
+        /**
+         * Creates a new Builder of NetworkCapabilities from an existing instance.
+         */
+        public Builder(@NonNull final NetworkCapabilities nc) {
+            Objects.requireNonNull(nc);
+            mCaps = new NetworkCapabilities(nc);
+        }
+
+        /**
+         * Adds the given transport type.
+         *
+         * Multiple transports may be added. Note that when searching for a network to satisfy a
+         * request, satisfying any of the transports listed in the request will satisfy the request.
+         * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
+         * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
+         * to be selected. This is logically different than
+         * {@code NetworkCapabilities.NET_CAPABILITY_*}.
+         *
+         * @param transportType the transport type to be added or removed.
+         * @return this builder
+         */
+        @NonNull
+        public Builder addTransportType(@Transport int transportType) {
+            checkValidTransportType(transportType);
+            mCaps.addTransportType(transportType);
+            return this;
+        }
+
+        /**
+         * Removes the given transport type.
+         *
+         * {@see #addTransportType}.
+         *
+         * @param transportType the transport type to be added or removed.
+         * @return this builder
+         */
+        @NonNull
+        public Builder removeTransportType(@Transport int transportType) {
+            checkValidTransportType(transportType);
+            mCaps.removeTransportType(transportType);
+            return this;
+        }
+
+        /**
+         * Adds the given capability.
+         *
+         * @param capability the capability
+         * @return this builder
+         */
+        @NonNull
+        public Builder addCapability(@NetCapability final int capability) {
+            mCaps.setCapability(capability, true);
+            return this;
+        }
+
+        /**
+         * Removes the given capability.
+         *
+         * @param capability the capability
+         * @return this builder
+         */
+        @NonNull
+        public Builder removeCapability(@NetCapability final int capability) {
+            mCaps.setCapability(capability, false);
+            return this;
+        }
+
+        /**
+         * Sets the owner UID.
+         *
+         * The default value is {@link Process#INVALID_UID}. Pass this value to reset.
+         *
+         * Note: for security the system will clear out this field when received from a
+         * non-privileged source.
+         *
+         * @param ownerUid the owner UID
+         * @return this builder
+         */
+        @NonNull
+        @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+        public Builder setOwnerUid(final int ownerUid) {
+            mCaps.setOwnerUid(ownerUid);
+            return this;
+        }
+
+        /**
+         * Sets the list of UIDs that are administrators of this network.
+         *
+         * <p>UIDs included in administratorUids gain administrator privileges over this
+         * Network. Examples of UIDs that should be included in administratorUids are:
+         * <ul>
+         *     <li>Carrier apps with privileges for the relevant subscription
+         *     <li>Active VPN apps
+         *     <li>Other application groups with a particular Network-related role
+         * </ul>
+         *
+         * <p>In general, user-supplied networks (such as WiFi networks) do not have
+         * administrators.
+         *
+         * <p>An app is granted owner privileges over Networks that it supplies. The owner
+         * UID MUST always be included in administratorUids.
+         *
+         * The default value is the empty array. Pass an empty array to reset.
+         *
+         * Note: for security the system will clear out this field when received from a
+         * non-privileged source, such as an app using reflection to call this or
+         * mutate the member in the built object.
+         *
+         * @param administratorUids the UIDs to be set as administrators of this Network.
+         * @return this builder
+         */
+        @NonNull
+        @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+        public Builder setAdministratorUids(@NonNull final int[] administratorUids) {
+            Objects.requireNonNull(administratorUids);
+            mCaps.setAdministratorUids(administratorUids);
+            return this;
+        }
+
+        /**
+         * Sets the upstream bandwidth of the link.
+         *
+         * Sets the upstream bandwidth for this network in Kbps. This always only refers to
+         * the estimated first hop transport bandwidth.
+         * <p>
+         * Note that when used to request a network, this specifies the minimum acceptable.
+         * When received as the state of an existing network this specifies the typical
+         * first hop bandwidth expected. This is never measured, but rather is inferred
+         * from technology type and other link parameters. It could be used to differentiate
+         * between very slow 1xRTT cellular links and other faster networks or even between
+         * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
+         * fast backhauls and slow backhauls.
+         *
+         * @param upKbps the estimated first hop upstream (device to network) bandwidth.
+         * @return this builder
+         */
+        @NonNull
+        public Builder setLinkUpstreamBandwidthKbps(final int upKbps) {
+            mCaps.setLinkUpstreamBandwidthKbps(upKbps);
+            return this;
+        }
+
+        /**
+         * Sets the downstream bandwidth for this network in Kbps. This always only refers to
+         * the estimated first hop transport bandwidth.
+         * <p>
+         * Note that when used to request a network, this specifies the minimum acceptable.
+         * When received as the state of an existing network this specifies the typical
+         * first hop bandwidth expected. This is never measured, but rather is inferred
+         * from technology type and other link parameters. It could be used to differentiate
+         * between very slow 1xRTT cellular links and other faster networks or even between
+         * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
+         * fast backhauls and slow backhauls.
+         *
+         * @param downKbps the estimated first hop downstream (network to device) bandwidth.
+         * @return this builder
+         */
+        @NonNull
+        public Builder setLinkDownstreamBandwidthKbps(final int downKbps) {
+            mCaps.setLinkDownstreamBandwidthKbps(downKbps);
+            return this;
+        }
+
+        /**
+         * Sets the optional bearer specific network specifier.
+         * This has no meaning if a single transport is also not specified, so calling
+         * this without a single transport set will generate an exception, as will
+         * subsequently adding or removing transports after this is set.
+         * </p>
+         *
+         * @param specifier a concrete, parcelable framework class that extends NetworkSpecifier,
+         *        or null to clear it.
+         * @return this builder
+         */
+        @NonNull
+        public Builder setNetworkSpecifier(@Nullable final NetworkSpecifier specifier) {
+            mCaps.setNetworkSpecifier(specifier);
+            return this;
+        }
+
+        /**
+         * Sets the optional transport specific information.
+         *
+         * @param info A concrete, parcelable framework class that extends {@link TransportInfo},
+         *             or null to clear it.
+         * @return this builder
+         */
+        @NonNull
+        public Builder setTransportInfo(@Nullable final TransportInfo info) {
+            mCaps.setTransportInfo(info);
+            return this;
+        }
+
+        /**
+         * Sets the signal strength. This is a signed integer, with higher values indicating a
+         * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the
+         * same RSSI units reported by wifi code.
+         * <p>
+         * Note that when used to register a network callback, this specifies the minimum
+         * acceptable signal strength. When received as the state of an existing network it
+         * specifies the current value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means
+         * no value when received and has no effect when requesting a callback.
+         *
+         * Note: for security the system will throw if it receives a NetworkRequest where
+         * the underlying NetworkCapabilities has this member set from a source that does
+         * not hold the {@link android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP}
+         * permission. Apps with this permission can use this indirectly through
+         * {@link android.net.NetworkRequest}.
+         *
+         * @param signalStrength the bearer-specific signal strength.
+         * @return this builder
+         */
+        @NonNull
+        @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP)
+        public Builder setSignalStrength(final int signalStrength) {
+            mCaps.setSignalStrength(signalStrength);
+            return this;
+        }
+
+        /**
+         * Sets the SSID of this network.
+         *
+         * Note: for security the system will clear out this field when received from a
+         * non-privileged source, like an app using reflection to set this.
+         *
+         * @param ssid the SSID, or null to clear it.
+         * @return this builder
+         */
+        @NonNull
+        @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+        public Builder setSsid(@Nullable final String ssid) {
+            mCaps.setSSID(ssid);
+            return this;
+        }
+
+        /**
+         * Set the uid of the app causing this network to exist.
+         *
+         * Note: for security the system will clear out this field when received from a
+         * non-privileged source.
+         *
+         * @param uid UID of the app.
+         * @return this builder
+         */
+        @NonNull
+        @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+        public Builder setRequestorUid(final int uid) {
+            mCaps.setRequestorUid(uid);
+            return this;
+        }
+
+        /**
+         * Set the package name of the app causing this network to exist.
+         *
+         * Note: for security the system will clear out this field when received from a
+         * non-privileged source.
+         *
+         * @param packageName package name of the app, or null to clear it.
+         * @return this builder
+         */
+        @NonNull
+        @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+        public Builder setRequestorPackageName(@Nullable final String packageName) {
+            mCaps.setRequestorPackageName(packageName);
+            return this;
+        }
+
+        /**
+         * Builds the instance of the capabilities.
+         *
+         * @return the built instance of NetworkCapabilities.
+         */
+        @NonNull
+        public NetworkCapabilities build() {
+            if (mCaps.getOwnerUid() != Process.INVALID_UID) {
+                if (!ArrayUtils.contains(mCaps.getAdministratorUids(), mCaps.getOwnerUid())) {
+                    throw new IllegalStateException("The owner UID must be included in "
+                            + " administrator UIDs.");
+                }
+            }
+            return new NetworkCapabilities(mCaps);
+        }
+    }
 }
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index febc730..4edbcd0 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -25,6 +25,7 @@
 import android.net.wifi.WifiManager;
 import android.os.Build;
 import android.service.NetworkIdentityProto;
+import android.telephony.Annotation.NetworkType;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
@@ -39,16 +40,6 @@
 public class NetworkIdentity implements Comparable<NetworkIdentity> {
     private static final String TAG = "NetworkIdentity";
 
-    /**
-     * When enabled, combine all {@link #mSubType} together under
-     * {@link #SUBTYPE_COMBINED}.
-     *
-     * @deprecated we no longer offer to collect statistics on a per-subtype
-     *             basis; this is always disabled.
-     */
-    @Deprecated
-    public static final boolean COMBINE_SUBTYPE_ENABLED = true;
-
     public static final int SUBTYPE_COMBINED = -1;
 
     final int mType;
@@ -63,7 +54,7 @@
             int type, int subType, String subscriberId, String networkId, boolean roaming,
             boolean metered, boolean defaultNetwork) {
         mType = type;
-        mSubType = COMBINE_SUBTYPE_ENABLED ? SUBTYPE_COMBINED : subType;
+        mSubType = subType;
         mSubscriberId = subscriberId;
         mNetworkId = networkId;
         mRoaming = roaming;
@@ -95,7 +86,7 @@
         final StringBuilder builder = new StringBuilder("{");
         builder.append("type=").append(getNetworkTypeName(mType));
         builder.append(", subType=");
-        if (COMBINE_SUBTYPE_ENABLED) {
+        if (mSubType == SUBTYPE_COMBINED) {
             builder.append("COMBINED");
         } else {
             builder.append(mSubType);
@@ -187,13 +178,14 @@
     }
 
     /**
-     * Build a {@link NetworkIdentity} from the given {@link NetworkState},
-     * assuming that any mobile networks are using the current IMSI.
+     * 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.
      */
     public static NetworkIdentity buildNetworkIdentity(Context context, NetworkState state,
-            boolean defaultNetwork) {
+            boolean defaultNetwork, @NetworkType int subType) {
         final int type = state.networkInfo.getType();
-        final int subType = state.networkInfo.getSubtype();
 
         String subscriberId = null;
         String networkId = null;
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 08fe159..d752901 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -22,6 +22,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.Annotation.NetworkType;
+import android.text.TextUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -538,7 +539,7 @@
     @Override
     public String toString() {
         synchronized (this) {
-            StringBuilder builder = new StringBuilder("[");
+            final StringBuilder builder = new StringBuilder("[");
             builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()).
             append("], state: ").append(mState).append("/").append(mDetailedState).
             append(", reason: ").append(mReason == null ? "(unspecified)" : mReason).
@@ -551,6 +552,32 @@
         }
     }
 
+    /**
+     * Returns a brief summary string suitable for debugging.
+     * @hide
+     */
+    public String toShortString() {
+        synchronized (this) {
+            final StringBuilder builder = new StringBuilder();
+            builder.append(getTypeName());
+
+            final String subtype = getSubtypeName();
+            if (!TextUtils.isEmpty(subtype)) {
+                builder.append("[").append(subtype).append("]");
+            }
+
+            builder.append(" ");
+            builder.append(mDetailedState);
+            if (mIsRoaming) {
+                builder.append(" ROAMING");
+            }
+            if (mExtraInfo != null) {
+                builder.append(" extra: ").append(mExtraInfo);
+            }
+            return builder.toString();
+        }
+    }
+
     @Override
     public int describeContents() {
         return 0;
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 14442a2..1922b6d 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -21,7 +21,6 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.app.ActivityManager;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -56,7 +55,6 @@
  * @hide
  */
 @SystemService(Context.NETWORK_POLICY_SERVICE)
-@SystemApi
 public class NetworkPolicyManager {
 
     /* POLICY_* are masks and can be ORed, although currently they are not.*/
@@ -162,11 +160,13 @@
 
     /**
      * Mask used to check if an override value is marked as unmetered.
+     * @hide
      */
     public static final int SUBSCRIPTION_OVERRIDE_UNMETERED = 1 << 0;
 
     /**
      * Mask used to check if an override value is marked as congested.
+     * @hide
      */
     public static final int SUBSCRIPTION_OVERRIDE_CONGESTED = 1 << 1;
 
@@ -294,7 +294,6 @@
 
     /** @hide */
     @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
-    @SystemApi
     public void registerSubscriptionCallback(@NonNull SubscriptionCallback callback) {
         if (callback == null) {
             throw new NullPointerException("Callback cannot be null.");
@@ -309,7 +308,6 @@
 
     /** @hide */
     @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
-    @SystemApi
     public void unregisterSubscriptionCallback(@NonNull SubscriptionCallback callback) {
         if (callback == null) {
             throw new NullPointerException("Callback cannot be null.");
@@ -373,6 +371,7 @@
      *            requested state until explicitly cleared, or the next reboot,
      *            whichever happens first
      * @param callingPackage the name of the package making the call.
+     * @hide
      */
     public void setSubscriptionOverride(int subId, @SubscriptionOverrideMask int overrideMask,
             @SubscriptionOverrideMask int overrideValue, long timeoutMillis,
@@ -391,6 +390,7 @@
      * @param subId the subscriber this relationship applies to.
      * @param plans the list of plans.
      * @param callingPackage the name of the package making the call
+     * @hide
      */
     public void setSubscriptionPlans(int subId, @NonNull SubscriptionPlan[] plans,
             @NonNull String callingPackage) {
@@ -406,6 +406,7 @@
      *
      * @param subId the subscriber to get the subscription plans for.
      * @param callingPackage the name of the package making the call.
+     * @hide
      */
     @NonNull
     public SubscriptionPlan[] getSubscriptionPlans(int subId, @NonNull String callingPackage) {
@@ -549,7 +550,6 @@
     }
 
     /** @hide */
-    @SystemApi
     public static class SubscriptionCallback {
         /**
          * Notify clients of a new override about a given subscription.
diff --git a/core/java/android/net/NetworkProvider.java b/core/java/android/net/NetworkProvider.java
index 2c0e4aa..418d691 100644
--- a/core/java/android/net/NetworkProvider.java
+++ b/core/java/android/net/NetworkProvider.java
@@ -106,10 +106,12 @@
     }
 
     // TODO: consider adding a register() method so ConnectivityManager does not need to call this.
+    /** @hide */
     public @Nullable Messenger getMessenger() {
         return mMessenger;
     }
 
+    /** @hide */
     public @NonNull String getName() {
         return mName;
     }
diff --git a/core/java/android/net/NetworkStack.java b/core/java/android/net/NetworkStack.java
index a46c410..86f3dfd 100644
--- a/core/java/android/net/NetworkStack.java
+++ b/core/java/android/net/NetworkStack.java
@@ -19,15 +19,17 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.content.Context;
+import android.os.IBinder;
+import android.os.ServiceManager;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 /**
- *
- * Constants for client code communicating with the network stack service.
+ * Constants and utilities for client code communicating with the network stack service.
  * @hide
  */
 @SystemApi
@@ -43,6 +45,34 @@
     public static final String PERMISSION_MAINLINE_NETWORK_STACK =
             "android.permission.MAINLINE_NETWORK_STACK";
 
+    @Nullable
+    private static volatile IBinder sMockService;
+
+    /**
+     * Get an {@link IBinder} representing the NetworkStack stable AIDL Interface, if registered.
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    @TestApi
+    public static IBinder getService() {
+        final IBinder mockService = sMockService;
+        if (mockService != null) return mockService;
+        return ServiceManager.getService(Context.NETWORK_STACK_SERVICE);
+    }
+
+    /**
+     * Set a mock service for testing, to be returned by future calls to {@link #getService()}.
+     *
+     * <p>Passing a {@code null} {@code mockService} resets {@link #getService()} to normal
+     * behavior.
+     * @hide
+     */
+    @TestApi
+    public static void setServiceForTest(@Nullable IBinder mockService) {
+        sMockService = mockService;
+    }
+
     private NetworkStack() {}
 
     /**
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 2f536ff..9c1fb41 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -21,7 +21,6 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
@@ -58,9 +57,12 @@
 public final class NetworkStats implements Parcelable {
     private static final String TAG = "NetworkStats";
 
-    /** {@link #iface} value when interface details unavailable. */
-    @SuppressLint("CompileTimeConstant")
+    /**
+     * {@link #iface} value when interface details unavailable.
+     * @hide
+     */
     @Nullable public static final String IFACE_ALL = null;
+
     /**
      * Virtual network interface for video telephony. This is for VT data usage counting
      * purpose.
@@ -248,7 +250,13 @@
     @UnsupportedAppUsage
     private long[] operations;
 
-    /** @hide */
+    /**
+     * Basic element of network statistics. Contains the number of packets and number of bytes
+     * transferred on both directions in a given set of conditions. See
+     * {@link Entry#Entry(String, int, int, int, int, int, int, long, long, long, long, long)}.
+     *
+     * @hide
+     */
     @SystemApi
     public static class Entry {
         /** @hide */
@@ -319,6 +327,35 @@
                     rxBytes, rxPackets, txBytes, txPackets, operations);
         }
 
+        /**
+         * Construct a {@link Entry} object by giving statistics of packet and byte transferred on
+         * both direction, and associated with a set of given conditions.
+         *
+         * @param iface interface name of this {@link Entry}. Or null if not specified.
+         * @param uid uid of this {@link Entry}. {@link #UID_TETHERING} if this {@link Entry} is
+         *            for tethering. Or {@link #UID_ALL} if this {@link NetworkStats} is only
+         *            counting iface stats.
+         * @param set usage state of this {@link Entry}. Should be one of the following
+         *            values: {@link #SET_DEFAULT}, {@link #SET_FOREGROUND}.
+         * @param tag tag of this {@link Entry}.
+         * @param metered metered state of this {@link Entry}. Should be one of the following
+         *                values: {link #METERED_YES}, {link #METERED_NO}.
+         * @param roaming roaming state of this {@link Entry}. Should be one of the following
+         *                values: {link #ROAMING_YES}, {link #ROAMING_NO}.
+         * @param defaultNetwork default network status of this {@link Entry}. Should be one
+         *                       of the following values: {link #DEFAULT_NETWORK_YES},
+         *                       {link #DEFAULT_NETWORK_NO}.
+         * @param rxBytes Number of bytes received for this {@link Entry}. Statistics should
+         *                represent the contents of IP packets, including IP headers.
+         * @param rxPackets Number of packets received for this {@link Entry}. Statistics should
+         *                  represent the contents of IP packets, including IP headers.
+         * @param txBytes Number of bytes transmitted for this {@link Entry}. Statistics should
+         *                represent the contents of IP packets, including IP headers.
+         * @param txPackets Number of bytes transmitted for this {@link Entry}. Statistics should
+         *                  represent the contents of IP packets, including IP headers.
+         * @param operations count of network operations performed for this {@link Entry}. This can
+         *                   be used to derive bytes-per-operation.
+         */
         public Entry(@Nullable String iface, int uid, @State int set, int tag,
                 @Meteredness int metered, @Roaming int roaming, @DefaultNetwork int defaultNetwork,
                 long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
@@ -466,7 +503,7 @@
         NetworkStats.Entry entry = null;
         for (int i = 0; i < size; i++) {
             entry = getValues(i, entry);
-            clone.addEntry(entry);
+            clone.insertEntry(entry);
         }
         return clone;
     }
@@ -493,26 +530,26 @@
 
     /** @hide */
     @VisibleForTesting
-    public NetworkStats addIfaceValues(
+    public NetworkStats insertEntry(
             String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) {
-        return addEntry(
+        return insertEntry(
                 iface, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 0L);
     }
 
     /** @hide */
     @VisibleForTesting
-    public NetworkStats addEntry(String iface, int uid, int set, int tag, long rxBytes,
+    public NetworkStats insertEntry(String iface, int uid, int set, int tag, long rxBytes,
             long rxPackets, long txBytes, long txPackets, long operations) {
-        return addEntry(new Entry(
+        return insertEntry(new Entry(
                 iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
     }
 
     /** @hide */
     @VisibleForTesting
-    public NetworkStats addEntry(String iface, int uid, int set, int tag, int metered, int roaming,
-            int defaultNetwork, long rxBytes, long rxPackets, long txBytes, long txPackets,
-            long operations) {
-        return addEntry(new Entry(
+    public NetworkStats insertEntry(String iface, int uid, int set, int tag, int metered,
+            int roaming, int defaultNetwork, long rxBytes, long rxPackets, long txBytes,
+            long txPackets, long operations) {
+        return insertEntry(new Entry(
                 iface, uid, set, tag, metered, roaming, defaultNetwork, rxBytes, rxPackets,
                 txBytes, txPackets, operations));
     }
@@ -522,7 +559,7 @@
      * object can be recycled across multiple calls.
      * @hide
      */
-    public NetworkStats addEntry(Entry entry) {
+    public NetworkStats insertEntry(Entry entry) {
         if (size >= capacity) {
             final int newLength = Math.max(size, 10) * 3 / 2;
             iface = Arrays.copyOf(iface, newLength);
@@ -665,7 +702,7 @@
                 entry.roaming, entry.defaultNetwork);
         if (i == -1) {
             // only create new entry when positive contribution
-            addEntry(entry);
+            insertEntry(entry);
         } else {
             rxBytes[i] += entry.rxBytes;
             rxPackets[i] += entry.rxPackets;
@@ -684,7 +721,7 @@
      * @param entry the {@link Entry} to add.
      * @return a new constructed {@link NetworkStats} object that contains the result.
      */
-    public @NonNull NetworkStats addValues(@NonNull Entry entry) {
+    public @NonNull NetworkStats addEntry(@NonNull Entry entry) {
         return this.clone().combineValues(entry);
     }
 
@@ -1003,7 +1040,7 @@
                 entry.operations = Math.max(entry.operations, 0);
             }
 
-            result.addEntry(entry);
+            result.insertEntry(entry);
         }
 
         return result;
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index 5498f74..cb9463a 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -34,9 +34,13 @@
 import static android.net.NetworkStats.ROAMING_YES;
 import static android.net.wifi.WifiInfo.sanitizeSsid;
 
+import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.telephony.Annotation.NetworkType;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
 import android.util.BackupUtils;
 import android.util.Log;
 
@@ -73,6 +77,14 @@
     public static final int MATCH_BLUETOOTH = 8;
     public static final int MATCH_PROXY = 9;
 
+    /**
+     * Include all network types when filtering. This is meant to merge in with the
+     * {@code TelephonyManager.NETWORK_TYPE_*} constants, and thus needs to stay in sync.
+     *
+     * @hide
+     */
+    public static final int NETWORK_TYPE_ALL = -1;
+
     private static boolean isKnownMatchRule(final int rule) {
         switch (rule) {
             case MATCH_MOBILE:
@@ -117,7 +129,22 @@
     }
 
     /**
-     * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks,
+     * Template to match cellular networks with the given IMSI and {@code ratType}.
+     * Use {@link #NETWORK_TYPE_ALL} to include all network types when filtering.
+     * See {@code TelephonyManager.NETWORK_TYPE_*}.
+     */
+    public static NetworkTemplate buildTemplateMobileWithRatType(@Nullable String subscriberId,
+            @NetworkType int ratType) {
+        if (TextUtils.isEmpty(subscriberId)) {
+            return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null, null,
+                    METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType);
+        }
+        return new NetworkTemplate(MATCH_MOBILE, subscriberId, new String[]{subscriberId}, null,
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType);
+    }
+
+    /**
+     * Template to match metered {@link ConnectivityManager#TYPE_MOBILE} networks,
      * regardless of IMSI.
      */
     @UnsupportedAppUsage
@@ -126,7 +153,7 @@
     }
 
     /**
-     * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks,
+     * Template to match all metered {@link ConnectivityManager#TYPE_WIFI} networks,
      * regardless of SSID.
      */
     @UnsupportedAppUsage
@@ -192,6 +219,7 @@
     private final int mMetered;
     private final int mRoaming;
     private final int mDefaultNetwork;
+    private final int mSubType;
 
     @UnsupportedAppUsage
     public NetworkTemplate(int matchRule, String subscriberId, String networkId) {
@@ -201,11 +229,11 @@
     public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
             String networkId) {
         this(matchRule, subscriberId, matchSubscriberIds, networkId, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL);
+                DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL);
     }
 
     public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
-            String networkId, int metered, int roaming, int defaultNetwork) {
+            String networkId, int metered, int roaming, int defaultNetwork, int subType) {
         mMatchRule = matchRule;
         mSubscriberId = subscriberId;
         mMatchSubscriberIds = matchSubscriberIds;
@@ -213,6 +241,7 @@
         mMetered = metered;
         mRoaming = roaming;
         mDefaultNetwork = defaultNetwork;
+        mSubType = subType;
 
         if (!isKnownMatchRule(matchRule)) {
             Log.e(TAG, "Unknown network template rule " + matchRule
@@ -228,6 +257,7 @@
         mMetered = in.readInt();
         mRoaming = in.readInt();
         mDefaultNetwork = in.readInt();
+        mSubType = in.readInt();
     }
 
     @Override
@@ -239,6 +269,7 @@
         dest.writeInt(mMetered);
         dest.writeInt(mRoaming);
         dest.writeInt(mDefaultNetwork);
+        dest.writeInt(mSubType);
     }
 
     @Override
@@ -271,13 +302,16 @@
             builder.append(", defaultNetwork=").append(NetworkStats.defaultNetworkToString(
                     mDefaultNetwork));
         }
+        if (mSubType != NETWORK_TYPE_ALL) {
+            builder.append(", subType=").append(mSubType);
+        }
         return builder.toString();
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(mMatchRule, mSubscriberId, mNetworkId, mMetered, mRoaming,
-                mDefaultNetwork);
+                mDefaultNetwork, mSubType);
     }
 
     @Override
@@ -289,7 +323,8 @@
                     && Objects.equals(mNetworkId, other.mNetworkId)
                     && mMetered == other.mMetered
                     && mRoaming == other.mRoaming
-                    && mDefaultNetwork == other.mDefaultNetwork;
+                    && mDefaultNetwork == other.mDefaultNetwork
+                    && mSubType == other.mSubType;
         }
         return false;
     }
@@ -376,6 +411,11 @@
             || (mDefaultNetwork == DEFAULT_NETWORK_NO && !ident.mDefaultNetwork);
     }
 
+    private boolean matchesCollapsedRatType(NetworkIdentity ident) {
+        return mSubType == NETWORK_TYPE_ALL
+                || getCollapsedRatType(mSubType) == getCollapsedRatType(ident.mSubType);
+    }
+
     public boolean matchesSubscriberId(String subscriberId) {
         return ArrayUtils.contains(mMatchSubscriberIds, subscriberId);
     }
@@ -388,9 +428,52 @@
             // TODO: consider matching against WiMAX subscriber identity
             return true;
         } else {
+            // Only metered mobile network would be matched regardless of metered filter.
+            // This is used to exclude non-metered APNs, e.g. IMS. See ag/908650.
+            // TODO: Respect metered filter and remove mMetered condition.
             return (sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered))
                     && !ArrayUtils.isEmpty(mMatchSubscriberIds)
-                    && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
+                    && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId)
+                    && matchesCollapsedRatType(ident);
+        }
+    }
+
+    /**
+     * Get a Radio Access Technology(RAT) type that is representative of a group of RAT types.
+     * The mapping is corresponding to {@code TelephonyManager#NETWORK_CLASS_BIT_MASK_*}.
+     *
+     * @param ratType An integer defined in {@code TelephonyManager#NETWORK_TYPE_*}.
+     */
+    // TODO: 1. Consider move this to TelephonyManager if used by other modules.
+    //       2. Consider make this configurable.
+    //       3. Use TelephonyManager APIs when available.
+    public static int getCollapsedRatType(int ratType) {
+        switch (ratType) {
+            case TelephonyManager.NETWORK_TYPE_GPRS:
+            case TelephonyManager.NETWORK_TYPE_GSM:
+            case TelephonyManager.NETWORK_TYPE_EDGE:
+            case TelephonyManager.NETWORK_TYPE_IDEN:
+            case TelephonyManager.NETWORK_TYPE_CDMA:
+            case TelephonyManager.NETWORK_TYPE_1xRTT:
+                return TelephonyManager.NETWORK_TYPE_GSM;
+            case TelephonyManager.NETWORK_TYPE_EVDO_0:
+            case TelephonyManager.NETWORK_TYPE_EVDO_A:
+            case TelephonyManager.NETWORK_TYPE_EVDO_B:
+            case TelephonyManager.NETWORK_TYPE_EHRPD:
+            case TelephonyManager.NETWORK_TYPE_UMTS:
+            case TelephonyManager.NETWORK_TYPE_HSDPA:
+            case TelephonyManager.NETWORK_TYPE_HSUPA:
+            case TelephonyManager.NETWORK_TYPE_HSPA:
+            case TelephonyManager.NETWORK_TYPE_HSPAP:
+            case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
+                return TelephonyManager.NETWORK_TYPE_UMTS;
+            case TelephonyManager.NETWORK_TYPE_LTE:
+            case TelephonyManager.NETWORK_TYPE_IWLAN:
+                return TelephonyManager.NETWORK_TYPE_LTE;
+            case TelephonyManager.NETWORK_TYPE_NR:
+                return TelephonyManager.NETWORK_TYPE_NR;
+            default:
+                return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
     }
 
@@ -421,7 +504,8 @@
         if (ident.mType == TYPE_WIMAX) {
             return true;
         } else {
-            return sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered);
+            return (sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered))
+                    && matchesCollapsedRatType(ident);
         }
     }
 
diff --git a/core/java/android/net/OWNERS b/core/java/android/net/OWNERS
index 767b693..5e2a718 100644
--- a/core/java/android/net/OWNERS
+++ b/core/java/android/net/OWNERS
@@ -8,4 +8,4 @@
 reminv@google.com
 satk@google.com
 
-per-file SSL*, Uri*, Url* = prb@google.com, dauletz@google.com, narayan@google.com, tobiast@google.com
+per-file SSL*, Uri*, Url* = prb@google.com, dauletz@google.com, narayan@google.com, ngeoffray@google.com
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index 2b9e9fe..dbdaa4c 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -26,6 +26,7 @@
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.Pair;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -527,6 +528,30 @@
     }
 
     /**
+     * A helper class that contains the destination and the gateway in a {@code RouteInfo},
+     * used by {@link ConnectivityService#updateRoutes} or
+     * {@link LinkProperties#addRoute} to calculate the list to be updated.
+     *
+     * @hide
+     */
+    public static class RouteKey extends Pair<IpPrefix, InetAddress> {
+        RouteKey(@NonNull IpPrefix destination, @Nullable InetAddress gateway) {
+            super(destination, gateway);
+        }
+    }
+
+    /**
+     * Get {@code RouteKey} of this {@code RouteInfo}.
+     * @return a {@code RouteKey} object.
+     *
+     * @hide
+     */
+    @NonNull
+    public RouteKey getRouteKey() {
+        return new RouteKey(mDestination, mGateway);
+    }
+
+    /**
      *  Returns a hashcode for this <code>RouteInfo</code> object.
      */
     public int hashCode() {
diff --git a/core/java/android/net/TestNetworkManager.java b/core/java/android/net/TestNetworkManager.java
index 4ac4a69..a0a563b 100644
--- a/core/java/android/net/TestNetworkManager.java
+++ b/core/java/android/net/TestNetworkManager.java
@@ -16,6 +16,7 @@
 package android.net;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -29,6 +30,18 @@
  */
 @TestApi
 public class TestNetworkManager {
+    /**
+     * Prefix for tun interfaces created by this class.
+     * @hide
+     */
+    public static final String TEST_TUN_PREFIX = "testtun";
+
+    /**
+     * Prefix for tap interfaces created by this class.
+     * @hide
+     */
+    public static final String TEST_TAP_PREFIX = "testtap";
+
     @NonNull private static final String TAG = TestNetworkManager.class.getSimpleName();
 
     @NonNull private final ITestNetworkManager mService;
@@ -53,6 +66,19 @@
         }
     }
 
+    private void setupTestNetwork(
+            @NonNull String iface,
+            @Nullable LinkProperties lp,
+            boolean isMetered,
+            @NonNull int[] administratorUids,
+            @NonNull IBinder binder) {
+        try {
+            mService.setupTestNetwork(iface, lp, isMetered, administratorUids, binder);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     /**
      * Sets up a capability-limited, testing-only network for a given interface
      *
@@ -66,11 +92,7 @@
     public void setupTestNetwork(
             @NonNull LinkProperties lp, boolean isMetered, @NonNull IBinder binder) {
         Preconditions.checkNotNull(lp, "Invalid LinkProperties");
-        try {
-            mService.setupTestNetwork(lp.getInterfaceName(), lp, isMetered, binder);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        setupTestNetwork(lp.getInterfaceName(), lp, isMetered, new int[0], binder);
     }
 
     /**
@@ -82,11 +104,21 @@
      */
     @TestApi
     public void setupTestNetwork(@NonNull String iface, @NonNull IBinder binder) {
-        try {
-            mService.setupTestNetwork(iface, null, true, binder);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        setupTestNetwork(iface, null, true, new int[0], binder);
+    }
+
+    /**
+     * Sets up a capability-limited, testing-only network for a given interface with the given
+     * administrator UIDs.
+     *
+     * @param iface the name of the interface to be used for the Network LinkProperties.
+     * @param administratorUids The administrator UIDs to be used for the test-only network
+     * @param binder A binder object guarding the lifecycle of this test network.
+     * @hide
+     */
+    public void setupTestNetwork(
+            @NonNull String iface, @NonNull int[] administratorUids, @NonNull IBinder binder) {
+        setupTestNetwork(iface, null, true, administratorUids, binder);
     }
 
     /**
diff --git a/core/java/android/net/http/OWNERS b/core/java/android/net/http/OWNERS
index 3092612..3271d24 100644
--- a/core/java/android/net/http/OWNERS
+++ b/core/java/android/net/http/OWNERS
@@ -1,4 +1,4 @@
 narayan@google.com
-tobiast@google.com
+ngeoffray@google.com
 include platform/libcore:/OWNERS
 include platform/external/conscrypt:/OWNERS
diff --git a/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java b/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java
deleted file mode 100644
index 740aa92..0000000
--- a/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.netstats.provider;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.net.NetworkStats;
-
-/**
- * A base class that allows external modules to implement a custom network statistics provider.
- * @hide
- */
-@SystemApi
-public abstract class AbstractNetworkStatsProvider {
-    /**
-     * A value used by {@link #setLimit} and {@link #setAlert} indicates there is no limit.
-     */
-    public static final int QUOTA_UNLIMITED = -1;
-
-    /**
-     * Called by {@code NetworkStatsService} when global polling is needed. Custom
-     * implementation of providers MUST respond to it by calling
-     * {@link NetworkStatsProviderCallback#onStatsUpdated} within one minute. Responding
-     * later than this may cause the stats to be dropped.
-     *
-     * @param token a positive number identifying the new state of the system under which
-     *              {@link NetworkStats} have to be gathered from now on. When this is called,
-     *              custom implementations of providers MUST report the latest stats with the
-     *              previous token, under which stats were being gathered so far.
-     */
-    public abstract void requestStatsUpdate(int token);
-
-    /**
-     * Called by {@code NetworkStatsService} when setting the interface quota for the specified
-     * upstream interface. When this is called, the custom implementation should block all egress
-     * packets on the {@code iface} associated with the provider when {@code quotaBytes} bytes have
-     * been reached, and MUST respond to it by calling
-     * {@link NetworkStatsProviderCallback#onLimitReached()}.
-     *
-     * @param iface the interface requiring the operation.
-     * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
-     *                   from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit.
-     */
-    public abstract void setLimit(@NonNull String iface, long quotaBytes);
-
-    /**
-     * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations
-     * MUST call {@link NetworkStatsProviderCallback#onAlertReached()} when {@code quotaBytes} bytes
-     * have been reached. Unlike {@link #setLimit(String, long)}, the custom implementation should
-     * not block all egress packets.
-     *
-     * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
-     *                   from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no alert.
-     */
-    public abstract void setAlert(long quotaBytes);
-}
diff --git a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl
index 55b3d4e..4078b24 100644
--- a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl
+++ b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl
@@ -22,7 +22,7 @@
  * @hide
  */
 oneway interface INetworkStatsProvider {
-    void requestStatsUpdate(int token);
-    void setLimit(String iface, long quotaBytes);
-    void setAlert(long quotaBytes);
+    void onRequestStatsUpdate(int token);
+    void onSetLimit(String iface, long quotaBytes);
+    void onSetAlert(long quotaBytes);
 }
diff --git a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
index 3ea9318..bd336dd 100644
--- a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
+++ b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl
@@ -24,8 +24,8 @@
  * @hide
  */
 oneway interface INetworkStatsProviderCallback {
-    void onStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats);
-    void onAlertReached();
-    void onLimitReached();
+    void notifyStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats);
+    void notifyAlertReached();
+    void notifyLimitReached();
     void unregister();
 }
diff --git a/core/java/android/net/netstats/provider/NetworkStatsProvider.java b/core/java/android/net/netstats/provider/NetworkStatsProvider.java
new file mode 100644
index 0000000..7639d22
--- /dev/null
+++ b/core/java/android/net/netstats/provider/NetworkStatsProvider.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netstats.provider;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.net.NetworkStats;
+import android.os.RemoteException;
+
+/**
+ * A base class that allows external modules to implement a custom network statistics provider.
+ * @hide
+ */
+@SystemApi
+public abstract class NetworkStatsProvider {
+    /**
+     * A value used by {@link #onSetLimit} and {@link #onSetAlert} indicates there is no limit.
+     */
+    public static final int QUOTA_UNLIMITED = -1;
+
+    @NonNull private final INetworkStatsProvider mProviderBinder =
+            new INetworkStatsProvider.Stub() {
+
+        @Override
+        public void onRequestStatsUpdate(int token) {
+            NetworkStatsProvider.this.onRequestStatsUpdate(token);
+        }
+
+        @Override
+        public void onSetLimit(String iface, long quotaBytes) {
+            NetworkStatsProvider.this.onSetLimit(iface, quotaBytes);
+        }
+
+        @Override
+        public void onSetAlert(long quotaBytes) {
+            NetworkStatsProvider.this.onSetAlert(quotaBytes);
+        }
+    };
+
+    // The binder given by the service when successfully registering. Only null before registering,
+    // never null once non-null.
+    @Nullable
+    private INetworkStatsProviderCallback mProviderCbBinder;
+
+    /**
+     * Return the binder invoked by the service and redirect function calls to the overridden
+     * methods.
+     * @hide
+     */
+    @NonNull
+    public INetworkStatsProvider getProviderBinder() {
+        return mProviderBinder;
+    }
+
+    /**
+     * Store the binder that was returned by the service when successfully registering. Note that
+     * the provider cannot be re-registered. Hence this method can only be called once per provider.
+     *
+     * @hide
+     */
+    public void setProviderCallbackBinder(@NonNull INetworkStatsProviderCallback binder) {
+        if (mProviderCbBinder != null) {
+            throw new IllegalArgumentException("provider is already registered");
+        }
+        mProviderCbBinder = binder;
+    }
+
+    /**
+     * Get the binder that was returned by the service when successfully registering. Or null if the
+     * provider was never registered.
+     *
+     * @hide
+     */
+    @Nullable
+    public INetworkStatsProviderCallback getProviderCallbackBinder() {
+        return mProviderCbBinder;
+    }
+
+    /**
+     * Get the binder that was returned by the service when successfully registering. Throw an
+     * {@link IllegalStateException} if the provider is not registered.
+     *
+     * @hide
+     */
+    @NonNull
+    public INetworkStatsProviderCallback getProviderCallbackBinderOrThrow() {
+        if (mProviderCbBinder == null) {
+            throw new IllegalStateException("the provider is not registered");
+        }
+        return mProviderCbBinder;
+    }
+
+    /**
+     * Notify the system of new network statistics.
+     *
+     * Send the network statistics recorded since the last call to {@link #notifyStatsUpdated}. Must
+     * be called as soon as possible after {@link NetworkStatsProvider#onRequestStatsUpdate(int)}
+     * being called. Responding later increases the probability stats will be dropped. The
+     * provider can also call this whenever it wants to reports new stats for any reason.
+     * Note that the system will not necessarily immediately propagate the statistics to
+     * reflect the update.
+     *
+     * @param token the token under which these stats were gathered. Providers can call this method
+     *              with the current token as often as they want, until the token changes.
+     *              {@see NetworkStatsProvider#onRequestStatsUpdate()}
+     * @param ifaceStats the {@link NetworkStats} per interface to be reported.
+     *                   The provider should not include any traffic that is already counted by
+     *                   kernel interface counters.
+     * @param uidStats the same stats as above, but counts {@link NetworkStats}
+     *                 per uid.
+     */
+    public void notifyStatsUpdated(int token, @NonNull NetworkStats ifaceStats,
+            @NonNull NetworkStats uidStats) {
+        try {
+            getProviderCallbackBinderOrThrow().notifyStatsUpdated(token, ifaceStats, uidStats);
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Notify system that the quota set by {@code onSetAlert} has been reached.
+     */
+    public void notifyAlertReached() {
+        try {
+            getProviderCallbackBinderOrThrow().notifyAlertReached();
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Notify system that the quota set by {@code onSetLimit} has been reached.
+     */
+    public void notifyLimitReached() {
+        try {
+            getProviderCallbackBinderOrThrow().notifyLimitReached();
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Called by {@code NetworkStatsService} when it requires to know updated stats.
+     * The provider MUST respond by calling {@link #notifyStatsUpdated} as soon as possible.
+     * Responding later increases the probability stats will be dropped. Memory allowing, the
+     * system will try to take stats into account up to one minute after calling
+     * {@link #onRequestStatsUpdate}.
+     *
+     * @param token a positive number identifying the new state of the system under which
+     *              {@link NetworkStats} have to be gathered from now on. When this is called,
+     *              custom implementations of providers MUST tally and report the latest stats with
+     *              the previous token, under which stats were being gathered so far.
+     */
+    public abstract void onRequestStatsUpdate(int token);
+
+    /**
+     * Called by {@code NetworkStatsService} when setting the interface quota for the specified
+     * upstream interface. When this is called, the custom implementation should block all egress
+     * packets on the {@code iface} associated with the provider when {@code quotaBytes} bytes have
+     * been reached, and MUST respond to it by calling
+     * {@link NetworkStatsProvider#notifyLimitReached()}.
+     *
+     * @param iface the interface requiring the operation.
+     * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
+     *                   from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit.
+     */
+    public abstract void onSetLimit(@NonNull String iface, long quotaBytes);
+
+    /**
+     * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations
+     * MUST call {@link NetworkStatsProvider#notifyAlertReached()} when {@code quotaBytes} bytes
+     * have been reached. Unlike {@link #onSetLimit(String, long)}, the custom implementation should
+     * not block all egress packets.
+     *
+     * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting
+     *                   from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no alert.
+     */
+    public abstract void onSetAlert(long quotaBytes);
+}
diff --git a/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java b/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java
deleted file mode 100644
index e17a8ee..0000000
--- a/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.netstats.provider;
-
-import android.annotation.NonNull;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.net.NetworkStats;
-import android.os.RemoteException;
-
-/**
- * A callback class that allows callers to report events to the system.
- * @hide
- */
-@SystemApi
-@SuppressLint("CallbackMethodName")
-public class NetworkStatsProviderCallback {
-    @NonNull private final INetworkStatsProviderCallback mBinder;
-
-    /** @hide */
-    public NetworkStatsProviderCallback(@NonNull INetworkStatsProviderCallback binder) {
-        mBinder = binder;
-    }
-
-    /**
-     * Notify the system of new network statistics.
-     *
-     * Send the network statistics recorded since the last call to {@link #onStatsUpdated}. Must be
-     * called within one minute of {@link AbstractNetworkStatsProvider#requestStatsUpdate(int)}
-     * being called. The provider can also call this whenever it wants to reports new stats for any
-     * reason. Note that the system will not necessarily immediately propagate the statistics to
-     * reflect the update.
-     *
-     * @param token the token under which these stats were gathered. Providers can call this method
-     *              with the current token as often as they want, until the token changes.
-     *              {@see AbstractNetworkStatsProvider#requestStatsUpdate()}
-     * @param ifaceStats the {@link NetworkStats} per interface to be reported.
-     *                   The provider should not include any traffic that is already counted by
-     *                   kernel interface counters.
-     * @param uidStats the same stats as above, but counts {@link NetworkStats}
-     *                 per uid.
-     */
-    public void onStatsUpdated(int token, @NonNull NetworkStats ifaceStats,
-            @NonNull NetworkStats uidStats) {
-        try {
-            mBinder.onStatsUpdated(token, ifaceStats, uidStats);
-        } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
-        }
-    }
-
-    /**
-     * Notify system that the quota set by {@code setAlert} has been reached.
-     */
-    public void onAlertReached() {
-        try {
-            mBinder.onAlertReached();
-        } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
-        }
-    }
-
-    /**
-     * Notify system that the quota set by {@code setLimit} has been reached.
-     */
-    public void onLimitReached() {
-        try {
-            mBinder.onLimitReached();
-        } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
-        }
-    }
-
-    /**
-     * Unregister the provider and the referencing callback.
-     */
-    public void unregister() {
-        try {
-            mBinder.unregister();
-        } catch (RemoteException e) {
-            // Ignore error.
-        }
-    }
-}
diff --git a/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java b/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java
deleted file mode 100644
index 4bf7c9b..0000000
--- a/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.netstats.provider;
-
-import android.annotation.NonNull;
-
-/**
- * A wrapper class of {@link INetworkStatsProvider} that hides the binder interface from exposing
- * to outer world.
- *
- * @hide
- */
-public class NetworkStatsProviderWrapper extends INetworkStatsProvider.Stub {
-    @NonNull final AbstractNetworkStatsProvider mProvider;
-
-    public NetworkStatsProviderWrapper(AbstractNetworkStatsProvider provider) {
-        mProvider = provider;
-    }
-
-    @Override
-    public void requestStatsUpdate(int token) {
-        mProvider.requestStatsUpdate(token);
-    }
-
-    @Override
-    public void setLimit(@NonNull String iface, long quotaBytes) {
-        mProvider.setLimit(iface, quotaBytes);
-    }
-
-    @Override
-    public void setAlert(long quotaBytes) {
-        mProvider.setAlert(quotaBytes);
-    }
-}
diff --git a/core/java/android/net/util/SocketUtils.java b/core/java/android/net/util/SocketUtils.java
index e9ea99f..6967084 100644
--- a/core/java/android/net/util/SocketUtils.java
+++ b/core/java/android/net/util/SocketUtils.java
@@ -66,6 +66,10 @@
 
     /**
      * Make socket address that packet sockets can bind to.
+     *
+     * @param protocol the layer 2 protocol of the packets to receive. One of the {@code ETH_P_*}
+     *                 constants in {@link android.system.OsConstants}.
+     * @param ifIndex the interface index on which packets will be received.
      */
     @NonNull
     public static SocketAddress makePacketSocketAddress(int protocol, int ifIndex) {
@@ -78,6 +82,9 @@
     /**
      * Make a socket address that packet socket can send packets to.
      * @deprecated Use {@link #makePacketSocketAddress(int, int, byte[])} instead.
+     *
+     * @param ifIndex the interface index on which packets will be sent.
+     * @param hwAddr the hardware address to which packets will be sent.
      */
     @Deprecated
     @NonNull
@@ -89,7 +96,12 @@
     }
 
     /**
-     * Make a socket address that packet socket can send packets to.
+     * Make a socket address that a packet socket can send packets to.
+     *
+     * @param protocol the layer 2 protocol of the packets to send. One of the {@code ETH_P_*}
+     *                 constants in {@link android.system.OsConstants}.
+     * @param ifIndex the interface index on which packets will be sent.
+     * @param hwAddr the hardware address to which packets will be sent.
      */
     @NonNull
     public static SocketAddress makePacketSocketAddress(int protocol, int ifIndex,
diff --git a/core/java/android/os/ConfigUpdate.java b/core/java/android/os/ConfigUpdate.java
index 9c999b2..a28f5fb 100644
--- a/core/java/android/os/ConfigUpdate.java
+++ b/core/java/android/os/ConfigUpdate.java
@@ -16,6 +16,9 @@
 
 package android.os;
 
+import android.annotation.RequiresPermission;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 
 /**
@@ -114,20 +117,37 @@
             = "android.os.action.UPDATE_CARRIER_ID_DB";
 
     /**
-    * Broadcast intent action indicating that the updated emergency number database is available.
-    * <p>Extra: "VERSION" the numeric version of the new data. Devices should only install if the
-    * update version is newer than the current one.
-    * <p>Extra: "REQUIRED_HASH" the hash of the current update data.
-    * <p>Input: {@link android.content.Intent#getData} is URI of downloaded emergency number file.
-    * Devices should pick up the downloaded file and persist to the database
-    * {@code com.android.internal.telephony.emergency.EmergencyNumberTracker}.
+    * Update the emergency number database into the devices.
+    * <p>Extra: {@link #EXTRA_VERSION} the numeric version of the database.
+    * <p>Extra: {@link #EXTRA_REQUIRED_HASH} the hash of the database.
+    * <p>Input: {@link android.content.Intent#getData} the URI to download emergency number
+    * database.
     *
     * @hide
     */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.UPDATE_CONFIG)
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_UPDATE_EMERGENCY_NUMBER_DB =
             "android.os.action.UPDATE_EMERGENCY_NUMBER_DB";
 
+    /**
+     * An integer to indicate the numeric version of the new data. Devices should only install
+     * if the update version is newer than the current one.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_VERSION = "android.os.extra.VERSION";
+
+    /**
+     * A string to indicate the hash of the data.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_REQUIRED_HASH = "android.os.extra.REQUIRED_HASH";
+
     private ConfigUpdate() {
     }
 }
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index fa7404c..51df971 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -792,6 +792,17 @@
     }
 
     /**
+     * Remove any pending posts of messages with code 'what' and whose obj is
+     * 'object' that are in the message queue.  If <var>object</var> is null,
+     * all messages will be removed.
+     *
+     *@hide
+     */
+    public final void removeEqualMessages(int what, @Nullable Object object) {
+        mQueue.removeEqualMessages(this, what, object);
+    }
+
+    /**
      * Remove any pending posts of callbacks and sent messages whose
      * <var>obj</var> is <var>token</var>.  If <var>token</var> is null,
      * all callbacks and messages will be removed.
@@ -801,6 +812,16 @@
     }
 
     /**
+     * Remove any pending posts of callbacks and sent messages whose
+     * <var>obj</var> is <var>token</var>.  If <var>token</var> is null,
+     * all callbacks and messages will be removed.
+     *
+     *@hide
+     */
+    public final void removeCallbacksAndEqualMessages(@Nullable Object token) {
+        mQueue.removeCallbacksAndEqualMessages(this, token);
+    }
+    /**
      * Check if there are any pending posts of messages with code 'what' in
      * the message queue.
      */
@@ -825,6 +846,16 @@
     }
 
     /**
+     * Check if there are any pending posts of messages with code 'what' and
+     * whose obj is 'object' in the message queue.
+     *
+     *@hide
+     */
+    public final boolean hasEqualMessages(int what, @Nullable Object object) {
+        return mQueue.hasEqualMessages(this, what, object);
+    }
+
+    /**
      * Check if there are any pending posts of messages with callback r in
      * the message queue.
      */
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index 4e91057..5293504 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -617,6 +617,23 @@
         }
     }
 
+    boolean hasEqualMessages(Handler h, int what, Object object) {
+        if (h == null) {
+            return false;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+            while (p != null) {
+                if (p.target == h && p.what == what && (object == null || object.equals(p.obj))) {
+                    return true;
+                }
+                p = p.next;
+            }
+            return false;
+        }
+    }
+
     @UnsupportedAppUsage
     boolean hasMessages(Handler h, Runnable r, Object object) {
         if (h == null) {
@@ -686,6 +703,40 @@
         }
     }
 
+    void removeEqualMessages(Handler h, int what, Object object) {
+        if (h == null) {
+            return;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+
+            // Remove all messages at front.
+            while (p != null && p.target == h && p.what == what
+                   && (object == null || object.equals(p.obj))) {
+                Message n = p.next;
+                mMessages = n;
+                p.recycleUnchecked();
+                p = n;
+            }
+
+            // Remove all messages after front.
+            while (p != null) {
+                Message n = p.next;
+                if (n != null) {
+                    if (n.target == h && n.what == what
+                        && (object == null || object.equals(n.obj))) {
+                        Message nn = n.next;
+                        n.recycleUnchecked();
+                        p.next = nn;
+                        continue;
+                    }
+                }
+                p = n;
+            }
+        }
+    }
+
     void removeMessages(Handler h, Runnable r, Object object) {
         if (h == null || r == null) {
             return;
@@ -720,6 +771,41 @@
         }
     }
 
+    void removeEqualMessages(Handler h, Runnable r, Object object) {
+        if (h == null || r == null) {
+            return;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+
+            // Remove all messages at front.
+            while (p != null && p.target == h && p.callback == r
+                   && (object == null || object.equals(p.obj))) {
+                Message n = p.next;
+                mMessages = n;
+                p.recycleUnchecked();
+                p = n;
+            }
+
+            // Remove all messages after front.
+            while (p != null) {
+                Message n = p.next;
+                if (n != null) {
+                    if (n.target == h && n.callback == r
+                        && (object == null || object.equals(n.obj))) {
+                        Message nn = n.next;
+                        n.recycleUnchecked();
+                        p.next = nn;
+                        continue;
+                    }
+                }
+                p = n;
+            }
+        }
+    }
+
+
     void removeCallbacksAndMessages(Handler h, Object object) {
         if (h == null) {
             return;
@@ -753,6 +839,39 @@
         }
     }
 
+    void removeCallbacksAndEqualMessages(Handler h, Object object) {
+        if (h == null) {
+            return;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+
+            // Remove all messages at front.
+            while (p != null && p.target == h
+                    && (object == null || object.equals(p.obj))) {
+                Message n = p.next;
+                mMessages = n;
+                p.recycleUnchecked();
+                p = n;
+            }
+
+            // Remove all messages after front.
+            while (p != null) {
+                Message n = p.next;
+                if (n != null) {
+                    if (n.target == h && (object == null || object.equals(n.obj))) {
+                        Message nn = n.next;
+                        n.recycleUnchecked();
+                        p.next = nn;
+                        continue;
+                    }
+                }
+                p = n;
+            }
+        }
+    }
+
     private void removeAllMessagesLocked() {
         Message p = mMessages;
         while (p != null) {
diff --git a/core/java/android/os/incremental/IncrementalFileSystemControlParcel.aidl b/core/java/android/os/incremental/IncrementalFileSystemControlParcel.aidl
index 0ae353d..5d8f6d1 100644
--- a/core/java/android/os/incremental/IncrementalFileSystemControlParcel.aidl
+++ b/core/java/android/os/incremental/IncrementalFileSystemControlParcel.aidl
@@ -17,11 +17,12 @@
 package android.os.incremental;
 
 /**
- * Wraps two file descriptors that Incremental Service uses to communicate
+ * Wraps the file descriptors Incremental Service uses to communicate
  * with Incremental FileSystem.
  * @hide
  */
 parcelable IncrementalFileSystemControlParcel {
     @nullable ParcelFileDescriptor cmd;
+    @nullable ParcelFileDescriptor pendingReads;
     @nullable ParcelFileDescriptor log;
 }
diff --git a/core/java/android/provider/BlockedNumberContract.java b/core/java/android/provider/BlockedNumberContract.java
index 1eb7664..dd2ea81 100644
--- a/core/java/android/provider/BlockedNumberContract.java
+++ b/core/java/android/provider/BlockedNumberContract.java
@@ -16,7 +16,6 @@
 package android.provider;
 
 import android.annotation.IntDef;
-import android.annotation.SystemApi;
 import android.annotation.WorkerThread;
 import android.content.Context;
 import android.net.Uri;
@@ -240,7 +239,6 @@
      * blocked.
      * @hide
      */
-    @SystemApi
     public static final int STATUS_NOT_BLOCKED = 0;
 
     /**
@@ -248,7 +246,6 @@
      * because it is in the list of blocked numbers maintained by the provider.
      * @hide
      */
-    @SystemApi
     public static final int STATUS_BLOCKED_IN_LIST = 1;
 
     /**
@@ -256,7 +253,6 @@
      * because it is from a restricted number.
      * @hide
      */
-    @SystemApi
     public static final int STATUS_BLOCKED_RESTRICTED = 2;
 
     /**
@@ -264,7 +260,6 @@
      * because it is from an unknown number.
      * @hide
      */
-    @SystemApi
     public static final int STATUS_BLOCKED_UNKNOWN_NUMBER = 3;
 
     /**
@@ -272,7 +267,6 @@
      * because it is from a pay phone.
      * @hide
      */
-    @SystemApi
     public static final int STATUS_BLOCKED_PAYPHONE = 4;
 
     /**
@@ -280,14 +274,12 @@
      * because it is from a number not in the users contacts.
      * @hide
      */
-    @SystemApi
     public static final int STATUS_BLOCKED_NOT_IN_CONTACTS = 5;
 
     /**
      * Integer reason indicating whether a call was blocked, and if so why.
      * @hide
      */
-    @SystemApi
     public static final String RES_BLOCK_STATUS = "block_status";
 
     /** @hide */
@@ -298,31 +290,6 @@
             "can_current_user_block_numbers";
 
     /** @hide */
-    @SystemApi
-    public static final String METHOD_NOTIFY_EMERGENCY_CONTACT = "notify_emergency_contact";
-
-    /** @hide */
-    public static final String METHOD_END_BLOCK_SUPPRESSION = "end_block_suppression";
-
-    /** @hide */
-    @SystemApi
-    public static final String METHOD_SHOULD_SYSTEM_BLOCK_NUMBER = "should_system_block_number";
-
-    /** @hide */
-    public static final String METHOD_GET_BLOCK_SUPPRESSION_STATUS =
-            "get_block_suppression_status";
-
-    /** @hide */
-    public static final String METHOD_SHOULD_SHOW_EMERGENCY_CALL_NOTIFICATION =
-            "should_show_emergency_call_notification";
-
-    /** @hide */
-    public static final String METHOD_GET_ENHANCED_BLOCK_SETTING = "get_enhanced_block_setting";
-
-    /** @hide */
-    public static final String METHOD_SET_ENHANCED_BLOCK_SETTING = "set_enhanced_block_setting";
-
-    /** @hide */
     public static final String RES_CAN_BLOCK_NUMBERS = "can_block";
 
     /** @hide */
@@ -439,11 +406,26 @@
         public static final String ACTION_BLOCK_SUPPRESSION_STATE_CHANGED =
                 "android.provider.action.BLOCK_SUPPRESSION_STATE_CHANGED";
 
+        public static final String METHOD_NOTIFY_EMERGENCY_CONTACT = "notify_emergency_contact";
+
+        public static final String METHOD_END_BLOCK_SUPPRESSION = "end_block_suppression";
+
+        public static final String METHOD_SHOULD_SYSTEM_BLOCK_NUMBER = "should_system_block_number";
+
+        public static final String METHOD_GET_BLOCK_SUPPRESSION_STATUS =
+                "get_block_suppression_status";
+
+        public static final String METHOD_SHOULD_SHOW_EMERGENCY_CALL_NOTIFICATION =
+                "should_show_emergency_call_notification";
+
         public static final String RES_IS_BLOCKING_SUPPRESSED = "blocking_suppressed";
 
         public static final String RES_BLOCKING_SUPPRESSED_UNTIL_TIMESTAMP =
                 "blocking_suppressed_until_timestamp";
 
+        public static final String METHOD_GET_ENHANCED_BLOCK_SETTING = "get_enhanced_block_setting";
+        public static final String METHOD_SET_ENHANCED_BLOCK_SETTING = "set_enhanced_block_setting";
+
         /* Preference key of block numbers not in contacts setting. */
         public static final String ENHANCED_SETTING_KEY_BLOCK_UNREGISTERED =
                 "block_numbers_not_in_contacts_setting";
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d6869c5..de30bce 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10197,6 +10197,8 @@
        public static final String NETSTATS_SAMPLE_ENABLED = "netstats_sample_enabled";
        /** {@hide} */
        public static final String NETSTATS_AUGMENT_ENABLED = "netstats_augment_enabled";
+       /** {@hide} */
+       public static final String NETSTATS_COMBINE_SUBTYPE_ENABLED = "netstats_combine_subtype_enabled";
 
        /** {@hide} */
        public static final String NETSTATS_DEV_BUCKET_DURATION = "netstats_dev_bucket_duration";
@@ -13407,12 +13409,12 @@
          * <p>
          * Type: int (0 for false, 1 for true)
          * @hide
-         * @deprecated Use {@link android.provider.Telephony.SimInfo#ENHANCED_4G_MODE_ENABLED}
-         * instead.
+         * @deprecated Use
+         * {@link android.provider.Telephony.SimInfo#COLUMN_ENHANCED_4G_MODE_ENABLED} instead.
          */
         @Deprecated
         public static final String ENHANCED_4G_MODE_ENABLED =
-                Telephony.SimInfo.ENHANCED_4G_MODE_ENABLED;
+                Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED;
 
         /**
          * Whether VT (Video Telephony over IMS) is enabled
@@ -13420,10 +13422,10 @@
          * Type: int (0 for false, 1 for true)
          *
          * @hide
-         * @deprecated Use {@link android.provider.Telephony.SimInfo#VT_IMS_ENABLED} instead.
+         * @deprecated Use {@link android.provider.Telephony.SimInfo#COLUMN_VT_IMS_ENABLED} instead.
          */
         @Deprecated
-        public static final String VT_IMS_ENABLED = Telephony.SimInfo.VT_IMS_ENABLED;
+        public static final String VT_IMS_ENABLED = Telephony.SimInfo.COLUMN_VT_IMS_ENABLED;
 
         /**
          * Whether WFC is enabled
@@ -13431,10 +13433,11 @@
          * Type: int (0 for false, 1 for true)
          *
          * @hide
-         * @deprecated Use {@link android.provider.Telephony.SimInfo#WFC_IMS_ENABLED} instead.
+         * @deprecated Use
+         * {@link android.provider.Telephony.SimInfo#COLUMN_WFC_IMS_ENABLED} instead.
          */
         @Deprecated
-        public static final String WFC_IMS_ENABLED = Telephony.SimInfo.WFC_IMS_ENABLED;
+        public static final String WFC_IMS_ENABLED = Telephony.SimInfo.COLUMN_WFC_IMS_ENABLED;
 
         /**
          * WFC mode on home/non-roaming network.
@@ -13442,10 +13445,10 @@
          * Type: int - 2=Wi-Fi preferred, 1=Cellular preferred, 0=Wi-Fi only
          *
          * @hide
-         * @deprecated Use {@link android.provider.Telephony.SimInfo#WFC_IMS_MODE} instead.
+         * @deprecated Use {@link android.provider.Telephony.SimInfo#COLUMN_WFC_IMS_MODE} instead.
          */
         @Deprecated
-        public static final String WFC_IMS_MODE = Telephony.SimInfo.WFC_IMS_MODE;
+        public static final String WFC_IMS_MODE = Telephony.SimInfo.COLUMN_WFC_IMS_MODE;
 
         /**
          * WFC mode on roaming network.
@@ -13453,11 +13456,12 @@
          * Type: int - see {@link #WFC_IMS_MODE} for values
          *
          * @hide
-         * @deprecated Use {@link android.provider.Telephony.SimInfo#WFC_IMS_ROAMING_MODE}
+         * @deprecated Use {@link android.provider.Telephony.SimInfo#COLUMN_WFC_IMS_ROAMING_MODE}
          * instead.
          */
         @Deprecated
-        public static final String WFC_IMS_ROAMING_MODE = Telephony.SimInfo.WFC_IMS_ROAMING_MODE;
+        public static final String WFC_IMS_ROAMING_MODE =
+                Telephony.SimInfo.COLUMN_WFC_IMS_ROAMING_MODE;
 
         /**
          * Whether WFC roaming is enabled
@@ -13465,12 +13469,12 @@
          * Type: int (0 for false, 1 for true)
          *
          * @hide
-         * @deprecated Use {@link android.provider.Telephony.SimInfo#WFC_IMS_ROAMING_ENABLED}
+         * @deprecated Use {@link android.provider.Telephony.SimInfo#COLUMN_WFC_IMS_ROAMING_ENABLED}
          * instead
          */
         @Deprecated
         public static final String WFC_IMS_ROAMING_ENABLED =
-                Telephony.SimInfo.WFC_IMS_ROAMING_ENABLED;
+                Telephony.SimInfo.COLUMN_WFC_IMS_ROAMING_ENABLED;
 
         /**
          * Whether user can enable/disable LTE as a preferred network. A carrier might control
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index a897a8e..db17d73 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1365,7 +1365,6 @@
      * Base column for the table that contain Carrier Public key.
      * @hide
      */
-    @SystemApi
     public interface CarrierColumns extends BaseColumns {
 
         /**
@@ -4358,6 +4357,7 @@
          * Indicates that whether the message has been broadcasted to the application.
          * <P>Type: BOOLEAN</P>
          */
+        // TODO: deprecate this in S.
         public static final String MESSAGE_BROADCASTED = "message_broadcasted";
 
         /**
@@ -4864,7 +4864,6 @@
          * Contains mappings between matching rules with carrier id for all carriers.
          * @hide
          */
-        @SystemApi
         public static final class All implements BaseColumns {
 
             /**
@@ -4940,7 +4939,6 @@
      * Contains SIM Information
      * @hide
      */
-    @SystemApi
     public static final class SimInfo {
         /**
          * Not instantiable.
@@ -4950,6 +4948,7 @@
 
         /**
          * The {@code content://} style URI for this provider.
+         * @hide
          */
         @NonNull
         public static final Uri CONTENT_URI = Uri.parse("content://telephony/siminfo");
@@ -4957,25 +4956,32 @@
         /**
          * TelephonyProvider unique key column name is the subscription id.
          * <P>Type: TEXT (String)</P>
+         *
+         * @hide
          */
-        public static final String UNIQUE_KEY_SUBSCRIPTION_ID = "_id";
+        public static final String COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID = "_id";
 
         /**
          * TelephonyProvider column name for a unique identifier for the subscription within the
          * specific subscription type. For example, it contains SIM ICC Identifier subscriptions
          * on Local SIMs. and Mac-address for Remote-SIM Subscriptions for Bluetooth devices.
          * <P>Type: TEXT (String)</P>
+         *
+         * @hide
          */
-        public static final String ICC_ID = "icc_id";
+        public static final String COLUMN_ICC_ID = "icc_id";
 
         /**
          * TelephonyProvider column name for user SIM_SlOT_INDEX
          * <P>Type: INTEGER (int)</P>
+         *
+         * @hide
          */
-        public static final String SIM_SLOT_INDEX = "sim_id";
+        public static final String COLUMN_SIM_SLOT_INDEX = "sim_id";
 
         /**
          * SIM is not inserted
+         * @hide
          */
         public static final int SIM_NOT_INSERTED = -1;
 
@@ -4984,14 +4990,18 @@
          * <P>Type: INTEGER (int)</P> {@link #SUBSCRIPTION_TYPE_LOCAL_SIM} for Local-SIM
          * Subscriptions, {@link #SUBSCRIPTION_TYPE_REMOTE_SIM} for Remote-SIM Subscriptions.
          * Default value is 0.
+         *
+         * @hide
          */
-        public static final String SUBSCRIPTION_TYPE = "subscription_type";
+        public static final String COLUMN_SUBSCRIPTION_TYPE = "subscription_type";
 
         /**
          * This constant is to designate a subscription as a Local-SIM Subscription.
          * <p> A Local-SIM can be a physical SIM inserted into a sim-slot in the device, or eSIM on
          * the device.
          * </p>
+         *
+         * @hide
          */
         public static final int SUBSCRIPTION_TYPE_LOCAL_SIM = 0;
 
@@ -5018,6 +5028,8 @@
          * phone; i.e., new Remote-SIM subscription treats the reconnected phone as a Remote-SIM
          * that was never seen before.
          * </p>
+         *
+         * @hide
          */
         public static final int SUBSCRIPTION_TYPE_REMOTE_SIM = 1;
 
@@ -5030,71 +5042,89 @@
          * subscription and while is in voice call.
          *
          * Default value is empty string.
+         *
+         * @hide
          */
-        public static final String DATA_ENABLED_OVERRIDE_RULES = "data_enabled_override_rules";
+        public static final String COLUMN_DATA_ENABLED_OVERRIDE_RULES =
+                "data_enabled_override_rules";
 
         /**
          * TelephonyProvider column name for user displayed name.
          * <P>Type: TEXT (String)</P>
+         *
+         * @hide
          */
-        public static final String DISPLAY_NAME = "display_name";
+        public static final String COLUMN_DISPLAY_NAME = "display_name";
 
         /**
          * TelephonyProvider column name for the service provider name for the SIM.
          * <P>Type: TEXT (String)</P>
+         *
+         * @hide
          */
-        public static final String CARRIER_NAME = "carrier_name";
+        public static final String COLUMN_CARRIER_NAME = "carrier_name";
 
         /**
          * TelephonyProvider column name for source of the user displayed name.
          * <P>Type: INT (int)</P> with one of the NAME_SOURCE_XXXX values below
+         *
+         * @hide
          */
-        public static final String NAME_SOURCE = "name_source";
+        public static final String COLUMN_NAME_SOURCE = "name_source";
 
-        /** The name_source is the default, which is from the carrier id. */
-        public static final int NAME_SOURCE_DEFAULT = 0;
+        /** The name_source is from the carrier id. {@hide} */
+        public static final int NAME_SOURCE_CARRIER_ID = 0;
 
         /**
          * The name_source is from SIM EF_SPN.
+         * @hide
          */
         public static final int NAME_SOURCE_SIM_SPN = 1;
 
         /**
          * The name_source is from user input
+         * @hide
          */
         public static final int NAME_SOURCE_USER_INPUT = 2;
 
         /**
          * The name_source is carrier (carrier app, carrier config, etc.)
+         * @hide
          */
         public static final int NAME_SOURCE_CARRIER = 3;
 
         /**
          * The name_source is from SIM EF_PNN.
+         * @hide
          */
         public static final int NAME_SOURCE_SIM_PNN = 4;
 
         /**
          * TelephonyProvider column name for the color of a SIM.
          * <P>Type: INTEGER (int)</P>
+         *
+         * @hide
          */
-        public static final String COLOR = "color";
+        public static final String COLUMN_COLOR = "color";
 
-        /** TelephonyProvider column name for the default color of a SIM {@hide} */
+        /** The default color of a SIM {@hide} */
         public static final int COLOR_DEFAULT = 0;
 
         /**
          * TelephonyProvider column name for the phone number of a SIM.
          * <P>Type: TEXT (String)</P>
+         *
+         * @hide
          */
-        public static final String NUMBER = "number";
+        public static final String COLUMN_NUMBER = "number";
 
         /**
          * TelephonyProvider column name for the number display format of a SIM.
          * <P>Type: INTEGER (int)</P>
+         *
          * @hide
          */
-        public static final String DISPLAY_NUMBER_FORMAT = "display_number_format";
+        public static final String COLUMN_DISPLAY_NUMBER_FORMAT = "display_number_format";
 
         /**
          * TelephonyProvider column name for the default display format of a SIM
@@ -5105,73 +5135,89 @@
         /**
          * TelephonyProvider column name for whether data roaming is enabled.
          * <P>Type: INTEGER (int)</P>
+         *
+         * @hide
          */
-        public static final String DATA_ROAMING = "data_roaming";
+        public static final String COLUMN_DATA_ROAMING = "data_roaming";
 
-        /** Indicates that data roaming is enabled for a subscription */
+        /** Indicates that data roaming is enabled for a subscription {@hide} */
         public static final int DATA_ROAMING_ENABLE = 1;
 
-        /** Indicates that data roaming is disabled for a subscription */
+        /** Indicates that data roaming is disabled for a subscription {@hide} */
         public static final int DATA_ROAMING_DISABLE = 0;
 
-        /** TelephonyProvider column name for default data roaming setting: disable */
-        public static final int DATA_ROAMING_DEFAULT = DATA_ROAMING_DISABLE;
-
         /**
          * TelephonyProvider column name for subscription carrier id.
          * @see TelephonyManager#getSimCarrierId()
          * <p>Type: INTEGER (int) </p>
+         *
+         * @hide
          */
-        public static final String CARRIER_ID = "carrier_id";
+        public static final String COLUMN_CARRIER_ID = "carrier_id";
 
         /**
          * A comma-separated list of EHPLMNs associated with the subscription
          * <P>Type: TEXT (String)</P>
+         *
+         * @hide
          */
-        public static final String EHPLMNS = "ehplmns";
+        public static final String COLUMN_EHPLMNS = "ehplmns";
 
         /**
          * A comma-separated list of HPLMNs associated with the subscription
          * <P>Type: TEXT (String)</P>
+         *
+         * @hide
          */
-        public static final String HPLMNS = "hplmns";
+        public static final String COLUMN_HPLMNS = "hplmns";
 
         /**
          * TelephonyProvider column name for the MCC associated with a SIM, stored as a string.
          * <P>Type: TEXT (String)</P>
+         *
+         * @hide
          */
-        public static final String MCC_STRING = "mcc_string";
+        public static final String COLUMN_MCC_STRING = "mcc_string";
 
         /**
          * TelephonyProvider column name for the MNC associated with a SIM, stored as a string.
          * <P>Type: TEXT (String)</P>
+         *
+         * @hide
          */
-        public static final String MNC_STRING = "mnc_string";
+        public static final String COLUMN_MNC_STRING = "mnc_string";
 
         /**
          * TelephonyProvider column name for the MCC associated with a SIM.
          * <P>Type: INTEGER (int)</P>
+         *
+         * @hide
          */
-        public static final String MCC = "mcc";
+        public static final String COLUMN_MCC = "mcc";
 
         /**
          * TelephonyProvider column name for the MNC associated with a SIM.
          * <P>Type: INTEGER (int)</P>
+         *
+         * @hide
          */
-        public static final String MNC = "mnc";
+        public static final String COLUMN_MNC = "mnc";
 
         /**
          * TelephonyProvider column name for the iso country code associated with a SIM.
          * <P>Type: TEXT (String)</P>
+         *
+         * @hide
          */
-        public static final String ISO_COUNTRY_CODE = "iso_country_code";
+        public static final String COLUMN_ISO_COUNTRY_CODE = "iso_country_code";
 
         /**
          * TelephonyProvider column name for the sim provisioning status associated with a SIM.
          * <P>Type: INTEGER (int)</P>
+         *
          * @hide
          */
-        public static final String SIM_PROVISIONING_STATUS = "sim_provisioning_status";
+        public static final String COLUMN_SIM_PROVISIONING_STATUS = "sim_provisioning_status";
 
         /** The sim is provisioned {@hide} */
         public static final int SIM_PROVISIONED = 0;
@@ -5180,147 +5226,174 @@
          * TelephonyProvider column name for whether a subscription is embedded (that is, present on
          * an eSIM).
          * <p>Type: INTEGER (int), 1 for embedded or 0 for non-embedded.
+         *
+         * @hide
          */
-        public static final String IS_EMBEDDED = "is_embedded";
+        public static final String COLUMN_IS_EMBEDDED = "is_embedded";
 
         /**
          * TelephonyProvider column name for SIM card identifier. For UICC card it is the ICCID of
          * the current enabled profile on the card, while for eUICC card it is the EID of the card.
          * <P>Type: TEXT (String)</P>
+         *
+         * @hide
          */
-        public static final String CARD_ID = "card_id";
+        public static final String COLUMN_CARD_ID = "card_id";
 
         /**
          * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from
-         * {@link UiccAccessRule#encodeRules}. Only present if {@link #IS_EMBEDDED} is 1.
+         * {@link UiccAccessRule#encodeRules}. Only present if {@link #COLUMN_IS_EMBEDDED} is 1.
          * <p>TYPE: BLOB
+         *
+         * @hide
          */
-        public static final String ACCESS_RULES = "access_rules";
+        public static final String COLUMN_ACCESS_RULES = "access_rules";
 
         /**
          * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from
          * {@link UiccAccessRule#encodeRules} but for the rules that come from CarrierConfigs.
          * Only present if there are access rules in CarrierConfigs
          * <p>TYPE: BLOB
+         *
+         * @hide
          */
-        public static final String ACCESS_RULES_FROM_CARRIER_CONFIGS =
+        public static final String COLUMN_ACCESS_RULES_FROM_CARRIER_CONFIGS =
                 "access_rules_from_carrier_configs";
 
         /**
          * TelephonyProvider column name identifying whether an embedded subscription is on a
          * removable card. Such subscriptions are marked inaccessible as soon as the current card
          * is removed. Otherwise, they will remain accessible unless explicitly deleted. Only
-         * present if {@link #IS_EMBEDDED} is 1.
+         * present if {@link #COLUMN_IS_EMBEDDED} is 1.
          * <p>TYPE: INTEGER (int), 1 for removable or 0 for non-removable.
+         *
+         * @hide
          */
-        public static final String IS_REMOVABLE = "is_removable";
+        public static final String COLUMN_IS_REMOVABLE = "is_removable";
 
-        /** TelephonyProvider column name for extreme threat in CB settings */
-        public static final String CB_EXTREME_THREAT_ALERT = "enable_cmas_extreme_threat_alerts";
+        /** TelephonyProvider column name for extreme threat in CB settings {@hide} */
+        public static final String COLUMN_CB_EXTREME_THREAT_ALERT =
+                "enable_cmas_extreme_threat_alerts";
 
-        /** TelephonyProvider column name for severe threat in CB settings */
-        public static final String CB_SEVERE_THREAT_ALERT = "enable_cmas_severe_threat_alerts";
+        /** TelephonyProvider column name for severe threat in CB settings {@hide} */
+        public static final String COLUMN_CB_SEVERE_THREAT_ALERT =
+                "enable_cmas_severe_threat_alerts";
 
-        /** TelephonyProvider column name for amber alert in CB settings */
-        public static final String CB_AMBER_ALERT = "enable_cmas_amber_alerts";
+        /** TelephonyProvider column name for amber alert in CB settings {@hide} */
+        public static final String COLUMN_CB_AMBER_ALERT = "enable_cmas_amber_alerts";
 
-        /** TelephonyProvider column name for emergency alert in CB settings */
-        public static final String CB_EMERGENCY_ALERT = "enable_emergency_alerts";
+        /** TelephonyProvider column name for emergency alert in CB settings {@hide} */
+        public static final String COLUMN_CB_EMERGENCY_ALERT = "enable_emergency_alerts";
 
-        /** TelephonyProvider column name for alert sound duration in CB settings */
-        public static final String CB_ALERT_SOUND_DURATION = "alert_sound_duration";
+        /** TelephonyProvider column name for alert sound duration in CB settings {@hide} */
+        public static final String COLUMN_CB_ALERT_SOUND_DURATION = "alert_sound_duration";
 
-        /** TelephonyProvider column name for alert reminder interval in CB settings */
-        public static final String CB_ALERT_REMINDER_INTERVAL = "alert_reminder_interval";
+        /** TelephonyProvider column name for alert reminder interval in CB settings {@hide} */
+        public static final String COLUMN_CB_ALERT_REMINDER_INTERVAL = "alert_reminder_interval";
 
-        /** TelephonyProvider column name for enabling vibrate in CB settings */
-        public static final String CB_ALERT_VIBRATE = "enable_alert_vibrate";
+        /** TelephonyProvider column name for enabling vibrate in CB settings {@hide} */
+        public static final String COLUMN_CB_ALERT_VIBRATE = "enable_alert_vibrate";
 
-        /** TelephonyProvider column name for enabling alert speech in CB settings */
-        public static final String CB_ALERT_SPEECH = "enable_alert_speech";
+        /** TelephonyProvider column name for enabling alert speech in CB settings {@hide} */
+        public static final String COLUMN_CB_ALERT_SPEECH = "enable_alert_speech";
 
-        /** TelephonyProvider column name for ETWS test alert in CB settings */
-        public static final String CB_ETWS_TEST_ALERT = "enable_etws_test_alerts";
+        /** TelephonyProvider column name for ETWS test alert in CB settings {@hide} */
+        public static final String COLUMN_CB_ETWS_TEST_ALERT = "enable_etws_test_alerts";
 
-        /** TelephonyProvider column name for enable channel50 alert in CB settings */
-        public static final String CB_CHANNEL_50_ALERT = "enable_channel_50_alerts";
+        /** TelephonyProvider column name for enable channel50 alert in CB settings {@hide} */
+        public static final String COLUMN_CB_CHANNEL_50_ALERT = "enable_channel_50_alerts";
 
-        /** TelephonyProvider column name for CMAS test alert in CB settings */
-        public static final String CB_CMAS_TEST_ALERT = "enable_cmas_test_alerts";
+        /** TelephonyProvider column name for CMAS test alert in CB settings {@hide} */
+        public static final String COLUMN_CB_CMAS_TEST_ALERT = "enable_cmas_test_alerts";
 
-        /** TelephonyProvider column name for Opt out dialog in CB settings */
-        public static final String CB_OPT_OUT_DIALOG = "show_cmas_opt_out_dialog";
+        /** TelephonyProvider column name for Opt out dialog in CB settings {@hide} */
+        public static final String COLUMN_CB_OPT_OUT_DIALOG = "show_cmas_opt_out_dialog";
 
         /**
          * TelephonyProvider column name for enable Volte.
          *
          * If this setting is not initialized (set to -1)  then we use the Carrier Config value
          * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
+         *
+         * @hide
          */
-        public static final String ENHANCED_4G_MODE_ENABLED = "volte_vt_enabled";
+        public static final String COLUMN_ENHANCED_4G_MODE_ENABLED = "volte_vt_enabled";
 
-        /** TelephonyProvider column name for enable VT (Video Telephony over IMS) */
-        public static final String VT_IMS_ENABLED = "vt_ims_enabled";
+        /** TelephonyProvider column name for enable VT (Video Telephony over IMS) {@hide} */
+        public static final String COLUMN_VT_IMS_ENABLED = "vt_ims_enabled";
 
-        /** TelephonyProvider column name for enable Wifi calling */
-        public static final String WFC_IMS_ENABLED = "wfc_ims_enabled";
+        /** TelephonyProvider column name for enable Wifi calling {@hide} */
+        public static final String COLUMN_WFC_IMS_ENABLED = "wfc_ims_enabled";
 
-        /** TelephonyProvider column name for Wifi calling mode */
-        public static final String WFC_IMS_MODE = "wfc_ims_mode";
+        /** TelephonyProvider column name for Wifi calling mode {@hide} */
+        public static final String COLUMN_WFC_IMS_MODE = "wfc_ims_mode";
 
-        /** TelephonyProvider column name for Wifi calling mode in roaming */
-        public static final String WFC_IMS_ROAMING_MODE = "wfc_ims_roaming_mode";
+        /** TelephonyProvider column name for Wifi calling mode in roaming {@hide} */
+        public static final String COLUMN_WFC_IMS_ROAMING_MODE = "wfc_ims_roaming_mode";
 
-        /** TelephonyProvider column name for enable Wifi calling in roaming */
-        public static final String WFC_IMS_ROAMING_ENABLED = "wfc_ims_roaming_enabled";
+        /** TelephonyProvider column name for enable Wifi calling in roaming {@hide} */
+        public static final String COLUMN_WFC_IMS_ROAMING_ENABLED = "wfc_ims_roaming_enabled";
 
         /**
-         * Determines if the user has enabled IMS RCS User Capability Exchange (UCE) for this
-         * subscription.
+         * TelephonyProvider column name for determining if the user has enabled IMS RCS User
+         * Capability Exchange (UCE) for this subscription.
+         *
+         * @hide
          */
-        public static final String IMS_RCS_UCE_ENABLED = "ims_rcs_uce_enabled";
+        public static final String COLUMN_IMS_RCS_UCE_ENABLED = "ims_rcs_uce_enabled";
 
         /**
          * TelephonyProvider column name for whether a subscription is opportunistic, that is,
          * whether the network it connects to is limited in functionality or coverage.
          * For example, CBRS.
          * <p>Type: INTEGER (int), 1 for opportunistic or 0 for non-opportunistic.
+         *
+         * @hide
          */
-        public static final String IS_OPPORTUNISTIC = "is_opportunistic";
+        public static final String COLUMN_IS_OPPORTUNISTIC = "is_opportunistic";
 
         /**
          * TelephonyProvider column name for group ID. Subscriptions with same group ID
          * are considered bundled together, and should behave as a single subscription at
          * certain scenarios.
+         *
+         * @hide
          */
-        public static final String GROUP_UUID = "group_uuid";
+        public static final String COLUMN_GROUP_UUID = "group_uuid";
 
         /**
          * TelephonyProvider column name for group owner. It's the package name who created
          * the subscription group.
+         *
+         * @hide
          */
-        public static final String GROUP_OWNER = "group_owner";
+        public static final String COLUMN_GROUP_OWNER = "group_owner";
 
         /**
          * TelephonyProvider column name for whether a subscription is metered or not, that is,
          * whether the network it connects to charges for subscription or not. For example, paid
          * CBRS or unpaid.
+         *
          * @hide
          */
-        public static final String IS_METERED = "is_metered";
+        public static final String COLUMN_IS_METERED = "is_metered";
 
         /**
          * TelephonyProvider column name for the profile class of a subscription
-         * Only present if {@link #IS_EMBEDDED} is 1.
+         * Only present if {@link #COLUMN_IS_EMBEDDED} is 1.
          * <P>Type: INTEGER (int)</P>
+         *
+         * @hide
          */
-        public static final String PROFILE_CLASS = "profile_class";
+        public static final String COLUMN_PROFILE_CLASS = "profile_class";
 
         /**
          * A testing profile can be pre-loaded or downloaded onto
          * the eUICC and provides connectivity to test equipment
          * for the purpose of testing the device and the eUICC. It
          * is not intended to store any operator credentials.
+         *
+         * @hide
          */
         public static final int PROFILE_CLASS_TESTING = 0;
 
@@ -5328,6 +5401,8 @@
          * A provisioning profile is pre-loaded onto the eUICC and
          * provides connectivity to a mobile network solely for the
          * purpose of provisioning profiles.
+         *
+         * @hide
          */
         public static final int PROFILE_CLASS_PROVISIONING = 1;
 
@@ -5335,6 +5410,8 @@
          * An operational profile can be pre-loaded or downloaded
          * onto the eUICC and provides services provided by the
          * operator.
+         *
+         * @hide
          */
         public static final int PROFILE_CLASS_OPERATIONAL = 2;
 
@@ -5342,25 +5419,32 @@
          * The profile class is unset. This occurs when profile class
          * info is not available. The subscription either has no profile
          * metadata or the profile metadata did not encode profile class.
+         *
+         * @hide
          */
         public static final int PROFILE_CLASS_UNSET = -1;
 
-        /** Default profile class */
-        public static final int PROFILE_CLASS_DEFAULT = PROFILE_CLASS_UNSET;
-
         /**
          * IMSI (International Mobile Subscriber Identity).
          * <P>Type: TEXT </P>
+         *
+         * @hide
          */
-        public static final String IMSI = "imsi";
+        public static final String COLUMN_IMSI = "imsi";
 
-        /** Whether uicc applications is set to be enabled or disabled. By default it's enabled. */
-        public static final String UICC_APPLICATIONS_ENABLED = "uicc_applications_enabled";
+        /**
+         * Whether uicc applications is set to be enabled or disabled. By default it's enabled.
+         * @hide
+         */
+        public static final String COLUMN_UICC_APPLICATIONS_ENABLED = "uicc_applications_enabled";
 
         /**
          * TelephonyProvider column name for allowed network types. Indicate which network types
          * are allowed. Default is -1.
+         * <P>Type: BIGINT (long) </P>
+         *
+         * @hide
          */
-        public static final String ALLOWED_NETWORK_TYPES = "allowed_network_types";
+        public static final String COLUMN_ALLOWED_NETWORK_TYPES = "allowed_network_types";
     }
 }
diff --git a/core/java/android/se/omapi/Reader.java b/core/java/android/se/omapi/Reader.java
index 7f68d91..90c934d 100644
--- a/core/java/android/se/omapi/Reader.java
+++ b/core/java/android/se/omapi/Reader.java
@@ -160,7 +160,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED)
+    @RequiresPermission(android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION)
     public boolean reset() {
         if (!mService.isConnected()) {
             Log.e(TAG, "service is not connected");
diff --git a/core/java/android/telephony/CellBroadcastIntents.java b/core/java/android/telephony/CellBroadcastIntents.java
index 32d330e..e07f69a 100644
--- a/core/java/android/telephony/CellBroadcastIntents.java
+++ b/core/java/android/telephony/CellBroadcastIntents.java
@@ -46,7 +46,11 @@
 
     /**
      * Broadcast intent action for notifying area information has been updated. The information
-     * can be retrieved by {@link CellBroadcastService#getCellBroadcastAreaInfo(int)}
+     * can be retrieved by {@link CellBroadcastService#getCellBroadcastAreaInfo(int)}. The
+     * associated SIM slot index of updated area information can be retrieved through the extra
+     * {@link SubscriptionManager#EXTRA_SLOT_INDEX}.
+     *
+     * @see SubscriptionManager#EXTRA_SLOT_INDEX
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_AREA_INFO_UPDATED =
@@ -81,7 +85,6 @@
             int initialCode, int slotIndex) {
         Intent backgroundIntent = new Intent(Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION);
         backgroundIntent.putExtra(EXTRA_MESSAGE, smsCbMessage);
-        backgroundIntent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
         putPhoneIdAndSubIdExtra(context, backgroundIntent, slotIndex);
 
         String receiverPermission = Manifest.permission.RECEIVE_SMS;
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 1dca7fd..f8b9f58 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -176,7 +176,6 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
-    @SystemApi
     public static final int LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH          = 0x00000200;
 
     /**
@@ -427,6 +426,17 @@
     @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
     public static final int LISTEN_REGISTRATION_FAILURE = 0x40000000;
 
+    /**
+     * Listen for Barring Information for the current registered / camped cell.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling
+     * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+     *
+     * @see #onBarringInfoChanged()
+     */
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public static final int LISTEN_BARRING_INFO = 0x80000000;
+
     /*
      * Subscription used to listen to the phone state changes
      * @hide
@@ -1036,6 +1046,20 @@
     }
 
     /**
+     * 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
+     */
+    public void onBarringInfoChanged(@NonNull BarringInfo barringInfo) {
+        // default implementation empty
+    }
+
+    /**
      * 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.
      *
@@ -1328,6 +1352,14 @@
                             cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode)));
             // default implementation empty
         }
+
+        public void onBarringInfoChanged(BarringInfo barringInfo) {
+            PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
+            if (psl == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> psl.onBarringInfoChanged(barringInfo)));
+        }
     }
 
 
diff --git a/core/java/android/telephony/SubscriptionPlan.java b/core/java/android/telephony/SubscriptionPlan.java
index 28a5c20..901957f 100644
--- a/core/java/android/telephony/SubscriptionPlan.java
+++ b/core/java/android/telephony/SubscriptionPlan.java
@@ -91,10 +91,11 @@
     private long dataUsageBytes = BYTES_UNKNOWN;
     private long dataUsageTime = TIME_UNKNOWN;
     private @NetworkType int[] networkTypes;
-    private long networkTypesBitMask;
 
     private SubscriptionPlan(RecurrenceRule cycleRule) {
         this.cycleRule = Preconditions.checkNotNull(cycleRule);
+        this.networkTypes = Arrays.copyOf(TelephonyManager.getAllNetworkTypes(),
+                TelephonyManager.getAllNetworkTypes().length);
     }
 
     private SubscriptionPlan(Parcel source) {
@@ -221,28 +222,10 @@
 
     /**
      * Return an array containing all {@link NetworkType}s this SubscriptionPlan applies to.
-     * A null value means this SubscriptionPlan applies to all network types.
+     * @see TelephonyManager for network types values
      */
-    public @Nullable @NetworkType int[] getNetworkTypes() {
-        return networkTypes;
-    }
-
-    /**
-     * Return the networkTypes array converted to a {@link TelephonyManager.NetworkTypeBitMask}
-     * @hide
-     */
-    public long getNetworkTypesBitMask() {
-        // calculate bitmask the first time and save for future calls
-        if (networkTypesBitMask == 0) {
-            if (networkTypes == null) {
-                networkTypesBitMask = ~0;
-            } else {
-                for (int networkType : networkTypes) {
-                    networkTypesBitMask |= TelephonyManager.getBitMaskForNetworkType(networkType);
-                }
-            }
-        }
-        return networkTypesBitMask;
+    public @NonNull @NetworkType int[] getNetworkTypes() {
+        return Arrays.copyOf(networkTypes, networkTypes.length);
     }
 
     /**
@@ -379,14 +362,14 @@
         }
 
         /**
-         * Set the network types this SubscriptionPlan applies to.
+         * Set the network types this SubscriptionPlan applies to. By default the plan will apply
+         * to all network types. An empty array means this plan applies to no network types.
          *
-         * @param networkTypes a set of all {@link NetworkType}s that apply to this plan.
-         *            A null value means the plan applies to all network types,
-         *            and an empty array means the plan applies to no network types.
+         * @param networkTypes an array of all {@link NetworkType}s that apply to this plan.
+         * @see TelephonyManager for network type values
          */
-        public @NonNull Builder setNetworkTypes(@Nullable @NetworkType int[] networkTypes) {
-            plan.networkTypes = networkTypes;
+        public @NonNull Builder setNetworkTypes(@NonNull @NetworkType int[] networkTypes) {
+            plan.networkTypes = Arrays.copyOf(networkTypes, networkTypes.length);
             return this;
         }
     }
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index c4b4c43..e362042 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -26,8 +26,10 @@
 import android.telephony.Annotation.CallState;
 import android.telephony.Annotation.DataActivityType;
 import android.telephony.Annotation.DataFailureCause;
+import android.telephony.Annotation.DisconnectCauses;
 import android.telephony.Annotation.NetworkType;
 import android.telephony.Annotation.PreciseCallStates;
+import android.telephony.Annotation.PreciseDisconnectCauses;
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SimActivationState;
 import android.telephony.Annotation.SrvccState;
@@ -229,11 +231,9 @@
      * invalid.
      * @param state latest call state. e.g, offhook, ringing
      * @param incomingNumber incoming phone number.
-     *
-     * @hide
      */
     public void notifyCallStateChanged(int subId, int slotIndex, @CallState int state,
-            String incomingNumber) {
+            @Nullable String incomingNumber) {
         try {
             sRegistry.notifyCallState(slotIndex, subId, state, incomingNumber);
         } catch (RemoteException ex) {
@@ -266,10 +266,8 @@
      * @param slotIndex for which the service state changed. Can be derived from subId except
      * subId is invalid.
      * @param state service state e.g, in service, out of service or roaming status.
-     *
-     * @hide
      */
-    public void notifyServiceStateChanged(int subId, int slotIndex, ServiceState state) {
+    public void notifyServiceStateChanged(int subId, int slotIndex, @NonNull ServiceState state) {
         try {
             sRegistry.notifyServiceStateForPhoneId(slotIndex, subId, state);
         } catch (RemoteException ex) {
@@ -284,11 +282,9 @@
      * @param slotIndex for which the signalstrength changed. Can be derived from subId except when
      * subId is invalid.
      * @param signalStrength e.g, signalstrength level {@see SignalStrength#getLevel()}
-     *
-     * @hide
      */
     public void notifySignalStrengthChanged(int subId, int slotIndex,
-        SignalStrength signalStrength) {
+            @NonNull SignalStrength signalStrength) {
         try {
             sRegistry.notifySignalStrengthForPhoneId(slotIndex, subId, signalStrength);
         } catch (RemoteException ex) {
@@ -305,8 +301,6 @@
      * except when subId is invalid.
      * @param msgWaitingInd {@code true} indicates there is message-waiting indicator, {@code false}
      * otherwise.
-     *
-     * @hide
      */
     public void notifyMessageWaitingChanged(int subId, int slotIndex, boolean msgWaitingInd) {
         try {
@@ -322,8 +316,6 @@
      * @param subId for which call forwarding status changed.
      * @param callForwardInd {@code true} indicates there is call forwarding, {@code false}
      * otherwise.
-     *
-     * @hide
      */
     public void notifyCallForwardingChanged(int subId, boolean callForwardInd) {
         try {
@@ -339,8 +331,6 @@
      * @param subId for which data activity state changed.
      * @param dataActivityType indicates the latest data activity type e.g, {@link
      * TelephonyManager#DATA_ACTIVITY_IN}
-     *
-     * @hide
      */
     public void notifyDataActivityChanged(int subId, @DataActivityType int dataActivityType) {
         try {
@@ -361,10 +351,9 @@
      *
      * @see android.telephony.PreciseDataConnection
      * @see TelephonyManager#DATA_DISCONNECTED
-     * @hide
      */
     public void notifyDataConnectionForSubscriber(int slotIndex, int subId,
-            String apnType, PreciseDataConnectionState preciseState) {
+            String apnType, @Nullable PreciseDataConnectionState preciseState) {
         try {
             sRegistry.notifyDataConnectionForSubscriber(
                     slotIndex, subId, apnType, preciseState);
@@ -381,10 +370,8 @@
      * subId is invalid.
      * @param callQuality Information about call quality e.g, call quality level
      * @param networkType associated with this data connection. e.g, LTE
-     *
-     * @hide
      */
-    public void notifyCallQualityChanged(int subId, int slotIndex, CallQuality callQuality,
+    public void notifyCallQualityChanged(int subId, int slotIndex, @NonNull CallQuality callQuality,
         @NetworkType int networkType) {
         try {
             sRegistry.notifyCallQualityChanged(callQuality, slotIndex, subId, networkType);
@@ -399,8 +386,6 @@
      * @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.
-     *
-     * @hide
      */
     public void notifyEmergencyNumberList(int subId, int slotIndex) {
         try {
@@ -417,8 +402,6 @@
      * @param slotIndex for which radio power state changed. Can be derived from subId except when
      * subId is invalid.
      * @param radioPowerState the current modem radio state.
-     *
-     * @hide
      */
     public void notifyRadioPowerStateChanged(int subId, int slotIndex,
         @RadioPowerState int radioPowerState) {
@@ -433,10 +416,8 @@
      * Notify {@link PhoneCapability} changed.
      *
      * @param phoneCapability the capability of the modem group.
-     *
-     * @hide
      */
-    public void notifyPhoneCapabilityChanged(PhoneCapability phoneCapability) {
+    public void notifyPhoneCapabilityChanged(@NonNull PhoneCapability phoneCapability) {
         try {
             sRegistry.notifyPhoneCapabilityChanged(phoneCapability);
         } catch (RemoteException ex) {
@@ -465,8 +446,6 @@
      * @param slotIndex for which data activation state changed. Can be derived from subId except
      * when subId is invalid.
      * @param activationState sim activation state e.g, activated.
-     *
-     * @hide
      */
     public void notifyDataActivationStateChanged(int subId, int slotIndex,
         @SimActivationState int activationState) {
@@ -486,8 +465,6 @@
      * @param slotIndex for which voice activation state changed. Can be derived from subId except
      * subId is invalid.
      * @param activationState sim activation state e.g, activated.
-     *
-     * @hide
      */
     public void notifyVoiceActivationStateChanged(int subId, int slotIndex,
         @SimActivationState int activationState) {
@@ -507,8 +484,6 @@
      * @param slotIndex for which mobile data state has changed. Can be derived from subId except
      * when subId is invalid.
      * @param state {@code true} indicates mobile data is enabled/on. {@code false} otherwise.
-     *
-     * @hide
      */
     public void notifyUserMobileDataStateChanged(int slotIndex, int subId, boolean state) {
         try {
@@ -519,23 +494,6 @@
     }
 
     /**
-     * TODO: this is marked as deprecated, can we move this one safely?
-     *
-     * @param subId
-     * @param slotIndex
-     * @param rawData
-     *
-     * @hide
-     */
-    public void notifyOemHookRawEventForSubscriber(int subId, int slotIndex, byte[] rawData) {
-        try {
-            sRegistry.notifyOemHookRawEventForSubscriber(slotIndex, subId, rawData);
-        } catch (RemoteException ex) {
-            // system process is dead
-        }
-    }
-
-    /**
      * Notify display info changed.
      *
      * @param slotIndex The SIM slot index for which display info has changed. Can be
@@ -558,10 +516,8 @@
      *
      * @param subId for which ims call disconnect.
      * @param imsReasonInfo the reason for ims call disconnect.
-     *
-     * @hide
      */
-    public void notifyImsDisconnectCause(int subId, ImsReasonInfo imsReasonInfo) {
+    public void notifyImsDisconnectCause(int subId, @NonNull ImsReasonInfo imsReasonInfo) {
         try {
             sRegistry.notifyImsDisconnectCause(subId, imsReasonInfo);
         } catch (RemoteException ex) {
@@ -578,11 +534,9 @@
      * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN.
      * @param apn the APN {@link ApnSetting#getApnName()} of this data connection.
      * @param failCause data fail cause.
-     *
-     * @hide
      */
     public void notifyPreciseDataConnectionFailed(int subId, int slotIndex, String apnType,
-        String apn, @DataFailureCause int failCause) {
+            @Nullable String apn, @DataFailureCause int failCause) {
         try {
             sRegistry.notifyPreciseDataConnectionFailed(slotIndex, subId, apnType, apn, failCause);
         } catch (RemoteException ex) {
@@ -596,8 +550,6 @@
      *
      * @param subId for which srvcc state changed.
      * @param state srvcc state
-     *
-     * @hide
      */
     public void notifySrvccStateChanged(int subId, @SrvccState int state) {
         try {
@@ -617,8 +569,6 @@
      * @param ringCallPreciseState ringCall state.
      * @param foregroundCallPreciseState foreground call state.
      * @param backgroundCallPreciseState background call state.
-     *
-     * @hide
      */
     public void notifyPreciseCallState(int subId, int slotIndex,
         @PreciseCallStates int ringCallPreciseState,
@@ -642,10 +592,9 @@
      * @param cause {@link DisconnectCause} for the disconnected call.
      * @param preciseCause {@link android.telephony.PreciseDisconnectCause} for the disconnected
      * call.
-     *
-     * @hide
      */
-    public void notifyDisconnectCause(int slotIndex, int subId, int cause, int preciseCause) {
+    public void notifyDisconnectCause(int slotIndex, int subId, @DisconnectCauses int cause,
+            @PreciseDisconnectCauses int preciseCause) {
         try {
             sRegistry.notifyDisconnectCause(slotIndex, subId, cause, preciseCause);
         } catch (RemoteException ex) {
@@ -658,10 +607,8 @@
      *
      * <p>To be compatible with {@link TelephonyRegistry}, use {@link CellIdentity} which is
      * parcelable, and convert to CellLocation in client code.
-     *
-     * @hide
      */
-    public void notifyCellLocation(int subId, CellIdentity cellLocation) {
+    public void notifyCellLocation(int subId, @NonNull CellIdentity cellLocation) {
         try {
             sRegistry.notifyCellLocationForSubscriber(subId, cellLocation);
         } catch (RemoteException ex) {
@@ -675,10 +622,8 @@
      *
      * @param subId for which cellinfo changed.
      * @param cellInfo A list of cellInfo associated with the given subscription.
-     *
-     * @hide
      */
-    public void notifyCellInfoChanged(int subId, List<CellInfo> cellInfo) {
+    public void notifyCellInfoChanged(int subId, @NonNull List<CellInfo> cellInfo) {
         try {
             sRegistry.notifyCellInfoForSubscriber(subId, cellInfo);
         } catch (RemoteException ex) {
@@ -687,8 +632,8 @@
     }
 
     /**
-     * @param activeDataSubId
-     * @hide
+     * Notify that the active data subscription ID has changed.
+     * @param activeDataSubId The new subscription ID for active data
      */
     public void notifyActiveDataSubIdChanged(int activeDataSubId) {
         try {
@@ -729,4 +674,21 @@
         } catch (RemoteException ex) {
         }
     }
+
+    /**
+     * Notify {@link BarringInfo} has changed for a specific subscription.
+     *
+     * @param slotIndex for the phone object that got updated barring info.
+     * @param subId for which the BarringInfo changed.
+     * @param barringInfo updated BarringInfo.
+     */
+    public void notifyBarringInfoChanged(
+            int slotIndex, int subId, @NonNull BarringInfo barringInfo) {
+        try {
+            sRegistry.notifyBarringInfoChanged(slotIndex, subId, barringInfo);
+        } catch (RemoteException ex) {
+            // system server crash
+        }
+    }
+
 }
diff --git a/core/java/android/view/inputmethod/OWNERS b/core/java/android/view/inputmethod/OWNERS
new file mode 100644
index 0000000..244cc30
--- /dev/null
+++ b/core/java/android/view/inputmethod/OWNERS
@@ -0,0 +1,3 @@
+set noparent
+
+include ../../../../../services/core/java/com/android/server/inputmethod/OWNERS
diff --git a/core/java/android/webkit/DateSorter.java b/core/java/android/webkit/DateSorter.java
index fede244..90d44db 100644
--- a/core/java/android/webkit/DateSorter.java
+++ b/core/java/android/webkit/DateSorter.java
@@ -19,11 +19,11 @@
 import android.content.Context;
 import android.content.res.Resources;
 
+import com.android.icu.text.DateSorterBridge;
+
 import java.util.Calendar;
 import java.util.Locale;
 
-import libcore.icu.LocaleData;
-
 /**
  * Sorts dates into the following groups:
  *   Today
@@ -69,9 +69,9 @@
         if (locale == null) {
             locale = Locale.getDefault();
         }
-        LocaleData localeData = LocaleData.get(locale);
-        mLabels[0] = localeData.today;
-        mLabels[1] = localeData.yesterday;
+        DateSorterBridge dateSorterBridge = DateSorterBridge.createInstance(locale);
+        mLabels[0] = dateSorterBridge.getToday();
+        mLabels[1] = dateSorterBridge.getYesterday();
 
         int resId = com.android.internal.R.plurals.last_num_days;
         String format = resources.getQuantityString(resId, NUM_DAYS_AGO);
diff --git a/core/java/com/android/ims/internal/uce/uceservice/ImsUceManager.java b/core/java/com/android/ims/internal/uce/uceservice/ImsUceManager.java
index 9aee879f..ef8d018 100644
--- a/core/java/com/android/ims/internal/uce/uceservice/ImsUceManager.java
+++ b/core/java/com/android/ims/internal/uce/uceservice/ImsUceManager.java
@@ -50,6 +50,16 @@
     public static final String ACTION_UCE_SERVICE_DOWN =
                                         "com.android.ims.internal.uce.UCE_SERVICE_DOWN";
 
+    /**
+     * Uce Service status received in IUceListener.setStatus() callback
+     */
+    public static final int UCE_SERVICE_STATUS_FAILURE = 0;
+    /** indicate UI to call Presence/Options API.   */
+    public static final int UCE_SERVICE_STATUS_ON = 1;
+    /** Indicate UI destroy Presence/Options   */
+    public static final int UCE_SERVICE_STATUS_CLOSED = 2;
+    /** Service up and trying to register for network events  */
+    public static final int UCE_SERVICE_STATUS_READY = 3;
 
     /**
      * Gets the instance of UCE Manager
diff --git a/core/java/com/android/internal/compat/CompatibilityChangeInfo.java b/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
index ab890d2..9ba0259 100644
--- a/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
+++ b/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
@@ -93,6 +93,43 @@
         dest.writeString(mDescription);
     }
 
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("CompatibilityChangeInfo(")
+                .append(getId());
+        if (getName() != null) {
+            sb.append("; name=").append(getName());
+        }
+        if (getEnableAfterTargetSdk() != -1) {
+            sb.append("; enableAfterTargetSdk=").append(getEnableAfterTargetSdk());
+        }
+        if (getDisabled()) {
+            sb.append("; disabled");
+        }
+        if (getLoggingOnly()) {
+            sb.append("; loggingOnly");
+        }
+        return sb.append(")").toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || !(o instanceof CompatibilityChangeInfo)) {
+            return false;
+        }
+        CompatibilityChangeInfo that = (CompatibilityChangeInfo) o;
+        return this.mChangeId == that.mChangeId
+                && this.mName.equals(that.mName)
+                && this.mEnableAfterTargetSdk == that.mEnableAfterTargetSdk
+                && this.mDisabled == that.mDisabled
+                && this.mLoggingOnly == that.mLoggingOnly
+                && this.mDescription.equals(that.mDescription);
+
+    }
+
     public static final Parcelable.Creator<CompatibilityChangeInfo> CREATOR =
             new Parcelable.Creator<CompatibilityChangeInfo>() {
 
diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl
index 523ed6f..6408def 100644
--- a/core/java/com/android/internal/compat/IPlatformCompat.aidl
+++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl
@@ -222,6 +222,14 @@
     CompatibilityChangeInfo[] listAllChanges();
 
     /**
+    * List the compatibility changes that should be present in the UI.
+    * Filters out certain changes like e.g. logging only.
+    *
+    * @return An array of {@link CompatChangeInfo}.
+    */
+    CompatibilityChangeInfo[] listUIChanges();
+
+    /**
      * Get an instance that can determine whether a changeid can be overridden for a package name.
      */
     IOverrideValidator getOverrideValidator();
diff --git a/core/java/com/android/internal/inputmethod/OWNERS b/core/java/com/android/internal/inputmethod/OWNERS
new file mode 100644
index 0000000..fc0e5d4
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/OWNERS
@@ -0,0 +1,3 @@
+set noparent
+
+include ../../../../../../services/core/java/com/android/server/inputmethod/OWNERS
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 5d50582..401933a 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -5421,7 +5421,7 @@
         if (mVideoOnNesting > 0) {
             final long elapsedRealtime = mClocks.elapsedRealtime();
             final long uptime = mClocks.uptimeMillis();
-            mAudioOnNesting = 0;
+            mVideoOnNesting = 0;
             mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
                     + Integer.toHexString(mHistoryCur.states));
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 300f71a..021f487 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -122,12 +122,6 @@
 
     private static boolean sPreloadComplete;
 
-    /**
-     * Cached classloader to use for the system server. Will only be populated in the system
-     * server process.
-     */
-    private static ClassLoader sCachedSystemServerClassLoader = null;
-
     static void preload(TimingsTraceLog bootTimingsTraceLog) {
         Log.d(TAG, "begin preload");
         bootTimingsTraceLog.traceBegin("BeginPreload");
@@ -499,13 +493,7 @@
 
         final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
         if (systemServerClasspath != null) {
-            if (performSystemServerDexOpt(systemServerClasspath)) {
-                // Throw away the cached classloader. If we compiled here, the classloader would
-                // not have had AoT-ed artifacts.
-                // Note: This only works in a very special environment where selinux enforcement is
-                // disabled, e.g., Mac builds.
-                sCachedSystemServerClassLoader = null;
-            }
+            performSystemServerDexOpt(systemServerClasspath);
             // Capturing profiles is only supported for debug or eng builds since selinux normally
             // prevents it.
             if (shouldProfileSystemServer() && (Build.IS_USERDEBUG || Build.IS_ENG)) {
@@ -537,9 +525,10 @@
 
             throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
         } else {
-            createSystemServerClassLoader();
-            ClassLoader cl = sCachedSystemServerClassLoader;
-            if (cl != null) {
+            ClassLoader cl = null;
+            if (systemServerClasspath != null) {
+                cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion);
+
                 Thread.currentThread().setContextClassLoader(cl);
             }
 
@@ -555,24 +544,6 @@
     }
 
     /**
-     * Create the classloader for the system server and store it in
-     * {@link sCachedSystemServerClassLoader}. This function may be called through JNI in
-     * system server startup, when the runtime is in a critically low state. Do not do
-     * extended computation etc here.
-     */
-    private static void createSystemServerClassLoader() {
-        if (sCachedSystemServerClassLoader != null) {
-            return;
-        }
-        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
-        // TODO: Should we run optimization here?
-        if (systemServerClasspath != null) {
-            sCachedSystemServerClassLoader = createPathClassLoader(systemServerClasspath,
-                    VMRuntime.SDK_VERSION_CUR_DEVELOPMENT);
-        }
-    }
-
-    /**
      * Note that preparing the profiles for system server does not require special selinux
      * permissions. From the installer perspective the system server is a regular package which can
      * capture profile information.
@@ -636,16 +607,15 @@
 
     /**
      * Performs dex-opt on the elements of {@code classPath}, if needed. We choose the instruction
-     * set of the current runtime. If something was compiled, return true.
+     * set of the current runtime.
      */
-    private static boolean performSystemServerDexOpt(String classPath) {
+    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 = "";
-        boolean compiledSomething = false;
         for (String classPathElement : classPathElements) {
             // We default to the verify filter because the compilation will happen on /data and
             // system server cannot load executable code outside /system.
@@ -686,7 +656,6 @@
                             uuid, classLoaderContext, seInfo, false /* downgrade */,
                             targetSdkVersion, /*profileName*/ null, /*dexMetadataPath*/ null,
                             "server-dexopt");
-                    compiledSomething = true;
                 } catch (RemoteException | ServiceSpecificException e) {
                     // Ignore (but log), we need this on the classpath for fallback mode.
                     Log.w(TAG, "Failed compiling classpath element for system server: "
@@ -697,8 +666,6 @@
             classPathForElement = encodeSystemServerClassPath(
                     classPathForElement, classPathElement);
         }
-
-        return compiledSomething;
     }
 
     /**
diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index d15f480..3d5dfbb 100644
--- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.telephony.BarringInfo;
 import android.telephony.CallAttributes;
 import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
@@ -66,4 +67,5 @@
     void onImsCallDisconnectCauseChanged(in ImsReasonInfo imsReasonInfo);
     void onRegistrationFailed(in CellIdentity cellIdentity,
              String chosenPlmn, int domain, int causeCode, int additionalCauseCode);
+    void onBarringInfoChanged(in BarringInfo barringInfo);
 }
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 3176f96..8667155 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -19,6 +19,7 @@
 import android.content.Intent;
 import android.net.LinkProperties;
 import android.net.NetworkCapabilities;
+import android.telephony.BarringInfo;
 import android.telephony.CallQuality;
 import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
@@ -102,4 +103,5 @@
     void notifyImsDisconnectCause(int subId, in ImsReasonInfo imsReasonInfo);
     void notifyRegistrationFailed(int slotIndex, int subId, in CellIdentity cellIdentity,
             String chosenPlmn, int domain, int causeCode, int additionalCauseCode);
+    void notifyBarringInfoChanged(int slotIndex, int subId, in BarringInfo barringInfo);
 }
diff --git a/core/jni/android_app_admin_SecurityLog.cpp b/core/jni/android_app_admin_SecurityLog.cpp
index b3bcaa0..e5a13db 100644
--- a/core/jni/android_app_admin_SecurityLog.cpp
+++ b/core/jni/android_app_admin_SecurityLog.cpp
@@ -41,7 +41,7 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, out);
+    SLog::readEvents(env, ANDROID_LOG_NONBLOCK, 0, out);
 }
 
 static void android_app_admin_SecurityLog_readEventsSince(JNIEnv* env, jobject /* clazz */,
@@ -52,7 +52,7 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, timestamp, out);
+    SLog::readEvents(env, ANDROID_LOG_NONBLOCK, timestamp, out);
 }
 
 static void android_app_admin_SecurityLog_readPreviousEvents(JNIEnv* env, jobject /* clazz */,
@@ -62,7 +62,7 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_PSTORE, 0, out);
+    SLog::readEvents(env, ANDROID_LOG_NONBLOCK | ANDROID_LOG_PSTORE, 0, out);
 }
 
 static void android_app_admin_SecurityLog_readEventsOnWrapping(JNIEnv* env, jobject /* clazz */,
@@ -72,8 +72,7 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    SLog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, timestamp,
-            out);
+    SLog::readEvents(env, ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, timestamp, out);
 }
 
 /*
diff --git a/core/jni/android_content_res_ApkAssets.cpp b/core/jni/android_content_res_ApkAssets.cpp
index bd4862d..d4369d4 100644
--- a/core/jni/android_content_res_ApkAssets.cpp
+++ b/core/jni/android_content_res_ApkAssets.cpp
@@ -78,12 +78,13 @@
     return 0;
   }
 
+  auto dup_fd_id = dup_fd.get();
   std::unique_ptr<const ApkAssets> apk_assets = ApkAssets::LoadFromFd(std::move(dup_fd),
                                                                       friendly_name_utf8.c_str(),
                                                                       system, force_shared_lib);
   if (apk_assets == nullptr) {
     std::string error_msg = base::StringPrintf("Failed to load asset path %s from fd %d",
-                                               friendly_name_utf8.c_str(), dup_fd.get());
+                                               friendly_name_utf8.c_str(), dup_fd_id);
     jniThrowException(env, "java/io/IOException", error_msg.c_str());
     return 0;
   }
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index 3b5a144..0a5e786 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -44,7 +44,7 @@
         return;
     }
 
-    ELog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, tags, 0, out);
+    ELog::readEvents(env, ANDROID_LOG_NONBLOCK, tags, 0, out);
  }
 /*
  * In class android.util.EventLog:
@@ -60,8 +60,7 @@
         jniThrowNullPointerException(env, NULL);
         return;
     }
-    ELog::readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, tags,
-            timestamp, out);
+    ELog::readEvents(env, ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, tags, timestamp, out);
 }
 
 /*
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 0ce61de..22f0478 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -113,15 +113,11 @@
 
 static pid_t gSystemServerPid = 0;
 
-static constexpr const char* kZygoteClassName = "com/android/internal/os/Zygote";
+static const char kZygoteClassName[] = "com/android/internal/os/Zygote";
 static jclass gZygoteClass;
 static jmethodID gCallPostForkSystemServerHooks;
 static jmethodID gCallPostForkChildHooks;
 
-static constexpr const char* kZygoteInitClassName = "com/android/internal/os/ZygoteInit";
-static jclass gZygoteInitClass;
-static jmethodID gCreateSystemServerClassLoader;
-
 static bool gIsSecurityEnforced = true;
 
 /**
@@ -1221,15 +1217,6 @@
       fail_fn("Error calling post fork system server hooks.");
     }
 
-    // Prefetch the classloader for the system server. This is done early to
-    // allow a tie-down of the proper system server selinux domain.
-    env->CallStaticVoidMethod(gZygoteInitClass, gCreateSystemServerClassLoader);
-    if (env->ExceptionCheck()) {
-      // Be robust here. The Java code will attempt to create the classloader
-      // at a later point (but may not have rights to use AoT artifacts).
-      env->ExceptionClear();
-    }
-
     // TODO(oth): Remove hardcoded label here (b/117874058).
     static const char* kSystemServerLabel = "u:r:system_server:s0";
     if (selinux_android_setcon(kSystemServerLabel) != 0) {
@@ -1908,13 +1895,6 @@
   gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkChildHooks",
                                                    "(IZZLjava/lang/String;)V");
 
-  gZygoteInitClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteInitClassName));
-  gCreateSystemServerClassLoader = GetStaticMethodIDOrDie(env, gZygoteInitClass,
-                                                          "createSystemServerClassLoader",
-                                                          "()V");
-
-  RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods));
-
-  return JNI_OK;
+  return RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods));
 }
 }  // namespace android
diff --git a/core/proto/android/stats/dnsresolver/dns_resolver.proto b/core/proto/android/stats/dnsresolver/dns_resolver.proto
index 15ef122..afd1099 100644
--- a/core/proto/android/stats/dnsresolver/dns_resolver.proto
+++ b/core/proto/android/stats/dnsresolver/dns_resolver.proto
@@ -43,6 +43,7 @@
     RC_EAI_BADHINTS = 12;
     RC_EAI_PROTOCOL = 13;
     RC_EAI_OVERFLOW = 14;
+    RC_RESOLV_INTERNAL_ERROR = 254;
     RC_RESOLV_TIMEOUT = 255;
     RC_EAI_MAX = 256;
 }
@@ -197,6 +198,144 @@
     CS_SKIP = 3;
 }
 
+// The enum LinuxErrno is defined in the following 2 files.
+// 1. bionic/libc/kernel/uapi/asm-generic/errno-base.h
+// 2. bionic/libc/kernel/uapi/asm-generic/errno.h
+enum LinuxErrno {
+    SYS_UNKNOWN = 0;
+    SYS_EPERM = 1;              // Not super-user
+    SYS_ENOENT = 2;             // No such file or directory
+    SYS_ESRCH = 3;              // No such process
+    SYS_EINTR = 4;              // Interrupted system call
+    SYS_EIO = 5;                // I/O error
+    SYS_ENXIO = 6;              // No such device or address
+    SYS_E2BIG = 7;              // Arg list too long
+    SYS_ENOEXEC = 8;            // Exec format error
+    SYS_EBADF = 9;              // Bad file number
+    SYS_ECHILD = 10;            // No children
+    SYS_EAGAIN = 11;            // No more processes
+    SYS_ENOMEM = 12;            // Not enough core
+    SYS_EACCES = 13;            // Permission denied
+    SYS_EFAULT = 14;            // Bad address
+    SYS_ENOTBLK = 15;           // Block device required
+    SYS_EBUSY = 16;             // Mount device busy
+    SYS_EEXIST = 17;            // File exists
+    SYS_EXDEV = 18;             // Cross-device link
+    SYS_ENODEV = 19;            // No such device
+    SYS_ENOTDIR = 20;           // Not a directory
+    SYS_EISDIR = 21;            // Is a directory
+    SYS_EINVAL = 22;            // Invalid argument
+    SYS_ENFILE = 23;            // Too many open files in system
+    SYS_EMFILE = 24;            // Too many open files
+    SYS_ENOTTY = 25;            // Not a typewriter
+    SYS_ETXTBSY = 26;           // Text file busy
+    SYS_EFBIG = 27;             // File too large
+    SYS_ENOSPC = 28;            // No space left on device
+    SYS_ESPIPE = 29;            // Illegal seek
+    SYS_EROFS = 30;             // Read only file system
+    SYS_EMLINK = 31;            // Too many links
+    SYS_EPIPE = 32;             // Broken pipe
+    SYS_EDOM = 33;              // Math arg out of domain of func
+    SYS_ERANGE = 34;            // Math result not representable
+    SYS_EDEADLOCK = 35;         // File locking deadlock error
+    SYS_ENAMETOOLONG = 36;      // File or path name too long
+    SYS_ENOLCK = 37;            // No record locks available
+    SYS_ENOSYS = 38;            // Function not implemented
+    SYS_ENOTEMPTY = 39;         // Directory not empty
+    SYS_ELOOP = 40;             // Too many symbolic links
+    SYS_ENOMSG = 42;            // No message of desired type
+    SYS_EIDRM = 43;             // Identifier removed
+    SYS_ECHRNG = 44;            // Channel number out of range
+    SYS_EL2NSYNC = 45;          // Level 2 not synchronized
+    SYS_EL3HLT = 46;            // Level 3 halted
+    SYS_EL3RST = 47;            // Level 3 reset
+    SYS_ELNRNG = 48;            // Link number out of range
+    SYS_EUNATCH = 49;           // rotocol driver not attached
+    SYS_ENOCSI = 50;            // No CSI structure available
+    SYS_EL2HLT = 51;            // Level 2 halted
+    SYS_EBADE = 52;             // Invalid exchange
+    SYS_EBADR = 53;             // Invalid request descriptor
+    SYS_EXFULL = 54;            // Exchange full
+    SYS_ENOANO = 55;            // No anode
+    SYS_EBADRQC = 56;           // Invalid request code
+    SYS_EBADSLT = 57;           // Invalid slot
+    SYS_EBFONT = 59;            // Bad font file fmt
+    SYS_ENOSTR = 60;            // Device not a stream
+    SYS_ENODATA = 61;           // No data (for no delay io)
+    SYS_ETIME = 62;             // Timer expired
+    SYS_ENOSR = 63;             // Out of streams resources
+    SYS_ENONET = 64;            // Machine is not on the network
+    SYS_ENOPKG = 65;            // Package not installed
+    SYS_EREMOTE = 66;           // The object is remote
+    SYS_ENOLINK = 67;           // The link has been severed
+    SYS_EADV = 68;              // Advertise error
+    SYS_ESRMNT = 69;            // Srmount error
+    SYS_ECOMM = 70;             // Communication error on send
+    SYS_EPROTO = 71;            // Protocol error
+    SYS_EMULTIHOP = 72;         // Multihop attempted
+    SYS_EDOTDOT = 73;           // Cross mount point (not really error)
+    SYS_EBADMSG = 74;           // Trying to read unreadable message
+    SYS_EOVERFLOW = 75;         // Value too large for defined data type
+    SYS_ENOTUNIQ = 76;          // Given log. name not unique
+    SYS_EBADFD = 77;            // f.d. invalid for this operation
+    SYS_EREMCHG = 78;           // Remote address changed
+    SYS_ELIBACC = 79;           // Can't access a needed shared lib
+    SYS_ELIBBAD = 80;           // Accessing a corrupted shared lib
+    SYS_ELIBSCN = 81;           // .lib section in a.out corrupted
+    SYS_ELIBMAX = 82;           // Attempting to link in too many libs
+    SYS_ELIBEXEC = 83;          // Attempting to exec a shared library
+    SYS_EILSEQ = 84;
+    SYS_ERESTART = 85;
+    SYS_ESTRPIPE = 86;
+    SYS_EUSERS = 87;
+    SYS_ENOTSOCK = 88;          // Socket operation on non-socket
+    SYS_EDESTADDRREQ = 89;      // Destination address required
+    SYS_EMSGSIZE = 90;          // Message too long
+    SYS_EPROTOTYPE = 91;        // Protocol wrong type for socket
+    SYS_ENOPROTOOPT = 92;       // Protocol not available
+    SYS_EPROTONOSUPPORT = 93;   // Unknown protocol
+    SYS_ESOCKTNOSUPPORT = 94;   // Socket type not supported
+    SYS_EOPNOTSUPP = 95;        // Operation not supported on transport endpoint
+    SYS_EPFNOSUPPORT = 96;      // Protocol family not supported
+    SYS_EAFNOSUPPORT = 97;      // Address family not supported by protocol family
+    SYS_EADDRINUSE = 98;        // Address already in use
+    SYS_EADDRNOTAVAIL = 99;     // Address not available
+    SYS_ENETDOWN = 100;         // Network interface is not configured
+    SYS_ENETUNREACH = 101;      // Network is unreachable
+    SYS_ENETRESET = 102;
+    SYS_ECONNABORTED = 103;     // Connection aborted
+    SYS_ECONNRESET = 104;       // Connection reset by peer
+    SYS_ENOBUFS = 105;          // No buffer space available
+    SYS_EISCONN = 106;          // Socket is already connected
+    SYS_ENOTCONN = 107;         // Socket is not connected
+    SYS_ESHUTDOWN = 108;        // Can't send after socket shutdown
+    SYS_ETOOMANYREFS = 109;
+    SYS_ETIMEDOUT = 110;        // Connection timed out
+    SYS_ECONNREFUSED = 111;     // Connection refused
+    SYS_EHOSTDOWN = 112;        // Host is down
+    SYS_EHOSTUNREACH = 113;     // Host is unreachable
+    SYS_EALREADY = 114;         // Socket already connected
+    SYS_EINPROGRESS = 115;      // Connection already in progress
+    SYS_ESTALE = 116;
+    SYS_EUCLEAN = 117;
+    SYS_ENOTNAM = 118;
+    SYS_ENAVAIL = 119;
+    SYS_EISNAM = 120;
+    SYS_EREMOTEIO = 121;
+    SYS_EDQUOT = 122;
+    SYS_ENOMEDIUM = 123;        // No medium (in tape drive)
+    SYS_EMEDIUMTYPE = 124;
+    SYS_ECANCELED = 125;
+    SYS_ENOKEY = 126;
+    SYS_EKEYEXPIRED = 127;
+    SYS_EKEYREVOKED = 128;
+    SYS_EKEYREJECTED = 129;
+    SYS_EOWNERDEAD = 130;
+    SYS_ENOTRECOVERABLE = 131;
+    SYS_ERFKILL = 132;
+    SYS_EHWPOISON = 133;
+}
+
 message DnsQueryEvent {
     optional android.stats.dnsresolver.NsRcode rcode = 1;
 
@@ -218,6 +357,8 @@
     optional bool connected = 8;
 
     optional int32 latency_micros = 9;
+
+    optional android.stats.dnsresolver.LinuxErrno linux_errno = 10;
 }
 
 message DnsQueryEvents {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9817ceb..e6dc15f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1645,6 +1645,10 @@
     <permission android:name="android.permission.NETWORK_FACTORY"
                 android:protectionLevel="signature" />
 
+    <!-- @SystemApi @hide Allows applications to access network stats provider -->
+    <permission android:name="android.permission.NETWORK_STATS_PROVIDER"
+                android:protectionLevel="signature" />
+
     <!-- Allows Settings and SystemUI to call methods in Networking services
          <p>Not for use by third-party or privileged applications.
          @SystemApi @TestApi
@@ -1794,7 +1798,7 @@
          and bypass OMAPI AccessControlEnforcer.
          <p>Not for use by third-party applications.
          @hide -->
-    <permission android:name="android.permission.SECURE_ELEMENT_PRIVILEGED"
+    <permission android:name="android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION"
         android:protectionLevel="signature|privileged" />
 
     <!-- @deprecated This permission used to allow too broad access to sensitive methods and all its
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d48c56c..4c6e1e3 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3049,6 +3049,10 @@
     <!-- Whether to use voip audio mode for ims call -->
     <bool name="config_use_voip_mode_for_ims">false</bool>
 
+    <!-- Boolean indicating USSD over IMS is allowed.
+     If it is not supported due to modem limitations, USSD send over the CS pipe instead.-->
+    <bool name="config_allow_ussd_over_ims">false</bool>
+
     <!-- String array containing numbers that shouldn't be logged. Country-specific. -->
     <string-array name="unloggable_phone_numbers" />
 
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 93080e9..8a7b515 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3010,8 +3010,6 @@
     </public-group>
 
     <public-group type="string" first-id="0x01040025">
-      <!-- @hide @SystemApi -->
-      <public name="low_memory" />
     </public-group>
 
     <public-group type="bool" first-id="0x01110005">
@@ -3026,14 +3024,7 @@
     <public-group type="array" first-id="0x01070006">
       <!-- @hide @SystemApi -->
       <public name="simColors" />
-      <!-- @hide @SystemApi -->
-      <public name="config_restrictedPreinstalledCarrierApps" />
-      <!-- @hide @SystemApi -->
-      <public name="config_sms_enabled_single_shift_tables" />
-      <!-- @hide @SystemApi -->
-      <public name="config_sms_enabled_locking_shift_tables" />
     </public-group>
-
   <!-- ===============================================================
        DO NOT ADD UN-GROUPED ITEMS HERE
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8810ac4..7f46380 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3450,8 +3450,6 @@
     <!-- A notification is shown when connected network without internet due to private dns validation failed. This is the notification's message. [CHAR LIMIT=NONE] -->
     <string name="private_dns_broken_detailed">Private DNS server cannot be accessed</string>
 
-    <!-- A notification is shown after the user logs in to a captive portal network, to indicate that the network should now have internet connectivity. This is the message of notification. [CHAR LIMIT=50] -->
-    <string name="captive_portal_logged_in_detailed">Connected</string>
     <!-- A notification is shown when the user connects to a network that doesn't have access to some services (e.g. Push notifications may not work). This is the notification's title. [CHAR LIMIT=50] -->
     <string name="network_partial_connectivity"><xliff:g id="network_ssid" example="GoogleGuest">%1$s</xliff:g> has limited connectivity</string>
 
@@ -5423,4 +5421,236 @@
     <!-- ChooserActivity - Alphabetically sorted apps list label. [CHAR LIMIT=NONE] -->
     <string name="chooser_all_apps_button_label">Apps list</string>
 
+    <!-- Icc depersonalization related strings -->
+    <!-- Label text for PIN entry widget on SIM Network Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY">SIM network unlock PIN</string>
+    <!-- Label text for PIN entry widget on SIM Network Subset Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ENTRY">SIM network subset unlock PIN</string>
+    <!-- Label text for PIN entry widget on SIM Corporate Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_ENTRY">SIM corporate unlock PIN</string>
+    <!-- Label text for PIN entry widget on SIM Service Provider Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ENTRY">SIM service provider unlock PIN</string>
+    <!-- Label text for PIN entry widget on SIM SIM Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SIM_ENTRY">SIM unlock PIN</string>
+    <!-- Label text for PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ENTRY">Enter PUK</string>
+    <!-- Label text for Subset PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ENTRY">Enter PUK</string>
+    <!-- Label text for Corporate PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_ENTRY">Enter PUK</string>
+    <!-- Label text for SIM service provider PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_ENTRY">Enter PUK</string>
+    <!-- Label text for SIM PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SIM_PUK_ENTRY">Enter PUK</string>
+    <!-- Label text for PIN entry widget on RUIM Network1 Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_ENTRY">RUIM network1 unlock PIN</string>
+    <!-- Label text for PIN entry widget on RUIM Network2 Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_ENTRY">RUIM network2 unlock PIN</string>
+    <!-- Label text for PIN entry widget on RUIM Hrpd Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_HRPD_ENTRY">RUIM hrpd unlock PIN</string>
+    <!-- Label text for PIN entry widget on RUIM Corporate Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_ENTRY">RUIM corporate unlock PIN</string>
+    <!-- Label text for PIN entry widget on RUIM Service Provider Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ENTRY">RUIM service provider unlock PIN</string>
+    <!-- Label text for PIN entry widget on RUIM RUIM Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_RUIM_ENTRY">RUIM unlock PIN</string>
+    <!-- Label text for PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ENTRY">Enter PUK</string>
+    <!-- Label text for PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ENTRY">Enter PUK</string>
+    <!-- Label text for PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ENTRY">Enter PUK</string>
+    <!-- Label text for PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ENTRY">Enter PUK</string>
+    <!-- Label text for PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ENTRY">Enter PUK</string>
+    <!-- Label text for PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ENTRY">Enter PUK</string>
+
+    <!-- Label text for PIN entry widget on SIM SPN Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SPN_ENTRY">SPN unlock PIN</string>
+    <!-- Label text for PIN entry widget on SIM SP EHPLMN Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ENTRY">SP Equivalent Home PLMN unlock PIN</string>
+    <!-- Label text for PIN entry widget on SIM ICCID Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_ICCID_ENTRY">ICCID unlock PIN</string>
+    <!-- Label text for PIN entry widget on SIM IMPI Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_IMPI_ENTRY">IMPI unlock PIN</string>
+    <!-- Label text for PIN entry widget on SIM NS_SP Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NS_SP_ENTRY">Network subset service provider unlock PIN</string>
+
+    <!-- Status message displayed on SIM Network Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_IN_PROGRESS">Requesting SIM network unlock\u2026</string>
+    <!-- Status message displayed on SIM Network Subset Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_IN_PROGRESS">Requesting SIM network subset unlock
+\u2026</string>
+    <!-- Status message displayed on SIM Service Provider Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_IN_PROGRESS">Requesting SIM service provider un
+lock\u2026</string>
+    <!-- Status message displayed on SIM Corporate Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_IN_PROGRESS">Requesting SIM corporate unlock\u2026</string>
+    <!-- Status message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+    <!-- Status message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+    <!-- Status message displayed on Corporate PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+    <!-- Status message displayed on SIM Service provider PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+    <!-- Status message displayed on SIM PUK entry widget on Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SIM_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+    <!-- Status message displayed on SIM SIM Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SIM_IN_PROGRESS">Requesting SIM unlock\u2026</string>
+    <!-- Status message displayed on RUIM Network1 Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_IN_PROGRESS">Requesting RUIM network1 unlock\u2026</string>
+    <!-- Status message displayed on RUIM Network2 Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_IN_PROGRESS">Requesting RUIM network2 unlock\u2026</string>
+    <!-- Status message displayed on RUIM Hrpd Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_HRPD_IN_PROGRESS">Requesting RUIM hrpd unlock\u2026</string>
+    <!-- Status message displayed on RUIM Service Provider Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_IN_PROGRESS">Requesting RUIM service provider
+unlock\u2026</string>
+    <!-- Status message displayed on RUIM Corporate Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_IN_PROGRESS">Requesting RUIM corporate unlock\u2026</string>
+
+    <!-- Status message displayed on SIM SPN Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SPN_IN_PROGRESS">Requesting SPN unlock\u2026</string>
+    <!-- Status message displayed on SIM SP EHPLMN Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_IN_PROGRESS">Requesting SP Equivalent Home PLMN unlock\u2026</string>
+    <!-- Status message displayed on SIM ICCID Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_ICCID_IN_PROGRESS">Requesting ICCID unlock\u2026</string>
+    <!-- Status message displayed on SIM IMPI Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_IMPI_IN_PROGRESS">Requesting IMPI unlock\u2026</string>
+    <!-- Status message displayed on SIM NS_SP Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NS_SP_IN_PROGRESS">Requesting Network subset service provider unlock\u2026</string>
+
+    <!-- Status message displayed on RUIM RUIM Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_RUIM_IN_PROGRESS">Requesting RUIM unlock\u2026</string>
+    <!-- Status message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+    <!-- Status message displayed on PUK Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+    <!-- Status message displayed on PUK Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+    <!-- Status message displayed on PUK Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+    <!-- Status message displayed on PUK Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+    <!-- Status message displayed on PUK Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_IN_PROGRESS">Requesting PUK unlock\u2026</string>
+    <!-- Error message displayed on SIM Network Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_ERROR">SIM Network unlock request unsuccessful.</string>
+    <!-- Error message displayed on SIM Network Subset Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_ERROR">SIM Network Subset unlock request unsucces
+sful.</string>
+    <!-- Error message displayed on SIM Service Provider Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_ERROR">SIM Service Provider unlock request unsu
+ccessful.</string>
+    <!-- Error message displayed on SIM Corporate Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_ERROR">SIM Corporate unlock request unsuccessful.</string>
+    <!-- Error message displayed on SIM SIM Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SIM_ERROR">SIM unlock request unsuccessful.</string>
+    <!-- Error message displayed on RUIM Network1 Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_ERROR">RUIM Network1 unlock request unsuccessful.</string>
+    <!-- Error message displayed on RUIM Network2 Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_ERROR">RUIM Network2 unlock request unsuccessful.</string>
+    <!-- Error message displayed on RUIM Hrpd Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_HRPD_ERROR">RUIM Hrpd unlock request unsuccessful.</string>
+    <!-- Error message displayed on RUIM Corporate Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_ERROR">RUIM Corporate unlock request unsuccessful.</string>
+    <!-- Error message displayed on RUIM Service Provider Depersonalization panel  [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_ERROR">RUIM Service Provider unlock request un
+successful.</string>
+    <!-- Error message displayed on RUIM RUIM Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_RUIM_ERROR">RUIM unlock request unsuccessful.</string>
+    <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_ERROR">PUK unlock unsuccessful.</string>
+    <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_ERROR">PUK unlock unsuccessful.</string>
+    <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_ERROR">PUK unlock unsuccessful.</string>
+    <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_ERROR">PUK unlock unsuccessful.</string>
+    <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SIM_PUK_ERROR">PUK unlock unsuccessful.</string>
+    <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_ERROR">PUK unlock unsuccessful.</string>
+    <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_ERROR">PUK unlock unsuccessful.</string>
+    <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_ERROR">PUK unlock unsuccessful.</string>
+    <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_ERROR">PUK unlock unsuccessful.</string>
+    <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_ERROR">PUK unlock unsuccessful.</string>
+    <!-- Error message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_ERROR">PUK unlock unsuccessful.</string>
+
+    <!--  Error message displayed on SIM SPN Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SPN_ERROR">SPN unlock request unsuccessful.</string>
+    <!--  Error message displayed on SIM SP EHPLMN Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_ERROR">SP Equivalent Home PLMN unlock request unsuccessful.</string>
+    <!--  Error message displayed on SIM ICCID Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_ICCID_ERROR">ICCID unlock request unsuccessful.</string>
+    <!--  Error message displayed on SIM IMPI Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_IMPI_ERROR">IMPI unlock request unsuccessful.</string>
+    <!--  Error message displayed on SIM NS_SP Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NS_SP_ERROR">Network subset service provider unlock request unsuccessful.</string>
+
+    <!-- Success message displayed on SIM Network Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUCCESS">SIM Network unlock successful.</string>
+    <!-- Success message displayed on SIM Network Subset Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_SUCCESS">SIM Network Subset unlock successful.</string>
+    <!-- Success message displayed on SIM Service Provider Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_SUCCESS">SIM Service Provider unlock successful
+.</string>
+    <!-- Success message displayed on SIM Corporate Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_SUCCESS">SIM Corporate unlock successful.</string>
+    <!-- Success message displayed on SIM SIM Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SIM_SUCCESS">SIM unlock successful.</string>
+    <!-- Success message displayed on RUIM Network1 Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_SUCCESS">RUIM Network1 unlock successful.</string>
+    <!-- Success message displayed on RUIM Network2 Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_SUCCESS">RUIM Network2 unlock successful.</string>
+    <!-- Success message displayed on RUIM Hrpd Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_HRPD_SUCCESS">RUIM Hrpd unlock successful.</string>
+    <!-- Success message displayed on RUIM Service Provider Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_SUCCESS">RUIM Service Provider unlock successf
+ul.</string>
+    <!-- Success message displayed on RUIM Corporate Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_SUCCESS">RUIM Corporate unlock successful.</string>
+    <!-- Success message displayed on RUIM RUIM Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_RUIM_SUCCESS">RUIM unlock successful.</string>
+    <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_PUK_SUCCESS">PUK unlock successful.</string>
+    <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK_SUCCESS">PUK unlock successful.</string>
+    <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_CORPORATE_PUK_SUCCESS">PUK unlock successful.</string>
+    <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK_SUCCESS">PUK unlock successful.</string>
+    <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SIM_PUK_SUCCESS">PUK unlock successful.</string>
+    <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK1_PUK_SUCCESS">PUK unlock successful.</string>
+    <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_NETWORK2_PUK_SUCCESS">PUK unlock successful.</string>
+    <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_HRPD_PUK_SUCCESS">PUK unlock successful.</string>
+    <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_CORPORATE_PUK_SUCCESS">PUK unlock successful.</string>
+    <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK_SUCCESS">PUK unlock successful.</string>
+    <!-- Success message displayed on PUK Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_RUIM_RUIM_PUK_SUCCESS">PUK unlock successful.</string>
+
+    <!-- Success message displayed on SIM SPN Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SPN_SUCCESS">SPN unlock successful.</string>
+    <!-- Success message displayed on SIM SP EHPLMN Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_SP_EHPLMN_SUCCESS">SP Equivalent Home PLMN unlock successful.</string>
+    <!-- Success message displayed on SIM ICCID Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_ICCID_SUCCESS">ICCID unlock successful.</string>
+    <!-- Success message displayed on SIM IMPI Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_IMPI_SUCCESS">IMPI unlock successful.</string>
+    <!-- Success message displayed on SIM NS_SP Depersonalization panel [CHAR LIMIT=none] -->
+    <string name="PERSOSUBSTATE_SIM_NS_SP_SUCCESS">Network subset service provider unlock successful.</string>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 0768856..7102f6c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -735,7 +735,6 @@
   <java-symbol type="string" name="capability_title_canControlMagnification" />
   <java-symbol type="string" name="capability_desc_canPerformGestures" />
   <java-symbol type="string" name="capability_title_canPerformGestures" />
-  <java-symbol type="string" name="captive_portal_logged_in_detailed" />
   <java-symbol type="string" name="cfTemplateForwarded" />
   <java-symbol type="string" name="cfTemplateForwardedTime" />
   <java-symbol type="string" name="cfTemplateNotForwarded" />
@@ -2635,6 +2634,7 @@
   <java-symbol type="bool" name="config_device_wfc_ims_available" />
   <java-symbol type="bool" name="config_carrier_wfc_ims_available" />
   <java-symbol type="bool" name="config_use_voip_mode_for_ims" />
+  <java-symbol type="bool" name="config_allow_ussd_over_ims" />
   <java-symbol type="attr" name="touchscreenBlocksFocus" />
   <java-symbol type="layout" name="resolver_list_with_default" />
   <java-symbol type="string" name="activity_resolver_set_always" />
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
index 5d42915..4b42f4ae 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
@@ -268,7 +268,7 @@
         File snd_stat = new File (root_filepath + "tcp_snd");
         int tx = BandwidthTestUtil.parseIntValueFromFile(snd_stat);
         NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
-        stats.addEntry(NetworkStats.IFACE_ALL, uid, NetworkStats.SET_DEFAULT,
+        stats.insertEntry(NetworkStats.IFACE_ALL, uid, NetworkStats.SET_DEFAULT,
                 NetworkStats.TAG_NONE, rx, 0, tx, 0, 0);
         return stats;
     }
diff --git a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
index 239f971..3ebe103 100644
--- a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
+++ b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
@@ -54,7 +54,7 @@
             recycle.txBytes = 150000;
             recycle.txPackets = 1500;
             recycle.operations = 0;
-            mNetworkStats.addEntry(recycle);
+            mNetworkStats.insertEntry(recycle);
             if (recycle.set == 1) {
                 uid++;
             }
@@ -70,7 +70,7 @@
             recycle.txBytes = 180000 * mSize;
             recycle.txPackets = 1200 * mSize;
             recycle.operations = 0;
-            mNetworkStats.addEntry(recycle);
+            mNetworkStats.insertEntry(recycle);
         }
     }
 
diff --git a/core/tests/coretests/src/android/app/timezonedetector/TelephonyTimeZoneSuggestionTest.java b/core/tests/coretests/src/android/app/timezonedetector/TelephonyTimeZoneSuggestionTest.java
index c4ff9be..28009d4 100644
--- a/core/tests/coretests/src/android/app/timezonedetector/TelephonyTimeZoneSuggestionTest.java
+++ b/core/tests/coretests/src/android/app/timezonedetector/TelephonyTimeZoneSuggestionTest.java
@@ -129,7 +129,7 @@
     }
 
     @Test(expected = RuntimeException.class)
-    public void testBuilderValidates_emptyZone_badMatchType() {
+    public void testBuilderValidates_nullZone_badMatchType() {
         TelephonyTimeZoneSuggestion.Builder builder =
                 new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX);
         // No zone ID, so match type should be left unset.
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 7d752cd..802b106 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -346,6 +346,7 @@
                     Settings.Global.NETSTATS_POLL_INTERVAL,
                     Settings.Global.NETSTATS_SAMPLE_ENABLED,
                     Settings.Global.NETSTATS_AUGMENT_ENABLED,
+                    Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED,
                     Settings.Global.NETSTATS_TIME_CACHE_MAX_AGE,
                     Settings.Global.NETSTATS_UID_BUCKET_DURATION,
                     Settings.Global.NETSTATS_UID_DELETE_AGE,
diff --git a/data/etc/framework-sysconfig.xml b/data/etc/framework-sysconfig.xml
index b0d2de1..ad001da 100644
--- a/data/etc/framework-sysconfig.xml
+++ b/data/etc/framework-sysconfig.xml
@@ -19,11 +19,29 @@
 
     <!-- Broadcast actions that are currently exempted from O+ background
          delivery restrictions. -->
-    <allow-implicit-broadcast action="android.intent.action.SIM_STATE_CHANGED" />
-    <allow-implicit-broadcast action="android.intent.action.PACKAGE_CHANGED" />
+    <allow-implicit-broadcast action="android.intent.action.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED" />
+    <allow-implicit-broadcast action="android.intent.action.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED" />
+    <allow-implicit-broadcast action="android.intent.action.DATA_SMS_RECEIVED" />
     <allow-implicit-broadcast action="android.intent.action.MEDIA_SCANNER_SCAN_FILE" />
-    <allow-implicit-broadcast action="android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION" />
+    <allow-implicit-broadcast action="android.intent.action.PACKAGE_CHANGED" />
+    <allow-implicit-broadcast action="android.intent.action.SIM_STATE_CHANGED" />
     <allow-implicit-broadcast action="android.media.action.CLOSE_AUDIO_EFFECT_CONTROL_SESSION" />
+    <allow-implicit-broadcast action="android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION" />
+    <allow-implicit-broadcast action="android.provider.Telephony.SECRET_CODE" />
+    <allow-implicit-broadcast action="android.provider.Telephony.SMS_CB_RECEIVED" />
+    <allow-implicit-broadcast action="android.provider.Telephony.SMS_DELIVER" />
+    <allow-implicit-broadcast action="android.provider.Telephony.SMS_RECEIVED" />
+    <allow-implicit-broadcast action="android.provider.Telephony.SMS_REJECTED" />
+    <allow-implicit-broadcast action="android.provider.Telephony.WAP_PUSH_DELIVER" />
+    <allow-implicit-broadcast action="android.provider.Telephony.WAP_PUSH_RECEIVED" />
+    <allow-implicit-broadcast action="android.telephony.action.CARRIER_CONFIG_CHANGED" />
+    <allow-implicit-broadcast action="android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED" />
+    <allow-implicit-broadcast action="android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED" />
+    <allow-implicit-broadcast action="android.telephony.action.SECRET_CODE" />
+    <allow-implicit-broadcast action="android.telephony.action.SIM_APPLICATION_STATE_CHANGED" />
+    <allow-implicit-broadcast action="android.telephony.action.SIM_CARD_STATE_CHANGED" />
+    <allow-implicit-broadcast action="android.telephony.action.SIM_SLOT_STATUS_CHANGED" />
+
 
     <!-- Whitelist of what components are permitted as backup data transports.  The
          'service' attribute here is a flattened ComponentName string. -->
diff --git a/data/etc/hiddenapi-package-whitelist.xml b/data/etc/hiddenapi-package-whitelist.xml
index d282744..e9de02e 100644
--- a/data/etc/hiddenapi-package-whitelist.xml
+++ b/data/etc/hiddenapi-package-whitelist.xml
@@ -57,7 +57,6 @@
   <hidden-api-whitelisted-app package="com.android.terminal" />
   <hidden-api-whitelisted-app package="com.android.wallpaper" />
   <hidden-api-whitelisted-app package="jp.co.omronsoft.openwnn" />
-  <!-- STOPSHIP: Remove this when fixing all @hide usage for tethering.-->
-  <hidden-api-whitelisted-app package="com.android.networkstack.tethering" />
+  <!-- TODO: Remove NetworkStack whitelisting -->
   <hidden-api-whitelisted-app package="com.android.networkstack" />
 </config>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index e007023..a1c8e13 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -39,11 +39,6 @@
         <permission name="android.permission.CRYPT_KEEPER"/>
     </privapp-permissions>
 
-    <privapp-permissions package="com.android.captiveportallogin">
-        <permission name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/>
-        <permission name="android.permission.NETWORK_BYPASS_PRIVATE_DNS"/>
-    </privapp-permissions>
-
     <privapp-permissions package="com.android.cellbroadcastreceiver">
         <permission name="android.permission.INTERACT_ACROSS_USERS"/>
         <permission name="android.permission.MANAGE_USERS"/>
@@ -238,6 +233,7 @@
     </privapp-permissions>
 
     <privapp-permissions package="com.android.networkstack.tethering">
+        <permission name="android.permission.BLUETOOTH_PRIVILEGED" />
         <permission name="android.permission.MANAGE_USB"/>
         <permission name="android.permission.MODIFY_PHONE_STATE"/>
         <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
@@ -332,6 +328,7 @@
         <permission name="android.permission.SUSPEND_APPS" />
         <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
         <permission name="android.permission.USE_RESERVED_DISK"/>
+        <permission name="android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE"/>
         <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
         <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
         <permission name="android.permission.STATUS_BAR_SERVICE"/>
@@ -358,6 +355,8 @@
         <!-- Permission required to test lights control APIs. -->
         <permission name="android.permission.CONTROL_DEVICE_LIGHTS" />
         <permission name="android.permission.REBOOT"/>
+        <!-- Permission required for testing system audio effect APIs. -->
+        <permission name="android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS"/>
     </privapp-permissions>
 
     <privapp-permissions package="com.android.statementservice">
diff --git a/keystore/tests/OWNERS b/keystore/tests/OWNERS
index 9e65f88..86c31f4 100644
--- a/keystore/tests/OWNERS
+++ b/keystore/tests/OWNERS
@@ -1,5 +1,4 @@
 # Android Enterprise security team
 eranm@google.com
-irinaid@google.com
 pgrafov@google.com
 rubinxu@google.com
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 237c1e9..09705e1 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -70,8 +70,11 @@
     LOG(ERROR) << "failed to load IDMAP " << idmap_path;
     return {};
   }
-  return LoadImpl({} /*fd*/, loaded_idmap->OverlayApkPath(), std::move(idmap_asset),
-                  std::move(loaded_idmap), system, false /*load_as_shared_library*/);
+  auto apkPath = loaded_idmap->OverlayApkPath();
+  return LoadImpl({} /*fd*/, apkPath,
+                  std::move(idmap_asset),
+                  std::move(loaded_idmap),
+                  system, false /*load_as_shared_library*/);
 }
 
 std::unique_ptr<const ApkAssets> ApkAssets::LoadFromFd(unique_fd fd,
diff --git a/libs/androidfw/LocaleDataTables.cpp b/libs/androidfw/LocaleDataTables.cpp
index e748bd8..6c6c5c9 100644
--- a/libs/androidfw/LocaleDataTables.cpp
+++ b/libs/androidfw/LocaleDataTables.cpp
@@ -15,1474 +15,1478 @@
     /* 11 */ {'C', 'a', 'r', 'i'},
     /* 12 */ {'C', 'h', 'a', 'm'},
     /* 13 */ {'C', 'h', 'e', 'r'},
-    /* 14 */ {'C', 'o', 'p', 't'},
-    /* 15 */ {'C', 'p', 'r', 't'},
-    /* 16 */ {'C', 'y', 'r', 'l'},
-    /* 17 */ {'D', 'e', 'v', 'a'},
-    /* 18 */ {'E', 'g', 'y', 'p'},
-    /* 19 */ {'E', 't', 'h', 'i'},
-    /* 20 */ {'G', 'e', 'o', 'r'},
-    /* 21 */ {'G', 'o', 'n', 'g'},
-    /* 22 */ {'G', 'o', 'n', 'm'},
-    /* 23 */ {'G', 'o', 't', 'h'},
-    /* 24 */ {'G', 'r', 'e', 'k'},
-    /* 25 */ {'G', 'u', 'j', 'r'},
-    /* 26 */ {'G', 'u', 'r', 'u'},
-    /* 27 */ {'H', 'a', 'n', 's'},
-    /* 28 */ {'H', 'a', 'n', 't'},
-    /* 29 */ {'H', 'a', 't', 'r'},
-    /* 30 */ {'H', 'e', 'b', 'r'},
-    /* 31 */ {'H', 'l', 'u', 'w'},
-    /* 32 */ {'H', 'm', 'n', 'g'},
-    /* 33 */ {'H', 'm', 'n', 'p'},
-    /* 34 */ {'I', 't', 'a', 'l'},
-    /* 35 */ {'J', 'p', 'a', 'n'},
-    /* 36 */ {'K', 'a', 'l', 'i'},
-    /* 37 */ {'K', 'a', 'n', 'a'},
-    /* 38 */ {'K', 'h', 'a', 'r'},
-    /* 39 */ {'K', 'h', 'm', 'r'},
-    /* 40 */ {'K', 'n', 'd', 'a'},
-    /* 41 */ {'K', 'o', 'r', 'e'},
-    /* 42 */ {'L', 'a', 'n', 'a'},
-    /* 43 */ {'L', 'a', 'o', 'o'},
-    /* 44 */ {'L', 'a', 't', 'n'},
-    /* 45 */ {'L', 'e', 'p', 'c'},
-    /* 46 */ {'L', 'i', 'n', 'a'},
-    /* 47 */ {'L', 'i', 's', 'u'},
-    /* 48 */ {'L', 'y', 'c', 'i'},
-    /* 49 */ {'L', 'y', 'd', 'i'},
-    /* 50 */ {'M', 'a', 'n', 'd'},
-    /* 51 */ {'M', 'a', 'n', 'i'},
-    /* 52 */ {'M', 'e', 'r', 'c'},
-    /* 53 */ {'M', 'l', 'y', 'm'},
-    /* 54 */ {'M', 'o', 'n', 'g'},
-    /* 55 */ {'M', 'r', 'o', 'o'},
-    /* 56 */ {'M', 'y', 'm', 'r'},
-    /* 57 */ {'N', 'a', 'r', 'b'},
-    /* 58 */ {'N', 'k', 'o', 'o'},
-    /* 59 */ {'N', 's', 'h', 'u'},
-    /* 60 */ {'O', 'g', 'a', 'm'},
-    /* 61 */ {'O', 'r', 'k', 'h'},
-    /* 62 */ {'O', 'r', 'y', 'a'},
-    /* 63 */ {'O', 's', 'g', 'e'},
-    /* 64 */ {'P', 'a', 'u', 'c'},
-    /* 65 */ {'P', 'h', 'l', 'i'},
-    /* 66 */ {'P', 'h', 'n', 'x'},
-    /* 67 */ {'P', 'l', 'r', 'd'},
-    /* 68 */ {'P', 'r', 't', 'i'},
-    /* 69 */ {'R', 'u', 'n', 'r'},
-    /* 70 */ {'S', 'a', 'm', 'r'},
-    /* 71 */ {'S', 'a', 'r', 'b'},
-    /* 72 */ {'S', 'a', 'u', 'r'},
-    /* 73 */ {'S', 'g', 'n', 'w'},
-    /* 74 */ {'S', 'i', 'n', 'h'},
-    /* 75 */ {'S', 'o', 'g', 'd'},
-    /* 76 */ {'S', 'o', 'r', 'a'},
-    /* 77 */ {'S', 'o', 'y', 'o'},
-    /* 78 */ {'S', 'y', 'r', 'c'},
-    /* 79 */ {'T', 'a', 'l', 'e'},
-    /* 80 */ {'T', 'a', 'l', 'u'},
-    /* 81 */ {'T', 'a', 'm', 'l'},
-    /* 82 */ {'T', 'a', 'n', 'g'},
-    /* 83 */ {'T', 'a', 'v', 't'},
-    /* 84 */ {'T', 'e', 'l', 'u'},
-    /* 85 */ {'T', 'f', 'n', 'g'},
-    /* 86 */ {'T', 'h', 'a', 'a'},
-    /* 87 */ {'T', 'h', 'a', 'i'},
-    /* 88 */ {'T', 'i', 'b', 't'},
-    /* 89 */ {'U', 'g', 'a', 'r'},
-    /* 90 */ {'V', 'a', 'i', 'i'},
-    /* 91 */ {'W', 'c', 'h', 'o'},
-    /* 92 */ {'X', 'p', 'e', 'o'},
-    /* 93 */ {'X', 's', 'u', 'x'},
-    /* 94 */ {'Y', 'i', 'i', 'i'},
-    /* 95 */ {'~', '~', '~', 'A'},
-    /* 96 */ {'~', '~', '~', 'B'},
+    /* 14 */ {'C', 'h', 'r', 's'},
+    /* 15 */ {'C', 'o', 'p', 't'},
+    /* 16 */ {'C', 'p', 'r', 't'},
+    /* 17 */ {'C', 'y', 'r', 'l'},
+    /* 18 */ {'D', 'e', 'v', 'a'},
+    /* 19 */ {'E', 'g', 'y', 'p'},
+    /* 20 */ {'E', 't', 'h', 'i'},
+    /* 21 */ {'G', 'e', 'o', 'r'},
+    /* 22 */ {'G', 'o', 'n', 'g'},
+    /* 23 */ {'G', 'o', 'n', 'm'},
+    /* 24 */ {'G', 'o', 't', 'h'},
+    /* 25 */ {'G', 'r', 'e', 'k'},
+    /* 26 */ {'G', 'u', 'j', 'r'},
+    /* 27 */ {'G', 'u', 'r', 'u'},
+    /* 28 */ {'H', 'a', 'n', 's'},
+    /* 29 */ {'H', 'a', 'n', 't'},
+    /* 30 */ {'H', 'a', 't', 'r'},
+    /* 31 */ {'H', 'e', 'b', 'r'},
+    /* 32 */ {'H', 'l', 'u', 'w'},
+    /* 33 */ {'H', 'm', 'n', 'g'},
+    /* 34 */ {'H', 'm', 'n', 'p'},
+    /* 35 */ {'I', 't', 'a', 'l'},
+    /* 36 */ {'J', 'p', 'a', 'n'},
+    /* 37 */ {'K', 'a', 'l', 'i'},
+    /* 38 */ {'K', 'a', 'n', 'a'},
+    /* 39 */ {'K', 'h', 'a', 'r'},
+    /* 40 */ {'K', 'h', 'm', 'r'},
+    /* 41 */ {'K', 'i', 't', 's'},
+    /* 42 */ {'K', 'n', 'd', 'a'},
+    /* 43 */ {'K', 'o', 'r', 'e'},
+    /* 44 */ {'L', 'a', 'n', 'a'},
+    /* 45 */ {'L', 'a', 'o', 'o'},
+    /* 46 */ {'L', 'a', 't', 'n'},
+    /* 47 */ {'L', 'e', 'p', 'c'},
+    /* 48 */ {'L', 'i', 'n', 'a'},
+    /* 49 */ {'L', 'i', 's', 'u'},
+    /* 50 */ {'L', 'y', 'c', 'i'},
+    /* 51 */ {'L', 'y', 'd', 'i'},
+    /* 52 */ {'M', 'a', 'n', 'd'},
+    /* 53 */ {'M', 'a', 'n', 'i'},
+    /* 54 */ {'M', 'e', 'r', 'c'},
+    /* 55 */ {'M', 'l', 'y', 'm'},
+    /* 56 */ {'M', 'o', 'n', 'g'},
+    /* 57 */ {'M', 'r', 'o', 'o'},
+    /* 58 */ {'M', 'y', 'm', 'r'},
+    /* 59 */ {'N', 'a', 'r', 'b'},
+    /* 60 */ {'N', 'k', 'o', 'o'},
+    /* 61 */ {'N', 's', 'h', 'u'},
+    /* 62 */ {'O', 'g', 'a', 'm'},
+    /* 63 */ {'O', 'r', 'k', 'h'},
+    /* 64 */ {'O', 'r', 'y', 'a'},
+    /* 65 */ {'O', 's', 'g', 'e'},
+    /* 66 */ {'P', 'a', 'u', 'c'},
+    /* 67 */ {'P', 'h', 'l', 'i'},
+    /* 68 */ {'P', 'h', 'n', 'x'},
+    /* 69 */ {'P', 'l', 'r', 'd'},
+    /* 70 */ {'P', 'r', 't', 'i'},
+    /* 71 */ {'R', 'u', 'n', 'r'},
+    /* 72 */ {'S', 'a', 'm', 'r'},
+    /* 73 */ {'S', 'a', 'r', 'b'},
+    /* 74 */ {'S', 'a', 'u', 'r'},
+    /* 75 */ {'S', 'g', 'n', 'w'},
+    /* 76 */ {'S', 'i', 'n', 'h'},
+    /* 77 */ {'S', 'o', 'g', 'd'},
+    /* 78 */ {'S', 'o', 'r', 'a'},
+    /* 79 */ {'S', 'o', 'y', 'o'},
+    /* 80 */ {'S', 'y', 'r', 'c'},
+    /* 81 */ {'T', 'a', 'l', 'e'},
+    /* 82 */ {'T', 'a', 'l', 'u'},
+    /* 83 */ {'T', 'a', 'm', 'l'},
+    /* 84 */ {'T', 'a', 'n', 'g'},
+    /* 85 */ {'T', 'a', 'v', 't'},
+    /* 86 */ {'T', 'e', 'l', 'u'},
+    /* 87 */ {'T', 'f', 'n', 'g'},
+    /* 88 */ {'T', 'h', 'a', 'a'},
+    /* 89 */ {'T', 'h', 'a', 'i'},
+    /* 90 */ {'T', 'i', 'b', 't'},
+    /* 91 */ {'U', 'g', 'a', 'r'},
+    /* 92 */ {'V', 'a', 'i', 'i'},
+    /* 93 */ {'W', 'c', 'h', 'o'},
+    /* 94 */ {'X', 'p', 'e', 'o'},
+    /* 95 */ {'X', 's', 'u', 'x'},
+    /* 96 */ {'Y', 'i', 'i', 'i'},
+    /* 97 */ {'~', '~', '~', 'A'},
+    /* 98 */ {'~', '~', '~', 'B'},
 };
 
 
 const std::unordered_map<uint32_t, uint8_t> LIKELY_SCRIPTS({
-    {0x61610000u, 44u}, // aa -> Latn
-    {0xA0000000u, 44u}, // aai -> Latn
-    {0xA8000000u, 44u}, // aak -> Latn
-    {0xD0000000u, 44u}, // aau -> Latn
-    {0x61620000u, 16u}, // ab -> Cyrl
-    {0xA0200000u, 44u}, // abi -> Latn
-    {0xC0200000u, 16u}, // abq -> Cyrl
-    {0xC4200000u, 44u}, // abr -> Latn
-    {0xCC200000u, 44u}, // abt -> Latn
-    {0xE0200000u, 44u}, // aby -> Latn
-    {0x8C400000u, 44u}, // acd -> Latn
-    {0x90400000u, 44u}, // ace -> Latn
-    {0x9C400000u, 44u}, // ach -> Latn
-    {0x80600000u, 44u}, // ada -> Latn
-    {0x90600000u, 44u}, // ade -> Latn
-    {0xA4600000u, 44u}, // adj -> Latn
-    {0xBC600000u, 88u}, // adp -> Tibt
-    {0xE0600000u, 16u}, // ady -> Cyrl
-    {0xE4600000u, 44u}, // adz -> Latn
+    {0x61610000u, 46u}, // aa -> Latn
+    {0xA0000000u, 46u}, // aai -> Latn
+    {0xA8000000u, 46u}, // aak -> Latn
+    {0xD0000000u, 46u}, // aau -> Latn
+    {0x61620000u, 17u}, // ab -> Cyrl
+    {0xA0200000u, 46u}, // abi -> Latn
+    {0xC0200000u, 17u}, // abq -> Cyrl
+    {0xC4200000u, 46u}, // abr -> Latn
+    {0xCC200000u, 46u}, // abt -> Latn
+    {0xE0200000u, 46u}, // aby -> Latn
+    {0x8C400000u, 46u}, // acd -> Latn
+    {0x90400000u, 46u}, // ace -> Latn
+    {0x9C400000u, 46u}, // ach -> Latn
+    {0x80600000u, 46u}, // ada -> Latn
+    {0x90600000u, 46u}, // ade -> Latn
+    {0xA4600000u, 46u}, // adj -> Latn
+    {0xBC600000u, 90u}, // adp -> Tibt
+    {0xE0600000u, 17u}, // ady -> Cyrl
+    {0xE4600000u, 46u}, // adz -> Latn
     {0x61650000u,  4u}, // ae -> Avst
     {0x84800000u,  1u}, // aeb -> Arab
-    {0xE0800000u, 44u}, // aey -> Latn
-    {0x61660000u, 44u}, // af -> Latn
-    {0x88C00000u, 44u}, // agc -> Latn
-    {0x8CC00000u, 44u}, // agd -> Latn
-    {0x98C00000u, 44u}, // agg -> Latn
-    {0xB0C00000u, 44u}, // agm -> Latn
-    {0xB8C00000u, 44u}, // ago -> Latn
-    {0xC0C00000u, 44u}, // agq -> Latn
-    {0x80E00000u, 44u}, // aha -> Latn
-    {0xACE00000u, 44u}, // ahl -> Latn
+    {0xE0800000u, 46u}, // aey -> Latn
+    {0x61660000u, 46u}, // af -> Latn
+    {0x88C00000u, 46u}, // agc -> Latn
+    {0x8CC00000u, 46u}, // agd -> Latn
+    {0x98C00000u, 46u}, // agg -> Latn
+    {0xB0C00000u, 46u}, // agm -> Latn
+    {0xB8C00000u, 46u}, // ago -> Latn
+    {0xC0C00000u, 46u}, // agq -> Latn
+    {0x80E00000u, 46u}, // aha -> Latn
+    {0xACE00000u, 46u}, // ahl -> Latn
     {0xB8E00000u,  0u}, // aho -> Ahom
-    {0x99200000u, 44u}, // ajg -> Latn
-    {0x616B0000u, 44u}, // ak -> Latn
-    {0xA9400000u, 93u}, // akk -> Xsux
-    {0x81600000u, 44u}, // ala -> Latn
-    {0xA1600000u, 44u}, // ali -> Latn
-    {0xB5600000u, 44u}, // aln -> Latn
-    {0xCD600000u, 16u}, // alt -> Cyrl
-    {0x616D0000u, 19u}, // am -> Ethi
-    {0xB1800000u, 44u}, // amm -> Latn
-    {0xB5800000u, 44u}, // amn -> Latn
-    {0xB9800000u, 44u}, // amo -> Latn
-    {0xBD800000u, 44u}, // amp -> Latn
-    {0x616E0000u, 44u}, // an -> Latn
-    {0x89A00000u, 44u}, // anc -> Latn
-    {0xA9A00000u, 44u}, // ank -> Latn
-    {0xB5A00000u, 44u}, // ann -> Latn
-    {0xE1A00000u, 44u}, // any -> Latn
-    {0xA5C00000u, 44u}, // aoj -> Latn
-    {0xB1C00000u, 44u}, // aom -> Latn
-    {0xE5C00000u, 44u}, // aoz -> Latn
+    {0x99200000u, 46u}, // ajg -> Latn
+    {0x616B0000u, 46u}, // ak -> Latn
+    {0xA9400000u, 95u}, // akk -> Xsux
+    {0x81600000u, 46u}, // ala -> Latn
+    {0xA1600000u, 46u}, // ali -> Latn
+    {0xB5600000u, 46u}, // aln -> Latn
+    {0xCD600000u, 17u}, // alt -> Cyrl
+    {0x616D0000u, 20u}, // am -> Ethi
+    {0xB1800000u, 46u}, // amm -> Latn
+    {0xB5800000u, 46u}, // amn -> Latn
+    {0xB9800000u, 46u}, // amo -> Latn
+    {0xBD800000u, 46u}, // amp -> Latn
+    {0x616E0000u, 46u}, // an -> Latn
+    {0x89A00000u, 46u}, // anc -> Latn
+    {0xA9A00000u, 46u}, // ank -> Latn
+    {0xB5A00000u, 46u}, // ann -> Latn
+    {0xE1A00000u, 46u}, // any -> Latn
+    {0xA5C00000u, 46u}, // aoj -> Latn
+    {0xB1C00000u, 46u}, // aom -> Latn
+    {0xE5C00000u, 46u}, // aoz -> Latn
     {0x89E00000u,  1u}, // apc -> Arab
     {0x8DE00000u,  1u}, // apd -> Arab
-    {0x91E00000u, 44u}, // ape -> Latn
-    {0xC5E00000u, 44u}, // apr -> Latn
-    {0xC9E00000u, 44u}, // aps -> Latn
-    {0xE5E00000u, 44u}, // apz -> Latn
+    {0x91E00000u, 46u}, // ape -> Latn
+    {0xC5E00000u, 46u}, // apr -> Latn
+    {0xC9E00000u, 46u}, // aps -> Latn
+    {0xE5E00000u, 46u}, // apz -> Latn
     {0x61720000u,  1u}, // ar -> Arab
-    {0x61725842u, 96u}, // ar-XB -> ~~~B
+    {0x61725842u, 98u}, // ar-XB -> ~~~B
     {0x8A200000u,  2u}, // arc -> Armi
-    {0x9E200000u, 44u}, // arh -> Latn
-    {0xB6200000u, 44u}, // arn -> Latn
-    {0xBA200000u, 44u}, // aro -> Latn
+    {0x9E200000u, 46u}, // arh -> Latn
+    {0xB6200000u, 46u}, // arn -> Latn
+    {0xBA200000u, 46u}, // aro -> Latn
     {0xC2200000u,  1u}, // arq -> Arab
     {0xCA200000u,  1u}, // ars -> Arab
     {0xE2200000u,  1u}, // ary -> Arab
     {0xE6200000u,  1u}, // arz -> Arab
     {0x61730000u,  7u}, // as -> Beng
-    {0x82400000u, 44u}, // asa -> Latn
-    {0x92400000u, 73u}, // ase -> Sgnw
-    {0x9A400000u, 44u}, // asg -> Latn
-    {0xBA400000u, 44u}, // aso -> Latn
-    {0xCE400000u, 44u}, // ast -> Latn
-    {0x82600000u, 44u}, // ata -> Latn
-    {0x9A600000u, 44u}, // atg -> Latn
-    {0xA6600000u, 44u}, // atj -> Latn
-    {0xE2800000u, 44u}, // auy -> Latn
-    {0x61760000u, 16u}, // av -> Cyrl
+    {0x82400000u, 46u}, // asa -> Latn
+    {0x92400000u, 75u}, // ase -> Sgnw
+    {0x9A400000u, 46u}, // asg -> Latn
+    {0xBA400000u, 46u}, // aso -> Latn
+    {0xCE400000u, 46u}, // ast -> Latn
+    {0x82600000u, 46u}, // ata -> Latn
+    {0x9A600000u, 46u}, // atg -> Latn
+    {0xA6600000u, 46u}, // atj -> Latn
+    {0xE2800000u, 46u}, // auy -> Latn
+    {0x61760000u, 17u}, // av -> Cyrl
     {0xAEA00000u,  1u}, // avl -> Arab
-    {0xB6A00000u, 44u}, // avn -> Latn
-    {0xCEA00000u, 44u}, // avt -> Latn
-    {0xD2A00000u, 44u}, // avu -> Latn
-    {0x82C00000u, 17u}, // awa -> Deva
-    {0x86C00000u, 44u}, // awb -> Latn
-    {0xBAC00000u, 44u}, // awo -> Latn
-    {0xDEC00000u, 44u}, // awx -> Latn
-    {0x61790000u, 44u}, // ay -> Latn
-    {0x87000000u, 44u}, // ayb -> Latn
-    {0x617A0000u, 44u}, // az -> Latn
+    {0xB6A00000u, 46u}, // avn -> Latn
+    {0xCEA00000u, 46u}, // avt -> Latn
+    {0xD2A00000u, 46u}, // avu -> Latn
+    {0x82C00000u, 18u}, // awa -> Deva
+    {0x86C00000u, 46u}, // awb -> Latn
+    {0xBAC00000u, 46u}, // awo -> Latn
+    {0xDEC00000u, 46u}, // awx -> Latn
+    {0x61790000u, 46u}, // ay -> Latn
+    {0x87000000u, 46u}, // ayb -> Latn
+    {0x617A0000u, 46u}, // az -> Latn
     {0x617A4951u,  1u}, // az-IQ -> Arab
     {0x617A4952u,  1u}, // az-IR -> Arab
-    {0x617A5255u, 16u}, // az-RU -> Cyrl
-    {0x62610000u, 16u}, // ba -> Cyrl
+    {0x617A5255u, 17u}, // az-RU -> Cyrl
+    {0x62610000u, 17u}, // ba -> Cyrl
     {0xAC010000u,  1u}, // bal -> Arab
-    {0xB4010000u, 44u}, // ban -> Latn
-    {0xBC010000u, 17u}, // bap -> Deva
-    {0xC4010000u, 44u}, // bar -> Latn
-    {0xC8010000u, 44u}, // bas -> Latn
-    {0xD4010000u, 44u}, // bav -> Latn
+    {0xB4010000u, 46u}, // ban -> Latn
+    {0xBC010000u, 18u}, // bap -> Deva
+    {0xC4010000u, 46u}, // bar -> Latn
+    {0xC8010000u, 46u}, // bas -> Latn
+    {0xD4010000u, 46u}, // bav -> Latn
     {0xDC010000u,  5u}, // bax -> Bamu
-    {0x80210000u, 44u}, // bba -> Latn
-    {0x84210000u, 44u}, // bbb -> Latn
-    {0x88210000u, 44u}, // bbc -> Latn
-    {0x8C210000u, 44u}, // bbd -> Latn
-    {0xA4210000u, 44u}, // bbj -> Latn
-    {0xBC210000u, 44u}, // bbp -> Latn
-    {0xC4210000u, 44u}, // bbr -> Latn
-    {0x94410000u, 44u}, // bcf -> Latn
-    {0x9C410000u, 44u}, // bch -> Latn
-    {0xA0410000u, 44u}, // bci -> Latn
-    {0xB0410000u, 44u}, // bcm -> Latn
-    {0xB4410000u, 44u}, // bcn -> Latn
-    {0xB8410000u, 44u}, // bco -> Latn
-    {0xC0410000u, 19u}, // bcq -> Ethi
-    {0xD0410000u, 44u}, // bcu -> Latn
-    {0x8C610000u, 44u}, // bdd -> Latn
-    {0x62650000u, 16u}, // be -> Cyrl
-    {0x94810000u, 44u}, // bef -> Latn
-    {0x9C810000u, 44u}, // beh -> Latn
+    {0x80210000u, 46u}, // bba -> Latn
+    {0x84210000u, 46u}, // bbb -> Latn
+    {0x88210000u, 46u}, // bbc -> Latn
+    {0x8C210000u, 46u}, // bbd -> Latn
+    {0xA4210000u, 46u}, // bbj -> Latn
+    {0xBC210000u, 46u}, // bbp -> Latn
+    {0xC4210000u, 46u}, // bbr -> Latn
+    {0x94410000u, 46u}, // bcf -> Latn
+    {0x9C410000u, 46u}, // bch -> Latn
+    {0xA0410000u, 46u}, // bci -> Latn
+    {0xB0410000u, 46u}, // bcm -> Latn
+    {0xB4410000u, 46u}, // bcn -> Latn
+    {0xB8410000u, 46u}, // bco -> Latn
+    {0xC0410000u, 20u}, // bcq -> Ethi
+    {0xD0410000u, 46u}, // bcu -> Latn
+    {0x8C610000u, 46u}, // bdd -> Latn
+    {0x62650000u, 17u}, // be -> Cyrl
+    {0x94810000u, 46u}, // bef -> Latn
+    {0x9C810000u, 46u}, // beh -> Latn
     {0xA4810000u,  1u}, // bej -> Arab
-    {0xB0810000u, 44u}, // bem -> Latn
-    {0xCC810000u, 44u}, // bet -> Latn
-    {0xD8810000u, 44u}, // bew -> Latn
-    {0xDC810000u, 44u}, // bex -> Latn
-    {0xE4810000u, 44u}, // bez -> Latn
-    {0x8CA10000u, 44u}, // bfd -> Latn
-    {0xC0A10000u, 81u}, // bfq -> Taml
+    {0xB0810000u, 46u}, // bem -> Latn
+    {0xCC810000u, 46u}, // bet -> Latn
+    {0xD8810000u, 46u}, // bew -> Latn
+    {0xDC810000u, 46u}, // bex -> Latn
+    {0xE4810000u, 46u}, // bez -> Latn
+    {0x8CA10000u, 46u}, // bfd -> Latn
+    {0xC0A10000u, 83u}, // bfq -> Taml
     {0xCCA10000u,  1u}, // bft -> Arab
-    {0xE0A10000u, 17u}, // bfy -> Deva
-    {0x62670000u, 16u}, // bg -> Cyrl
-    {0x88C10000u, 17u}, // bgc -> Deva
+    {0xE0A10000u, 18u}, // bfy -> Deva
+    {0x62670000u, 17u}, // bg -> Cyrl
+    {0x88C10000u, 18u}, // bgc -> Deva
     {0xB4C10000u,  1u}, // bgn -> Arab
-    {0xDCC10000u, 24u}, // bgx -> Grek
-    {0x84E10000u, 17u}, // bhb -> Deva
-    {0x98E10000u, 44u}, // bhg -> Latn
-    {0xA0E10000u, 17u}, // bhi -> Deva
-    {0xACE10000u, 44u}, // bhl -> Latn
-    {0xB8E10000u, 17u}, // bho -> Deva
-    {0xE0E10000u, 44u}, // bhy -> Latn
-    {0x62690000u, 44u}, // bi -> Latn
-    {0x85010000u, 44u}, // bib -> Latn
-    {0x99010000u, 44u}, // big -> Latn
-    {0xA9010000u, 44u}, // bik -> Latn
-    {0xB1010000u, 44u}, // bim -> Latn
-    {0xB5010000u, 44u}, // bin -> Latn
-    {0xB9010000u, 44u}, // bio -> Latn
-    {0xC1010000u, 44u}, // biq -> Latn
-    {0x9D210000u, 44u}, // bjh -> Latn
-    {0xA1210000u, 19u}, // bji -> Ethi
-    {0xA5210000u, 17u}, // bjj -> Deva
-    {0xB5210000u, 44u}, // bjn -> Latn
-    {0xB9210000u, 44u}, // bjo -> Latn
-    {0xC5210000u, 44u}, // bjr -> Latn
-    {0xCD210000u, 44u}, // bjt -> Latn
-    {0xE5210000u, 44u}, // bjz -> Latn
-    {0x89410000u, 44u}, // bkc -> Latn
-    {0xB1410000u, 44u}, // bkm -> Latn
-    {0xC1410000u, 44u}, // bkq -> Latn
-    {0xD1410000u, 44u}, // bku -> Latn
-    {0xD5410000u, 44u}, // bkv -> Latn
-    {0xCD610000u, 83u}, // blt -> Tavt
-    {0x626D0000u, 44u}, // bm -> Latn
-    {0x9D810000u, 44u}, // bmh -> Latn
-    {0xA9810000u, 44u}, // bmk -> Latn
-    {0xC1810000u, 44u}, // bmq -> Latn
-    {0xD1810000u, 44u}, // bmu -> Latn
+    {0xDCC10000u, 25u}, // bgx -> Grek
+    {0x84E10000u, 18u}, // bhb -> Deva
+    {0x98E10000u, 46u}, // bhg -> Latn
+    {0xA0E10000u, 18u}, // bhi -> Deva
+    {0xACE10000u, 46u}, // bhl -> Latn
+    {0xB8E10000u, 18u}, // bho -> Deva
+    {0xE0E10000u, 46u}, // bhy -> Latn
+    {0x62690000u, 46u}, // bi -> Latn
+    {0x85010000u, 46u}, // bib -> Latn
+    {0x99010000u, 46u}, // big -> Latn
+    {0xA9010000u, 46u}, // bik -> Latn
+    {0xB1010000u, 46u}, // bim -> Latn
+    {0xB5010000u, 46u}, // bin -> Latn
+    {0xB9010000u, 46u}, // bio -> Latn
+    {0xC1010000u, 46u}, // biq -> Latn
+    {0x9D210000u, 46u}, // bjh -> Latn
+    {0xA1210000u, 20u}, // bji -> Ethi
+    {0xA5210000u, 18u}, // bjj -> Deva
+    {0xB5210000u, 46u}, // bjn -> Latn
+    {0xB9210000u, 46u}, // bjo -> Latn
+    {0xC5210000u, 46u}, // bjr -> Latn
+    {0xCD210000u, 46u}, // bjt -> Latn
+    {0xE5210000u, 46u}, // bjz -> Latn
+    {0x89410000u, 46u}, // bkc -> Latn
+    {0xB1410000u, 46u}, // bkm -> Latn
+    {0xC1410000u, 46u}, // bkq -> Latn
+    {0xD1410000u, 46u}, // bku -> Latn
+    {0xD5410000u, 46u}, // bkv -> Latn
+    {0xCD610000u, 85u}, // blt -> Tavt
+    {0x626D0000u, 46u}, // bm -> Latn
+    {0x9D810000u, 46u}, // bmh -> Latn
+    {0xA9810000u, 46u}, // bmk -> Latn
+    {0xC1810000u, 46u}, // bmq -> Latn
+    {0xD1810000u, 46u}, // bmu -> Latn
     {0x626E0000u,  7u}, // bn -> Beng
-    {0x99A10000u, 44u}, // bng -> Latn
-    {0xB1A10000u, 44u}, // bnm -> Latn
-    {0xBDA10000u, 44u}, // bnp -> Latn
-    {0x626F0000u, 88u}, // bo -> Tibt
-    {0xA5C10000u, 44u}, // boj -> Latn
-    {0xB1C10000u, 44u}, // bom -> Latn
-    {0xB5C10000u, 44u}, // bon -> Latn
+    {0x99A10000u, 46u}, // bng -> Latn
+    {0xB1A10000u, 46u}, // bnm -> Latn
+    {0xBDA10000u, 46u}, // bnp -> Latn
+    {0x626F0000u, 90u}, // bo -> Tibt
+    {0xA5C10000u, 46u}, // boj -> Latn
+    {0xB1C10000u, 46u}, // bom -> Latn
+    {0xB5C10000u, 46u}, // bon -> Latn
     {0xE1E10000u,  7u}, // bpy -> Beng
-    {0x8A010000u, 44u}, // bqc -> Latn
+    {0x8A010000u, 46u}, // bqc -> Latn
     {0xA2010000u,  1u}, // bqi -> Arab
-    {0xBE010000u, 44u}, // bqp -> Latn
-    {0xD6010000u, 44u}, // bqv -> Latn
-    {0x62720000u, 44u}, // br -> Latn
-    {0x82210000u, 17u}, // bra -> Deva
+    {0xBE010000u, 46u}, // bqp -> Latn
+    {0xD6010000u, 46u}, // bqv -> Latn
+    {0x62720000u, 46u}, // br -> Latn
+    {0x82210000u, 18u}, // bra -> Deva
     {0x9E210000u,  1u}, // brh -> Arab
-    {0xDE210000u, 17u}, // brx -> Deva
-    {0xE6210000u, 44u}, // brz -> Latn
-    {0x62730000u, 44u}, // bs -> Latn
-    {0xA6410000u, 44u}, // bsj -> Latn
+    {0xDE210000u, 18u}, // brx -> Deva
+    {0xE6210000u, 46u}, // brz -> Latn
+    {0x62730000u, 46u}, // bs -> Latn
+    {0xA6410000u, 46u}, // bsj -> Latn
     {0xC2410000u,  6u}, // bsq -> Bass
-    {0xCA410000u, 44u}, // bss -> Latn
-    {0xCE410000u, 19u}, // bst -> Ethi
-    {0xBA610000u, 44u}, // bto -> Latn
-    {0xCE610000u, 44u}, // btt -> Latn
-    {0xD6610000u, 17u}, // btv -> Deva
-    {0x82810000u, 16u}, // bua -> Cyrl
-    {0x8A810000u, 44u}, // buc -> Latn
-    {0x8E810000u, 44u}, // bud -> Latn
-    {0x9A810000u, 44u}, // bug -> Latn
-    {0xAA810000u, 44u}, // buk -> Latn
-    {0xB2810000u, 44u}, // bum -> Latn
-    {0xBA810000u, 44u}, // buo -> Latn
-    {0xCA810000u, 44u}, // bus -> Latn
-    {0xD2810000u, 44u}, // buu -> Latn
-    {0x86A10000u, 44u}, // bvb -> Latn
-    {0x8EC10000u, 44u}, // bwd -> Latn
-    {0xC6C10000u, 44u}, // bwr -> Latn
-    {0x9EE10000u, 44u}, // bxh -> Latn
-    {0x93010000u, 44u}, // bye -> Latn
-    {0xB7010000u, 19u}, // byn -> Ethi
-    {0xC7010000u, 44u}, // byr -> Latn
-    {0xCB010000u, 44u}, // bys -> Latn
-    {0xD7010000u, 44u}, // byv -> Latn
-    {0xDF010000u, 44u}, // byx -> Latn
-    {0x83210000u, 44u}, // bza -> Latn
-    {0x93210000u, 44u}, // bze -> Latn
-    {0x97210000u, 44u}, // bzf -> Latn
-    {0x9F210000u, 44u}, // bzh -> Latn
-    {0xDB210000u, 44u}, // bzw -> Latn
-    {0x63610000u, 44u}, // ca -> Latn
-    {0xB4020000u, 44u}, // can -> Latn
-    {0xA4220000u, 44u}, // cbj -> Latn
-    {0x9C420000u, 44u}, // cch -> Latn
+    {0xCA410000u, 46u}, // bss -> Latn
+    {0xCE410000u, 20u}, // bst -> Ethi
+    {0xBA610000u, 46u}, // bto -> Latn
+    {0xCE610000u, 46u}, // btt -> Latn
+    {0xD6610000u, 18u}, // btv -> Deva
+    {0x82810000u, 17u}, // bua -> Cyrl
+    {0x8A810000u, 46u}, // buc -> Latn
+    {0x8E810000u, 46u}, // bud -> Latn
+    {0x9A810000u, 46u}, // bug -> Latn
+    {0xAA810000u, 46u}, // buk -> Latn
+    {0xB2810000u, 46u}, // bum -> Latn
+    {0xBA810000u, 46u}, // buo -> Latn
+    {0xCA810000u, 46u}, // bus -> Latn
+    {0xD2810000u, 46u}, // buu -> Latn
+    {0x86A10000u, 46u}, // bvb -> Latn
+    {0x8EC10000u, 46u}, // bwd -> Latn
+    {0xC6C10000u, 46u}, // bwr -> Latn
+    {0x9EE10000u, 46u}, // bxh -> Latn
+    {0x93010000u, 46u}, // bye -> Latn
+    {0xB7010000u, 20u}, // byn -> Ethi
+    {0xC7010000u, 46u}, // byr -> Latn
+    {0xCB010000u, 46u}, // bys -> Latn
+    {0xD7010000u, 46u}, // byv -> Latn
+    {0xDF010000u, 46u}, // byx -> Latn
+    {0x83210000u, 46u}, // bza -> Latn
+    {0x93210000u, 46u}, // bze -> Latn
+    {0x97210000u, 46u}, // bzf -> Latn
+    {0x9F210000u, 46u}, // bzh -> Latn
+    {0xDB210000u, 46u}, // bzw -> Latn
+    {0x63610000u, 46u}, // ca -> Latn
+    {0xB4020000u, 46u}, // can -> Latn
+    {0xA4220000u, 46u}, // cbj -> Latn
+    {0x9C420000u, 46u}, // cch -> Latn
     {0xBC420000u,  9u}, // ccp -> Cakm
-    {0x63650000u, 16u}, // ce -> Cyrl
-    {0x84820000u, 44u}, // ceb -> Latn
-    {0x80A20000u, 44u}, // cfa -> Latn
-    {0x98C20000u, 44u}, // cgg -> Latn
-    {0x63680000u, 44u}, // ch -> Latn
-    {0xA8E20000u, 44u}, // chk -> Latn
-    {0xB0E20000u, 16u}, // chm -> Cyrl
-    {0xB8E20000u, 44u}, // cho -> Latn
-    {0xBCE20000u, 44u}, // chp -> Latn
+    {0x63650000u, 17u}, // ce -> Cyrl
+    {0x84820000u, 46u}, // ceb -> Latn
+    {0x80A20000u, 46u}, // cfa -> Latn
+    {0x98C20000u, 46u}, // cgg -> Latn
+    {0x63680000u, 46u}, // ch -> Latn
+    {0xA8E20000u, 46u}, // chk -> Latn
+    {0xB0E20000u, 17u}, // chm -> Cyrl
+    {0xB8E20000u, 46u}, // cho -> Latn
+    {0xBCE20000u, 46u}, // chp -> Latn
     {0xC4E20000u, 13u}, // chr -> Cher
-    {0x89020000u, 44u}, // cic -> Latn
+    {0x89020000u, 46u}, // cic -> Latn
     {0x81220000u,  1u}, // cja -> Arab
     {0xB1220000u, 12u}, // cjm -> Cham
-    {0xD5220000u, 44u}, // cjv -> Latn
+    {0xD5220000u, 46u}, // cjv -> Latn
     {0x85420000u,  1u}, // ckb -> Arab
-    {0xAD420000u, 44u}, // ckl -> Latn
-    {0xB9420000u, 44u}, // cko -> Latn
-    {0xE1420000u, 44u}, // cky -> Latn
-    {0x81620000u, 44u}, // cla -> Latn
-    {0x91820000u, 44u}, // cme -> Latn
-    {0x99820000u, 77u}, // cmg -> Soyo
-    {0x636F0000u, 44u}, // co -> Latn
-    {0xBDC20000u, 14u}, // cop -> Copt
-    {0xC9E20000u, 44u}, // cps -> Latn
+    {0xAD420000u, 46u}, // ckl -> Latn
+    {0xB9420000u, 46u}, // cko -> Latn
+    {0xE1420000u, 46u}, // cky -> Latn
+    {0x81620000u, 46u}, // cla -> Latn
+    {0x91820000u, 46u}, // cme -> Latn
+    {0x99820000u, 79u}, // cmg -> Soyo
+    {0x636F0000u, 46u}, // co -> Latn
+    {0xBDC20000u, 15u}, // cop -> Copt
+    {0xC9E20000u, 46u}, // cps -> Latn
     {0x63720000u, 10u}, // cr -> Cans
-    {0x9E220000u, 16u}, // crh -> Cyrl
+    {0x9E220000u, 17u}, // crh -> Cyrl
     {0xA6220000u, 10u}, // crj -> Cans
     {0xAA220000u, 10u}, // crk -> Cans
     {0xAE220000u, 10u}, // crl -> Cans
     {0xB2220000u, 10u}, // crm -> Cans
-    {0xCA220000u, 44u}, // crs -> Latn
-    {0x63730000u, 44u}, // cs -> Latn
-    {0x86420000u, 44u}, // csb -> Latn
+    {0xCA220000u, 46u}, // crs -> Latn
+    {0x63730000u, 46u}, // cs -> Latn
+    {0x86420000u, 46u}, // csb -> Latn
     {0xDA420000u, 10u}, // csw -> Cans
-    {0x8E620000u, 64u}, // ctd -> Pauc
-    {0x63750000u, 16u}, // cu -> Cyrl
-    {0x63760000u, 16u}, // cv -> Cyrl
-    {0x63790000u, 44u}, // cy -> Latn
-    {0x64610000u, 44u}, // da -> Latn
-    {0x8C030000u, 44u}, // dad -> Latn
-    {0x94030000u, 44u}, // daf -> Latn
-    {0x98030000u, 44u}, // dag -> Latn
-    {0x9C030000u, 44u}, // dah -> Latn
-    {0xA8030000u, 44u}, // dak -> Latn
-    {0xC4030000u, 16u}, // dar -> Cyrl
-    {0xD4030000u, 44u}, // dav -> Latn
-    {0x8C230000u, 44u}, // dbd -> Latn
-    {0xC0230000u, 44u}, // dbq -> Latn
+    {0x8E620000u, 66u}, // ctd -> Pauc
+    {0x63750000u, 17u}, // cu -> Cyrl
+    {0x63760000u, 17u}, // cv -> Cyrl
+    {0x63790000u, 46u}, // cy -> Latn
+    {0x64610000u, 46u}, // da -> Latn
+    {0x8C030000u, 46u}, // dad -> Latn
+    {0x94030000u, 46u}, // daf -> Latn
+    {0x98030000u, 46u}, // dag -> Latn
+    {0x9C030000u, 46u}, // dah -> Latn
+    {0xA8030000u, 46u}, // dak -> Latn
+    {0xC4030000u, 17u}, // dar -> Cyrl
+    {0xD4030000u, 46u}, // dav -> Latn
+    {0x8C230000u, 46u}, // dbd -> Latn
+    {0xC0230000u, 46u}, // dbq -> Latn
     {0x88430000u,  1u}, // dcc -> Arab
-    {0xB4630000u, 44u}, // ddn -> Latn
-    {0x64650000u, 44u}, // de -> Latn
-    {0x8C830000u, 44u}, // ded -> Latn
-    {0xB4830000u, 44u}, // den -> Latn
-    {0x80C30000u, 44u}, // dga -> Latn
-    {0x9CC30000u, 44u}, // dgh -> Latn
-    {0xA0C30000u, 44u}, // dgi -> Latn
+    {0xB4630000u, 46u}, // ddn -> Latn
+    {0x64650000u, 46u}, // de -> Latn
+    {0x8C830000u, 46u}, // ded -> Latn
+    {0xB4830000u, 46u}, // den -> Latn
+    {0x80C30000u, 46u}, // dga -> Latn
+    {0x9CC30000u, 46u}, // dgh -> Latn
+    {0xA0C30000u, 46u}, // dgi -> Latn
     {0xACC30000u,  1u}, // dgl -> Arab
-    {0xC4C30000u, 44u}, // dgr -> Latn
-    {0xE4C30000u, 44u}, // dgz -> Latn
-    {0x81030000u, 44u}, // dia -> Latn
-    {0x91230000u, 44u}, // dje -> Latn
-    {0xA5A30000u, 44u}, // dnj -> Latn
-    {0x85C30000u, 44u}, // dob -> Latn
+    {0xC4C30000u, 46u}, // dgr -> Latn
+    {0xE4C30000u, 46u}, // dgz -> Latn
+    {0x81030000u, 46u}, // dia -> Latn
+    {0x91230000u, 46u}, // dje -> Latn
+    {0xA5A30000u, 46u}, // dnj -> Latn
+    {0x85C30000u, 46u}, // dob -> Latn
     {0xA1C30000u,  1u}, // doi -> Arab
-    {0xBDC30000u, 44u}, // dop -> Latn
-    {0xD9C30000u, 44u}, // dow -> Latn
-    {0x9E230000u, 54u}, // drh -> Mong
-    {0xA2230000u, 44u}, // dri -> Latn
-    {0xCA230000u, 19u}, // drs -> Ethi
-    {0x86430000u, 44u}, // dsb -> Latn
-    {0xB2630000u, 44u}, // dtm -> Latn
-    {0xBE630000u, 44u}, // dtp -> Latn
-    {0xCA630000u, 44u}, // dts -> Latn
-    {0xE2630000u, 17u}, // dty -> Deva
-    {0x82830000u, 44u}, // dua -> Latn
-    {0x8A830000u, 44u}, // duc -> Latn
-    {0x8E830000u, 44u}, // dud -> Latn
-    {0x9A830000u, 44u}, // dug -> Latn
-    {0x64760000u, 86u}, // dv -> Thaa
-    {0x82A30000u, 44u}, // dva -> Latn
-    {0xDAC30000u, 44u}, // dww -> Latn
-    {0xBB030000u, 44u}, // dyo -> Latn
-    {0xD3030000u, 44u}, // dyu -> Latn
-    {0x647A0000u, 88u}, // dz -> Tibt
-    {0x9B230000u, 44u}, // dzg -> Latn
-    {0xD0240000u, 44u}, // ebu -> Latn
-    {0x65650000u, 44u}, // ee -> Latn
-    {0xA0A40000u, 44u}, // efi -> Latn
-    {0xACC40000u, 44u}, // egl -> Latn
-    {0xE0C40000u, 18u}, // egy -> Egyp
-    {0x81440000u, 44u}, // eka -> Latn
-    {0xE1440000u, 36u}, // eky -> Kali
-    {0x656C0000u, 24u}, // el -> Grek
-    {0x81840000u, 44u}, // ema -> Latn
-    {0xA1840000u, 44u}, // emi -> Latn
-    {0x656E0000u, 44u}, // en -> Latn
-    {0x656E5841u, 95u}, // en-XA -> ~~~A
-    {0xB5A40000u, 44u}, // enn -> Latn
-    {0xC1A40000u, 44u}, // enq -> Latn
-    {0x656F0000u, 44u}, // eo -> Latn
-    {0xA2240000u, 44u}, // eri -> Latn
-    {0x65730000u, 44u}, // es -> Latn
-    {0x9A440000u, 22u}, // esg -> Gonm
-    {0xD2440000u, 44u}, // esu -> Latn
-    {0x65740000u, 44u}, // et -> Latn
-    {0xC6640000u, 44u}, // etr -> Latn
-    {0xCE640000u, 34u}, // ett -> Ital
-    {0xD2640000u, 44u}, // etu -> Latn
-    {0xDE640000u, 44u}, // etx -> Latn
-    {0x65750000u, 44u}, // eu -> Latn
-    {0xBAC40000u, 44u}, // ewo -> Latn
-    {0xCEE40000u, 44u}, // ext -> Latn
+    {0xBDC30000u, 46u}, // dop -> Latn
+    {0xD9C30000u, 46u}, // dow -> Latn
+    {0x9E230000u, 56u}, // drh -> Mong
+    {0xA2230000u, 46u}, // dri -> Latn
+    {0xCA230000u, 20u}, // drs -> Ethi
+    {0x86430000u, 46u}, // dsb -> Latn
+    {0xB2630000u, 46u}, // dtm -> Latn
+    {0xBE630000u, 46u}, // dtp -> Latn
+    {0xCA630000u, 46u}, // dts -> Latn
+    {0xE2630000u, 18u}, // dty -> Deva
+    {0x82830000u, 46u}, // dua -> Latn
+    {0x8A830000u, 46u}, // duc -> Latn
+    {0x8E830000u, 46u}, // dud -> Latn
+    {0x9A830000u, 46u}, // dug -> Latn
+    {0x64760000u, 88u}, // dv -> Thaa
+    {0x82A30000u, 46u}, // dva -> Latn
+    {0xDAC30000u, 46u}, // dww -> Latn
+    {0xBB030000u, 46u}, // dyo -> Latn
+    {0xD3030000u, 46u}, // dyu -> Latn
+    {0x647A0000u, 90u}, // dz -> Tibt
+    {0x9B230000u, 46u}, // dzg -> Latn
+    {0xD0240000u, 46u}, // ebu -> Latn
+    {0x65650000u, 46u}, // ee -> Latn
+    {0xA0A40000u, 46u}, // efi -> Latn
+    {0xACC40000u, 46u}, // egl -> Latn
+    {0xE0C40000u, 19u}, // egy -> Egyp
+    {0x81440000u, 46u}, // eka -> Latn
+    {0xE1440000u, 37u}, // eky -> Kali
+    {0x656C0000u, 25u}, // el -> Grek
+    {0x81840000u, 46u}, // ema -> Latn
+    {0xA1840000u, 46u}, // emi -> Latn
+    {0x656E0000u, 46u}, // en -> Latn
+    {0x656E5841u, 97u}, // en-XA -> ~~~A
+    {0xB5A40000u, 46u}, // enn -> Latn
+    {0xC1A40000u, 46u}, // enq -> Latn
+    {0x656F0000u, 46u}, // eo -> Latn
+    {0xA2240000u, 46u}, // eri -> Latn
+    {0x65730000u, 46u}, // es -> Latn
+    {0x9A440000u, 23u}, // esg -> Gonm
+    {0xD2440000u, 46u}, // esu -> Latn
+    {0x65740000u, 46u}, // et -> Latn
+    {0xC6640000u, 46u}, // etr -> Latn
+    {0xCE640000u, 35u}, // ett -> Ital
+    {0xD2640000u, 46u}, // etu -> Latn
+    {0xDE640000u, 46u}, // etx -> Latn
+    {0x65750000u, 46u}, // eu -> Latn
+    {0xBAC40000u, 46u}, // ewo -> Latn
+    {0xCEE40000u, 46u}, // ext -> Latn
     {0x66610000u,  1u}, // fa -> Arab
-    {0x80050000u, 44u}, // faa -> Latn
-    {0x84050000u, 44u}, // fab -> Latn
-    {0x98050000u, 44u}, // fag -> Latn
-    {0xA0050000u, 44u}, // fai -> Latn
-    {0xB4050000u, 44u}, // fan -> Latn
-    {0x66660000u, 44u}, // ff -> Latn
-    {0xA0A50000u, 44u}, // ffi -> Latn
-    {0xB0A50000u, 44u}, // ffm -> Latn
-    {0x66690000u, 44u}, // fi -> Latn
+    {0x80050000u, 46u}, // faa -> Latn
+    {0x84050000u, 46u}, // fab -> Latn
+    {0x98050000u, 46u}, // fag -> Latn
+    {0xA0050000u, 46u}, // fai -> Latn
+    {0xB4050000u, 46u}, // fan -> Latn
+    {0x66660000u, 46u}, // ff -> Latn
+    {0xA0A50000u, 46u}, // ffi -> Latn
+    {0xB0A50000u, 46u}, // ffm -> Latn
+    {0x66690000u, 46u}, // fi -> Latn
     {0x81050000u,  1u}, // fia -> Arab
-    {0xAD050000u, 44u}, // fil -> Latn
-    {0xCD050000u, 44u}, // fit -> Latn
-    {0x666A0000u, 44u}, // fj -> Latn
-    {0xC5650000u, 44u}, // flr -> Latn
-    {0xBD850000u, 44u}, // fmp -> Latn
-    {0x666F0000u, 44u}, // fo -> Latn
-    {0x8DC50000u, 44u}, // fod -> Latn
-    {0xB5C50000u, 44u}, // fon -> Latn
-    {0xC5C50000u, 44u}, // for -> Latn
-    {0x91E50000u, 44u}, // fpe -> Latn
-    {0xCA050000u, 44u}, // fqs -> Latn
-    {0x66720000u, 44u}, // fr -> Latn
-    {0x8A250000u, 44u}, // frc -> Latn
-    {0xBE250000u, 44u}, // frp -> Latn
-    {0xC6250000u, 44u}, // frr -> Latn
-    {0xCA250000u, 44u}, // frs -> Latn
+    {0xAD050000u, 46u}, // fil -> Latn
+    {0xCD050000u, 46u}, // fit -> Latn
+    {0x666A0000u, 46u}, // fj -> Latn
+    {0xC5650000u, 46u}, // flr -> Latn
+    {0xBD850000u, 46u}, // fmp -> Latn
+    {0x666F0000u, 46u}, // fo -> Latn
+    {0x8DC50000u, 46u}, // fod -> Latn
+    {0xB5C50000u, 46u}, // fon -> Latn
+    {0xC5C50000u, 46u}, // for -> Latn
+    {0x91E50000u, 46u}, // fpe -> Latn
+    {0xCA050000u, 46u}, // fqs -> Latn
+    {0x66720000u, 46u}, // fr -> Latn
+    {0x8A250000u, 46u}, // frc -> Latn
+    {0xBE250000u, 46u}, // frp -> Latn
+    {0xC6250000u, 46u}, // frr -> Latn
+    {0xCA250000u, 46u}, // frs -> Latn
     {0x86850000u,  1u}, // fub -> Arab
-    {0x8E850000u, 44u}, // fud -> Latn
-    {0x92850000u, 44u}, // fue -> Latn
-    {0x96850000u, 44u}, // fuf -> Latn
-    {0x9E850000u, 44u}, // fuh -> Latn
-    {0xC2850000u, 44u}, // fuq -> Latn
-    {0xC6850000u, 44u}, // fur -> Latn
-    {0xD6850000u, 44u}, // fuv -> Latn
-    {0xE2850000u, 44u}, // fuy -> Latn
-    {0xC6A50000u, 44u}, // fvr -> Latn
-    {0x66790000u, 44u}, // fy -> Latn
-    {0x67610000u, 44u}, // ga -> Latn
-    {0x80060000u, 44u}, // gaa -> Latn
-    {0x94060000u, 44u}, // gaf -> Latn
-    {0x98060000u, 44u}, // gag -> Latn
-    {0x9C060000u, 44u}, // gah -> Latn
-    {0xA4060000u, 44u}, // gaj -> Latn
-    {0xB0060000u, 44u}, // gam -> Latn
-    {0xB4060000u, 27u}, // gan -> Hans
-    {0xD8060000u, 44u}, // gaw -> Latn
-    {0xE0060000u, 44u}, // gay -> Latn
-    {0x80260000u, 44u}, // gba -> Latn
-    {0x94260000u, 44u}, // gbf -> Latn
-    {0xB0260000u, 17u}, // gbm -> Deva
-    {0xE0260000u, 44u}, // gby -> Latn
+    {0x8E850000u, 46u}, // fud -> Latn
+    {0x92850000u, 46u}, // fue -> Latn
+    {0x96850000u, 46u}, // fuf -> Latn
+    {0x9E850000u, 46u}, // fuh -> Latn
+    {0xC2850000u, 46u}, // fuq -> Latn
+    {0xC6850000u, 46u}, // fur -> Latn
+    {0xD6850000u, 46u}, // fuv -> Latn
+    {0xE2850000u, 46u}, // fuy -> Latn
+    {0xC6A50000u, 46u}, // fvr -> Latn
+    {0x66790000u, 46u}, // fy -> Latn
+    {0x67610000u, 46u}, // ga -> Latn
+    {0x80060000u, 46u}, // gaa -> Latn
+    {0x94060000u, 46u}, // gaf -> Latn
+    {0x98060000u, 46u}, // gag -> Latn
+    {0x9C060000u, 46u}, // gah -> Latn
+    {0xA4060000u, 46u}, // gaj -> Latn
+    {0xB0060000u, 46u}, // gam -> Latn
+    {0xB4060000u, 28u}, // gan -> Hans
+    {0xD8060000u, 46u}, // gaw -> Latn
+    {0xE0060000u, 46u}, // gay -> Latn
+    {0x80260000u, 46u}, // gba -> Latn
+    {0x94260000u, 46u}, // gbf -> Latn
+    {0xB0260000u, 18u}, // gbm -> Deva
+    {0xE0260000u, 46u}, // gby -> Latn
     {0xE4260000u,  1u}, // gbz -> Arab
-    {0xC4460000u, 44u}, // gcr -> Latn
-    {0x67640000u, 44u}, // gd -> Latn
-    {0x90660000u, 44u}, // gde -> Latn
-    {0xB4660000u, 44u}, // gdn -> Latn
-    {0xC4660000u, 44u}, // gdr -> Latn
-    {0x84860000u, 44u}, // geb -> Latn
-    {0xA4860000u, 44u}, // gej -> Latn
-    {0xAC860000u, 44u}, // gel -> Latn
-    {0xE4860000u, 19u}, // gez -> Ethi
-    {0xA8A60000u, 44u}, // gfk -> Latn
-    {0xB4C60000u, 17u}, // ggn -> Deva
-    {0xC8E60000u, 44u}, // ghs -> Latn
-    {0xAD060000u, 44u}, // gil -> Latn
-    {0xB1060000u, 44u}, // gim -> Latn
+    {0xC4460000u, 46u}, // gcr -> Latn
+    {0x67640000u, 46u}, // gd -> Latn
+    {0x90660000u, 46u}, // gde -> Latn
+    {0xB4660000u, 46u}, // gdn -> Latn
+    {0xC4660000u, 46u}, // gdr -> Latn
+    {0x84860000u, 46u}, // geb -> Latn
+    {0xA4860000u, 46u}, // gej -> Latn
+    {0xAC860000u, 46u}, // gel -> Latn
+    {0xE4860000u, 20u}, // gez -> Ethi
+    {0xA8A60000u, 46u}, // gfk -> Latn
+    {0xB4C60000u, 18u}, // ggn -> Deva
+    {0xC8E60000u, 46u}, // ghs -> Latn
+    {0xAD060000u, 46u}, // gil -> Latn
+    {0xB1060000u, 46u}, // gim -> Latn
     {0xA9260000u,  1u}, // gjk -> Arab
-    {0xB5260000u, 44u}, // gjn -> Latn
+    {0xB5260000u, 46u}, // gjn -> Latn
     {0xD1260000u,  1u}, // gju -> Arab
-    {0xB5460000u, 44u}, // gkn -> Latn
-    {0xBD460000u, 44u}, // gkp -> Latn
-    {0x676C0000u, 44u}, // gl -> Latn
+    {0xB5460000u, 46u}, // gkn -> Latn
+    {0xBD460000u, 46u}, // gkp -> Latn
+    {0x676C0000u, 46u}, // gl -> Latn
     {0xA9660000u,  1u}, // glk -> Arab
-    {0xB1860000u, 44u}, // gmm -> Latn
-    {0xD5860000u, 19u}, // gmv -> Ethi
-    {0x676E0000u, 44u}, // gn -> Latn
-    {0x8DA60000u, 44u}, // gnd -> Latn
-    {0x99A60000u, 44u}, // gng -> Latn
-    {0x8DC60000u, 44u}, // god -> Latn
-    {0x95C60000u, 19u}, // gof -> Ethi
-    {0xA1C60000u, 44u}, // goi -> Latn
-    {0xB1C60000u, 17u}, // gom -> Deva
-    {0xB5C60000u, 84u}, // gon -> Telu
-    {0xC5C60000u, 44u}, // gor -> Latn
-    {0xC9C60000u, 44u}, // gos -> Latn
-    {0xCDC60000u, 23u}, // got -> Goth
-    {0x86260000u, 44u}, // grb -> Latn
-    {0x8A260000u, 15u}, // grc -> Cprt
+    {0xB1860000u, 46u}, // gmm -> Latn
+    {0xD5860000u, 20u}, // gmv -> Ethi
+    {0x676E0000u, 46u}, // gn -> Latn
+    {0x8DA60000u, 46u}, // gnd -> Latn
+    {0x99A60000u, 46u}, // gng -> Latn
+    {0x8DC60000u, 46u}, // god -> Latn
+    {0x95C60000u, 20u}, // gof -> Ethi
+    {0xA1C60000u, 46u}, // goi -> Latn
+    {0xB1C60000u, 18u}, // gom -> Deva
+    {0xB5C60000u, 86u}, // gon -> Telu
+    {0xC5C60000u, 46u}, // gor -> Latn
+    {0xC9C60000u, 46u}, // gos -> Latn
+    {0xCDC60000u, 24u}, // got -> Goth
+    {0x86260000u, 46u}, // grb -> Latn
+    {0x8A260000u, 16u}, // grc -> Cprt
     {0xCE260000u,  7u}, // grt -> Beng
-    {0xDA260000u, 44u}, // grw -> Latn
-    {0xDA460000u, 44u}, // gsw -> Latn
-    {0x67750000u, 25u}, // gu -> Gujr
-    {0x86860000u, 44u}, // gub -> Latn
-    {0x8A860000u, 44u}, // guc -> Latn
-    {0x8E860000u, 44u}, // gud -> Latn
-    {0xC6860000u, 44u}, // gur -> Latn
-    {0xDA860000u, 44u}, // guw -> Latn
-    {0xDE860000u, 44u}, // gux -> Latn
-    {0xE6860000u, 44u}, // guz -> Latn
-    {0x67760000u, 44u}, // gv -> Latn
-    {0x96A60000u, 44u}, // gvf -> Latn
-    {0xC6A60000u, 17u}, // gvr -> Deva
-    {0xCAA60000u, 44u}, // gvs -> Latn
+    {0xDA260000u, 46u}, // grw -> Latn
+    {0xDA460000u, 46u}, // gsw -> Latn
+    {0x67750000u, 26u}, // gu -> Gujr
+    {0x86860000u, 46u}, // gub -> Latn
+    {0x8A860000u, 46u}, // guc -> Latn
+    {0x8E860000u, 46u}, // gud -> Latn
+    {0xC6860000u, 46u}, // gur -> Latn
+    {0xDA860000u, 46u}, // guw -> Latn
+    {0xDE860000u, 46u}, // gux -> Latn
+    {0xE6860000u, 46u}, // guz -> Latn
+    {0x67760000u, 46u}, // gv -> Latn
+    {0x96A60000u, 46u}, // gvf -> Latn
+    {0xC6A60000u, 18u}, // gvr -> Deva
+    {0xCAA60000u, 46u}, // gvs -> Latn
     {0x8AC60000u,  1u}, // gwc -> Arab
-    {0xA2C60000u, 44u}, // gwi -> Latn
+    {0xA2C60000u, 46u}, // gwi -> Latn
     {0xCEC60000u,  1u}, // gwt -> Arab
-    {0xA3060000u, 44u}, // gyi -> Latn
-    {0x68610000u, 44u}, // ha -> Latn
+    {0xA3060000u, 46u}, // gyi -> Latn
+    {0x68610000u, 46u}, // ha -> Latn
     {0x6861434Du,  1u}, // ha-CM -> Arab
     {0x68615344u,  1u}, // ha-SD -> Arab
-    {0x98070000u, 44u}, // hag -> Latn
-    {0xA8070000u, 27u}, // hak -> Hans
-    {0xB0070000u, 44u}, // ham -> Latn
-    {0xD8070000u, 44u}, // haw -> Latn
+    {0x98070000u, 46u}, // hag -> Latn
+    {0xA8070000u, 28u}, // hak -> Hans
+    {0xB0070000u, 46u}, // ham -> Latn
+    {0xD8070000u, 46u}, // haw -> Latn
     {0xE4070000u,  1u}, // haz -> Arab
-    {0x84270000u, 44u}, // hbb -> Latn
-    {0xE0670000u, 19u}, // hdy -> Ethi
-    {0x68650000u, 30u}, // he -> Hebr
-    {0xE0E70000u, 44u}, // hhy -> Latn
-    {0x68690000u, 17u}, // hi -> Deva
-    {0x81070000u, 44u}, // hia -> Latn
-    {0x95070000u, 44u}, // hif -> Latn
-    {0x99070000u, 44u}, // hig -> Latn
-    {0x9D070000u, 44u}, // hih -> Latn
-    {0xAD070000u, 44u}, // hil -> Latn
-    {0x81670000u, 44u}, // hla -> Latn
-    {0xD1670000u, 31u}, // hlu -> Hluw
-    {0x8D870000u, 67u}, // hmd -> Plrd
-    {0xCD870000u, 44u}, // hmt -> Latn
+    {0x84270000u, 46u}, // hbb -> Latn
+    {0xE0670000u, 20u}, // hdy -> Ethi
+    {0x68650000u, 31u}, // he -> Hebr
+    {0xE0E70000u, 46u}, // hhy -> Latn
+    {0x68690000u, 18u}, // hi -> Deva
+    {0x81070000u, 46u}, // hia -> Latn
+    {0x95070000u, 46u}, // hif -> Latn
+    {0x99070000u, 46u}, // hig -> Latn
+    {0x9D070000u, 46u}, // hih -> Latn
+    {0xAD070000u, 46u}, // hil -> Latn
+    {0x81670000u, 46u}, // hla -> Latn
+    {0xD1670000u, 32u}, // hlu -> Hluw
+    {0x8D870000u, 69u}, // hmd -> Plrd
+    {0xCD870000u, 46u}, // hmt -> Latn
     {0x8DA70000u,  1u}, // hnd -> Arab
-    {0x91A70000u, 17u}, // hne -> Deva
-    {0xA5A70000u, 32u}, // hnj -> Hmng
-    {0xB5A70000u, 44u}, // hnn -> Latn
+    {0x91A70000u, 18u}, // hne -> Deva
+    {0xA5A70000u, 33u}, // hnj -> Hmng
+    {0xB5A70000u, 46u}, // hnn -> Latn
     {0xB9A70000u,  1u}, // hno -> Arab
-    {0x686F0000u, 44u}, // ho -> Latn
-    {0x89C70000u, 17u}, // hoc -> Deva
-    {0xA5C70000u, 17u}, // hoj -> Deva
-    {0xCDC70000u, 44u}, // hot -> Latn
-    {0x68720000u, 44u}, // hr -> Latn
-    {0x86470000u, 44u}, // hsb -> Latn
-    {0xB6470000u, 27u}, // hsn -> Hans
-    {0x68740000u, 44u}, // ht -> Latn
-    {0x68750000u, 44u}, // hu -> Latn
-    {0xA2870000u, 44u}, // hui -> Latn
+    {0x686F0000u, 46u}, // ho -> Latn
+    {0x89C70000u, 18u}, // hoc -> Deva
+    {0xA5C70000u, 18u}, // hoj -> Deva
+    {0xCDC70000u, 46u}, // hot -> Latn
+    {0x68720000u, 46u}, // hr -> Latn
+    {0x86470000u, 46u}, // hsb -> Latn
+    {0xB6470000u, 28u}, // hsn -> Hans
+    {0x68740000u, 46u}, // ht -> Latn
+    {0x68750000u, 46u}, // hu -> Latn
+    {0xA2870000u, 46u}, // hui -> Latn
     {0x68790000u,  3u}, // hy -> Armn
-    {0x687A0000u, 44u}, // hz -> Latn
-    {0x69610000u, 44u}, // ia -> Latn
-    {0xB4080000u, 44u}, // ian -> Latn
-    {0xC4080000u, 44u}, // iar -> Latn
-    {0x80280000u, 44u}, // iba -> Latn
-    {0x84280000u, 44u}, // ibb -> Latn
-    {0xE0280000u, 44u}, // iby -> Latn
-    {0x80480000u, 44u}, // ica -> Latn
-    {0x9C480000u, 44u}, // ich -> Latn
-    {0x69640000u, 44u}, // id -> Latn
-    {0x8C680000u, 44u}, // idd -> Latn
-    {0xA0680000u, 44u}, // idi -> Latn
-    {0xD0680000u, 44u}, // idu -> Latn
-    {0x90A80000u, 44u}, // ife -> Latn
-    {0x69670000u, 44u}, // ig -> Latn
-    {0x84C80000u, 44u}, // igb -> Latn
-    {0x90C80000u, 44u}, // ige -> Latn
-    {0x69690000u, 94u}, // ii -> Yiii
-    {0xA5280000u, 44u}, // ijj -> Latn
-    {0x696B0000u, 44u}, // ik -> Latn
-    {0xA9480000u, 44u}, // ikk -> Latn
-    {0xCD480000u, 44u}, // ikt -> Latn
-    {0xD9480000u, 44u}, // ikw -> Latn
-    {0xDD480000u, 44u}, // ikx -> Latn
-    {0xB9680000u, 44u}, // ilo -> Latn
-    {0xB9880000u, 44u}, // imo -> Latn
-    {0x696E0000u, 44u}, // in -> Latn
-    {0x9DA80000u, 16u}, // inh -> Cyrl
-    {0x696F0000u, 44u}, // io -> Latn
-    {0xD1C80000u, 44u}, // iou -> Latn
-    {0xA2280000u, 44u}, // iri -> Latn
-    {0x69730000u, 44u}, // is -> Latn
-    {0x69740000u, 44u}, // it -> Latn
+    {0x687A0000u, 46u}, // hz -> Latn
+    {0x69610000u, 46u}, // ia -> Latn
+    {0xB4080000u, 46u}, // ian -> Latn
+    {0xC4080000u, 46u}, // iar -> Latn
+    {0x80280000u, 46u}, // iba -> Latn
+    {0x84280000u, 46u}, // ibb -> Latn
+    {0xE0280000u, 46u}, // iby -> Latn
+    {0x80480000u, 46u}, // ica -> Latn
+    {0x9C480000u, 46u}, // ich -> Latn
+    {0x69640000u, 46u}, // id -> Latn
+    {0x8C680000u, 46u}, // idd -> Latn
+    {0xA0680000u, 46u}, // idi -> Latn
+    {0xD0680000u, 46u}, // idu -> Latn
+    {0x90A80000u, 46u}, // ife -> Latn
+    {0x69670000u, 46u}, // ig -> Latn
+    {0x84C80000u, 46u}, // igb -> Latn
+    {0x90C80000u, 46u}, // ige -> Latn
+    {0x69690000u, 96u}, // ii -> Yiii
+    {0xA5280000u, 46u}, // ijj -> Latn
+    {0x696B0000u, 46u}, // ik -> Latn
+    {0xA9480000u, 46u}, // ikk -> Latn
+    {0xCD480000u, 46u}, // ikt -> Latn
+    {0xD9480000u, 46u}, // ikw -> Latn
+    {0xDD480000u, 46u}, // ikx -> Latn
+    {0xB9680000u, 46u}, // ilo -> Latn
+    {0xB9880000u, 46u}, // imo -> Latn
+    {0x696E0000u, 46u}, // in -> Latn
+    {0x9DA80000u, 17u}, // inh -> Cyrl
+    {0x696F0000u, 46u}, // io -> Latn
+    {0xD1C80000u, 46u}, // iou -> Latn
+    {0xA2280000u, 46u}, // iri -> Latn
+    {0x69730000u, 46u}, // is -> Latn
+    {0x69740000u, 46u}, // it -> Latn
     {0x69750000u, 10u}, // iu -> Cans
-    {0x69770000u, 30u}, // iw -> Hebr
-    {0xB2C80000u, 44u}, // iwm -> Latn
-    {0xCAC80000u, 44u}, // iws -> Latn
-    {0x9F280000u, 44u}, // izh -> Latn
-    {0xA3280000u, 44u}, // izi -> Latn
-    {0x6A610000u, 35u}, // ja -> Jpan
-    {0x84090000u, 44u}, // jab -> Latn
-    {0xB0090000u, 44u}, // jam -> Latn
-    {0xB8290000u, 44u}, // jbo -> Latn
-    {0xD0290000u, 44u}, // jbu -> Latn
-    {0xB4890000u, 44u}, // jen -> Latn
-    {0xA8C90000u, 44u}, // jgk -> Latn
-    {0xB8C90000u, 44u}, // jgo -> Latn
-    {0x6A690000u, 30u}, // ji -> Hebr
-    {0x85090000u, 44u}, // jib -> Latn
-    {0x89890000u, 44u}, // jmc -> Latn
-    {0xAD890000u, 17u}, // jml -> Deva
-    {0x82290000u, 44u}, // jra -> Latn
-    {0xCE890000u, 44u}, // jut -> Latn
-    {0x6A760000u, 44u}, // jv -> Latn
-    {0x6A770000u, 44u}, // jw -> Latn
-    {0x6B610000u, 20u}, // ka -> Geor
-    {0x800A0000u, 16u}, // kaa -> Cyrl
-    {0x840A0000u, 44u}, // kab -> Latn
-    {0x880A0000u, 44u}, // kac -> Latn
-    {0x8C0A0000u, 44u}, // kad -> Latn
-    {0xA00A0000u, 44u}, // kai -> Latn
-    {0xA40A0000u, 44u}, // kaj -> Latn
-    {0xB00A0000u, 44u}, // kam -> Latn
-    {0xB80A0000u, 44u}, // kao -> Latn
-    {0x8C2A0000u, 16u}, // kbd -> Cyrl
-    {0xB02A0000u, 44u}, // kbm -> Latn
-    {0xBC2A0000u, 44u}, // kbp -> Latn
-    {0xC02A0000u, 44u}, // kbq -> Latn
-    {0xDC2A0000u, 44u}, // kbx -> Latn
+    {0x69770000u, 31u}, // iw -> Hebr
+    {0xB2C80000u, 46u}, // iwm -> Latn
+    {0xCAC80000u, 46u}, // iws -> Latn
+    {0x9F280000u, 46u}, // izh -> Latn
+    {0xA3280000u, 46u}, // izi -> Latn
+    {0x6A610000u, 36u}, // ja -> Jpan
+    {0x84090000u, 46u}, // jab -> Latn
+    {0xB0090000u, 46u}, // jam -> Latn
+    {0xB8290000u, 46u}, // jbo -> Latn
+    {0xD0290000u, 46u}, // jbu -> Latn
+    {0xB4890000u, 46u}, // jen -> Latn
+    {0xA8C90000u, 46u}, // jgk -> Latn
+    {0xB8C90000u, 46u}, // jgo -> Latn
+    {0x6A690000u, 31u}, // ji -> Hebr
+    {0x85090000u, 46u}, // jib -> Latn
+    {0x89890000u, 46u}, // jmc -> Latn
+    {0xAD890000u, 18u}, // jml -> Deva
+    {0x82290000u, 46u}, // jra -> Latn
+    {0xCE890000u, 46u}, // jut -> Latn
+    {0x6A760000u, 46u}, // jv -> Latn
+    {0x6A770000u, 46u}, // jw -> Latn
+    {0x6B610000u, 21u}, // ka -> Geor
+    {0x800A0000u, 17u}, // kaa -> Cyrl
+    {0x840A0000u, 46u}, // kab -> Latn
+    {0x880A0000u, 46u}, // kac -> Latn
+    {0x8C0A0000u, 46u}, // kad -> Latn
+    {0xA00A0000u, 46u}, // kai -> Latn
+    {0xA40A0000u, 46u}, // kaj -> Latn
+    {0xB00A0000u, 46u}, // kam -> Latn
+    {0xB80A0000u, 46u}, // kao -> Latn
+    {0x8C2A0000u, 17u}, // kbd -> Cyrl
+    {0xB02A0000u, 46u}, // kbm -> Latn
+    {0xBC2A0000u, 46u}, // kbp -> Latn
+    {0xC02A0000u, 46u}, // kbq -> Latn
+    {0xDC2A0000u, 46u}, // kbx -> Latn
     {0xE02A0000u,  1u}, // kby -> Arab
-    {0x984A0000u, 44u}, // kcg -> Latn
-    {0xA84A0000u, 44u}, // kck -> Latn
-    {0xAC4A0000u, 44u}, // kcl -> Latn
-    {0xCC4A0000u, 44u}, // kct -> Latn
-    {0x906A0000u, 44u}, // kde -> Latn
+    {0x984A0000u, 46u}, // kcg -> Latn
+    {0xA84A0000u, 46u}, // kck -> Latn
+    {0xAC4A0000u, 46u}, // kcl -> Latn
+    {0xCC4A0000u, 46u}, // kct -> Latn
+    {0x906A0000u, 46u}, // kde -> Latn
     {0x9C6A0000u,  1u}, // kdh -> Arab
-    {0xAC6A0000u, 44u}, // kdl -> Latn
-    {0xCC6A0000u, 87u}, // kdt -> Thai
-    {0x808A0000u, 44u}, // kea -> Latn
-    {0xB48A0000u, 44u}, // ken -> Latn
-    {0xE48A0000u, 44u}, // kez -> Latn
-    {0xB8AA0000u, 44u}, // kfo -> Latn
-    {0xC4AA0000u, 17u}, // kfr -> Deva
-    {0xE0AA0000u, 17u}, // kfy -> Deva
-    {0x6B670000u, 44u}, // kg -> Latn
-    {0x90CA0000u, 44u}, // kge -> Latn
-    {0x94CA0000u, 44u}, // kgf -> Latn
-    {0xBCCA0000u, 44u}, // kgp -> Latn
-    {0x80EA0000u, 44u}, // kha -> Latn
-    {0x84EA0000u, 80u}, // khb -> Talu
-    {0xB4EA0000u, 17u}, // khn -> Deva
-    {0xC0EA0000u, 44u}, // khq -> Latn
-    {0xC8EA0000u, 44u}, // khs -> Latn
-    {0xCCEA0000u, 56u}, // kht -> Mymr
+    {0xAC6A0000u, 46u}, // kdl -> Latn
+    {0xCC6A0000u, 89u}, // kdt -> Thai
+    {0x808A0000u, 46u}, // kea -> Latn
+    {0xB48A0000u, 46u}, // ken -> Latn
+    {0xE48A0000u, 46u}, // kez -> Latn
+    {0xB8AA0000u, 46u}, // kfo -> Latn
+    {0xC4AA0000u, 18u}, // kfr -> Deva
+    {0xE0AA0000u, 18u}, // kfy -> Deva
+    {0x6B670000u, 46u}, // kg -> Latn
+    {0x90CA0000u, 46u}, // kge -> Latn
+    {0x94CA0000u, 46u}, // kgf -> Latn
+    {0xBCCA0000u, 46u}, // kgp -> Latn
+    {0x80EA0000u, 46u}, // kha -> Latn
+    {0x84EA0000u, 82u}, // khb -> Talu
+    {0xB4EA0000u, 18u}, // khn -> Deva
+    {0xC0EA0000u, 46u}, // khq -> Latn
+    {0xC8EA0000u, 46u}, // khs -> Latn
+    {0xCCEA0000u, 58u}, // kht -> Mymr
     {0xD8EA0000u,  1u}, // khw -> Arab
-    {0xE4EA0000u, 44u}, // khz -> Latn
-    {0x6B690000u, 44u}, // ki -> Latn
-    {0xA50A0000u, 44u}, // kij -> Latn
-    {0xD10A0000u, 44u}, // kiu -> Latn
-    {0xD90A0000u, 44u}, // kiw -> Latn
-    {0x6B6A0000u, 44u}, // kj -> Latn
-    {0x8D2A0000u, 44u}, // kjd -> Latn
-    {0x992A0000u, 43u}, // kjg -> Laoo
-    {0xC92A0000u, 44u}, // kjs -> Latn
-    {0xE12A0000u, 44u}, // kjy -> Latn
-    {0x6B6B0000u, 16u}, // kk -> Cyrl
+    {0xE4EA0000u, 46u}, // khz -> Latn
+    {0x6B690000u, 46u}, // ki -> Latn
+    {0xA50A0000u, 46u}, // kij -> Latn
+    {0xD10A0000u, 46u}, // kiu -> Latn
+    {0xD90A0000u, 46u}, // kiw -> Latn
+    {0x6B6A0000u, 46u}, // kj -> Latn
+    {0x8D2A0000u, 46u}, // kjd -> Latn
+    {0x992A0000u, 45u}, // kjg -> Laoo
+    {0xC92A0000u, 46u}, // kjs -> Latn
+    {0xE12A0000u, 46u}, // kjy -> Latn
+    {0x6B6B0000u, 17u}, // kk -> Cyrl
     {0x6B6B4146u,  1u}, // kk-AF -> Arab
     {0x6B6B434Eu,  1u}, // kk-CN -> Arab
     {0x6B6B4952u,  1u}, // kk-IR -> Arab
     {0x6B6B4D4Eu,  1u}, // kk-MN -> Arab
-    {0x894A0000u, 44u}, // kkc -> Latn
-    {0xA54A0000u, 44u}, // kkj -> Latn
-    {0x6B6C0000u, 44u}, // kl -> Latn
-    {0xB56A0000u, 44u}, // kln -> Latn
-    {0xC16A0000u, 44u}, // klq -> Latn
-    {0xCD6A0000u, 44u}, // klt -> Latn
-    {0xDD6A0000u, 44u}, // klx -> Latn
-    {0x6B6D0000u, 39u}, // km -> Khmr
-    {0x858A0000u, 44u}, // kmb -> Latn
-    {0x9D8A0000u, 44u}, // kmh -> Latn
-    {0xB98A0000u, 44u}, // kmo -> Latn
-    {0xC98A0000u, 44u}, // kms -> Latn
-    {0xD18A0000u, 44u}, // kmu -> Latn
-    {0xD98A0000u, 44u}, // kmw -> Latn
-    {0x6B6E0000u, 40u}, // kn -> Knda
-    {0x95AA0000u, 44u}, // knf -> Latn
-    {0xBDAA0000u, 44u}, // knp -> Latn
-    {0x6B6F0000u, 41u}, // ko -> Kore
-    {0xA1CA0000u, 16u}, // koi -> Cyrl
-    {0xA9CA0000u, 17u}, // kok -> Deva
-    {0xADCA0000u, 44u}, // kol -> Latn
-    {0xC9CA0000u, 44u}, // kos -> Latn
-    {0xE5CA0000u, 44u}, // koz -> Latn
-    {0x91EA0000u, 44u}, // kpe -> Latn
-    {0x95EA0000u, 44u}, // kpf -> Latn
-    {0xB9EA0000u, 44u}, // kpo -> Latn
-    {0xC5EA0000u, 44u}, // kpr -> Latn
-    {0xDDEA0000u, 44u}, // kpx -> Latn
-    {0x860A0000u, 44u}, // kqb -> Latn
-    {0x960A0000u, 44u}, // kqf -> Latn
-    {0xCA0A0000u, 44u}, // kqs -> Latn
-    {0xE20A0000u, 19u}, // kqy -> Ethi
-    {0x6B720000u, 44u}, // kr -> Latn
-    {0x8A2A0000u, 16u}, // krc -> Cyrl
-    {0xA22A0000u, 44u}, // kri -> Latn
-    {0xA62A0000u, 44u}, // krj -> Latn
-    {0xAE2A0000u, 44u}, // krl -> Latn
-    {0xCA2A0000u, 44u}, // krs -> Latn
-    {0xD22A0000u, 17u}, // kru -> Deva
+    {0x894A0000u, 46u}, // kkc -> Latn
+    {0xA54A0000u, 46u}, // kkj -> Latn
+    {0x6B6C0000u, 46u}, // kl -> Latn
+    {0xB56A0000u, 46u}, // kln -> Latn
+    {0xC16A0000u, 46u}, // klq -> Latn
+    {0xCD6A0000u, 46u}, // klt -> Latn
+    {0xDD6A0000u, 46u}, // klx -> Latn
+    {0x6B6D0000u, 40u}, // km -> Khmr
+    {0x858A0000u, 46u}, // kmb -> Latn
+    {0x9D8A0000u, 46u}, // kmh -> Latn
+    {0xB98A0000u, 46u}, // kmo -> Latn
+    {0xC98A0000u, 46u}, // kms -> Latn
+    {0xD18A0000u, 46u}, // kmu -> Latn
+    {0xD98A0000u, 46u}, // kmw -> Latn
+    {0x6B6E0000u, 42u}, // kn -> Knda
+    {0x95AA0000u, 46u}, // knf -> Latn
+    {0xBDAA0000u, 46u}, // knp -> Latn
+    {0x6B6F0000u, 43u}, // ko -> Kore
+    {0xA1CA0000u, 17u}, // koi -> Cyrl
+    {0xA9CA0000u, 18u}, // kok -> Deva
+    {0xADCA0000u, 46u}, // kol -> Latn
+    {0xC9CA0000u, 46u}, // kos -> Latn
+    {0xE5CA0000u, 46u}, // koz -> Latn
+    {0x91EA0000u, 46u}, // kpe -> Latn
+    {0x95EA0000u, 46u}, // kpf -> Latn
+    {0xB9EA0000u, 46u}, // kpo -> Latn
+    {0xC5EA0000u, 46u}, // kpr -> Latn
+    {0xDDEA0000u, 46u}, // kpx -> Latn
+    {0x860A0000u, 46u}, // kqb -> Latn
+    {0x960A0000u, 46u}, // kqf -> Latn
+    {0xCA0A0000u, 46u}, // kqs -> Latn
+    {0xE20A0000u, 20u}, // kqy -> Ethi
+    {0x6B720000u, 46u}, // kr -> Latn
+    {0x8A2A0000u, 17u}, // krc -> Cyrl
+    {0xA22A0000u, 46u}, // kri -> Latn
+    {0xA62A0000u, 46u}, // krj -> Latn
+    {0xAE2A0000u, 46u}, // krl -> Latn
+    {0xCA2A0000u, 46u}, // krs -> Latn
+    {0xD22A0000u, 18u}, // kru -> Deva
     {0x6B730000u,  1u}, // ks -> Arab
-    {0x864A0000u, 44u}, // ksb -> Latn
-    {0x8E4A0000u, 44u}, // ksd -> Latn
-    {0x964A0000u, 44u}, // ksf -> Latn
-    {0x9E4A0000u, 44u}, // ksh -> Latn
-    {0xA64A0000u, 44u}, // ksj -> Latn
-    {0xC64A0000u, 44u}, // ksr -> Latn
-    {0x866A0000u, 19u}, // ktb -> Ethi
-    {0xB26A0000u, 44u}, // ktm -> Latn
-    {0xBA6A0000u, 44u}, // kto -> Latn
-    {0xC66A0000u, 44u}, // ktr -> Latn
-    {0x6B750000u, 44u}, // ku -> Latn
+    {0x864A0000u, 46u}, // ksb -> Latn
+    {0x8E4A0000u, 46u}, // ksd -> Latn
+    {0x964A0000u, 46u}, // ksf -> Latn
+    {0x9E4A0000u, 46u}, // ksh -> Latn
+    {0xA64A0000u, 46u}, // ksj -> Latn
+    {0xC64A0000u, 46u}, // ksr -> Latn
+    {0x866A0000u, 20u}, // ktb -> Ethi
+    {0xB26A0000u, 46u}, // ktm -> Latn
+    {0xBA6A0000u, 46u}, // kto -> Latn
+    {0xC66A0000u, 46u}, // ktr -> Latn
+    {0x6B750000u, 46u}, // ku -> Latn
     {0x6B754952u,  1u}, // ku-IR -> Arab
     {0x6B754C42u,  1u}, // ku-LB -> Arab
-    {0x868A0000u, 44u}, // kub -> Latn
-    {0x8E8A0000u, 44u}, // kud -> Latn
-    {0x928A0000u, 44u}, // kue -> Latn
-    {0xA68A0000u, 44u}, // kuj -> Latn
-    {0xB28A0000u, 16u}, // kum -> Cyrl
-    {0xB68A0000u, 44u}, // kun -> Latn
-    {0xBE8A0000u, 44u}, // kup -> Latn
-    {0xCA8A0000u, 44u}, // kus -> Latn
-    {0x6B760000u, 16u}, // kv -> Cyrl
-    {0x9AAA0000u, 44u}, // kvg -> Latn
-    {0xC6AA0000u, 44u}, // kvr -> Latn
+    {0x868A0000u, 46u}, // kub -> Latn
+    {0x8E8A0000u, 46u}, // kud -> Latn
+    {0x928A0000u, 46u}, // kue -> Latn
+    {0xA68A0000u, 46u}, // kuj -> Latn
+    {0xB28A0000u, 17u}, // kum -> Cyrl
+    {0xB68A0000u, 46u}, // kun -> Latn
+    {0xBE8A0000u, 46u}, // kup -> Latn
+    {0xCA8A0000u, 46u}, // kus -> Latn
+    {0x6B760000u, 17u}, // kv -> Cyrl
+    {0x9AAA0000u, 46u}, // kvg -> Latn
+    {0xC6AA0000u, 46u}, // kvr -> Latn
     {0xDEAA0000u,  1u}, // kvx -> Arab
-    {0x6B770000u, 44u}, // kw -> Latn
-    {0xA6CA0000u, 44u}, // kwj -> Latn
-    {0xBACA0000u, 44u}, // kwo -> Latn
-    {0xC2CA0000u, 44u}, // kwq -> Latn
-    {0x82EA0000u, 44u}, // kxa -> Latn
-    {0x8AEA0000u, 19u}, // kxc -> Ethi
-    {0x92EA0000u, 44u}, // kxe -> Latn
-    {0xB2EA0000u, 87u}, // kxm -> Thai
+    {0x6B770000u, 46u}, // kw -> Latn
+    {0xA6CA0000u, 46u}, // kwj -> Latn
+    {0xBACA0000u, 46u}, // kwo -> Latn
+    {0xC2CA0000u, 46u}, // kwq -> Latn
+    {0x82EA0000u, 46u}, // kxa -> Latn
+    {0x8AEA0000u, 20u}, // kxc -> Ethi
+    {0x92EA0000u, 46u}, // kxe -> Latn
+    {0xB2EA0000u, 89u}, // kxm -> Thai
     {0xBEEA0000u,  1u}, // kxp -> Arab
-    {0xDAEA0000u, 44u}, // kxw -> Latn
-    {0xE6EA0000u, 44u}, // kxz -> Latn
-    {0x6B790000u, 16u}, // ky -> Cyrl
+    {0xDAEA0000u, 46u}, // kxw -> Latn
+    {0xE6EA0000u, 46u}, // kxz -> Latn
+    {0x6B790000u, 17u}, // ky -> Cyrl
     {0x6B79434Eu,  1u}, // ky-CN -> Arab
-    {0x6B795452u, 44u}, // ky-TR -> Latn
-    {0x930A0000u, 44u}, // kye -> Latn
-    {0xDF0A0000u, 44u}, // kyx -> Latn
-    {0xA72A0000u, 44u}, // kzj -> Latn
-    {0xC72A0000u, 44u}, // kzr -> Latn
-    {0xCF2A0000u, 44u}, // kzt -> Latn
-    {0x6C610000u, 44u}, // la -> Latn
-    {0x840B0000u, 46u}, // lab -> Lina
-    {0x8C0B0000u, 30u}, // lad -> Hebr
-    {0x980B0000u, 44u}, // lag -> Latn
+    {0x6B795452u, 46u}, // ky-TR -> Latn
+    {0x930A0000u, 46u}, // kye -> Latn
+    {0xDF0A0000u, 46u}, // kyx -> Latn
+    {0xA72A0000u, 46u}, // kzj -> Latn
+    {0xC72A0000u, 46u}, // kzr -> Latn
+    {0xCF2A0000u, 46u}, // kzt -> Latn
+    {0x6C610000u, 46u}, // la -> Latn
+    {0x840B0000u, 48u}, // lab -> Lina
+    {0x8C0B0000u, 31u}, // lad -> Hebr
+    {0x980B0000u, 46u}, // lag -> Latn
     {0x9C0B0000u,  1u}, // lah -> Arab
-    {0xA40B0000u, 44u}, // laj -> Latn
-    {0xC80B0000u, 44u}, // las -> Latn
-    {0x6C620000u, 44u}, // lb -> Latn
-    {0x902B0000u, 16u}, // lbe -> Cyrl
-    {0xD02B0000u, 44u}, // lbu -> Latn
-    {0xD82B0000u, 44u}, // lbw -> Latn
-    {0xB04B0000u, 44u}, // lcm -> Latn
-    {0xBC4B0000u, 87u}, // lcp -> Thai
-    {0x846B0000u, 44u}, // ldb -> Latn
-    {0x8C8B0000u, 44u}, // led -> Latn
-    {0x908B0000u, 44u}, // lee -> Latn
-    {0xB08B0000u, 44u}, // lem -> Latn
-    {0xBC8B0000u, 45u}, // lep -> Lepc
-    {0xC08B0000u, 44u}, // leq -> Latn
-    {0xD08B0000u, 44u}, // leu -> Latn
-    {0xE48B0000u, 16u}, // lez -> Cyrl
-    {0x6C670000u, 44u}, // lg -> Latn
-    {0x98CB0000u, 44u}, // lgg -> Latn
-    {0x6C690000u, 44u}, // li -> Latn
-    {0x810B0000u, 44u}, // lia -> Latn
-    {0x8D0B0000u, 44u}, // lid -> Latn
-    {0x950B0000u, 17u}, // lif -> Deva
-    {0x990B0000u, 44u}, // lig -> Latn
-    {0x9D0B0000u, 44u}, // lih -> Latn
-    {0xA50B0000u, 44u}, // lij -> Latn
-    {0xC90B0000u, 47u}, // lis -> Lisu
-    {0xBD2B0000u, 44u}, // ljp -> Latn
+    {0xA40B0000u, 46u}, // laj -> Latn
+    {0xC80B0000u, 46u}, // las -> Latn
+    {0x6C620000u, 46u}, // lb -> Latn
+    {0x902B0000u, 17u}, // lbe -> Cyrl
+    {0xD02B0000u, 46u}, // lbu -> Latn
+    {0xD82B0000u, 46u}, // lbw -> Latn
+    {0xB04B0000u, 46u}, // lcm -> Latn
+    {0xBC4B0000u, 89u}, // lcp -> Thai
+    {0x846B0000u, 46u}, // ldb -> Latn
+    {0x8C8B0000u, 46u}, // led -> Latn
+    {0x908B0000u, 46u}, // lee -> Latn
+    {0xB08B0000u, 46u}, // lem -> Latn
+    {0xBC8B0000u, 47u}, // lep -> Lepc
+    {0xC08B0000u, 46u}, // leq -> Latn
+    {0xD08B0000u, 46u}, // leu -> Latn
+    {0xE48B0000u, 17u}, // lez -> Cyrl
+    {0x6C670000u, 46u}, // lg -> Latn
+    {0x98CB0000u, 46u}, // lgg -> Latn
+    {0x6C690000u, 46u}, // li -> Latn
+    {0x810B0000u, 46u}, // lia -> Latn
+    {0x8D0B0000u, 46u}, // lid -> Latn
+    {0x950B0000u, 18u}, // lif -> Deva
+    {0x990B0000u, 46u}, // lig -> Latn
+    {0x9D0B0000u, 46u}, // lih -> Latn
+    {0xA50B0000u, 46u}, // lij -> Latn
+    {0xC90B0000u, 49u}, // lis -> Lisu
+    {0xBD2B0000u, 46u}, // ljp -> Latn
     {0xA14B0000u,  1u}, // lki -> Arab
-    {0xCD4B0000u, 44u}, // lkt -> Latn
-    {0x916B0000u, 44u}, // lle -> Latn
-    {0xB56B0000u, 44u}, // lln -> Latn
-    {0xB58B0000u, 84u}, // lmn -> Telu
-    {0xB98B0000u, 44u}, // lmo -> Latn
-    {0xBD8B0000u, 44u}, // lmp -> Latn
-    {0x6C6E0000u, 44u}, // ln -> Latn
-    {0xC9AB0000u, 44u}, // lns -> Latn
-    {0xD1AB0000u, 44u}, // lnu -> Latn
-    {0x6C6F0000u, 43u}, // lo -> Laoo
-    {0xA5CB0000u, 44u}, // loj -> Latn
-    {0xA9CB0000u, 44u}, // lok -> Latn
-    {0xADCB0000u, 44u}, // lol -> Latn
-    {0xC5CB0000u, 44u}, // lor -> Latn
-    {0xC9CB0000u, 44u}, // los -> Latn
-    {0xE5CB0000u, 44u}, // loz -> Latn
+    {0xCD4B0000u, 46u}, // lkt -> Latn
+    {0x916B0000u, 46u}, // lle -> Latn
+    {0xB56B0000u, 46u}, // lln -> Latn
+    {0xB58B0000u, 86u}, // lmn -> Telu
+    {0xB98B0000u, 46u}, // lmo -> Latn
+    {0xBD8B0000u, 46u}, // lmp -> Latn
+    {0x6C6E0000u, 46u}, // ln -> Latn
+    {0xC9AB0000u, 46u}, // lns -> Latn
+    {0xD1AB0000u, 46u}, // lnu -> Latn
+    {0x6C6F0000u, 45u}, // lo -> Laoo
+    {0xA5CB0000u, 46u}, // loj -> Latn
+    {0xA9CB0000u, 46u}, // lok -> Latn
+    {0xADCB0000u, 46u}, // lol -> Latn
+    {0xC5CB0000u, 46u}, // lor -> Latn
+    {0xC9CB0000u, 46u}, // los -> Latn
+    {0xE5CB0000u, 46u}, // loz -> Latn
     {0x8A2B0000u,  1u}, // lrc -> Arab
-    {0x6C740000u, 44u}, // lt -> Latn
-    {0x9A6B0000u, 44u}, // ltg -> Latn
-    {0x6C750000u, 44u}, // lu -> Latn
-    {0x828B0000u, 44u}, // lua -> Latn
-    {0xBA8B0000u, 44u}, // luo -> Latn
-    {0xE28B0000u, 44u}, // luy -> Latn
+    {0x6C740000u, 46u}, // lt -> Latn
+    {0x9A6B0000u, 46u}, // ltg -> Latn
+    {0x6C750000u, 46u}, // lu -> Latn
+    {0x828B0000u, 46u}, // lua -> Latn
+    {0xBA8B0000u, 46u}, // luo -> Latn
+    {0xE28B0000u, 46u}, // luy -> Latn
     {0xE68B0000u,  1u}, // luz -> Arab
-    {0x6C760000u, 44u}, // lv -> Latn
-    {0xAECB0000u, 87u}, // lwl -> Thai
-    {0x9F2B0000u, 27u}, // lzh -> Hans
-    {0xE72B0000u, 44u}, // lzz -> Latn
-    {0x8C0C0000u, 44u}, // mad -> Latn
-    {0x940C0000u, 44u}, // maf -> Latn
-    {0x980C0000u, 17u}, // mag -> Deva
-    {0xA00C0000u, 17u}, // mai -> Deva
-    {0xA80C0000u, 44u}, // mak -> Latn
-    {0xB40C0000u, 44u}, // man -> Latn
-    {0xB40C474Eu, 58u}, // man-GN -> Nkoo
-    {0xC80C0000u, 44u}, // mas -> Latn
-    {0xD80C0000u, 44u}, // maw -> Latn
-    {0xE40C0000u, 44u}, // maz -> Latn
-    {0x9C2C0000u, 44u}, // mbh -> Latn
-    {0xB82C0000u, 44u}, // mbo -> Latn
-    {0xC02C0000u, 44u}, // mbq -> Latn
-    {0xD02C0000u, 44u}, // mbu -> Latn
-    {0xD82C0000u, 44u}, // mbw -> Latn
-    {0xA04C0000u, 44u}, // mci -> Latn
-    {0xBC4C0000u, 44u}, // mcp -> Latn
-    {0xC04C0000u, 44u}, // mcq -> Latn
-    {0xC44C0000u, 44u}, // mcr -> Latn
-    {0xD04C0000u, 44u}, // mcu -> Latn
-    {0x806C0000u, 44u}, // mda -> Latn
+    {0x6C760000u, 46u}, // lv -> Latn
+    {0xAECB0000u, 89u}, // lwl -> Thai
+    {0x9F2B0000u, 28u}, // lzh -> Hans
+    {0xE72B0000u, 46u}, // lzz -> Latn
+    {0x8C0C0000u, 46u}, // mad -> Latn
+    {0x940C0000u, 46u}, // maf -> Latn
+    {0x980C0000u, 18u}, // mag -> Deva
+    {0xA00C0000u, 18u}, // mai -> Deva
+    {0xA80C0000u, 46u}, // mak -> Latn
+    {0xB40C0000u, 46u}, // man -> Latn
+    {0xB40C474Eu, 60u}, // man-GN -> Nkoo
+    {0xC80C0000u, 46u}, // mas -> Latn
+    {0xD80C0000u, 46u}, // maw -> Latn
+    {0xE40C0000u, 46u}, // maz -> Latn
+    {0x9C2C0000u, 46u}, // mbh -> Latn
+    {0xB82C0000u, 46u}, // mbo -> Latn
+    {0xC02C0000u, 46u}, // mbq -> Latn
+    {0xD02C0000u, 46u}, // mbu -> Latn
+    {0xD82C0000u, 46u}, // mbw -> Latn
+    {0xA04C0000u, 46u}, // mci -> Latn
+    {0xBC4C0000u, 46u}, // mcp -> Latn
+    {0xC04C0000u, 46u}, // mcq -> Latn
+    {0xC44C0000u, 46u}, // mcr -> Latn
+    {0xD04C0000u, 46u}, // mcu -> Latn
+    {0x806C0000u, 46u}, // mda -> Latn
     {0x906C0000u,  1u}, // mde -> Arab
-    {0x946C0000u, 16u}, // mdf -> Cyrl
-    {0x9C6C0000u, 44u}, // mdh -> Latn
-    {0xA46C0000u, 44u}, // mdj -> Latn
-    {0xC46C0000u, 44u}, // mdr -> Latn
-    {0xDC6C0000u, 19u}, // mdx -> Ethi
-    {0x8C8C0000u, 44u}, // med -> Latn
-    {0x908C0000u, 44u}, // mee -> Latn
-    {0xA88C0000u, 44u}, // mek -> Latn
-    {0xB48C0000u, 44u}, // men -> Latn
-    {0xC48C0000u, 44u}, // mer -> Latn
-    {0xCC8C0000u, 44u}, // met -> Latn
-    {0xD08C0000u, 44u}, // meu -> Latn
+    {0x946C0000u, 17u}, // mdf -> Cyrl
+    {0x9C6C0000u, 46u}, // mdh -> Latn
+    {0xA46C0000u, 46u}, // mdj -> Latn
+    {0xC46C0000u, 46u}, // mdr -> Latn
+    {0xDC6C0000u, 20u}, // mdx -> Ethi
+    {0x8C8C0000u, 46u}, // med -> Latn
+    {0x908C0000u, 46u}, // mee -> Latn
+    {0xA88C0000u, 46u}, // mek -> Latn
+    {0xB48C0000u, 46u}, // men -> Latn
+    {0xC48C0000u, 46u}, // mer -> Latn
+    {0xCC8C0000u, 46u}, // met -> Latn
+    {0xD08C0000u, 46u}, // meu -> Latn
     {0x80AC0000u,  1u}, // mfa -> Arab
-    {0x90AC0000u, 44u}, // mfe -> Latn
-    {0xB4AC0000u, 44u}, // mfn -> Latn
-    {0xB8AC0000u, 44u}, // mfo -> Latn
-    {0xC0AC0000u, 44u}, // mfq -> Latn
-    {0x6D670000u, 44u}, // mg -> Latn
-    {0x9CCC0000u, 44u}, // mgh -> Latn
-    {0xACCC0000u, 44u}, // mgl -> Latn
-    {0xB8CC0000u, 44u}, // mgo -> Latn
-    {0xBCCC0000u, 17u}, // mgp -> Deva
-    {0xE0CC0000u, 44u}, // mgy -> Latn
-    {0x6D680000u, 44u}, // mh -> Latn
-    {0xA0EC0000u, 44u}, // mhi -> Latn
-    {0xACEC0000u, 44u}, // mhl -> Latn
-    {0x6D690000u, 44u}, // mi -> Latn
-    {0x950C0000u, 44u}, // mif -> Latn
-    {0xB50C0000u, 44u}, // min -> Latn
-    {0xC90C0000u, 29u}, // mis -> Hatr
-    {0xD90C0000u, 44u}, // miw -> Latn
-    {0x6D6B0000u, 16u}, // mk -> Cyrl
+    {0x90AC0000u, 46u}, // mfe -> Latn
+    {0xB4AC0000u, 46u}, // mfn -> Latn
+    {0xB8AC0000u, 46u}, // mfo -> Latn
+    {0xC0AC0000u, 46u}, // mfq -> Latn
+    {0x6D670000u, 46u}, // mg -> Latn
+    {0x9CCC0000u, 46u}, // mgh -> Latn
+    {0xACCC0000u, 46u}, // mgl -> Latn
+    {0xB8CC0000u, 46u}, // mgo -> Latn
+    {0xBCCC0000u, 18u}, // mgp -> Deva
+    {0xE0CC0000u, 46u}, // mgy -> Latn
+    {0x6D680000u, 46u}, // mh -> Latn
+    {0xA0EC0000u, 46u}, // mhi -> Latn
+    {0xACEC0000u, 46u}, // mhl -> Latn
+    {0x6D690000u, 46u}, // mi -> Latn
+    {0x950C0000u, 46u}, // mif -> Latn
+    {0xB50C0000u, 46u}, // min -> Latn
+    {0xC90C0000u, 30u}, // mis -> Hatr
+    {0xD90C0000u, 46u}, // miw -> Latn
+    {0x6D6B0000u, 17u}, // mk -> Cyrl
     {0xA14C0000u,  1u}, // mki -> Arab
-    {0xAD4C0000u, 44u}, // mkl -> Latn
-    {0xBD4C0000u, 44u}, // mkp -> Latn
-    {0xD94C0000u, 44u}, // mkw -> Latn
-    {0x6D6C0000u, 53u}, // ml -> Mlym
-    {0x916C0000u, 44u}, // mle -> Latn
-    {0xBD6C0000u, 44u}, // mlp -> Latn
-    {0xC96C0000u, 44u}, // mls -> Latn
-    {0xB98C0000u, 44u}, // mmo -> Latn
-    {0xD18C0000u, 44u}, // mmu -> Latn
-    {0xDD8C0000u, 44u}, // mmx -> Latn
-    {0x6D6E0000u, 16u}, // mn -> Cyrl
-    {0x6D6E434Eu, 54u}, // mn-CN -> Mong
-    {0x81AC0000u, 44u}, // mna -> Latn
-    {0x95AC0000u, 44u}, // mnf -> Latn
+    {0xAD4C0000u, 46u}, // mkl -> Latn
+    {0xBD4C0000u, 46u}, // mkp -> Latn
+    {0xD94C0000u, 46u}, // mkw -> Latn
+    {0x6D6C0000u, 55u}, // ml -> Mlym
+    {0x916C0000u, 46u}, // mle -> Latn
+    {0xBD6C0000u, 46u}, // mlp -> Latn
+    {0xC96C0000u, 46u}, // mls -> Latn
+    {0xB98C0000u, 46u}, // mmo -> Latn
+    {0xD18C0000u, 46u}, // mmu -> Latn
+    {0xDD8C0000u, 46u}, // mmx -> Latn
+    {0x6D6E0000u, 17u}, // mn -> Cyrl
+    {0x6D6E434Eu, 56u}, // mn-CN -> Mong
+    {0x81AC0000u, 46u}, // mna -> Latn
+    {0x95AC0000u, 46u}, // mnf -> Latn
     {0xA1AC0000u,  7u}, // mni -> Beng
-    {0xD9AC0000u, 56u}, // mnw -> Mymr
-    {0x6D6F0000u, 44u}, // mo -> Latn
-    {0x81CC0000u, 44u}, // moa -> Latn
-    {0x91CC0000u, 44u}, // moe -> Latn
-    {0x9DCC0000u, 44u}, // moh -> Latn
-    {0xC9CC0000u, 44u}, // mos -> Latn
-    {0xDDCC0000u, 44u}, // mox -> Latn
-    {0xBDEC0000u, 44u}, // mpp -> Latn
-    {0xC9EC0000u, 44u}, // mps -> Latn
-    {0xCDEC0000u, 44u}, // mpt -> Latn
-    {0xDDEC0000u, 44u}, // mpx -> Latn
-    {0xAE0C0000u, 44u}, // mql -> Latn
-    {0x6D720000u, 17u}, // mr -> Deva
-    {0x8E2C0000u, 17u}, // mrd -> Deva
-    {0xA62C0000u, 16u}, // mrj -> Cyrl
-    {0xBA2C0000u, 55u}, // mro -> Mroo
-    {0x6D730000u, 44u}, // ms -> Latn
+    {0xD9AC0000u, 58u}, // mnw -> Mymr
+    {0x6D6F0000u, 46u}, // mo -> Latn
+    {0x81CC0000u, 46u}, // moa -> Latn
+    {0x91CC0000u, 46u}, // moe -> Latn
+    {0x9DCC0000u, 46u}, // moh -> Latn
+    {0xC9CC0000u, 46u}, // mos -> Latn
+    {0xDDCC0000u, 46u}, // mox -> Latn
+    {0xBDEC0000u, 46u}, // mpp -> Latn
+    {0xC9EC0000u, 46u}, // mps -> Latn
+    {0xCDEC0000u, 46u}, // mpt -> Latn
+    {0xDDEC0000u, 46u}, // mpx -> Latn
+    {0xAE0C0000u, 46u}, // mql -> Latn
+    {0x6D720000u, 18u}, // mr -> Deva
+    {0x8E2C0000u, 18u}, // mrd -> Deva
+    {0xA62C0000u, 17u}, // mrj -> Cyrl
+    {0xBA2C0000u, 57u}, // mro -> Mroo
+    {0x6D730000u, 46u}, // ms -> Latn
     {0x6D734343u,  1u}, // ms-CC -> Arab
     {0x6D734944u,  1u}, // ms-ID -> Arab
-    {0x6D740000u, 44u}, // mt -> Latn
-    {0x8A6C0000u, 44u}, // mtc -> Latn
-    {0x966C0000u, 44u}, // mtf -> Latn
-    {0xA26C0000u, 44u}, // mti -> Latn
-    {0xC66C0000u, 17u}, // mtr -> Deva
-    {0x828C0000u, 44u}, // mua -> Latn
-    {0xC68C0000u, 44u}, // mur -> Latn
-    {0xCA8C0000u, 44u}, // mus -> Latn
-    {0x82AC0000u, 44u}, // mva -> Latn
-    {0xB6AC0000u, 44u}, // mvn -> Latn
+    {0x6D740000u, 46u}, // mt -> Latn
+    {0x8A6C0000u, 46u}, // mtc -> Latn
+    {0x966C0000u, 46u}, // mtf -> Latn
+    {0xA26C0000u, 46u}, // mti -> Latn
+    {0xC66C0000u, 18u}, // mtr -> Deva
+    {0x828C0000u, 46u}, // mua -> Latn
+    {0xC68C0000u, 46u}, // mur -> Latn
+    {0xCA8C0000u, 46u}, // mus -> Latn
+    {0x82AC0000u, 46u}, // mva -> Latn
+    {0xB6AC0000u, 46u}, // mvn -> Latn
     {0xE2AC0000u,  1u}, // mvy -> Arab
-    {0xAACC0000u, 44u}, // mwk -> Latn
-    {0xC6CC0000u, 17u}, // mwr -> Deva
-    {0xD6CC0000u, 44u}, // mwv -> Latn
-    {0xDACC0000u, 33u}, // mww -> Hmnp
-    {0x8AEC0000u, 44u}, // mxc -> Latn
-    {0xB2EC0000u, 44u}, // mxm -> Latn
-    {0x6D790000u, 56u}, // my -> Mymr
-    {0xAB0C0000u, 44u}, // myk -> Latn
-    {0xB30C0000u, 19u}, // mym -> Ethi
-    {0xD70C0000u, 16u}, // myv -> Cyrl
-    {0xDB0C0000u, 44u}, // myw -> Latn
-    {0xDF0C0000u, 44u}, // myx -> Latn
-    {0xE70C0000u, 50u}, // myz -> Mand
-    {0xAB2C0000u, 44u}, // mzk -> Latn
-    {0xB32C0000u, 44u}, // mzm -> Latn
+    {0xAACC0000u, 46u}, // mwk -> Latn
+    {0xC6CC0000u, 18u}, // mwr -> Deva
+    {0xD6CC0000u, 46u}, // mwv -> Latn
+    {0xDACC0000u, 34u}, // mww -> Hmnp
+    {0x8AEC0000u, 46u}, // mxc -> Latn
+    {0xB2EC0000u, 46u}, // mxm -> Latn
+    {0x6D790000u, 58u}, // my -> Mymr
+    {0xAB0C0000u, 46u}, // myk -> Latn
+    {0xB30C0000u, 20u}, // mym -> Ethi
+    {0xD70C0000u, 17u}, // myv -> Cyrl
+    {0xDB0C0000u, 46u}, // myw -> Latn
+    {0xDF0C0000u, 46u}, // myx -> Latn
+    {0xE70C0000u, 52u}, // myz -> Mand
+    {0xAB2C0000u, 46u}, // mzk -> Latn
+    {0xB32C0000u, 46u}, // mzm -> Latn
     {0xB72C0000u,  1u}, // mzn -> Arab
-    {0xBF2C0000u, 44u}, // mzp -> Latn
-    {0xDB2C0000u, 44u}, // mzw -> Latn
-    {0xE72C0000u, 44u}, // mzz -> Latn
-    {0x6E610000u, 44u}, // na -> Latn
-    {0x880D0000u, 44u}, // nac -> Latn
-    {0x940D0000u, 44u}, // naf -> Latn
-    {0xA80D0000u, 44u}, // nak -> Latn
-    {0xB40D0000u, 27u}, // nan -> Hans
-    {0xBC0D0000u, 44u}, // nap -> Latn
-    {0xC00D0000u, 44u}, // naq -> Latn
-    {0xC80D0000u, 44u}, // nas -> Latn
-    {0x6E620000u, 44u}, // nb -> Latn
-    {0x804D0000u, 44u}, // nca -> Latn
-    {0x904D0000u, 44u}, // nce -> Latn
-    {0x944D0000u, 44u}, // ncf -> Latn
-    {0x9C4D0000u, 44u}, // nch -> Latn
-    {0xB84D0000u, 44u}, // nco -> Latn
-    {0xD04D0000u, 44u}, // ncu -> Latn
-    {0x6E640000u, 44u}, // nd -> Latn
-    {0x886D0000u, 44u}, // ndc -> Latn
-    {0xC86D0000u, 44u}, // nds -> Latn
-    {0x6E650000u, 17u}, // ne -> Deva
-    {0x848D0000u, 44u}, // neb -> Latn
-    {0xD88D0000u, 17u}, // new -> Deva
-    {0xDC8D0000u, 44u}, // nex -> Latn
-    {0xC4AD0000u, 44u}, // nfr -> Latn
-    {0x6E670000u, 44u}, // ng -> Latn
-    {0x80CD0000u, 44u}, // nga -> Latn
-    {0x84CD0000u, 44u}, // ngb -> Latn
-    {0xACCD0000u, 44u}, // ngl -> Latn
-    {0x84ED0000u, 44u}, // nhb -> Latn
-    {0x90ED0000u, 44u}, // nhe -> Latn
-    {0xD8ED0000u, 44u}, // nhw -> Latn
-    {0x950D0000u, 44u}, // nif -> Latn
-    {0xA10D0000u, 44u}, // nii -> Latn
-    {0xA50D0000u, 44u}, // nij -> Latn
-    {0xB50D0000u, 44u}, // nin -> Latn
-    {0xD10D0000u, 44u}, // niu -> Latn
-    {0xE10D0000u, 44u}, // niy -> Latn
-    {0xE50D0000u, 44u}, // niz -> Latn
-    {0xB92D0000u, 44u}, // njo -> Latn
-    {0x994D0000u, 44u}, // nkg -> Latn
-    {0xB94D0000u, 44u}, // nko -> Latn
-    {0x6E6C0000u, 44u}, // nl -> Latn
-    {0x998D0000u, 44u}, // nmg -> Latn
-    {0xE58D0000u, 44u}, // nmz -> Latn
-    {0x6E6E0000u, 44u}, // nn -> Latn
-    {0x95AD0000u, 44u}, // nnf -> Latn
-    {0x9DAD0000u, 44u}, // nnh -> Latn
-    {0xA9AD0000u, 44u}, // nnk -> Latn
-    {0xB1AD0000u, 44u}, // nnm -> Latn
-    {0xBDAD0000u, 91u}, // nnp -> Wcho
-    {0x6E6F0000u, 44u}, // no -> Latn
-    {0x8DCD0000u, 42u}, // nod -> Lana
-    {0x91CD0000u, 17u}, // noe -> Deva
-    {0xB5CD0000u, 69u}, // non -> Runr
-    {0xBDCD0000u, 44u}, // nop -> Latn
-    {0xD1CD0000u, 44u}, // nou -> Latn
-    {0xBA0D0000u, 58u}, // nqo -> Nkoo
-    {0x6E720000u, 44u}, // nr -> Latn
-    {0x862D0000u, 44u}, // nrb -> Latn
+    {0xBF2C0000u, 46u}, // mzp -> Latn
+    {0xDB2C0000u, 46u}, // mzw -> Latn
+    {0xE72C0000u, 46u}, // mzz -> Latn
+    {0x6E610000u, 46u}, // na -> Latn
+    {0x880D0000u, 46u}, // nac -> Latn
+    {0x940D0000u, 46u}, // naf -> Latn
+    {0xA80D0000u, 46u}, // nak -> Latn
+    {0xB40D0000u, 28u}, // nan -> Hans
+    {0xBC0D0000u, 46u}, // nap -> Latn
+    {0xC00D0000u, 46u}, // naq -> Latn
+    {0xC80D0000u, 46u}, // nas -> Latn
+    {0x6E620000u, 46u}, // nb -> Latn
+    {0x804D0000u, 46u}, // nca -> Latn
+    {0x904D0000u, 46u}, // nce -> Latn
+    {0x944D0000u, 46u}, // ncf -> Latn
+    {0x9C4D0000u, 46u}, // nch -> Latn
+    {0xB84D0000u, 46u}, // nco -> Latn
+    {0xD04D0000u, 46u}, // ncu -> Latn
+    {0x6E640000u, 46u}, // nd -> Latn
+    {0x886D0000u, 46u}, // ndc -> Latn
+    {0xC86D0000u, 46u}, // nds -> Latn
+    {0x6E650000u, 18u}, // ne -> Deva
+    {0x848D0000u, 46u}, // neb -> Latn
+    {0xD88D0000u, 18u}, // new -> Deva
+    {0xDC8D0000u, 46u}, // nex -> Latn
+    {0xC4AD0000u, 46u}, // nfr -> Latn
+    {0x6E670000u, 46u}, // ng -> Latn
+    {0x80CD0000u, 46u}, // nga -> Latn
+    {0x84CD0000u, 46u}, // ngb -> Latn
+    {0xACCD0000u, 46u}, // ngl -> Latn
+    {0x84ED0000u, 46u}, // nhb -> Latn
+    {0x90ED0000u, 46u}, // nhe -> Latn
+    {0xD8ED0000u, 46u}, // nhw -> Latn
+    {0x950D0000u, 46u}, // nif -> Latn
+    {0xA10D0000u, 46u}, // nii -> Latn
+    {0xA50D0000u, 46u}, // nij -> Latn
+    {0xB50D0000u, 46u}, // nin -> Latn
+    {0xD10D0000u, 46u}, // niu -> Latn
+    {0xE10D0000u, 46u}, // niy -> Latn
+    {0xE50D0000u, 46u}, // niz -> Latn
+    {0xB92D0000u, 46u}, // njo -> Latn
+    {0x994D0000u, 46u}, // nkg -> Latn
+    {0xB94D0000u, 46u}, // nko -> Latn
+    {0x6E6C0000u, 46u}, // nl -> Latn
+    {0x998D0000u, 46u}, // nmg -> Latn
+    {0xE58D0000u, 46u}, // nmz -> Latn
+    {0x6E6E0000u, 46u}, // nn -> Latn
+    {0x95AD0000u, 46u}, // nnf -> Latn
+    {0x9DAD0000u, 46u}, // nnh -> Latn
+    {0xA9AD0000u, 46u}, // nnk -> Latn
+    {0xB1AD0000u, 46u}, // nnm -> Latn
+    {0xBDAD0000u, 93u}, // nnp -> Wcho
+    {0x6E6F0000u, 46u}, // no -> Latn
+    {0x8DCD0000u, 44u}, // nod -> Lana
+    {0x91CD0000u, 18u}, // noe -> Deva
+    {0xB5CD0000u, 71u}, // non -> Runr
+    {0xBDCD0000u, 46u}, // nop -> Latn
+    {0xD1CD0000u, 46u}, // nou -> Latn
+    {0xBA0D0000u, 60u}, // nqo -> Nkoo
+    {0x6E720000u, 46u}, // nr -> Latn
+    {0x862D0000u, 46u}, // nrb -> Latn
     {0xAA4D0000u, 10u}, // nsk -> Cans
-    {0xB64D0000u, 44u}, // nsn -> Latn
-    {0xBA4D0000u, 44u}, // nso -> Latn
-    {0xCA4D0000u, 44u}, // nss -> Latn
-    {0xB26D0000u, 44u}, // ntm -> Latn
-    {0xC66D0000u, 44u}, // ntr -> Latn
-    {0xA28D0000u, 44u}, // nui -> Latn
-    {0xBE8D0000u, 44u}, // nup -> Latn
-    {0xCA8D0000u, 44u}, // nus -> Latn
-    {0xD68D0000u, 44u}, // nuv -> Latn
-    {0xDE8D0000u, 44u}, // nux -> Latn
-    {0x6E760000u, 44u}, // nv -> Latn
-    {0x86CD0000u, 44u}, // nwb -> Latn
-    {0xC2ED0000u, 44u}, // nxq -> Latn
-    {0xC6ED0000u, 44u}, // nxr -> Latn
-    {0x6E790000u, 44u}, // ny -> Latn
-    {0xB30D0000u, 44u}, // nym -> Latn
-    {0xB70D0000u, 44u}, // nyn -> Latn
-    {0xA32D0000u, 44u}, // nzi -> Latn
-    {0x6F630000u, 44u}, // oc -> Latn
-    {0x88CE0000u, 44u}, // ogc -> Latn
-    {0xC54E0000u, 44u}, // okr -> Latn
-    {0xD54E0000u, 44u}, // okv -> Latn
-    {0x6F6D0000u, 44u}, // om -> Latn
-    {0x99AE0000u, 44u}, // ong -> Latn
-    {0xB5AE0000u, 44u}, // onn -> Latn
-    {0xC9AE0000u, 44u}, // ons -> Latn
-    {0xB1EE0000u, 44u}, // opm -> Latn
-    {0x6F720000u, 62u}, // or -> Orya
-    {0xBA2E0000u, 44u}, // oro -> Latn
+    {0xB64D0000u, 46u}, // nsn -> Latn
+    {0xBA4D0000u, 46u}, // nso -> Latn
+    {0xCA4D0000u, 46u}, // nss -> Latn
+    {0xB26D0000u, 46u}, // ntm -> Latn
+    {0xC66D0000u, 46u}, // ntr -> Latn
+    {0xA28D0000u, 46u}, // nui -> Latn
+    {0xBE8D0000u, 46u}, // nup -> Latn
+    {0xCA8D0000u, 46u}, // nus -> Latn
+    {0xD68D0000u, 46u}, // nuv -> Latn
+    {0xDE8D0000u, 46u}, // nux -> Latn
+    {0x6E760000u, 46u}, // nv -> Latn
+    {0x86CD0000u, 46u}, // nwb -> Latn
+    {0xC2ED0000u, 46u}, // nxq -> Latn
+    {0xC6ED0000u, 46u}, // nxr -> Latn
+    {0x6E790000u, 46u}, // ny -> Latn
+    {0xB30D0000u, 46u}, // nym -> Latn
+    {0xB70D0000u, 46u}, // nyn -> Latn
+    {0xA32D0000u, 46u}, // nzi -> Latn
+    {0x6F630000u, 46u}, // oc -> Latn
+    {0x88CE0000u, 46u}, // ogc -> Latn
+    {0xC54E0000u, 46u}, // okr -> Latn
+    {0xD54E0000u, 46u}, // okv -> Latn
+    {0x6F6D0000u, 46u}, // om -> Latn
+    {0x99AE0000u, 46u}, // ong -> Latn
+    {0xB5AE0000u, 46u}, // onn -> Latn
+    {0xC9AE0000u, 46u}, // ons -> Latn
+    {0xB1EE0000u, 46u}, // opm -> Latn
+    {0x6F720000u, 64u}, // or -> Orya
+    {0xBA2E0000u, 46u}, // oro -> Latn
     {0xD22E0000u,  1u}, // oru -> Arab
-    {0x6F730000u, 16u}, // os -> Cyrl
-    {0x824E0000u, 63u}, // osa -> Osge
+    {0x6F730000u, 17u}, // os -> Cyrl
+    {0x824E0000u, 65u}, // osa -> Osge
     {0x826E0000u,  1u}, // ota -> Arab
-    {0xAA6E0000u, 61u}, // otk -> Orkh
-    {0xB32E0000u, 44u}, // ozm -> Latn
-    {0x70610000u, 26u}, // pa -> Guru
+    {0xAA6E0000u, 63u}, // otk -> Orkh
+    {0xB32E0000u, 46u}, // ozm -> Latn
+    {0x70610000u, 27u}, // pa -> Guru
     {0x7061504Bu,  1u}, // pa-PK -> Arab
-    {0x980F0000u, 44u}, // pag -> Latn
-    {0xAC0F0000u, 65u}, // pal -> Phli
-    {0xB00F0000u, 44u}, // pam -> Latn
-    {0xBC0F0000u, 44u}, // pap -> Latn
-    {0xD00F0000u, 44u}, // pau -> Latn
-    {0xA02F0000u, 44u}, // pbi -> Latn
-    {0x8C4F0000u, 44u}, // pcd -> Latn
-    {0xB04F0000u, 44u}, // pcm -> Latn
-    {0x886F0000u, 44u}, // pdc -> Latn
-    {0xCC6F0000u, 44u}, // pdt -> Latn
-    {0x8C8F0000u, 44u}, // ped -> Latn
-    {0xB88F0000u, 92u}, // peo -> Xpeo
-    {0xDC8F0000u, 44u}, // pex -> Latn
-    {0xACAF0000u, 44u}, // pfl -> Latn
+    {0x980F0000u, 46u}, // pag -> Latn
+    {0xAC0F0000u, 67u}, // pal -> Phli
+    {0xB00F0000u, 46u}, // pam -> Latn
+    {0xBC0F0000u, 46u}, // pap -> Latn
+    {0xD00F0000u, 46u}, // pau -> Latn
+    {0xA02F0000u, 46u}, // pbi -> Latn
+    {0x8C4F0000u, 46u}, // pcd -> Latn
+    {0xB04F0000u, 46u}, // pcm -> Latn
+    {0x886F0000u, 46u}, // pdc -> Latn
+    {0xCC6F0000u, 46u}, // pdt -> Latn
+    {0x8C8F0000u, 46u}, // ped -> Latn
+    {0xB88F0000u, 94u}, // peo -> Xpeo
+    {0xDC8F0000u, 46u}, // pex -> Latn
+    {0xACAF0000u, 46u}, // pfl -> Latn
     {0xACEF0000u,  1u}, // phl -> Arab
-    {0xB4EF0000u, 66u}, // phn -> Phnx
-    {0xAD0F0000u, 44u}, // pil -> Latn
-    {0xBD0F0000u, 44u}, // pip -> Latn
+    {0xB4EF0000u, 68u}, // phn -> Phnx
+    {0xAD0F0000u, 46u}, // pil -> Latn
+    {0xBD0F0000u, 46u}, // pip -> Latn
     {0x814F0000u,  8u}, // pka -> Brah
-    {0xB94F0000u, 44u}, // pko -> Latn
-    {0x706C0000u, 44u}, // pl -> Latn
-    {0x816F0000u, 44u}, // pla -> Latn
-    {0xC98F0000u, 44u}, // pms -> Latn
-    {0x99AF0000u, 44u}, // png -> Latn
-    {0xB5AF0000u, 44u}, // pnn -> Latn
-    {0xCDAF0000u, 24u}, // pnt -> Grek
-    {0xB5CF0000u, 44u}, // pon -> Latn
-    {0x81EF0000u, 17u}, // ppa -> Deva
-    {0xB9EF0000u, 44u}, // ppo -> Latn
-    {0x822F0000u, 38u}, // pra -> Khar
+    {0xB94F0000u, 46u}, // pko -> Latn
+    {0x706C0000u, 46u}, // pl -> Latn
+    {0x816F0000u, 46u}, // pla -> Latn
+    {0xC98F0000u, 46u}, // pms -> Latn
+    {0x99AF0000u, 46u}, // png -> Latn
+    {0xB5AF0000u, 46u}, // pnn -> Latn
+    {0xCDAF0000u, 25u}, // pnt -> Grek
+    {0xB5CF0000u, 46u}, // pon -> Latn
+    {0x81EF0000u, 18u}, // ppa -> Deva
+    {0xB9EF0000u, 46u}, // ppo -> Latn
+    {0x822F0000u, 39u}, // pra -> Khar
     {0x8E2F0000u,  1u}, // prd -> Arab
-    {0x9A2F0000u, 44u}, // prg -> Latn
+    {0x9A2F0000u, 46u}, // prg -> Latn
     {0x70730000u,  1u}, // ps -> Arab
-    {0xCA4F0000u, 44u}, // pss -> Latn
-    {0x70740000u, 44u}, // pt -> Latn
-    {0xBE6F0000u, 44u}, // ptp -> Latn
-    {0xD28F0000u, 44u}, // puu -> Latn
-    {0x82CF0000u, 44u}, // pwa -> Latn
-    {0x71750000u, 44u}, // qu -> Latn
-    {0x8A900000u, 44u}, // quc -> Latn
-    {0x9A900000u, 44u}, // qug -> Latn
-    {0xA0110000u, 44u}, // rai -> Latn
-    {0xA4110000u, 17u}, // raj -> Deva
-    {0xB8110000u, 44u}, // rao -> Latn
-    {0x94510000u, 44u}, // rcf -> Latn
-    {0xA4910000u, 44u}, // rej -> Latn
-    {0xAC910000u, 44u}, // rel -> Latn
-    {0xC8910000u, 44u}, // res -> Latn
-    {0xB4D10000u, 44u}, // rgn -> Latn
+    {0xCA4F0000u, 46u}, // pss -> Latn
+    {0x70740000u, 46u}, // pt -> Latn
+    {0xBE6F0000u, 46u}, // ptp -> Latn
+    {0xD28F0000u, 46u}, // puu -> Latn
+    {0x82CF0000u, 46u}, // pwa -> Latn
+    {0x71750000u, 46u}, // qu -> Latn
+    {0x8A900000u, 46u}, // quc -> Latn
+    {0x9A900000u, 46u}, // qug -> Latn
+    {0xA0110000u, 46u}, // rai -> Latn
+    {0xA4110000u, 18u}, // raj -> Deva
+    {0xB8110000u, 46u}, // rao -> Latn
+    {0x94510000u, 46u}, // rcf -> Latn
+    {0xA4910000u, 46u}, // rej -> Latn
+    {0xAC910000u, 46u}, // rel -> Latn
+    {0xC8910000u, 46u}, // res -> Latn
+    {0xB4D10000u, 46u}, // rgn -> Latn
     {0x98F10000u,  1u}, // rhg -> Arab
-    {0x81110000u, 44u}, // ria -> Latn
-    {0x95110000u, 85u}, // rif -> Tfng
-    {0x95114E4Cu, 44u}, // rif-NL -> Latn
-    {0xC9310000u, 17u}, // rjs -> Deva
+    {0x81110000u, 46u}, // ria -> Latn
+    {0x95110000u, 87u}, // rif -> Tfng
+    {0x95114E4Cu, 46u}, // rif-NL -> Latn
+    {0xC9310000u, 18u}, // rjs -> Deva
     {0xCD510000u,  7u}, // rkt -> Beng
-    {0x726D0000u, 44u}, // rm -> Latn
-    {0x95910000u, 44u}, // rmf -> Latn
-    {0xB9910000u, 44u}, // rmo -> Latn
+    {0x726D0000u, 46u}, // rm -> Latn
+    {0x95910000u, 46u}, // rmf -> Latn
+    {0xB9910000u, 46u}, // rmo -> Latn
     {0xCD910000u,  1u}, // rmt -> Arab
-    {0xD1910000u, 44u}, // rmu -> Latn
-    {0x726E0000u, 44u}, // rn -> Latn
-    {0x81B10000u, 44u}, // rna -> Latn
-    {0x99B10000u, 44u}, // rng -> Latn
-    {0x726F0000u, 44u}, // ro -> Latn
-    {0x85D10000u, 44u}, // rob -> Latn
-    {0x95D10000u, 44u}, // rof -> Latn
-    {0xB9D10000u, 44u}, // roo -> Latn
-    {0xBA310000u, 44u}, // rro -> Latn
-    {0xB2710000u, 44u}, // rtm -> Latn
-    {0x72750000u, 16u}, // ru -> Cyrl
-    {0x92910000u, 16u}, // rue -> Cyrl
-    {0x9A910000u, 44u}, // rug -> Latn
-    {0x72770000u, 44u}, // rw -> Latn
-    {0xAAD10000u, 44u}, // rwk -> Latn
-    {0xBAD10000u, 44u}, // rwo -> Latn
-    {0xD3110000u, 37u}, // ryu -> Kana
-    {0x73610000u, 17u}, // sa -> Deva
-    {0x94120000u, 44u}, // saf -> Latn
-    {0x9C120000u, 16u}, // sah -> Cyrl
-    {0xC0120000u, 44u}, // saq -> Latn
-    {0xC8120000u, 44u}, // sas -> Latn
-    {0xCC120000u, 44u}, // sat -> Latn
-    {0xD4120000u, 44u}, // sav -> Latn
-    {0xE4120000u, 72u}, // saz -> Saur
-    {0x80320000u, 44u}, // sba -> Latn
-    {0x90320000u, 44u}, // sbe -> Latn
-    {0xBC320000u, 44u}, // sbp -> Latn
-    {0x73630000u, 44u}, // sc -> Latn
-    {0xA8520000u, 17u}, // sck -> Deva
+    {0xD1910000u, 46u}, // rmu -> Latn
+    {0x726E0000u, 46u}, // rn -> Latn
+    {0x81B10000u, 46u}, // rna -> Latn
+    {0x99B10000u, 46u}, // rng -> Latn
+    {0x726F0000u, 46u}, // ro -> Latn
+    {0x85D10000u, 46u}, // rob -> Latn
+    {0x95D10000u, 46u}, // rof -> Latn
+    {0xB9D10000u, 46u}, // roo -> Latn
+    {0xBA310000u, 46u}, // rro -> Latn
+    {0xB2710000u, 46u}, // rtm -> Latn
+    {0x72750000u, 17u}, // ru -> Cyrl
+    {0x92910000u, 17u}, // rue -> Cyrl
+    {0x9A910000u, 46u}, // rug -> Latn
+    {0x72770000u, 46u}, // rw -> Latn
+    {0xAAD10000u, 46u}, // rwk -> Latn
+    {0xBAD10000u, 46u}, // rwo -> Latn
+    {0xD3110000u, 38u}, // ryu -> Kana
+    {0x73610000u, 18u}, // sa -> Deva
+    {0x94120000u, 46u}, // saf -> Latn
+    {0x9C120000u, 17u}, // sah -> Cyrl
+    {0xC0120000u, 46u}, // saq -> Latn
+    {0xC8120000u, 46u}, // sas -> Latn
+    {0xCC120000u, 46u}, // sat -> Latn
+    {0xD4120000u, 46u}, // sav -> Latn
+    {0xE4120000u, 74u}, // saz -> Saur
+    {0x80320000u, 46u}, // sba -> Latn
+    {0x90320000u, 46u}, // sbe -> Latn
+    {0xBC320000u, 46u}, // sbp -> Latn
+    {0x73630000u, 46u}, // sc -> Latn
+    {0xA8520000u, 18u}, // sck -> Deva
     {0xAC520000u,  1u}, // scl -> Arab
-    {0xB4520000u, 44u}, // scn -> Latn
-    {0xB8520000u, 44u}, // sco -> Latn
-    {0xC8520000u, 44u}, // scs -> Latn
+    {0xB4520000u, 46u}, // scn -> Latn
+    {0xB8520000u, 46u}, // sco -> Latn
+    {0xC8520000u, 46u}, // scs -> Latn
     {0x73640000u,  1u}, // sd -> Arab
-    {0x88720000u, 44u}, // sdc -> Latn
+    {0x88720000u, 46u}, // sdc -> Latn
     {0x9C720000u,  1u}, // sdh -> Arab
-    {0x73650000u, 44u}, // se -> Latn
-    {0x94920000u, 44u}, // sef -> Latn
-    {0x9C920000u, 44u}, // seh -> Latn
-    {0xA0920000u, 44u}, // sei -> Latn
-    {0xC8920000u, 44u}, // ses -> Latn
-    {0x73670000u, 44u}, // sg -> Latn
-    {0x80D20000u, 60u}, // sga -> Ogam
-    {0xC8D20000u, 44u}, // sgs -> Latn
-    {0xD8D20000u, 19u}, // sgw -> Ethi
-    {0xE4D20000u, 44u}, // sgz -> Latn
-    {0x73680000u, 44u}, // sh -> Latn
-    {0xA0F20000u, 85u}, // shi -> Tfng
-    {0xA8F20000u, 44u}, // shk -> Latn
-    {0xB4F20000u, 56u}, // shn -> Mymr
+    {0x73650000u, 46u}, // se -> Latn
+    {0x94920000u, 46u}, // sef -> Latn
+    {0x9C920000u, 46u}, // seh -> Latn
+    {0xA0920000u, 46u}, // sei -> Latn
+    {0xC8920000u, 46u}, // ses -> Latn
+    {0x73670000u, 46u}, // sg -> Latn
+    {0x80D20000u, 62u}, // sga -> Ogam
+    {0xC8D20000u, 46u}, // sgs -> Latn
+    {0xD8D20000u, 20u}, // sgw -> Ethi
+    {0xE4D20000u, 46u}, // sgz -> Latn
+    {0x73680000u, 46u}, // sh -> Latn
+    {0xA0F20000u, 87u}, // shi -> Tfng
+    {0xA8F20000u, 46u}, // shk -> Latn
+    {0xB4F20000u, 58u}, // shn -> Mymr
     {0xD0F20000u,  1u}, // shu -> Arab
-    {0x73690000u, 74u}, // si -> Sinh
-    {0x8D120000u, 44u}, // sid -> Latn
-    {0x99120000u, 44u}, // sig -> Latn
-    {0xAD120000u, 44u}, // sil -> Latn
-    {0xB1120000u, 44u}, // sim -> Latn
-    {0xC5320000u, 44u}, // sjr -> Latn
-    {0x736B0000u, 44u}, // sk -> Latn
-    {0x89520000u, 44u}, // skc -> Latn
+    {0x73690000u, 76u}, // si -> Sinh
+    {0x8D120000u, 46u}, // sid -> Latn
+    {0x99120000u, 46u}, // sig -> Latn
+    {0xAD120000u, 46u}, // sil -> Latn
+    {0xB1120000u, 46u}, // sim -> Latn
+    {0xC5320000u, 46u}, // sjr -> Latn
+    {0x736B0000u, 46u}, // sk -> Latn
+    {0x89520000u, 46u}, // skc -> Latn
     {0xC5520000u,  1u}, // skr -> Arab
-    {0xC9520000u, 44u}, // sks -> Latn
-    {0x736C0000u, 44u}, // sl -> Latn
-    {0x8D720000u, 44u}, // sld -> Latn
-    {0xA1720000u, 44u}, // sli -> Latn
-    {0xAD720000u, 44u}, // sll -> Latn
-    {0xE1720000u, 44u}, // sly -> Latn
-    {0x736D0000u, 44u}, // sm -> Latn
-    {0x81920000u, 44u}, // sma -> Latn
-    {0xA5920000u, 44u}, // smj -> Latn
-    {0xB5920000u, 44u}, // smn -> Latn
-    {0xBD920000u, 70u}, // smp -> Samr
-    {0xC1920000u, 44u}, // smq -> Latn
-    {0xC9920000u, 44u}, // sms -> Latn
-    {0x736E0000u, 44u}, // sn -> Latn
-    {0x89B20000u, 44u}, // snc -> Latn
-    {0xA9B20000u, 44u}, // snk -> Latn
-    {0xBDB20000u, 44u}, // snp -> Latn
-    {0xDDB20000u, 44u}, // snx -> Latn
-    {0xE1B20000u, 44u}, // sny -> Latn
-    {0x736F0000u, 44u}, // so -> Latn
-    {0x99D20000u, 75u}, // sog -> Sogd
-    {0xA9D20000u, 44u}, // sok -> Latn
-    {0xC1D20000u, 44u}, // soq -> Latn
-    {0xD1D20000u, 87u}, // sou -> Thai
-    {0xE1D20000u, 44u}, // soy -> Latn
-    {0x8DF20000u, 44u}, // spd -> Latn
-    {0xADF20000u, 44u}, // spl -> Latn
-    {0xC9F20000u, 44u}, // sps -> Latn
-    {0x73710000u, 44u}, // sq -> Latn
-    {0x73720000u, 16u}, // sr -> Cyrl
-    {0x73724D45u, 44u}, // sr-ME -> Latn
-    {0x7372524Fu, 44u}, // sr-RO -> Latn
-    {0x73725255u, 44u}, // sr-RU -> Latn
-    {0x73725452u, 44u}, // sr-TR -> Latn
-    {0x86320000u, 76u}, // srb -> Sora
-    {0xB6320000u, 44u}, // srn -> Latn
-    {0xC6320000u, 44u}, // srr -> Latn
-    {0xDE320000u, 17u}, // srx -> Deva
-    {0x73730000u, 44u}, // ss -> Latn
-    {0x8E520000u, 44u}, // ssd -> Latn
-    {0x9A520000u, 44u}, // ssg -> Latn
-    {0xE2520000u, 44u}, // ssy -> Latn
-    {0x73740000u, 44u}, // st -> Latn
-    {0xAA720000u, 44u}, // stk -> Latn
-    {0xC2720000u, 44u}, // stq -> Latn
-    {0x73750000u, 44u}, // su -> Latn
-    {0x82920000u, 44u}, // sua -> Latn
-    {0x92920000u, 44u}, // sue -> Latn
-    {0xAA920000u, 44u}, // suk -> Latn
-    {0xC6920000u, 44u}, // sur -> Latn
-    {0xCA920000u, 44u}, // sus -> Latn
-    {0x73760000u, 44u}, // sv -> Latn
-    {0x73770000u, 44u}, // sw -> Latn
+    {0xC9520000u, 46u}, // sks -> Latn
+    {0x736C0000u, 46u}, // sl -> Latn
+    {0x8D720000u, 46u}, // sld -> Latn
+    {0xA1720000u, 46u}, // sli -> Latn
+    {0xAD720000u, 46u}, // sll -> Latn
+    {0xE1720000u, 46u}, // sly -> Latn
+    {0x736D0000u, 46u}, // sm -> Latn
+    {0x81920000u, 46u}, // sma -> Latn
+    {0xA5920000u, 46u}, // smj -> Latn
+    {0xB5920000u, 46u}, // smn -> Latn
+    {0xBD920000u, 72u}, // smp -> Samr
+    {0xC1920000u, 46u}, // smq -> Latn
+    {0xC9920000u, 46u}, // sms -> Latn
+    {0x736E0000u, 46u}, // sn -> Latn
+    {0x89B20000u, 46u}, // snc -> Latn
+    {0xA9B20000u, 46u}, // snk -> Latn
+    {0xBDB20000u, 46u}, // snp -> Latn
+    {0xDDB20000u, 46u}, // snx -> Latn
+    {0xE1B20000u, 46u}, // sny -> Latn
+    {0x736F0000u, 46u}, // so -> Latn
+    {0x99D20000u, 77u}, // sog -> Sogd
+    {0xA9D20000u, 46u}, // sok -> Latn
+    {0xC1D20000u, 46u}, // soq -> Latn
+    {0xD1D20000u, 89u}, // sou -> Thai
+    {0xE1D20000u, 46u}, // soy -> Latn
+    {0x8DF20000u, 46u}, // spd -> Latn
+    {0xADF20000u, 46u}, // spl -> Latn
+    {0xC9F20000u, 46u}, // sps -> Latn
+    {0x73710000u, 46u}, // sq -> Latn
+    {0x73720000u, 17u}, // sr -> Cyrl
+    {0x73724D45u, 46u}, // sr-ME -> Latn
+    {0x7372524Fu, 46u}, // sr-RO -> Latn
+    {0x73725255u, 46u}, // sr-RU -> Latn
+    {0x73725452u, 46u}, // sr-TR -> Latn
+    {0x86320000u, 78u}, // srb -> Sora
+    {0xB6320000u, 46u}, // srn -> Latn
+    {0xC6320000u, 46u}, // srr -> Latn
+    {0xDE320000u, 18u}, // srx -> Deva
+    {0x73730000u, 46u}, // ss -> Latn
+    {0x8E520000u, 46u}, // ssd -> Latn
+    {0x9A520000u, 46u}, // ssg -> Latn
+    {0xE2520000u, 46u}, // ssy -> Latn
+    {0x73740000u, 46u}, // st -> Latn
+    {0xAA720000u, 46u}, // stk -> Latn
+    {0xC2720000u, 46u}, // stq -> Latn
+    {0x73750000u, 46u}, // su -> Latn
+    {0x82920000u, 46u}, // sua -> Latn
+    {0x92920000u, 46u}, // sue -> Latn
+    {0xAA920000u, 46u}, // suk -> Latn
+    {0xC6920000u, 46u}, // sur -> Latn
+    {0xCA920000u, 46u}, // sus -> Latn
+    {0x73760000u, 46u}, // sv -> Latn
+    {0x73770000u, 46u}, // sw -> Latn
     {0x86D20000u,  1u}, // swb -> Arab
-    {0x8AD20000u, 44u}, // swc -> Latn
-    {0x9AD20000u, 44u}, // swg -> Latn
-    {0xBED20000u, 44u}, // swp -> Latn
-    {0xD6D20000u, 17u}, // swv -> Deva
-    {0xB6F20000u, 44u}, // sxn -> Latn
-    {0xDAF20000u, 44u}, // sxw -> Latn
+    {0x8AD20000u, 46u}, // swc -> Latn
+    {0x9AD20000u, 46u}, // swg -> Latn
+    {0xBED20000u, 46u}, // swp -> Latn
+    {0xD6D20000u, 18u}, // swv -> Deva
+    {0xB6F20000u, 46u}, // sxn -> Latn
+    {0xDAF20000u, 46u}, // sxw -> Latn
     {0xAF120000u,  7u}, // syl -> Beng
-    {0xC7120000u, 78u}, // syr -> Syrc
-    {0xAF320000u, 44u}, // szl -> Latn
-    {0x74610000u, 81u}, // ta -> Taml
-    {0xA4130000u, 17u}, // taj -> Deva
-    {0xAC130000u, 44u}, // tal -> Latn
-    {0xB4130000u, 44u}, // tan -> Latn
-    {0xC0130000u, 44u}, // taq -> Latn
-    {0x88330000u, 44u}, // tbc -> Latn
-    {0x8C330000u, 44u}, // tbd -> Latn
-    {0x94330000u, 44u}, // tbf -> Latn
-    {0x98330000u, 44u}, // tbg -> Latn
-    {0xB8330000u, 44u}, // tbo -> Latn
-    {0xD8330000u, 44u}, // tbw -> Latn
-    {0xE4330000u, 44u}, // tbz -> Latn
-    {0xA0530000u, 44u}, // tci -> Latn
-    {0xE0530000u, 40u}, // tcy -> Knda
-    {0x8C730000u, 79u}, // tdd -> Tale
-    {0x98730000u, 17u}, // tdg -> Deva
-    {0x9C730000u, 17u}, // tdh -> Deva
-    {0xD0730000u, 44u}, // tdu -> Latn
-    {0x74650000u, 84u}, // te -> Telu
-    {0x8C930000u, 44u}, // ted -> Latn
-    {0xB0930000u, 44u}, // tem -> Latn
-    {0xB8930000u, 44u}, // teo -> Latn
-    {0xCC930000u, 44u}, // tet -> Latn
-    {0xA0B30000u, 44u}, // tfi -> Latn
-    {0x74670000u, 16u}, // tg -> Cyrl
+    {0xC7120000u, 80u}, // syr -> Syrc
+    {0xAF320000u, 46u}, // szl -> Latn
+    {0x74610000u, 83u}, // ta -> Taml
+    {0xA4130000u, 18u}, // taj -> Deva
+    {0xAC130000u, 46u}, // tal -> Latn
+    {0xB4130000u, 46u}, // tan -> Latn
+    {0xC0130000u, 46u}, // taq -> Latn
+    {0x88330000u, 46u}, // tbc -> Latn
+    {0x8C330000u, 46u}, // tbd -> Latn
+    {0x94330000u, 46u}, // tbf -> Latn
+    {0x98330000u, 46u}, // tbg -> Latn
+    {0xB8330000u, 46u}, // tbo -> Latn
+    {0xD8330000u, 46u}, // tbw -> Latn
+    {0xE4330000u, 46u}, // tbz -> Latn
+    {0xA0530000u, 46u}, // tci -> Latn
+    {0xE0530000u, 42u}, // tcy -> Knda
+    {0x8C730000u, 81u}, // tdd -> Tale
+    {0x98730000u, 18u}, // tdg -> Deva
+    {0x9C730000u, 18u}, // tdh -> Deva
+    {0xD0730000u, 46u}, // tdu -> Latn
+    {0x74650000u, 86u}, // te -> Telu
+    {0x8C930000u, 46u}, // ted -> Latn
+    {0xB0930000u, 46u}, // tem -> Latn
+    {0xB8930000u, 46u}, // teo -> Latn
+    {0xCC930000u, 46u}, // tet -> Latn
+    {0xA0B30000u, 46u}, // tfi -> Latn
+    {0x74670000u, 17u}, // tg -> Cyrl
     {0x7467504Bu,  1u}, // tg-PK -> Arab
-    {0x88D30000u, 44u}, // tgc -> Latn
-    {0xB8D30000u, 44u}, // tgo -> Latn
-    {0xD0D30000u, 44u}, // tgu -> Latn
-    {0x74680000u, 87u}, // th -> Thai
-    {0xACF30000u, 17u}, // thl -> Deva
-    {0xC0F30000u, 17u}, // thq -> Deva
-    {0xC4F30000u, 17u}, // thr -> Deva
-    {0x74690000u, 19u}, // ti -> Ethi
-    {0x95130000u, 44u}, // tif -> Latn
-    {0x99130000u, 19u}, // tig -> Ethi
-    {0xA9130000u, 44u}, // tik -> Latn
-    {0xB1130000u, 44u}, // tim -> Latn
-    {0xB9130000u, 44u}, // tio -> Latn
-    {0xD5130000u, 44u}, // tiv -> Latn
-    {0x746B0000u, 44u}, // tk -> Latn
-    {0xAD530000u, 44u}, // tkl -> Latn
-    {0xC5530000u, 44u}, // tkr -> Latn
-    {0xCD530000u, 17u}, // tkt -> Deva
-    {0x746C0000u, 44u}, // tl -> Latn
-    {0x95730000u, 44u}, // tlf -> Latn
-    {0xDD730000u, 44u}, // tlx -> Latn
-    {0xE1730000u, 44u}, // tly -> Latn
-    {0x9D930000u, 44u}, // tmh -> Latn
-    {0xE1930000u, 44u}, // tmy -> Latn
-    {0x746E0000u, 44u}, // tn -> Latn
-    {0x9DB30000u, 44u}, // tnh -> Latn
-    {0x746F0000u, 44u}, // to -> Latn
-    {0x95D30000u, 44u}, // tof -> Latn
-    {0x99D30000u, 44u}, // tog -> Latn
-    {0xC1D30000u, 44u}, // toq -> Latn
-    {0xA1F30000u, 44u}, // tpi -> Latn
-    {0xB1F30000u, 44u}, // tpm -> Latn
-    {0xE5F30000u, 44u}, // tpz -> Latn
-    {0xBA130000u, 44u}, // tqo -> Latn
-    {0x74720000u, 44u}, // tr -> Latn
-    {0xD2330000u, 44u}, // tru -> Latn
-    {0xD6330000u, 44u}, // trv -> Latn
+    {0x88D30000u, 46u}, // tgc -> Latn
+    {0xB8D30000u, 46u}, // tgo -> Latn
+    {0xD0D30000u, 46u}, // tgu -> Latn
+    {0x74680000u, 89u}, // th -> Thai
+    {0xACF30000u, 18u}, // thl -> Deva
+    {0xC0F30000u, 18u}, // thq -> Deva
+    {0xC4F30000u, 18u}, // thr -> Deva
+    {0x74690000u, 20u}, // ti -> Ethi
+    {0x95130000u, 46u}, // tif -> Latn
+    {0x99130000u, 20u}, // tig -> Ethi
+    {0xA9130000u, 46u}, // tik -> Latn
+    {0xB1130000u, 46u}, // tim -> Latn
+    {0xB9130000u, 46u}, // tio -> Latn
+    {0xD5130000u, 46u}, // tiv -> Latn
+    {0x746B0000u, 46u}, // tk -> Latn
+    {0xAD530000u, 46u}, // tkl -> Latn
+    {0xC5530000u, 46u}, // tkr -> Latn
+    {0xCD530000u, 18u}, // tkt -> Deva
+    {0x746C0000u, 46u}, // tl -> Latn
+    {0x95730000u, 46u}, // tlf -> Latn
+    {0xDD730000u, 46u}, // tlx -> Latn
+    {0xE1730000u, 46u}, // tly -> Latn
+    {0x9D930000u, 46u}, // tmh -> Latn
+    {0xE1930000u, 46u}, // tmy -> Latn
+    {0x746E0000u, 46u}, // tn -> Latn
+    {0x9DB30000u, 46u}, // tnh -> Latn
+    {0x746F0000u, 46u}, // to -> Latn
+    {0x95D30000u, 46u}, // tof -> Latn
+    {0x99D30000u, 46u}, // tog -> Latn
+    {0xC1D30000u, 46u}, // toq -> Latn
+    {0xA1F30000u, 46u}, // tpi -> Latn
+    {0xB1F30000u, 46u}, // tpm -> Latn
+    {0xE5F30000u, 46u}, // tpz -> Latn
+    {0xBA130000u, 46u}, // tqo -> Latn
+    {0x74720000u, 46u}, // tr -> Latn
+    {0xD2330000u, 46u}, // tru -> Latn
+    {0xD6330000u, 46u}, // trv -> Latn
     {0xDA330000u,  1u}, // trw -> Arab
-    {0x74730000u, 44u}, // ts -> Latn
-    {0x8E530000u, 24u}, // tsd -> Grek
-    {0x96530000u, 17u}, // tsf -> Deva
-    {0x9A530000u, 44u}, // tsg -> Latn
-    {0xA6530000u, 88u}, // tsj -> Tibt
-    {0xDA530000u, 44u}, // tsw -> Latn
-    {0x74740000u, 16u}, // tt -> Cyrl
-    {0x8E730000u, 44u}, // ttd -> Latn
-    {0x92730000u, 44u}, // tte -> Latn
-    {0xA6730000u, 44u}, // ttj -> Latn
-    {0xC6730000u, 44u}, // ttr -> Latn
-    {0xCA730000u, 87u}, // tts -> Thai
-    {0xCE730000u, 44u}, // ttt -> Latn
-    {0x9E930000u, 44u}, // tuh -> Latn
-    {0xAE930000u, 44u}, // tul -> Latn
-    {0xB2930000u, 44u}, // tum -> Latn
-    {0xC2930000u, 44u}, // tuq -> Latn
-    {0x8EB30000u, 44u}, // tvd -> Latn
-    {0xAEB30000u, 44u}, // tvl -> Latn
-    {0xD2B30000u, 44u}, // tvu -> Latn
-    {0x9ED30000u, 44u}, // twh -> Latn
-    {0xC2D30000u, 44u}, // twq -> Latn
-    {0x9AF30000u, 82u}, // txg -> Tang
-    {0x74790000u, 44u}, // ty -> Latn
-    {0x83130000u, 44u}, // tya -> Latn
-    {0xD7130000u, 16u}, // tyv -> Cyrl
-    {0xB3330000u, 44u}, // tzm -> Latn
-    {0xD0340000u, 44u}, // ubu -> Latn
-    {0xB0740000u, 16u}, // udm -> Cyrl
+    {0x74730000u, 46u}, // ts -> Latn
+    {0x8E530000u, 25u}, // tsd -> Grek
+    {0x96530000u, 18u}, // tsf -> Deva
+    {0x9A530000u, 46u}, // tsg -> Latn
+    {0xA6530000u, 90u}, // tsj -> Tibt
+    {0xDA530000u, 46u}, // tsw -> Latn
+    {0x74740000u, 17u}, // tt -> Cyrl
+    {0x8E730000u, 46u}, // ttd -> Latn
+    {0x92730000u, 46u}, // tte -> Latn
+    {0xA6730000u, 46u}, // ttj -> Latn
+    {0xC6730000u, 46u}, // ttr -> Latn
+    {0xCA730000u, 89u}, // tts -> Thai
+    {0xCE730000u, 46u}, // ttt -> Latn
+    {0x9E930000u, 46u}, // tuh -> Latn
+    {0xAE930000u, 46u}, // tul -> Latn
+    {0xB2930000u, 46u}, // tum -> Latn
+    {0xC2930000u, 46u}, // tuq -> Latn
+    {0x8EB30000u, 46u}, // tvd -> Latn
+    {0xAEB30000u, 46u}, // tvl -> Latn
+    {0xD2B30000u, 46u}, // tvu -> Latn
+    {0x9ED30000u, 46u}, // twh -> Latn
+    {0xC2D30000u, 46u}, // twq -> Latn
+    {0x9AF30000u, 84u}, // txg -> Tang
+    {0x74790000u, 46u}, // ty -> Latn
+    {0x83130000u, 46u}, // tya -> Latn
+    {0xD7130000u, 17u}, // tyv -> Cyrl
+    {0xB3330000u, 46u}, // tzm -> Latn
+    {0xD0340000u, 46u}, // ubu -> Latn
+    {0xB0740000u, 17u}, // udm -> Cyrl
     {0x75670000u,  1u}, // ug -> Arab
-    {0x75674B5Au, 16u}, // ug-KZ -> Cyrl
-    {0x75674D4Eu, 16u}, // ug-MN -> Cyrl
-    {0x80D40000u, 89u}, // uga -> Ugar
-    {0x756B0000u, 16u}, // uk -> Cyrl
-    {0xA1740000u, 44u}, // uli -> Latn
-    {0x85940000u, 44u}, // umb -> Latn
+    {0x75674B5Au, 17u}, // ug-KZ -> Cyrl
+    {0x75674D4Eu, 17u}, // ug-MN -> Cyrl
+    {0x80D40000u, 91u}, // uga -> Ugar
+    {0x756B0000u, 17u}, // uk -> Cyrl
+    {0xA1740000u, 46u}, // uli -> Latn
+    {0x85940000u, 46u}, // umb -> Latn
     {0xC5B40000u,  7u}, // unr -> Beng
-    {0xC5B44E50u, 17u}, // unr-NP -> Deva
+    {0xC5B44E50u, 18u}, // unr-NP -> Deva
     {0xDDB40000u,  7u}, // unx -> Beng
-    {0xA9D40000u, 44u}, // uok -> Latn
+    {0xA9D40000u, 46u}, // uok -> Latn
     {0x75720000u,  1u}, // ur -> Arab
-    {0xA2340000u, 44u}, // uri -> Latn
-    {0xCE340000u, 44u}, // urt -> Latn
-    {0xDA340000u, 44u}, // urw -> Latn
-    {0x82540000u, 44u}, // usa -> Latn
-    {0xC6740000u, 44u}, // utr -> Latn
-    {0x9EB40000u, 44u}, // uvh -> Latn
-    {0xAEB40000u, 44u}, // uvl -> Latn
-    {0x757A0000u, 44u}, // uz -> Latn
+    {0xA2340000u, 46u}, // uri -> Latn
+    {0xCE340000u, 46u}, // urt -> Latn
+    {0xDA340000u, 46u}, // urw -> Latn
+    {0x82540000u, 46u}, // usa -> Latn
+    {0xC6740000u, 46u}, // utr -> Latn
+    {0x9EB40000u, 46u}, // uvh -> Latn
+    {0xAEB40000u, 46u}, // uvl -> Latn
+    {0x757A0000u, 46u}, // uz -> Latn
     {0x757A4146u,  1u}, // uz-AF -> Arab
-    {0x757A434Eu, 16u}, // uz-CN -> Cyrl
-    {0x98150000u, 44u}, // vag -> Latn
-    {0xA0150000u, 90u}, // vai -> Vaii
-    {0xB4150000u, 44u}, // van -> Latn
-    {0x76650000u, 44u}, // ve -> Latn
-    {0x88950000u, 44u}, // vec -> Latn
-    {0xBC950000u, 44u}, // vep -> Latn
-    {0x76690000u, 44u}, // vi -> Latn
-    {0x89150000u, 44u}, // vic -> Latn
-    {0xD5150000u, 44u}, // viv -> Latn
-    {0xC9750000u, 44u}, // vls -> Latn
-    {0x95950000u, 44u}, // vmf -> Latn
-    {0xD9950000u, 44u}, // vmw -> Latn
-    {0x766F0000u, 44u}, // vo -> Latn
-    {0xCDD50000u, 44u}, // vot -> Latn
-    {0xBA350000u, 44u}, // vro -> Latn
-    {0xB6950000u, 44u}, // vun -> Latn
-    {0xCE950000u, 44u}, // vut -> Latn
-    {0x77610000u, 44u}, // wa -> Latn
-    {0x90160000u, 44u}, // wae -> Latn
-    {0xA4160000u, 44u}, // waj -> Latn
-    {0xAC160000u, 19u}, // wal -> Ethi
-    {0xB4160000u, 44u}, // wan -> Latn
-    {0xC4160000u, 44u}, // war -> Latn
-    {0xBC360000u, 44u}, // wbp -> Latn
-    {0xC0360000u, 84u}, // wbq -> Telu
-    {0xC4360000u, 17u}, // wbr -> Deva
-    {0xA0560000u, 44u}, // wci -> Latn
-    {0xC4960000u, 44u}, // wer -> Latn
-    {0xA0D60000u, 44u}, // wgi -> Latn
-    {0x98F60000u, 44u}, // whg -> Latn
-    {0x85160000u, 44u}, // wib -> Latn
-    {0xD1160000u, 44u}, // wiu -> Latn
-    {0xD5160000u, 44u}, // wiv -> Latn
-    {0x81360000u, 44u}, // wja -> Latn
-    {0xA1360000u, 44u}, // wji -> Latn
-    {0xC9760000u, 44u}, // wls -> Latn
-    {0xB9960000u, 44u}, // wmo -> Latn
-    {0x89B60000u, 44u}, // wnc -> Latn
+    {0x757A434Eu, 17u}, // uz-CN -> Cyrl
+    {0x98150000u, 46u}, // vag -> Latn
+    {0xA0150000u, 92u}, // vai -> Vaii
+    {0xB4150000u, 46u}, // van -> Latn
+    {0x76650000u, 46u}, // ve -> Latn
+    {0x88950000u, 46u}, // vec -> Latn
+    {0xBC950000u, 46u}, // vep -> Latn
+    {0x76690000u, 46u}, // vi -> Latn
+    {0x89150000u, 46u}, // vic -> Latn
+    {0xD5150000u, 46u}, // viv -> Latn
+    {0xC9750000u, 46u}, // vls -> Latn
+    {0x95950000u, 46u}, // vmf -> Latn
+    {0xD9950000u, 46u}, // vmw -> Latn
+    {0x766F0000u, 46u}, // vo -> Latn
+    {0xCDD50000u, 46u}, // vot -> Latn
+    {0xBA350000u, 46u}, // vro -> Latn
+    {0xB6950000u, 46u}, // vun -> Latn
+    {0xCE950000u, 46u}, // vut -> Latn
+    {0x77610000u, 46u}, // wa -> Latn
+    {0x90160000u, 46u}, // wae -> Latn
+    {0xA4160000u, 46u}, // waj -> Latn
+    {0xAC160000u, 20u}, // wal -> Ethi
+    {0xB4160000u, 46u}, // wan -> Latn
+    {0xC4160000u, 46u}, // war -> Latn
+    {0xBC360000u, 46u}, // wbp -> Latn
+    {0xC0360000u, 86u}, // wbq -> Telu
+    {0xC4360000u, 18u}, // wbr -> Deva
+    {0xA0560000u, 46u}, // wci -> Latn
+    {0xC4960000u, 46u}, // wer -> Latn
+    {0xA0D60000u, 46u}, // wgi -> Latn
+    {0x98F60000u, 46u}, // whg -> Latn
+    {0x85160000u, 46u}, // wib -> Latn
+    {0xD1160000u, 46u}, // wiu -> Latn
+    {0xD5160000u, 46u}, // wiv -> Latn
+    {0x81360000u, 46u}, // wja -> Latn
+    {0xA1360000u, 46u}, // wji -> Latn
+    {0xC9760000u, 46u}, // wls -> Latn
+    {0xB9960000u, 46u}, // wmo -> Latn
+    {0x89B60000u, 46u}, // wnc -> Latn
     {0xA1B60000u,  1u}, // wni -> Arab
-    {0xD1B60000u, 44u}, // wnu -> Latn
-    {0x776F0000u, 44u}, // wo -> Latn
-    {0x85D60000u, 44u}, // wob -> Latn
-    {0xC9D60000u, 44u}, // wos -> Latn
-    {0xCA360000u, 44u}, // wrs -> Latn
-    {0x9A560000u, 21u}, // wsg -> Gong
-    {0xAA560000u, 44u}, // wsk -> Latn
-    {0xB2760000u, 17u}, // wtm -> Deva
-    {0xD2960000u, 27u}, // wuu -> Hans
-    {0xD6960000u, 44u}, // wuv -> Latn
-    {0x82D60000u, 44u}, // wwa -> Latn
-    {0xD4170000u, 44u}, // xav -> Latn
-    {0xA0370000u, 44u}, // xbi -> Latn
+    {0xD1B60000u, 46u}, // wnu -> Latn
+    {0x776F0000u, 46u}, // wo -> Latn
+    {0x85D60000u, 46u}, // wob -> Latn
+    {0xC9D60000u, 46u}, // wos -> Latn
+    {0xCA360000u, 46u}, // wrs -> Latn
+    {0x9A560000u, 22u}, // wsg -> Gong
+    {0xAA560000u, 46u}, // wsk -> Latn
+    {0xB2760000u, 18u}, // wtm -> Deva
+    {0xD2960000u, 28u}, // wuu -> Hans
+    {0xD6960000u, 46u}, // wuv -> Latn
+    {0x82D60000u, 46u}, // wwa -> Latn
+    {0xD4170000u, 46u}, // xav -> Latn
+    {0xA0370000u, 46u}, // xbi -> Latn
+    {0xB8570000u, 14u}, // xco -> Chrs
     {0xC4570000u, 11u}, // xcr -> Cari
-    {0xC8970000u, 44u}, // xes -> Latn
-    {0x78680000u, 44u}, // xh -> Latn
-    {0x81770000u, 44u}, // xla -> Latn
-    {0x89770000u, 48u}, // xlc -> Lyci
-    {0x8D770000u, 49u}, // xld -> Lydi
-    {0x95970000u, 20u}, // xmf -> Geor
-    {0xB5970000u, 51u}, // xmn -> Mani
-    {0xC5970000u, 52u}, // xmr -> Merc
-    {0x81B70000u, 57u}, // xna -> Narb
-    {0xC5B70000u, 17u}, // xnr -> Deva
-    {0x99D70000u, 44u}, // xog -> Latn
-    {0xB5D70000u, 44u}, // xon -> Latn
-    {0xC5F70000u, 68u}, // xpr -> Prti
-    {0x86370000u, 44u}, // xrb -> Latn
-    {0x82570000u, 71u}, // xsa -> Sarb
-    {0xA2570000u, 44u}, // xsi -> Latn
-    {0xB2570000u, 44u}, // xsm -> Latn
-    {0xC6570000u, 17u}, // xsr -> Deva
-    {0x92D70000u, 44u}, // xwe -> Latn
-    {0xB0180000u, 44u}, // yam -> Latn
-    {0xB8180000u, 44u}, // yao -> Latn
-    {0xBC180000u, 44u}, // yap -> Latn
-    {0xC8180000u, 44u}, // yas -> Latn
-    {0xCC180000u, 44u}, // yat -> Latn
-    {0xD4180000u, 44u}, // yav -> Latn
-    {0xE0180000u, 44u}, // yay -> Latn
-    {0xE4180000u, 44u}, // yaz -> Latn
-    {0x80380000u, 44u}, // yba -> Latn
-    {0x84380000u, 44u}, // ybb -> Latn
-    {0xE0380000u, 44u}, // yby -> Latn
-    {0xC4980000u, 44u}, // yer -> Latn
-    {0xC4D80000u, 44u}, // ygr -> Latn
-    {0xD8D80000u, 44u}, // ygw -> Latn
-    {0x79690000u, 30u}, // yi -> Hebr
-    {0xB9580000u, 44u}, // yko -> Latn
-    {0x91780000u, 44u}, // yle -> Latn
-    {0x99780000u, 44u}, // ylg -> Latn
-    {0xAD780000u, 44u}, // yll -> Latn
-    {0xAD980000u, 44u}, // yml -> Latn
-    {0x796F0000u, 44u}, // yo -> Latn
-    {0xB5D80000u, 44u}, // yon -> Latn
-    {0x86380000u, 44u}, // yrb -> Latn
-    {0x92380000u, 44u}, // yre -> Latn
-    {0xAE380000u, 44u}, // yrl -> Latn
-    {0xCA580000u, 44u}, // yss -> Latn
-    {0x82980000u, 44u}, // yua -> Latn
-    {0x92980000u, 28u}, // yue -> Hant
-    {0x9298434Eu, 27u}, // yue-CN -> Hans
-    {0xA6980000u, 44u}, // yuj -> Latn
-    {0xCE980000u, 44u}, // yut -> Latn
-    {0xDA980000u, 44u}, // yuw -> Latn
-    {0x7A610000u, 44u}, // za -> Latn
-    {0x98190000u, 44u}, // zag -> Latn
+    {0xC8970000u, 46u}, // xes -> Latn
+    {0x78680000u, 46u}, // xh -> Latn
+    {0x81770000u, 46u}, // xla -> Latn
+    {0x89770000u, 50u}, // xlc -> Lyci
+    {0x8D770000u, 51u}, // xld -> Lydi
+    {0x95970000u, 21u}, // xmf -> Geor
+    {0xB5970000u, 53u}, // xmn -> Mani
+    {0xC5970000u, 54u}, // xmr -> Merc
+    {0x81B70000u, 59u}, // xna -> Narb
+    {0xC5B70000u, 18u}, // xnr -> Deva
+    {0x99D70000u, 46u}, // xog -> Latn
+    {0xB5D70000u, 46u}, // xon -> Latn
+    {0xC5F70000u, 70u}, // xpr -> Prti
+    {0x86370000u, 46u}, // xrb -> Latn
+    {0x82570000u, 73u}, // xsa -> Sarb
+    {0xA2570000u, 46u}, // xsi -> Latn
+    {0xB2570000u, 46u}, // xsm -> Latn
+    {0xC6570000u, 18u}, // xsr -> Deva
+    {0x92D70000u, 46u}, // xwe -> Latn
+    {0xB0180000u, 46u}, // yam -> Latn
+    {0xB8180000u, 46u}, // yao -> Latn
+    {0xBC180000u, 46u}, // yap -> Latn
+    {0xC8180000u, 46u}, // yas -> Latn
+    {0xCC180000u, 46u}, // yat -> Latn
+    {0xD4180000u, 46u}, // yav -> Latn
+    {0xE0180000u, 46u}, // yay -> Latn
+    {0xE4180000u, 46u}, // yaz -> Latn
+    {0x80380000u, 46u}, // yba -> Latn
+    {0x84380000u, 46u}, // ybb -> Latn
+    {0xE0380000u, 46u}, // yby -> Latn
+    {0xC4980000u, 46u}, // yer -> Latn
+    {0xC4D80000u, 46u}, // ygr -> Latn
+    {0xD8D80000u, 46u}, // ygw -> Latn
+    {0x79690000u, 31u}, // yi -> Hebr
+    {0xB9580000u, 46u}, // yko -> Latn
+    {0x91780000u, 46u}, // yle -> Latn
+    {0x99780000u, 46u}, // ylg -> Latn
+    {0xAD780000u, 46u}, // yll -> Latn
+    {0xAD980000u, 46u}, // yml -> Latn
+    {0x796F0000u, 46u}, // yo -> Latn
+    {0xB5D80000u, 46u}, // yon -> Latn
+    {0x86380000u, 46u}, // yrb -> Latn
+    {0x92380000u, 46u}, // yre -> Latn
+    {0xAE380000u, 46u}, // yrl -> Latn
+    {0xCA580000u, 46u}, // yss -> Latn
+    {0x82980000u, 46u}, // yua -> Latn
+    {0x92980000u, 29u}, // yue -> Hant
+    {0x9298434Eu, 28u}, // yue-CN -> Hans
+    {0xA6980000u, 46u}, // yuj -> Latn
+    {0xCE980000u, 46u}, // yut -> Latn
+    {0xDA980000u, 46u}, // yuw -> Latn
+    {0x7A610000u, 46u}, // za -> Latn
+    {0x98190000u, 46u}, // zag -> Latn
     {0xA4790000u,  1u}, // zdj -> Arab
-    {0x80990000u, 44u}, // zea -> Latn
-    {0x9CD90000u, 85u}, // zgh -> Tfng
-    {0x7A680000u, 27u}, // zh -> Hans
-    {0x7A684155u, 28u}, // zh-AU -> Hant
-    {0x7A68424Eu, 28u}, // zh-BN -> Hant
-    {0x7A684742u, 28u}, // zh-GB -> Hant
-    {0x7A684746u, 28u}, // zh-GF -> Hant
-    {0x7A68484Bu, 28u}, // zh-HK -> Hant
-    {0x7A684944u, 28u}, // zh-ID -> Hant
-    {0x7A684D4Fu, 28u}, // zh-MO -> Hant
-    {0x7A684D59u, 28u}, // zh-MY -> Hant
-    {0x7A685041u, 28u}, // zh-PA -> Hant
-    {0x7A685046u, 28u}, // zh-PF -> Hant
-    {0x7A685048u, 28u}, // zh-PH -> Hant
-    {0x7A685352u, 28u}, // zh-SR -> Hant
-    {0x7A685448u, 28u}, // zh-TH -> Hant
-    {0x7A685457u, 28u}, // zh-TW -> Hant
-    {0x7A685553u, 28u}, // zh-US -> Hant
-    {0x7A68564Eu, 28u}, // zh-VN -> Hant
-    {0xDCF90000u, 59u}, // zhx -> Nshu
-    {0x81190000u, 44u}, // zia -> Latn
-    {0xB1790000u, 44u}, // zlm -> Latn
-    {0xA1990000u, 44u}, // zmi -> Latn
-    {0x91B90000u, 44u}, // zne -> Latn
-    {0x7A750000u, 44u}, // zu -> Latn
-    {0x83390000u, 44u}, // zza -> Latn
+    {0x80990000u, 46u}, // zea -> Latn
+    {0x9CD90000u, 87u}, // zgh -> Tfng
+    {0x7A680000u, 28u}, // zh -> Hans
+    {0x7A684155u, 29u}, // zh-AU -> Hant
+    {0x7A68424Eu, 29u}, // zh-BN -> Hant
+    {0x7A684742u, 29u}, // zh-GB -> Hant
+    {0x7A684746u, 29u}, // zh-GF -> Hant
+    {0x7A68484Bu, 29u}, // zh-HK -> Hant
+    {0x7A684944u, 29u}, // zh-ID -> Hant
+    {0x7A684D4Fu, 29u}, // zh-MO -> Hant
+    {0x7A684D59u, 29u}, // zh-MY -> Hant
+    {0x7A685041u, 29u}, // zh-PA -> Hant
+    {0x7A685046u, 29u}, // zh-PF -> Hant
+    {0x7A685048u, 29u}, // zh-PH -> Hant
+    {0x7A685352u, 29u}, // zh-SR -> Hant
+    {0x7A685448u, 29u}, // zh-TH -> Hant
+    {0x7A685457u, 29u}, // zh-TW -> Hant
+    {0x7A685553u, 29u}, // zh-US -> Hant
+    {0x7A68564Eu, 29u}, // zh-VN -> Hant
+    {0xDCF90000u, 61u}, // zhx -> Nshu
+    {0x81190000u, 46u}, // zia -> Latn
+    {0xCD590000u, 41u}, // zkt -> Kits
+    {0xB1790000u, 46u}, // zlm -> Latn
+    {0xA1990000u, 46u}, // zmi -> Latn
+    {0x91B90000u, 46u}, // zne -> Latn
+    {0x7A750000u, 46u}, // zu -> Latn
+    {0x83390000u, 46u}, // zza -> Latn
 });
 
 std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({
@@ -1829,6 +1833,7 @@
     0xC66A4D594C61746ELLU, // ktr_Latn_MY
     0x6B75495141726162LLU, // ku_Arab_IQ
     0x6B7554524C61746ELLU, // ku_Latn_TR
+    0x6B75474559657A69LLU, // ku_Yezi_GE
     0xB28A52554379726CLLU, // kum_Cyrl_RU
     0x6B7652554379726CLLU, // kv_Cyrl_RU
     0xC6AA49444C61746ELLU, // kvr_Latn_ID
@@ -2199,6 +2204,7 @@
     0xB276494E44657661LLU, // wtm_Deva_IN
     0xD296434E48616E73LLU, // wuu_Hans_CN
     0xD41742524C61746ELLU, // xav_Latn_BR
+    0xB857555A43687273LLU, // xco_Chrs_UZ
     0xC457545243617269LLU, // xcr_Cari_TR
     0x78685A414C61746ELLU, // xh_Latn_ZA
     0x897754524C796369LLU, // xlc_Lyci_TR
@@ -2231,6 +2237,7 @@
     0x7A68434E48616E73LLU, // zh_Hans_CN
     0x7A68545748616E74LLU, // zh_Hant_TW
     0xDCF9434E4E736875LLU, // zhx_Nshu_CN
+    0xCD59434E4B697473LLU, // zkt_Kits_CN
     0xB17954474C61746ELLU, // zlm_Latn_TG
     0xA1994D594C61746ELLU, // zmi_Latn_MY
     0x7A755A414C61746ELLU, // zu_Latn_ZA
diff --git a/libs/androidfw/OWNERS b/libs/androidfw/OWNERS
index 8cffd6a..bc056df 100644
--- a/libs/androidfw/OWNERS
+++ b/libs/androidfw/OWNERS
@@ -3,4 +3,4 @@
 rtmitchell@google.com
 
 per-file CursorWindow.cpp=omakoto@google.com
-per-file LocaleDataTables.cpp=vichang@google.com,tobiast@google.com,nikitai@google.com
+per-file LocaleDataTables.cpp=vichang@google.com,ngeoffray@google.com,nikitai@google.com
diff --git a/libs/androidfw/include/androidfw/ConfigDescription.h b/libs/androidfw/include/androidfw/ConfigDescription.h
index 6fa089a..acf413a 100644
--- a/libs/androidfw/include/androidfw/ConfigDescription.h
+++ b/libs/androidfw/include/androidfw/ConfigDescription.h
@@ -151,8 +151,8 @@
   size = sizeof(android::ResTable_config);
 }
 
-inline ConfigDescription::ConfigDescription(const ConfigDescription& o) {
-  *static_cast<android::ResTable_config*>(this) = o;
+inline ConfigDescription::ConfigDescription(const ConfigDescription& o)
+  : android::ResTable_config(o) {
 }
 
 inline ConfigDescription::ConfigDescription(ConfigDescription&& o) noexcept {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 94d32c6..59943eb 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -4213,6 +4213,7 @@
      * {@hide}
      */
     @UnsupportedAppUsage
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     public void setWiredDeviceConnectionState(int type, int state, String address, String name) {
         final IAudioService service = getService();
         try {
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index 392e8fe..a5da648 100644
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -20,9 +20,10 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Handler;
 import android.os.Looper;
-import android.os.Message;
 import android.util.Log;
 
+import com.android.internal.annotations.GuardedBy;
+
 import java.lang.ref.WeakReference;
 
 /**
@@ -158,6 +159,7 @@
     /**
      * Indicates the state of the Visualizer instance
      */
+    @GuardedBy("mStateLock")
     private int mState = STATE_UNINITIALIZED;
     /**
      * Lock to synchronize access to mState
@@ -166,6 +168,7 @@
     /**
      * System wide unique Identifier of the visualizer engine used by this Visualizer instance
      */
+    @GuardedBy("mStateLock")
     @UnsupportedAppUsage
     private int mId;
 
@@ -176,19 +179,24 @@
     /**
      * Handler for events coming from the native code
      */
-    private NativeEventHandler mNativeEventHandler = null;
+    @GuardedBy("mListenerLock")
+    private Handler mNativeEventHandler = null;
     /**
      *  PCM and FFT capture listener registered by client
      */
+    @GuardedBy("mListenerLock")
     private OnDataCaptureListener mCaptureListener = null;
     /**
      *  Server Died listener registered by client
      */
+    @GuardedBy("mListenerLock")
     private OnServerDiedListener mServerDiedListener = null;
 
     // accessed by native methods
-    private long mNativeVisualizer;
-    private long mJniData;
+    private long mNativeVisualizer;  // guarded by a static lock in native code
+    private long mJniData;  // set in native_setup, _release;
+                            // get in native_release, _setEnabled, _setPeriodicCapture
+                            // thus, effectively guarded by mStateLock
 
     //--------------------------------------------------------------------------
     // Constructor, Finalize
@@ -244,7 +252,9 @@
 
     @Override
     protected void finalize() {
-        native_finalize();
+        synchronized (mStateLock) {
+            native_finalize();
+        }
     }
 
     /**
@@ -601,25 +611,28 @@
      */
     public int setDataCaptureListener(OnDataCaptureListener listener,
             int rate, boolean waveform, boolean fft) {
-        synchronized (mListenerLock) {
-            mCaptureListener = listener;
-        }
         if (listener == null) {
             // make sure capture callback is stopped in native code
             waveform = false;
             fft = false;
         }
-        int status = native_setPeriodicCapture(rate, waveform, fft);
+        int status;
+        synchronized (mStateLock) {
+            status = native_setPeriodicCapture(rate, waveform, fft);
+        }
         if (status == SUCCESS) {
-            if ((listener != null) && (mNativeEventHandler == null)) {
-                Looper looper;
-                if ((looper = Looper.myLooper()) != null) {
-                    mNativeEventHandler = new NativeEventHandler(this, looper);
-                } else if ((looper = Looper.getMainLooper()) != null) {
-                    mNativeEventHandler = new NativeEventHandler(this, looper);
-                } else {
-                    mNativeEventHandler = null;
-                    status = ERROR_NO_INIT;
+            synchronized (mListenerLock) {
+                mCaptureListener = listener;
+                if ((listener != null) && (mNativeEventHandler == null)) {
+                    Looper looper;
+                    if ((looper = Looper.myLooper()) != null) {
+                        mNativeEventHandler = new Handler(looper);
+                    } else if ((looper = Looper.getMainLooper()) != null) {
+                        mNativeEventHandler = new Handler(looper);
+                    } else {
+                        mNativeEventHandler = null;
+                        status = ERROR_NO_INIT;
+                    }
                 }
             }
         }
@@ -663,112 +676,61 @@
         return SUCCESS;
     }
 
-    /**
-     * Helper class to handle the forwarding of native events to the appropriate listeners
-     */
-    private class NativeEventHandler extends Handler
-    {
-        private Visualizer mVisualizer;
-
-        public NativeEventHandler(Visualizer v, Looper looper) {
-            super(looper);
-            mVisualizer = v;
-        }
-
-        private void handleCaptureMessage(Message msg) {
-            OnDataCaptureListener l = null;
-            synchronized (mListenerLock) {
-                l = mVisualizer.mCaptureListener;
-            }
-
-            if (l != null) {
-                byte[] data = (byte[])msg.obj;
-                int samplingRate = msg.arg1;
-
-                switch(msg.what) {
-                case NATIVE_EVENT_PCM_CAPTURE:
-                    l.onWaveFormDataCapture(mVisualizer, data, samplingRate);
-                    break;
-                case NATIVE_EVENT_FFT_CAPTURE:
-                    l.onFftDataCapture(mVisualizer, data, samplingRate);
-                    break;
-                default:
-                    Log.e(TAG,"Unknown native event in handleCaptureMessge: "+msg.what);
-                    break;
-                }
-            }
-        }
-
-        private void handleServerDiedMessage(Message msg) {
-            OnServerDiedListener l = null;
-            synchronized (mListenerLock) {
-                l = mVisualizer.mServerDiedListener;
-            }
-
-            if (l != null)
-                l.onServerDied();
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            if (mVisualizer == null) {
-                return;
-            }
-
-            switch(msg.what) {
-            case NATIVE_EVENT_PCM_CAPTURE:
-            case NATIVE_EVENT_FFT_CAPTURE:
-                handleCaptureMessage(msg);
-                break;
-            case NATIVE_EVENT_SERVER_DIED:
-                handleServerDiedMessage(msg);
-                break;
-            default:
-                Log.e(TAG,"Unknown native event: "+msg.what);
-                break;
-            }
-        }
-    }
-
     //---------------------------------------------------------
     // Interface definitions
     //--------------------
 
     private static native final void native_init();
 
+    @GuardedBy("mStateLock")
     private native final int native_setup(Object audioeffect_this,
                                           int audioSession,
                                           int[] id,
                                           String opPackageName);
 
+    @GuardedBy("mStateLock")
     private native final void native_finalize();
 
+    @GuardedBy("mStateLock")
     private native final void native_release();
 
+    @GuardedBy("mStateLock")
     private native final int native_setEnabled(boolean enabled);
 
+    @GuardedBy("mStateLock")
     private native final boolean native_getEnabled();
 
+    @GuardedBy("mStateLock")
     private native final int native_setCaptureSize(int size);
 
+    @GuardedBy("mStateLock")
     private native final int native_getCaptureSize();
 
+    @GuardedBy("mStateLock")
     private native final int native_setScalingMode(int mode);
 
+    @GuardedBy("mStateLock")
     private native final int native_getScalingMode();
 
+    @GuardedBy("mStateLock")
     private native final int native_setMeasurementMode(int mode);
 
+    @GuardedBy("mStateLock")
     private native final int native_getMeasurementMode();
 
+    @GuardedBy("mStateLock")
     private native final int native_getSamplingRate();
 
+    @GuardedBy("mStateLock")
     private native final int native_getWaveForm(byte[] waveform);
 
+    @GuardedBy("mStateLock")
     private native final int native_getFft(byte[] fft);
 
+    @GuardedBy("mStateLock")
     private native final int native_getPeakRms(MeasurementPeakRms measurement);
 
+    @GuardedBy("mStateLock")
     private native final int native_setPeriodicCapture(int rate, boolean waveForm, boolean fft);
 
     //---------------------------------------------------------
@@ -776,17 +738,47 @@
     //--------------------
     @SuppressWarnings("unused")
     private static void postEventFromNative(Object effect_ref,
-            int what, int arg1, int arg2, Object obj) {
-        Visualizer visu = (Visualizer)((WeakReference)effect_ref).get();
-        if (visu == null) {
-            return;
-        }
+            int what, int samplingRate, byte[] data) {
+        final Visualizer visualizer = (Visualizer) ((WeakReference) effect_ref).get();
+        if (visualizer == null) return;
 
-        if (visu.mNativeEventHandler != null) {
-            Message m = visu.mNativeEventHandler.obtainMessage(what, arg1, arg2, obj);
-            visu.mNativeEventHandler.sendMessage(m);
+        final Handler handler;
+        synchronized (visualizer.mListenerLock) {
+            handler = visualizer.mNativeEventHandler;
         }
+        if (handler == null) return;
 
+        switch (what) {
+            case NATIVE_EVENT_PCM_CAPTURE:
+            case NATIVE_EVENT_FFT_CAPTURE:
+                handler.post(() -> {
+                    final OnDataCaptureListener l;
+                    synchronized (visualizer.mListenerLock) {
+                        l = visualizer.mCaptureListener;
+                    }
+                    if (l != null) {
+                        if (what == NATIVE_EVENT_PCM_CAPTURE) {
+                            l.onWaveFormDataCapture(visualizer, data, samplingRate);
+                        } else { // what == NATIVE_EVENT_FFT_CAPTURE
+                            l.onFftDataCapture(visualizer, data, samplingRate);
+                        }
+                    }
+                });
+                break;
+            case NATIVE_EVENT_SERVER_DIED:
+                handler.post(() -> {
+                    final OnServerDiedListener l;
+                    synchronized (visualizer.mListenerLock) {
+                        l = visualizer.mServerDiedListener;
+                    }
+                    if (l != null) {
+                        l.onServerDied();
+                    }
+                });
+                break;
+            default:
+                Log.e(TAG, "Unknown native event in postEventFromNative: " + what);
+                break;
+        }
     }
 }
-
diff --git a/media/java/android/media/tv/OWNERS b/media/java/android/media/tv/OWNERS
index 64c0bb5..a891154 100644
--- a/media/java/android/media/tv/OWNERS
+++ b/media/java/android/media/tv/OWNERS
@@ -3,3 +3,7 @@
 shubang@google.com
 quxiangfang@google.com
 
+# For android remote service
+per-file ITvRemoteServiceInput.aidl = file:/media/lib/tvremote/OWNERS
+per-file ITvRemoteProvider.aidl = file:/media/lib/tvremote/OWNERS
+
diff --git a/media/jni/audioeffect/Visualizer.cpp b/media/jni/audioeffect/Visualizer.cpp
index 83f3b6e..efeb335 100644
--- a/media/jni/audioeffect/Visualizer.cpp
+++ b/media/jni/audioeffect/Visualizer.cpp
@@ -120,8 +120,9 @@
     }
 
     if (mCaptureThread != 0) {
+        sp<CaptureThread> t = mCaptureThread;
         mCaptureLock.unlock();
-        mCaptureThread->requestExitAndWait();
+        t->requestExitAndWait();
         mCaptureLock.lock();
     }
 
diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp
index 1362433..f9a77f4 100644
--- a/media/jni/audioeffect/android_media_Visualizer.cpp
+++ b/media/jni/audioeffect/android_media_Visualizer.cpp
@@ -196,7 +196,6 @@
                 callbackInfo->visualizer_ref,
                 NATIVE_EVENT_PCM_CAPTURE,
                 samplingrate,
-                0,
                 jArray);
         }
     }
@@ -217,7 +216,6 @@
                 callbackInfo->visualizer_ref,
                 NATIVE_EVENT_FFT_CAPTURE,
                 samplingrate,
-                0,
                 jArray);
         }
     }
@@ -286,7 +284,7 @@
     // Get the postEvent method
     fields.midPostNativeEvent = env->GetStaticMethodID(
             fields.clazzEffect,
-            "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V");
+            "postEventFromNative", "(Ljava/lang/Object;II[B)V");
     if (fields.midPostNativeEvent == NULL) {
         ALOGE("Can't find Visualizer.%s", "postEventFromNative");
         return;
@@ -343,7 +341,7 @@
             fields.midPostNativeEvent,
             callbackInfo->visualizer_ref,
             NATIVE_EVENT_SERVER_DIED,
-            0, 0, NULL);
+            0, NULL);
     }
 }
 
diff --git a/media/tests/EffectsTest/res/layout/visualizertest.xml b/media/tests/EffectsTest/res/layout/visualizertest.xml
index 50ac7bb..18d7a36 100644
--- a/media/tests/EffectsTest/res/layout/visualizertest.xml
+++ b/media/tests/EffectsTest/res/layout/visualizertest.xml
@@ -56,6 +56,37 @@
          android:layout_height="wrap_content"
          android:scaleType="fitXY"/>
 
+    <LinearLayout android:id="@+id/visuMultithreadedLayout"
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="10dip"
+        android:layout_marginTop="10dip"
+        android:layout_marginRight="10dip"
+        android:layout_marginBottom="10dip" >
+
+        <TextView android:id="@+id/visuMultithreaded"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:layout_weight="1.0"
+            android:layout_gravity="center_vertical|left"
+            android:text="@string/effect_multithreaded"
+            style="@android:style/TextAppearance.Medium" />
+
+        <ToggleButton android:id="@+id/visuMultithreadedOnOff"
+            android:layout_width="wrap_content"
+            android:layout_height="fill_parent"
+            android:layout_gravity="center_vertical|right"
+            android:layout_weight="0.0" />
+
+    </LinearLayout>
+
+    <ImageView
+         android:src="@android:drawable/divider_horizontal_dark"
+         android:layout_width="fill_parent"
+         android:layout_height="wrap_content"
+         android:scaleType="fitXY"/>
+
     <LinearLayout android:id="@+id/visuControlLayout"
         android:orientation="horizontal"
         android:layout_width="fill_parent"
diff --git a/media/tests/EffectsTest/res/values/strings.xml b/media/tests/EffectsTest/res/values/strings.xml
index 2a85184..7c12da1 100644
--- a/media/tests/EffectsTest/res/values/strings.xml
+++ b/media/tests/EffectsTest/res/values/strings.xml
@@ -35,4 +35,6 @@
     <string name="effect_attach_off">Attach</string>
     <string name="effect_attach_on">Detach</string>
     <string name="send_level_name">Send Level</string>
+    <!-- Toggles use of a multi-threaded client for an effect [CHAR LIMIT=24] -->
+    <string name="effect_multithreaded">Multithreaded Use</string>
 </resources>
diff --git a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstance.java b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstance.java
new file mode 100644
index 0000000..817bd3d
--- /dev/null
+++ b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstance.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.effectstest;
+
+interface VisualizerInstance {
+    void enableDataCaptureListener(boolean enable);
+    boolean getEnabled();
+    void release();
+    void setEnabled(boolean enabled);
+    void startStopCapture(boolean start);
+}
diff --git a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceMT.java b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceMT.java
new file mode 100644
index 0000000..89cfbeb
--- /dev/null
+++ b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceMT.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.effectstest;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+class VisualizerInstanceMT implements VisualizerInstance {
+
+    private static final String TAG = "VisualizerInstanceMT";
+
+    private final Object mLock = new Object();
+    private final int mThreadCount;
+    @GuardedBy("mLock")
+    private Handler mVisualizerHandler;
+    @GuardedBy("mLock")
+    private VisualizerInstanceSync mVisualizer;
+
+    VisualizerInstanceMT(int session, Handler uiHandler, int extraThreadCount) {
+        Log.d(TAG, "Multi-threaded constructor");
+        mThreadCount = 1 + extraThreadCount;
+        Thread t = new Thread() {
+            @Override public void run() {
+                Looper.prepare();
+                VisualizerInstanceSync v = new VisualizerInstanceSync(session, uiHandler);
+                synchronized (mLock) {
+                    mVisualizerHandler = new Handler();
+                    mVisualizer = v;
+                }
+                Looper.loop();
+            }
+        };
+        t.start();
+    }
+
+    private VisualizerInstance getVisualizer() {
+        synchronized (mLock) {
+            return mVisualizer != null ? new VisualizerInstanceSync(mVisualizer) : null;
+        }
+    }
+
+    private interface VisualizerOperation {
+        void run(VisualizerInstance v);
+    }
+
+    private void runOperationMt(VisualizerOperation op) {
+        final VisualizerInstance v = getVisualizer();
+        if (v == null) return;
+        for (int i = 0; i < mThreadCount; ++i) {
+            Thread t = new Thread() {
+                @Override
+                public void run() {
+                    op.run(v);
+                }
+            };
+            t.start();
+        }
+    }
+
+    @Override
+    public void enableDataCaptureListener(boolean enable) {
+        runOperationMt(v -> v.enableDataCaptureListener(enable));
+    }
+
+    @Override
+    public boolean getEnabled() {
+        final VisualizerInstance v = getVisualizer();
+        return v != null ? v.getEnabled() : false;
+    }
+
+    @Override
+    public void release() {
+        runOperationMt(v -> v.release());
+        synchronized (mLock) {
+            if (mVisualizerHandler == null) return;
+            mVisualizerHandler.post(() -> {
+                synchronized (mLock) {
+                    mVisualizerHandler = null;
+                    mVisualizer = null;
+                    Looper.myLooper().quitSafely();
+                }
+                Log.d(TAG, "Exiting looper");
+            });
+        }
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        runOperationMt(v -> v.setEnabled(enabled));
+    }
+
+    @Override
+    public void startStopCapture(boolean start) {
+        runOperationMt(v -> v.startStopCapture(start));
+    }
+}
diff --git a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceSync.java b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceSync.java
new file mode 100644
index 0000000..e64f4e5
--- /dev/null
+++ b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceSync.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.effectstest;
+
+import android.media.audiofx.Visualizer;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+// This class only has `final' members, thus any thread-safety concerns
+// can only come from the Visualizer effect class.
+class VisualizerInstanceSync implements VisualizerInstance {
+
+    private static final String TAG = "VisualizerInstance";
+
+    private final Handler mUiHandler;
+    private final Visualizer mVisualizer;
+    private final VisualizerTestHandler mVisualizerTestHandler;
+    private final VisualizerListener mVisualizerListener;
+
+    VisualizerInstanceSync(int session, Handler uiHandler) {
+        mUiHandler = uiHandler;
+        try {
+            mVisualizer = new Visualizer(session);
+        } catch (UnsupportedOperationException e) {
+            Log.e(TAG, "Visualizer library not loaded");
+            throw new RuntimeException("Cannot initialize effect");
+        } catch (RuntimeException e) {
+            throw e;
+        }
+        mVisualizerTestHandler = new VisualizerTestHandler();
+        mVisualizerListener = new VisualizerListener();
+    }
+
+    // Not a "deep" copy, only copies the references.
+    VisualizerInstanceSync(VisualizerInstanceSync other) {
+        mUiHandler = other.mUiHandler;
+        mVisualizer = other.mVisualizer;
+        mVisualizerTestHandler = other.mVisualizerTestHandler;
+        mVisualizerListener = other.mVisualizerListener;
+    }
+
+    @Override
+    public void enableDataCaptureListener(boolean enable) {
+        mVisualizer.setDataCaptureListener(enable ? mVisualizerListener : null,
+                10000, enable, enable);
+    }
+
+    @Override
+    public boolean getEnabled() {
+        return mVisualizer.getEnabled();
+    }
+
+    @Override
+    public void release() {
+        mVisualizer.release();
+        Log.d(TAG, "Visualizer released");
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        mVisualizer.setEnabled(enabled);
+    }
+
+    @Override
+    public void startStopCapture(boolean start) {
+        mVisualizerTestHandler.sendMessage(mVisualizerTestHandler.obtainMessage(
+                        start ? MSG_START_CAPTURE : MSG_STOP_CAPTURE));
+    }
+
+    private static final int MSG_START_CAPTURE = 0;
+    private static final int MSG_STOP_CAPTURE = 1;
+    private static final int MSG_NEW_CAPTURE = 2;
+    private static final int CAPTURE_PERIOD_MS = 100;
+
+    private static int[] dataToMinMaxCenter(byte[] data, int len) {
+        int[] minMaxCenter = new int[3];
+        minMaxCenter[0] = data[0];
+        minMaxCenter[1] = data[len - 1];
+        minMaxCenter[2] = data[len / 2];
+        return minMaxCenter;
+    }
+
+    private class VisualizerTestHandler extends Handler {
+        private final int mCaptureSize;
+        private boolean mActive = false;
+
+        VisualizerTestHandler() {
+            mCaptureSize = mVisualizer.getCaptureSize();
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_START_CAPTURE:
+                    if (!mActive) {
+                        Log.d(TAG, "Start capture");
+                        mActive = true;
+                        sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE), CAPTURE_PERIOD_MS);
+                    }
+                    break;
+                case MSG_STOP_CAPTURE:
+                    if (mActive) {
+                        Log.d(TAG, "Stop capture");
+                        mActive = false;
+                    }
+                    break;
+                case MSG_NEW_CAPTURE:
+                    if (mActive) {
+                        if (mCaptureSize > 0) {
+                            byte[] data = new byte[mCaptureSize];
+                            if (mVisualizer.getWaveForm(data) == Visualizer.SUCCESS) {
+                                int len = data.length < mCaptureSize ? data.length : mCaptureSize;
+                                mUiHandler.sendMessage(
+                                        mUiHandler.obtainMessage(
+                                                VisualizerTest.MSG_DISPLAY_WAVEFORM_VAL,
+                                                dataToMinMaxCenter(data, len)));
+                            }
+                            if (mVisualizer.getFft(data) == Visualizer.SUCCESS) {
+                                int len = data.length < mCaptureSize ? data.length : mCaptureSize;
+                                mUiHandler.sendMessage(
+                                        mUiHandler.obtainMessage(VisualizerTest.MSG_DISPLAY_FFT_VAL,
+                                                dataToMinMaxCenter(data, len)));
+                            }
+                        }
+                        sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE), CAPTURE_PERIOD_MS);
+                    }
+                    break;
+            }
+        }
+    }
+
+    private class VisualizerListener implements Visualizer.OnDataCaptureListener {
+        @Override
+        public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform,
+                int samplingRate) {
+            if (visualizer == mVisualizer && waveform.length > 0) {
+                Log.d(TAG, "onWaveFormDataCapture(): " + waveform[0]
+                        + " smp rate: " + samplingRate / 1000);
+                mUiHandler.sendMessage(
+                        mUiHandler.obtainMessage(VisualizerTest.MSG_DISPLAY_WAVEFORM_VAL,
+                                dataToMinMaxCenter(waveform, waveform.length)));
+            }
+        }
+
+        @Override
+        public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
+            if (visualizer == mVisualizer && fft.length > 0) {
+                Log.d(TAG, "onFftDataCapture(): " + fft[0]);
+                mUiHandler.sendMessage(
+                        mUiHandler.obtainMessage(VisualizerTest.MSG_DISPLAY_FFT_VAL,
+                                dataToMinMaxCenter(fft, fft.length)));
+            }
+        }
+    }
+}
diff --git a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java
index 7db1d8d..2e141c5 100644
--- a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java
+++ b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java
@@ -17,51 +17,42 @@
 package com.android.effectstest;
 
 import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.media.audiofx.Visualizer;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.util.Log;
 import android.view.KeyEvent;
-import android.view.Menu;
 import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.Button;
 import android.widget.CompoundButton;
 import android.widget.CompoundButton.OnCheckedChangeListener;
 import android.widget.EditText;
 import android.widget.TextView;
 import android.widget.ToggleButton;
-import android.widget.SeekBar;
 
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
 import java.util.HashMap;
-import java.util.Map;
 
 public class VisualizerTest extends Activity implements OnCheckedChangeListener {
 
     private final static String TAG = "Visualizer Test";
 
-    private Visualizer mVisualizer;
+    private VisualizerInstance mVisualizer;
+    ToggleButton mMultithreadedButton;
     ToggleButton mOnOffButton;
     ToggleButton mReleaseButton;
+    boolean mUseMTInstance;
     boolean mEnabled;
     EditText mSessionText;
     static int sSession = 0;
-    int mCaptureSize;
     ToggleButton mCallbackButton;
     boolean mCallbackOn;
-    VisualizerListener mVisualizerListener;
-    private static HashMap<Integer, Visualizer> sInstances = new HashMap<Integer, Visualizer>(10);
-    private VisualizerTestHandler mVisualizerTestHandler = null;
+    private static HashMap<Integer, VisualizerInstance> sInstances =
+            new HashMap<Integer, VisualizerInstance>(10);
+    private Handler mUiHandler;
 
     public VisualizerTest() {
         Log.d(TAG, "contructor");
+        mUiHandler = new UiHandler(Looper.getMainLooper());
     }
 
     @Override
@@ -76,109 +67,45 @@
         mSessionText.setOnKeyListener(mSessionKeyListener);
         mSessionText.setText(Integer.toString(sSession));
 
-        mReleaseButton = (ToggleButton)findViewById(R.id.visuReleaseButton);
-        mOnOffButton = (ToggleButton)findViewById(R.id.visualizerOnOff);
-        mCallbackButton = (ToggleButton)findViewById(R.id.visuCallbackOnOff);
+        mMultithreadedButton = (ToggleButton) findViewById(R.id.visuMultithreadedOnOff);
+        mReleaseButton = (ToggleButton) findViewById(R.id.visuReleaseButton);
+        mOnOffButton = (ToggleButton) findViewById(R.id.visualizerOnOff);
+        mCallbackButton = (ToggleButton) findViewById(R.id.visuCallbackOnOff);
         mCallbackOn = false;
         mCallbackButton.setChecked(mCallbackOn);
 
-        mVisualizerTestHandler = new VisualizerTestHandler();
-        mVisualizerListener = new VisualizerListener();
-
-        getEffect(sSession);
-
-        if (mVisualizer != null) {
+        mMultithreadedButton.setOnCheckedChangeListener(this);
+        if (getEffect(sSession) != null) {
             mReleaseButton.setOnCheckedChangeListener(this);
             mOnOffButton.setOnCheckedChangeListener(this);
             mCallbackButton.setOnCheckedChangeListener(this);
         }
     }
 
-    private static final int MSG_START_CAPTURE = 0;
-    private static final int MSG_STOP_CAPTURE = 1;
-    private static final int MSG_NEW_CAPTURE = 2;
-    private static final int CAPTURE_PERIOD_MS = 100;
+    public static final int MSG_DISPLAY_WAVEFORM_VAL = 0;
+    public static final int MSG_DISPLAY_FFT_VAL = 1;
 
-    private class VisualizerTestHandler extends Handler {
-        boolean mActive = false;
+    private class UiHandler extends Handler {
+        UiHandler(Looper looper) {
+            super(looper);
+        }
+
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-            case MSG_START_CAPTURE:
-                if (!mActive) {
-                    Log.d(TAG, "Start capture");
-                    mActive = true;
-                    sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE, 0, 0, null), CAPTURE_PERIOD_MS);
+                case MSG_DISPLAY_WAVEFORM_VAL:
+                case MSG_DISPLAY_FFT_VAL:
+                    int[] minMaxCenter = (int[]) msg.obj;
+                    boolean waveform = msg.what == MSG_DISPLAY_WAVEFORM_VAL;
+                    displayVal(waveform ? R.id.waveformMin : R.id.fftMin, minMaxCenter[0]);
+                    displayVal(waveform ? R.id.waveformMax : R.id.fftMax, minMaxCenter[1]);
+                    displayVal(waveform ? R.id.waveformCenter : R.id.fftCenter, minMaxCenter[2]);
+                    break;
                 }
-                break;
-            case MSG_STOP_CAPTURE:
-                if (mActive) {
-                    Log.d(TAG, "Stop capture");
-                    mActive = false;
-                }
-                break;
-            case MSG_NEW_CAPTURE:
-                if (mActive && mVisualizer != null) {
-                    if (mCaptureSize > 0) {
-                        byte[] data = new byte[mCaptureSize];
-                        if (mVisualizer.getWaveForm(data) == Visualizer.SUCCESS) {
-                            int len = data.length < mCaptureSize ? data.length : mCaptureSize;
-                            displayVal(R.id.waveformMin, data[0]);
-                            displayVal(R.id.waveformMax, data[len-1]);
-                            displayVal(R.id.waveformCenter, data[len/2]);
-                        };
-                        if (mVisualizer.getFft(data) == Visualizer.SUCCESS) {
-                            int len = data.length < mCaptureSize ? data.length : mCaptureSize;
-                            displayVal(R.id.fftMin, data[0]);
-                            displayVal(R.id.fftMax, data[len-1]);
-                            displayVal(R.id.fftCenter, data[len/2]);
-                        };
-                    }
-                    sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE, 0, 0, null), CAPTURE_PERIOD_MS);
-                }
-                break;
-            }
         }
     }
 
-    private class VisualizerListener implements Visualizer.OnDataCaptureListener {
-
-        public VisualizerListener() {
-        }
-        public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
-            if (visualizer == mVisualizer) {
-                if (waveform.length > 0) {
-                    Log.d(TAG, "onWaveFormDataCapture(): "+waveform[0]+" smp rate: "+samplingRate/1000);
-                    displayVal(R.id.waveformMin, waveform[0]);
-                    displayVal(R.id.waveformMax, waveform[waveform.length - 1]);
-                    displayVal(R.id.waveformCenter, waveform[waveform.length/2]);
-                }
-            }
-        }
-        public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
-            if (visualizer == mVisualizer) {
-                if (fft.length > 0) {
-                    Log.d(TAG, "onFftDataCapture(): "+fft[0]);
-                    displayVal(R.id.fftMin, fft[0]);
-                    displayVal(R.id.fftMax, fft[fft.length - 1]);
-                    displayVal(R.id.fftCenter, fft[fft.length/2]);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-    }
-
-    private View.OnKeyListener mSessionKeyListener
-    = new View.OnKeyListener() {
+    private View.OnKeyListener mSessionKeyListener = new View.OnKeyListener() {
         public boolean onKey(View v, int keyCode, KeyEvent event) {
             if (event.getAction() == KeyEvent.ACTION_DOWN) {
                 switch (keyCode) {
@@ -199,29 +126,26 @@
     };
 
     // OnCheckedChangeListener
+    @Override
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+        if (buttonView.getId() == R.id.visuMultithreadedOnOff) {
+            mUseMTInstance = isChecked;
+            Log.d(TAG, "Multi-threaded client: " + (isChecked ? "enabled" : "disabled"));
+        }
         if (buttonView.getId() == R.id.visualizerOnOff) {
             if (mVisualizer != null) {
                 mEnabled = isChecked;
                 mCallbackButton.setEnabled(!mEnabled);
                 if (mCallbackOn && mEnabled) {
-                    mVisualizer.setDataCaptureListener(mVisualizerListener,
-                            10000,
-                            true,
-                            true);
+                    mVisualizer.enableDataCaptureListener(true);
                 }
                 mVisualizer.setEnabled(mEnabled);
                 if (mCallbackOn) {
                     if (!mEnabled) {
-                        mVisualizer.setDataCaptureListener(null,
-                                10000,
-                                false,
-                                false);
+                        mVisualizer.enableDataCaptureListener(false);
                     }
                 } else {
-                    int msg = isChecked ? MSG_START_CAPTURE : MSG_STOP_CAPTURE;
-                    mVisualizerTestHandler.sendMessage(
-                            mVisualizerTestHandler.obtainMessage(msg, 0, 0, null));
+                    mVisualizer.startStopCapture(isChecked);
                 }
             }
         }
@@ -248,16 +172,15 @@
     }
 
 
-    private void getEffect(int session) {
+    private VisualizerInstance getEffect(int session) {
         synchronized (sInstances) {
             if (sInstances.containsKey(session)) {
                 mVisualizer = sInstances.get(session);
             } else {
-                try{
-                    mVisualizer = new Visualizer(session);
-                } catch (UnsupportedOperationException e) {
-                    Log.e(TAG,"Visualizer library not loaded");
-                    throw (new RuntimeException("Cannot initialize effect"));
+                try {
+                    mVisualizer = mUseMTInstance
+                            ? new VisualizerInstanceMT(session, mUiHandler, 0 /*extraThreadCount*/)
+                            : new VisualizerInstanceSync(session, mUiHandler);
                 } catch (RuntimeException e) {
                     throw e;
                 }
@@ -267,8 +190,6 @@
         mReleaseButton.setEnabled(false);
         mOnOffButton.setEnabled(false);
         if (mVisualizer != null) {
-            mCaptureSize = mVisualizer.getCaptureSize();
-
             mReleaseButton.setChecked(true);
             mReleaseButton.setEnabled(true);
 
@@ -278,6 +199,7 @@
 
             mCallbackButton.setEnabled(!mEnabled);
         }
+        return mVisualizer;
     }
 
     private void putEffect(int session) {
@@ -286,9 +208,8 @@
         synchronized (sInstances) {
             if (mVisualizer != null) {
                 mVisualizer.release();
-                Log.d(TAG,"Visualizer released");
-                mVisualizer = null;
                 sInstances.remove(session);
+                mVisualizer = null;
             }
         }
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index c9c847f..3c78560 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -218,24 +218,32 @@
     }
 
     public boolean supportsHighQualityAudio(BluetoothDevice device) {
-        int support = mService.supportsOptionalCodecs(device);
+        BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice();
+        if (bluetoothDevice == null) {
+            return false;
+        }
+        int support = mService.isOptionalCodecsSupported(bluetoothDevice);
         return support == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED;
     }
 
     public boolean isHighQualityAudioEnabled(BluetoothDevice device) {
-        int enabled = mService.getOptionalCodecsEnabled(device);
+        BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice();
+        if (bluetoothDevice == null) {
+            return false;
+        }
+        int enabled = mService.isOptionalCodecsEnabled(bluetoothDevice);
         if (enabled != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN) {
             return enabled == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED;
-        } else if (getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED &&
-                supportsHighQualityAudio(device)) {
+        } else if (getConnectionStatus(bluetoothDevice) != BluetoothProfile.STATE_CONNECTED
+                && supportsHighQualityAudio(bluetoothDevice)) {
             // Since we don't have a stored preference and the device isn't connected, just return
             // true since the default behavior when the device gets connected in the future would be
             // to have optional codecs enabled.
             return true;
         }
         BluetoothCodecConfig codecConfig = null;
-        if (mService.getCodecStatus(device) != null) {
-            codecConfig = mService.getCodecStatus(device).getCodecConfig();
+        if (mService.getCodecStatus(bluetoothDevice) != null) {
+            codecConfig = mService.getCodecStatus(bluetoothDevice).getCodecConfig();
         }
         if (codecConfig != null)  {
             return !codecConfig.isMandatoryCodec();
@@ -245,23 +253,28 @@
     }
 
     public void setHighQualityAudioEnabled(BluetoothDevice device, boolean enabled) {
+        BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice();
+        if (bluetoothDevice == null) {
+            return;
+        }
         int prefValue = enabled
                 ? BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED
                 : BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED;
-        mService.setOptionalCodecsEnabled(device, prefValue);
-        if (getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED) {
+        mService.setOptionalCodecsEnabled(bluetoothDevice, prefValue);
+        if (getConnectionStatus(bluetoothDevice) != BluetoothProfile.STATE_CONNECTED) {
             return;
         }
         if (enabled) {
-            mService.enableOptionalCodecs(device);
+            mService.enableOptionalCodecs(bluetoothDevice);
         } else {
-            mService.disableOptionalCodecs(device);
+            mService.disableOptionalCodecs(bluetoothDevice);
         }
     }
 
     public String getHighQualityAudioOptionLabel(BluetoothDevice device) {
+        BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice();
         int unknownCodecId = R.string.bluetooth_profile_a2dp_high_quality_unknown_codec;
-        if (!supportsHighQualityAudio(device)
+        if (bluetoothDevice == null || !supportsHighQualityAudio(device)
                 || getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED) {
             return mContext.getString(unknownCodecId);
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index bb9d42e..994a9b3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -611,8 +611,8 @@
          * If a connect was attempted earlier without any UUID, we will do the connect now.
          * Otherwise, allow the connect on UUID change.
          */
-        if (!mProfiles.isEmpty()
-                && ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime())) {
+        if ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime()) {
+            Log.d(TAG, "onUuidChanged: triggering connectAllEnabledProfiles");
             connectAllEnabledProfiles();
         }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
index d17f242..a1fba4a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
@@ -174,7 +174,7 @@
 
     @Override
     public boolean isEnabled(BluetoothDevice device) {
-        if (mService == null) {
+        if (mService == null || device == null) {
             return false;
         }
         return mService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN;
@@ -182,7 +182,7 @@
 
     @Override
     public int getConnectionPolicy(BluetoothDevice device) {
-        if (mService == null) {
+        if (mService == null || device == null) {
             return CONNECTION_POLICY_FORBIDDEN;
         }
         return mService.getConnectionPolicy(device);
@@ -191,7 +191,7 @@
     @Override
     public boolean setEnabled(BluetoothDevice device, boolean enabled) {
         boolean isEnabled = false;
-        if (mService == null) {
+        if (mService == null || device == null) {
             return false;
         }
         if (enabled) {
@@ -213,7 +213,7 @@
     }
 
     public long getHiSyncId(BluetoothDevice device) {
-        if (mService == null) {
+        if (mService == null || device == null) {
             return BluetoothHearingAid.HI_SYNC_ID_INVALID;
         }
         return mService.getHiSyncId(device);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
index 414c39b..9afdd43c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
@@ -69,30 +69,31 @@
         mProfile = new A2dpProfile(mContext, mDeviceManager, mProfileManager);
         mServiceListener = mShadowBluetoothAdapter.getServiceListener();
         mServiceListener.onServiceConnected(BluetoothProfile.A2DP, mBluetoothA2dp);
+        when(mBluetoothA2dp.getActiveDevice()).thenReturn(mDevice);
     }
 
     @Test
     public void supportsHighQualityAudio() {
-        when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
+        when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
         assertThat(mProfile.supportsHighQualityAudio(mDevice)).isTrue();
 
-        when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
+        when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
         assertThat(mProfile.supportsHighQualityAudio(mDevice)).isFalse();
 
-        when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
+        when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN);
         assertThat(mProfile.supportsHighQualityAudio(mDevice)).isFalse();
     }
 
     @Test
     public void isHighQualityAudioEnabled() {
-        when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn(
+        when(mBluetoothA2dp.isOptionalCodecsEnabled(mDevice)).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED);
         assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isTrue();
 
-        when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn(
+        when(mBluetoothA2dp.isOptionalCodecsEnabled(mDevice)).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED);
         assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isFalse();
 
@@ -100,16 +101,16 @@
         // then isHighQualityAudioEnabled() should return true or false based on whether optional
         // codecs are supported. If the device is connected then we should ask it directly, but if
         // the device isn't connected then rely on the stored pref about such support.
-        when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn(
+        when(mBluetoothA2dp.isOptionalCodecsEnabled(mDevice)).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN);
         when(mBluetoothA2dp.getConnectionState(any())).thenReturn(
                 BluetoothProfile.STATE_DISCONNECTED);
 
-        when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
+        when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
         assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isFalse();
 
-        when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
+        when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
         assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isTrue();
 
@@ -151,14 +152,14 @@
 
         // Most tests want to simulate optional codecs being supported by the device, so do that
         // by default here.
-        when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
+        when(mBluetoothA2dp.isOptionalCodecsSupported(any())).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
     }
 
     @Test
     public void getLableCodecsNotSupported() {
         setupLabelTest();
-        when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
+        when(mBluetoothA2dp.isOptionalCodecsSupported(any())).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
         assertThat(mProfile.getHighQualityAudioOptionLabel(mDevice)).isEqualTo(UNKNOWN_CODEC_LABEL);
     }
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index f44f9cf..ff91c79 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -241,6 +241,12 @@
     <!-- Permission needed to read wifi network credentials for CtsNetTestCases -->
     <uses-permission android:name="android.permission.READ_WIFI_CREDENTIAL" />
 
+    <!-- Permission needed to use wifi usability API's for CtsNetTestCases -->
+    <uses-permission android:name="android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE" />
+
+    <!-- Permission required for testing system audio effect APIs. -->
+    <uses-permission android:name="android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS"/>
+
     <application android:label="@string/app_label"
                 android:theme="@android:style/Theme.DeviceDefault.DayNight"
                 android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index 656827a..c8cf7f50 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -4,7 +4,6 @@
 
 adamcohen@google.com
 asc@google.com
-ashaikh@google.com
 beverlyt@google.com
 brockman@google.com
 cinek@google.com
@@ -12,8 +11,8 @@
 dupin@google.com
 ethibodeau@google.com
 evanlaird@google.com
+hwwang@google.com
 hyunyoungs@google.com
-jmonk@google.com
 jaggies@google.com
 jjaggi@google.com
 joshmcgrath@google.com
@@ -29,16 +28,16 @@
 mrenouf@google.com
 nbenbernou@google.com
 nesciosquid@google.com
-ngmatthew@google.com
 ogunwale@google.com
+peanutbutter@google.com
 pixel@google.com
 roosa@google.com
-shahrk@google.com
 snoeberger@google.com
 steell@google.com
 stwu@google.com
 sunnygoyal@google.com
 susikp@google.com
+tracyzhou@google.com
 tsuji@google.com
 twickham@google.com
 winsonc@google.com
diff --git a/packages/SystemUI/res/drawable/ic_qs_nfc_enabled.xml b/packages/SystemUI/res/drawable/ic_qs_nfc.xml
similarity index 95%
rename from packages/SystemUI/res/drawable/ic_qs_nfc_enabled.xml
rename to packages/SystemUI/res/drawable/ic_qs_nfc.xml
index becb18a..2c08096 100644
--- a/packages/SystemUI/res/drawable/ic_qs_nfc_enabled.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_nfc.xml
@@ -14,8 +14,8 @@
      limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
+    android:width="48dp"
+    android:height="48dp"
     android:viewportWidth="24"
     android:viewportHeight="24">
 
diff --git a/packages/SystemUI/res/drawable/ic_qs_nfc_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_nfc_disabled.xml
deleted file mode 100644
index 558f3d0..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_nfc_disabled.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-     Copyright (C) 2016 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M4 20h16V4H4v16z" />
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1 .9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0
-18H4V4h16v16zM18 6h-5c-1.1 0-2 .9-2 2v2.28c-.6 .35 -1 .98-1 1.72 0 1.1 .9 2 2
-2s2-.9 2-2c0-.74-.4-1.38-1-1.72V8h3v8H8V8h2V6H6v12h12V6z" />
-    <path
-        android:pathData="M0 0h24v24H0z" />
-</vector>
diff --git a/packages/SystemUI/res/layout/menu_ime.xml b/packages/SystemUI/res/layout/menu_ime.xml
index 24374e8..df717f6 100644
--- a/packages/SystemUI/res/layout/menu_ime.xml
+++ b/packages/SystemUI/res/layout/menu_ime.xml
@@ -17,13 +17,13 @@
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/menu_container"
-    android:layout_width="@dimen/navigation_key_width"
+    android:layout_width="@dimen/navigation_side_padding"
     android:layout_height="match_parent"
     android:importantForAccessibility="no"
     >
     <!-- Use nav button width & height=match_parent for parent FrameLayout and buttons because they
     are placed inside a view that has a size controlled by weight. Ensure weight is large enough to
-    support icon size. -->
+    support icon size. Use layout_width=navigation_side_padding like other navbar buttons. -->
 
     <com.android.systemui.statusbar.policy.KeyButtonView
         android:id="@+id/menu"
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
index 476a239..d0bd073 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
@@ -38,6 +38,8 @@
 /** Quick settings tile: Enable/Disable NFC **/
 public class NfcTile extends QSTileImpl<BooleanState> {
 
+    private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_nfc);
+
     private NfcAdapter mAdapter;
 
     private boolean mListening;
@@ -105,8 +107,7 @@
         state.state = getAdapter() == null
                 ? Tile.STATE_UNAVAILABLE
                 : state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
-        state.icon = ResourceIcon.get(
-                state.value ? R.drawable.ic_qs_nfc_enabled : R.drawable.ic_qs_nfc_disabled);
+        state.icon = mIcon;
         state.label = mContext.getString(R.string.quick_settings_nfc_label);
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.contentDescription = state.label;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
index ef09434..7f7db2f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.database.ContentObserver;
 import android.hardware.display.AmbientDisplayConfiguration;
+import android.os.Build;
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -53,7 +54,7 @@
 
     private static final String TAG = "InterruptionStateProvider";
     private static final boolean DEBUG = false;
-    private static final boolean DEBUG_HEADS_UP = true;
+    private static final boolean DEBUG_HEADS_UP = Build.IS_DEBUGGABLE;
     private static final boolean ENABLE_HEADS_UP = true;
     private static final String SETTING_HEADS_UP_TICKER = "ticker_gets_heads_up";
 
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 7892381..48534f6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -577,7 +577,7 @@
     }
 
     boolean isDataDisabled() {
-        return !mPhone.isDataConnectionEnabled();
+        return !mPhone.isDataConnectionAllowed();
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index c08726d..e3d8ea2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.policy;
 
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_IN;
 import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT;
 import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_NONE;
@@ -160,6 +161,7 @@
     ServiceState mLastServiceState;
     private boolean mUserSetup;
     private boolean mSimDetected;
+    private boolean mForceCellularValidated;
 
     /**
      * Construct this controller object and register for updates.
@@ -275,12 +277,41 @@
         mPhoneStateListener = new PhoneStateListener(bgLooper) {
             @Override
             public void onActiveDataSubscriptionIdChanged(int subId) {
+                // For data switching from A to B, we assume B is validated for up to 2 seconds iff:
+                // 1) A and B are in the same subscription group e.g. CBRS data switch. And
+                // 2) A was validated before the switch.
+                // This is to provide smooth transition for UI without showing cross during data
+                // switch.
+                if (keepCellularValidationBitInSwitch(mActiveMobileDataSubscription, subId)) {
+                    if (DEBUG) Log.d(TAG, ": mForceCellularValidated to true.");
+                    mForceCellularValidated = true;
+                    mReceiverHandler.removeCallbacks(mClearForceValidated);
+                    mReceiverHandler.postDelayed(mClearForceValidated, 2000);
+                }
                 mActiveMobileDataSubscription = subId;
                 doUpdateMobileControllers();
             }
         };
     }
 
+    private final Runnable mClearForceValidated = () -> {
+        if (DEBUG) Log.d(TAG, ": mClearForceValidated");
+        mForceCellularValidated = false;
+        updateConnectivity();
+    };
+
+    boolean isInGroupDataSwitch(int subId1, int subId2) {
+        SubscriptionInfo info1 = mSubscriptionManager.getActiveSubscriptionInfo(subId1);
+        SubscriptionInfo info2 = mSubscriptionManager.getActiveSubscriptionInfo(subId2);
+        return (info1 != null && info2 != null && info1.getGroupUuid() != null
+            && info1.getGroupUuid().equals(info2.getGroupUuid()));
+    }
+
+    boolean keepCellularValidationBitInSwitch(int sourceSubId, int destSubId) {
+        return mValidatedTransports.get(TRANSPORT_CELLULAR)
+                && isInGroupDataSwitch(sourceSubId, destSubId);
+    }
+
     public DataSaverController getDataSaverController() {
         return mDataSaverController;
     }
@@ -794,6 +825,8 @@
             }
         }
 
+        if (mForceCellularValidated) mValidatedTransports.set(TRANSPORT_CELLULAR);
+
         if (CHATTY) {
             Log.d(TAG, "updateConnectivity: mConnectedTransports=" + mConnectedTransports);
             Log.d(TAG, "updateConnectivity: mValidatedTransports=" + mValidatedTransports);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
index 5a8ff4b..7f4d614 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
@@ -19,7 +19,7 @@
 
 import static android.telephony.SubscriptionManager.DATA_ROAMING_DISABLE;
 import static android.telephony.SubscriptionManager.DATA_ROAMING_ENABLE;
-import static android.telephony.SubscriptionManager.NAME_SOURCE_DEFAULT;
+import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
 
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.TestCase.assertFalse;
@@ -79,14 +79,14 @@
     private static final String TEST_CARRIER_2 = "TEST_CARRIER_2";
     private static final int TEST_CARRIER_ID = 1;
     private static final SubscriptionInfo TEST_SUBSCRIPTION = new SubscriptionInfo(0, "", 0,
-            TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_DEFAULT, 0xFFFFFF, "",
+            TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "",
             DATA_ROAMING_DISABLE, null, null, null, null, false, null, "", false, null,
             TEST_CARRIER_ID, 0);
     private static final SubscriptionInfo TEST_SUBSCRIPTION_NULL = new SubscriptionInfo(0, "", 0,
-            TEST_CARRIER, null, NAME_SOURCE_DEFAULT, 0xFFFFFF, "", DATA_ROAMING_DISABLE,
+            TEST_CARRIER, null, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "", DATA_ROAMING_DISABLE,
             null, null, null, null, false, null, "");
     private static final SubscriptionInfo TEST_SUBSCRIPTION_ROAMING = new SubscriptionInfo(0, "", 0,
-            TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_DEFAULT, 0xFFFFFF, "",
+            TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "",
             DATA_ROAMING_ENABLE, null, null, null, null, false, null, "");
     @Mock
     private WifiManager mWifiManager;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 78687a2..9271caf 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -17,7 +17,7 @@
 package com.android.keyguard;
 
 import static android.telephony.SubscriptionManager.DATA_ROAMING_DISABLE;
-import static android.telephony.SubscriptionManager.NAME_SOURCE_DEFAULT;
+import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -83,11 +83,11 @@
     private static final int TEST_CARRIER_ID = 1;
     private static final String TEST_GROUP_UUID = "59b5c870-fc4c-47a4-a99e-9db826b48b24";
     private static final SubscriptionInfo TEST_SUBSCRIPTION = new SubscriptionInfo(1, "", 0,
-            TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_DEFAULT, 0xFFFFFF, "",
+            TEST_CARRIER, TEST_CARRIER, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "",
             DATA_ROAMING_DISABLE, null, null, null, null, false, null, "", false, TEST_GROUP_UUID,
             TEST_CARRIER_ID, 0);
     private static final SubscriptionInfo TEST_SUBSCRIPTION_2 = new SubscriptionInfo(2, "", 0,
-            TEST_CARRIER, TEST_CARRIER_2, NAME_SOURCE_DEFAULT, 0xFFFFFF, "",
+            TEST_CARRIER, TEST_CARRIER_2, NAME_SOURCE_CARRIER_ID, 0xFFFFFF, "",
             DATA_ROAMING_DISABLE, null, null, null, null, false, null, "", true, TEST_GROUP_UUID,
             TEST_CARRIER_ID, 0);
     @Mock
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 2649054..698185f 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
@@ -176,7 +176,7 @@
     protected void setupNetworkController() {
         // For now just pretend to be the data sim, so we can test that too.
         mSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
-        when(mMockTm.isDataConnectionEnabled()).thenReturn(true);
+        when(mMockTm.isDataConnectionAllowed()).thenReturn(true);
         setDefaultSubId(mSubId);
         setSubscriptions(mSubId);
         mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 6b02ff0..bac1b8c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -119,7 +119,7 @@
     @Test
     public void testNoInternetIcon_withDefaultSub() {
         setupNetworkController();
-        when(mMockTm.isDataConnectionEnabled()).thenReturn(false);
+        when(mMockTm.isDataConnectionAllowed()).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0);
         setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -133,7 +133,7 @@
     @Test
     public void testDataDisabledIcon_withDefaultSub() {
         setupNetworkController();
-        when(mMockTm.isDataConnectionEnabled()).thenReturn(false);
+        when(mMockTm.isDataConnectionAllowed()).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
         setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -147,7 +147,7 @@
     @Test
     public void testNonDefaultSIM_showsFullSignal_connected() {
         setupNetworkController();
-        when(mMockTm.isDataConnectionEnabled()).thenReturn(false);
+        when(mMockTm.isDataConnectionAllowed()).thenReturn(false);
         setupDefaultSignal();
         setDefaultSubId(mSubId + 1);
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0);
@@ -162,7 +162,7 @@
     @Test
     public void testNonDefaultSIM_showsFullSignal_disconnected() {
         setupNetworkController();
-        when(mMockTm.isDataConnectionEnabled()).thenReturn(false);
+        when(mMockTm.isDataConnectionAllowed()).thenReturn(false);
         setupDefaultSignal();
         setDefaultSubId(mSubId + 1);
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
@@ -177,7 +177,7 @@
     @Test
     public void testDataDisabledIcon_UserNotSetup() {
         setupNetworkController();
-        when(mMockTm.isDataConnectionEnabled()).thenReturn(false);
+        when(mMockTm.isDataConnectionAllowed()).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
         setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -192,7 +192,7 @@
     @Test
     public void testAlwaysShowDataRatIcon() {
         setupDefaultSignal();
-        when(mMockTm.isDataConnectionEnabled()).thenReturn(false);
+        when(mMockTm.isDataConnectionAllowed()).thenReturn(false);
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED,
                 TelephonyManager.NETWORK_TYPE_GSM);
 
diff --git a/packages/Tethering/AndroidManifest.xml b/packages/Tethering/AndroidManifest.xml
index c71d0d7..9328611 100644
--- a/packages/Tethering/AndroidManifest.xml
+++ b/packages/Tethering/AndroidManifest.xml
@@ -27,7 +27,7 @@
          added to the privileged permissions whitelist for that package. -->
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
-    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
     <uses-permission android:name="android.permission.BROADCAST_STICKY" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
     <uses-permission android:name="android.permission.MANAGE_USB" />
diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp
index 5b73dd5..00d0d9c 100644
--- a/packages/Tethering/common/TetheringLib/Android.bp
+++ b/packages/Tethering/common/TetheringLib/Android.bp
@@ -60,28 +60,17 @@
     hostdex: true, // for hiddenapi check
     visibility: ["//frameworks/base/packages/Tethering:__subpackages__"],
     apex_available: ["com.android.tethering"],
+    permitted_packages: ["android.net"],
 }
 
-droidstubs {
-    name: "framework-tethering-stubs-sources",
-    defaults: ["framework-module-stubs-defaults-module_libs_api"],
+stubs_defaults {
+    name: "framework-tethering-stubs-defaults",
     srcs: [
         "src/android/net/TetheredClient.java",
         "src/android/net/TetheringManager.java",
         "src/android/net/TetheringConstants.java",
     ],
-    libs: [
-        "tethering-aidl-interfaces-java",
-        "framework-all",
-    ],
-    sdk_version: "core_platform",
-}
-
-java_library {
-    name: "framework-tethering-stubs",
-    srcs: [":framework-tethering-stubs-sources"],
-    libs: ["framework-all"],
-    sdk_version: "core_platform",
+    libs: ["tethering-aidl-interfaces-java"],
 }
 
 filegroup {
@@ -101,3 +90,53 @@
     ],
     path: "src"
 }
+
+droidstubs {
+    name: "framework-tethering-stubs-srcs-publicapi",
+    defaults: [
+        "framework-module-stubs-defaults-publicapi",
+        "framework-tethering-stubs-defaults",
+    ],
+}
+
+droidstubs {
+    name: "framework-tethering-stubs-srcs-systemapi",
+    defaults: [
+        "framework-module-stubs-defaults-systemapi",
+        "framework-tethering-stubs-defaults",
+    ],
+}
+
+droidstubs {
+    name: "framework-tethering-api-module_libs_api",
+    defaults: [
+        "framework-module-api-defaults-module_libs_api",
+        "framework-tethering-stubs-defaults",
+    ],
+}
+
+droidstubs {
+    name: "framework-tethering-stubs-srcs-module_libs_api",
+    defaults: [
+        "framework-module-stubs-defaults-module_libs_api",
+        "framework-tethering-stubs-defaults",
+    ],
+}
+
+java_library {
+    name: "framework-tethering-stubs-publicapi",
+    srcs: [":framework-tethering-stubs-srcs-publicapi"],
+    sdk_version: "current",
+}
+
+java_library {
+    name: "framework-tethering-stubs-systemapi",
+    srcs: [":framework-tethering-stubs-srcs-systemapi"],
+    sdk_version: "system_current",
+}
+
+java_library {
+    name: "framework-tethering-stubs-module_libs_api",
+    srcs: [":framework-tethering-stubs-srcs-module_libs_api"],
+    sdk_version: "module_current",
+}
diff --git a/packages/Tethering/common/TetheringLib/api/current.txt b/packages/Tethering/common/TetheringLib/api/current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Tethering/common/TetheringLib/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Tethering/common/TetheringLib/api/module-lib-current.txt b/packages/Tethering/common/TetheringLib/api/module-lib-current.txt
new file mode 100644
index 0000000..754584e
--- /dev/null
+++ b/packages/Tethering/common/TetheringLib/api/module-lib-current.txt
@@ -0,0 +1,129 @@
+// Signature format: 2.0
+package android.net {
+
+  public final class TetheredClient implements android.os.Parcelable {
+    ctor public TetheredClient(@NonNull android.net.MacAddress, @NonNull java.util.Collection<android.net.TetheredClient.AddressInfo>, int);
+    method public int describeContents();
+    method @NonNull public java.util.List<android.net.TetheredClient.AddressInfo> getAddresses();
+    method @NonNull public android.net.MacAddress getMacAddress();
+    method public int getTetheringType();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient> CREATOR;
+  }
+
+  public static final class TetheredClient.AddressInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.net.LinkAddress getAddress();
+    method @Nullable public String getHostname();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR;
+  }
+
+  public final class TetheringConstants {
+    field public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
+    field public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback";
+    field public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType";
+    field public static final String EXTRA_RUN_PROVISION = "extraRunProvision";
+    field public static final String EXTRA_SET_ALARM = "extraSetAlarm";
+  }
+
+  public class TetheringManager {
+    ctor public TetheringManager(@NonNull android.content.Context, @NonNull java.util.function.Supplier<android.os.IBinder>);
+    method public int getLastTetherError(@NonNull String);
+    method @NonNull public String[] getTetherableBluetoothRegexs();
+    method @NonNull public String[] getTetherableIfaces();
+    method @NonNull public String[] getTetherableUsbRegexs();
+    method @NonNull public String[] getTetherableWifiRegexs();
+    method @NonNull public String[] getTetheredIfaces();
+    method @NonNull public String[] getTetheringErroredIfaces();
+    method public boolean isTetheringSupported();
+    method public boolean isTetheringSupported(@NonNull String);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
+    method public void requestLatestTetheringEntitlementResult(int, @NonNull android.os.ResultReceiver, boolean);
+    method @Deprecated public int setUsbTethering(boolean);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
+    method @Deprecated public int tether(@NonNull String);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
+    method @Deprecated public int untether(@NonNull String);
+    field public static final String ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED";
+    field public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY";
+    field public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
+    field public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
+    field public static final String EXTRA_ERRORED_TETHER = "erroredArray";
+    field public static final int TETHERING_BLUETOOTH = 2; // 0x2
+    field public static final int TETHERING_ETHERNET = 5; // 0x5
+    field public static final int TETHERING_INVALID = -1; // 0xffffffff
+    field public static final int TETHERING_NCM = 4; // 0x4
+    field public static final int TETHERING_USB = 1; // 0x1
+    field public static final int TETHERING_WIFI = 0; // 0x0
+    field public static final int TETHERING_WIFI_P2P = 3; // 0x3
+    field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc
+    field public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; // 0x9
+    field public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; // 0x8
+    field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd
+    field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa
+    field public static final int TETHER_ERROR_INTERNAL_ERROR = 5; // 0x5
+    field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf
+    field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe
+    field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
+    field public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; // 0xb
+    field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2
+    field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6
+    field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4
+    field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1
+    field public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; // 0x10
+    field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3
+    field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7
+    field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2
+    field public static final int TETHER_HARDWARE_OFFLOAD_STARTED = 1; // 0x1
+    field public static final int TETHER_HARDWARE_OFFLOAD_STOPPED = 0; // 0x0
+  }
+
+  public static interface TetheringManager.OnTetheringEntitlementResultListener {
+    method public void onTetheringEntitlementResult(int);
+  }
+
+  public static interface TetheringManager.StartTetheringCallback {
+    method public default void onTetheringFailed(int);
+    method public default void onTetheringStarted();
+  }
+
+  public static interface TetheringManager.TetheringEventCallback {
+    method public default void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
+    method public default void onError(@NonNull String, int);
+    method public default void onOffloadStatusChanged(int);
+    method public default void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps);
+    method public default void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+    method public default void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+    method public default void onTetheringSupported(boolean);
+    method public default void onUpstreamChanged(@Nullable android.net.Network);
+  }
+
+  public static class TetheringManager.TetheringInterfaceRegexps {
+    method @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs();
+    method @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs();
+    method @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs();
+  }
+
+  public static class TetheringManager.TetheringRequest {
+    method @Nullable public android.net.LinkAddress getClientStaticIpv4Address();
+    method @Nullable public android.net.LinkAddress getLocalIpv4Address();
+    method public boolean getShouldShowEntitlementUi();
+    method public int getTetheringType();
+    method public boolean isExemptFromEntitlementCheck();
+  }
+
+  public static class TetheringManager.TetheringRequest.Builder {
+    ctor public TetheringManager.TetheringRequest.Builder(int);
+    method @NonNull public android.net.TetheringManager.TetheringRequest build();
+    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress);
+  }
+
+}
+
diff --git a/packages/Tethering/common/TetheringLib/api/module-lib-removed.txt b/packages/Tethering/common/TetheringLib/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Tethering/common/TetheringLib/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Tethering/common/TetheringLib/api/removed.txt b/packages/Tethering/common/TetheringLib/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Tethering/common/TetheringLib/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Tethering/common/TetheringLib/api/system-current.txt b/packages/Tethering/common/TetheringLib/api/system-current.txt
new file mode 100644
index 0000000..edd1ebb
--- /dev/null
+++ b/packages/Tethering/common/TetheringLib/api/system-current.txt
@@ -0,0 +1,99 @@
+// Signature format: 2.0
+package android.net {
+
+  public final class TetheredClient implements android.os.Parcelable {
+    ctor public TetheredClient(@NonNull android.net.MacAddress, @NonNull java.util.Collection<android.net.TetheredClient.AddressInfo>, int);
+    method public int describeContents();
+    method @NonNull public java.util.List<android.net.TetheredClient.AddressInfo> getAddresses();
+    method @NonNull public android.net.MacAddress getMacAddress();
+    method public int getTetheringType();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient> CREATOR;
+  }
+
+  public static final class TetheredClient.AddressInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.net.LinkAddress getAddress();
+    method @Nullable public String getHostname();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR;
+  }
+
+  public class TetheringManager {
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering();
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int);
+    method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback);
+    field public static final String ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED";
+    field public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY";
+    field public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
+    field public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
+    field public static final String EXTRA_ERRORED_TETHER = "erroredArray";
+    field public static final int TETHERING_BLUETOOTH = 2; // 0x2
+    field public static final int TETHERING_ETHERNET = 5; // 0x5
+    field public static final int TETHERING_INVALID = -1; // 0xffffffff
+    field public static final int TETHERING_NCM = 4; // 0x4
+    field public static final int TETHERING_USB = 1; // 0x1
+    field public static final int TETHERING_WIFI = 0; // 0x0
+    field public static final int TETHERING_WIFI_P2P = 3; // 0x3
+    field public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12; // 0xc
+    field public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9; // 0x9
+    field public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8; // 0x8
+    field public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13; // 0xd
+    field public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10; // 0xa
+    field public static final int TETHER_ERROR_INTERNAL_ERROR = 5; // 0x5
+    field public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15; // 0xf
+    field public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14; // 0xe
+    field public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
+    field public static final int TETHER_ERROR_PROVISIONING_FAILED = 11; // 0xb
+    field public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2; // 0x2
+    field public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6; // 0x6
+    field public static final int TETHER_ERROR_UNAVAIL_IFACE = 4; // 0x4
+    field public static final int TETHER_ERROR_UNKNOWN_IFACE = 1; // 0x1
+    field public static final int TETHER_ERROR_UNKNOWN_TYPE = 16; // 0x10
+    field public static final int TETHER_ERROR_UNSUPPORTED = 3; // 0x3
+    field public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7; // 0x7
+    field public static final int TETHER_HARDWARE_OFFLOAD_FAILED = 2; // 0x2
+    field public static final int TETHER_HARDWARE_OFFLOAD_STARTED = 1; // 0x1
+    field public static final int TETHER_HARDWARE_OFFLOAD_STOPPED = 0; // 0x0
+  }
+
+  public static interface TetheringManager.OnTetheringEntitlementResultListener {
+    method public void onTetheringEntitlementResult(int);
+  }
+
+  public static interface TetheringManager.StartTetheringCallback {
+    method public default void onTetheringFailed(int);
+    method public default void onTetheringStarted();
+  }
+
+  public static interface TetheringManager.TetheringEventCallback {
+    method public default void onClientsChanged(@NonNull java.util.Collection<android.net.TetheredClient>);
+    method public default void onError(@NonNull String, int);
+    method public default void onOffloadStatusChanged(int);
+    method public default void onTetherableInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+    method public default void onTetheredInterfacesChanged(@NonNull java.util.List<java.lang.String>);
+    method public default void onTetheringSupported(boolean);
+    method public default void onUpstreamChanged(@Nullable android.net.Network);
+  }
+
+  public static class TetheringManager.TetheringRequest {
+    method @Nullable public android.net.LinkAddress getClientStaticIpv4Address();
+    method @Nullable public android.net.LinkAddress getLocalIpv4Address();
+    method public boolean getShouldShowEntitlementUi();
+    method public int getTetheringType();
+    method public boolean isExemptFromEntitlementCheck();
+  }
+
+  public static class TetheringManager.TetheringRequest.Builder {
+    ctor public TetheringManager.TetheringRequest.Builder(int);
+    method @NonNull public android.net.TetheringManager.TetheringRequest build();
+    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress);
+  }
+
+}
+
diff --git a/packages/Tethering/common/TetheringLib/api/system-removed.txt b/packages/Tethering/common/TetheringLib/api/system-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Tethering/common/TetheringLib/api/system-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java
index 8b8b9e5..48be0d9 100644
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java
+++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java
@@ -64,16 +64,26 @@
         dest.writeInt(mTetheringType);
     }
 
+    /**
+     * Get the MAC address used to identify the client.
+     */
     @NonNull
     public MacAddress getMacAddress() {
         return mMacAddress;
     }
 
+    /**
+     * Get information on the list of addresses that are associated with the client.
+     */
     @NonNull
     public List<AddressInfo> getAddresses() {
         return new ArrayList<>(mAddresses);
     }
 
+    /**
+     * Get the type of tethering used by the client.
+     * @return one of the {@code TetheringManager#TETHERING_*} constants.
+     */
     public int getTetheringType() {
         return mTetheringType;
     }
@@ -115,45 +125,47 @@
         private final LinkAddress mAddress;
         @Nullable
         private final String mHostname;
-        // TODO: use LinkAddress expiration time once it is supported
-        private final long mExpirationTime;
 
         /** @hide */
         public AddressInfo(@NonNull LinkAddress address, @Nullable String hostname) {
-            this(address, hostname, 0);
-        }
-
-        /** @hide */
-        public AddressInfo(@NonNull LinkAddress address, String hostname, long expirationTime) {
             this.mAddress = address;
             this.mHostname = hostname;
-            this.mExpirationTime = expirationTime;
         }
 
         private AddressInfo(Parcel in) {
-            this(in.readParcelable(null),  in.readString(), in.readLong());
+            this(in.readParcelable(null),  in.readString());
         }
 
         @Override
         public void writeToParcel(@NonNull Parcel dest, int flags) {
             dest.writeParcelable(mAddress, flags);
             dest.writeString(mHostname);
-            dest.writeLong(mExpirationTime);
         }
 
+        /**
+         * Get the link address (including prefix length and lifetime) used by the client.
+         *
+         * This may be an IPv4 or IPv6 address.
+         */
         @NonNull
         public LinkAddress getAddress() {
             return mAddress;
         }
 
+        /**
+         * Get the hostname that was advertised by the client when obtaining its address, if any.
+         */
         @Nullable
         public String getHostname() {
             return mHostname;
         }
 
-        /** @hide TODO: use expiration time in LinkAddress */
+        /**
+         * Get the expiration time of the address assigned to the client.
+         * @hide
+         */
         public long getExpirationTime() {
-            return mExpirationTime;
+            return mAddress.getExpirationTime();
         }
 
         @Override
@@ -163,7 +175,7 @@
 
         @Override
         public int hashCode() {
-            return Objects.hash(mAddress, mHostname, mExpirationTime);
+            return Objects.hash(mAddress, mHostname);
         }
 
         @Override
@@ -173,8 +185,7 @@
             // Use .equals() for addresses as all changes, including address expiry changes,
             // should be included.
             return other.mAddress.equals(mAddress)
-                    && Objects.equals(mHostname, other.mHostname)
-                    && mExpirationTime == other.mExpirationTime;
+                    && Objects.equals(mHostname, other.mHostname);
         }
 
         @NonNull
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java
index a18f5da..fd6f171 100644
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java
+++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java
@@ -32,7 +32,7 @@
  * @hide
  */
 @SystemApi(client = MODULE_LIBRARIES)
-public class TetheringConstants {
+public final class TetheringConstants {
     /** An explicit private class to avoid exposing constructor.*/
     private TetheringConstants() { }
 
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
index 5d680b0..0107a7e 100644
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
+++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
@@ -115,6 +115,19 @@
      */
     public static final String EXTRA_ERRORED_TETHER = "erroredArray";
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = false, value = {
+            TETHERING_WIFI,
+            TETHERING_USB,
+            TETHERING_BLUETOOTH,
+            TETHERING_WIFI_P2P,
+            TETHERING_NCM,
+            TETHERING_ETHERNET,
+    })
+    public @interface TetheringType {
+    }
+
     /**
      * Invalid tethering type.
      * @see #startTethering.
@@ -158,22 +171,60 @@
      */
     public static final int TETHERING_ETHERNET = 5;
 
-    public static final int TETHER_ERROR_NO_ERROR           = 0;
-    public static final int TETHER_ERROR_UNKNOWN_IFACE      = 1;
-    public static final int TETHER_ERROR_SERVICE_UNAVAIL    = 2;
-    public static final int TETHER_ERROR_UNSUPPORTED        = 3;
-    public static final int TETHER_ERROR_UNAVAIL_IFACE      = 4;
-    public static final int TETHER_ERROR_MASTER_ERROR       = 5;
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            TETHER_ERROR_NO_ERROR,
+            TETHER_ERROR_PROVISIONING_FAILED,
+            TETHER_ERROR_ENTITLEMENT_UNKNOWN,
+    })
+    public @interface EntitlementResult {
+    }
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            TETHER_ERROR_NO_ERROR,
+            TETHER_ERROR_UNKNOWN_IFACE,
+            TETHER_ERROR_SERVICE_UNAVAIL,
+            TETHER_ERROR_INTERNAL_ERROR,
+            TETHER_ERROR_TETHER_IFACE_ERROR,
+            TETHER_ERROR_ENABLE_FORWARDING_ERROR,
+            TETHER_ERROR_DISABLE_FORWARDING_ERROR,
+            TETHER_ERROR_IFACE_CFG_ERROR,
+            TETHER_ERROR_DHCPSERVER_ERROR,
+    })
+    public @interface TetheringIfaceError {
+    }
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            TETHER_ERROR_SERVICE_UNAVAIL,
+            TETHER_ERROR_INTERNAL_ERROR,
+            TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION,
+            TETHER_ERROR_UNKNOWN_TYPE,
+    })
+    public @interface StartTetheringError {
+    }
+
+    public static final int TETHER_ERROR_NO_ERROR = 0;
+    public static final int TETHER_ERROR_UNKNOWN_IFACE = 1;
+    public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2;
+    public static final int TETHER_ERROR_UNSUPPORTED = 3;
+    public static final int TETHER_ERROR_UNAVAIL_IFACE = 4;
+    public static final int TETHER_ERROR_INTERNAL_ERROR = 5;
     public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
     public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
-    public static final int TETHER_ERROR_ENABLE_NAT_ERROR     = 8;
-    public static final int TETHER_ERROR_DISABLE_NAT_ERROR    = 9;
-    public static final int TETHER_ERROR_IFACE_CFG_ERROR      = 10;
-    public static final int TETHER_ERROR_PROVISION_FAILED     = 11;
-    public static final int TETHER_ERROR_DHCPSERVER_ERROR     = 12;
+    public static final int TETHER_ERROR_ENABLE_FORWARDING_ERROR = 8;
+    public static final int TETHER_ERROR_DISABLE_FORWARDING_ERROR = 9;
+    public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10;
+    public static final int TETHER_ERROR_PROVISIONING_FAILED = 11;
+    public static final int TETHER_ERROR_DHCPSERVER_ERROR = 12;
     public static final int TETHER_ERROR_ENTITLEMENT_UNKNOWN = 13;
     public static final int TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION = 14;
     public static final int TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION = 15;
+    public static final int TETHER_ERROR_UNKNOWN_TYPE = 16;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -508,23 +559,36 @@
             private final TetheringRequestParcel mBuilderParcel;
 
             /** Default constructor of Builder. */
-            public Builder(final int type) {
+            public Builder(@TetheringType final int type) {
                 mBuilderParcel = new TetheringRequestParcel();
                 mBuilderParcel.tetheringType = type;
                 mBuilderParcel.localIPv4Address = null;
+                mBuilderParcel.staticClientAddress = null;
                 mBuilderParcel.exemptFromEntitlementCheck = false;
                 mBuilderParcel.showProvisioningUi = true;
             }
 
             /**
-             * Configure tethering with static IPv4 assignment (with DHCP disabled).
+             * Configure tethering with static IPv4 assignment.
              *
-             * @param localIPv4Address The preferred local IPv4 address to use.
+             * A DHCP server will be started, but will only be able to offer the client address.
+             * The two addresses must be in the same prefix.
+             *
+             * @param localIPv4Address The preferred local IPv4 link address to use.
+             * @param clientAddress The static client address.
              */
             @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
             @NonNull
-            public Builder useStaticIpv4Addresses(@NonNull final LinkAddress localIPv4Address) {
+            public Builder setStaticIpv4Addresses(@NonNull final LinkAddress localIPv4Address,
+                    @NonNull final LinkAddress clientAddress) {
+                Objects.requireNonNull(localIPv4Address);
+                Objects.requireNonNull(clientAddress);
+                if (!checkStaticAddressConfiguration(localIPv4Address, clientAddress)) {
+                    throw new IllegalArgumentException("Invalid server or client addresses");
+                }
+
                 mBuilderParcel.localIPv4Address = localIPv4Address;
+                mBuilderParcel.staticClientAddress = clientAddress;
                 return this;
             }
 
@@ -536,11 +600,14 @@
                 return this;
             }
 
-            /** Start tethering without showing the provisioning UI. */
+            /**
+             * If an entitlement check is needed, sets whether to show the entitlement UI or to
+             * perform a silent entitlement check. By default, the entitlement UI is shown.
+             */
             @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
             @NonNull
-            public Builder setSilentProvisioning(boolean silent) {
-                mBuilderParcel.showProvisioningUi = silent;
+            public Builder setShouldShowEntitlementUi(boolean showUi) {
+                mBuilderParcel.showProvisioningUi = showUi;
                 return this;
             }
 
@@ -552,6 +619,53 @@
         }
 
         /**
+         * Get the local IPv4 address, if one was configured with
+         * {@link Builder#setStaticIpv4Addresses}.
+         */
+        @Nullable
+        public LinkAddress getLocalIpv4Address() {
+            return mRequestParcel.localIPv4Address;
+        }
+
+        /**
+         * Get the static IPv4 address of the client, if one was configured with
+         * {@link Builder#setStaticIpv4Addresses}.
+         */
+        @Nullable
+        public LinkAddress getClientStaticIpv4Address() {
+            return mRequestParcel.staticClientAddress;
+        }
+
+        /** Get tethering type. */
+        @TetheringType
+        public int getTetheringType() {
+            return mRequestParcel.tetheringType;
+        }
+
+        /** Check if exempt from entitlement check. */
+        public boolean isExemptFromEntitlementCheck() {
+            return mRequestParcel.exemptFromEntitlementCheck;
+        }
+
+        /** Check if show entitlement ui.  */
+        public boolean getShouldShowEntitlementUi() {
+            return mRequestParcel.showProvisioningUi;
+        }
+
+        /**
+         * Check whether the two addresses are ipv4 and in the same prefix.
+         * @hide
+         */
+        public static boolean checkStaticAddressConfiguration(
+                @NonNull final LinkAddress localIPv4Address,
+                @NonNull final LinkAddress clientAddress) {
+            return localIPv4Address.getPrefixLength() == clientAddress.getPrefixLength()
+                    && localIPv4Address.isIpv4() && clientAddress.isIpv4()
+                    && new IpPrefix(localIPv4Address.toString()).equals(
+                    new IpPrefix(clientAddress.toString()));
+        }
+
+        /**
          * Get a TetheringRequestParcel from the configuration
          * @hide
          */
@@ -563,6 +677,7 @@
         public String toString() {
             return "TetheringRequest [ type= " + mRequestParcel.tetheringType
                     + ", localIPv4Address= " + mRequestParcel.localIPv4Address
+                    + ", staticClientAddress= " + mRequestParcel.staticClientAddress
                     + ", exemptFromEntitlementCheck= "
                     + mRequestParcel.exemptFromEntitlementCheck + ", showProvisioningUi= "
                     + mRequestParcel.showProvisioningUi + " ]";
@@ -572,18 +687,18 @@
     /**
      * Callback for use with {@link #startTethering} to find out whether tethering succeeded.
      */
-    public abstract static class StartTetheringCallback {
+    public interface StartTetheringCallback {
         /**
          * Called when tethering has been successfully started.
          */
-        public void onTetheringStarted() {}
+        default void onTetheringStarted() {}
 
         /**
          * Called when starting tethering failed.
          *
-         * @param resultCode One of the {@code TETHER_ERROR_*} constants.
+         * @param error The error that caused the failure.
          */
-        public void onTetheringFailed(final int resultCode) {}
+        default void onTetheringFailed(@StartTetheringError final int error) {}
     }
 
     /**
@@ -633,11 +748,13 @@
      * @param type The tethering type, on of the {@code TetheringManager#TETHERING_*} constants.
      * @param executor {@link Executor} to specify the thread upon which the callback of
      *         TetheringRequest will be invoked.
+     * @hide
      */
     @RequiresPermission(anyOf = {
             android.Manifest.permission.TETHER_PRIVILEGED,
             android.Manifest.permission.WRITE_SETTINGS
     })
+    @SystemApi(client = MODULE_LIBRARIES)
     public void startTethering(int type, @NonNull final Executor executor,
             @NonNull final StartTetheringCallback callback) {
         startTethering(new TetheringRequest.Builder(type).build(), executor, callback);
@@ -654,7 +771,7 @@
             android.Manifest.permission.TETHER_PRIVILEGED,
             android.Manifest.permission.WRITE_SETTINGS
     })
-    public void stopTethering(final int type) {
+    public void stopTethering(@TetheringType final int type) {
         final String callerPkg = mContext.getOpPackageName();
         Log.i(TAG, "stopTethering caller:" + callerPkg);
 
@@ -679,10 +796,10 @@
          *
          * @param resultCode an int value of entitlement result. It may be one of
          *         {@link #TETHER_ERROR_NO_ERROR},
-         *         {@link #TETHER_ERROR_PROVISION_FAILED}, or
+         *         {@link #TETHER_ERROR_PROVISIONING_FAILED}, or
          *         {@link #TETHER_ERROR_ENTITLEMENT_UNKNOWN}.
          */
-        void onTetheringEntitlementResult(int resultCode);
+        void onTetheringEntitlementResult(@EntitlementResult int result);
     }
 
     /**
@@ -697,7 +814,8 @@
      * fail if a tethering entitlement check is required.
      *
      * @param type the downstream type of tethering. Must be one of {@code #TETHERING_*} constants.
-     * @param showEntitlementUi a boolean indicating whether to run UI-based entitlement check.
+     * @param showEntitlementUi a boolean indicating whether to check result for the UI-based
+     *         entitlement check or the silent entitlement check.
      * @param executor the executor on which callback will be invoked.
      * @param listener an {@link OnTetheringEntitlementResultListener} which will be called to
      *         notify the caller of the result of entitlement check. The listener may be called zero
@@ -707,7 +825,8 @@
             android.Manifest.permission.TETHER_PRIVILEGED,
             android.Manifest.permission.WRITE_SETTINGS
     })
-    public void requestLatestTetheringEntitlementResult(int type, boolean showEntitlementUi,
+    public void requestLatestTetheringEntitlementResult(@TetheringType int type,
+            boolean showEntitlementUi,
             @NonNull Executor executor,
             @NonNull final OnTetheringEntitlementResultListener listener) {
         if (listener == null) {
@@ -736,7 +855,7 @@
      */
     // TODO: improve the usage of ResultReceiver, b/145096122
     @SystemApi(client = MODULE_LIBRARIES)
-    public void requestLatestTetheringEntitlementResult(final int type,
+    public void requestLatestTetheringEntitlementResult(@TetheringType final int type,
             @NonNull final ResultReceiver receiver, final boolean showEntitlementUi) {
         final String callerPkg = mContext.getOpPackageName();
         Log.i(TAG, "getLatestTetheringEntitlementResult caller:" + callerPkg);
@@ -749,7 +868,7 @@
      * Callback for use with {@link registerTetheringEventCallback} to find out tethering
      * upstream status.
      */
-    public abstract static class TetheringEventCallback {
+    public interface TetheringEventCallback {
         /**
          * Called when tethering supported status changed.
          *
@@ -761,7 +880,7 @@
          *
          * @param supported The new supported status
          */
-        public void onTetheringSupported(boolean supported) {}
+        default void onTetheringSupported(boolean supported) {}
 
         /**
          * Called when tethering upstream changed.
@@ -772,7 +891,7 @@
          * @param network the {@link Network} of tethering upstream. Null means tethering doesn't
          * have any upstream.
          */
-        public void onUpstreamChanged(@Nullable Network network) {}
+        default void onUpstreamChanged(@Nullable Network network) {}
 
         /**
          * Called when there was a change in tethering interface regular expressions.
@@ -780,28 +899,30 @@
          * <p>This will be called immediately after the callback is registered, and may be called
          * multiple times later upon changes.
          * @param reg The new regular expressions.
-         * @deprecated Referencing interfaces by regular expressions is a deprecated mechanism.
+         *
+         * @hide
          */
-        @Deprecated
-        public void onTetherableInterfaceRegexpsChanged(@NonNull TetheringInterfaceRegexps reg) {}
+        @SystemApi(client = MODULE_LIBRARIES)
+        default void onTetherableInterfaceRegexpsChanged(@NonNull TetheringInterfaceRegexps reg) {}
 
         /**
-         * Called when there was a change in the list of tetherable interfaces.
+         * Called when there was a change in the list of tetherable interfaces. Tetherable
+         * interface means this interface is available and can be used for tethering.
          *
          * <p>This will be called immediately after the callback is registered, and may be called
          * multiple times later upon changes.
-         * @param interfaces The list of tetherable interfaces.
+         * @param interfaces The list of tetherable interface names.
          */
-        public void onTetherableInterfacesChanged(@NonNull List<String> interfaces) {}
+        default void onTetherableInterfacesChanged(@NonNull List<String> interfaces) {}
 
         /**
          * Called when there was a change in the list of tethered interfaces.
          *
          * <p>This will be called immediately after the callback is registered, and may be called
          * multiple times later upon changes.
-         * @param interfaces The list of tethered interfaces.
+         * @param interfaces The list of 0 or more String of currently tethered interface names.
          */
-        public void onTetheredInterfacesChanged(@NonNull List<String> interfaces) {}
+        default void onTetheredInterfacesChanged(@NonNull List<String> interfaces) {}
 
         /**
          * Called when an error occurred configuring tethering.
@@ -811,7 +932,7 @@
          * @param ifName Name of the interface.
          * @param error One of {@code TetheringManager#TETHER_ERROR_*}.
          */
-        public void onError(@NonNull String ifName, int error) {}
+        default void onError(@NonNull String ifName, @TetheringIfaceError int error) {}
 
         /**
          * Called when the list of tethered clients changes.
@@ -824,7 +945,7 @@
          * determine if they are still connected.
          * @param clients The new set of tethered clients; the collection is not ordered.
          */
-        public void onClientsChanged(@NonNull Collection<TetheredClient> clients) {}
+        default void onClientsChanged(@NonNull Collection<TetheredClient> clients) {}
 
         /**
          * Called when tethering offload status changes.
@@ -832,19 +953,20 @@
          * <p>This will be called immediately after the callback is registered.
          * @param status The offload status.
          */
-        public void onOffloadStatusChanged(@TetherOffloadStatus int status) {}
+        default void onOffloadStatusChanged(@TetherOffloadStatus int status) {}
     }
 
     /**
      * Regular expressions used to identify tethering interfaces.
-     * @deprecated Referencing interfaces by regular expressions is a deprecated mechanism.
+     * @hide
      */
-    @Deprecated
+    @SystemApi(client = MODULE_LIBRARIES)
     public static class TetheringInterfaceRegexps {
         private final String[] mTetherableBluetoothRegexs;
         private final String[] mTetherableUsbRegexs;
         private final String[] mTetherableWifiRegexs;
 
+        /** @hide */
         public TetheringInterfaceRegexps(@NonNull String[] tetherableBluetoothRegexs,
                 @NonNull String[] tetherableUsbRegexs, @NonNull String[] tetherableWifiRegexs) {
             mTetherableBluetoothRegexs = tetherableBluetoothRegexs.clone();
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringRequestParcel.aidl b/packages/Tethering/common/TetheringLib/src/android/net/TetheringRequestParcel.aidl
index bf19d85f..c0280d3 100644
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringRequestParcel.aidl
+++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringRequestParcel.aidl
@@ -25,6 +25,7 @@
 parcelable TetheringRequestParcel {
     int tetheringType;
     LinkAddress localIPv4Address;
+    LinkAddress staticClientAddress;
     boolean exemptFromEntitlementCheck;
     boolean showProvisioningUi;
 }
diff --git a/packages/Tethering/res/values-af/strings.xml b/packages/Tethering/res/values-af/strings.xml
index 1258805..f06d1a2 100644
--- a/packages/Tethering/res/values-af/strings.xml
+++ b/packages/Tethering/res/values-af/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Verbinding of Wi-Fi-warmkol aktief"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tik om op te stel."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Verbinding is gedeaktiveer"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontak jou administrateur vir besonderhede"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Verbinding of warmkol is aktief"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tik om op te stel."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Verbinding is gedeaktiveer"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontak jou administrateur vir besonderhede"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Warmkol- en verbindingstatus"</string>
 </resources>
diff --git a/packages/Tethering/res/values-am/strings.xml b/packages/Tethering/res/values-am/strings.xml
index 9c36192..aa0e693 100644
--- a/packages/Tethering/res/values-am/strings.xml
+++ b/packages/Tethering/res/values-am/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"መሰካት ወይም ገባሪ ድረስ ነጥብ"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"ለማዋቀር መታ ያድርጉ።"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"እንደ ሞደም መሰካት ተሰናክሏል"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ለዝርዝሮች የእርስዎን አስተዳዳሪ ያነጋግሩ"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"እንደ ሞደም መሰካት ወይም መገናኛ ነጥብ ገባሪ"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"ለማዋቀር መታ ያድርጉ።"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"እንደ ሞደም መሰካት ተሰናክሏል"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"ለዝርዝሮች የእርስዎን አስተዳዳሪ ያነጋግሩ"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"መገናኛ ነጥብ እና እንደ ሞደም የመሰካት ሁኔታ"</string>
 </resources>
diff --git a/packages/Tethering/res/values-ar/strings.xml b/packages/Tethering/res/values-ar/strings.xml
index 9f84ce4..ce73720 100644
--- a/packages/Tethering/res/values-ar/strings.xml
+++ b/packages/Tethering/res/values-ar/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"النطاق أو نقطة الاتصال نشطة"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"انقر للإعداد."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"تم إيقاف التوصيل"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"اتصل بالمشرف للحصول على التفاصيل"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"النطاق نشط أو نقطة الاتصال نشطة"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"انقر للإعداد."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"التوصيل متوقف."</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"تواصَل مع المشرف للحصول على التفاصيل."</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"حالة نقطة الاتصال والتوصيل"</string>
 </resources>
diff --git a/packages/Tethering/res/values-as/strings.xml b/packages/Tethering/res/values-as/strings.xml
deleted file mode 100644
index 8855822..0000000
--- a/packages/Tethering/res/values-as/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"টেডাৰিং বা হটস্প\'ট সক্ৰিয় অৱস্থাত আছে"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"ছেট আপ কৰিবলৈ টিপক।"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"টেডাৰিং অক্ষম কৰি থোৱা হৈছে"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"সবিশেষ জানিবলৈ আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক"</string>
-</resources>
diff --git a/packages/Tethering/res/values-az/strings.xml b/packages/Tethering/res/values-az/strings.xml
index eba50eb..82661f4 100644
--- a/packages/Tethering/res/values-az/strings.xml
+++ b/packages/Tethering/res/values-az/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tezerinq və ya hotspot aktivdir"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Quraşdırmaq üçün tıklayın."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Birləşmə deaktivdir"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Məlumat üçün adminlə əlaqə saxlayın"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Birləşmə və ya hotspot aktivdir"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Ayarlamaq üçün toxunun."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Birləşmə deaktivdir"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Detallar üçün adminlə əlaqə saxlayın"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot &amp; birləşmə statusu"</string>
 </resources>
diff --git a/packages/Tethering/res/values-b+sr+Latn/strings.xml b/packages/Tethering/res/values-b+sr+Latn/strings.xml
index 5b0e488..0f1fb9e 100644
--- a/packages/Tethering/res/values-b+sr+Latn/strings.xml
+++ b/packages/Tethering/res/values-b+sr+Latn/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Aktivno povezivanje sa internetom preko mobilnog uređaja ili hotspot"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite da biste podesili."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Privezivanje je onemogućeno"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Potražite detalje od administratora"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Privezivanje ili hotspot je aktivan"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da biste podesili."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Privezivanje je onemogućeno"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Potražite detalje od administratora"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status hotspota i privezivanja"</string>
 </resources>
diff --git a/packages/Tethering/res/values-be/strings.xml b/packages/Tethering/res/values-be/strings.xml
index 5966c71..31c6957 100644
--- a/packages/Tethering/res/values-be/strings.xml
+++ b/packages/Tethering/res/values-be/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"USB-мадэм або хот-спот Wi-Fi актыўныя"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Дакраніцеся, каб наладзіць."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Рэжым мадэма адключаны"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Звярніцеся да адміністратара па падрабязную інфармацыю"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Мадэм або хот-спот актыўныя"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Дакраніцеся, каб наладзіць."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Рэжым мадэма выключаны"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Звярніцеся да адміністратара па падрабязную інфармацыю"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Стан \"Хот-спот і мадэм\""</string>
 </resources>
diff --git a/packages/Tethering/res/values-bg/strings.xml b/packages/Tethering/res/values-bg/strings.xml
index ed58d73..22d0320 100644
--- a/packages/Tethering/res/values-bg/strings.xml
+++ b/packages/Tethering/res/values-bg/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Има активна споделена връзка или безжична точка за достъп"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Докоснете, за да настроите."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Функцията за тетъринг е деактивирана"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Свържете се с администратора си за подробности"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Има активна споделена връзка или точка за достъп"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Докоснете, за да настроите."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Функцията за тетъринг е деактивирана"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Свържете се с администратора си за подробности"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Състояние на функцията за точка за достъп и тетъринг"</string>
 </resources>
diff --git a/packages/Tethering/res/values-bn/strings.xml b/packages/Tethering/res/values-bn/strings.xml
deleted file mode 100644
index 8d9880a..0000000
--- a/packages/Tethering/res/values-bn/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"টিথারিং বা হটস্পট সক্রিয় আছে"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"সেট-আপ করার জন্য আলতো চাপুন৷"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"টিথারিং অক্ষম করা আছে"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"বিশদ বিবরণের জন্য প্রশাসকের সাথে যোগাযোগ করুন"</string>
-</resources>
diff --git a/packages/Tethering/res/values-bs/strings.xml b/packages/Tethering/res/values-bs/strings.xml
index 2361b9d..f22180d 100644
--- a/packages/Tethering/res/values-bs/strings.xml
+++ b/packages/Tethering/res/values-bs/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Uređaj dijeli vezu ili djeluje kao pristupna tačka"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite za postavke"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Povezivanje putem mobitela je onemogućeno"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontaktirajte svog administratora za dodatne detalje"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Aktivno je povezivanje putem mobitela ili pristupna tačka"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da postavite."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Povezivanje putem mobitela je onemogućeno"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontaktirajte svog administratora za detalje"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status pristupne tačke i povezivanja putem mobitela"</string>
 </resources>
diff --git a/packages/Tethering/res/values-ca/strings.xml b/packages/Tethering/res/values-ca/strings.xml
index 6752b51..a91a9b4 100644
--- a/packages/Tethering/res/values-ca/strings.xml
+++ b/packages/Tethering/res/values-ca/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Compartició de xarxa o punt d\'accés Wi-Fi activat"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Toca per configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"La compartició de xarxa està desactivada"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacta amb el teu administrador per obtenir més informació"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Compartició de xarxa o punt d\'accés Wi‑Fi activat"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Toca per configurar."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"La compartició de xarxa està desactivada"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacta amb el teu administrador per obtenir més informació"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estat del punt d\'accés Wi‑Fi i de la compartició de xarxa"</string>
 </resources>
diff --git a/packages/Tethering/res/values-cs/strings.xml b/packages/Tethering/res/values-cs/strings.xml
index 5fdd53a..4a8ce53 100644
--- a/packages/Tethering/res/values-cs/strings.xml
+++ b/packages/Tethering/res/values-cs/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Sdílené připojení nebo hotspot je aktivní."</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Klepnutím zahájíte nastavení."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering je zakázán"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"O podrobnosti požádejte administrátora"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering nebo hotspot je aktivní"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Klepnutím zahájíte nastavení."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering je zakázán"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"O podrobnosti požádejte administrátora"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stav hotspotu a tetheringu"</string>
 </resources>
diff --git a/packages/Tethering/res/values-da/strings.xml b/packages/Tethering/res/values-da/strings.xml
index 2775dfa..1fe048b 100644
--- a/packages/Tethering/res/values-da/strings.xml
+++ b/packages/Tethering/res/values-da/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Netdeling eller hotspot er aktivt"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tryk for at konfigurere"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Netdeling er deaktiveret"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakt din administrator for at få oplysninger"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Netdeling eller hotspot er aktivt"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tryk for at konfigurere."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Netdeling er deaktiveret"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakt din administrator for at få oplysninger"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status for hotspot og netdeling"</string>
 </resources>
diff --git a/packages/Tethering/res/values-de/strings.xml b/packages/Tethering/res/values-de/strings.xml
deleted file mode 100644
index 9046cd5..0000000
--- a/packages/Tethering/res/values-de/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering oder Hotspot aktiv"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Zum Einrichten tippen."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering ist deaktiviert"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Bitte wende dich für weitere Informationen an den Administrator"</string>
-</resources>
diff --git a/packages/Tethering/res/values-el/strings.xml b/packages/Tethering/res/values-el/strings.xml
index 3b9f537..045d707 100644
--- a/packages/Tethering/res/values-el/strings.xml
+++ b/packages/Tethering/res/values-el/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Πρόσδεση ή σύνδεση σημείου πρόσβασης ενεργή"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Πατήστε για ρύθμιση."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Η σύνδεση είναι απενεργοποιημένη"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Επικοινωνήστε με τον διαχειριστή σας για λεπτομέρειες"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Πρόσδεση ή σύνδεση σημείου πρόσβασης ενεργή"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Πατήστε για ρύθμιση."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Η σύνδεση είναι απενεργοποιημένη"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Επικοινωνήστε με τον διαχειριστή σας για λεπτομέρειες"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Κατάσταση σημείου πρόσβασης Wi-Fi και σύνδεσης"</string>
 </resources>
diff --git a/packages/Tethering/res/values-en-rAU/strings.xml b/packages/Tethering/res/values-en-rAU/strings.xml
index 56b88a5..14bf2aa 100644
--- a/packages/Tethering/res/values-en-rAU/strings.xml
+++ b/packages/Tethering/res/values-en-rAU/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
 </resources>
diff --git a/packages/Tethering/res/values-en-rCA/strings.xml b/packages/Tethering/res/values-en-rCA/strings.xml
index 56b88a5..14bf2aa 100644
--- a/packages/Tethering/res/values-en-rCA/strings.xml
+++ b/packages/Tethering/res/values-en-rCA/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
 </resources>
diff --git a/packages/Tethering/res/values-en-rGB/strings.xml b/packages/Tethering/res/values-en-rGB/strings.xml
index 56b88a5..14bf2aa 100644
--- a/packages/Tethering/res/values-en-rGB/strings.xml
+++ b/packages/Tethering/res/values-en-rGB/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
 </resources>
diff --git a/packages/Tethering/res/values-en-rIN/strings.xml b/packages/Tethering/res/values-en-rIN/strings.xml
index 56b88a5..14bf2aa 100644
--- a/packages/Tethering/res/values-en-rIN/strings.xml
+++ b/packages/Tethering/res/values-en-rIN/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
 </resources>
diff --git a/packages/Tethering/res/values-en-rXC/strings.xml b/packages/Tethering/res/values-en-rXC/strings.xml
index 7f47fc8..43f504c 100644
--- a/packages/Tethering/res/values-en-rXC/strings.xml
+++ b/packages/Tethering/res/values-en-rXC/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎‏‎‎‏‎Tethering or hotspot active‎‏‎‎‏‎"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‏‎‎‏‎‏‎‎‎‏‎Tap to set up.‎‏‎‎‏‎"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‏‏‎Tethering is disabled‎‏‎‎‏‎"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‎Contact your admin for details‎‏‎‎‏‎"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎Tethering or hotspot active‎‏‎‎‏‎"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎Tap to set up.‎‏‎‎‏‎"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‏‏‎Tethering is disabled‎‏‎‎‏‎"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎Contact your admin for details‎‏‎‎‏‎"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎Hotspot &amp; tethering status‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/Tethering/res/values-es-rUS/strings.xml b/packages/Tethering/res/values-es-rUS/strings.xml
index e4618b8..8706a93 100644
--- a/packages/Tethering/res/values-es-rUS/strings.xml
+++ b/packages/Tethering/res/values-es-rUS/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Anclaje a red o zona activa conectados"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Presiona para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Se inhabilitó la conexión mediante dispositivo portátil"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Para obtener más información, comunícate con el administrador"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Anclaje a red o zona activa conectados"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Presiona para configurar esta opción."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Se inhabilitó la conexión mediante dispositivo portátil"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Para obtener más información, comunícate con el administrador"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado del hotspot y la conexión mediante dispositivo portátil"</string>
 </resources>
diff --git a/packages/Tethering/res/values-es/strings.xml b/packages/Tethering/res/values-es/strings.xml
index 8dc1575..67f8f2e 100644
--- a/packages/Tethering/res/values-es/strings.xml
+++ b/packages/Tethering/res/values-es/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Compartir conexión/Zona Wi-Fi activada"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Toca para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"La conexión compartida está inhabilitada"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ponte en contacto con el administrador para obtener más información"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión compartida o punto de acceso activos"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Toca para configurar."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"La conexión compartida está inhabilitada"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Solicita más información a tu administrador"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado del punto de acceso y de la conexión compartida"</string>
 </resources>
diff --git a/packages/Tethering/res/values-et/strings.xml b/packages/Tethering/res/values-et/strings.xml
index 872c8a7..1ebf7b1 100644
--- a/packages/Tethering/res/values-et/strings.xml
+++ b/packages/Tethering/res/values-et/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Jagamine või kuumkoht on aktiivne"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Puudutage seadistamiseks."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Jagamine on keelatud"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Lisateabe saamiseks võtke ühendust oma administraatoriga"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Jagamine või kuumkoht on aktiivne"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Puudutage seadistamiseks."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Jagamine on keelatud"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Lisateabe saamiseks võtke ühendust oma administraatoriga"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Kuumkoha ja jagamise olek"</string>
 </resources>
diff --git a/packages/Tethering/res/values-eu/strings.xml b/packages/Tethering/res/values-eu/strings.xml
index 6c4605e..8e39d47 100644
--- a/packages/Tethering/res/values-eu/strings.xml
+++ b/packages/Tethering/res/values-eu/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Konexioa partekatzea edo sare publikoa aktibo"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Sakatu konfiguratzeko."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Desgaituta dago konexioa partekatzeko aukera"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Xehetasunak lortzeko, jarri administratzailearekin harremanetan"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Konexioa partekatzea edo sare publikoa aktibo"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Sakatu konfiguratzeko."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Desgaituta dago konexioa partekatzeko aukera"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Xehetasunak lortzeko, jarri administratzailearekin harremanetan"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Sare publikoaren eta konexioa partekatzeko eginbidearen egoera"</string>
 </resources>
diff --git a/packages/Tethering/res/values-fa/strings.xml b/packages/Tethering/res/values-fa/strings.xml
index bc2ee23..ee722ff 100644
--- a/packages/Tethering/res/values-fa/strings.xml
+++ b/packages/Tethering/res/values-fa/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"اشتراک‌گذاری اینترنت یا نقطه اتصال فعال"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"برای راه‌اندازی ضربه بزنید."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"اشتراک‌گذاری اینترنت غیرفعال است"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"برای جزئیات، با سرپرستتان تماس بگیرید"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"اشتراک‌گذاری اینترنت یا نقطه اتصال فعال"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"برای راه‌اندازی ضربه بزنید."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"اشتراک‌گذاری اینترنت غیرفعال است"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"برای جزئیات، با سرپرستتان تماس بگیرید"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"وضعیت نقطه اتصال و اشتراک‌گذاری اینترنت"</string>
 </resources>
diff --git a/packages/Tethering/res/values-fi/strings.xml b/packages/Tethering/res/values-fi/strings.xml
index ff0fca6..fae2e8e 100644
--- a/packages/Tethering/res/values-fi/strings.xml
+++ b/packages/Tethering/res/values-fi/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Internetin jakaminen tai yhteyspiste käytössä"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Määritä napauttamalla."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Yhteyden jakaminen poistettu käytöstä"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kysy lisätietoja järjestelmänvalvojalta."</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Yhteyden jakaminen tai hotspot käytössä"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Ota käyttöön napauttamalla."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Yhteyden jakaminen on poistettu käytöstä"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Pyydä lisätietoja järjestelmänvalvojalta"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspotin ja yhteyden jakamisen tila"</string>
 </resources>
diff --git a/packages/Tethering/res/values-fr-rCA/strings.xml b/packages/Tethering/res/values-fr-rCA/strings.xml
index 1f5df0e..afe5df8 100644
--- a/packages/Tethering/res/values-fr-rCA/strings.xml
+++ b/packages/Tethering/res/values-fr-rCA/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Partage de connexion ou point d\'accès sans fil activé"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Touchez pour configurer."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Le partage de connexion est désactivé"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Communiquez avec votre administrateur pour obtenir plus de détails"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Partage de connexion ou point d\'accès sans fil activé"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Touchez pour configurer."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Le partage de connexion est désactivé"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Communiquez avec votre administrateur pour obtenir plus de détails"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Point d\'accès et partage de connexion"</string>
 </resources>
diff --git a/packages/Tethering/res/values-fr/strings.xml b/packages/Tethering/res/values-fr/strings.xml
index daf7c9d..4d54be1 100644
--- a/packages/Tethering/res/values-fr/strings.xml
+++ b/packages/Tethering/res/values-fr/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Partage de connexion ou point d\'accès sans fil activé"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Appuyez ici pour configurer."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Le partage de connexion est désactivé"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Pour en savoir plus, contactez votre administrateur"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Partage de connexion ou point d\'accès activé"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Appuyez pour effectuer la configuration."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Le partage de connexion est désactivé"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Pour en savoir plus, contactez votre administrateur"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"État du point d\'accès et du partage de connexion"</string>
 </resources>
diff --git a/packages/Tethering/res/values-gl/strings.xml b/packages/Tethering/res/values-gl/strings.xml
index 0d16a1d..8f803e9 100644
--- a/packages/Tethering/res/values-gl/strings.xml
+++ b/packages/Tethering/res/values-gl/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Conexión compartida ou zona wifi activada"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tocar para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"A conexión compartida está desactivada"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacta co administrador para obter información"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión compartida ou zona wifi activada"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Toca para configurar."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"A conexión compartida está desactivada"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacta co administrador para obter información"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado da zona wifi e da conexión compartida"</string>
 </resources>
diff --git a/packages/Tethering/res/values-gu/strings.xml b/packages/Tethering/res/values-gu/strings.xml
deleted file mode 100644
index 9d6b02f..0000000
--- a/packages/Tethering/res/values-gu/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ટિથરિંગ અથવા હૉટસ્પૉટ સક્રિય"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"સેટ કરવા માટે ટૅપ કરો."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ટિથરિંગ અક્ષમ કરેલ છે"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"વિગતો માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો"</string>
-</resources>
diff --git a/packages/Tethering/res/values-hi/strings.xml b/packages/Tethering/res/values-hi/strings.xml
deleted file mode 100644
index 9c29d9a..0000000
--- a/packages/Tethering/res/values-hi/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग या हॉटस्‍पॉट सक्रिय"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करने के लिए टैप करें."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग अक्षम है"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"जानकारी के लिए अपने एडमिन से संपर्क करें"</string>
-</resources>
diff --git a/packages/Tethering/res/values-hr/strings.xml b/packages/Tethering/res/values-hr/strings.xml
index d0d25bb..9727bc9 100644
--- a/packages/Tethering/res/values-hr/strings.xml
+++ b/packages/Tethering/res/values-hr/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Ograničenje ili aktivan hotspot"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite da biste postavili."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Modemsko je povezivanje onemogućeno"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Obratite se administratoru da biste saznali pojedinosti"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Modemsko povezivanje ili žarišna točka aktivni"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da biste postavili."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Modemsko je povezivanje onemogućeno"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Obratite se administratoru da biste saznali pojedinosti"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status žarišne točke i modemskog povezivanja"</string>
 </resources>
diff --git a/packages/Tethering/res/values-hu/strings.xml b/packages/Tethering/res/values-hu/strings.xml
index 3129659..ce4ccbec 100644
--- a/packages/Tethering/res/values-hu/strings.xml
+++ b/packages/Tethering/res/values-hu/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Megosztás vagy aktív hotspot"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Koppintson a beállításhoz."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Az internetmegosztás le van tiltva"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"A részletekért forduljon rendszergazdájához"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Megosztás vagy aktív hotspot"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Koppintson a beállításhoz."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Az internetmegosztás le van tiltva"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"A részletekért forduljon rendszergazdájához"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot és internetmegosztás állapota"</string>
 </resources>
diff --git a/packages/Tethering/res/values-hy/strings.xml b/packages/Tethering/res/values-hy/strings.xml
index 8ba6435..b4a6848 100644
--- a/packages/Tethering/res/values-hy/strings.xml
+++ b/packages/Tethering/res/values-hy/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Մոդեմի ռեժիմը միացված է"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Հպեք՝ կարգավորելու համար:"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Մոդեմի ռեժիմն անջատված է"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Մանրամասների համար դիմեք ձեր ադմինիստրատորին"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Մոդեմի ռեժիմը միացված է"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Հպեք՝ կարգավորելու համար։"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Մոդեմի ռեժիմն անջատված է"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Մանրամասների համար դիմեք ձեր ադմինիստրատորին"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Թեժ կետի և մոդեմի ռեժիմի կարգավիճակը"</string>
 </resources>
diff --git a/packages/Tethering/res/values-in/strings.xml b/packages/Tethering/res/values-in/strings.xml
index 1e093ab..6f33685 100644
--- a/packages/Tethering/res/values-in/strings.xml
+++ b/packages/Tethering/res/values-in/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering (Penambatan) atau hotspot aktif"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Ketuk untuk menyiapkan."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering dinonaktifkan"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi admin untuk mengetahui detailnya"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering atau hotspot aktif"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Ketuk untuk menyiapkan."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering dinonaktifkan"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hubungi admin untuk mengetahui detailnya"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status hotspot &amp; tethering"</string>
 </resources>
diff --git a/packages/Tethering/res/values-is/strings.xml b/packages/Tethering/res/values-is/strings.xml
index f5769d5..c149818 100644
--- a/packages/Tethering/res/values-is/strings.xml
+++ b/packages/Tethering/res/values-is/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Kveikt á tjóðrun eða aðgangsstað"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Ýttu til að setja upp."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Slökkt er á tjóðrun"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hafðu samband við kerfisstjórann til að fá upplýsingar"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Kveikt á tjóðrun eða aðgangsstað"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Ýttu til að setja upp."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Slökkt er á tjóðrun"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hafðu samband við kerfisstjórann til að fá upplýsingar"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Staða heits reits og tjóðrunar"</string>
 </resources>
diff --git a/packages/Tethering/res/values-it/strings.xml b/packages/Tethering/res/values-it/strings.xml
index e0b3724..09d0c92 100644
--- a/packages/Tethering/res/values-it/strings.xml
+++ b/packages/Tethering/res/values-it/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering oppure hotspot attivo"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tocca per impostare."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering disattivato"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contatta il tuo amministratore per avere informazioni dettagliate"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Hotspot o tethering attivo"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tocca per impostare."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering disattivato"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contatta il tuo amministratore per avere informazioni dettagliate"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stato hotspot e tethering"</string>
 </resources>
diff --git a/packages/Tethering/res/values-iw/strings.xml b/packages/Tethering/res/values-iw/strings.xml
index c002c44..101fb51 100644
--- a/packages/Tethering/res/values-iw/strings.xml
+++ b/packages/Tethering/res/values-iw/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"שיתוף אינטרנט פעיל"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"הקש כדי להגדיר."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"שיתוף האינטרנט בין ניידים מושבת"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"לפרטים, יש לפנות למנהל המערכת"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"נקודה לשיתוף אינטרנט או שיתוף אינטרנט בין מכשירים: בסטטוס פעיל"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"יש להקיש כדי להגדיר."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"שיתוף האינטרנט בין מכשירים מושבת"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"לפרטים, יש לפנות למנהל המערכת"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"סטטוס של נקודה לשיתוף אינטרנט ושיתוף אינטרנט בין מכשירים"</string>
 </resources>
diff --git a/packages/Tethering/res/values-ja/strings.xml b/packages/Tethering/res/values-ja/strings.xml
index 314bde0..214780d 100644
--- a/packages/Tethering/res/values-ja/strings.xml
+++ b/packages/Tethering/res/values-ja/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"テザリングまたはアクセスポイントが有効です"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"タップしてセットアップします。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"テザリングは無効に設定されています"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"詳しくは、管理者にお問い合わせください"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"テザリングまたはアクセス ポイントが有効です"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"タップしてセットアップします。"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"テザリングは無効に設定されています"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"詳しくは、管理者にお問い合わせください"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"アクセス ポイントとテザリングのステータス"</string>
 </resources>
diff --git a/packages/Tethering/res/values-ka/strings.xml b/packages/Tethering/res/values-ka/strings.xml
index 7bbd81d..68dcecc 100644
--- a/packages/Tethering/res/values-ka/strings.xml
+++ b/packages/Tethering/res/values-ka/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ტეტერინგი ან უსადენო ქსელი აქტიურია"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"შეეხეთ დასაყენებლად."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ტეტერინგი გათიშულია"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"დამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"ტეტერინგი ან უსადენო ქსელი აქტიურია"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"შეეხეთ დასაყენებლად."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ტეტერინგი გათიშულია"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"დამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"უსადენო ქსელის და ტეტერინგის სტატუსი"</string>
 </resources>
diff --git a/packages/Tethering/res/values-kk/strings.xml b/packages/Tethering/res/values-kk/strings.xml
index 7fd87a1..39de166 100644
--- a/packages/Tethering/res/values-kk/strings.xml
+++ b/packages/Tethering/res/values-kk/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Тетеринг немесе хотспот қосулы"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Реттеу үшін түртіңіз."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Тетеринг өшірілді"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Мәліметтерді әкімшіден алыңыз"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Тетеринг немесе хотспот қосулы"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Реттеу үшін түртіңіз."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Тетеринг өшірілді."</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Мәліметтерді әкімшіден алыңыз."</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Хотспот және тетеринг күйі"</string>
 </resources>
diff --git a/packages/Tethering/res/values-km/strings.xml b/packages/Tethering/res/values-km/strings.xml
index 2f85224..be0f0aa6 100644
--- a/packages/Tethering/res/values-km/strings.xml
+++ b/packages/Tethering/res/values-km/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ភ្ជាប់ ឬ​ហតស្ពត​សកម្ម"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"ប៉ះដើម្បីកំណត់"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ការភ្ជាប់​ត្រូវបានបិទ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ទាក់ទងអ្នកគ្រប់គ្រង​របស់អ្នកសម្រាប់​ព័ត៌មានលម្អិត"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"ការភ្ជាប់ ឬហតស្ប៉ត​កំពុងដំណើរការ"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"ចុច​ដើម្បី​រៀបចំ។"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ការភ្ជាប់​ត្រូវបានបិទ"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"ទាក់ទងអ្នកគ្រប់គ្រង​របស់អ្នក ដើម្បីទទួលបានព័ត៌មានលម្អិត"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ស្ថានភាពការភ្ជាប់ និងហតស្ប៉ត"</string>
 </resources>
diff --git a/packages/Tethering/res/values-kn/strings.xml b/packages/Tethering/res/values-kn/strings.xml
deleted file mode 100644
index f11a83ea..0000000
--- a/packages/Tethering/res/values-kn/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ಟೆಥರಿಂಗ್ ಅಥವಾ ಹಾಟ್‌ಸ್ಪಾಟ್ ಸಕ್ರಿಯವಾಗಿದೆ"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ಟೆಥರಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string>
-</resources>
diff --git a/packages/Tethering/res/values-ko/strings.xml b/packages/Tethering/res/values-ko/strings.xml
index 57f24f5..7ce45a2 100644
--- a/packages/Tethering/res/values-ko/strings.xml
+++ b/packages/Tethering/res/values-ko/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"테더링 또는 핫스팟 사용"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"설정하려면 탭하세요."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"테더링이 사용 중지됨"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"자세한 정보는 관리자에게 문의하세요."</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"테더링 또는 핫스팟 사용"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"설정하려면 탭하세요."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"테더링이 사용 중지됨"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"자세한 정보는 관리자에게 문의하세요."</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"핫스팟 및 테더링 상태"</string>
 </resources>
diff --git a/packages/Tethering/res/values-ky/strings.xml b/packages/Tethering/res/values-ky/strings.xml
index 7985485..9a5088e 100644
--- a/packages/Tethering/res/values-ky/strings.xml
+++ b/packages/Tethering/res/values-ky/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Жалгаштыруу же хотспот жандырылган"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Жөндөө үчүн таптап коюңуз."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Жалгаштыруу функциясы өчүрүлгөн"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Кеңири маалымат үчүн администраторуңузга кайрылыңыз"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Жалгаштыруу же хотспот жандырылган"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Жөндөө үчүн таптап коюңуз."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Жалгаштыруу функциясы өчүрүлгөн"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Кеңири маалымат үчүн администраторуңузга кайрылыңыз"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Хотспот жана байланыш түйүнүүн статусу"</string>
 </resources>
diff --git a/packages/Tethering/res/values-lo/strings.xml b/packages/Tethering/res/values-lo/strings.xml
index 78f1585..7384237 100644
--- a/packages/Tethering/res/values-lo/strings.xml
+++ b/packages/Tethering/res/values-lo/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ເປີດ​ການ​ປ່ອຍ​ສັນຍານ ຫຼື​ຮັອດສະປອດ​ແລ້ວ"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"ແຕະເພື່ອຕັ້ງຄ່າ."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ການປ່ອຍສັນຍານຖືກປິດໄວ້"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບລາຍລະອຽດ"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"ເປີດການປ່ອຍສັນຍານ ຫຼື ຮັອດສະປອດແລ້ວ"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"ແຕະເພື່ອຕັ້ງຄ່າ."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ການປ່ອຍສັນຍານຖືກປິດໄວ້"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບລາຍລະອຽດ"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ສະຖານະຮັອດສະປອດ ແລະ ການປ່ອຍສັນຍານ"</string>
 </resources>
diff --git a/packages/Tethering/res/values-lt/strings.xml b/packages/Tethering/res/values-lt/strings.xml
index ebff8ac..dc4fdf5 100644
--- a/packages/Tethering/res/values-lt/strings.xml
+++ b/packages/Tethering/res/values-lt/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Susietas ar aktyvus"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Palieskite, kad nustatytumėte."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Įrenginio kaip modemo naudojimas išjungtas"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Jei reikia išsamios informacijos, susisiekite su administratoriumi"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Įrenginys naudojamas kaip modemas arba įjungtas viešosios interneto prieigos taškas"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Palieskite, kad nustatytumėte."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Įrenginio kaip modemo naudojimas išjungtas"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Jei reikia išsamios informacijos, susisiekite su administratoriumi"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Viešosios interneto prieigos taško ir įrenginio kaip modemo naudojimo būsena"</string>
 </resources>
diff --git a/packages/Tethering/res/values-lv/strings.xml b/packages/Tethering/res/values-lv/strings.xml
index 54d0048..db0401a 100644
--- a/packages/Tethering/res/values-lv/strings.xml
+++ b/packages/Tethering/res/values-lv/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Piesaiste vai tīklājs ir aktīvs."</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Pieskarieties, lai iestatītu."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Piesaiste ir atspējota"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Lai iegūtu detalizētu informāciju, sazinieties ar savu administratoru."</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Piesaiste vai tīklājs ir aktīvs."</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Pieskarieties, lai to iestatītu."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Piesaiste ir atspējota"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Lai iegūtu detalizētu informāciju, sazinieties ar savu administratoru."</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Tīklāja un piesaistes statuss"</string>
 </resources>
diff --git a/packages/Tethering/res/values-mcc204-mnc04/strings.xml b/packages/Tethering/res/values-mcc204-mnc04/strings.xml
new file mode 100644
index 0000000..a996b42
--- /dev/null
+++ b/packages/Tethering/res/values-mcc204-mnc04/strings.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+<resources>
+    <!-- String for no upstream notification title [CHAR LIMIT=200] -->
+    <string name="no_upstream_notification_title">Hotspot has no internet</string>
+    <!-- String for no upstream notification title [CHAR LIMIT=200] -->
+    <string name="no_upstream_notification_message">Devices can\u2019t connect to internet</string>
+    <!-- String for cellular roaming notification disable button [CHAR LIMIT=200]  -->
+    <string name="no_upstream_notification_disable_button">Turn off hotspot</string>
+
+    <!-- String for cellular roaming notification title [CHAR LIMIT=200]  -->
+    <string name="upstream_roaming_notification_title">Hotspot is on</string>
+    <!-- String for cellular roaming notification message [CHAR LIMIT=500]  -->
+    <string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string>
+    <!-- String for cellular roaming notification continue button [CHAR LIMIT=200]  -->
+    <string name="upstream_roaming_notification_continue_button">Continue</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004/strings.xml b/packages/Tethering/res/values-mcc310-mnc004/strings.xml
new file mode 100644
index 0000000..a996b42
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004/strings.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+<resources>
+    <!-- String for no upstream notification title [CHAR LIMIT=200] -->
+    <string name="no_upstream_notification_title">Hotspot has no internet</string>
+    <!-- String for no upstream notification title [CHAR LIMIT=200] -->
+    <string name="no_upstream_notification_message">Devices can\u2019t connect to internet</string>
+    <!-- String for cellular roaming notification disable button [CHAR LIMIT=200]  -->
+    <string name="no_upstream_notification_disable_button">Turn off hotspot</string>
+
+    <!-- String for cellular roaming notification title [CHAR LIMIT=200]  -->
+    <string name="upstream_roaming_notification_title">Hotspot is on</string>
+    <!-- String for cellular roaming notification message [CHAR LIMIT=500]  -->
+    <string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string>
+    <!-- String for cellular roaming notification continue button [CHAR LIMIT=200]  -->
+    <string name="upstream_roaming_notification_continue_button">Continue</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc120/strings.xml b/packages/Tethering/res/values-mcc310-mnc120/strings.xml
new file mode 100644
index 0000000..618df90
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc120/strings.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- String for tethered notification title with client number info. -->
+    <plurals name="tethered_notification_title_with_client_number">
+        <item quantity="one"><xliff:g>%1$d</xliff:g> device connected.</item>
+        <item quantity="other"><xliff:g>%1$d</xliff:g> devices connected.</item>
+    </plurals>
+</resources>
\ No newline at end of file
diff --git a/packages/Tethering/res/values-mcc311-mnc480/strings.xml b/packages/Tethering/res/values-mcc311-mnc480/strings.xml
new file mode 100644
index 0000000..a996b42
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480/strings.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+<resources>
+    <!-- String for no upstream notification title [CHAR LIMIT=200] -->
+    <string name="no_upstream_notification_title">Hotspot has no internet</string>
+    <!-- String for no upstream notification title [CHAR LIMIT=200] -->
+    <string name="no_upstream_notification_message">Devices can\u2019t connect to internet</string>
+    <!-- String for cellular roaming notification disable button [CHAR LIMIT=200]  -->
+    <string name="no_upstream_notification_disable_button">Turn off hotspot</string>
+
+    <!-- String for cellular roaming notification title [CHAR LIMIT=200]  -->
+    <string name="upstream_roaming_notification_title">Hotspot is on</string>
+    <!-- String for cellular roaming notification message [CHAR LIMIT=500]  -->
+    <string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string>
+    <!-- String for cellular roaming notification continue button [CHAR LIMIT=200]  -->
+    <string name="upstream_roaming_notification_continue_button">Continue</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc490/strings.xml b/packages/Tethering/res/values-mcc311-mnc490/strings.xml
new file mode 100644
index 0000000..618df90
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc490/strings.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- String for tethered notification title with client number info. -->
+    <plurals name="tethered_notification_title_with_client_number">
+        <item quantity="one"><xliff:g>%1$d</xliff:g> device connected.</item>
+        <item quantity="other"><xliff:g>%1$d</xliff:g> devices connected.</item>
+    </plurals>
+</resources>
\ No newline at end of file
diff --git a/packages/Tethering/res/values-mcc312-mnc530/strings.xml b/packages/Tethering/res/values-mcc312-mnc530/strings.xml
new file mode 100644
index 0000000..618df90
--- /dev/null
+++ b/packages/Tethering/res/values-mcc312-mnc530/strings.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- String for tethered notification title with client number info. -->
+    <plurals name="tethered_notification_title_with_client_number">
+        <item quantity="one"><xliff:g>%1$d</xliff:g> device connected.</item>
+        <item quantity="other"><xliff:g>%1$d</xliff:g> devices connected.</item>
+    </plurals>
+</resources>
\ No newline at end of file
diff --git a/packages/Tethering/res/values-mk/strings.xml b/packages/Tethering/res/values-mk/strings.xml
index 0fab8aa..ad255b6 100644
--- a/packages/Tethering/res/values-mk/strings.xml
+++ b/packages/Tethering/res/values-mk/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Поврзувањето или точката на пристап се активни"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Допрете за поставување."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Врзувањето е оневозможено"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Контактирајте со администраторот за детали"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Активно е врзување или точка на пристап"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Допрете за поставување."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Врзувањето е оневозможено"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Контактирајте со администраторот за детали"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус на точката на пристап и врзувањето"</string>
 </resources>
diff --git a/packages/Tethering/res/values-ml/strings.xml b/packages/Tethering/res/values-ml/strings.xml
deleted file mode 100644
index fd7e556..0000000
--- a/packages/Tethering/res/values-ml/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ടെതറിംഗ് അല്ലെങ്കിൽ ഹോട്ട്സ്‌പോട്ട് സജീവമാണ്"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"സജ്ജമാക്കാൻ ടാപ്പുചെയ്യുക."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ടെതറിംഗ് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"വിശദവിവരങ്ങൾക്ക് നിങ്ങളുടെ അഡ്മിനെ ബന്ധപ്പെടുക"</string>
-</resources>
diff --git a/packages/Tethering/res/values-mn/strings.xml b/packages/Tethering/res/values-mn/strings.xml
index 4596577..ed5b69b 100644
--- a/packages/Tethering/res/values-mn/strings.xml
+++ b/packages/Tethering/res/values-mn/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Модем болгох эсвэл идэвхтэй цэг болгох"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Тохируулахын тулд товшино уу."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Модем болгох боломжгүй байна"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Дэлгэрэнгүй мэдээлэл авахын тулд админтайгаа холбогдоно уу"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Модем болгох эсвэл сүлжээний цэг идэвхтэй байна"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Тохируулахын тулд товшино уу."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Модем болгохыг идэвхгүй болгосон"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Дэлгэрэнгүй мэдээлэл авахын тулд админтайгаа холбогдоно уу"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Сүлжээний цэг болон модем болгох төлөв"</string>
 </resources>
diff --git a/packages/Tethering/res/values-mr/strings.xml b/packages/Tethering/res/values-mr/strings.xml
deleted file mode 100644
index 85c9ade..0000000
--- a/packages/Tethering/res/values-mr/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग किंवा हॉटस्पॉट सक्रिय"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करण्यासाठी टॅप करा."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग बंद आहे"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"तपशीलांसाठी तुमच्या प्रशासकाशी संपर्क साधा"</string>
-</resources>
diff --git a/packages/Tethering/res/values-ms/strings.xml b/packages/Tethering/res/values-ms/strings.xml
index ec6bdbd..09c5a0e 100644
--- a/packages/Tethering/res/values-ms/strings.xml
+++ b/packages/Tethering/res/values-ms/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Penambatan atau titik panas aktif"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Ketik untuk membuat persediaan."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Penambatan dilumpuhkan"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi pentadbir anda untuk maklumat lanjut"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Penambatan atau tempat liputan aktif"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Ketik untuk membuat persediaan."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Penambatan dilumpuhkan"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hubungi pentadbir anda untuk mendapatkan maklumat lanjut"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status tempat liputan &amp; penambatan"</string>
 </resources>
diff --git a/packages/Tethering/res/values-my/strings.xml b/packages/Tethering/res/values-my/strings.xml
index 83978b6..ff96086 100644
--- a/packages/Tethering/res/values-my/strings.xml
+++ b/packages/Tethering/res/values-my/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"တဆင့်ပြန်လည်လွှင့်ခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"စနစ်ထည့်သွင်းရန် တို့ပါ။"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"မိုဘိုင်းဖုန်းကို မိုဒမ်အဖြစ်သုံးခြင်းအား ပိတ်ထားသည်"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"အသေးစိတ်အချက်အလက်များအတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"စနစ်ထည့်သွင်းရန် တို့ပါ။"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်းကို ပိတ်ထားသည်"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"အသေးစိတ်အတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ဟော့စပေါ့နှင့် မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း အခြေအနေ"</string>
 </resources>
diff --git a/packages/Tethering/res/values-nb/strings.xml b/packages/Tethering/res/values-nb/strings.xml
index 9abf32d..d6e1fee1 100644
--- a/packages/Tethering/res/values-nb/strings.xml
+++ b/packages/Tethering/res/values-nb/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Internettdeling eller trådløs sone er aktiv"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Trykk for å konfigurere."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Internettdeling er slått av"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ta kontakt med administratoren din for å få mer informasjon"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Internettdeling eller Wi-Fi-sone er aktiv"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Trykk for å konfigurere."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Internettdeling er slått av"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Ta kontakt med administratoren din for å få mer informasjon"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status for Wi-Fi-sone og internettdeling"</string>
 </resources>
diff --git a/packages/Tethering/res/values-ne/strings.xml b/packages/Tethering/res/values-ne/strings.xml
deleted file mode 100644
index c886929..0000000
--- a/packages/Tethering/res/values-ne/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"टेथर गर्ने वा हटस्पट सक्रिय"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"सेटअप गर्न ट्याप गर्नुहोस्।"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिङलाई असक्षम पारिएको छ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"विवरणहरूका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्"</string>
-</resources>
diff --git a/packages/Tethering/res/values-nl/strings.xml b/packages/Tethering/res/values-nl/strings.xml
index 0ec4bff..49f8fd6 100644
--- a/packages/Tethering/res/values-nl/strings.xml
+++ b/packages/Tethering/res/values-nl/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering of hotspot actief"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tik om in te stellen."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is uitgeschakeld"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Neem contact op met je beheerder voor meer informatie"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering of hotspot actief"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tik om in te stellen."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is uitgeschakeld"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Neem contact op met je beheerder voor meer informatie"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status van hotspot en tethering"</string>
 </resources>
diff --git a/packages/Tethering/res/values-or/strings.xml b/packages/Tethering/res/values-or/strings.xml
deleted file mode 100644
index 4576857..0000000
--- a/packages/Tethering/res/values-or/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ଟିଥରିଙ୍ଗ କିମ୍ୱା ହଟସ୍ପଟ୍‌ ସକ୍ରିୟ ଅଛି"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"ସେଟଅପ୍‍ କରିବାକୁ ଟାପ୍‍ କରନ୍ତୁ।"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ଟିଥରିଙ୍ଗ ଅକ୍ଷମ କରାଯାଇଛି"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ବିବରଣୀ ପାଇଁ ନିଜ ଆଡମିନ୍‌ଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ"</string>
-</resources>
diff --git a/packages/Tethering/res/values-pa/strings.xml b/packages/Tethering/res/values-pa/strings.xml
deleted file mode 100644
index deddf2e..0000000
--- a/packages/Tethering/res/values-pa/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ਟੈਦਰਿੰਗ ਜਾਂ ਹੌਟਸਪੌਟ ਕਿਰਿਆਸ਼ੀਲ"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"ਸਥਾਪਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ਟੈਦਰਿੰਗ ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ"</string>
-</resources>
diff --git a/packages/Tethering/res/values-pl/strings.xml b/packages/Tethering/res/values-pl/strings.xml
index 48d8468..98cfbbb 100644
--- a/packages/Tethering/res/values-pl/strings.xml
+++ b/packages/Tethering/res/values-pl/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Aktywny tethering lub punkt dostępu"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Kliknij, by skonfigurować."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering został wyłączony"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Aby uzyskać szczegółowe informacje, skontaktuj się z administratorem"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Aktywny tethering lub punkt dostępu"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Kliknij, by skonfigurować"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering został wyłączony"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Aby uzyskać szczegółowe informacje, skontaktuj się z administratorem"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot i tethering – stan"</string>
 </resources>
diff --git a/packages/Tethering/res/values-pt-rBR/strings.xml b/packages/Tethering/res/values-pt-rBR/strings.xml
index 32c22b8..338f8fc 100644
--- a/packages/Tethering/res/values-pt-rBR/strings.xml
+++ b/packages/Tethering/res/values-pt-rBR/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Ponto de acesso ou tethering ativo"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Ponto de acesso ou tethering ativo"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering desativado"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Fale com seu administrador para saber detalhes"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status de ponto de acesso e tethering"</string>
 </resources>
diff --git a/packages/Tethering/res/values-pt-rPT/strings.xml b/packages/Tethering/res/values-pt-rPT/strings.xml
index 641e22f..a06f033 100644
--- a/packages/Tethering/res/values-pt-rPT/strings.xml
+++ b/packages/Tethering/res/values-pt-rPT/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Ligação ponto a ponto ou hotspot activos"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"A ligação (à Internet) via telemóvel está desativada."</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacte o gestor para obter detalhes."</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Ligação (à Internet) via telemóvel ou zona Wi-Fi ativos"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"A ligação (à Internet) via telemóvel está desativada."</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacte o administrador para obter detalhes."</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado da zona Wi-Fi e da ligação (à Internet) via telemóvel"</string>
 </resources>
diff --git a/packages/Tethering/res/values-pt/strings.xml b/packages/Tethering/res/values-pt/strings.xml
index 32c22b8..338f8fc 100644
--- a/packages/Tethering/res/values-pt/strings.xml
+++ b/packages/Tethering/res/values-pt/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Ponto de acesso ou tethering ativo"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Ponto de acesso ou tethering ativo"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering desativado"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Fale com seu administrador para saber detalhes"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status de ponto de acesso e tethering"</string>
 </resources>
diff --git a/packages/Tethering/res/values-ro/strings.xml b/packages/Tethering/res/values-ro/strings.xml
index f861f73..7480ec5 100644
--- a/packages/Tethering/res/values-ro/strings.xml
+++ b/packages/Tethering/res/values-ro/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering sau hotspot activ"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Atingeți ca să configurați."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tetheringul este dezactivat"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contactați administratorul pentru detalii"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering sau hotspot activ"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Atingeți ca să configurați."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tetheringul este dezactivat"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contactați administratorul pentru detalii"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Starea hotspotului și a tetheringului"</string>
 </resources>
diff --git a/packages/Tethering/res/values-ru/strings.xml b/packages/Tethering/res/values-ru/strings.xml
index 027cb41..3153e0b 100644
--- a/packages/Tethering/res/values-ru/strings.xml
+++ b/packages/Tethering/res/values-ru/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Включен режим модема"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Нажмите, чтобы настроить."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Включить режим модема нельзя"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Обратитесь к администратору, чтобы узнать подробности."</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Включен режим модема или хот-спот"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Нажмите, чтобы настроить."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Использование телефона в качестве модема запрещено"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Чтобы узнать подробности, обратитесь к администратору."</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус хот-спота и режима модема"</string>
 </resources>
diff --git a/packages/Tethering/res/values-si/strings.xml b/packages/Tethering/res/values-si/strings.xml
index 7d8599f..2b117bc 100644
--- a/packages/Tethering/res/values-si/strings.xml
+++ b/packages/Tethering/res/values-si/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ටෙදරින් හෝ හොට්ස්පොට් සක්‍රීයයි"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"පිහිටුවීමට තට්ටු කරන්න."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ටෙදරින් අබල කර ඇත"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"විස්තර සඳහා ඔබගේ පරිපාලක අමතන්න"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"ටෙදරින් හෝ හොට්ස්පොට් සක්‍රීයයි"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"පිහිටුවීමට තට්ටු කරන්න."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ටෙදරින් අබල කර ඇත"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"විස්තර සඳහා ඔබගේ පරිපාලක අමතන්න"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"හොට්ස්පොට් &amp; ටෙදරින් තත්ත්වය"</string>
 </resources>
diff --git a/packages/Tethering/res/values-sk/strings.xml b/packages/Tethering/res/values-sk/strings.xml
index a8fe297..e1db50a 100644
--- a/packages/Tethering/res/values-sk/strings.xml
+++ b/packages/Tethering/res/values-sk/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering alebo prístupový bod je aktívny"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Klepnutím prejdete na nastavenie."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering je deaktivovaný"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"O podrobnosti požiadajte svojho správcu"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering alebo prístupový bod je aktívny"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Klepnutím prejdete na nastavenie."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering je deaktivovaný"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"O podrobnosti požiadajte svojho správcu"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stav hotspotu a tetheringu"</string>
 </resources>
diff --git a/packages/Tethering/res/values-sl/strings.xml b/packages/Tethering/res/values-sl/strings.xml
index b5e5e38..bcfe487 100644
--- a/packages/Tethering/res/values-sl/strings.xml
+++ b/packages/Tethering/res/values-sl/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Aktivna povezava z internetom ali dostopna točka sta aktivni"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Dotaknite se, če želite nastaviti."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Povezava z internetom prek mobilnega telefona je onemogočena"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Za podrobnosti se obrnite na skrbnika"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Povezava z internetom prek mobilnega telefona ali dostopna točka je aktivna"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Dotaknite se, če želite nastaviti."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Povezava z internetom prek mobilnega telefona je onemogočena"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Za podrobnosti se obrnite na skrbnika"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stanje dostopne točke in povezave z internetom prek mobilnega telefona"</string>
 </resources>
diff --git a/packages/Tethering/res/values-sq/strings.xml b/packages/Tethering/res/values-sq/strings.xml
index fdd4906..2e56020 100644
--- a/packages/Tethering/res/values-sq/strings.xml
+++ b/packages/Tethering/res/values-sq/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Lidhja e çiftimit ose ajo e qasjes në zona publike interneti është aktive"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Trokit për ta konfiguruar."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Lidhja e çiftimit është çaktivizuar"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakto me administratorin për detaje"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Ndarja e internetit ose zona e qasjes së internetit është aktive"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Trokit për ta konfiguruar."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Ndarja e internetit është çaktivizuar"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakto me administratorin për detaje"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Statusi i zonës së qasjes dhe ndarjes së internetit"</string>
 </resources>
diff --git a/packages/Tethering/res/values-sr/strings.xml b/packages/Tethering/res/values-sr/strings.xml
index 9fab34589..09c7c16 100644
--- a/packages/Tethering/res/values-sr/strings.xml
+++ b/packages/Tethering/res/values-sr/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Активно повезивање са интернетом преко мобилног уређаја или хотспот"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Додирните да бисте подесили."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Привезивање је онемогућено"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Потражите детаље од администратора"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Привезивање или хотспот је активан"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Додирните да бисте подесили."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Привезивање је онемогућено"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Потражите детаље од администратора"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус хотспота и привезивања"</string>
 </resources>
diff --git a/packages/Tethering/res/values-sv/strings.xml b/packages/Tethering/res/values-sv/strings.xml
index 10eeb0f..adb6b81 100644
--- a/packages/Tethering/res/values-sv/strings.xml
+++ b/packages/Tethering/res/values-sv/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Internetdelning eller surfzon aktiverad"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tryck om du vill konfigurera."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Internetdelning har inaktiverats"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakta administratören om du vill veta mer"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Internetdelning eller surfzon har aktiverats"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Tryck om du vill konfigurera."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Internetdelning har inaktiverats"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakta administratören om du vill veta mer"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Trådlös surfzon och internetdelning har inaktiverats"</string>
 </resources>
diff --git a/packages/Tethering/res/values-sw/strings.xml b/packages/Tethering/res/values-sw/strings.xml
index 3353963..3f10e47 100644
--- a/packages/Tethering/res/values-sw/strings.xml
+++ b/packages/Tethering/res/values-sw/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Kushiriki au kusambaza intaneti kumewashwa"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Gusa ili uweke mipangilio."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Umezima kipengele cha kusambaza mtandao"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Wasiliana na msimamizi wako ili upate maelezo zaidi"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Kusambaza mtandao au mtandaopepe umewashwa"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Gusa ili uweke mipangilio."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Umezima kipengele cha kusambaza mtandao"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Wasiliana na msimamizi wako ili upate maelezo zaidi"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Mtandaopepe na hali ya kusambaza mtandao"</string>
 </resources>
diff --git a/packages/Tethering/res/values-ta/strings.xml b/packages/Tethering/res/values-ta/strings.xml
deleted file mode 100644
index b1e5cc2..0000000
--- a/packages/Tethering/res/values-ta/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"டெதெரிங்/ஹாட்ஸ்பாட் இயங்குகிறது"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"அமைக்க, தட்டவும்."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"இணைப்பு முறை முடக்கப்பட்டுள்ளது"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"விவரங்களுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்"</string>
-</resources>
diff --git a/packages/Tethering/res/values-te/strings.xml b/packages/Tethering/res/values-te/strings.xml
deleted file mode 100644
index aae40de..0000000
--- a/packages/Tethering/res/values-te/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"టీథర్ చేయబడినది లేదా హాట్‌స్పాట్ సక్రియంగా ఉండేది"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"సెటప్ చేయడానికి నొక్కండి."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"టెథెరింగ్ నిలిపివేయబడింది"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"వివరాల కోసం మీ నిర్వాహకులను సంప్రదించండి"</string>
-</resources>
diff --git a/packages/Tethering/res/values-th/strings.xml b/packages/Tethering/res/values-th/strings.xml
index 1b80056..33a8b0c 100644
--- a/packages/Tethering/res/values-th/strings.xml
+++ b/packages/Tethering/res/values-th/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"การปล่อยสัญญาณหรือฮอตสปอตทำงานอยู่"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"แตะเพื่อตั้งค่า"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ปิดใช้การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือแล้ว"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"ติดต่อผู้ดูแลระบบเพื่อขอรายละเอียด"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือหรือฮอตสปอตทำงานอยู่"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"แตะเพื่อตั้งค่า"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"ปิดใช้การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือแล้ว"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"ติดต่อผู้ดูแลระบบเพื่อขอรายละเอียด"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"สถานะฮอตสปอตและการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
 </resources>
diff --git a/packages/Tethering/res/values-tl/strings.xml b/packages/Tethering/res/values-tl/strings.xml
index 12863f9..0f31daf 100644
--- a/packages/Tethering/res/values-tl/strings.xml
+++ b/packages/Tethering/res/values-tl/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Pagsasama o aktibong hotspot"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"I-tap upang i-set up."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Naka-disable ang pag-tether"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Makipag-ugnayan sa iyong admin para sa mga detalye"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Aktibo ang pag-tether o hotspot"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"I-tap para i-set up."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Naka-disable ang pag-tether"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Makipag-ugnayan sa iyong admin para sa mga detalye"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status ng hotspot at pag-tether"</string>
 </resources>
diff --git a/packages/Tethering/res/values-tr/strings.xml b/packages/Tethering/res/values-tr/strings.xml
index bfcf1ac..aaa264f 100644
--- a/packages/Tethering/res/values-tr/strings.xml
+++ b/packages/Tethering/res/values-tr/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering veya hotspot etkin"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Ayarlamak için dokunun."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering devre dışı bırakıldı"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ayrıntılı bilgi için yöneticinize başvurun"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering veya hotspot etkin"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Ayarlamak için dokunun."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering devre dışı bırakıldı"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Ayrıntılı bilgi için yöneticinize başvurun"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot ve tethering durumu"</string>
 </resources>
diff --git a/packages/Tethering/res/values-uk/strings.xml b/packages/Tethering/res/values-uk/strings.xml
index 8e159c0..875ba84 100644
--- a/packages/Tethering/res/values-uk/strings.xml
+++ b/packages/Tethering/res/values-uk/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Прив\'язка чи точка дост. активна"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Торкніться, щоб налаштувати."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Використання телефона в режимі модема вимкнено"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Щоб дізнатися більше, зв’яжіться з адміністратором"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Модем чи точка доступу активні"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Натисніть, щоб налаштувати."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Використання телефона як модема вимкнено"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Щоб дізнатися більше, зв\'яжіться з адміністратором"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус точки доступу та модема"</string>
 </resources>
diff --git a/packages/Tethering/res/values-ur/strings.xml b/packages/Tethering/res/values-ur/strings.xml
deleted file mode 100644
index 89195d4..0000000
--- a/packages/Tethering/res/values-ur/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"ٹیدرنگ یا ہاٹ اسپاٹ فعال"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"سیٹ اپ کرنے کیلئے تھپتھپائیں۔"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"ٹیدرنگ غیر فعال ہے"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"تفصیلات کے لئے اپنے منتظم سے رابطہ کریں"</string>
-</resources>
diff --git a/packages/Tethering/res/values-uz/strings.xml b/packages/Tethering/res/values-uz/strings.xml
index 0ac4d4a..50b3998 100644
--- a/packages/Tethering/res/values-uz/strings.xml
+++ b/packages/Tethering/res/values-uz/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Modem rejimi yoniq"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Sozlash uchun bosing."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Modem rejimi faolsizlantirildi"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Tafsilotlari uchun administratoringizga murojaat qiling"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Modem rejimi yoki hotspot yoniq"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Sozlash uchun bosing."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Modem rejimi faolsizlantirildi"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Tafsilotlari uchun administratoringizga murojaat qiling"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot va modem rejimi holati"</string>
 </resources>
diff --git a/packages/Tethering/res/values-vi/strings.xml b/packages/Tethering/res/values-vi/strings.xml
index 85a4db8..b6e2942 100644
--- a/packages/Tethering/res/values-vi/strings.xml
+++ b/packages/Tethering/res/values-vi/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Chức năng điểm truy cập Internet hoặc điểm phát sóng đang hoạt động"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Nhấn để thiết lập."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Đã tắt tính năng chia sẻ kết nối"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hãy liên hệ với quản trị viên của bạn để biết chi tiết"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Tính năng chia sẻ kết nối hoặc điểm phát sóng đang hoạt động"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Hãy nhấn để thiết lập."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Đã tắt tính năng chia sẻ kết nối"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hãy liên hệ với quản trị viên của bạn để biết chi tiết"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Trạng thái điểm phát sóng và trạng thái chia sẻ kết nối"</string>
 </resources>
diff --git a/packages/Tethering/res/values-zh-rCN/strings.xml b/packages/Tethering/res/values-zh-rCN/strings.xml
index ff1fe03..55e2f1a 100644
--- a/packages/Tethering/res/values-zh-rCN/strings.xml
+++ b/packages/Tethering/res/values-zh-rCN/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"网络共享或热点已启用"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"点按即可进行设置。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"网络共享已停用"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"请与您的管理员联系以了解详情"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"网络共享或热点已启用"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"点按即可设置。"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"网络共享已停用"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"如需了解详情,请与您的管理员联系"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"热点和网络共享状态"</string>
 </resources>
diff --git a/packages/Tethering/res/values-zh-rHK/strings.xml b/packages/Tethering/res/values-zh-rHK/strings.xml
index 0de39fa..5d4c4e8 100644
--- a/packages/Tethering/res/values-zh-rHK/strings.xml
+++ b/packages/Tethering/res/values-zh-rHK/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"已啟用網絡共享或熱點"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"輕按即可設定。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"網絡共享已停用"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"請聯絡您的管理員以瞭解詳情"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"網絡共享或熱點已啟用"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"輕按即可設定。"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"網絡共享已停用"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"請聯絡您的管理員以瞭解詳情"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"熱點和網絡共享狀態"</string>
 </resources>
diff --git a/packages/Tethering/res/values-zh-rTW/strings.xml b/packages/Tethering/res/values-zh-rTW/strings.xml
index 9a117bb..a6561a2 100644
--- a/packages/Tethering/res/values-zh-rTW/strings.xml
+++ b/packages/Tethering/res/values-zh-rTW/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"網路共用或無線基地台已啟用"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"輕觸即可進行設定。"</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"數據連線已停用"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"詳情請洽你的管理員"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"數據連線或無線基地台已啟用"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"輕觸即可進行設定。"</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"數據連線已停用"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"詳情請洽你的管理員"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"無線基地台與數據連線狀態"</string>
 </resources>
diff --git a/packages/Tethering/res/values-zu/strings.xml b/packages/Tethering/res/values-zu/strings.xml
index 8fe10d8..aa65c80 100644
--- a/packages/Tethering/res/values-zu/strings.xml
+++ b/packages/Tethering/res/values-zu/strings.xml
@@ -1,8 +1,24 @@
 <?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.
+ -->
+
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Ukusebenzisa njengemodemu noma i-hotspot ephathekayo kuvuliwe"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Thepha ukuze usethe."</string>
-    <string name="disable_tether_notification_title" msgid="7526977944111313195">"Ukusebenzisa ifoni njengemodemu kukhutshaziwe"</string>
-    <string name="disable_tether_notification_message" msgid="2913366428516852495">"Xhumana nomphathi wakho ukuze uthole imininingwane"</string>
+    <string name="tethered_notification_title" msgid="6426563586025792944">"Ukusebenzisa njengemodemu noma i-hotspot ephathekayo kuvuliwe"</string>
+    <string name="tethered_notification_message" msgid="64800879503420696">"Thepha ukuze usethe."</string>
+    <string name="disable_tether_notification_title" msgid="3004509127903564191">"Ukusebenzisa ifoni njengemodemu kukhutshaziwe"</string>
+    <string name="disable_tether_notification_message" msgid="6717523799293901476">"Xhumana nomphathi wakho ukuze uthole imininingwane"</string>
+    <string name="notification_channel_tethering_status" msgid="2663463891530932727">"I-Hotspot nesimo sokusebenzisa ifoni njengemodemu"</string>
 </resources>
diff --git a/packages/Tethering/res/values/strings.xml b/packages/Tethering/res/values/strings.xml
index ba98a66..52a1654 100644
--- a/packages/Tethering/res/values/strings.xml
+++ b/packages/Tethering/res/values/strings.xml
@@ -13,12 +13,15 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<resources>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Shown when the device is tethered -->
     <!-- String for tethered notification title [CHAR LIMIT=200] -->
     <string name="tethered_notification_title">Tethering or hotspot active</string>
     <!-- String for tethered notification message [CHAR LIMIT=200] -->
     <string name="tethered_notification_message">Tap to set up.</string>
+    <!-- String for tethered notification title with client number info. -->
+    <plurals name="tethered_notification_title_with_client_number">
+    </plurals>
 
     <!-- This notification is shown when tethering has been disabled on a user's device.
     The device is managed by the user's employer. Tethering can't be turned on unless the
@@ -32,4 +35,18 @@
     Internet" settings page. That is currently the tether_settings_title_all string. -->
     <!-- String for tether notification channel name [CHAR LIMIT=200] -->
     <string name="notification_channel_tethering_status">Hotspot &amp; tethering status</string>
-</resources>
\ No newline at end of file
+
+    <!-- String for no upstream notification title [CHAR LIMIT=200] -->
+    <string name="no_upstream_notification_title"></string>
+    <!-- String for no upstream notification message [CHAR LIMIT=200] -->
+    <string name="no_upstream_notification_message"></string>
+    <!-- String for cellular roaming notification disable button [CHAR LIMIT=200]  -->
+    <string name="no_upstream_notification_disable_button"></string>
+
+    <!-- String for cellular roaming notification title [CHAR LIMIT=200]  -->
+    <string name="upstream_roaming_notification_title"></string>
+    <!-- String for cellular roaming notification message [CHAR LIMIT=500]  -->
+    <string name="upstream_roaming_notification_message"></string>
+    <!-- String for cellular roaming notification continue button [CHAR LIMIT=200]  -->
+    <string name="upstream_roaming_notification_continue_button"></string>
+</resources>
diff --git a/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java b/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
index d6bc063..82a26be 100644
--- a/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
+++ b/packages/Tethering/src/android/net/dhcp/DhcpServingParamsParcelExt.java
@@ -18,10 +18,12 @@
 
 import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
 
-import android.annotation.NonNull;
 import android.net.LinkAddress;
 import android.util.ArraySet;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import java.net.Inet4Address;
 import java.util.Collection;
 import java.util.Collections;
@@ -160,6 +162,17 @@
         return this;
     }
 
+    /**
+     * Set the client address to tell DHCP server only offer this address.
+     * The client's prefix length is the same as server's.
+     *
+     * <p>If not set, the default value is null.
+     */
+    public DhcpServingParamsParcelExt setSingleClientAddr(@Nullable Inet4Address clientAddr) {
+        this.clientAddr = clientAddr == null ? 0 : inet4AddressToIntHTH(clientAddr);
+        return this;
+    }
+
     private static int[] toIntArray(@NonNull Collection<Inet4Address> addrs) {
         int[] res = new int[addrs.size()];
         int i = 0;
diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java
index 38f8609..82b17ac 100644
--- a/packages/Tethering/src/android/net/ip/IpServer.java
+++ b/packages/Tethering/src/android/net/ip/IpServer.java
@@ -18,12 +18,14 @@
 
 import static android.net.InetAddresses.parseNumericAddress;
 import static android.net.RouteInfo.RTN_UNICAST;
+import static android.net.TetheringManager.TetheringRequest.checkStaticAddressConfiguration;
 import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
 import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
 import static android.net.util.NetworkConstants.FF;
 import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
 import static android.net.util.NetworkConstants.asByte;
 import static android.net.util.TetheringMessageBase.BASE_IPSERVER;
+import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
 
 import android.net.INetd;
 import android.net.INetworkStackStatusCallback;
@@ -34,6 +36,7 @@
 import android.net.RouteInfo;
 import android.net.TetheredClient;
 import android.net.TetheringManager;
+import android.net.TetheringRequestParcel;
 import android.net.dhcp.DhcpLeaseParcelable;
 import android.net.dhcp.DhcpServerCallbacks;
 import android.net.dhcp.DhcpServingParamsParcel;
@@ -242,6 +245,10 @@
     private IDhcpServer mDhcpServer;
     private RaParams mLastRaParams;
     private LinkAddress mIpv4Address;
+
+    private LinkAddress mStaticIpv4ServerAddr;
+    private LinkAddress mStaticIpv4ClientAddr;
+
     @NonNull
     private List<TetheredClient> mDhcpLeases = Collections.emptyList();
 
@@ -448,7 +455,9 @@
             final ArrayList<TetheredClient> leases = new ArrayList<>();
             for (DhcpLeaseParcelable lease : leaseParcelables) {
                 final LinkAddress address = new LinkAddress(
-                        intToInet4AddressHTH(lease.netAddr), lease.prefixLength);
+                        intToInet4AddressHTH(lease.netAddr), lease.prefixLength,
+                        0 /* flags */, RT_SCOPE_UNIVERSE /* as per RFC6724#3.2 */,
+                        lease.expTime /* deprecationTime */, lease.expTime /* expirationTime */);
 
                 final MacAddress macAddress;
                 try {
@@ -460,7 +469,7 @@
                 }
 
                 final TetheredClient.AddressInfo addressInfo = new TetheredClient.AddressInfo(
-                        address, lease.hostname, lease.expTime);
+                        address, lease.hostname);
                 leases.add(new TetheredClient(
                         macAddress,
                         Collections.singletonList(addressInfo),
@@ -484,17 +493,24 @@
         }
     }
 
-    private boolean startDhcp(Inet4Address addr, int prefixLen) {
+    private boolean startDhcp(final LinkAddress serverLinkAddr, final LinkAddress clientLinkAddr) {
         if (mUsingLegacyDhcp) {
             return true;
         }
+
+        final Inet4Address addr = (Inet4Address) serverLinkAddr.getAddress();
+        final int prefixLen = serverLinkAddr.getPrefixLength();
+        final Inet4Address clientAddr = clientLinkAddr == null ? null :
+                (Inet4Address) clientLinkAddr.getAddress();
+
         final DhcpServingParamsParcel params;
         params = new DhcpServingParamsParcelExt()
                 .setDefaultRouters(addr)
                 .setDhcpLeaseTimeSecs(DHCP_LEASE_TIME_SECS)
                 .setDnsServers(addr)
-                .setServerAddr(new LinkAddress(addr, prefixLen))
-                .setMetered(true);
+                .setServerAddr(serverLinkAddr)
+                .setMetered(true)
+                .setSingleClientAddr(clientAddr);
         // TODO: also advertise link MTU
 
         mDhcpServerStartIndex++;
@@ -529,9 +545,10 @@
         }
     }
 
-    private boolean configureDhcp(boolean enable, Inet4Address addr, int prefixLen) {
+    private boolean configureDhcp(boolean enable, final LinkAddress serverAddr,
+            final LinkAddress clientAddr) {
         if (enable) {
-            return startDhcp(addr, prefixLen);
+            return startDhcp(serverAddr, clientAddr);
         } else {
             stopDhcp();
             return true;
@@ -544,6 +561,8 @@
         // into calls to InterfaceController, shared with startIPv4().
         mInterfaceCtrl.clearIPv4Address();
         mIpv4Address = null;
+        mStaticIpv4ServerAddr = null;
+        mStaticIpv4ClientAddr = null;
     }
 
     private boolean configureIPv4(boolean enabled) {
@@ -554,7 +573,10 @@
         final Inet4Address srvAddr;
         int prefixLen = 0;
         try {
-            if (mInterfaceType == TetheringManager.TETHERING_USB
+            if (mStaticIpv4ServerAddr != null) {
+                srvAddr = (Inet4Address) mStaticIpv4ServerAddr.getAddress();
+                prefixLen = mStaticIpv4ServerAddr.getPrefixLength();
+            } else if (mInterfaceType == TetheringManager.TETHERING_USB
                     || mInterfaceType == TetheringManager.TETHERING_NCM) {
                 srvAddr = (Inet4Address) parseNumericAddress(USB_NEAR_IFACE_ADDR);
                 prefixLen = USB_PREFIX_LENGTH;
@@ -574,7 +596,7 @@
                 // code that calls into NetworkManagementService directly.
                 srvAddr = (Inet4Address) parseNumericAddress(BLUETOOTH_IFACE_ADDR);
                 mIpv4Address = new LinkAddress(srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
-                return configureDhcp(enabled, srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
+                return configureDhcp(enabled, mIpv4Address, null /* clientAddress */);
             }
             mIpv4Address = new LinkAddress(srvAddr, prefixLen);
         } catch (IllegalArgumentException e) {
@@ -599,10 +621,6 @@
             return false;
         }
 
-        if (!configureDhcp(enabled, srvAddr, prefixLen)) {
-            return false;
-        }
-
         // Directly-connected route.
         final IpPrefix ipv4Prefix = new IpPrefix(mIpv4Address.getAddress(),
                 mIpv4Address.getPrefixLength());
@@ -614,7 +632,8 @@
             mLinkProperties.removeLinkAddress(mIpv4Address);
             mLinkProperties.removeRoute(route);
         }
-        return true;
+
+        return configureDhcp(enabled, mIpv4Address, mStaticIpv4ClientAddr);
     }
 
     private String getRandomWifiIPv4Address() {
@@ -934,6 +953,20 @@
         mLinkProperties.setInterfaceName(mIfaceName);
     }
 
+    private void maybeConfigureStaticIp(final TetheringRequestParcel request) {
+        // Ignore static address configuration if they are invalid or null. In theory, static
+        // addresses should not be invalid here because TetheringManager do not allow caller to
+        // specify invalid static address configuration.
+        if (request == null || request.localIPv4Address == null
+                || request.staticClientAddress == null || !checkStaticAddressConfiguration(
+                request.localIPv4Address, request.staticClientAddress)) {
+            return;
+        }
+
+        mStaticIpv4ServerAddr = request.localIPv4Address;
+        mStaticIpv4ClientAddr = request.staticClientAddress;
+    }
+
     class InitialState extends State {
         @Override
         public void enter() {
@@ -948,9 +981,11 @@
                     mLastError = TetheringManager.TETHER_ERROR_NO_ERROR;
                     switch (message.arg1) {
                         case STATE_LOCAL_ONLY:
+                            maybeConfigureStaticIp((TetheringRequestParcel) message.obj);
                             transitionTo(mLocalHotspotState);
                             break;
                         case STATE_TETHERED:
+                            maybeConfigureStaticIp((TetheringRequestParcel) message.obj);
                             transitionTo(mTetheredState);
                             break;
                         default:
@@ -1035,7 +1070,7 @@
                 case CMD_START_TETHERING_ERROR:
                 case CMD_STOP_TETHERING_ERROR:
                 case CMD_SET_DNS_FORWARDERS_ERROR:
-                    mLastError = TetheringManager.TETHER_ERROR_MASTER_ERROR;
+                    mLastError = TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
                     transitionTo(mInitialState);
                     break;
                 default:
@@ -1166,7 +1201,7 @@
                         } catch (RemoteException | ServiceSpecificException e) {
                             mLog.e("Exception enabling NAT: " + e.toString());
                             cleanupUpstream();
-                            mLastError = TetheringManager.TETHER_ERROR_ENABLE_NAT_ERROR;
+                            mLastError = TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR;
                             transitionTo(mInitialState);
                             return true;
                         }
diff --git a/packages/Tethering/src/android/net/util/TetheringUtils.java b/packages/Tethering/src/android/net/util/TetheringUtils.java
index 5a6d5c1..dd67ddd 100644
--- a/packages/Tethering/src/android/net/util/TetheringUtils.java
+++ b/packages/Tethering/src/android/net/util/TetheringUtils.java
@@ -15,8 +15,11 @@
  */
 package android.net.util;
 
+import android.net.TetheringRequestParcel;
+
 import java.io.FileDescriptor;
 import java.net.SocketException;
+import java.util.Objects;
 
 /**
  * Native methods for tethering utilization.
@@ -38,4 +41,17 @@
     public static int uint16(short s) {
         return s & 0xffff;
     }
+
+    /** Check whether two TetheringRequestParcels are the same. */
+    public static boolean isTetheringRequestEquals(final TetheringRequestParcel request,
+            final TetheringRequestParcel otherRequest) {
+        if (request == otherRequest) return true;
+
+        return request != null && otherRequest != null
+                && request.tetheringType == otherRequest.tetheringType
+                && Objects.equals(request.localIPv4Address, otherRequest.localIPv4Address)
+                && Objects.equals(request.staticClientAddress, otherRequest.staticClientAddress)
+                && request.exemptFromEntitlementCheck == otherRequest.exemptFromEntitlementCheck
+                && request.showProvisioningUi == otherRequest.showProvisioningUi;
+    }
 }
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java b/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java
index e81d6ac..bd60594f 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java
@@ -25,7 +25,7 @@
 import static android.net.TetheringManager.TETHERING_WIFI;
 import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
 import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
-import static android.net.TetheringManager.TETHER_ERROR_PROVISION_FAILED;
+import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
 
 import android.app.AlarmManager;
 import android.app.PendingIntent;
@@ -579,7 +579,7 @@
         switch (value) {
             case TETHER_ERROR_ENTITLEMENT_UNKNOWN: return "TETHER_ERROR_ENTITLEMENT_UNKONWN";
             case TETHER_ERROR_NO_ERROR: return "TETHER_ERROR_NO_ERROR";
-            case TETHER_ERROR_PROVISION_FAILED: return "TETHER_ERROR_PROVISION_FAILED";
+            case TETHER_ERROR_PROVISIONING_FAILED: return "TETHER_ERROR_PROVISIONING_FAILED";
             default:
                 return String.format("UNKNOWN ERROR (%d)", value);
         }
@@ -592,7 +592,7 @@
             protected void onReceiveResult(int resultCode, Bundle resultData) {
                 int updatedCacheValue = updateEntitlementCacheValue(type, resultCode);
                 addDownstreamMapping(type, updatedCacheValue);
-                if (updatedCacheValue == TETHER_ERROR_PROVISION_FAILED && notifyFail) {
+                if (updatedCacheValue == TETHER_ERROR_PROVISIONING_FAILED && notifyFail) {
                     mListener.onUiEntitlementFailed(type);
                 }
                 if (receiver != null) receiver.send(updatedCacheValue, null);
@@ -635,8 +635,8 @@
             mEntitlementCacheValue.put(type, resultCode);
             return resultCode;
         } else {
-            mEntitlementCacheValue.put(type, TETHER_ERROR_PROVISION_FAILED);
-            return TETHER_ERROR_PROVISION_FAILED;
+            mEntitlementCacheValue.put(type, TETHER_ERROR_PROVISIONING_FAILED);
+            return TETHER_ERROR_PROVISIONING_FAILED;
         }
     }
 
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java
index a402ffa..15cdb6a 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java
@@ -39,8 +39,7 @@
 import android.net.netlink.ConntrackMessage;
 import android.net.netlink.NetlinkConstants;
 import android.net.netlink.NetlinkSocket;
-import android.net.netstats.provider.AbstractNetworkStatsProvider;
-import android.net.netstats.provider.NetworkStatsProviderCallback;
+import android.net.netstats.provider.NetworkStatsProvider;
 import android.net.util.SharedLog;
 import android.os.Handler;
 import android.provider.Settings;
@@ -89,8 +88,8 @@
     private final Handler mHandler;
     private final OffloadHardwareInterface mHwInterface;
     private final ContentResolver mContentResolver;
-    private final @NonNull OffloadTetheringStatsProvider mStatsProvider;
-    private final @Nullable NetworkStatsProviderCallback mStatsProviderCb;
+    @Nullable
+    private final OffloadTetheringStatsProvider mStatsProvider;
     private final SharedLog mLog;
     private final HashMap<String, LinkProperties> mDownstreams;
     private boolean mConfigInitialized;
@@ -124,19 +123,18 @@
         mHandler = h;
         mHwInterface = hwi;
         mContentResolver = contentResolver;
-        mStatsProvider = new OffloadTetheringStatsProvider();
         mLog = log.forSubComponent(TAG);
         mDownstreams = new HashMap<>();
         mExemptPrefixes = new HashSet<>();
         mLastLocalPrefixStrs = new HashSet<>();
-        NetworkStatsProviderCallback providerCallback = null;
+        OffloadTetheringStatsProvider provider = new OffloadTetheringStatsProvider();
         try {
-            providerCallback = nsm.registerNetworkStatsProvider(
-                    getClass().getSimpleName(), mStatsProvider);
+            nsm.registerNetworkStatsProvider(getClass().getSimpleName(), provider);
         } catch (RuntimeException e) {
             Log.wtf(TAG, "Cannot register offload stats provider: " + e);
+            provider = null;
         }
-        mStatsProviderCb = providerCallback;
+        mStatsProvider = provider;
     }
 
     /** Start hardware offload. */
@@ -185,7 +183,7 @@
                         // and we need to synchronize stats and limits between
                         // software and hardware forwarding.
                         updateStatsForAllUpstreams();
-                        mStatsProvider.pushTetherStats();
+                        if (mStatsProvider != null) mStatsProvider.pushTetherStats();
                     }
 
                     @Override
@@ -198,7 +196,7 @@
                         // limits set take into account any software tethering
                         // traffic that has been happening in the meantime.
                         updateStatsForAllUpstreams();
-                        mStatsProvider.pushTetherStats();
+                        if (mStatsProvider != null) mStatsProvider.pushTetherStats();
                         // [2] (Re)Push all state.
                         computeAndPushLocalPrefixes(UpdateType.FORCE);
                         pushAllDownstreamState();
@@ -217,10 +215,12 @@
                         // TODO: rev the HAL so that it provides an interface name.
 
                         updateStatsForCurrentUpstream();
-                        mStatsProvider.pushTetherStats();
-                        // Push stats to service does not cause the service react to it immediately.
-                        // Inform the service about limit reached.
-                        if (mStatsProviderCb != null) mStatsProviderCb.onLimitReached();
+                        if (mStatsProvider != null) {
+                            mStatsProvider.pushTetherStats();
+                            // Push stats to service does not cause the service react to it
+                            // immediately. Inform the service about limit reached.
+                            mStatsProvider.notifyLimitReached();
+                        }
                     }
 
                     @Override
@@ -263,13 +263,17 @@
     }
 
     @VisibleForTesting
-    class OffloadTetheringStatsProvider extends AbstractNetworkStatsProvider {
+    class OffloadTetheringStatsProvider extends NetworkStatsProvider {
         // These stats must only ever be touched on the handler thread.
         @NonNull
         private NetworkStats mIfaceStats = new NetworkStats(0L, 0);
         @NonNull
         private NetworkStats mUidStats = new NetworkStats(0L, 0);
 
+        /**
+         * A helper function that collect tether stats from local hashmap. Note that this does not
+         * invoke binder call.
+         */
         @VisibleForTesting
         @NonNull
         NetworkStats getTetherStats(@NonNull StatsType how) {
@@ -280,14 +284,14 @@
                 final ForwardedStats value = kv.getValue();
                 final Entry entry = new Entry(kv.getKey(), uid, SET_DEFAULT, TAG_NONE, METERED_NO,
                         ROAMING_NO, DEFAULT_NETWORK_NO, value.rxBytes, 0L, value.txBytes, 0L, 0L);
-                stats = stats.addValues(entry);
+                stats = stats.addEntry(entry);
             }
 
             return stats;
         }
 
         @Override
-        public void setLimit(String iface, long quotaBytes) {
+        public void onSetLimit(String iface, long quotaBytes) {
             // Listen for all iface is necessary since upstream might be changed after limit
             // is set.
             mHandler.post(() -> {
@@ -315,13 +319,12 @@
          */
         public void pushTetherStats() {
             // TODO: remove the accumulated stats and report the diff from HAL directly.
-            if (null == mStatsProviderCb) return;
             final NetworkStats ifaceDiff =
                     getTetherStats(StatsType.STATS_PER_IFACE).subtract(mIfaceStats);
             final NetworkStats uidDiff =
                     getTetherStats(StatsType.STATS_PER_UID).subtract(mUidStats);
             try {
-                mStatsProviderCb.onStatsUpdated(0 /* token */, ifaceDiff, uidDiff);
+                notifyStatsUpdated(0 /* token */, ifaceDiff, uidDiff);
                 mIfaceStats = mIfaceStats.add(ifaceDiff);
                 mUidStats = mUidStats.add(uidDiff);
             } catch (RuntimeException e) {
@@ -330,7 +333,7 @@
         }
 
         @Override
-        public void requestStatsUpdate(int token) {
+        public void onRequestStatsUpdate(int token) {
             // Do not attempt to update stats by querying the offload HAL
             // synchronously from a different thread than the Handler thread. http://b/64771555.
             mHandler.post(() -> {
@@ -340,7 +343,7 @@
         }
 
         @Override
-        public void setAlert(long quotaBytes) {
+        public void onSetAlert(long quotaBytes) {
             // TODO: Ask offload HAL to notify alert without stopping traffic.
         }
     }
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
index 5539017..343ed4b 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
@@ -39,11 +39,12 @@
 import static android.net.TetheringManager.TETHERING_USB;
 import static android.net.TetheringManager.TETHERING_WIFI;
 import static android.net.TetheringManager.TETHERING_WIFI_P2P;
-import static android.net.TetheringManager.TETHER_ERROR_MASTER_ERROR;
+import static android.net.TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
 import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
 import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
 import static android.net.TetheringManager.TETHER_ERROR_UNAVAIL_IFACE;
 import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
+import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_TYPE;
 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
@@ -92,6 +93,7 @@
 import android.net.util.InterfaceSet;
 import android.net.util.PrefixUtils;
 import android.net.util.SharedLog;
+import android.net.util.TetheringUtils;
 import android.net.util.VersionedBroadcastListener;
 import android.net.wifi.WifiClient;
 import android.net.wifi.WifiManager;
@@ -196,6 +198,11 @@
     private final SharedLog mLog = new SharedLog(TAG);
     private final RemoteCallbackList<ITetheringEventCallback> mTetheringEventCallbacks =
             new RemoteCallbackList<>();
+    // Currently active tethering requests per tethering type. Only one of each type can be
+    // requested at a time. After a tethering type is requested, the map keeps tethering parameters
+    // to be used after the interface comes up asynchronously.
+    private final SparseArray<TetheringRequestParcel> mActiveTetheringRequests =
+            new SparseArray<>();
 
     // used to synchronize public access to members
     private final Object mPublicSync;
@@ -296,31 +303,26 @@
 
         final UserManager userManager = (UserManager) mContext.getSystemService(
                 Context.USER_SERVICE);
-        mTetheringRestriction = new UserRestrictionActionListener(userManager, this);
+        mTetheringRestriction = new UserRestrictionActionListener(
+                userManager, this, mNotificationUpdater);
         mExecutor = new TetheringThreadExecutor(mHandler);
         mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor);
+        mNetdCallback = new NetdCallback();
 
         // Load tethering configuration.
         updateConfiguration();
-        // NetdCallback should be registered after updateConfiguration() to ensure
-        // TetheringConfiguration is created.
-        mNetdCallback = new NetdCallback();
+    }
+
+    /**
+     * Start to register callbacks.
+     * Call this function when tethering is ready to handle callback events.
+     */
+    public void startStateMachineUpdaters() {
         try {
             mNetd.registerUnsolicitedEventListener(mNetdCallback);
         } catch (RemoteException e) {
             mLog.e("Unable to register netd UnsolicitedEventListener");
         }
-
-        startStateMachineUpdaters(mHandler);
-        startTrackDefaultNetwork();
-
-        final WifiManager wifiManager = getWifiManager();
-        if (wifiManager != null) {
-            wifiManager.registerSoftApCallback(mExecutor, new TetheringSoftApCallback());
-        }
-    }
-
-    private void startStateMachineUpdaters(Handler handler) {
         mCarrierConfigChange.startListening();
         mContext.getSystemService(TelephonyManager.class).listen(mActiveDataSubIdListener,
                 PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
@@ -333,7 +335,14 @@
         filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
         filter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED);
         filter.addAction(ACTION_RESTRICT_BACKGROUND_CHANGED);
-        mContext.registerReceiver(mStateReceiver, filter, null, handler);
+        mContext.registerReceiver(mStateReceiver, filter, null, mHandler);
+
+        final WifiManager wifiManager = getWifiManager();
+        if (wifiManager != null) {
+            wifiManager.registerSoftApCallback(mExecutor, new TetheringSoftApCallback());
+        }
+
+        startTrackDefaultNetwork();
     }
 
     private class TetheringThreadExecutor implements Executor {
@@ -362,9 +371,10 @@
 
             mActiveDataSubId = subId;
             updateConfiguration();
+            mNotificationUpdater.onActiveDataSubscriptionIdChanged(subId);
             // To avoid launching unexpected provisioning checks, ignore re-provisioning
             // when no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning()
-            // ill be triggered again when CarrierConfig is loaded.
+            // will be triggered again when CarrierConfig is loaded.
             if (mEntitlementMgr.getCarrierConfig(mConfig) != null) {
                 mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
             } else {
@@ -424,9 +434,7 @@
         // Called by wifi when the number of soft AP clients changed.
         @Override
         public void onConnectedClientsChanged(final List<WifiClient> clients) {
-            if (mConnectedClientsTracker.updateConnectedClients(mForwardedDownstreams, clients)) {
-                reportTetherClientsChanged(mConnectedClientsTracker.getLastTetheredClients());
-            }
+            updateConnectedClients(clients);
         }
     }
 
@@ -487,14 +495,31 @@
     }
 
     void startTethering(final TetheringRequestParcel request, final IIntResultListener listener) {
-        mEntitlementMgr.startProvisioningIfNeeded(request.tetheringType,
-                request.showProvisioningUi);
-        enableTetheringInternal(request.tetheringType, true /* enabled */, listener);
+        mHandler.post(() -> {
+            final TetheringRequestParcel unfinishedRequest = mActiveTetheringRequests.get(
+                    request.tetheringType);
+            // If tethering is already enabled with a different request,
+            // disable before re-enabling.
+            if (unfinishedRequest != null
+                    && !TetheringUtils.isTetheringRequestEquals(unfinishedRequest, request)) {
+                enableTetheringInternal(request.tetheringType, false /* disabled */, null);
+                mEntitlementMgr.stopProvisioningIfNeeded(request.tetheringType);
+            }
+            mActiveTetheringRequests.put(request.tetheringType, request);
+
+            mEntitlementMgr.startProvisioningIfNeeded(request.tetheringType,
+                    request.showProvisioningUi);
+            enableTetheringInternal(request.tetheringType, true /* enabled */, listener);
+        });
     }
 
     void stopTethering(int type) {
-        enableTetheringInternal(type, false /* disabled */, null);
-        mEntitlementMgr.stopProvisioningIfNeeded(type);
+        mHandler.post(() -> {
+            mActiveTetheringRequests.remove(type);
+
+            enableTetheringInternal(type, false /* disabled */, null);
+            mEntitlementMgr.stopProvisioningIfNeeded(type);
+        });
     }
 
     /**
@@ -503,39 +528,45 @@
      */
     private void enableTetheringInternal(int type, boolean enable,
             final IIntResultListener listener) {
-        int result;
+        int result = TETHER_ERROR_NO_ERROR;
         switch (type) {
             case TETHERING_WIFI:
                 result = setWifiTethering(enable);
-                sendTetherResult(listener, result);
                 break;
             case TETHERING_USB:
                 result = setUsbTethering(enable);
-                sendTetherResult(listener, result);
                 break;
             case TETHERING_BLUETOOTH:
                 setBluetoothTethering(enable, listener);
                 break;
             case TETHERING_NCM:
                 result = setNcmTethering(enable);
-                sendTetherResult(listener, result);
                 break;
             case TETHERING_ETHERNET:
                 result = setEthernetTethering(enable);
-                sendTetherResult(listener, result);
                 break;
             default:
                 Log.w(TAG, "Invalid tether type.");
-                sendTetherResult(listener, TETHER_ERROR_UNKNOWN_IFACE);
+                result = TETHER_ERROR_UNKNOWN_TYPE;
+        }
+
+        // The result of Bluetooth tethering will be sent by #setBluetoothTethering.
+        if (type != TETHERING_BLUETOOTH) {
+            sendTetherResult(listener, result, type);
         }
     }
 
-    private void sendTetherResult(final IIntResultListener listener, int result) {
+    private void sendTetherResult(final IIntResultListener listener, final int result,
+            final int type) {
         if (listener != null) {
             try {
                 listener.onResult(result);
             } catch (RemoteException e) { }
         }
+
+        // If changing tethering fail, remove corresponding request
+        // no matter who trigger the start/stop.
+        if (result != TETHER_ERROR_NO_ERROR) mActiveTetheringRequests.remove(type);
     }
 
     private int setWifiTethering(final boolean enable) {
@@ -557,7 +588,7 @@
             Binder.restoreCallingIdentity(ident);
         }
 
-        return TETHER_ERROR_MASTER_ERROR;
+        return TETHER_ERROR_INTERNAL_ERROR;
     }
 
     private void setBluetoothTethering(final boolean enable, final IIntResultListener listener) {
@@ -565,7 +596,7 @@
         if (adapter == null || !adapter.isEnabled()) {
             Log.w(TAG, "Tried to enable bluetooth tethering with null or disabled adapter. null: "
                     + (adapter == null));
-            sendTetherResult(listener, TETHER_ERROR_SERVICE_UNAVAIL);
+            sendTetherResult(listener, TETHER_ERROR_SERVICE_UNAVAIL, TETHERING_BLUETOOTH);
             return;
         }
 
@@ -593,8 +624,8 @@
                 // We should figure out a way to bubble up that failure instead of sending success.
                 final int result = (((BluetoothPan) proxy).isTetheringOn() == enable)
                         ? TETHER_ERROR_NO_ERROR
-                        : TETHER_ERROR_MASTER_ERROR;
-                sendTetherResult(listener, result);
+                        : TETHER_ERROR_INTERNAL_ERROR;
+                sendTetherResult(listener, result, TETHERING_BLUETOOTH);
                 adapter.closeProfileProxy(BluetoothProfile.PAN, proxy);
             }
         }, BluetoothProfile.PAN);
@@ -605,27 +636,30 @@
                 Context.ETHERNET_SERVICE);
         synchronized (mPublicSync) {
             if (enable) {
-                if (mEthernetCallback != null) return TETHER_ERROR_NO_ERROR;
+                if (mEthernetCallback != null) {
+                    Log.d(TAG, "Ethernet tethering already started");
+                    return TETHER_ERROR_NO_ERROR;
+                }
 
                 mEthernetCallback = new EthernetCallback();
                 mEthernetIfaceRequest = em.requestTetheredInterface(mExecutor, mEthernetCallback);
             } else {
                 stopEthernetTetheringLocked();
-                if (mEthernetCallback != null) {
-                    mEthernetIfaceRequest.release();
-                    mEthernetCallback = null;
-                    mEthernetIfaceRequest = null;
-                }
             }
         }
         return TETHER_ERROR_NO_ERROR;
     }
 
     private void stopEthernetTetheringLocked() {
-        if (mConfiguredEthernetIface == null) return;
-        changeInterfaceState(mConfiguredEthernetIface, IpServer.STATE_AVAILABLE);
-        stopTrackingInterfaceLocked(mConfiguredEthernetIface);
-        mConfiguredEthernetIface = null;
+        if (mConfiguredEthernetIface != null) {
+            stopTrackingInterfaceLocked(mConfiguredEthernetIface);
+            mConfiguredEthernetIface = null;
+        }
+        if (mEthernetCallback != null) {
+            mEthernetIfaceRequest.release();
+            mEthernetCallback = null;
+            mEthernetIfaceRequest = null;
+        }
     }
 
     private class EthernetCallback implements EthernetManager.TetheredInterfaceCallback {
@@ -672,12 +706,18 @@
                 Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring");
                 return TETHER_ERROR_UNAVAIL_IFACE;
             }
-            // NOTE: If a CMD_TETHER_REQUESTED message is already in the TISM's
-            // queue but not yet processed, this will be a no-op and it will not
-            // return an error.
+            // NOTE: If a CMD_TETHER_REQUESTED message is already in the TISM's queue but not yet
+            // processed, this will be a no-op and it will not return an error.
             //
-            // TODO: reexamine the threading and messaging model.
-            tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_REQUESTED, requestedState);
+            // This code cannot race with untether() because they both synchronize on mPublicSync.
+            // TODO: reexamine the threading and messaging model to totally remove mPublicSync.
+            final int type = tetherState.ipServer.interfaceType();
+            final TetheringRequestParcel request = mActiveTetheringRequests.get(type, null);
+            if (request != null) {
+                mActiveTetheringRequests.delete(type);
+            }
+            tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_REQUESTED, requestedState, 0,
+                    request);
             return TETHER_ERROR_NO_ERROR;
         }
     }
@@ -960,11 +1000,14 @@
     protected static class UserRestrictionActionListener {
         private final UserManager mUserManager;
         private final Tethering mWrapper;
+        private final TetheringNotificationUpdater mNotificationUpdater;
         public boolean mDisallowTethering;
 
-        public UserRestrictionActionListener(UserManager um, Tethering wrapper) {
+        public UserRestrictionActionListener(@NonNull UserManager um, @NonNull Tethering wrapper,
+                @NonNull TetheringNotificationUpdater updater) {
             mUserManager = um;
             mWrapper = wrapper;
+            mNotificationUpdater = updater;
             mDisallowTethering = false;
         }
 
@@ -983,13 +1026,21 @@
                 return;
             }
 
-            // TODO: Add user restrictions notification.
-            final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0);
-
-            if (newlyDisallowed && isTetheringActiveOnDevice) {
-                mWrapper.untetherAll();
-                // TODO(b/148139325): send tetheringSupported on restriction change
+            if (!newlyDisallowed) {
+                // Clear the restricted notification when user is allowed to have tethering
+                // function.
+                mNotificationUpdater.tetheringRestrictionLifted();
+                return;
             }
+
+            // Restricted notification is shown when tethering function is disallowed on
+            // user's device.
+            mNotificationUpdater.notifyTetheringDisabledByRestriction();
+
+            // Untether from all downstreams since tethering is disallowed.
+            mWrapper.untetherAll();
+
+            // TODO(b/148139325): send tetheringSupported on restriction change
         }
     }
 
@@ -1458,7 +1509,7 @@
             } else {
                 dnsServers = mConfig.defaultIPv4DNS;
             }
-            final int netId = (network != null) ? network.netId : NETID_UNSET;
+            final int netId = (network != null) ? network.getNetId() : NETID_UNSET;
             try {
                 mNetd.tetherDnsSet(netId, dnsServers);
                 mLog.log(String.format(
@@ -1523,6 +1574,7 @@
             mIPv6TetheringCoordinator.removeActiveDownstream(who);
             mOffload.excludeDownstreamInterface(who.interfaceName());
             mForwardedDownstreams.remove(who);
+            updateConnectedClients(null /* wifiClients */);
 
             // If this is a Wi-Fi interface, tell WifiManager of any errors
             // or the inactive serving state.
@@ -2105,6 +2157,12 @@
         return false;
     }
 
+    private void updateConnectedClients(final List<WifiClient> wifiClients) {
+        if (mConnectedClientsTracker.updateConnectedClients(mForwardedDownstreams, wifiClients)) {
+            reportTetherClientsChanged(mConnectedClientsTracker.getLastTetheredClients());
+        }
+    }
+
     private IpServer.Callback makeControlCallback() {
         return new IpServer.Callback() {
             @Override
@@ -2119,10 +2177,7 @@
 
             @Override
             public void dhcpLeasesChanged() {
-                if (mConnectedClientsTracker.updateConnectedClients(
-                        mForwardedDownstreams, null /* wifiClients */)) {
-                    reportTetherClientsChanged(mConnectedClientsTracker.getLastTetheredClients());
-                }
+                updateConnectedClients(null /* wifiClients */);
             }
         };
     }
@@ -2145,7 +2200,7 @@
         // If TetherMasterSM is in ErrorState, TetherMasterSM stays there.
         // Thus we give a chance for TetherMasterSM to recover to InitialState
         // by sending CMD_CLEAR_ERROR
-        if (error == TETHER_ERROR_MASTER_ERROR) {
+        if (error == TETHER_ERROR_INTERNAL_ERROR) {
             mTetherMasterSM.sendMessage(TetherMasterSM.CMD_CLEAR_ERROR, who);
         }
         int which;
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringNotificationUpdater.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringNotificationUpdater.java
index b97f752..992cdd8 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringNotificationUpdater.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringNotificationUpdater.java
@@ -29,12 +29,14 @@
 import android.content.res.Resources;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.telephony.SubscriptionManager;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseArray;
 
 import androidx.annotation.ArrayRes;
 import androidx.annotation.DrawableRes;
+import androidx.annotation.IntDef;
 import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
 
@@ -54,10 +56,15 @@
 public class TetheringNotificationUpdater {
     private static final String TAG = TetheringNotificationUpdater.class.getSimpleName();
     private static final String CHANNEL_ID = "TETHERING_STATUS";
+    private static final String WIFI_DOWNSTREAM = "WIFI";
+    private static final String USB_DOWNSTREAM = "USB";
+    private static final String BLUETOOTH_DOWNSTREAM = "BT";
     private static final boolean NOTIFY_DONE = true;
     private static final boolean NO_NOTIFY = false;
     // Id to update and cancel tethering notification. Must be unique within the tethering app.
-    private static final int NOTIFY_ID = 20191115;
+    private static final int ENABLE_NOTIFICATION_ID = 1000;
+    // Id to update and cancel restricted notification. Must be unique within the tethering app.
+    private static final int RESTRICTED_NOTIFICATION_ID = 1001;
     @VisibleForTesting
     static final int NO_ICON_ID = 0;
     @VisibleForTesting
@@ -65,14 +72,25 @@
     private final Context mContext;
     private final NotificationManager mNotificationManager;
     private final NotificationChannel mChannel;
-    // Downstream type is one of ConnectivityManager.TETHERING_* constants, 0 1 or 2.
-    // This value has to be made 1 2 and 4, and OR'd with the others.
+
     // WARNING : the constructor is called on a different thread. Thread safety therefore
     // relies on this value being initialized to 0, and not any other value. If you need
     // to change this, you will need to change the thread where the constructor is invoked,
     // or to introduce synchronization.
+    // Downstream type is one of ConnectivityManager.TETHERING_* constants, 0 1 or 2.
+    // This value has to be made 1 2 and 4, and OR'd with the others.
     private int mDownstreamTypesMask = DOWNSTREAM_NONE;
 
+    // WARNING : this value is not able to being initialized to 0 and must have volatile because
+    // telephony service is not guaranteed that is up before tethering service starts. If telephony
+    // is up later than tethering, TetheringNotificationUpdater will use incorrect and valid
+    // subscription id(0) to query resources. Therefore, initialized subscription id must be
+    // INVALID_SUBSCRIPTION_ID.
+    private volatile int mActiveDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+    @IntDef({ENABLE_NOTIFICATION_ID, RESTRICTED_NOTIFICATION_ID})
+    @interface NotificationId {}
+
     public TetheringNotificationUpdater(@NonNull final Context context) {
         mContext = context;
         mNotificationManager = (NotificationManager) context.createContextAsUser(UserHandle.ALL, 0)
@@ -88,19 +106,46 @@
     public void onDownstreamChanged(@IntRange(from = 0, to = 7) final int downstreamTypesMask) {
         if (mDownstreamTypesMask == downstreamTypesMask) return;
         mDownstreamTypesMask = downstreamTypesMask;
-        updateNotification();
+        updateEnableNotification();
     }
 
-    private void updateNotification() {
+    /** Called when active data subscription id changed */
+    public void onActiveDataSubscriptionIdChanged(final int subId) {
+        if (mActiveDataSubId == subId) return;
+        mActiveDataSubId = subId;
+        updateEnableNotification();
+    }
+
+    @VisibleForTesting
+    Resources getResourcesForSubId(@NonNull final Context c, final int subId) {
+        return SubscriptionManager.getResourcesForSubId(c, subId);
+    }
+
+    private void updateEnableNotification() {
         final boolean tetheringInactive = mDownstreamTypesMask <= DOWNSTREAM_NONE;
 
         if (tetheringInactive || setupNotification() == NO_NOTIFY) {
-            clearNotification();
+            clearNotification(ENABLE_NOTIFICATION_ID);
         }
     }
 
-    private void clearNotification() {
-        mNotificationManager.cancel(null /* tag */, NOTIFY_ID);
+    @VisibleForTesting
+    void tetheringRestrictionLifted() {
+        clearNotification(RESTRICTED_NOTIFICATION_ID);
+    }
+
+    private void clearNotification(@NotificationId final int id) {
+        mNotificationManager.cancel(null /* tag */, id);
+    }
+
+    @VisibleForTesting
+    void notifyTetheringDisabledByRestriction() {
+        final Resources res = getResourcesForSubId(mContext, mActiveDataSubId);
+        final String title = res.getString(R.string.disable_tether_notification_title);
+        final String message = res.getString(R.string.disable_tether_notification_message);
+
+        showNotification(R.drawable.stat_sys_tether_general, title, message,
+                RESTRICTED_NOTIFICATION_ID);
     }
 
     /**
@@ -110,16 +155,17 @@
      *
      * @return downstream types mask value.
      */
+    @VisibleForTesting
     @IntRange(from = 0, to = 7)
-    private int getDownstreamTypesMask(@NonNull final String types) {
+    int getDownstreamTypesMask(@NonNull final String types) {
         int downstreamTypesMask = DOWNSTREAM_NONE;
         final String[] downstreams = types.split("\\|");
         for (String downstream : downstreams) {
-            if ("USB".equals(downstream.trim())) {
+            if (USB_DOWNSTREAM.equals(downstream.trim())) {
                 downstreamTypesMask |= (1 << TETHERING_USB);
-            } else if ("WIFI".equals(downstream.trim())) {
+            } else if (WIFI_DOWNSTREAM.equals(downstream.trim())) {
                 downstreamTypesMask |= (1 << TETHERING_WIFI);
-            } else if ("BT".equals(downstream.trim())) {
+            } else if (BLUETOOTH_DOWNSTREAM.equals(downstream.trim())) {
                 downstreamTypesMask |= (1 << TETHERING_BLUETOOTH);
             }
         }
@@ -134,9 +180,8 @@
      *
      * @return {@link android.util.SparseArray} with downstream types and icon id info.
      */
-    @NonNull
-    private SparseArray<Integer> getIcons(@ArrayRes int id) {
-        final Resources res = mContext.getResources();
+    @VisibleForTesting
+    SparseArray<Integer> getIcons(@ArrayRes int id, @NonNull Resources res) {
         final String[] array = res.getStringArray(id);
         final SparseArray<Integer> icons = new SparseArray<>();
         for (String config : array) {
@@ -161,8 +206,9 @@
     }
 
     private boolean setupNotification() {
-        final Resources res = mContext.getResources();
-        final SparseArray<Integer> downstreamIcons = getIcons(R.array.tethering_notification_icons);
+        final Resources res = getResourcesForSubId(mContext, mActiveDataSubId);
+        final SparseArray<Integer> downstreamIcons =
+                getIcons(R.array.tethering_notification_icons, res);
 
         final int iconId = downstreamIcons.get(mDownstreamTypesMask, NO_ICON_ID);
         if (iconId == NO_ICON_ID) return NO_NOTIFY;
@@ -170,12 +216,12 @@
         final String title = res.getString(R.string.tethering_notification_title);
         final String message = res.getString(R.string.tethering_notification_message);
 
-        showNotification(iconId, title, message);
+        showNotification(iconId, title, message, ENABLE_NOTIFICATION_ID);
         return NOTIFY_DONE;
     }
 
     private void showNotification(@DrawableRes final int iconId, @NonNull final String title,
-            @NonNull final String message) {
+            @NonNull final String message, @NotificationId final int id) {
         final Intent intent = new Intent(Settings.ACTION_TETHER_SETTINGS);
         final PendingIntent pi = PendingIntent.getActivity(
                 mContext.createContextAsUser(UserHandle.CURRENT, 0),
@@ -193,6 +239,6 @@
                         .setContentIntent(pi)
                         .build();
 
-        mNotificationManager.notify(null /* tag */, NOTIFY_ID, notification);
+        mNotificationManager.notify(null /* tag */, id, notification);
     }
 }
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java
index 020b32a..c30be25 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java
@@ -33,6 +33,7 @@
 import android.net.ITetheringEventCallback;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.net.NetworkStack;
 import android.net.TetheringRequestParcel;
 import android.net.dhcp.DhcpServerCallbacks;
 import android.net.dhcp.DhcpServingParamsParcel;
@@ -79,6 +80,7 @@
         mContext = mDeps.getContext();
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         mTethering = makeTethering(mDeps);
+        mTethering.startStateMachineUpdaters();
     }
 
     /**
@@ -364,8 +366,7 @@
                     IBinder connector;
                     try {
                         final long before = System.currentTimeMillis();
-                        while ((connector = (IBinder) mContext.getSystemService(
-                                Context.NETWORK_STACK_SERVICE)) == null) {
+                        while ((connector = NetworkStack.getService()) == null) {
                             if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) {
                                 Log.wtf(TAG, "Timeout, fail to get INetworkStackConnector");
                                 return null;
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
index 2875f71..45bb4ab 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
@@ -244,7 +244,8 @@
         // Additionally, we log a message to aid in any subsequent debugging.
         mLog.i("requesting mobile upstream network: " + mobileUpstreamRequest);
 
-        cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, legacyType, mHandler);
+        cm().requestNetwork(mobileUpstreamRequest, 0, legacyType, mHandler,
+                mMobileNetworkCallback);
     }
 
     /** Release mobile network request. */
@@ -585,21 +586,21 @@
      */
     @VisibleForTesting
     public static NetworkCapabilities networkCapabilitiesForType(int type) {
-        final NetworkCapabilities nc = new NetworkCapabilities();
+        final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
 
         // Map from type to transports.
         final int notFound = -1;
         final int transport = sLegacyTypeToTransport.get(type, notFound);
         Preconditions.checkArgument(transport != notFound, "unknown legacy type: " + type);
-        nc.addTransportType(transport);
+        builder.addTransportType(transport);
 
         if (type == TYPE_MOBILE_DUN) {
-            nc.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
+            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
             // DUN is restricted network, see NetworkCapabilities#FORCE_RESTRICTED_CAPABILITIES.
-            nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
         } else {
-            nc.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
         }
-        return nc;
+        return builder.build();
     }
 }
diff --git a/packages/Tethering/tests/integration/Android.bp b/packages/Tethering/tests/integration/Android.bp
new file mode 100644
index 0000000..1a1c30d
--- /dev/null
+++ b/packages/Tethering/tests/integration/Android.bp
@@ -0,0 +1,42 @@
+//
+// 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: "TetheringIntegrationTests",
+    certificate: "platform",
+    platform_apis: true,
+    srcs: [
+        "src/**/*.java",
+        "src/**/*.kt",
+    ],
+    test_suites: [
+        "device-tests",
+        "mts",
+    ],
+    static_libs: [
+        "NetworkStackApiStableLib",
+        "androidx.test.rules",
+        "frameworks-base-testutils",
+        "mockito-target-extended-minus-junit4",
+        "net-tests-utils",
+        "testables",
+    ],
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+        "android.test.mock",
+    ],
+}
diff --git a/packages/Tethering/tests/integration/AndroidManifest.xml b/packages/Tethering/tests/integration/AndroidManifest.xml
new file mode 100644
index 0000000..233ba40
--- /dev/null
+++ b/packages/Tethering/tests/integration/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?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.integration">
+
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.TETHER_PRIVILEGED"/>
+
+    <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.integration"
+        android:label="Tethering integration tests">
+    </instrumentation>
+</manifest>
diff --git a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
new file mode 100644
index 0000000..492ce3d
--- /dev/null
+++ b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -0,0 +1,459 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
+import static android.Manifest.permission.NETWORK_SETTINGS;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.UiAutomation;
+import android.content.Context;
+import android.net.EthernetManager.TetheredInterfaceCallback;
+import android.net.EthernetManager.TetheredInterfaceRequest;
+import android.net.TetheringManager.StartTetheringCallback;
+import android.net.TetheringManager.TetheringEventCallback;
+import android.net.TetheringManager.TetheringRequest;
+import android.net.dhcp.DhcpAckPacket;
+import android.net.dhcp.DhcpOfferPacket;
+import android.net.dhcp.DhcpPacket;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.SystemClock;
+import android.system.Os;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.HandlerUtilsKt;
+import com.android.testutils.TapPacketReader;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.FileDescriptor;
+import java.net.Inet4Address;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class EthernetTetheringTest {
+
+    private static final String TAG = EthernetTetheringTest.class.getSimpleName();
+    private static final int TIMEOUT_MS = 1000;
+    private static final int PACKET_READ_TIMEOUT_MS = 100;
+    private static final int DHCP_DISCOVER_ATTEMPTS = 10;
+    private static final byte[] DHCP_REQUESTED_PARAMS = new byte[] {
+            DhcpPacket.DHCP_SUBNET_MASK,
+            DhcpPacket.DHCP_ROUTER,
+            DhcpPacket.DHCP_DNS_SERVER,
+            DhcpPacket.DHCP_LEASE_TIME,
+    };
+    private static final String DHCP_HOSTNAME = "testhostname";
+
+    private final Context mContext = InstrumentationRegistry.getContext();
+    private final EthernetManager mEm = mContext.getSystemService(EthernetManager.class);
+    private final TetheringManager mTm = mContext.getSystemService(TetheringManager.class);
+
+    private TestNetworkInterface mTestIface;
+    private HandlerThread mHandlerThread;
+    private Handler mHandler;
+    private TapPacketReader mTapPacketReader;
+
+    private TetheredInterfaceRequester mTetheredInterfaceRequester;
+    private MyTetheringEventCallback mTetheringEventCallback;
+
+    private UiAutomation mUiAutomation =
+            InstrumentationRegistry.getInstrumentation().getUiAutomation();
+
+    @Before
+    public void setUp() throws Exception {
+        mHandlerThread = new HandlerThread(getClass().getSimpleName());
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+        mTetheredInterfaceRequester = new TetheredInterfaceRequester(mHandler, mEm);
+        // Needed to create a TestNetworkInterface, to call requestTetheredInterface, and to receive
+        // tethered client callbacks.
+        mUiAutomation.adoptShellPermissionIdentity(MANAGE_TEST_NETWORKS, NETWORK_SETTINGS);
+    }
+
+    private void cleanUp() throws Exception {
+        mTm.stopTethering(TetheringManager.TETHERING_ETHERNET);
+        if (mTetheringEventCallback != null) {
+            mTetheringEventCallback.awaitInterfaceUntethered();
+            mTetheringEventCallback.unregister();
+            mTetheringEventCallback = null;
+        }
+        if (mTapPacketReader != null) {
+            TapPacketReader reader = mTapPacketReader;
+            mHandler.post(() -> reader.stop());
+            mTapPacketReader = null;
+        }
+        mHandlerThread.quitSafely();
+        mTetheredInterfaceRequester.release();
+        mEm.setIncludeTestInterfaces(false);
+        maybeDeleteTestInterface();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        try {
+            cleanUp();
+        } finally {
+            mUiAutomation.dropShellPermissionIdentity();
+        }
+    }
+
+    @Test
+    public void testVirtualEthernetAlreadyExists() throws Exception {
+        // This test requires manipulating packets. Skip if there is a physical Ethernet connected.
+        assumeFalse(mEm.isAvailable());
+
+        mTestIface = createTestInterface();
+        // This must be done now because as soon as setIncludeTestInterfaces(true) is called, the
+        // interface will be placed in client mode, which will delete the link-local address.
+        // At that point NetworkInterface.getByName() will cease to work on the interface, because
+        // starting in R NetworkInterface can no longer see interfaces without IP addresses.
+        int mtu = getMTU(mTestIface);
+
+        Log.d(TAG, "Including test interfaces");
+        mEm.setIncludeTestInterfaces(true);
+
+        final String iface = mTetheredInterfaceRequester.getInterface();
+        assertEquals("TetheredInterfaceCallback for unexpected interface",
+                mTestIface.getInterfaceName(), iface);
+
+        checkVirtualEthernet(mTestIface, mtu);
+    }
+
+    @Test
+    public void testVirtualEthernet() throws Exception {
+        // This test requires manipulating packets. Skip if there is a physical Ethernet connected.
+        assumeFalse(mEm.isAvailable());
+
+        CompletableFuture<String> futureIface = mTetheredInterfaceRequester.requestInterface();
+
+        mEm.setIncludeTestInterfaces(true);
+
+        mTestIface = createTestInterface();
+
+        final String iface = futureIface.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        assertEquals("TetheredInterfaceCallback for unexpected interface",
+                mTestIface.getInterfaceName(), iface);
+
+        checkVirtualEthernet(mTestIface, getMTU(mTestIface));
+    }
+
+    @Test
+    public void testPhysicalEthernet() throws Exception {
+        assumeTrue(mEm.isAvailable());
+
+        // Get an interface to use.
+        final String iface = mTetheredInterfaceRequester.getInterface();
+
+        // Enable Ethernet tethering and check that it starts.
+        mTetheringEventCallback = enableEthernetTethering(iface);
+
+        // There is nothing more we can do on a physical interface without connecting an actual
+        // client, which is not possible in this test.
+    }
+
+    private static final class MyTetheringEventCallback implements TetheringEventCallback {
+        private final TetheringManager mTm;
+        private final CountDownLatch mTetheringStartedLatch = new CountDownLatch(1);
+        private final CountDownLatch mTetheringStoppedLatch = new CountDownLatch(1);
+        private final CountDownLatch mClientConnectedLatch = new CountDownLatch(1);
+        private final String mIface;
+
+        private volatile boolean mInterfaceWasTethered = false;
+        private volatile boolean mUnregistered = false;
+        private volatile Collection<TetheredClient> mClients = null;
+
+        MyTetheringEventCallback(TetheringManager tm, String iface) {
+            mTm = tm;
+            mIface = iface;
+        }
+
+        public void unregister() {
+            mTm.unregisterTetheringEventCallback(this);
+            mUnregistered = true;
+        }
+
+        @Override
+        public void onTetheredInterfacesChanged(List<String> interfaces) {
+            // Ignore stale callbacks registered by previous test cases.
+            if (mUnregistered) return;
+
+            final boolean wasTethered = mTetheringStartedLatch.getCount() == 0;
+            if (!mInterfaceWasTethered && (mIface == null || interfaces.contains(mIface))) {
+                // This interface is being tethered for the first time.
+                Log.d(TAG, "Tethering started: " + interfaces);
+                mInterfaceWasTethered = true;
+                mTetheringStartedLatch.countDown();
+            } else if (mInterfaceWasTethered && !interfaces.contains(mIface)) {
+                Log.d(TAG, "Tethering stopped: " + interfaces);
+                mTetheringStoppedLatch.countDown();
+            }
+        }
+
+        public void awaitInterfaceTethered() throws Exception {
+            assertTrue("Ethernet not tethered after " + TIMEOUT_MS + "ms",
+                    mTetheringStartedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        }
+
+        public void awaitInterfaceUntethered() throws Exception {
+            // Don't block teardown if the interface was never tethered.
+            // This is racy because the interface might become tethered right after this check, but
+            // that can only happen in tearDown if startTethering timed out, which likely means
+            // the test has already failed.
+            if (!mInterfaceWasTethered) return;
+
+            assertTrue(mIface + " not untethered after " + TIMEOUT_MS + "ms",
+                    mTetheringStoppedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        }
+
+        @Override
+        public void onError(String ifName, int error) {
+            // Ignore stale callbacks registered by previous test cases.
+            if (mUnregistered) return;
+
+            fail("TetheringEventCallback got error:" + error + " on iface " + ifName);
+        }
+
+        @Override
+        public void onClientsChanged(Collection<TetheredClient> clients) {
+            // Ignore stale callbacks registered by previous test cases.
+            if (mUnregistered) return;
+
+            Log.d(TAG, "Got clients changed: " + clients);
+            mClients = clients;
+            if (clients.size() > 0) {
+                mClientConnectedLatch.countDown();
+            }
+        }
+
+        public Collection<TetheredClient> awaitClientConnected() throws Exception {
+            assertTrue("Did not receive client connected callback after " + TIMEOUT_MS + "ms",
+                    mClientConnectedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            return mClients;
+        }
+    }
+
+    private MyTetheringEventCallback enableEthernetTethering(String iface) throws Exception {
+        MyTetheringEventCallback callback = new MyTetheringEventCallback(mTm, iface);
+        mTm.registerTetheringEventCallback(mHandler::post, callback);
+
+        StartTetheringCallback startTetheringCallback = new StartTetheringCallback() {
+            @Override
+            public void onTetheringFailed(int resultCode) {
+                fail("Unexpectedly got onTetheringFailed");
+            }
+        };
+        Log.d(TAG, "Starting Ethernet tethering");
+        mTm.startTethering(
+                new TetheringRequest.Builder(TetheringManager.TETHERING_ETHERNET).build(),
+                mHandler::post /* executor */,  startTetheringCallback);
+        callback.awaitInterfaceTethered();
+        return callback;
+    }
+
+    private int getMTU(TestNetworkInterface iface) throws SocketException {
+        NetworkInterface nif = NetworkInterface.getByName(iface.getInterfaceName());
+        assertNotNull("Can't get NetworkInterface object for " + iface.getInterfaceName(), nif);
+        return nif.getMTU();
+    }
+
+    private void checkVirtualEthernet(TestNetworkInterface iface, int mtu) throws Exception {
+        FileDescriptor fd = iface.getFileDescriptor().getFileDescriptor();
+        mTapPacketReader = new TapPacketReader(mHandler, fd, mtu);
+        mHandler.post(() -> mTapPacketReader.start());
+        HandlerUtilsKt.waitForIdle(mHandler, TIMEOUT_MS);
+
+        mTetheringEventCallback = enableEthernetTethering(iface.getInterfaceName());
+        checkTetheredClientCallbacks(fd);
+    }
+
+    private void checkTetheredClientCallbacks(FileDescriptor fd) throws Exception {
+        // Create a fake client.
+        byte[] clientMacAddr = new byte[6];
+        new Random().nextBytes(clientMacAddr);
+
+        // We have to retransmit DHCP requests because IpServer declares itself to be ready before
+        // its DhcpServer is actually started. TODO: fix this race and remove this loop.
+        DhcpPacket offerPacket = null;
+        for (int i = 0; i < DHCP_DISCOVER_ATTEMPTS; i++) {
+            Log.d(TAG, "Sending DHCP discover");
+            sendDhcpDiscover(fd, clientMacAddr);
+            offerPacket = getNextDhcpPacket();
+            if (offerPacket instanceof DhcpOfferPacket) break;
+        }
+        assertTrue("No DHCPOFFER received on interface within timeout",
+                offerPacket instanceof DhcpOfferPacket);
+
+        sendDhcpRequest(fd, offerPacket, clientMacAddr);
+        DhcpPacket ackPacket = getNextDhcpPacket();
+        assertTrue("No DHCPACK received on interface within timeout",
+                ackPacket instanceof DhcpAckPacket);
+
+        final Collection<TetheredClient> clients = mTetheringEventCallback.awaitClientConnected();
+        assertEquals(1, clients.size());
+        final TetheredClient client = clients.iterator().next();
+
+        // Check the MAC address.
+        assertEquals(MacAddress.fromBytes(clientMacAddr), client.getMacAddress());
+        assertEquals(TetheringManager.TETHERING_ETHERNET, client.getTetheringType());
+
+        // Check the hostname.
+        assertEquals(1, client.getAddresses().size());
+        TetheredClient.AddressInfo info = client.getAddresses().get(0);
+        assertEquals(DHCP_HOSTNAME, info.getHostname());
+
+        // Check the address is the one that was handed out in the DHCP ACK.
+        DhcpResults dhcpResults = offerPacket.toDhcpResults();
+        assertLinkAddressMatches(dhcpResults.ipAddress, info.getAddress());
+
+        // Check that the lifetime is correct +/- 10s.
+        final long now = SystemClock.elapsedRealtime();
+        final long actualLeaseDuration = (info.getAddress().getExpirationTime() - now) / 1000;
+        final String msg = String.format("IP address should have lifetime of %d, got %d",
+                dhcpResults.leaseDuration, actualLeaseDuration);
+        assertTrue(msg, Math.abs(dhcpResults.leaseDuration - actualLeaseDuration) < 10);
+    }
+
+    private DhcpPacket getNextDhcpPacket() throws ParseException {
+        byte[] packet;
+        while ((packet = mTapPacketReader.popPacket(PACKET_READ_TIMEOUT_MS)) != null) {
+            try {
+                return DhcpPacket.decodeFullPacket(packet, packet.length, DhcpPacket.ENCAP_L2);
+            } catch (DhcpPacket.ParseException e) {
+                // Not a DHCP packet. Continue.
+            }
+        }
+        return null;
+    }
+
+    private static final class TetheredInterfaceRequester implements TetheredInterfaceCallback {
+        private final CountDownLatch mInterfaceAvailableLatch = new CountDownLatch(1);
+        private final Handler mHandler;
+        private final EthernetManager mEm;
+
+        private TetheredInterfaceRequest mRequest;
+        private final CompletableFuture<String> mFuture = new CompletableFuture<>();
+
+        TetheredInterfaceRequester(Handler handler, EthernetManager em) {
+            mHandler = handler;
+            mEm = em;
+        }
+
+        @Override
+        public void onAvailable(String iface) {
+            Log.d(TAG, "Ethernet interface available: " + iface);
+            mFuture.complete(iface);
+        }
+
+        @Override
+        public void onUnavailable() {
+            mFuture.completeExceptionally(new IllegalStateException("onUnavailable received"));
+        }
+
+        public CompletableFuture<String> requestInterface() {
+            assertNull("BUG: more than one tethered interface request", mRequest);
+            Log.d(TAG, "Requesting tethered interface");
+            mRequest = mEm.requestTetheredInterface(mHandler::post, this);
+            return mFuture;
+        }
+
+        public String getInterface() throws Exception {
+            return requestInterface().get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        }
+
+        public void release() {
+            if (mRequest != null) {
+                mFuture.obtrudeException(new IllegalStateException("Request already released"));
+                mRequest.release();
+                mRequest = null;
+            }
+        }
+    }
+
+    private void sendDhcpDiscover(FileDescriptor fd, byte[] macAddress) throws Exception {
+        ByteBuffer packet = DhcpPacket.buildDiscoverPacket(DhcpPacket.ENCAP_L2,
+                new Random().nextInt() /* transactionId */, (short) 0 /* secs */,
+                macAddress,  false /* unicast */, DHCP_REQUESTED_PARAMS,
+                false /* rapid commit */,  DHCP_HOSTNAME);
+        sendPacket(fd, packet);
+    }
+
+    private void sendDhcpRequest(FileDescriptor fd, DhcpPacket offerPacket, byte[] macAddress)
+            throws Exception {
+        DhcpResults results = offerPacket.toDhcpResults();
+        Inet4Address clientIp = (Inet4Address) results.ipAddress.getAddress();
+        Inet4Address serverIdentifier = results.serverAddress;
+        ByteBuffer packet = DhcpPacket.buildRequestPacket(DhcpPacket.ENCAP_L2,
+                0 /* transactionId */, (short) 0 /* secs */, DhcpPacket.INADDR_ANY /* clientIp */,
+                false /* broadcast */, macAddress, clientIp /* requestedIpAddress */,
+                serverIdentifier, DHCP_REQUESTED_PARAMS, DHCP_HOSTNAME);
+        sendPacket(fd, packet);
+    }
+
+    private void sendPacket(FileDescriptor fd, ByteBuffer packet) throws Exception {
+        assertNotNull("Only tests on virtual interfaces can send packets", fd);
+        Os.write(fd, packet);
+    }
+
+    public void assertLinkAddressMatches(LinkAddress l1, LinkAddress l2) {
+        // Check all fields except the deprecation and expiry times.
+        String msg = String.format("LinkAddresses do not match. expected: %s actual: %s", l1, l2);
+        assertTrue(msg, l1.isSameAddressAs(l2));
+        assertEquals("LinkAddress flags do not match", l1.getFlags(), l2.getFlags());
+        assertEquals("LinkAddress scope does not match", l1.getScope(), l2.getScope());
+    }
+
+    private TestNetworkInterface createTestInterface() throws Exception {
+        TestNetworkManager tnm = mContext.getSystemService(TestNetworkManager.class);
+        TestNetworkInterface iface = tnm.createTapInterface();
+        Log.d(TAG, "Created test interface " + iface.getInterfaceName());
+        assertNotNull(NetworkInterface.getByName(iface.getInterfaceName()));
+        return iface;
+    }
+
+    private void maybeDeleteTestInterface() throws Exception {
+        if (mTestIface != null) {
+            mTestIface.getFileDescriptor().close();
+            Log.d(TAG, "Deleted test interface " + mTestIface.getInterfaceName());
+            mTestIface = null;
+        }
+    }
+}
diff --git a/packages/Tethering/tests/unit/src/android/net/TetheredClientTest.kt b/packages/Tethering/tests/unit/src/android/net/TetheredClientTest.kt
index d85389a..a20a0df 100644
--- a/packages/Tethering/tests/unit/src/android/net/TetheredClientTest.kt
+++ b/packages/Tethering/tests/unit/src/android/net/TetheredClientTest.kt
@@ -20,6 +20,7 @@
 import android.net.TetheredClient.AddressInfo
 import android.net.TetheringManager.TETHERING_BLUETOOTH
 import android.net.TetheringManager.TETHERING_USB
+import android.system.OsConstants.RT_SCOPE_UNIVERSE
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
 import com.android.testutils.assertParcelSane
@@ -30,11 +31,19 @@
 
 private val TEST_MACADDR = MacAddress.fromBytes(byteArrayOf(12, 23, 34, 45, 56, 67))
 private val TEST_OTHER_MACADDR = MacAddress.fromBytes(byteArrayOf(23, 34, 45, 56, 67, 78))
-private val TEST_ADDR1 = LinkAddress(parseNumericAddress("192.168.113.3"), 24)
-private val TEST_ADDR2 = LinkAddress(parseNumericAddress("fe80::1:2:3"), 64)
+private val TEST_ADDR1 = makeLinkAddress("192.168.113.3", prefixLength = 24, expTime = 123L)
+private val TEST_ADDR2 = makeLinkAddress("fe80::1:2:3", prefixLength = 64, expTime = 456L)
 private val TEST_ADDRINFO1 = AddressInfo(TEST_ADDR1, "test_hostname")
 private val TEST_ADDRINFO2 = AddressInfo(TEST_ADDR2, null)
 
+private fun makeLinkAddress(addr: String, prefixLength: Int, expTime: Long) = LinkAddress(
+        parseNumericAddress(addr),
+        prefixLength,
+        0 /* flags */,
+        RT_SCOPE_UNIVERSE,
+        expTime /* deprecationTime */,
+        expTime /* expirationTime */)
+
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class TetheredClientTest {
diff --git a/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java b/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java
index e8add98..f8eb147 100644
--- a/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java
+++ b/packages/Tethering/tests/unit/src/android/net/dhcp/DhcpServingParamsParcelExtTest.java
@@ -42,7 +42,9 @@
 @SmallTest
 public class DhcpServingParamsParcelExtTest {
     private static final Inet4Address TEST_ADDRESS = inet4Addr("192.168.0.123");
+    private static final Inet4Address TEST_CLIENT_ADDRESS = inet4Addr("192.168.0.42");
     private static final int TEST_ADDRESS_PARCELED = 0xc0a8007b;
+    private static final int TEST_CLIENT_ADDRESS_PARCELED = 0xc0a8002a;
     private static final int TEST_PREFIX_LENGTH = 17;
     private static final int TEST_LEASE_TIME_SECS = 120;
     private static final int TEST_MTU = 1000;
@@ -105,6 +107,12 @@
         assertFalse(mParcel.metered);
     }
 
+    @Test
+    public void testSetClientAddr() {
+        mParcel.setSingleClientAddr(TEST_CLIENT_ADDRESS);
+        assertEquals(TEST_CLIENT_ADDRESS_PARCELED, mParcel.clientAddr);
+    }
+
     private static Inet4Address inet4Addr(String addr) {
         return (Inet4Address) parseNumericAddress(addr);
     }
diff --git a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index 948266d..3106e0e 100644
--- a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -21,7 +21,7 @@
 import static android.net.TetheringManager.TETHERING_USB;
 import static android.net.TetheringManager.TETHERING_WIFI;
 import static android.net.TetheringManager.TETHERING_WIFI_P2P;
-import static android.net.TetheringManager.TETHER_ERROR_ENABLE_NAT_ERROR;
+import static android.net.TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR;
 import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
 import static android.net.TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR;
 import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
@@ -448,7 +448,7 @@
         usbTeardownOrder.verify(mNetd, times(2)).interfaceSetCfg(
                 argThat(cfg -> IFACE_NAME.equals(cfg.ifName)));
         usbTeardownOrder.verify(mCallback).updateInterfaceState(
-                mIpServer, STATE_AVAILABLE, TETHER_ERROR_ENABLE_NAT_ERROR);
+                mIpServer, STATE_AVAILABLE, TETHER_ERROR_ENABLE_FORWARDING_ERROR);
         usbTeardownOrder.verify(mCallback).updateLinkProperties(
                 eq(mIpServer), mLinkPropertiesCaptor.capture());
         assertNoAddressesNorRoutes(mLinkPropertiesCaptor.getValue());
diff --git a/packages/Tethering/tests/unit/src/android/net/util/TetheringUtilsTest.java b/packages/Tethering/tests/unit/src/android/net/util/TetheringUtilsTest.java
new file mode 100644
index 0000000..1499f3b
--- /dev/null
+++ b/packages/Tethering/tests/unit/src/android/net/util/TetheringUtilsTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.net.util;
+
+import static android.net.TetheringManager.TETHERING_USB;
+import static android.net.TetheringManager.TETHERING_WIFI;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import android.net.LinkAddress;
+import android.net.TetheringRequestParcel;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.MiscAssertsKt;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class TetheringUtilsTest {
+    private static final LinkAddress TEST_SERVER_ADDR = new LinkAddress("192.168.43.1/24");
+    private static final LinkAddress TEST_CLIENT_ADDR = new LinkAddress("192.168.43.5/24");
+    private TetheringRequestParcel mTetheringRequest;
+
+    @Before
+    public void setUp() {
+        mTetheringRequest = makeTetheringRequestParcel();
+    }
+
+    public TetheringRequestParcel makeTetheringRequestParcel() {
+        final TetheringRequestParcel request = new TetheringRequestParcel();
+        request.tetheringType = TETHERING_WIFI;
+        request.localIPv4Address = TEST_SERVER_ADDR;
+        request.staticClientAddress = TEST_CLIENT_ADDR;
+        request.exemptFromEntitlementCheck = false;
+        request.showProvisioningUi = true;
+        return request;
+    }
+
+    @Test
+    public void testIsTetheringRequestEquals() throws Exception {
+        TetheringRequestParcel request = makeTetheringRequestParcel();
+
+        assertTrue(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, mTetheringRequest));
+        assertTrue(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request));
+        assertTrue(TetheringUtils.isTetheringRequestEquals(null, null));
+        assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, null));
+        assertFalse(TetheringUtils.isTetheringRequestEquals(null, mTetheringRequest));
+
+        request = makeTetheringRequestParcel();
+        request.tetheringType = TETHERING_USB;
+        assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request));
+
+        request = makeTetheringRequestParcel();
+        request.localIPv4Address = null;
+        request.staticClientAddress = null;
+        assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request));
+
+        request = makeTetheringRequestParcel();
+        request.exemptFromEntitlementCheck = true;
+        assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request));
+
+        request = makeTetheringRequestParcel();
+        request.showProvisioningUi = false;
+        assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request));
+
+        MiscAssertsKt.assertFieldCountEquals(5, TetheringRequestParcel.class);
+    }
+}
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/ConnectedClientsTrackerTest.kt b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/ConnectedClientsTrackerTest.kt
index 56f3e21..1cdc3bb 100644
--- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/ConnectedClientsTrackerTest.kt
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/ConnectedClientsTrackerTest.kt
@@ -46,23 +46,28 @@
 
     private val client1Addr = MacAddress.fromString("01:23:45:67:89:0A")
     private val client1 = TetheredClient(client1Addr, listOf(
-            AddressInfo(LinkAddress("192.168.43.44/32"), null /* hostname */, clock.time + 20)),
+            makeAddrInfo("192.168.43.44/32", null /* hostname */, clock.time + 20)),
             TETHERING_WIFI)
     private val wifiClient1 = makeWifiClient(client1Addr)
     private val client2Addr = MacAddress.fromString("02:34:56:78:90:AB")
-    private val client2Exp30AddrInfo = AddressInfo(
-            LinkAddress("192.168.43.45/32"), "my_hostname", clock.time + 30)
+    private val client2Exp30AddrInfo = makeAddrInfo(
+            "192.168.43.45/32", "my_hostname", clock.time + 30)
     private val client2 = TetheredClient(client2Addr, listOf(
             client2Exp30AddrInfo,
-            AddressInfo(LinkAddress("2001:db8:12::34/72"), "other_hostname", clock.time + 10)),
+            makeAddrInfo("2001:db8:12::34/72", "other_hostname", clock.time + 10)),
             TETHERING_WIFI)
     private val wifiClient2 = makeWifiClient(client2Addr)
     private val client3Addr = MacAddress.fromString("03:45:67:89:0A:BC")
     private val client3 = TetheredClient(client3Addr,
-            listOf(AddressInfo(LinkAddress("2001:db8:34::34/72"), "other_other_hostname",
-                    clock.time + 10)),
+            listOf(makeAddrInfo("2001:db8:34::34/72", "other_other_hostname", clock.time + 10)),
             TETHERING_USB)
 
+    private fun makeAddrInfo(addr: String, hostname: String?, expTime: Long) =
+            LinkAddress(addr).let {
+                AddressInfo(LinkAddress(it.address, it.prefixLength, it.flags, it.scope,
+                        expTime /* deprecationTime */, expTime /* expirationTime */), hostname)
+            }
+
     @Test
     fun testUpdateConnectedClients() {
         doReturn(emptyList<TetheredClient>()).`when`(server1).allLeases
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java
index 3a1d4a6..0a7850b 100644
--- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java
@@ -21,7 +21,7 @@
 import static android.net.TetheringManager.TETHERING_WIFI;
 import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
 import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
-import static android.net.TetheringManager.TETHER_ERROR_PROVISION_FAILED;
+import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
 import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
@@ -284,11 +284,11 @@
         assertEquals(0, mEnMgr.uiProvisionCount);
         mEnMgr.reset();
         // 3. No cache value and ui entitlement check is needed.
-        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
         receiver = new ResultReceiver(null) {
             @Override
             protected void onReceiveResult(int resultCode, Bundle resultData) {
-                assertEquals(TETHER_ERROR_PROVISION_FAILED, resultCode);
+                assertEquals(TETHER_ERROR_PROVISIONING_FAILED, resultCode);
                 mCallbacklatch.countDown();
             }
         };
@@ -297,12 +297,13 @@
         callbackTimeoutHelper(mCallbacklatch);
         assertEquals(1, mEnMgr.uiProvisionCount);
         mEnMgr.reset();
-        // 4. Cache value is TETHER_ERROR_PROVISION_FAILED and don't need to run entitlement check.
+        // 4. Cache value is TETHER_ERROR_PROVISIONING_FAILED and don't need to run entitlement
+        // check.
         mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
         receiver = new ResultReceiver(null) {
             @Override
             protected void onReceiveResult(int resultCode, Bundle resultData) {
-                assertEquals(TETHER_ERROR_PROVISION_FAILED, resultCode);
+                assertEquals(TETHER_ERROR_PROVISIONING_FAILED, resultCode);
                 mCallbacklatch.countDown();
             }
         };
@@ -311,7 +312,7 @@
         callbackTimeoutHelper(mCallbacklatch);
         assertEquals(0, mEnMgr.uiProvisionCount);
         mEnMgr.reset();
-        // 5. Cache value is TETHER_ERROR_PROVISION_FAILED and ui entitlement check is needed.
+        // 5. Cache value is TETHER_ERROR_PROVISIONING_FAILED and ui entitlement check is needed.
         mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
         receiver = new ResultReceiver(null) {
             @Override
@@ -364,7 +365,7 @@
     public void verifyPermissionResult() {
         setupForRequiredProvisioning();
         mEnMgr.notifyUpstream(true);
-        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
         mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
         mLooper.dispatchAll();
         assertFalse(mEnMgr.isCellularUpstreamPermitted());
@@ -380,15 +381,15 @@
     public void verifyPermissionIfAllNotApproved() {
         setupForRequiredProvisioning();
         mEnMgr.notifyUpstream(true);
-        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
         mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
         mLooper.dispatchAll();
         assertFalse(mEnMgr.isCellularUpstreamPermitted());
-        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
         mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
         mLooper.dispatchAll();
         assertFalse(mEnMgr.isCellularUpstreamPermitted());
-        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
         mEnMgr.startProvisioningIfNeeded(TETHERING_BLUETOOTH, true);
         mLooper.dispatchAll();
         assertFalse(mEnMgr.isCellularUpstreamPermitted());
@@ -403,7 +404,7 @@
         mLooper.dispatchAll();
         assertTrue(mEnMgr.isCellularUpstreamPermitted());
         mLooper.dispatchAll();
-        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
         mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
         mLooper.dispatchAll();
         assertTrue(mEnMgr.isCellularUpstreamPermitted());
@@ -465,7 +466,7 @@
         assertEquals(0, mEnMgr.silentProvisionCount);
         mEnMgr.reset();
         // 6. switch upstream back to mobile again
-        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
         mEnMgr.notifyUpstream(true);
         mLooper.dispatchAll();
         assertEquals(0, mEnMgr.uiProvisionCount);
@@ -477,7 +478,7 @@
     public void testCallStopTetheringWhenUiProvisioningFail() {
         setupForRequiredProvisioning();
         verify(mEntitlementFailedListener, times(0)).onUiEntitlementFailed(TETHERING_WIFI);
-        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISIONING_FAILED;
         mEnMgr.notifyUpstream(true);
         mLooper.dispatchAll();
         mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java
index 7e62e5a..fe84086 100644
--- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java
@@ -33,6 +33,8 @@
 import static com.android.testutils.MiscAssertsKt.assertThrows;
 import static com.android.testutils.NetworkStatsUtilsKt.orderInsensitiveEquals;
 
+import static junit.framework.Assert.assertNotNull;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -61,8 +63,7 @@
 import android.net.NetworkStats;
 import android.net.NetworkStats.Entry;
 import android.net.RouteInfo;
-import android.net.netstats.provider.AbstractNetworkStatsProvider;
-import android.net.netstats.provider.NetworkStatsProviderCallback;
+import android.net.netstats.provider.INetworkStatsProviderCallback;
 import android.net.util.SharedLog;
 import android.os.Handler;
 import android.os.Looper;
@@ -108,12 +109,10 @@
     @Mock private ApplicationInfo mApplicationInfo;
     @Mock private Context mContext;
     @Mock private NetworkStatsManager mStatsManager;
-    @Mock private NetworkStatsProviderCallback mTetherStatsProviderCb;
+    @Mock private INetworkStatsProviderCallback mTetherStatsProviderCb;
+    private OffloadController.OffloadTetheringStatsProvider mTetherStatsProvider;
     private final ArgumentCaptor<ArrayList> mStringArrayCaptor =
             ArgumentCaptor.forClass(ArrayList.class);
-    private final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider>
-            mTetherStatsProviderCaptor =
-            ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class);
     private final ArgumentCaptor<OffloadHardwareInterface.ControlCallback> mControlCallbackCaptor =
             ArgumentCaptor.forClass(OffloadHardwareInterface.ControlCallback.class);
     private MockContentResolver mContentResolver;
@@ -126,8 +125,6 @@
         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
         FakeSettingsProvider.clearSettingsProvider();
-        when(mStatsManager.registerNetworkStatsProvider(anyString(), any()))
-                .thenReturn(mTetherStatsProviderCb);
     }
 
     @After public void tearDown() throws Exception {
@@ -154,8 +151,14 @@
     private OffloadController makeOffloadController() throws Exception {
         OffloadController offload = new OffloadController(new Handler(Looper.getMainLooper()),
                 mHardware, mContentResolver, mStatsManager, new SharedLog("test"));
+        final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider>
+                tetherStatsProviderCaptor =
+                ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class);
         verify(mStatsManager).registerNetworkStatsProvider(anyString(),
-                mTetherStatsProviderCaptor.capture());
+                tetherStatsProviderCaptor.capture());
+        mTetherStatsProvider = tetherStatsProviderCaptor.getValue();
+        assertNotNull(mTetherStatsProvider);
+        mTetherStatsProvider.setProviderCallbackBinder(mTetherStatsProviderCb);
         return offload;
     }
 
@@ -413,9 +416,6 @@
         final OffloadController offload = makeOffloadController();
         offload.start();
 
-        final OffloadController.OffloadTetheringStatsProvider provider =
-                mTetherStatsProviderCaptor.getValue();
-
         final String ethernetIface = "eth1";
         final String mobileIface = "rmnet_data0";
 
@@ -443,15 +443,15 @@
         inOrder.verify(mHardware, times(1)).getForwardedStats(eq(mobileIface));
 
         // Verify that the fetched stats are stored.
-        final NetworkStats ifaceStats = provider.getTetherStats(STATS_PER_IFACE);
-        final NetworkStats uidStats = provider.getTetherStats(STATS_PER_UID);
+        final NetworkStats ifaceStats = mTetherStatsProvider.getTetherStats(STATS_PER_IFACE);
+        final NetworkStats uidStats = mTetherStatsProvider.getTetherStats(STATS_PER_UID);
         final NetworkStats expectedIfaceStats = new NetworkStats(0L, 2)
-                .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999))
-                .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 12345, 54321));
+                .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999))
+                .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 12345, 54321));
 
         final NetworkStats expectedUidStats = new NetworkStats(0L, 2)
-                .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
-                .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 12345, 54321));
+                .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
+                .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 12345, 54321));
 
         assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStats));
         assertTrue(orderInsensitiveEquals(expectedUidStats, uidStats));
@@ -462,13 +462,12 @@
                 NetworkStats.class);
 
         // Force pushing stats update to verify the stats reported.
-        provider.pushTetherStats();
-        verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(),
-                ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
+        mTetherStatsProvider.pushTetherStats();
+        verify(mTetherStatsProviderCb, times(1))
+                .notifyStatsUpdated(anyInt(), ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
         assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStatsCaptor.getValue()));
         assertTrue(orderInsensitiveEquals(expectedUidStats, uidStatsCaptor.getValue()));
 
-
         when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn(
                 new ForwardedStats(100000, 100000));
         offload.setUpstreamLinkProperties(null);
@@ -483,31 +482,31 @@
         inOrder.verifyNoMoreInteractions();
 
         // Verify that the stored stats is accumulated.
-        final NetworkStats ifaceStatsAccu = provider.getTetherStats(STATS_PER_IFACE);
-        final NetworkStats uidStatsAccu = provider.getTetherStats(STATS_PER_UID);
+        final NetworkStats ifaceStatsAccu = mTetherStatsProvider.getTetherStats(STATS_PER_IFACE);
+        final NetworkStats uidStatsAccu = mTetherStatsProvider.getTetherStats(STATS_PER_UID);
         final NetworkStats expectedIfaceStatsAccu = new NetworkStats(0L, 2)
-                .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999))
-                .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 112345, 154321));
+                .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999))
+                .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 112345, 154321));
 
         final NetworkStats expectedUidStatsAccu = new NetworkStats(0L, 2)
-                .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
-                .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 112345, 154321));
+                .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 999, 99999))
+                .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 112345, 154321));
 
         assertTrue(orderInsensitiveEquals(expectedIfaceStatsAccu, ifaceStatsAccu));
         assertTrue(orderInsensitiveEquals(expectedUidStatsAccu, uidStatsAccu));
 
         // Verify that only diff of stats is reported.
         reset(mTetherStatsProviderCb);
-        provider.pushTetherStats();
+        mTetherStatsProvider.pushTetherStats();
         final NetworkStats expectedIfaceStatsDiff = new NetworkStats(0L, 2)
-                .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 0, 0))
-                .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 100000, 100000));
+                .addEntry(buildTestEntry(STATS_PER_IFACE, mobileIface, 0, 0))
+                .addEntry(buildTestEntry(STATS_PER_IFACE, ethernetIface, 100000, 100000));
 
         final NetworkStats expectedUidStatsDiff = new NetworkStats(0L, 2)
-                .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 0, 0))
-                .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 100000, 100000));
-        verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(),
-                ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
+                .addEntry(buildTestEntry(STATS_PER_UID, mobileIface, 0, 0))
+                .addEntry(buildTestEntry(STATS_PER_UID, ethernetIface, 100000, 100000));
+        verify(mTetherStatsProviderCb, times(1))
+                .notifyStatsUpdated(anyInt(), ifaceStatsCaptor.capture(), uidStatsCaptor.capture());
         assertTrue(orderInsensitiveEquals(expectedIfaceStatsDiff, ifaceStatsCaptor.getValue()));
         assertTrue(orderInsensitiveEquals(expectedUidStatsDiff, uidStatsCaptor.getValue()));
     }
@@ -529,19 +528,18 @@
         lp.setInterfaceName(ethernetIface);
         offload.setUpstreamLinkProperties(lp);
 
-        AbstractNetworkStatsProvider provider = mTetherStatsProviderCaptor.getValue();
         final InOrder inOrder = inOrder(mHardware);
         when(mHardware.setUpstreamParameters(any(), any(), any(), any())).thenReturn(true);
         when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(true);
 
         // Applying an interface quota to the current upstream immediately sends it to the hardware.
-        provider.setLimit(ethernetIface, ethernetLimit);
+        mTetherStatsProvider.onSetLimit(ethernetIface, ethernetLimit);
         waitForIdle();
         inOrder.verify(mHardware).setDataLimit(ethernetIface, ethernetLimit);
         inOrder.verifyNoMoreInteractions();
 
         // Applying an interface quota to another upstream does not take any immediate action.
-        provider.setLimit(mobileIface, mobileLimit);
+        mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit);
         waitForIdle();
         inOrder.verify(mHardware, never()).setDataLimit(anyString(), anyLong());
 
@@ -554,7 +552,7 @@
 
         // Setting a limit of ITetheringStatsProvider.QUOTA_UNLIMITED causes the limit to be set
         // to Long.MAX_VALUE.
-        provider.setLimit(mobileIface, ITetheringStatsProvider.QUOTA_UNLIMITED);
+        mTetherStatsProvider.onSetLimit(mobileIface, ITetheringStatsProvider.QUOTA_UNLIMITED);
         waitForIdle();
         inOrder.verify(mHardware).setDataLimit(mobileIface, Long.MAX_VALUE);
 
@@ -562,7 +560,7 @@
         when(mHardware.setUpstreamParameters(any(), any(), any(), any())).thenReturn(false);
         lp.setInterfaceName(ethernetIface);
         offload.setUpstreamLinkProperties(lp);
-        provider.setLimit(mobileIface, mobileLimit);
+        mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit);
         waitForIdle();
         inOrder.verify(mHardware, never()).setDataLimit(anyString(), anyLong());
 
@@ -571,7 +569,7 @@
         when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(false);
         lp.setInterfaceName(mobileIface);
         offload.setUpstreamLinkProperties(lp);
-        provider.setLimit(mobileIface, mobileLimit);
+        mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit);
         waitForIdle();
         inOrder.verify(mHardware).getForwardedStats(ethernetIface);
         inOrder.verify(mHardware).stopOffloadControl();
@@ -587,7 +585,7 @@
 
         OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
         callback.onStoppedLimitReached();
-        verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any());
+        verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
     }
 
     @Test
@@ -691,7 +689,7 @@
         verify(mHardware, times(1)).getForwardedStats(eq(RMNET0));
         verify(mHardware, times(1)).getForwardedStats(eq(WLAN0));
         // TODO: verify the exact stats reported.
-        verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any());
+        verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
         verifyNoMoreInteractions(mTetherStatsProviderCb);
         verifyNoMoreInteractions(mHardware);
     }
@@ -756,7 +754,7 @@
         // Verify forwarded stats behaviour.
         verify(mHardware, times(1)).getForwardedStats(eq(RMNET0));
         verify(mHardware, times(1)).getForwardedStats(eq(WLAN0));
-        verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any());
+        verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any());
         verifyNoMoreInteractions(mTetherStatsProviderCb);
 
         // TODO: verify local prefixes and downstreams are also pushed to the HAL.
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringNotificationUpdaterTest.kt b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringNotificationUpdaterTest.kt
new file mode 100644
index 0000000..b869491
--- /dev/null
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringNotificationUpdaterTest.kt
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity.tethering
+
+import android.app.Notification
+import android.app.NotificationManager
+import android.content.Context
+import android.content.res.Resources
+import android.net.ConnectivityManager.TETHERING_BLUETOOTH
+import android.net.ConnectivityManager.TETHERING_USB
+import android.net.ConnectivityManager.TETHERING_WIFI
+import android.os.UserHandle
+import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.util.test.BroadcastInterceptingContext
+import com.android.networkstack.tethering.R
+import com.android.server.connectivity.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+const val TEST_SUBID = 1
+const val WIFI_ICON_ID = 1
+const val USB_ICON_ID = 2
+const val BT_ICON_ID = 3
+const val GENERAL_ICON_ID = 4
+const val WIFI_MASK = 1 shl TETHERING_WIFI
+const val USB_MASK = 1 shl TETHERING_USB
+const val BT_MASK = 1 shl TETHERING_BLUETOOTH
+const val TITTLE = "Tethering active"
+const val MESSAGE = "Tap here to set up."
+const val TEST_TITTLE = "Hotspot active"
+const val TEST_MESSAGE = "Tap to set up hotspot."
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class TetheringNotificationUpdaterTest {
+    // lateinit used here for mocks as they need to be reinitialized between each test and the test
+    // should crash if they are used before being initialized.
+    @Mock private lateinit var mockContext: Context
+    @Mock private lateinit var notificationManager: NotificationManager
+    @Mock private lateinit var defaultResources: Resources
+    @Mock private lateinit var testResources: Resources
+
+    // lateinit for this class under test, as it should be reset to a different instance for every
+    // tests but should always be initialized before use (or the test should crash).
+    private lateinit var notificationUpdater: TetheringNotificationUpdater
+
+    private val ENABLE_ICON_CONFIGS = arrayOf(
+            "USB;android.test:drawable/usb", "BT;android.test:drawable/bluetooth",
+            "WIFI|BT;android.test:drawable/general", "WIFI|USB;android.test:drawable/general",
+            "USB|BT;android.test:drawable/general", "WIFI|USB|BT;android.test:drawable/general")
+
+    private inner class TestContext(c: Context) : BroadcastInterceptingContext(c) {
+        override fun createContextAsUser(user: UserHandle, flags: Int) =
+                if (user == UserHandle.ALL) mockContext else this
+    }
+
+    private inner class WrappedNotificationUpdater(c: Context) : TetheringNotificationUpdater(c) {
+        override fun getResourcesForSubId(context: Context, subId: Int) =
+                if (subId == TEST_SUBID) testResources else defaultResources
+    }
+
+    private fun setupResources() {
+        doReturn(ENABLE_ICON_CONFIGS).`when`(defaultResources)
+                .getStringArray(R.array.tethering_notification_icons)
+        doReturn(arrayOf("WIFI;android.test:drawable/wifi")).`when`(testResources)
+                .getStringArray(R.array.tethering_notification_icons)
+        doReturn(TITTLE).`when`(defaultResources).getString(R.string.tethering_notification_title)
+        doReturn(MESSAGE).`when`(defaultResources)
+                .getString(R.string.tethering_notification_message)
+        doReturn(TEST_TITTLE).`when`(testResources).getString(R.string.tethering_notification_title)
+        doReturn(TEST_MESSAGE).`when`(testResources)
+                .getString(R.string.tethering_notification_message)
+        doReturn(USB_ICON_ID).`when`(defaultResources)
+                .getIdentifier(eq("android.test:drawable/usb"), any(), any())
+        doReturn(BT_ICON_ID).`when`(defaultResources)
+                .getIdentifier(eq("android.test:drawable/bluetooth"), any(), any())
+        doReturn(GENERAL_ICON_ID).`when`(defaultResources)
+                .getIdentifier(eq("android.test:drawable/general"), any(), any())
+        doReturn(WIFI_ICON_ID).`when`(testResources)
+                .getIdentifier(eq("android.test:drawable/wifi"), any(), any())
+    }
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        val context = TestContext(InstrumentationRegistry.getInstrumentation().context)
+        doReturn(notificationManager).`when`(mockContext)
+                .getSystemService(Context.NOTIFICATION_SERVICE)
+        notificationUpdater = WrappedNotificationUpdater(context)
+        setupResources()
+    }
+
+    private fun Notification.title() = this.extras.getString(Notification.EXTRA_TITLE)
+    private fun Notification.text() = this.extras.getString(Notification.EXTRA_TEXT)
+
+    private fun verifyNotification(iconId: Int = 0, title: String = "", text: String = "") {
+        verify(notificationManager, never()).cancel(any(), anyInt())
+
+        val notificationCaptor = ArgumentCaptor.forClass(Notification::class.java)
+        verify(notificationManager, times(1))
+                .notify(any(), anyInt(), notificationCaptor.capture())
+
+        val notification = notificationCaptor.getValue()
+        assertEquals(iconId, notification.smallIcon.resId)
+        assertEquals(title, notification.title())
+        assertEquals(text, notification.text())
+
+        reset(notificationManager)
+    }
+
+    private fun verifyNoNotification() {
+        verify(notificationManager, times(1)).cancel(any(), anyInt())
+        verify(notificationManager, never()).notify(any(), anyInt(), any())
+
+        reset(notificationManager)
+    }
+
+    @Test
+    fun testNotificationWithDownstreamChanged() {
+        // Wifi downstream. No notification.
+        notificationUpdater.onDownstreamChanged(WIFI_MASK)
+        verifyNoNotification()
+
+        // Same downstream changed. Nothing happened.
+        notificationUpdater.onDownstreamChanged(WIFI_MASK)
+        verifyZeroInteractions(notificationManager)
+
+        // Wifi and usb downstreams. Show enable notification
+        notificationUpdater.onDownstreamChanged(WIFI_MASK or USB_MASK)
+        verifyNotification(GENERAL_ICON_ID, TITTLE, MESSAGE)
+
+        // Usb downstream. Still show enable notification.
+        notificationUpdater.onDownstreamChanged(USB_MASK)
+        verifyNotification(USB_ICON_ID, TITTLE, MESSAGE)
+
+        // No downstream. No notification.
+        notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE)
+        verifyNoNotification()
+    }
+
+    @Test
+    fun testNotificationWithActiveDataSubscriptionIdChanged() {
+        // Usb downstream. Showed enable notification with default resource.
+        notificationUpdater.onDownstreamChanged(USB_MASK)
+        verifyNotification(USB_ICON_ID, TITTLE, MESSAGE)
+
+        // Same subId changed. Nothing happened.
+        notificationUpdater.onActiveDataSubscriptionIdChanged(INVALID_SUBSCRIPTION_ID)
+        verifyZeroInteractions(notificationManager)
+
+        // Set test sub id. Clear notification with test resource.
+        notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID)
+        verifyNoNotification()
+
+        // Wifi downstream. Show enable notification with test resource.
+        notificationUpdater.onDownstreamChanged(WIFI_MASK)
+        verifyNotification(WIFI_ICON_ID, TEST_TITTLE, TEST_MESSAGE)
+
+        // No downstream. No notification.
+        notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE)
+        verifyNoNotification()
+    }
+
+    private fun assertIconNumbers(number: Int, configs: Array<String?>) {
+        doReturn(configs).`when`(defaultResources)
+                .getStringArray(R.array.tethering_notification_icons)
+        assertEquals(number, notificationUpdater.getIcons(
+                R.array.tethering_notification_icons, defaultResources).size())
+    }
+
+    @Test
+    fun testGetIcons() {
+        assertIconNumbers(0, arrayOfNulls<String>(0))
+        assertIconNumbers(0, arrayOf(null, ""))
+        assertIconNumbers(3, arrayOf(
+                // These configurations are invalid with wrong strings or symbols.
+                ";", ",", "|", "|,;", "WIFI", "1;2", " U SB; ", "bt;", "WIFI;USB;BT", "WIFI|USB|BT",
+                "WIFI,BT,USB", " WIFI| |  | USB, test:drawable/test",
+                // This configuration is valid with two downstream types (USB, BT).
+                "USB|,,,,,|BT;drawable/test ",
+                // This configuration is valid with one downstream types (WIFI).
+                "     WIFI     ; android.test:drawable/xxx "))
+    }
+
+    @Test
+    fun testGetDownstreamTypesMask() {
+        assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask(""))
+        assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask("1"))
+        assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask("WIFI_P2P"))
+        assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask("usb"))
+        assertEquals(WIFI_MASK, notificationUpdater.getDownstreamTypesMask(" WIFI "))
+        assertEquals(USB_MASK, notificationUpdater.getDownstreamTypesMask("USB | B T"))
+        assertEquals(BT_MASK, notificationUpdater.getDownstreamTypesMask(" WIFI: | BT"))
+        assertEquals(WIFI_MASK or USB_MASK,
+                notificationUpdater.getDownstreamTypesMask("1|2|USB|WIFI|BLUETOOTH||"))
+    }
+
+    @Test
+    fun testSetupRestrictedNotification() {
+        val title = InstrumentationRegistry.getInstrumentation().context.resources
+                .getString(R.string.disable_tether_notification_title)
+        val message = InstrumentationRegistry.getInstrumentation().context.resources
+                .getString(R.string.disable_tether_notification_message)
+        val disallowTitle = "Tether function is disallowed"
+        val disallowMessage = "Please contact your admin"
+        doReturn(title).`when`(defaultResources)
+                .getString(R.string.disable_tether_notification_title)
+        doReturn(message).`when`(defaultResources)
+                .getString(R.string.disable_tether_notification_message)
+        doReturn(disallowTitle).`when`(testResources)
+                .getString(R.string.disable_tether_notification_title)
+        doReturn(disallowMessage).`when`(testResources)
+                .getString(R.string.disable_tether_notification_message)
+
+        // User restrictions on. Show restricted notification.
+        notificationUpdater.notifyTetheringDisabledByRestriction()
+        verifyNotification(R.drawable.stat_sys_tether_general, title, message)
+
+        // User restrictions off. Clear notification.
+        notificationUpdater.tetheringRestrictionLifted()
+        verifyNoNotification()
+
+        // Set test sub id. No notification.
+        notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID)
+        verifyNoNotification()
+
+        // User restrictions on again. Show restricted notification with test resource.
+        notificationUpdater.notifyTetheringDisabledByRestriction()
+        verifyNotification(R.drawable.stat_sys_tether_general, disallowTitle, disallowMessage)
+    }
+}
\ No newline at end of file
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
index 2f7c88a..a418c4a 100644
--- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
@@ -38,6 +38,7 @@
 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
 import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
+import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
@@ -82,6 +83,7 @@
 import android.net.ConnectivityManager;
 import android.net.EthernetManager;
 import android.net.EthernetManager.TetheredInterfaceRequest;
+import android.net.IIntResultListener;
 import android.net.INetd;
 import android.net.ITetheringEventCallback;
 import android.net.InetAddresses;
@@ -209,7 +211,6 @@
     private PhoneStateListener mPhoneStateListener;
     private InterfaceConfigurationParcel mInterfaceConfiguration;
 
-
     private class TestContext extends BroadcastInterceptingContext {
         TestContext(Context base) {
             super(base);
@@ -484,6 +485,7 @@
         mServiceContext.registerReceiver(mBroadcastReceiver,
                 new IntentFilter(ACTION_TETHER_STATE_CHANGED));
         mTethering = makeTethering();
+        mTethering.startStateMachineUpdaters();
         verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any());
         verify(mNetd).registerUnsolicitedEventListener(any());
         final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
@@ -499,10 +501,16 @@
         return new Tethering(mTetheringDependencies);
     }
 
-    private TetheringRequestParcel createTetheringRquestParcel(final int type) {
+    private TetheringRequestParcel createTetheringRequestParcel(final int type) {
+        return createTetheringRequestParcel(type, null, null);
+    }
+
+    private TetheringRequestParcel createTetheringRequestParcel(final int type,
+            final LinkAddress serverAddr, final LinkAddress clientAddr) {
         final TetheringRequestParcel request = new TetheringRequestParcel();
         request.tetheringType = type;
-        request.localIPv4Address = null;
+        request.localIPv4Address = serverAddr;
+        request.staticClientAddress = clientAddr;
         request.exemptFromEntitlementCheck = false;
         request.showProvisioningUi = false;
 
@@ -616,7 +624,7 @@
 
     private void prepareNcmTethering() {
         // Emulate startTethering(TETHERING_NCM) called
-        mTethering.startTethering(createTetheringRquestParcel(TETHERING_NCM), null);
+        mTethering.startTethering(createTetheringRequestParcel(TETHERING_NCM), null);
         mLooper.dispatchAll();
         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM);
 
@@ -629,7 +637,7 @@
                 .thenReturn(upstreamState);
 
         // Emulate pressing the USB tethering button in Settings UI.
-        mTethering.startTethering(createTetheringRquestParcel(TETHERING_USB), null);
+        mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), null);
         mLooper.dispatchAll();
         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
 
@@ -903,7 +911,7 @@
         when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
 
         // Emulate pressing the WiFi tethering button.
-        mTethering.startTethering(createTetheringRquestParcel(TETHERING_WIFI), null);
+        mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
         mLooper.dispatchAll();
         verify(mWifiManager, times(1)).startSoftAp(null);
         verifyNoMoreInteractions(mWifiManager);
@@ -931,7 +939,7 @@
         when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
 
         // Emulate pressing the WiFi tethering button.
-        mTethering.startTethering(createTetheringRquestParcel(TETHERING_WIFI), null);
+        mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
         mLooper.dispatchAll();
         verify(mWifiManager, times(1)).startSoftAp(null);
         verifyNoMoreInteractions(mWifiManager);
@@ -1008,7 +1016,7 @@
         doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME);
 
         // Emulate pressing the WiFi tethering button.
-        mTethering.startTethering(createTetheringRquestParcel(TETHERING_WIFI), null);
+        mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
         mLooper.dispatchAll();
         verify(mWifiManager, times(1)).startSoftAp(null);
         verifyNoMoreInteractions(mWifiManager);
@@ -1066,13 +1074,15 @@
         when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions);
 
         final Tethering.UserRestrictionActionListener ural =
-                new Tethering.UserRestrictionActionListener(mUserManager, mockTethering);
+                new Tethering.UserRestrictionActionListener(
+                        mUserManager, mockTethering, mNotificationUpdater);
         ural.mDisallowTethering = currentDisallow;
 
         ural.onUserRestrictionsChanged();
 
-        verify(mockTethering, times(expectedInteractionsWithShowNotification))
-                .untetherAll();
+        verify(mNotificationUpdater, times(expectedInteractionsWithShowNotification))
+                .notifyTetheringDisabledByRestriction();
+        verify(mockTethering, times(expectedInteractionsWithShowNotification)).untetherAll();
     }
 
     @Test
@@ -1080,7 +1090,7 @@
         final String[] emptyActiveIfacesList = new String[]{};
         final boolean currDisallow = false;
         final boolean nextDisallow = true;
-        final int expectedInteractionsWithShowNotification = 0;
+        final int expectedInteractionsWithShowNotification = 1;
 
         runUserRestrictionsChange(currDisallow, nextDisallow, emptyActiveIfacesList,
                 expectedInteractionsWithShowNotification);
@@ -1303,7 +1313,7 @@
         tetherState = callback.pollTetherStatesChanged();
         assertArrayEquals(tetherState.availableList, new String[] {TEST_WLAN_IFNAME});
 
-        mTethering.startTethering(createTetheringRquestParcel(TETHERING_WIFI), null);
+        mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
         mLooper.dispatchAll();
         tetherState = callback.pollTetherStatesChanged();
@@ -1392,16 +1402,17 @@
         mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
         final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration();
         assertEquals(fakeSubId, newConfig.activeDataSubId);
+        verify(mNotificationUpdater, times(1)).onActiveDataSubscriptionIdChanged(eq(fakeSubId));
     }
 
     @Test
     public void testNoDuplicatedEthernetRequest() throws Exception {
         final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class);
         when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
-        mTethering.startTethering(createTetheringRquestParcel(TETHERING_ETHERNET), null);
+        mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
         mLooper.dispatchAll();
         verify(mEm, times(1)).requestTetheredInterface(any(), any());
-        mTethering.startTethering(createTetheringRquestParcel(TETHERING_ETHERNET), null);
+        mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
         mLooper.dispatchAll();
         verifyNoMoreInteractions(mEm);
         mTethering.stopTethering(TETHERING_ETHERNET);
@@ -1580,6 +1591,93 @@
         assertTrue(element + " not found in " + collection, collection.contains(element));
     }
 
+    private class ResultListener extends IIntResultListener.Stub {
+        private final int mExpectedResult;
+        private boolean mHasResult = false;
+        ResultListener(final int expectedResult) {
+            mExpectedResult = expectedResult;
+        }
+
+        @Override
+        public void onResult(final int resultCode) {
+            mHasResult = true;
+            if (resultCode != mExpectedResult) {
+                fail("expected result: " + mExpectedResult + " but actual result: " + resultCode);
+            }
+        }
+
+        public void assertHasResult() {
+            if (!mHasResult) fail("No callback result");
+        }
+    }
+
+    @Test
+    public void testMultipleStartTethering() throws Exception {
+        final LinkAddress serverLinkAddr = new LinkAddress("192.168.20.1/24");
+        final LinkAddress clientLinkAddr = new LinkAddress("192.168.20.42/24");
+        final String serverAddr = "192.168.20.1";
+        final ResultListener firstResult = new ResultListener(TETHER_ERROR_NO_ERROR);
+        final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR);
+        final ResultListener thirdResult = new ResultListener(TETHER_ERROR_NO_ERROR);
+
+        // Enable USB tethering and check that Tethering starts USB.
+        mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
+                  null, null), firstResult);
+        mLooper.dispatchAll();
+        firstResult.assertHasResult();
+        verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
+        verifyNoMoreInteractions(mUsbManager);
+
+        // Enable USB tethering again with the same request and expect no change to USB.
+        mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
+                  null, null), secondResult);
+        mLooper.dispatchAll();
+        secondResult.assertHasResult();
+        verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE);
+        reset(mUsbManager);
+
+        // Enable USB tethering with a different request and expect that USB is stopped and
+        // started.
+        mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
+                  serverLinkAddr, clientLinkAddr), thirdResult);
+        mLooper.dispatchAll();
+        thirdResult.assertHasResult();
+        verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
+        verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
+
+        // Expect that when USB comes up, the DHCP server is configured with the requested address.
+        mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
+        sendUsbBroadcast(true, true, true, TETHERING_USB);
+        mLooper.dispatchAll();
+        verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
+                any(), any());
+        verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
+    }
+
+    @Test
+    public void testRequestStaticIp() throws Exception {
+        final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24");
+        final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24");
+        final String serverAddr = "192.168.0.123";
+        final int clientAddrParceled = 0xc0a8002a;
+        final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor =
+                ArgumentCaptor.forClass(DhcpServingParamsParcel.class);
+        mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
+                  serverLinkAddr, clientLinkAddr), null);
+        mLooper.dispatchAll();
+        verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
+        mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true);
+        sendUsbBroadcast(true, true, true, TETHERING_USB);
+        mLooper.dispatchAll();
+        verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
+        verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(),
+                any());
+        final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue();
+        assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress());
+        assertEquals(24, params.serverAddrPrefixLength);
+        assertEquals(clientAddrParceled, params.clientAddr);
+    }
+
     // TODO: Test that a request for hotspot mode doesn't interfere with an
     // already operating tethering mode interface.
 }
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
index 5ed75bf..7c98f62 100644
--- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
@@ -212,8 +212,8 @@
         mUNM.updateMobileRequiresDun(true);
         mUNM.registerMobileNetworkRequest();
         verify(mCM, times(1)).requestNetwork(
-                any(NetworkRequest.class), any(NetworkCallback.class), anyInt(), anyInt(),
-                any(Handler.class));
+                any(NetworkRequest.class), anyInt(), anyInt(), any(Handler.class),
+                any(NetworkCallback.class));
 
         assertTrue(mUNM.mobileNetworkRequested());
         assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
@@ -649,8 +649,8 @@
         }
 
         @Override
-        public void requestNetwork(NetworkRequest req, NetworkCallback cb,
-                int timeoutMs, int legacyType, Handler h) {
+        public void requestNetwork(NetworkRequest req,
+                int timeoutMs, int legacyType, Handler h, NetworkCallback cb) {
             assertFalse(allCallbacks.containsKey(cb));
             allCallbacks.put(cb, h);
             assertFalse(requested.containsKey(cb));
diff --git a/services/Android.bp b/services/Android.bp
index 5019bb1..90f98e2 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -72,11 +72,7 @@
 
     libs: [
         "android.hidl.manager-V1.0-java",
-        "framework-tethering-stubs",
-    ],
-
-    plugins: [
-        "compat-changeid-annotation-processor",
+        "framework-tethering-stubs-module_libs_api",
     ],
 
     // Uncomment to enable output of certain warnings (deprecated, unchecked)
@@ -94,8 +90,8 @@
 }
 
 platform_compat_config {
-    name: "services-platform-compat-config",
-    src: ":services",
+   name: "services-platform-compat-config",
+   src: ":services",
 }
 
 filegroup {
@@ -110,6 +106,7 @@
     name: "services-stubs.sources",
     srcs: [":services-sources"],
     installable: false,
+    api_tag_name: "SYSTEM_SERVER",
     args: " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.SYSTEM_SERVER\\)" +
         " --hide-annotation android.annotation.Hide" +
         " --hide InternalClasses" + // com.android.* classes are okay in this interface
@@ -138,7 +135,8 @@
 }
 
 java_library {
-    name: "services-stubs",
+    name: "android_system_server_stubs_current",
     srcs: [":services-stubs.sources"],
     installable: false,
+    static_libs: ["android_module_lib_stubs_current"],
 }
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 123c5d5..7a3a910 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -28,9 +28,9 @@
         "android.hardware.power-V1.0-java",
         "android.hardware.tv.cec-V1.0-java",
         "android.hardware.vibrator-java",
+        "android.net.ipsec.ike.stubs.module_libs_api",
         "app-compat-annotations",
-        "framework-tethering-stubs",
-        "ike-stubs",
+        "framework-tethering-stubs-module_libs_api",
     ],
 
     required: [
@@ -56,10 +56,6 @@
         "dnsresolver_aidl_interface-V2-java",
         "netd_event_listener_interface-java",
     ],
-
-    plugins: [
-        "compat-changeid-annotation-processor",
-    ],
 }
 
 java_genrule {
diff --git a/services/core/java/com/android/server/AppStateTracker.java b/services/core/java/com/android/server/AppStateTracker.java
index 207e007..ecbf9a4 100644
--- a/services/core/java/com/android/server/AppStateTracker.java
+++ b/services/core/java/com/android/server/AppStateTracker.java
@@ -54,7 +54,6 @@
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.IndentingPrintWriter;
-import com.android.internal.util.Preconditions;
 import com.android.internal.util.StatLogger;
 import com.android.server.ForceAppStandbyTrackerProto.ExemptedPackage;
 import com.android.server.ForceAppStandbyTrackerProto.RunAnyInBackgroundRestrictedPackages;
@@ -62,6 +61,7 @@
 import java.io.PrintWriter;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Class to keep track of the information related to "force app standby", which includes:
@@ -416,12 +416,12 @@
             }
             mStarted = true;
 
-            mIActivityManager = Preconditions.checkNotNull(injectIActivityManager());
-            mActivityManagerInternal = Preconditions.checkNotNull(injectActivityManagerInternal());
-            mAppOpsManager = Preconditions.checkNotNull(injectAppOpsManager());
-            mAppOpsService = Preconditions.checkNotNull(injectIAppOpsService());
-            mPowerManagerInternal = Preconditions.checkNotNull(injectPowerManagerInternal());
-            mUsageStatsManagerInternal = Preconditions.checkNotNull(
+            mIActivityManager = Objects.requireNonNull(injectIActivityManager());
+            mActivityManagerInternal = Objects.requireNonNull(injectActivityManagerInternal());
+            mAppOpsManager = Objects.requireNonNull(injectAppOpsManager());
+            mAppOpsService = Objects.requireNonNull(injectIAppOpsService());
+            mPowerManagerInternal = Objects.requireNonNull(injectPowerManagerInternal());
+            mUsageStatsManagerInternal = Objects.requireNonNull(
                     injectUsageStatsManagerInternal());
 
             mFlagsObserver = new FeatureFlagsObserver();
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index fa8eda5..168c8cd 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -106,9 +106,13 @@
     private static final int USER_SWITCHED_TIME_MS = 200;
     // Delay for the addProxy function in msec
     private static final int ADD_PROXY_DELAY_MS = 100;
+    // Delay for retrying enable and disable in msec
+    private static final int ENABLE_DISABLE_DELAY_MS = 300;
 
     private static final int MESSAGE_ENABLE = 1;
     private static final int MESSAGE_DISABLE = 2;
+    private static final int MESSAGE_HANDLE_ENABLE_DELAYED = 3;
+    private static final int MESSAGE_HANDLE_DISABLE_DELAYED = 4;
     private static final int MESSAGE_REGISTER_ADAPTER = 20;
     private static final int MESSAGE_UNREGISTER_ADAPTER = 21;
     private static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30;
@@ -130,6 +134,7 @@
     private static final int RESTORE_SETTING_TO_OFF = 0;
 
     private static final int MAX_ERROR_RESTART_RETRIES = 6;
+    private static final int MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES = 10;
 
     // Bluetooth persisted setting is off
     private static final int BLUETOOTH_OFF = 0;
@@ -160,6 +165,8 @@
     private final ReentrantReadWriteLock mBluetoothLock = new ReentrantReadWriteLock();
     private boolean mBinding;
     private boolean mUnbinding;
+    private int mWaitForEnableRetry;
+    private int mWaitForDisableRetry;
 
     private BluetoothAirplaneModeListener mBluetoothAirplaneModeListener;
 
@@ -740,13 +747,7 @@
         }
     }
 
-    public int updateBleAppCount(IBinder token, boolean enable, String packageName) {
-        // Check if packageName belongs to callingUid
-        final int callingUid = Binder.getCallingUid();
-        final boolean isCallerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
-        if (!isCallerSystem) {
-            checkPackage(callingUid, packageName);
-        }
+    private int updateBleAppCount(IBinder token, boolean enable, String packageName) {
         ClientDeathRecipient r = mBleApps.get(token);
         if (r == null && enable) {
             ClientDeathRecipient deathRec = new ClientDeathRecipient(packageName);
@@ -771,15 +772,96 @@
         if (DBG) {
             Slog.d(TAG, appCount + " registered Ble Apps");
         }
-        if (appCount == 0 && mEnable) {
-            disableBleScanMode();
-        }
-        if (appCount == 0 && !mEnableExternal) {
-            sendBrEdrDownCallback();
-        }
         return appCount;
     }
 
+    private boolean checkBluetoothPermissions(String packageName, boolean requireForeground) {
+        if (isBluetoothDisallowed()) {
+            if (DBG) {
+                Slog.d(TAG, "checkBluetoothPermissions: bluetooth disallowed");
+            }
+            return false;
+        }
+        // Check if packageName belongs to callingUid
+        final int callingUid = Binder.getCallingUid();
+        final boolean isCallerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
+        if (!isCallerSystem) {
+            checkPackage(callingUid, packageName);
+
+            if (requireForeground && !checkIfCallerIsForegroundUser()) {
+                Slog.w(TAG, "Not allowed for non-active and non system user");
+                return false;
+            }
+
+            mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
+                    "Need BLUETOOTH ADMIN permission");
+        }
+        return true;
+    }
+
+    public boolean enableBle(String packageName, IBinder token) throws RemoteException {
+        if (!checkBluetoothPermissions(packageName, false)) {
+            if (DBG) {
+                Slog.d(TAG, "enableBle(): bluetooth disallowed");
+            }
+            return false;
+        }
+
+        if (DBG) {
+            Slog.d(TAG, "enableBle(" + packageName + "):  mBluetooth =" + mBluetooth
+                    + " mBinding = " + mBinding + " mState = "
+                    + BluetoothAdapter.nameForState(mState));
+        }
+        updateBleAppCount(token, true, packageName);
+
+        if (mState == BluetoothAdapter.STATE_ON
+                || mState == BluetoothAdapter.STATE_BLE_ON
+                || mState == BluetoothAdapter.STATE_TURNING_ON
+                || mState == BluetoothAdapter.STATE_TURNING_OFF) {
+            Log.d(TAG, "enableBLE(): Bluetooth already enabled");
+            return true;
+        }
+        synchronized (mReceiver) {
+            // waive WRITE_SECURE_SETTINGS permission check
+            sendEnableMsg(false,
+                    BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
+        }
+        return true;
+    }
+
+    public boolean disableBle(String packageName, IBinder token) throws RemoteException {
+        if (!checkBluetoothPermissions(packageName, false)) {
+            if (DBG) {
+                Slog.d(TAG, "disableBLE(): bluetooth disallowed");
+            }
+            return false;
+        }
+
+        if (DBG) {
+            Slog.d(TAG, "disableBle(" + packageName + "):  mBluetooth =" + mBluetooth
+                    + " mBinding = " + mBinding + " mState = "
+                    + BluetoothAdapter.nameForState(mState));
+        }
+
+        if (mState == BluetoothAdapter.STATE_OFF) {
+            Slog.d(TAG, "disableBLE(): Already disabled");
+            return false;
+        }
+        updateBleAppCount(token, false, packageName);
+
+        if (mState == BluetoothAdapter.STATE_BLE_ON && !isBleAppPresent()) {
+            if (mEnable) {
+                disableBleScanMode();
+            }
+            if (!mEnableExternal) {
+                addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
+                        packageName, false);
+                sendBrEdrDownCallback();
+            }
+        }
+        return true;
+    }
+
     // Clear all apps using BLE scan only mode.
     private void clearBleApps() {
         mBleApps.clear();
@@ -806,6 +888,13 @@
                 Slog.e(TAG, "onBluetoothServiceUp: mBluetooth is null!");
                 return;
             }
+            if (!mEnableExternal && !isBleAppPresent() && isAirplaneModeOn()) {
+                // Airplane mode is turned on while enabling BLE only mode, disable
+                // BLE now.
+                disableBleScanMode();
+                sendBrEdrDownCallback();
+                return;
+            }
             if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
                 // This triggers transition to STATE_ON
                 mBluetooth.onLeServiceUp();
@@ -855,29 +944,19 @@
     }
 
     public boolean enableNoAutoConnect(String packageName) {
-        if (isBluetoothDisallowed()) {
+        if (!checkBluetoothPermissions(packageName, false)) {
             if (DBG) {
                 Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
             }
             return false;
         }
 
-        // Check if packageName belongs to callingUid
-        final int callingUid = Binder.getCallingUid();
-        final boolean isCallerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
-        if (!isCallerSystem) {
-            checkPackage(callingUid, packageName);
-        }
-
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                "Need BLUETOOTH ADMIN permission");
-
         if (DBG) {
             Slog.d(TAG, "enableNoAutoConnect():  mBluetooth =" + mBluetooth + " mBinding = "
                     + mBinding);
         }
-        int callingAppId = UserHandle.getAppId(callingUid);
 
+        int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
         if (callingAppId != Process.NFC_UID) {
             throw new SecurityException("no permission to enable Bluetooth quietly");
         }
@@ -892,32 +971,19 @@
     }
 
     public boolean enable(String packageName) throws RemoteException {
-        final int callingUid = Binder.getCallingUid();
-        final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
-
-        if (isBluetoothDisallowed()) {
+        if (!checkBluetoothPermissions(packageName, true)) {
             if (DBG) {
                 Slog.d(TAG, "enable(): not enabling - bluetooth disallowed");
             }
             return false;
         }
 
-        if (!callerSystem) {
-            // Check if packageName belongs to callingUid
-            checkPackage(callingUid, packageName);
-
-            if (!checkIfCallerIsForegroundUser()) {
-                Slog.w(TAG, "enable(): not allowed for non-active and non system user");
-                return false;
-            }
-
-            mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                    "Need BLUETOOTH ADMIN permission");
-
-            if (!isEnabled() && mWirelessConsentRequired && startConsentUiIfNeeded(packageName,
-                    callingUid, BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
-                return false;
-            }
+        final int callingUid = Binder.getCallingUid();
+        final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
+        if (!callerSystem && !isEnabled() && mWirelessConsentRequired
+                && startConsentUiIfNeeded(packageName,
+                callingUid, BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
+            return false;
         }
 
         if (DBG) {
@@ -939,25 +1005,19 @@
     }
 
     public boolean disable(String packageName, boolean persist) throws RemoteException {
+        if (!checkBluetoothPermissions(packageName, true)) {
+            if (DBG) {
+                Slog.d(TAG, "disable(): not disabling - bluetooth disallowed");
+            }
+            return false;
+        }
+
         final int callingUid = Binder.getCallingUid();
         final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
-
-        if (!callerSystem) {
-            // Check if packageName belongs to callingUid
-            checkPackage(callingUid, packageName);
-
-            if (!checkIfCallerIsForegroundUser()) {
-                Slog.w(TAG, "disable(): not allowed for non-active and non system user");
-                return false;
-            }
-
-            mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                    "Need BLUETOOTH ADMIN permission");
-
-            if (isEnabled() && mWirelessConsentRequired && startConsentUiIfNeeded(packageName,
-                    callingUid, BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
-                return false;
-            }
+        if (!callerSystem && isEnabled() && mWirelessConsentRequired
+                && startConsentUiIfNeeded(packageName,
+                callingUid, BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
+            return false;
         }
 
         if (DBG) {
@@ -1597,8 +1657,18 @@
                     break;
 
                 case MESSAGE_ENABLE:
+                    int quietEnable = msg.arg1;
+                    if (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED)
+                            || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)) {
+                        // We are handling enable or disable right now, wait for it.
+                        mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_ENABLE,
+                                quietEnable, 0), ENABLE_DISABLE_DELAY_MS);
+                        break;
+                    }
+
                     if (DBG) {
-                        Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth);
+                        Slog.d(TAG, "MESSAGE_ENABLE(" + quietEnable + "): mBluetooth = "
+                                + mBluetooth);
                     }
                     mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
                     mEnable = true;
@@ -1621,7 +1691,7 @@
                         mBluetoothLock.readLock().unlock();
                     }
 
-                    mQuietEnable = (msg.arg1 == 1);
+                    mQuietEnable = (quietEnable == 1);
                     if (mBluetooth == null) {
                         handleEnable(mQuietEnable);
                     } else {
@@ -1630,7 +1700,8 @@
                         // the previous Bluetooth process has exited. The
                         // waiting period has three components:
                         // (a) Wait until the local state is STATE_OFF. This
-                        //     is accomplished by "waitForOnOff(false, true)".
+                        //     is accomplished by sending delay a message
+                        //     MESSAGE_HANDLE_ENABLE_DELAYED
                         // (b) Wait until the STATE_OFF state is updated to
                         //     all components.
                         // (c) Wait until the Bluetooth process exits, and
@@ -1640,29 +1711,109 @@
                         // message. The delay time is backed off if Bluetooth
                         // continuously failed to turn on itself.
                         //
-                        waitForOnOff(false, true);
-                        Message restartMsg =
-                                mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
-                        mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
+                        mWaitForEnableRetry = 0;
+                        Message enableDelayedMsg =
+                                mHandler.obtainMessage(MESSAGE_HANDLE_ENABLE_DELAYED);
+                        mHandler.sendMessageDelayed(enableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
                     }
                     break;
 
                 case MESSAGE_DISABLE:
+                    if (mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED) || mBinding
+                            || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED)) {
+                        // We are handling enable or disable right now, wait for it.
+                        mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_DISABLE),
+                                ENABLE_DISABLE_DELAY_MS);
+                        break;
+                    }
+
                     if (DBG) {
-                        Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth);
+                        Slog.d(TAG, "MESSAGE_DISABLE: mBluetooth = " + mBluetooth
+                                + ", mBinding = " + mBinding);
                     }
                     mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
+
                     if (mEnable && mBluetooth != null) {
-                        waitForOnOff(true, false);
-                        mEnable = false;
-                        handleDisable();
-                        waitForOnOff(false, false);
+                        mWaitForDisableRetry = 0;
+                        Message disableDelayedMsg =
+                                mHandler.obtainMessage(MESSAGE_HANDLE_DISABLE_DELAYED, 0, 0);
+                        mHandler.sendMessageDelayed(disableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
                     } else {
                         mEnable = false;
                         handleDisable();
                     }
                     break;
 
+                case MESSAGE_HANDLE_ENABLE_DELAYED: {
+                    // The Bluetooth is turning off, wait for STATE_OFF
+                    if (mState != BluetoothAdapter.STATE_OFF) {
+                        if (mWaitForEnableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
+                            mWaitForEnableRetry++;
+                            Message enableDelayedMsg =
+                                    mHandler.obtainMessage(MESSAGE_HANDLE_ENABLE_DELAYED);
+                            mHandler.sendMessageDelayed(enableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
+                            break;
+                        } else {
+                            Slog.e(TAG, "Wait for STATE_OFF timeout");
+                        }
+                    }
+                    // Either state is changed to STATE_OFF or reaches the maximum retry, we
+                    // should move forward to the next step.
+                    mWaitForEnableRetry = 0;
+                    Message restartMsg =
+                            mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
+                    mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
+                    Slog.d(TAG, "Handle enable is finished");
+                    break;
+                }
+
+                case MESSAGE_HANDLE_DISABLE_DELAYED: {
+                    boolean disabling = (msg.arg1 == 1);
+                    Slog.d(TAG, "MESSAGE_HANDLE_DISABLE_DELAYED: disabling:" + disabling);
+                    if (!disabling) {
+                        // The Bluetooth is turning on, wait for STATE_ON
+                        if (mState != BluetoothAdapter.STATE_ON) {
+                            if (mWaitForDisableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
+                                mWaitForDisableRetry++;
+                                Message disableDelayedMsg = mHandler.obtainMessage(
+                                        MESSAGE_HANDLE_DISABLE_DELAYED, 0, 0);
+                                mHandler.sendMessageDelayed(disableDelayedMsg,
+                                        ENABLE_DISABLE_DELAY_MS);
+                                break;
+                            } else {
+                                Slog.e(TAG, "Wait for STATE_ON timeout");
+                            }
+                        }
+                        // Either state is changed to STATE_ON or reaches the maximum retry, we
+                        // should move forward to the next step.
+                        mWaitForDisableRetry = 0;
+                        mEnable = false;
+                        handleDisable();
+                        // Wait for state exiting STATE_ON
+                        Message disableDelayedMsg =
+                                mHandler.obtainMessage(MESSAGE_HANDLE_DISABLE_DELAYED, 1, 0);
+                        mHandler.sendMessageDelayed(disableDelayedMsg, ENABLE_DISABLE_DELAY_MS);
+                    } else {
+                        // The Bluetooth is turning off, wait for exiting STATE_ON
+                        if (mState == BluetoothAdapter.STATE_ON) {
+                            if (mWaitForDisableRetry < MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES) {
+                                mWaitForDisableRetry++;
+                                Message disableDelayedMsg = mHandler.obtainMessage(
+                                        MESSAGE_HANDLE_DISABLE_DELAYED, 1, 0);
+                                mHandler.sendMessageDelayed(disableDelayedMsg,
+                                        ENABLE_DISABLE_DELAY_MS);
+                                break;
+                            } else {
+                                Slog.e(TAG, "Wait for exiting STATE_ON timeout");
+                            }
+                        }
+                        // Either state is exited from STATE_ON or reaches the maximum retry, we
+                        // should move forward to the next step.
+                        Slog.d(TAG, "Handle disable is finished");
+                    }
+                    break;
+                }
+
                 case MESSAGE_RESTORE_USER_SETTING:
                     if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) {
                         if (DBG) {
@@ -2031,6 +2182,7 @@
         try {
             mBluetoothLock.writeLock().lock();
             if ((mBluetooth == null) && (!mBinding)) {
+                Slog.d(TAG, "binding Bluetooth service");
                 //Start bind timeout and bind
                 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
                 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
@@ -2418,6 +2570,12 @@
                 writer.println("  " + app.getPackageName());
             }
 
+            writer.println("\nBluetoothManagerService:");
+            writer.println("  mEnable:" + mEnable);
+            writer.println("  mQuietEnable:" + mQuietEnable);
+            writer.println("  mEnableExternal:" + mEnableExternal);
+            writer.println("  mQuietEnableExternal:" + mQuietEnableExternal);
+
             writer.println("");
             writer.flush();
             if (args.length == 0) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index fae14fe..1484fe7 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -40,6 +40,7 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_TEST;
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 import static android.net.NetworkPolicyManager.RULE_NONE;
 import static android.net.NetworkPolicyManager.uidRulesToString;
@@ -48,10 +49,9 @@
 import static android.system.OsConstants.IPPROTO_TCP;
 import static android.system.OsConstants.IPPROTO_UDP;
 
-import static com.android.internal.util.Preconditions.checkNotNull;
-
 import static java.util.Map.Entry;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
@@ -63,6 +63,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.database.ContentObserver;
 import android.net.CaptivePortal;
@@ -112,6 +113,7 @@
 import android.net.PrivateDnsConfigParcel;
 import android.net.ProxyInfo;
 import android.net.RouteInfo;
+import android.net.RouteInfoParcel;
 import android.net.SocketKeepalive;
 import android.net.TetheringManager;
 import android.net.UidRange;
@@ -122,6 +124,7 @@
 import android.net.metrics.NetworkEvent;
 import android.net.netlink.InetDiagMessage;
 import android.net.shared.PrivateDnsConfig;
+import android.net.util.LinkPropertiesUtils.CompareOrUpdateResult;
 import android.net.util.LinkPropertiesUtils.CompareResult;
 import android.net.util.MultinetworkPolicyTracker;
 import android.net.util.NetdService;
@@ -275,9 +278,6 @@
     // connect anyway?" dialog after the user selects a network that doesn't validate.
     private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000;
 
-    // How long to dismiss network notification.
-    private static final int TIMEOUT_NOTIFICATION_DELAY_MS = 20 * 1000;
-
     // Default to 30s linger time-out. Modifiable only for testing.
     private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger";
     private static final int DEFAULT_LINGER_DELAY_MS = 30_000;
@@ -525,18 +525,13 @@
     private static final int EVENT_PROVISIONING_NOTIFICATION = 43;
 
     /**
-     * This event can handle dismissing notification by given network id.
-     */
-    private static final int EVENT_TIMEOUT_NOTIFICATION = 44;
-
-    /**
      * Used to specify whether a network should be used even if connectivity is partial.
      * arg1 = whether to accept the network if its connectivity is partial (1 for true or 0 for
      * false)
      * arg2 = whether to remember this choice in the future (1 for true or 0 for false)
      * obj  = network
      */
-    private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 45;
+    private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 44;
 
     /**
      * Event for NetworkMonitor to inform ConnectivityService that the probe status has changed.
@@ -545,7 +540,7 @@
      * arg1 = A bitmask to describe which probes are completed.
      * arg2 = A bitmask to describe which probes are successful.
      */
-    public static final int EVENT_PROBE_STATUS_CHANGED = 46;
+    public static final int EVENT_PROBE_STATUS_CHANGED = 45;
 
     /**
      * Event for NetworkMonitor to inform ConnectivityService that captive portal data has changed.
@@ -553,7 +548,7 @@
      * arg2 = netId
      * obj = captive portal data
      */
-    private static final int EVENT_CAPPORT_DATA_CHANGED = 47;
+    private static final int EVENT_CAPPORT_DATA_CHANGED = 46;
 
     /**
      * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
@@ -933,7 +928,7 @@
          * @see IpConnectivityMetrics.Logger
          */
         public IpConnectivityMetrics.Logger getMetricsLogger() {
-            return checkNotNull(LocalServices.getService(IpConnectivityMetrics.Logger.class),
+            return Objects.requireNonNull(LocalServices.getService(IpConnectivityMetrics.Logger.class),
                     "no IpConnectivityMetrics service");
         }
 
@@ -962,10 +957,10 @@
             IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd, Dependencies deps) {
         if (DBG) log("ConnectivityService starting up");
 
-        mDeps = checkNotNull(deps, "missing Dependencies");
+        mDeps = Objects.requireNonNull(deps, "missing Dependencies");
         mSystemProperties = mDeps.getSystemProperties();
         mNetIdManager = mDeps.makeNetIdManager();
-        mContext = checkNotNull(context, "missing Context");
+        mContext = Objects.requireNonNull(context, "missing Context");
 
         mMetricsLog = logger;
         mDefaultRequest = createDefaultInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST);
@@ -995,13 +990,13 @@
 
         mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
 
-        mNMS = checkNotNull(netManager, "missing INetworkManagementService");
-        mStatsService = checkNotNull(statsService, "missing INetworkStatsService");
-        mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
-        mPolicyManagerInternal = checkNotNull(
+        mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService");
+        mStatsService = Objects.requireNonNull(statsService, "missing INetworkStatsService");
+        mPolicyManager = Objects.requireNonNull(policyManager, "missing INetworkPolicyManager");
+        mPolicyManagerInternal = Objects.requireNonNull(
                 LocalServices.getService(NetworkPolicyManagerInternal.class),
                 "missing NetworkPolicyManagerInternal");
-        mDnsResolver = checkNotNull(dnsresolver, "missing IDnsResolver");
+        mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver");
         mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
 
         mNetd = netd;
@@ -1676,7 +1671,7 @@
         if (newNc.getNetworkSpecifier() != null) {
             newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact());
         }
-        newNc.setAdministratorUids(Collections.EMPTY_LIST);
+        newNc.setAdministratorUids(new int[0]);
 
         return newNc;
     }
@@ -1720,7 +1715,7 @@
         }
 
         if (checkSettingsPermission(callerPid, callerUid)) {
-            return lp.makeSensitiveFieldsParcelingCopy();
+            return new LinkProperties(lp, true /* parcelSensitiveFields */);
         }
 
         final LinkProperties newLp = new LinkProperties(lp);
@@ -1737,7 +1732,7 @@
             nc.setSingleUid(callerUid);
         }
         nc.setRequestorUidAndPackageName(callerUid, callerPackageName);
-        nc.setAdministratorUids(Collections.EMPTY_LIST);
+        nc.setAdministratorUids(new int[0]);
 
         // Clear owner UID; this can never come from an app.
         nc.setOwnerUid(INVALID_UID);
@@ -2238,14 +2233,9 @@
             if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
                 final NetworkInfo ni = intent.getParcelableExtra(
                         ConnectivityManager.EXTRA_NETWORK_INFO);
-                if (ni.getType() == ConnectivityManager.TYPE_MOBILE_SUPL) {
-                    intent.setAction(ConnectivityManager.CONNECTIVITY_ACTION_SUPL);
-                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-                } else {
-                    BroadcastOptions opts = BroadcastOptions.makeBasic();
-                    opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M);
-                    options = opts.toBundle();
-                }
+                final BroadcastOptions opts = BroadcastOptions.makeBasic();
+                opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M);
+                options = opts.toBundle();
                 final IBatteryStats bs = mDeps.getBatteryStatsService();
                 try {
                     bs.noteConnectivityChanged(intent.getIntExtra(
@@ -2706,10 +2696,18 @@
 
             switch (msg.what) {
                 case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
-                    final NetworkCapabilities networkCapabilities = (NetworkCapabilities) msg.obj;
+                    NetworkCapabilities networkCapabilities = (NetworkCapabilities) msg.obj;
                     if (networkCapabilities.hasConnectivityManagedCapability()) {
                         Slog.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
                     }
+                    if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
+                        // Make sure the original object is not mutated. NetworkAgent normally
+                        // makes a copy of the capabilities when sending the message through
+                        // the Messenger, but if this ever changes, not making a defensive copy
+                        // here will give attack vectors to clients using this code path.
+                        networkCapabilities = new NetworkCapabilities(networkCapabilities);
+                        networkCapabilities.restrictCapabilitesForTestNetwork();
+                    }
                     updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities);
                     break;
                 }
@@ -2870,13 +2868,6 @@
             final boolean valid = ((testResult & NETWORK_VALIDATION_RESULT_VALID) != 0);
             final boolean wasValidated = nai.lastValidated;
             final boolean wasDefault = isDefaultNetwork(nai);
-            // Only show a connected notification if the network is pending validation
-            // after the captive portal app was open, and it has now validated.
-            if (nai.captivePortalValidationPending && valid) {
-                // User is now logged in, network validated.
-                nai.captivePortalValidationPending = false;
-                showNetworkNotification(nai, NotificationType.LOGGED_IN);
-            }
 
             if (DBG) {
                 final String logMsg = !TextUtils.isEmpty(redirectUrl)
@@ -3757,12 +3748,6 @@
                 new CaptivePortal(new CaptivePortalImpl(network).asBinder()));
         appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
 
-        // This runs on a random binder thread, but getNetworkAgentInfoForNetwork is thread-safe,
-        // and captivePortalValidationPending is volatile.
-        final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
-        if (nai != null) {
-            nai.captivePortalValidationPending = true;
-        }
         Binder.withCleanCallingIdentity(() ->
                 mContext.startActivityAsUser(appIntent, UserHandle.CURRENT));
     }
@@ -3881,14 +3866,6 @@
         final String action;
         final boolean highPriority;
         switch (type) {
-            case LOGGED_IN:
-                action = Settings.ACTION_WIFI_SETTINGS;
-                mHandler.removeMessages(EVENT_TIMEOUT_NOTIFICATION);
-                mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NOTIFICATION,
-                        nai.network.netId, 0), TIMEOUT_NOTIFICATION_DELAY_MS);
-                // High priority because it is a direct result of the user logging in to a portal.
-                highPriority = true;
-                break;
             case NO_INTERNET:
                 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED;
                 // High priority because it is only displayed for explicitly selected networks.
@@ -3916,7 +3893,7 @@
         }
 
         Intent intent = new Intent(action);
-        if (type != NotificationType.LOGGED_IN && type != NotificationType.PRIVATE_DNS_BROKEN) {
+        if (type != NotificationType.PRIVATE_DNS_BROKEN) {
             intent.setData(Uri.fromParts("netId", Integer.toString(nai.network.netId), null));
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             intent.setClassName("com.android.settings",
@@ -4132,9 +4109,6 @@
                 case EVENT_DATA_SAVER_CHANGED:
                     handleRestrictBackgroundChanged(toBool(msg.arg1));
                     break;
-                case EVENT_TIMEOUT_NOTIFICATION:
-                    mNotifier.clearNotification(msg.arg1, NotificationType.LOGGED_IN);
-                    break;
             }
         }
     }
@@ -5358,7 +5332,7 @@
     // specific SSID/SignalStrength, or the calling app has permission to do so.
     private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
             int callerPid, int callerUid, String callerPackageName) {
-        if (null != nc.getSSID() && !checkSettingsPermission(callerPid, callerUid)) {
+        if (null != nc.getSsid() && !checkSettingsPermission(callerPid, callerUid)) {
             throw new SecurityException("Insufficient permissions to request a specific SSID");
         }
 
@@ -5423,10 +5397,26 @@
         }
     }
 
+    private boolean checkUnsupportedStartingFrom(int version, String callingPackageName) {
+        final PackageManager pm = mContext.getPackageManager();
+        final int userId = UserHandle.getCallingUserId();
+        try {
+            final int callingVersion = pm.getApplicationInfoAsUser(
+                    callingPackageName, 0 /* flags */, userId).targetSdkVersion;
+            if (callingVersion < version) return false;
+        } catch (PackageManager.NameNotFoundException e) { }
+        return true;
+    }
+
     @Override
     public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
             Messenger messenger, int timeoutMs, IBinder binder, int legacyType,
             @NonNull String callingPackageName) {
+        if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) {
+            if (checkUnsupportedStartingFrom(Build.VERSION_CODES.M, callingPackageName)) {
+                throw new SecurityException("Insufficient permissions to specify legacy type");
+            }
+        }
         final int callingUid = Binder.getCallingUid();
         final NetworkRequest.Type type = (networkCapabilities == null)
                 ? NetworkRequest.Type.TRACK_DEFAULT
@@ -5530,7 +5520,7 @@
     @Override
     public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
             PendingIntent operation, @NonNull String callingPackageName) {
-        checkNotNull(operation, "PendingIntent cannot be null.");
+        Objects.requireNonNull(operation, "PendingIntent cannot be null.");
         final int callingUid = Binder.getCallingUid();
         networkCapabilities = new NetworkCapabilities(networkCapabilities);
         enforceNetworkRequestPermissions(networkCapabilities);
@@ -5559,7 +5549,7 @@
 
     @Override
     public void releasePendingNetworkRequest(PendingIntent operation) {
-        checkNotNull(operation, "PendingIntent cannot be null.");
+        Objects.requireNonNull(operation, "PendingIntent cannot be null.");
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
                 getCallingUid(), 0, operation));
     }
@@ -5618,7 +5608,7 @@
     @Override
     public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
             PendingIntent operation, @NonNull String callingPackageName) {
-        checkNotNull(operation, "PendingIntent cannot be null.");
+        Objects.requireNonNull(operation, "PendingIntent cannot be null.");
         final int callingUid = Binder.getCallingUid();
         if (!hasWifiNetworkListenPermission(networkCapabilities)) {
             enforceAccessPermission();
@@ -5803,7 +5793,16 @@
     public Network registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
             int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) {
-        enforceNetworkFactoryPermission();
+        if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
+            enforceAnyPermissionOf(Manifest.permission.MANAGE_TEST_NETWORKS);
+            // Strictly, sanitizing here is unnecessary as the capabilities will be sanitized in
+            // the call to mixInCapabilities below anyway, but sanitizing here means the NAI never
+            // sees capabilities that may be malicious, which might prevent mistakes in the future.
+            networkCapabilities = new NetworkCapabilities(networkCapabilities);
+            networkCapabilities.restrictCapabilitesForTestNetwork();
+        } else {
+            enforceNetworkFactoryPermission();
+        }
 
         LinkProperties lp = new LinkProperties(linkProperties);
         lp.ensureDirectlyConnectedRoutes();
@@ -5818,7 +5817,7 @@
         nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
         final String extraInfo = networkInfo.getExtraInfo();
         final String name = TextUtils.isEmpty(extraInfo)
-                ? nai.networkCapabilities.getSSID() : extraInfo;
+                ? nai.networkCapabilities.getSsid() : extraInfo;
         if (DBG) log("registerNetworkAgent " + nai);
         final long token = Binder.clearCallingIdentity();
         try {
@@ -5976,15 +5975,49 @@
         }
     }
 
+    // TODO: move to frameworks/libs/net.
+    private RouteInfoParcel convertRouteInfo(RouteInfo route) {
+        final String nextHop;
+
+        switch (route.getType()) {
+            case RouteInfo.RTN_UNICAST:
+                if (route.hasGateway()) {
+                    nextHop = route.getGateway().getHostAddress();
+                } else {
+                    nextHop = INetd.NEXTHOP_NONE;
+                }
+                break;
+            case RouteInfo.RTN_UNREACHABLE:
+                nextHop = INetd.NEXTHOP_UNREACHABLE;
+                break;
+            case RouteInfo.RTN_THROW:
+                nextHop = INetd.NEXTHOP_THROW;
+                break;
+            default:
+                nextHop = INetd.NEXTHOP_NONE;
+                break;
+        }
+
+        final RouteInfoParcel rip = new RouteInfoParcel();
+        rip.ifName = route.getInterface();
+        rip.destination = route.getDestination().toString();
+        rip.nextHop = nextHop;
+        rip.mtu = route.getMtu();
+
+        return rip;
+    }
+
     /**
      * Have netd update routes from oldLp to newLp.
      * @return true if routes changed between oldLp and newLp
      */
     private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
-        // Compare the route diff to determine which routes should be added and removed.
-        CompareResult<RouteInfo> routeDiff = new CompareResult<>(
-                oldLp != null ? oldLp.getAllRoutes() : null,
-                newLp != null ? newLp.getAllRoutes() : null);
+        // compare the route diff to determine which routes have been updated
+        final CompareOrUpdateResult<RouteInfo.RouteKey, RouteInfo> routeDiff =
+                new CompareOrUpdateResult<>(
+                        oldLp != null ? oldLp.getAllRoutes() : null,
+                        newLp != null ? newLp.getAllRoutes() : null,
+                        (r) -> r.getRouteKey());
 
         // add routes before removing old in case it helps with continuous connectivity
 
@@ -5993,10 +6026,10 @@
             if (route.hasGateway()) continue;
             if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
             try {
-                mNMS.addRoute(netId, route);
+                mNetd.networkAddRouteParcel(netId, convertRouteInfo(route));
             } catch (Exception e) {
                 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) {
-                    loge("Exception in addRoute for non-gateway: " + e);
+                    loge("Exception in networkAddRouteParcel for non-gateway: " + e);
                 }
             }
         }
@@ -6004,10 +6037,10 @@
             if (!route.hasGateway()) continue;
             if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
             try {
-                mNMS.addRoute(netId, route);
+                mNetd.networkAddRouteParcel(netId, convertRouteInfo(route));
             } catch (Exception e) {
                 if ((route.getGateway() instanceof Inet4Address) || VDBG) {
-                    loge("Exception in addRoute for gateway: " + e);
+                    loge("Exception in networkAddRouteParcel for gateway: " + e);
                 }
             }
         }
@@ -6015,12 +6048,22 @@
         for (RouteInfo route : routeDiff.removed) {
             if (VDBG || DDBG) log("Removing Route [" + route + "] from network " + netId);
             try {
-                mNMS.removeRoute(netId, route);
+                mNetd.networkRemoveRouteParcel(netId, convertRouteInfo(route));
             } catch (Exception e) {
-                loge("Exception in removeRoute: " + e);
+                loge("Exception in networkRemoveRouteParcel: " + e);
             }
         }
-        return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty();
+
+        for (RouteInfo route : routeDiff.updated) {
+            if (VDBG || DDBG) log("Updating Route [" + route + "] from network " + netId);
+            try {
+                mNetd.networkUpdateRouteParcel(netId, convertRouteInfo(route));
+            } catch (Exception e) {
+                loge("Exception in networkUpdateRouteParcel: " + e);
+            }
+        }
+        return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty()
+                || !routeDiff.updated.isEmpty();
     }
 
     private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
@@ -7842,7 +7885,7 @@
                 getMatchingPermissionedCallbacks(nai);
         for (final IConnectivityDiagnosticsCallback cb : results) {
             try {
-                cb.onConnectivityReport(report);
+                cb.onConnectivityReportAvailable(report);
             } catch (RemoteException ex) {
                 loge("Error invoking onConnectivityReport", ex);
             }
@@ -7889,7 +7932,7 @@
 
     private void clearNetworkCapabilitiesUids(@NonNull NetworkCapabilities nc) {
         nc.setUids(null);
-        nc.setAdministratorUids(Collections.EMPTY_LIST);
+        nc.setAdministratorUids(new int[0]);
         nc.setOwnerUid(Process.INVALID_UID);
     }
 
@@ -7917,20 +7960,31 @@
             return true;
         }
 
-        if (!mLocationPermissionChecker.checkLocationPermission(
-                callbackPackageName, null /* featureId */, callbackUid, null /* message */)) {
+        // LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid
+        // and package name don't match. Throwing on the CS thread is not acceptable, so wrap the
+        // call in a try-catch.
+        try {
+            if (!mLocationPermissionChecker.checkLocationPermission(
+                    callbackPackageName, null /* featureId */, callbackUid, null /* message */)) {
+                return false;
+            }
+        } catch (SecurityException e) {
             return false;
         }
 
+        final Network[] underlyingNetworks;
         synchronized (mVpns) {
-            if (getVpnIfOwner(callbackUid) != null) {
-                return true;
-            }
+            final Vpn vpn = getVpnIfOwner(callbackUid);
+            underlyingNetworks = (vpn == null) ? null : vpn.getUnderlyingNetworks();
+        }
+        if (underlyingNetworks != null) {
+            if (Arrays.asList(underlyingNetworks).contains(nai.network)) return true;
         }
 
         // Administrator UIDs also contains the Owner UID
-        if (nai.networkCapabilities.getAdministratorUids().contains(callbackUid)) {
-            return true;
+        final int[] administratorUids = nai.networkCapabilities.getAdministratorUids();
+        for (final int uid : administratorUids) {
+            if (uid == callbackUid) return true;
         }
 
         return false;
diff --git a/services/core/java/com/android/server/ExplicitHealthCheckController.java b/services/core/java/com/android/server/ExplicitHealthCheckController.java
index f7c4aac..77059d9 100644
--- a/services/core/java/com/android/server/ExplicitHealthCheckController.java
+++ b/services/core/java/com/android/server/ExplicitHealthCheckController.java
@@ -47,6 +47,7 @@
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 import java.util.function.Consumer;
 
@@ -113,9 +114,9 @@
                 Slog.wtf(TAG, "Resetting health check controller callbacks");
             }
 
-            mPassedConsumer = Preconditions.checkNotNull(passedConsumer);
-            mSupportedConsumer = Preconditions.checkNotNull(supportedConsumer);
-            mNotifySyncRunnable = Preconditions.checkNotNull(notifySyncRunnable);
+            mPassedConsumer = Objects.requireNonNull(passedConsumer);
+            mSupportedConsumer = Objects.requireNonNull(supportedConsumer);
+            mNotifySyncRunnable = Objects.requireNonNull(notifySyncRunnable);
         }
     }
 
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 98ac4cb..905c489 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -25,8 +25,6 @@
 import static android.system.OsConstants.IPPROTO_UDP;
 import static android.system.OsConstants.SOCK_DGRAM;
 
-import static com.android.internal.util.Preconditions.checkNotNull;
-
 import android.annotation.NonNull;
 import android.app.AppOpsManager;
 import android.content.Context;
@@ -48,6 +46,7 @@
 import android.net.util.NetdService;
 import android.os.Binder;
 import android.os.IBinder;
+import android.os.INetworkManagementService;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
@@ -76,6 +75,7 @@
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * A service to manage multiple clients that want to access the IpSec API. The service is
@@ -115,6 +115,9 @@
     /* Binder context for this service */
     private final Context mContext;
 
+    /* NetworkManager instance */
+    private final INetworkManagementService mNetworkManager;
+
     /**
      * The next non-repeating global ID for tracking resources between users, this service, and
      * kernel data structures. Accessing this variable is not thread safe, so it is only read or
@@ -360,10 +363,14 @@
     @VisibleForTesting
     static final class UserRecord {
         /* Maximum number of each type of resource that a single UID may possess */
-        public static final int MAX_NUM_TUNNEL_INTERFACES = 2;
-        public static final int MAX_NUM_ENCAP_SOCKETS = 2;
-        public static final int MAX_NUM_TRANSFORMS = 4;
-        public static final int MAX_NUM_SPIS = 8;
+
+        // Up to 4 active VPNs/IWLAN with potential soft handover.
+        public static final int MAX_NUM_TUNNEL_INTERFACES = 8;
+        public static final int MAX_NUM_ENCAP_SOCKETS = 16;
+
+        // SPIs and Transforms are both cheap, and are 1:1 correlated.
+        public static final int MAX_NUM_TRANSFORMS = 64;
+        public static final int MAX_NUM_SPIS = 64;
 
         /**
          * Store each of the OwnedResource types in an (thinly wrapped) sparse array for indexing
@@ -566,7 +573,7 @@
         }
 
         void put(int key, RefcountedResource<T> obj) {
-            checkNotNull(obj, "Null resources cannot be added");
+            Objects.requireNonNull(obj, "Null resources cannot be added");
             mArray.put(key, obj);
         }
 
@@ -989,12 +996,13 @@
      *
      * @param context Binder context for this service
      */
-    private IpSecService(Context context) {
-        this(context, IpSecServiceConfiguration.GETSRVINSTANCE);
+    private IpSecService(Context context, INetworkManagementService networkManager) {
+        this(context, networkManager, IpSecServiceConfiguration.GETSRVINSTANCE);
     }
 
-    static IpSecService create(Context context) throws InterruptedException {
-        final IpSecService service = new IpSecService(context);
+    static IpSecService create(Context context, INetworkManagementService networkManager)
+            throws InterruptedException {
+        final IpSecService service = new IpSecService(context, networkManager);
         service.connectNativeNetdService();
         return service;
     }
@@ -1008,9 +1016,11 @@
 
     /** @hide */
     @VisibleForTesting
-    public IpSecService(Context context, IpSecServiceConfiguration config) {
+    public IpSecService(Context context, INetworkManagementService networkManager,
+            IpSecServiceConfiguration config) {
         this(
                 context,
+                networkManager,
                 config,
                 (fd, uid) -> {
                     try {
@@ -1024,9 +1034,10 @@
 
     /** @hide */
     @VisibleForTesting
-    public IpSecService(
-            Context context, IpSecServiceConfiguration config, UidFdTagger uidFdTagger) {
+    public IpSecService(Context context, INetworkManagementService networkManager,
+            IpSecServiceConfiguration config, UidFdTagger uidFdTagger) {
         mContext = context;
+        mNetworkManager = Objects.requireNonNull(networkManager);
         mSrvConfig = config;
         mUidFdTagger = uidFdTagger;
     }
@@ -1101,7 +1112,7 @@
         if (requestedSpi > 0 && requestedSpi < 256) {
             throw new IllegalArgumentException("ESP SPI must not be in the range of 0-255.");
         }
-        checkNotNull(binder, "Null Binder passed to allocateSecurityParameterIndex");
+        Objects.requireNonNull(binder, "Null Binder passed to allocateSecurityParameterIndex");
 
         int callingUid = Binder.getCallingUid();
         UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
@@ -1218,7 +1229,7 @@
             throw new IllegalArgumentException(
                     "Specified port number must be a valid non-reserved UDP port");
         }
-        checkNotNull(binder, "Null Binder passed to openUdpEncapsulationSocket");
+        Objects.requireNonNull(binder, "Null Binder passed to openUdpEncapsulationSocket");
 
         int callingUid = Binder.getCallingUid();
         UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
@@ -1278,8 +1289,8 @@
             String localAddr, String remoteAddr, Network underlyingNetwork, IBinder binder,
             String callingPackage) {
         enforceTunnelFeatureAndPermissions(callingPackage);
-        checkNotNull(binder, "Null Binder passed to createTunnelInterface");
-        checkNotNull(underlyingNetwork, "No underlying network was specified");
+        Objects.requireNonNull(binder, "Null Binder passed to createTunnelInterface");
+        Objects.requireNonNull(underlyingNetwork, "No underlying network was specified");
         checkInetAddress(localAddr);
         checkInetAddress(remoteAddr);
 
@@ -1305,6 +1316,10 @@
             final INetd netd = mSrvConfig.getNetdInstance();
             netd.ipSecAddTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey, resourceId);
 
+            Binder.withCleanCallingIdentity(() -> {
+                mNetworkManager.setInterfaceUp(intfName);
+            });
+
             for (int selAddrFamily : ADDRESS_FAMILIES) {
                 // Always send down correct local/remote addresses for template.
                 netd.ipSecAddSecurityPolicy(
@@ -1556,7 +1571,7 @@
                     "IPsec Tunnel Mode requires PackageManager.FEATURE_IPSEC_TUNNELS");
         }
 
-        checkNotNull(callingPackage, "Null calling package cannot create IpSec tunnels");
+        Objects.requireNonNull(callingPackage, "Null calling package cannot create IpSec tunnels");
 
         // OP_MANAGE_IPSEC_TUNNELS will return MODE_ERRORED by default, including for the system
         // server. If the appop is not granted, require that the caller has the MANAGE_IPSEC_TUNNELS
@@ -1625,12 +1640,12 @@
     @Override
     public synchronized IpSecTransformResponse createTransform(
             IpSecConfig c, IBinder binder, String callingPackage) throws RemoteException {
-        checkNotNull(c);
+        Objects.requireNonNull(c);
         if (c.getMode() == IpSecTransform.MODE_TUNNEL) {
             enforceTunnelFeatureAndPermissions(callingPackage);
         }
         checkIpSecConfig(c);
-        checkNotNull(binder, "Null Binder passed to createTransform");
+        Objects.requireNonNull(binder, "Null Binder passed to createTransform");
         final int resourceId = mNextResourceId++;
 
         UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 90e4670..f4b769f 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -25,7 +25,6 @@
 import static android.os.PowerManager.locationPowerSaveModeToString;
 import static android.provider.Settings.Global.LOCATION_DISABLE_STATUS_CALLBACKS;
 
-import static com.android.internal.util.Preconditions.checkNotNull;
 import static com.android.internal.util.Preconditions.checkState;
 
 import android.Manifest;
@@ -133,6 +132,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Objects;
 import java.util.NoSuchElementException;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -986,7 +986,7 @@
 
         @GuardedBy("mLock")
         public void attachLocked(AbstractLocationProvider provider) {
-            checkNotNull(provider);
+            Objects.requireNonNull(provider);
             checkState(mProvider == null);
 
             if (D) {
diff --git a/services/core/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java
index ad02aad..eac767f 100644
--- a/services/core/java/com/android/server/NativeDaemonConnector.java
+++ b/services/core/java/com/android/server/NativeDaemonConnector.java
@@ -46,6 +46,7 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.LinkedList;
+import java.util.Objects;
 
 /**
  * Generic connector class for interfacing with a native daemon which uses the
@@ -126,7 +127,7 @@
      */
     public void setWarnIfHeld(Object warnIfHeld) {
         Preconditions.checkState(mWarnIfHeld == null);
-        mWarnIfHeld = Preconditions.checkNotNull(warnIfHeld);
+        mWarnIfHeld = Objects.requireNonNull(warnIfHeld);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 7d6ae21..1bb3c3a 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -111,6 +111,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 /**
  * @hide
@@ -458,7 +459,7 @@
     @Override
     public void registerTetheringStatsProvider(ITetheringStatsProvider provider, String name) {
         NetworkStack.checkNetworkStackPermission(mContext);
-        Preconditions.checkNotNull(provider);
+        Objects.requireNonNull(provider);
         synchronized(mTetheringStatsProviders) {
             mTetheringStatsProviders.put(provider, name);
         }
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index 76e0c13..8099f8f 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -1,5 +1,5 @@
 # Connectivity / Networking
-per-file ConnectivityService.java,NetworkManagementService.java,NsdService.java = codewiz@google.com, ek@google.com, jchalard@google.com, lorenzo@google.com, reminv@google.com, satk@google.com
+per-file ConnectivityService.java,NetworkManagementService.java,NsdService.java = codewiz@google.com, ek@google.com, jchalard@google.com, junyulai@google.com, lorenzo@google.com, reminv@google.com, satk@google.com
 
 # Vibrator / Threads
 per-file VibratorService.java, DisplayThread.java = michaelwr@google.com
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 39ad354..ba1d8ac 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -1934,7 +1934,7 @@
     public void setVolumeNickname(String fsUuid, String nickname) {
         enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
 
-        Preconditions.checkNotNull(fsUuid);
+        Objects.requireNonNull(fsUuid);
         synchronized (mLock) {
             final VolumeRecord rec = mRecords.get(fsUuid);
             rec.nickname = nickname;
@@ -1947,7 +1947,7 @@
     public void setVolumeUserFlags(String fsUuid, int flags, int mask) {
         enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
 
-        Preconditions.checkNotNull(fsUuid);
+        Objects.requireNonNull(fsUuid);
         synchronized (mLock) {
             final VolumeRecord rec = mRecords.get(fsUuid);
             rec.userFlags = (rec.userFlags & ~mask) | (flags & mask);
@@ -1960,7 +1960,7 @@
     public void forgetVolume(String fsUuid) {
         enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
 
-        Preconditions.checkNotNull(fsUuid);
+        Objects.requireNonNull(fsUuid);
 
         synchronized (mLock) {
             final VolumeRecord rec = mRecords.remove(fsUuid);
@@ -2361,7 +2361,7 @@
 
     @Override
     public String getMountedObbPath(String rawPath) {
-        Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
+        Objects.requireNonNull(rawPath, "rawPath cannot be null");
 
         warnOnNotMounted();
 
@@ -2379,7 +2379,7 @@
 
     @Override
     public boolean isObbMounted(String rawPath) {
-        Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
+        Objects.requireNonNull(rawPath, "rawPath cannot be null");
         synchronized (mObbMounts) {
             return mObbPathToStateMap.containsKey(rawPath);
         }
@@ -2388,10 +2388,10 @@
     @Override
     public void mountObb(String rawPath, String canonicalPath, String key,
             IObbActionListener token, int nonce, ObbInfo obbInfo) {
-        Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
-        Preconditions.checkNotNull(canonicalPath, "canonicalPath cannot be null");
-        Preconditions.checkNotNull(token, "token cannot be null");
-        Preconditions.checkNotNull(obbInfo, "obbIfno cannot be null");
+        Objects.requireNonNull(rawPath, "rawPath cannot be null");
+        Objects.requireNonNull(canonicalPath, "canonicalPath cannot be null");
+        Objects.requireNonNull(token, "token cannot be null");
+        Objects.requireNonNull(obbInfo, "obbIfno cannot be null");
 
         final int callingUid = Binder.getCallingUid();
         final ObbState obbState = new ObbState(rawPath, canonicalPath,
@@ -2405,7 +2405,7 @@
 
     @Override
     public void unmountObb(String rawPath, boolean force, IObbActionListener token, int nonce) {
-        Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
+        Objects.requireNonNull(rawPath, "rawPath cannot be null");
 
         final ObbState existingState;
         synchronized (mObbMounts) {
diff --git a/services/core/java/com/android/server/SystemServerInitThreadPool.java b/services/core/java/com/android/server/SystemServerInitThreadPool.java
index ff6a537..ba82938 100644
--- a/services/core/java/com/android/server/SystemServerInitThreadPool.java
+++ b/services/core/java/com/android/server/SystemServerInitThreadPool.java
@@ -26,6 +26,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index f45d54d..ac897e4 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -45,6 +45,7 @@
 import android.telephony.Annotation.DataFailureCause;
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SrvccState;
+import android.telephony.BarringInfo;
 import android.telephony.CallAttributes;
 import android.telephony.CallQuality;
 import android.telephony.CellIdentity;
@@ -167,14 +168,13 @@
 
         @Override
         public String toString() {
-            return "{callingPackage=" + callingPackage + " binder=" + binder
-                    + " callback=" + callback
+            return "{callingPackage=" + pii(callingPackage) + " callerUid=" + callerUid + " binder="
+                    + binder + " callback=" + callback
                     + " onSubscriptionsChangedListenererCallback="
                     + onSubscriptionsChangedListenerCallback
                     + " onOpportunisticSubscriptionsChangedListenererCallback="
-                    + onOpportunisticSubscriptionsChangedListenerCallback
-                    + " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId
-                    + " events=" + Integer.toHexString(events) + "}";
+                    + onOpportunisticSubscriptionsChangedListenerCallback + " subId=" + subId
+                    + " phoneId=" + phoneId + " events=" + Integer.toHexString(events) + "}";
         }
     }
 
@@ -258,6 +258,8 @@
 
     private int[] mCallPreciseDisconnectCause;
 
+    private List<BarringInfo> mBarringInfo = null;
+
     private boolean mCarrierNetworkChangeState = false;
 
     private PhoneCapability mPhoneCapability = null;
@@ -451,6 +453,7 @@
             cutListToSize(mCellInfo, mNumPhones);
             cutListToSize(mImsReasonInfo, mNumPhones);
             cutListToSize(mPreciseDataConnectionStates, mNumPhones);
+            cutListToSize(mBarringInfo, mNumPhones);
             return;
         }
 
@@ -483,6 +486,7 @@
             mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
             mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>());
             mDisplayInfos[i] = null;
+            mBarringInfo.add(i, new BarringInfo());
         }
     }
 
@@ -541,6 +545,7 @@
         mOutgoingCallEmergencyNumber = new EmergencyNumber[numPhones];
         mOutgoingSmsEmergencyNumber = new EmergencyNumber[numPhones];
         mDisplayInfos = new DisplayInfo[numPhones];
+        mBarringInfo = new ArrayList<>();
         for (int i = 0; i < numPhones; i++) {
             mCallState[i] =  TelephonyManager.CALL_STATE_IDLE;
             mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
@@ -569,6 +574,7 @@
             mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
             mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>());
             mDisplayInfos[i] = null;
+            mBarringInfo.add(i, new BarringInfo());
         }
 
         mAppOps = mContext.getSystemService(AppOpsManager.class);
@@ -591,9 +597,9 @@
         int callerUserId = UserHandle.getCallingUserId();
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
         if (VDBG) {
-            log("listen oscl: E pkg=" + callingPackage + " myUserId=" + UserHandle.myUserId()
-                + " callerUserId="  + callerUserId + " callback=" + callback
-                + " callback.asBinder=" + callback.asBinder());
+            log("listen oscl: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid()
+                    + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId
+                    + " callback=" + callback + " callback.asBinder=" + callback.asBinder());
         }
 
         synchronized (mRecords) {
@@ -645,9 +651,9 @@
         int callerUserId = UserHandle.getCallingUserId();
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
         if (VDBG) {
-            log("listen ooscl: E pkg=" + callingPackage + " myUserId=" + UserHandle.myUserId()
-                    + " callerUserId="  + callerUserId + " callback=" + callback
-                    + " callback.asBinder=" + callback.asBinder());
+            log("listen ooscl: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid()
+                    + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId
+                    + " callback=" + callback + " callback.asBinder=" + callback.asBinder());
         }
 
         synchronized (mRecords) {
@@ -762,9 +768,9 @@
             IPhoneStateListener callback, int events, boolean notifyNow, int subId) {
         int callerUserId = UserHandle.getCallingUserId();
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
-        String str = "listen: E pkg=" + callingPackage + " events=0x" + Integer.toHexString(events)
-                + " notifyNow=" + notifyNow + " subId=" + subId + " myUserId="
-                + UserHandle.myUserId() + " callerUserId=" + callerUserId;
+        String str = "listen: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid()
+                + " events=0x" + Integer.toHexString(events) + " notifyNow=" + notifyNow + " subId="
+                + subId + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId;
         mListenLog.log(str);
         if (VDBG) {
             log(str);
@@ -1031,6 +1037,19 @@
                             remove(r.binder);
                         }
                     }
+                    if ((events & PhoneStateListener.LISTEN_BARRING_INFO) != 0) {
+                        BarringInfo barringInfo = mBarringInfo.get(phoneId);
+                        BarringInfo biNoLocation = barringInfo != null
+                                ? barringInfo.createLocationInfoSanitizedCopy() : null;
+                        if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo);
+                        try {
+                            r.callback.onBarringInfoChanged(
+                                    checkFineLocationAccess(r, Build.VERSION_CODES.R)
+                                            ? barringInfo : biNoLocation);
+                        } catch (RemoteException ex) {
+                            remove(r.binder);
+                        }
+                    }
                 }
             }
         } else {
@@ -1518,17 +1537,15 @@
         }
         synchronized (mRecords) {
             if (validatePhoneId(phoneId)) {
-                if (mDisplayInfos[phoneId] != null) {
-                    mDisplayInfos[phoneId] = displayInfo;
-                    for (Record r : mRecords) {
-                        if (r.matchPhoneStateListenerEvent(
-                                PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
-                                && idMatch(r.subId, subId, phoneId)) {
-                            try {
-                                r.callback.onDisplayInfoChanged(displayInfo);
-                            } catch (RemoteException ex) {
-                                mRemoveList.add(r.binder);
-                            }
+                mDisplayInfos[phoneId] = displayInfo;
+                for (Record r : mRecords) {
+                    if (r.matchPhoneStateListenerEvent(
+                            PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
+                            && idMatch(r.subId, subId, phoneId)) {
+                        try {
+                            r.callback.onDisplayInfoChanged(displayInfo);
+                        } catch (RemoteException ex) {
+                            mRemoveList.add(r.binder);
                         }
                     }
                 }
@@ -2207,6 +2224,52 @@
         }
     }
 
+    /**
+     * Send a notification of changes to barring status to PhoneStateListener registrants.
+     *
+     * @param phoneId the phoneId
+     * @param subId the subId
+     * @param barringInfo a structure containing the complete updated barring info.
+     */
+    public void notifyBarringInfoChanged(int phoneId, int subId, @NonNull BarringInfo barringInfo) {
+        if (!checkNotifyPermission("notifyBarringInfo()")) {
+            return;
+        }
+        if (barringInfo == null) {
+            log("Received null BarringInfo for subId=" + subId + ", phoneId=" + phoneId);
+            mBarringInfo.set(phoneId, new BarringInfo());
+            return;
+        }
+
+        synchronized (mRecords) {
+            if (validatePhoneId(phoneId)) {
+                mBarringInfo.set(phoneId, barringInfo);
+                // Barring info is non-null
+                BarringInfo biNoLocation = barringInfo.createLocationInfoSanitizedCopy();
+                if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo);
+                for (Record r : mRecords) {
+                    if (r.matchPhoneStateListenerEvent(
+                            PhoneStateListener.LISTEN_BARRING_INFO)
+                            && idMatch(r.subId, subId, phoneId)) {
+                        try {
+                            if (DBG_LOC) {
+                                log("notifyBarringInfo: mBarringInfo="
+                                        + barringInfo + " r=" + r);
+                            }
+                            r.callback.onBarringInfoChanged(
+                                    checkFineLocationAccess(r, Build.VERSION_CODES.R)
+                                        ? barringInfo : biNoLocation);
+                        } catch (RemoteException ex) {
+                            mRemoveList.add(r.binder);
+                        }
+                    }
+                }
+            }
+            handleRemoveListLocked();
+        }
+    }
+
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
@@ -2247,6 +2310,7 @@
                 pw.println("mPreciseDataConnectionStates=" + mPreciseDataConnectionStates.get(i));
                 pw.println("mOutgoingCallEmergencyNumber=" + mOutgoingCallEmergencyNumber[i]);
                 pw.println("mOutgoingSmsEmergencyNumber=" + mOutgoingSmsEmergencyNumber[i]);
+                pw.println("mBarringInfo=" + mBarringInfo.get(i));
                 pw.decreaseIndent();
             }
             pw.println("mCarrierNetworkChangeState=" + mCarrierNetworkChangeState);
@@ -2870,4 +2934,14 @@
         if (info == null) return INVALID_SIM_SLOT_INDEX;
         return info.getSimSlotIndex();
     }
+
+    /**
+     * On certain build types, we should redact information by default. UID information will be
+     * preserved in the same log line, so no debugging capability is lost in full bug reports.
+     * However, privacy-constrained bug report types (e.g. connectivity) cannot display raw
+     * package names on user builds as it's considered an information leak.
+     */
+    private static String pii(String packageName) {
+        return Build.IS_DEBUGGABLE ? packageName : "***";
+    }
 }
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index 95ac900..0ea7346 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -16,7 +16,8 @@
 
 package com.android.server;
 
-import static com.android.internal.util.Preconditions.checkNotNull;
+import static android.net.TestNetworkManager.TEST_TAP_PREFIX;
+import static android.net.TestNetworkManager.TEST_TUN_PREFIX;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -55,14 +56,13 @@
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.util.ArrayList;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /** @hide */
 class TestNetworkService extends ITestNetworkManager.Stub {
     @NonNull private static final String TAG = TestNetworkService.class.getSimpleName();
     @NonNull private static final String TEST_NETWORK_TYPE = "TEST_NETWORK";
-    @NonNull private static final String TEST_TUN_PREFIX = "testtun";
-    @NonNull private static final String TEST_TAP_PREFIX = "testtap";
     @NonNull private static final AtomicInteger sTestTunIndex = new AtomicInteger();
 
     @NonNull private final Context mContext;
@@ -82,9 +82,9 @@
         mHandlerThread.start();
         mHandler = new Handler(mHandlerThread.getLooper());
 
-        mContext = checkNotNull(context, "missing Context");
-        mNMS = checkNotNull(netManager, "missing INetworkManagementService");
-        mNetd = checkNotNull(NetdService.getInstance(), "could not get netd instance");
+        mContext = Objects.requireNonNull(context, "missing Context");
+        mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService");
+        mNetd = Objects.requireNonNull(NetdService.getInstance(), "could not get netd instance");
     }
 
     /**
@@ -96,7 +96,7 @@
     private TestNetworkInterface createInterface(boolean isTun, LinkAddress[] linkAddrs) {
         enforceTestNetworkPermissions(mContext);
 
-        checkNotNull(linkAddrs, "missing linkAddrs");
+        Objects.requireNonNull(linkAddrs, "missing linkAddrs");
 
         String ifacePrefix = isTun ? TEST_TUN_PREFIX : TEST_TAP_PREFIX;
         String iface = ifacePrefix + sTestTunIndex.getAndIncrement();
@@ -231,10 +231,11 @@
             @Nullable LinkProperties lp,
             boolean isMetered,
             int callingUid,
+            @NonNull int[] administratorUids,
             @NonNull IBinder binder)
             throws RemoteException, SocketException {
-        checkNotNull(looper, "missing Looper");
-        checkNotNull(context, "missing Context");
+        Objects.requireNonNull(looper, "missing Looper");
+        Objects.requireNonNull(context, "missing Context");
         // iface and binder validity checked by caller
 
         // Build network info with special testing type
@@ -249,6 +250,7 @@
         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
         nc.setNetworkSpecifier(new StringNetworkSpecifier(iface));
+        nc.setAdministratorUids(administratorUids);
         if (!isMetered) {
             nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
         }
@@ -267,7 +269,7 @@
         // Find the currently assigned addresses, and add them to LinkProperties
         boolean allowIPv4 = false, allowIPv6 = false;
         NetworkInterface netIntf = NetworkInterface.getByName(iface);
-        checkNotNull(netIntf, "No such network interface found: " + netIntf);
+        Objects.requireNonNull(netIntf, "No such network interface found: " + netIntf);
 
         for (InterfaceAddress intfAddr : netIntf.getInterfaceAddresses()) {
             lp.addLinkAddress(
@@ -302,11 +304,12 @@
             @NonNull String iface,
             @Nullable LinkProperties lp,
             boolean isMetered,
+            @NonNull int[] administratorUids,
             @NonNull IBinder binder) {
         enforceTestNetworkPermissions(mContext);
 
-        checkNotNull(iface, "missing Iface");
-        checkNotNull(binder, "missing IBinder");
+        Objects.requireNonNull(iface, "missing Iface");
+        Objects.requireNonNull(binder, "missing IBinder");
 
         if (!(iface.startsWith(INetd.IPSEC_INTERFACE_PREFIX)
                 || iface.startsWith(TEST_TUN_PREFIX))) {
@@ -336,6 +339,7 @@
                                             lp,
                                             isMetered,
                                             callingUid,
+                                            administratorUids,
                                             binder);
 
                             mTestNetworkTracker.put(agent.getNetwork().netId, agent);
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 454941c..5f9d1d8 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -115,6 +115,7 @@
             "android.hardware.media.c2@1.0::IComponentStore",
             "android.hardware.media.omx@1.0::IOmx",
             "android.hardware.media.omx@1.0::IOmxStore",
+            "android.hardware.neuralnetworks@1.0::IDevice",
             "android.hardware.power.stats@1.0::IPowerStats",
             "android.hardware.sensors@1.0::ISensors",
             "android.hardware.vr@1.0::IVr",
diff --git a/services/core/java/com/android/server/accounts/TokenCache.java b/services/core/java/com/android/server/accounts/TokenCache.java
index 2af2f38..2aa9776 100644
--- a/services/core/java/com/android/server/accounts/TokenCache.java
+++ b/services/core/java/com/android/server/accounts/TokenCache.java
@@ -148,7 +148,7 @@
                 accountEvictor = new Evictor();
             }
             accountEvictor.add(k);
-            mAccountEvictors.put(k.account, tokenEvictor);
+            mAccountEvictors.put(k.account, accountEvictor);
 
             // Only cache the token once we can remove it directly or by account.
             put(k, v);
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index d935162..f5cefb3 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -106,7 +106,6 @@
 import com.android.server.wm.ActivityServiceConnectionsHolder;
 import com.android.server.wm.WindowManagerService;
 
-import dalvik.annotation.compat.VersionCodes;
 import dalvik.system.VMRuntime;
 
 import java.io.File;
@@ -290,7 +289,7 @@
      * Pointers</a>
      */
     @ChangeId
-    @EnabledAfter(targetSdkVersion = VersionCodes.Q)
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
     private static final long NATIVE_HEAP_POINTER_TAGGING = 135754954; // This is a bug id.
 
     ActivityManagerService mService = null;
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 068d6fc..fc6d9f7 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -672,7 +672,7 @@
             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume;
         } else {
             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] =
-                    (maxCallVolume * 3) / 4;
+                    (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4;
         }
 
         int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1);
@@ -4318,6 +4318,7 @@
     public void setWiredDeviceConnectionState(int type,
             @ConnectionState int state, String address, String name,
             String caller) {
+        enforceModifyAudioRoutingPermission();
         if (state != CONNECTION_STATE_CONNECTED
                 && state != CONNECTION_STATE_DISCONNECTED) {
             throw new IllegalArgumentException("Invalid state " + state);
diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java
index 7bdeb59..2e9818d 100644
--- a/services/core/java/com/android/server/compat/CompatChange.java
+++ b/services/core/java/com/android/server/compat/CompatChange.java
@@ -151,6 +151,15 @@
         return true;
     }
 
+    /**
+     * Checks whether a change has an override for a package.
+     * @param packageName name of the package
+     * @return true if there is such override
+     */
+    boolean hasOverride(String packageName) {
+        return mPackageOverrides != null && mPackageOverrides.containsKey(packageName);
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder("ChangeId(")
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index 33eeb8a..d3f4eb4 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -242,11 +242,13 @@
             CompatChange c = mChanges.get(changeId);
             try {
                 if (c != null) {
-                    OverrideAllowedState allowedState =
-                            mOverrideValidator.getOverrideAllowedState(changeId, packageName);
-                    allowedState.enforce(changeId, packageName);
-                    overrideExists = true;
-                    c.removePackageOverride(packageName);
+                    overrideExists = c.hasOverride(packageName);
+                    if (overrideExists) {
+                        OverrideAllowedState allowedState =
+                                mOverrideValidator.getOverrideAllowedState(changeId, packageName);
+                        allowedState.enforce(changeId, packageName);
+                        c.removePackageOverride(packageName);
+                    }
                 }
             } catch (RemoteException e) {
                 // Should never occur, since validator is in the same process.
@@ -291,12 +293,14 @@
             for (int i = 0; i < mChanges.size(); ++i) {
                 try {
                     CompatChange change = mChanges.valueAt(i);
-                    OverrideAllowedState allowedState =
-                            mOverrideValidator.getOverrideAllowedState(change.getId(),
-                                                                       packageName);
-                    allowedState.enforce(change.getId(), packageName);
-                    if (change != null) {
-                        mChanges.valueAt(i).removePackageOverride(packageName);
+                    if (change.hasOverride(packageName)) {
+                        OverrideAllowedState allowedState =
+                                mOverrideValidator.getOverrideAllowedState(change.getId(),
+                                        packageName);
+                        allowedState.enforce(change.getId(), packageName);
+                        if (change != null) {
+                            mChanges.valueAt(i).removePackageOverride(packageName);
+                        }
                     }
                 } catch (RemoteException e) {
                     // Should never occur, since validator is in the same process.
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 3e51ee7..470e1b1 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -28,6 +28,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.os.Binder;
+import android.os.Build;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Slog;
@@ -43,6 +44,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.Arrays;
 
 /**
  * System server internal API for gating and reporting compatibility changes.
@@ -55,6 +57,9 @@
     private final ChangeReporter mChangeReporter;
     private final CompatConfig mCompatConfig;
 
+    private static int sMinTargetSdk = Build.VERSION_CODES.P;
+    private static int sMaxTargetSdk = Build.VERSION_CODES.Q;
+
     public PlatformCompat(Context context) {
         mContext = context;
         mChangeReporter = new ChangeReporter(
@@ -219,6 +224,12 @@
         return mCompatConfig.dumpChanges();
     }
 
+    @Override
+    public CompatibilityChangeInfo[] listUIChanges() {
+        return Arrays.stream(listAllChanges()).filter(
+                x -> isShownInUI(x)).toArray(CompatibilityChangeInfo[]::new);
+    }
+
     /**
      * Check whether the change is known to the compat config.
      *
@@ -342,4 +353,17 @@
         checkCompatChangeReadPermission();
         checkCompatChangeLogPermission();
     }
+
+    private boolean isShownInUI(CompatibilityChangeInfo change) {
+        if (change.getLoggingOnly()) {
+            return false;
+        }
+        if (change.getEnableAfterTargetSdk() > 0) {
+            if (change.getEnableAfterTargetSdk() < sMinTargetSdk
+                    || change.getEnableAfterTargetSdk() > sMaxTargetSdk) {
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index 5059a48..7c8fb5a 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -220,9 +220,9 @@
                     + " network=" + mNai.network
                     + " startedState=" + startedStateString(mStartedState)
                     + " "
-                    + IpUtils.addressAndPortToString(mPacket.srcAddress, mPacket.srcPort)
+                    + IpUtils.addressAndPortToString(mPacket.getSrcAddress(), mPacket.getSrcPort())
                     + "->"
-                    + IpUtils.addressAndPortToString(mPacket.dstAddress, mPacket.dstPort)
+                    + IpUtils.addressAndPortToString(mPacket.getDstAddress(), mPacket.getDstPort())
                     + " interval=" + mInterval
                     + " uid=" + mUid + " pid=" + mPid + " privileged=" + mPrivileged
                     + " packetData=" + HexDump.toHexString(mPacket.getPacket())
@@ -250,7 +250,7 @@
         private int checkSourceAddress() {
             // Check that we have the source address.
             for (InetAddress address : mNai.linkProperties.getAddresses()) {
-                if (address.equals(mPacket.srcAddress)) {
+                if (address.equals(mPacket.getSrcAddress())) {
                     return SUCCESS;
                 }
             }
@@ -619,7 +619,7 @@
             packet = NattKeepalivePacketData.nattKeepalivePacket(
                     srcAddress, srcPort, dstAddress, NATT_PORT);
         } catch (InvalidPacketException e) {
-            notifyErrorCallback(cb, e.error);
+            notifyErrorCallback(cb, e.getError());
             return;
         }
         KeepaliveInfo ki = null;
@@ -662,7 +662,7 @@
             notifyErrorCallback(cb, e.error);
             return;
         } catch (InvalidPacketException e) {
-            notifyErrorCallback(cb, e.error);
+            notifyErrorCallback(cb, e.getError());
             return;
         }
         KeepaliveInfo ki = null;
diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index 04c792a..d548871 100644
--- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -25,6 +25,7 @@
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkPolicy.LIMIT_DISABLED;
 import static android.net.NetworkPolicy.WARNING_DISABLED;
+import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
 import static android.provider.Settings.Global.NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
@@ -220,7 +221,7 @@
             mNetworkTemplate = new NetworkTemplate(
                     NetworkTemplate.MATCH_MOBILE, subscriberId, new String[] { subscriberId },
                     null, NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL,
-                    NetworkStats.DEFAULT_NETWORK_NO);
+                    NetworkStats.DEFAULT_NETWORK_NO, NETWORK_TYPE_ALL);
             mUsageCallback = new UsageCallback() {
                 @Override
                 public void onThresholdReached(int networkType, String subscriberId) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 23b954c..f844844 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -160,10 +160,6 @@
     // Whether a captive portal was found during the last network validation attempt.
     public boolean lastCaptivePortalDetected;
 
-    // Indicates the captive portal app was opened to show a login UI to the user, but the network
-    // has not validated yet.
-    public volatile boolean captivePortalValidationPending;
-
     // Set to true when partial connectivity was detected.
     public boolean partialConnectivity;
 
@@ -625,23 +621,23 @@
         for (LingerTimer timer : mLingerTimers) { pw.println(timer); }
     }
 
-    // TODO: Print shorter members first and only print the boolean variable which value is true
-    // to improve readability.
     public String toString() {
-        return "NetworkAgentInfo{ ni{" + networkInfo + "}  "
-                + "network{" + network + "}  nethandle{" + network.getNetworkHandle() + "}  "
-                + "lp{" + linkProperties + "}  "
-                + "nc{" + networkCapabilities + "}  Score{" + getCurrentScore() + "}  "
-                + "everValidated{" + everValidated + "}  lastValidated{" + lastValidated + "}  "
-                + "created{" + created + "} lingering{" + isLingering() + "} "
-                + "explicitlySelected{" + networkAgentConfig.explicitlySelected + "} "
-                + "acceptUnvalidated{" + networkAgentConfig.acceptUnvalidated + "} "
-                + "everCaptivePortalDetected{" + everCaptivePortalDetected + "} "
-                + "lastCaptivePortalDetected{" + lastCaptivePortalDetected + "} "
-                + "captivePortalValidationPending{" + captivePortalValidationPending + "} "
-                + "partialConnectivity{" + partialConnectivity + "} "
-                + "acceptPartialConnectivity{" + networkAgentConfig.acceptPartialConnectivity + "} "
-                + "clat{" + clatd + "} "
+        return "NetworkAgentInfo{"
+                + "network{" + network + "}  handle{" + network.getNetworkHandle() + "}  ni{"
+                + networkInfo.toShortString() + "} "
+                + "  Score{" + getCurrentScore() + "} "
+                + (isLingering() ? " lingering" : "")
+                + (everValidated ? " everValidated" : "")
+                + (lastValidated ? " lastValidated" : "")
+                + (partialConnectivity ? " partialConnectivity" : "")
+                + (everCaptivePortalDetected ? " everCaptivePortal" : "")
+                + (lastCaptivePortalDetected ? " isCaptivePortal" : "")
+                + (networkAgentConfig.explicitlySelected ? " explicitlySelected" : "")
+                + (networkAgentConfig.acceptUnvalidated ? " acceptUnvalidated" : "")
+                + (networkAgentConfig.acceptPartialConnectivity ? " acceptPartialConnectivity" : "")
+                + (clatd.isStarted() ? " clat{" + clatd + "} " : "")
+                + "  lp{" + linkProperties + "}"
+                + "  nc{" + networkCapabilities + "}"
                 + "}";
     }
 
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 25c761a..34b0aa2 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -51,7 +51,6 @@
         LOST_INTERNET(SystemMessage.NOTE_NETWORK_LOST_INTERNET),
         NETWORK_SWITCH(SystemMessage.NOTE_NETWORK_SWITCH),
         NO_INTERNET(SystemMessage.NOTE_NETWORK_NO_INTERNET),
-        LOGGED_IN(SystemMessage.NOTE_NETWORK_LOGGED_IN),
         PARTIAL_CONNECTIVITY(SystemMessage.NOTE_NETWORK_PARTIAL_CONNECTIVITY),
         SIGN_IN(SystemMessage.NOTE_NETWORK_SIGN_IN),
         PRIVATE_DNS_BROKEN(SystemMessage.NOTE_NETWORK_PRIVATE_DNS_BROKEN);
@@ -114,14 +113,10 @@
         }
     }
 
-    private static int getIcon(int transportType, NotificationType notifyType) {
-        if (transportType != TRANSPORT_WIFI) {
-            return R.drawable.stat_notify_rssi_in_range;
-        }
-
-        return notifyType == NotificationType.LOGGED_IN
-            ? R.drawable.ic_wifi_signal_4
-            : R.drawable.stat_notify_wifi_in_range;  // TODO: Distinguish ! from ?.
+    private static int getIcon(int transportType) {
+        return (transportType == TRANSPORT_WIFI)
+                ? R.drawable.stat_notify_wifi_in_range :  // TODO: Distinguish ! from ?.
+                R.drawable.stat_notify_rssi_in_range;
     }
 
     /**
@@ -155,7 +150,7 @@
         if (nai != null) {
             transportType = approximateTransportType(nai);
             final String extraInfo = nai.networkInfo.getExtraInfo();
-            name = TextUtils.isEmpty(extraInfo) ? nai.networkCapabilities.getSSID() : extraInfo;
+            name = TextUtils.isEmpty(extraInfo) ? nai.networkCapabilities.getSsid() : extraInfo;
             // Only notify for Internet-capable networks.
             if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_INTERNET)) return;
         } else {
@@ -185,17 +180,17 @@
         Resources r = mContext.getResources();
         final CharSequence title;
         final CharSequence details;
-        int icon = getIcon(transportType, notifyType);
+        int icon = getIcon(transportType);
         if (notifyType == NotificationType.NO_INTERNET && transportType == TRANSPORT_WIFI) {
             title = r.getString(R.string.wifi_no_internet,
-                    WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
+                    WifiInfo.sanitizeSsid(nai.networkCapabilities.getSsid()));
             details = r.getString(R.string.wifi_no_internet_detailed);
         } else if (notifyType == NotificationType.PRIVATE_DNS_BROKEN) {
             if (transportType == TRANSPORT_CELLULAR) {
                 title = r.getString(R.string.mobile_no_internet);
             } else if (transportType == TRANSPORT_WIFI) {
                 title = r.getString(R.string.wifi_no_internet,
-                        WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
+                        WifiInfo.sanitizeSsid(nai.networkCapabilities.getSsid()));
             } else {
                 title = r.getString(R.string.other_networks_no_internet);
             }
@@ -203,19 +198,19 @@
         } else if (notifyType == NotificationType.PARTIAL_CONNECTIVITY
                 && transportType == TRANSPORT_WIFI) {
             title = r.getString(R.string.network_partial_connectivity,
-                    WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
+                    WifiInfo.sanitizeSsid(nai.networkCapabilities.getSsid()));
             details = r.getString(R.string.network_partial_connectivity_detailed);
         } else if (notifyType == NotificationType.LOST_INTERNET &&
                 transportType == TRANSPORT_WIFI) {
             title = r.getString(R.string.wifi_no_internet,
-                    WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
+                    WifiInfo.sanitizeSsid(nai.networkCapabilities.getSsid()));
             details = r.getString(R.string.wifi_no_internet_detailed);
         } else if (notifyType == NotificationType.SIGN_IN) {
             switch (transportType) {
                 case TRANSPORT_WIFI:
                     title = r.getString(R.string.wifi_available_sign_in, 0);
                     details = r.getString(R.string.network_available_sign_in_detailed,
-                            WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
+                            WifiInfo.sanitizeSsid(nai.networkCapabilities.getSsid()));
                     break;
                 case TRANSPORT_CELLULAR:
                     title = r.getString(R.string.network_available_sign_in, 0);
@@ -235,9 +230,6 @@
                     details = r.getString(R.string.network_available_sign_in_detailed, name);
                     break;
             }
-        } else if (notifyType == NotificationType.LOGGED_IN) {
-            title = WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID());
-            details = r.getString(R.string.captive_portal_logged_in_detailed);
         } else if (notifyType == NotificationType.NETWORK_SWITCH) {
             String fromTransport = getTransportName(transportType);
             String toTransport = getTransportName(approximateTransportType(switchToNai));
@@ -379,7 +371,6 @@
             case NETWORK_SWITCH:
                 return 2;
             case LOST_INTERNET:
-            case LOGGED_IN:
                 return 1;
             default:
                 return 0;
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 7c42cc2..3006ef4 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -306,10 +306,6 @@
     static final String PROPERTY_PREFERRED_ADDRESS_PLAYBACK = "persist.sys.hdmi.addr.playback";
     static final String PROPERTY_PREFERRED_ADDRESS_TV = "persist.sys.hdmi.addr.tv";
 
-    // Property name for the local device configurations.
-    // TODO(OEM): OEM should provide this property, and the value is the comma separated integer
-    //     values which denotes the device type in HDMI Spec 1.4.
-    static final String PROPERTY_DEVICE_TYPE = "ro.hdmi.device_type";
 
     // TODO(OEM): Set this to false to keep the playback device in sleep upon hotplug event.
     //            True by default.
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index a83dd21..d489c39 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -67,6 +67,7 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings.Global;
+import android.sysprop.HdmiProperties;
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Slog;
@@ -94,6 +95,8 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * Provides a service for sending and processing HDMI control messages,
@@ -435,7 +438,14 @@
 
     public HdmiControlService(Context context) {
         super(context);
-        mLocalDevices = getIntList(SystemProperties.get(Constants.PROPERTY_DEVICE_TYPE));
+        List<Integer> deviceTypes = HdmiProperties.device_type();
+        if (deviceTypes.contains(null)) {
+            Slog.w(TAG, "Error parsing ro.hdmi.device.type: " + SystemProperties.get(
+                    "ro.hdmi.device_type"));
+            deviceTypes = deviceTypes.stream().filter(Objects::nonNull).collect(
+                    Collectors.toList());
+        }
+        mLocalDevices = deviceTypes;
         mSettingsObserver = new SettingsObserver(mHandler);
     }
 
diff --git a/services/core/java/com/android/server/inputmethod/OWNERS b/services/core/java/com/android/server/inputmethod/OWNERS
new file mode 100644
index 0000000..25ef9fa
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/OWNERS
@@ -0,0 +1,6 @@
+set noparent
+
+ogunwale@google.com
+yukawa@google.com
+tarandeep@google.com
+lumark@google.com
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
index 563dcf7..48f1ddb 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
@@ -21,7 +21,7 @@
 import android.annotation.NonNull;
 import android.net.Network;
 import android.net.NetworkTemplate;
-import android.net.netstats.provider.AbstractNetworkStatsProvider;
+import android.net.netstats.provider.NetworkStatsProvider;
 import android.telephony.SubscriptionPlan;
 
 import java.util.Set;
@@ -130,8 +130,8 @@
             Set<String> packageNames, int userId);
 
     /**
-     *  Notifies that the specified {@link AbstractNetworkStatsProvider} has reached its quota
-     *  which was set through {@link AbstractNetworkStatsProvider#setLimit(String, long)}.
+     *  Notifies that the specified {@link NetworkStatsProvider} has reached its quota
+     *  which was set through {@link NetworkStatsProvider#onSetLimit(String, long)}.
      *
      * @param tag the human readable identifier of the custom network stats provider.
      */
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 10cf250..22ed661 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -75,7 +75,7 @@
 import static android.net.NetworkTemplate.MATCH_WIFI;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.TrafficStats.MB_IN_BYTES;
-import static android.net.netstats.provider.AbstractNetworkStatsProvider.QUOTA_UNLIMITED;
+import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
 import static android.os.Trace.TRACE_TAG_NETWORK;
 import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED;
 import static android.provider.Settings.Global.NETPOLICY_QUOTA_ENABLED;
@@ -1869,8 +1869,11 @@
                 mNetIdToSubId.put(state.network.netId, parseSubId(state));
             }
             if (state.networkInfo != null && state.networkInfo.isConnected()) {
+                // Policies matched by NPMS only match by subscriber ID or by ssid. Thus subtype
+                // in the object created here is never used and its value doesn't matter, so use
+                // NETWORK_TYPE_UNKNOWN.
                 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
-                        true);
+                        true, TelephonyManager.NETWORK_TYPE_UNKNOWN /* subType */);
                 identified.put(state, ident);
             }
         }
@@ -3088,31 +3091,64 @@
     private void enforceSubscriptionPlanValidity(SubscriptionPlan[] plans) {
         // nothing to check if no plans
         if (plans.length == 0) {
+            Log.d(TAG, "Received empty plans list. Clearing existing SubscriptionPlans.");
             return;
         }
 
-        long applicableNetworkTypes = 0;
-        boolean allNetworks = false;
-        for (SubscriptionPlan plan : plans) {
-            if (plan.getNetworkTypes() == null) {
-                allNetworks = true;
+        final int[] allNetworkTypes = TelephonyManager.getAllNetworkTypes();
+        final ArraySet<Integer> allNetworksSet = new ArraySet<>();
+        addAll(allNetworksSet, allNetworkTypes);
+
+        final ArraySet<Integer> applicableNetworkTypes = new ArraySet<>();
+        boolean hasGeneralPlan = false;
+        for (int i = 0; i < plans.length; i++) {
+            final int[] planNetworkTypes = plans[i].getNetworkTypes();
+            final ArraySet<Integer> planNetworksSet = new ArraySet<>();
+            for (int j = 0; j < planNetworkTypes.length; j++) {
+                // ensure all network types are valid
+                if (allNetworksSet.contains(planNetworkTypes[j])) {
+                    // ensure no duplicate network types in the same SubscriptionPlan
+                    if (!planNetworksSet.add(planNetworkTypes[j])) {
+                        throw new IllegalArgumentException(
+                                "Subscription plan contains duplicate network types.");
+                    }
+                } else {
+                    throw new IllegalArgumentException("Invalid network type: "
+                            + planNetworkTypes[j]);
+                }
+            }
+
+            if (planNetworkTypes.length == allNetworkTypes.length) {
+                hasGeneralPlan = true;
             } else {
-                if ((applicableNetworkTypes & plan.getNetworkTypesBitMask()) != 0) {
+                // ensure no network type applies to multiple plans
+                if (!addAll(applicableNetworkTypes, planNetworkTypes)) {
                     throw new IllegalArgumentException(
                             "Multiple subscription plans defined for a single network type.");
-                } else {
-                    applicableNetworkTypes |= plan.getNetworkTypesBitMask();
                 }
             }
         }
 
         // ensure at least one plan applies for every network type
-        if (!allNetworks) {
+        if (!hasGeneralPlan) {
             throw new IllegalArgumentException(
                     "No generic subscription plan that applies to all network types.");
         }
     }
 
+    /**
+     * Adds all of the {@code elements} to the {@code set}.
+     *
+     * @return {@code false} if any element is not added because the set already has the value.
+     */
+    private static boolean addAll(@NonNull ArraySet<Integer> set, @NonNull int... elements) {
+        boolean result = true;
+        for (int i = 0; i < elements.length; i++) {
+            result &= set.add(elements[i]);
+        }
+        return result;
+    }
+
     @Override
     public SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage) {
         enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage);
diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java
index 22b01be..75ffe35 100644
--- a/services/core/java/com/android/server/net/NetworkStatsFactory.java
+++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java
@@ -229,7 +229,7 @@
                     entry.txPackets += reader.nextLong();
                 }
 
-                stats.addEntry(entry);
+                stats.insertEntry(entry);
                 reader.finishLine();
             }
         } catch (NullPointerException|NumberFormatException e) {
@@ -279,7 +279,7 @@
                 entry.txBytes = reader.nextLong();
                 entry.txPackets = reader.nextLong();
 
-                stats.addEntry(entry);
+                stats.insertEntry(entry);
                 reader.finishLine();
             }
         } catch (NullPointerException|NumberFormatException e) {
@@ -439,7 +439,7 @@
                 if ((limitIfaces == null || ArrayUtils.contains(limitIfaces, entry.iface))
                         && (limitUid == UID_ALL || limitUid == entry.uid)
                         && (limitTag == TAG_ALL || limitTag == entry.tag)) {
-                    stats.addEntry(entry);
+                    stats.insertEntry(entry);
                 }
 
                 reader.finishLine();
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 66e691a..2680858 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -17,14 +17,17 @@
 package com.android.server.net;
 
 import static android.Manifest.permission.ACCESS_NETWORK_STATE;
+import static android.Manifest.permission.NETWORK_STATS_PROVIDER;
 import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
 import static android.Manifest.permission.UPDATE_DEVICE_STATS;
 import static android.content.Intent.ACTION_SHUTDOWN;
 import static android.content.Intent.ACTION_UID_REMOVED;
 import static android.content.Intent.ACTION_USER_REMOVED;
 import static android.content.Intent.EXTRA_UID;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
 import static android.net.ConnectivityManager.isNetworkTypeMobile;
+import static android.net.NetworkIdentity.SUBTYPE_COMBINED;
 import static android.net.NetworkStack.checkNetworkStackPermission;
 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
 import static android.net.NetworkStats.IFACE_ALL;
@@ -43,10 +46,12 @@
 import static android.net.NetworkStatsHistory.FIELD_ALL;
 import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
 import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
+import static android.net.NetworkTemplate.getCollapsedRatType;
 import static android.net.TrafficStats.KB_IN_BYTES;
 import static android.net.TrafficStats.MB_IN_BYTES;
 import static android.os.Trace.TRACE_TAG_NETWORK;
 import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED;
+import static android.provider.Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED;
 import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
 import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
 import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
@@ -62,6 +67,9 @@
 import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
 import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
 import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
+import static android.telephony.PhoneStateListener.LISTEN_NONE;
+import static android.telephony.PhoneStateListener.LISTEN_SERVICE_STATE;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
 import static android.text.format.DateUtils.DAY_IN_MILLIS;
 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
@@ -101,12 +109,13 @@
 import android.net.TrafficStats;
 import android.net.netstats.provider.INetworkStatsProvider;
 import android.net.netstats.provider.INetworkStatsProviderCallback;
-import android.net.netstats.provider.NetworkStatsProviderCallback;
+import android.net.netstats.provider.NetworkStatsProvider;
 import android.os.BestClock;
 import android.os.Binder;
 import android.os.DropBoxManager;
 import android.os.Environment;
 import android.os.Handler;
+import android.os.HandlerExecutor;
 import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
@@ -123,6 +132,8 @@
 import android.provider.Settings.Global;
 import android.service.NetworkInterfaceProto;
 import android.service.NetworkStatsServiceDumpProto;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
 import android.telephony.SubscriptionPlan;
 import android.telephony.TelephonyManager;
 import android.text.format.DateUtils;
@@ -155,6 +166,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.Executor;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
@@ -171,6 +183,7 @@
     private static final int MSG_PERFORM_POLL = 1;
     // Perform polling, persist network, and register the global alert again.
     private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2;
+    private static final int MSG_UPDATE_IFACES = 3;
 
     /** Flags to control detail level of poll event. */
     private static final int FLAG_PERSIST_NETWORK = 0x1;
@@ -227,12 +240,20 @@
      * Settings that can be changed externally.
      */
     public interface NetworkStatsSettings {
-        public long getPollInterval();
-        public long getPollDelay();
-        public boolean getSampleEnabled();
-        public boolean getAugmentEnabled();
+        long getPollInterval();
+        long getPollDelay();
+        boolean getSampleEnabled();
+        boolean getAugmentEnabled();
+        /**
+         * When enabled, all mobile data is reported under {@link NetworkIdentity#SUBTYPE_COMBINED}.
+         * When disabled, mobile data is broken down by a granular subtype representative of the
+         * actual subtype. {@see NetworkTemplate#getCollapsedRatType}.
+         * Enabling this decreases the level of detail but saves performance, disk space and
+         * amount of data logged.
+         */
+        boolean getCombineSubtypeEnabled();
 
-        public static class Config {
+        class Config {
             public final long bucketDuration;
             public final long rotateAgeMillis;
             public final long deleteAgeMillis;
@@ -244,16 +265,16 @@
             }
         }
 
-        public Config getDevConfig();
-        public Config getXtConfig();
-        public Config getUidConfig();
-        public Config getUidTagConfig();
+        Config getDevConfig();
+        Config getXtConfig();
+        Config getUidConfig();
+        Config getUidTagConfig();
 
-        public long getGlobalAlertBytes(long def);
-        public long getDevPersistBytes(long def);
-        public long getXtPersistBytes(long def);
-        public long getUidPersistBytes(long def);
-        public long getUidTagPersistBytes(long def);
+        long getGlobalAlertBytes(long def);
+        long getDevPersistBytes(long def);
+        long getXtPersistBytes(long def);
+        long getUidPersistBytes(long def);
+        long getUidTagPersistBytes(long def);
     }
 
     private final Object mStatsLock = new Object();
@@ -278,6 +299,11 @@
     @GuardedBy("mStatsLock")
     private Network[] mDefaultNetworks = new Network[0];
 
+    /** Last states of all networks sent from ConnectivityService. */
+    @GuardedBy("mStatsLock")
+    @Nullable
+    private NetworkState[] mLastNetworkStates = null;
+
     private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
             new DropBoxNonMonotonicObserver();
 
@@ -353,6 +379,12 @@
                     performPoll(FLAG_PERSIST_ALL);
                     break;
                 }
+                case MSG_UPDATE_IFACES: {
+                    // If no cached states, ignore.
+                    if (mLastNetworkStates == null) break;
+                    updateIfaces(mDefaultNetworks, mLastNetworkStates, mActiveIface);
+                    break;
+                }
                 case MSG_PERFORM_POLL_REGISTER_ALERT: {
                     performPoll(FLAG_PERSIST_NETWORK);
                     registerGlobalAlert();
@@ -405,6 +437,7 @@
         final HandlerThread handlerThread = mDeps.makeHandlerThread();
         handlerThread.start();
         mHandler = new NetworkStatsHandler(handlerThread.getLooper());
+        mPhoneListener = new NetworkTypeListener(new HandlerExecutor(mHandler));
     }
 
     /**
@@ -484,6 +517,13 @@
         mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
                 mSettings.getPollInterval(), pollIntent);
 
+        // TODO: 1. listen to changes from all subscriptions.
+        //       2. listen to settings changed to support dynamically enable/disable.
+        // watch for networkType changes
+        if (!mSettings.getCombineSubtypeEnabled()) {
+            mTeleManager.listen(mPhoneListener, LISTEN_SERVICE_STATE);
+        }
+
         registerGlobalAlert();
     }
 
@@ -504,6 +544,8 @@
         mContext.unregisterReceiver(mUserReceiver);
         mContext.unregisterReceiver(mShutdownReceiver);
 
+        mTeleManager.listen(mPhoneListener, LISTEN_NONE);
+
         final long currentTime = mClock.millis();
 
         // persist any pending stats
@@ -556,7 +598,7 @@
         } catch (RemoteException e) {
             // ignored; service lives in system_server
         }
-        invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setAlert(mGlobalAlertBytes));
+        invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetAlert(mGlobalAlertBytes));
     }
 
     @Override
@@ -757,7 +799,7 @@
         final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
 
         final NetworkStats stats = new NetworkStats(end - start, 1);
-        stats.addEntry(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
+        stats.insertEntry(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
                 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets,
                 entry.txBytes, entry.txPackets, entry.operations));
         return stats;
@@ -1154,6 +1196,38 @@
         }
     };
 
+    /**
+     * Receiver that watches for {@link TelephonyManager} changes, such as
+     * transitioning between Radio Access Technology(RAT) types.
+     */
+    @NonNull
+    private final NetworkTypeListener mPhoneListener;
+
+    class NetworkTypeListener extends PhoneStateListener {
+        private volatile int mLastCollapsedRatType = NETWORK_TYPE_UNKNOWN;
+
+        NetworkTypeListener(@NonNull Executor executor) {
+            super(executor);
+        }
+
+        @Override
+        public void onServiceStateChanged(@NonNull ServiceState ss) {
+            final int networkType = ss.getDataNetworkType();
+            final int collapsedRatType = getCollapsedRatType(networkType);
+            if (collapsedRatType == mLastCollapsedRatType) return;
+
+            if (LOGD) {
+                Log.d(TAG, "subtype changed for mobile: "
+                        + mLastCollapsedRatType + " -> " + collapsedRatType);
+            }
+            // Protect service from frequently updating. Remove pending messages if any.
+            mHandler.removeMessages(MSG_UPDATE_IFACES);
+            mLastCollapsedRatType = collapsedRatType;
+            mHandler.sendMessageDelayed(
+                    mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay());
+        }
+    }
+
     private void updateIfaces(
             Network[] defaultNetworks,
             NetworkState[] networkStates,
@@ -1175,7 +1249,8 @@
      * they are combined under a single {@link NetworkIdentitySet}.
      */
     @GuardedBy("mStatsLock")
-    private void updateIfacesLocked(Network[] defaultNetworks, NetworkState[] states) {
+    private void updateIfacesLocked(@Nullable Network[] defaultNetworks,
+            @NonNull NetworkState[] states) {
         if (!mSystemReady) return;
         if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
 
@@ -1195,13 +1270,18 @@
             mDefaultNetworks = defaultNetworks;
         }
 
+        mLastNetworkStates = states;
+
+        final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled();
         final ArraySet<String> mobileIfaces = new ArraySet<>();
         for (NetworkState state : states) {
             if (state.networkInfo.isConnected()) {
                 final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType());
                 final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network);
+                final int subType = combineSubtypeEnabled ? SUBTYPE_COMBINED
+                        : getSubTypeForState(state);
                 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
-                        isDefault);
+                        isDefault, subType);
 
                 // Traffic occurring on the base interface is always counted for
                 // both total usage and UID details.
@@ -1262,6 +1342,20 @@
         mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]);
     }
 
+    /**
+     * For networks with {@code TRANSPORT_CELLULAR}, get subType that was obtained through
+     * {@link PhoneStateListener}. Otherwise, return 0 given that other networks with different
+     * transport types do not actually fill this value.
+     */
+    private int getSubTypeForState(@NonNull NetworkState state) {
+        if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
+            return 0;
+        }
+
+        // TODO: return different subType for different subscriptions.
+        return mPhoneListener.mLastCollapsedRatType;
+    }
+
     private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
             ArrayMap<K, NetworkIdentitySet> map, K key) {
         NetworkIdentitySet ident = map.get(key);
@@ -1374,7 +1468,8 @@
         Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate");
         final int registeredCallbackCount = mStatsProviderCbList.getRegisteredCallbackCount();
         mStatsProviderSem.drainPermits();
-        invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.requestStatsUpdate(0 /* unused */));
+        invokeForAllStatsProviderCallbacks(
+                (cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */));
         try {
             mStatsProviderSem.tryAcquire(registeredCallbackCount,
                     MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS);
@@ -1549,7 +1644,7 @@
         @Override
         public void setStatsProviderLimitAsync(@NonNull String iface, long quota) {
             Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")");
-            invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setLimit(iface, quota));
+            invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetLimit(iface, quota));
         }
     }
 
@@ -1614,6 +1709,12 @@
                 return;
             }
 
+            pw.println("Configs:");
+            pw.increaseIndent();
+            pw.printPair(NETSTATS_COMBINE_SUBTYPE_ENABLED, mSettings.getCombineSubtypeEnabled());
+            pw.println();
+            pw.decreaseIndent();
+
             pw.println("Active interfaces:");
             pw.increaseIndent();
             for (int i = 0; i < mActiveIfaces.size(); i++) {
@@ -1793,6 +1894,24 @@
         }
     }
 
+    // TODO: It is copied from ConnectivityService, consider refactor these check permission
+    //  functions to a proper util.
+    private boolean checkAnyPermissionOf(String... permissions) {
+        for (String permission : permissions) {
+            if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void enforceAnyPermissionOf(String... permissions) {
+        if (!checkAnyPermissionOf(permissions)) {
+            throw new SecurityException("Requires one of the following permissions: "
+                    + String.join(", ", permissions) + ".");
+        }
+    }
+
     /**
      * Registers a custom provider of {@link android.net.NetworkStats} to combine the network
      * statistics that cannot be seen by the kernel to system. To unregister, invoke the
@@ -1800,16 +1919,15 @@
      *
      * @param tag a human readable identifier of the custom network stats provider.
      * @param provider the {@link INetworkStatsProvider} binder corresponding to the
-     *                 {@link android.net.netstats.provider.AbstractNetworkStatsProvider} to be
-     *                 registered.
+     *                 {@link NetworkStatsProvider} to be registered.
      *
-     * @return a binder interface of
-     *         {@link android.net.netstats.provider.NetworkStatsProviderCallback}, which can be
-     *         used to report events to the system.
+     * @return a {@link INetworkStatsProviderCallback} binder
+     *         interface, which can be used to report events to the system.
      */
     public @NonNull INetworkStatsProviderCallback registerNetworkStatsProvider(
             @NonNull String tag, @NonNull INetworkStatsProvider provider) {
-        mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG);
+        enforceAnyPermissionOf(NETWORK_STATS_PROVIDER,
+                NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
         Objects.requireNonNull(provider, "provider is null");
         Objects.requireNonNull(tag, "tag is null");
         try {
@@ -1910,7 +2028,7 @@
         }
 
         @Override
-        public void onStatsUpdated(int token, @Nullable NetworkStats ifaceStats,
+        public void notifyStatsUpdated(int token, @Nullable NetworkStats ifaceStats,
                 @Nullable NetworkStats uidStats) {
             // TODO: 1. Use token to map ifaces to correct NetworkIdentity.
             //       2. Store the difference and store it directly to the recorder.
@@ -1922,12 +2040,12 @@
         }
 
         @Override
-        public void onAlertReached() throws RemoteException {
+        public void notifyAlertReached() throws RemoteException {
             mAlertObserver.limitReached(LIMIT_GLOBAL_ALERT, null /* unused */);
         }
 
         @Override
-        public void onLimitReached() {
+        public void notifyLimitReached() {
             Log.d(TAG, mTag + ": onLimitReached");
             LocalServices.getService(NetworkPolicyManagerInternal.class)
                     .onStatsProviderLimitReached(mTag);
@@ -2025,6 +2143,10 @@
             return getGlobalBoolean(NETSTATS_AUGMENT_ENABLED, true);
         }
         @Override
+        public boolean getCombineSubtypeEnabled() {
+            return getGlobalBoolean(NETSTATS_COMBINE_SUBTYPE_ENABLED, false);
+        }
+        @Override
         public Config getDevConfig() {
             return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
                     getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index ebc4191..0e3268b 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -844,13 +844,13 @@
             final boolean policyChanged = !Objects.equals(getNotificationPolicy(mConfig),
                     getNotificationPolicy(config));
             if (!config.equals(mConfig)) {
+                mConfig = config;
                 dispatchOnConfigChanged();
                 updateConsolidatedPolicy(reason);
             }
             if (policyChanged) {
                 dispatchOnPolicyChanged();
             }
-            mConfig = config;
             mHandler.postApplyConfig(config, reason, triggeringComponent, setRingerMode);
             return true;
         } catch (SecurityException e) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index fd8db4b..b217dce 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -26,7 +26,6 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PackageDeleteObserver;
-import android.app.PackageInstallObserver;
 import android.app.admin.DevicePolicyEventLogger;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.content.Context;
@@ -994,73 +993,56 @@
         }
     }
 
-    static class PackageInstallObserverAdapter extends PackageInstallObserver {
-        private final Context mContext;
-        private final IntentSender mTarget;
-        private final int mSessionId;
-        private final boolean mShowNotification;
-        private final int mUserId;
-
-        public PackageInstallObserverAdapter(Context context, IntentSender target, int sessionId,
-                boolean showNotification, int userId) {
-            mContext = context;
-            mTarget = target;
-            mSessionId = sessionId;
-            mShowNotification = showNotification;
-            mUserId = userId;
+    static void sendOnUserActionRequired(Context context, IntentSender target, int sessionId,
+            Intent intent) {
+        final Intent fillIn = new Intent();
+        fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
+        fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
+                PackageInstaller.STATUS_PENDING_USER_ACTION);
+        fillIn.putExtra(Intent.EXTRA_INTENT, intent);
+        try {
+            target.sendIntent(context, 0, fillIn, null, null);
+        } catch (SendIntentException ignored) {
         }
+    }
 
-        @Override
-        public void onUserActionRequired(Intent intent) {
-            final Intent fillIn = new Intent();
-            fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId);
-            fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
-                    PackageInstaller.STATUS_PENDING_USER_ACTION);
-            fillIn.putExtra(Intent.EXTRA_INTENT, intent);
-            try {
-                mTarget.sendIntent(mContext, 0, fillIn, null, null);
-            } catch (SendIntentException ignored) {
+    static void sendOnPackageInstalled(Context context, IntentSender target, int sessionId,
+            boolean showNotification, int userId, String basePackageName, int returnCode,
+            String msg, Bundle extras) {
+        if (PackageManager.INSTALL_SUCCEEDED == returnCode && showNotification) {
+            boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING);
+            Notification notification = buildSuccessNotification(context,
+                    context.getResources()
+                            .getString(update ? R.string.package_updated_device_owner :
+                                    R.string.package_installed_device_owner),
+                    basePackageName,
+                    userId);
+            if (notification != null) {
+                NotificationManager notificationManager = (NotificationManager)
+                        context.getSystemService(Context.NOTIFICATION_SERVICE);
+                notificationManager.notify(basePackageName,
+                        SystemMessage.NOTE_PACKAGE_STATE,
+                        notification);
             }
         }
-
-        @Override
-        public void onPackageInstalled(String basePackageName, int returnCode, String msg,
-                Bundle extras) {
-            if (PackageManager.INSTALL_SUCCEEDED == returnCode && mShowNotification) {
-                boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING);
-                Notification notification = buildSuccessNotification(mContext,
-                        mContext.getResources()
-                                .getString(update ? R.string.package_updated_device_owner :
-                                        R.string.package_installed_device_owner),
-                        basePackageName,
-                        mUserId);
-                if (notification != null) {
-                    NotificationManager notificationManager = (NotificationManager)
-                            mContext.getSystemService(Context.NOTIFICATION_SERVICE);
-                    notificationManager.notify(basePackageName,
-                            SystemMessage.NOTE_PACKAGE_STATE,
-                            notification);
-                }
+        final Intent fillIn = new Intent();
+        fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName);
+        fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
+        fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
+                PackageManager.installStatusToPublicStatus(returnCode));
+        fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
+                PackageManager.installStatusToString(returnCode, msg));
+        fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode);
+        if (extras != null) {
+            final String existing = extras.getString(
+                    PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE);
+            if (!TextUtils.isEmpty(existing)) {
+                fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing);
             }
-            final Intent fillIn = new Intent();
-            fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, basePackageName);
-            fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId);
-            fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
-                    PackageManager.installStatusToPublicStatus(returnCode));
-            fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
-                    PackageManager.installStatusToString(returnCode, msg));
-            fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode);
-            if (extras != null) {
-                final String existing = extras.getString(
-                        PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE);
-                if (!TextUtils.isEmpty(existing)) {
-                    fillIn.putExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME, existing);
-                }
-            }
-            try {
-                mTarget.sendIntent(mContext, 0, fillIn, null, null);
-            } catch (SendIntentException ignored) {
-            }
+        }
+        try {
+            target.sendIntent(context, 0, fillIn, null, null);
+        } catch (SendIntentException ignored) {
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 7091c7c..6f6c315 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -18,7 +18,6 @@
 
 import static android.content.pm.PackageManager.INSTALL_FAILED_ABORTED;
 import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_SIGNATURE;
-import static android.content.pm.PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
@@ -79,7 +78,6 @@
 import android.os.ParcelFileDescriptor;
 import android.os.ParcelableException;
 import android.os.Process;
-import android.os.RemoteException;
 import android.os.RevocableFileDescriptor;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -107,7 +105,6 @@
 import com.android.internal.util.Preconditions;
 import com.android.server.LocalServices;
 import com.android.server.pm.Installer.InstallerException;
-import com.android.server.pm.PackageInstallerService.PackageInstallObserverAdapter;
 import com.android.server.pm.dex.DexManager;
 import com.android.server.security.VerityUtils;
 
@@ -131,7 +128,7 @@
 public class PackageInstallerSession extends IPackageInstallerSession.Stub {
     private static final String TAG = "PackageInstallerSession";
     private static final boolean LOGD = true;
-    private static final String REMOVE_SPLIT_MARKER_EXTENSION = ".removed";
+    private static final String REMOVE_MARKER_EXTENSION = ".removed";
 
     private static final int MSG_COMMIT = 1;
     private static final int MSG_ON_PACKAGE_INSTALLED = 2;
@@ -257,7 +254,7 @@
     private final ArrayList<FileBridge> mBridges = new ArrayList<>();
 
     @GuardedBy("mLock")
-    private IPackageInstallObserver2 mRemoteObserver;
+    private IntentSender mRemoteStatusReceiver;
 
     /** Fields derived from commit parsing */
     @GuardedBy("mLock")
@@ -294,9 +291,6 @@
     private File mResolvedBaseFile;
 
     @GuardedBy("mLock")
-    private File mResolvedStageDir;
-
-    @GuardedBy("mLock")
     private final List<File> mResolvedStagedFiles = new ArrayList<>();
     @GuardedBy("mLock")
     private final List<File> mResolvedInheritedFiles = new ArrayList<>();
@@ -315,7 +309,7 @@
             // Installers can't stage directories, so it's fine to ignore
             // entries like "lost+found".
             if (file.isDirectory()) return false;
-            if (file.getName().endsWith(REMOVE_SPLIT_MARKER_EXTENSION)) return false;
+            if (file.getName().endsWith(REMOVE_MARKER_EXTENSION)) return false;
             if (DexMetadataHelper.isDexMetadataFile(file)) return false;
             if (VerityUtils.isFsveritySignatureFile(file)) return false;
             return true;
@@ -325,7 +319,7 @@
         @Override
         public boolean accept(File file) {
             if (file.isDirectory()) return false;
-            if (!file.getName().endsWith(REMOVE_SPLIT_MARKER_EXTENSION)) return false;
+            if (!file.getName().endsWith(REMOVE_MARKER_EXTENSION)) return false;
             return true;
         }
     };
@@ -342,14 +336,14 @@
                     final String packageName = (String) args.arg1;
                     final String message = (String) args.arg2;
                     final Bundle extras = (Bundle) args.arg3;
-                    final IPackageInstallObserver2 observer = (IPackageInstallObserver2) args.arg4;
+                    final IntentSender statusReceiver = (IntentSender) args.arg4;
                     final int returnCode = args.argi1;
                     args.recycle();
 
-                    try {
-                        observer.onPackageInstalled(packageName, returnCode, message, extras);
-                    } catch (RemoteException ignored) {
-                    }
+                    PackageInstallerService.sendOnPackageInstalled(mContext,
+                            statusReceiver, sessionId,
+                            isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId,
+                            packageName, returnCode, message, extras);
 
                     break;
             }
@@ -559,23 +553,6 @@
         }
     }
 
-    /**
-     * Resolve the actual location where staged data should be written. This
-     * might point at an ASEC mount point, which is why we delay path resolution
-     * until someone actively works with the session.
-     */
-    @GuardedBy("mLock")
-    private File resolveStageDirLocked() throws IOException {
-        if (mResolvedStageDir == null) {
-            if (stageDir != null) {
-                mResolvedStageDir = stageDir;
-            } else {
-                throw new IOException("Missing stageDir");
-            }
-        }
-        return mResolvedStageDir;
-    }
-
     @Override
     public void setClientProgress(float progress) {
         synchronized (mLock) {
@@ -615,14 +592,32 @@
             assertCallerIsOwnerOrRootLocked();
             assertPreparedAndNotCommittedOrDestroyedLocked("getNames");
 
-            try {
-                return resolveStageDirLocked().list();
-            } catch (IOException e) {
-                throw ExceptionUtils.wrap(e);
-            }
+            return getNamesLocked();
         }
     }
 
+    @GuardedBy("mLock")
+    private String[] getNamesLocked() {
+        return stageDir.list();
+    }
+
+    private static File[] filterFiles(File parent, String[] names, FileFilter filter) {
+        return Arrays.stream(names).map(name -> new File(parent, name)).filter(
+                file -> filter.accept(file)).toArray(File[]::new);
+    }
+
+    @GuardedBy("mLock")
+    private File[] getAddedFilesLocked() {
+        String[] names = getNamesLocked();
+        return filterFiles(stageDir, names, sAddedFilter);
+    }
+
+    @GuardedBy("mLock")
+    private File[] getRemovedFilesLocked() {
+        String[] names = getNamesLocked();
+        return filterFiles(stageDir, names, sRemovedFilter);
+    }
+
     @Override
     public void removeSplit(String splitName) {
         if (TextUtils.isEmpty(params.appPackageName)) {
@@ -641,13 +636,17 @@
         }
     }
 
+    private static String getRemoveMarkerName(String name) {
+        final String markerName = name + REMOVE_MARKER_EXTENSION;
+        if (!FileUtils.isValidExtFilename(markerName)) {
+            throw new IllegalArgumentException("Invalid marker: " + markerName);
+        }
+        return markerName;
+    }
+
     private void createRemoveSplitMarkerLocked(String splitName) throws IOException {
         try {
-            final String markerName = splitName + REMOVE_SPLIT_MARKER_EXTENSION;
-            if (!FileUtils.isValidExtFilename(markerName)) {
-                throw new IllegalArgumentException("Invalid marker: " + markerName);
-            }
-            final File target = new File(resolveStageDirLocked(), markerName);
+            final File target = new File(stageDir, getRemoveMarkerName(splitName));
             target.createNewFile();
             Os.chmod(target.getAbsolutePath(), 0 /*mode*/);
         } catch (ErrnoException e) {
@@ -681,7 +680,6 @@
         // will block any attempted install transitions.
         final RevocableFileDescriptor fd;
         final FileBridge bridge;
-        final File stageDir;
         synchronized (mLock) {
             assertCallerIsOwnerOrRootLocked();
             assertPreparedAndNotSealedLocked("openWrite");
@@ -695,8 +693,6 @@
                 bridge = new FileBridge();
                 mBridges.add(bridge);
             }
-
-            stageDir = resolveStageDirLocked();
         }
 
         try {
@@ -802,7 +798,7 @@
             if (!FileUtils.isValidExtFilename(name)) {
                 throw new IllegalArgumentException("Invalid name: " + name);
             }
-            final File target = new File(resolveStageDirLocked(), name);
+            final File target = new File(stageDir, name);
             final FileDescriptor targetFd = Os.open(target.getAbsolutePath(), O_RDONLY, 0);
             return new ParcelFileDescriptor(targetFd);
         } catch (ErrnoException e) {
@@ -948,7 +944,7 @@
      * This method may be called multiple times to update the status receiver validate caller
      * permissions.
      */
-    public boolean markAsCommitted(
+    private boolean markAsCommitted(
             @NonNull IntentSender statusReceiver, boolean forTransfer) {
         Preconditions.checkNotNull(statusReceiver);
 
@@ -959,10 +955,7 @@
             assertCallerIsOwnerOrRootLocked();
             assertPreparedAndNotDestroyedLocked("commit");
 
-            final PackageInstallObserverAdapter adapter = new PackageInstallObserverAdapter(
-                    mContext, statusReceiver, sessionId,
-                    isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId);
-            mRemoteObserver = adapter.getBinder();
+            mRemoteStatusReceiver = statusReceiver;
 
             if (forTransfer) {
                 mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, null);
@@ -986,12 +979,7 @@
             if (!mSealed) {
                 try {
                     sealAndValidateLocked(childSessions);
-                } catch (IOException e) {
-                    throw new IllegalArgumentException(e);
                 } catch (PackageManagerException e) {
-                    // Do now throw an exception here to stay compatible with O and older
-                    destroyInternal();
-                    dispatchSessionFinished(e.error, ExceptionUtils.getCompleteMessage(e), null);
                     return false;
                 }
             }
@@ -1091,52 +1079,50 @@
      */
     @GuardedBy("mLock")
     private void sealAndValidateLocked(List<PackageInstallerSession> childSessions)
-            throws PackageManagerException, IOException {
-        assertNoWriteFileTransfersOpenLocked();
-        assertPreparedAndNotDestroyedLocked("sealing of session");
+            throws PackageManagerException {
+        try {
+            assertNoWriteFileTransfersOpenLocked();
+            assertPreparedAndNotDestroyedLocked("sealing of session");
 
-        mSealed = true;
+            mSealed = true;
 
-        if (childSessions != null) {
-            assertMultiPackageConsistencyLocked(childSessions);
-        }
-
-        if (params.isStaged) {
-            final PackageInstallerSession activeSession = mStagingManager.getActiveSession();
-            final boolean anotherSessionAlreadyInProgress =
-                    activeSession != null && sessionId != activeSession.sessionId
-                            && mParentSessionId != activeSession.sessionId;
-            if (anotherSessionAlreadyInProgress) {
-                throw new PackageManagerException(
-                        PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
-                        "There is already in-progress committed staged session "
-                                + activeSession.sessionId, null);
+            if (childSessions != null) {
+                assertMultiPackageConsistencyLocked(childSessions);
             }
-        }
 
-        // Read transfers from the original owner stay open, but as the session's data
-        // cannot be modified anymore, there is no leak of information. For staged sessions,
-        // further validation is performed by the staging manager.
-        if (!params.isMultiPackage) {
-            final PackageInfo pkgInfo = mPm.getPackageInfo(
-                    params.appPackageName, PackageManager.GET_SIGNATURES
-                            | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId);
+            // Read transfers from the original owner stay open, but as the session's data
+            // cannot be modified anymore, there is no leak of information. For staged sessions,
+            // further validation is performed by the staging manager.
+            if (!params.isMultiPackage) {
+                final PackageInfo pkgInfo = mPm.getPackageInfo(
+                        params.appPackageName, PackageManager.GET_SIGNATURES
+                                | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId);
 
-            resolveStageDirLocked();
-
-            try {
-                if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
-                    validateApexInstallLocked();
-                } else {
-                    validateApkInstallLocked(pkgInfo);
+                try {
+                    if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
+                        validateApexInstallLocked();
+                    } else {
+                        validateApkInstallLocked(pkgInfo);
+                    }
+                } catch (PackageManagerException e) {
+                    throw e;
+                } catch (Throwable e) {
+                    // Convert all exceptions into package manager exceptions as only those are
+                    // handled in the code above.
+                    throw new PackageManagerException(e);
                 }
-            } catch (PackageManagerException e) {
-                throw e;
-            } catch (Throwable e) {
-                // Convert all exceptions into package manager exceptions as only those are handled
-                // in the code above
-                throw new PackageManagerException(e);
             }
+
+            if (params.isStaged) {
+                mStagingManager.checkNonOverlappingWithStagedSessions(this);
+            }
+        } catch (PackageManagerException e) {
+            // Session is sealed but could not be verified, we need to destroy it.
+            destroyInternal();
+            // Dispatch message to remove session from PackageInstallerService
+            dispatchSessionFinished(
+                    e.error, ExceptionUtils.getCompleteMessage(e), null);
+            throw e;
         }
     }
 
@@ -1159,15 +1145,8 @@
         synchronized (mLock) {
             try {
                 sealAndValidateLocked(childSessions);
-            } catch (IOException e) {
-                throw new IllegalStateException(e);
             } catch (PackageManagerException e) {
                 Slog.e(TAG, "Package not valid", e);
-                // Session is sealed but could not be verified, we need to destroy it.
-                destroyInternal();
-                // Dispatch message to remove session from PackageInstallerService
-                dispatchSessionFinished(
-                        e.error, ExceptionUtils.getCompleteMessage(e), null);
             }
         }
     }
@@ -1208,13 +1187,7 @@
 
             try {
                 sealAndValidateLocked(childSessions);
-            } catch (IOException e) {
-                throw new IllegalStateException(e);
             } catch (PackageManagerException e) {
-                // Session is sealed but could not be verified, we need to destroy it
-                destroyInternal();
-                dispatchSessionFinished(e.error, ExceptionUtils.getCompleteMessage(e), null);
-
                 throw new IllegalArgumentException("Package is not valid", e);
             }
 
@@ -1299,11 +1272,10 @@
                 }
             }
             if (!success) {
-                try {
-                    mRemoteObserver.onPackageInstalled(
-                            null, failure.error, failure.getLocalizedMessage(), null);
-                } catch (RemoteException ignored) {
-                }
+                PackageInstallerService.sendOnPackageInstalled(mContext,
+                        mRemoteStatusReceiver, sessionId,
+                        isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked(), userId, null,
+                        failure.error, failure.getLocalizedMessage(), null);
                 return;
             }
             mPm.installStage(activeChildSessions);
@@ -1347,10 +1319,9 @@
                     final Intent intent = new Intent(PackageInstaller.ACTION_CONFIRM_INSTALL);
                     intent.setPackage(mPm.getPackageInstallerPackageName());
                     intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
-                    try {
-                        mRemoteObserver.onUserActionRequired(intent);
-                    } catch (RemoteException ignored) {
-                    }
+
+                    PackageInstallerService.sendOnUserActionRequired(mContext,
+                            mRemoteStatusReceiver, sessionId, intent);
 
                     // Commit was keeping session marked as active until now; release
                     // that extra refcount so session appears idle.
@@ -1363,7 +1334,7 @@
                 if (params.mode == SessionParams.MODE_INHERIT_EXISTING) {
                     try {
                         final List<File> fromFiles = mResolvedInheritedFiles;
-                        final File toDir = resolveStageDirLocked();
+                        final File toDir = stageDir;
 
                         if (LOGD) Slog.d(TAG, "Inherited files: " + mResolvedInheritedFiles);
                         if (!mResolvedInheritedFiles.isEmpty() && mInheritedFilesBase == null) {
@@ -1413,8 +1384,7 @@
                 computeProgressLocked(true);
 
                 // Unpack native libraries
-                extractNativeLibraries(mResolvedStageDir, params.abiOverride,
-                        mayInheritNativeLibs());
+                extractNativeLibraries(stageDir, params.abiOverride, mayInheritNativeLibs());
             }
 
             // We've reached point of no return; call into PMS to install the stage.
@@ -1470,12 +1440,13 @@
     /**
      * Validate apex install.
      * <p>
-     * Sets {@link #mResolvedBaseFile} for RollbackManager to use.
+     * Sets {@link #mResolvedBaseFile} for RollbackManager to use. Sets {@link #mPackageName} for
+     * StagingManager to use.
      */
     @GuardedBy("mLock")
     private void validateApexInstallLocked()
             throws PackageManagerException {
-        final File[] addedFiles = mResolvedStageDir.listFiles(sAddedFilter);
+        final File[] addedFiles = getAddedFilesLocked();
         if (ArrayUtils.isEmpty(addedFiles)) {
             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged");
         }
@@ -1485,13 +1456,6 @@
                     "Too many files for apex install");
         }
 
-        try {
-            resolveStageDirLocked();
-        } catch (IOException e) {
-            throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
-                    "Failed to resolve stage location", e);
-        }
-
         File addedFile = addedFiles[0]; // there is only one file
 
         // Ensure file name has proper suffix
@@ -1504,10 +1468,24 @@
                     "Invalid filename: " + targetName);
         }
 
-        final File targetFile = new File(mResolvedStageDir, targetName);
+        final File targetFile = new File(stageDir, targetName);
         resolveAndStageFile(addedFile, targetFile);
-
         mResolvedBaseFile = targetFile;
+
+        // Populate package name of the apex session
+        mPackageName = null;
+        final ApkLite apk;
+        try {
+            apk = PackageParser.parseApkLite(
+                    mResolvedBaseFile, PackageParser.PARSE_COLLECT_CERTIFICATES);
+        } catch (PackageParserException e) {
+            throw PackageManagerException.from(e);
+        }
+
+        if (mPackageName == null) {
+            mPackageName = apk.packageName;
+            mVersionCode = apk.getLongVersionCode();
+        }
     }
 
     /**
@@ -1545,25 +1523,18 @@
                 && params.mode == SessionParams.MODE_INHERIT_EXISTING
                 && VerityUtils.hasFsverity(pkgInfo.applicationInfo.getBaseCodePath());
 
-        try {
-            resolveStageDirLocked();
-        } catch (IOException e) {
-            throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
-                    "Failed to resolve stage location", e);
-        }
-
-        final File[] removedFiles = mResolvedStageDir.listFiles(sRemovedFilter);
+        final File[] removedFiles = getRemovedFilesLocked();
         final List<String> removeSplitList = new ArrayList<>();
         if (!ArrayUtils.isEmpty(removedFiles)) {
             for (File removedFile : removedFiles) {
                 final String fileName = removedFile.getName();
                 final String splitName = fileName.substring(
-                        0, fileName.length() - REMOVE_SPLIT_MARKER_EXTENSION.length());
+                        0, fileName.length() - REMOVE_MARKER_EXTENSION.length());
                 removeSplitList.add(splitName);
             }
         }
 
-        final File[] addedFiles = mResolvedStageDir.listFiles(sAddedFilter);
+        final File[] addedFiles = getAddedFilesLocked();
         if (ArrayUtils.isEmpty(addedFiles) && removeSplitList.size() == 0) {
             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged");
         }
@@ -1607,7 +1578,7 @@
                         "Invalid filename: " + targetName);
             }
 
-            final File targetFile = new File(mResolvedStageDir, targetName);
+            final File targetFile = new File(stageDir, targetName);
             resolveAndStageFile(addedFile, targetFile);
 
             // Base is coming from session
@@ -1622,7 +1593,7 @@
                     throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
                             "Invalid filename: " + dexMetadataFile);
                 }
-                final File targetDexMetadataFile = new File(mResolvedStageDir,
+                final File targetDexMetadataFile = new File(stageDir,
                         DexMetadataHelper.buildDexMetadataPathForApk(targetName));
                 resolveAndStageFile(dexMetadataFile, targetDexMetadataFile);
             }
@@ -1883,6 +1854,15 @@
     }
 
     /**
+     * @return the package name of this session
+     */
+    String getPackageName() {
+        synchronized (mLock) {
+            return mPackageName;
+        }
+    }
+
+    /**
      * @return the timestamp of when this session last changed state
      */
     public long getUpdatedMillis() {
@@ -2182,17 +2162,17 @@
     }
 
     private void dispatchSessionFinished(int returnCode, String msg, Bundle extras) {
-        final IPackageInstallObserver2 observer;
+        final IntentSender statusReceiver;
         final String packageName;
         synchronized (mLock) {
             mFinalStatus = returnCode;
             mFinalMessage = msg;
 
-            observer = mRemoteObserver;
+            statusReceiver = mRemoteStatusReceiver;
             packageName = mPackageName;
         }
 
-        if (observer != null) {
+        if (statusReceiver != null) {
             // Execute observer.onPackageInstalled on different tread as we don't want callers
             // inside the system server have to worry about catching the callbacks while they are
             // calling into the session
@@ -2200,7 +2180,7 @@
             args.arg1 = packageName;
             args.arg2 = msg;
             args.arg3 = extras;
-            args.arg4 = observer;
+            args.arg4 = statusReceiver;
             args.argi1 = returnCode;
 
             mHandler.obtainMessage(MSG_ON_PACKAGE_INSTALLED, args).sendToTarget();
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 8cc66b2..96ccba5 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -39,6 +39,8 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.ParcelableException;
 import android.os.PowerManager;
@@ -59,6 +61,7 @@
 import java.util.List;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
@@ -73,7 +76,7 @@
     private final PackageInstallerService mPi;
     private final ApexManager mApexManager;
     private final PowerManager mPowerManager;
-    private final Handler mBgHandler;
+    private final PreRebootVerificationHandler mPreRebootVerificationHandler;
 
     @GuardedBy("mStagedSessions")
     private final SparseArray<PackageInstallerSession> mStagedSessions = new SparseArray<>();
@@ -82,7 +85,8 @@
         mPi = pi;
         mApexManager = am;
         mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-        mBgHandler = BackgroundThread.getHandler();
+        mPreRebootVerificationHandler = new PreRebootVerificationHandler(
+                BackgroundThread.get().getLooper());
     }
 
     private void updateStoredSession(@NonNull PackageInstallerSession sessionInfo) {
@@ -110,18 +114,17 @@
      * Validates the signature used to sign the container of the new apex package
      *
      * @param newApexPkg The new apex package that is being installed
-     * @param installFlags flags related to the session
      * @throws PackageManagerException
      */
-    private void validateApexSignature(PackageInfo newApexPkg, int installFlags)
+    private void validateApexSignature(PackageInfo newApexPkg)
             throws PackageManagerException {
         // Get signing details of the new package
         final String apexPath = newApexPkg.applicationInfo.sourceDir;
         final String packageName = newApexPkg.packageName;
 
-        final SigningDetails signingDetails;
+        final SigningDetails newSigningDetails;
         try {
-            signingDetails = ApkSignatureVerifier.verify(apexPath, SignatureSchemeVersion.JAR);
+            newSigningDetails = ApkSignatureVerifier.verify(apexPath, SignatureSchemeVersion.JAR);
         } catch (PackageParserException e) {
             throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
                     "Failed to parse APEX package " + apexPath, e);
@@ -146,8 +149,10 @@
         }
 
         // Verify signing details for upgrade
-        if (signingDetails.checkCapability(existingSigningDetails,
-                PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)) {
+        if (newSigningDetails.checkCapability(existingSigningDetails,
+                SigningDetails.CertCapabilities.INSTALLED_DATA)
+                || existingSigningDetails.checkCapability(newSigningDetails,
+                SigningDetails.CertCapabilities.ROLLBACK)) {
             return;
         }
 
@@ -242,75 +247,6 @@
         return (session.params.installFlags & PackageManager.INSTALL_APEX) != 0;
     }
 
-    private void preRebootVerification(@NonNull PackageInstallerSession session) {
-        Slog.d(TAG, "Starting preRebootVerification for session " + session.sessionId);
-        final boolean hasApex = sessionContainsApex(session);
-        // APEX checks. For single-package sessions, check if they contain an APEX. For
-        // multi-package sessions, find all the child sessions that contain an APEX.
-        if (hasApex) {
-            try {
-                final List<PackageInfo> apexPackages = submitSessionToApexService(session);
-                for (PackageInfo apexPackage : apexPackages) {
-                    validateApexSignature(apexPackage, session.params.installFlags);
-                }
-            } catch (PackageManagerException e) {
-                session.setStagedSessionFailed(e.error, e.getMessage());
-                return;
-            }
-        }
-
-        if (sessionContainsApk(session)) {
-            try {
-                Slog.d(TAG, "Running a pre-reboot verification for APKs in session "
-                        + session.sessionId + " by performing a dry-run install");
-                installApksInSession(session, /* preReboot */ true);
-                // TODO(b/118865310): abort the session on apexd.
-            } catch (PackageManagerException e) {
-                session.setStagedSessionFailed(e.error, e.getMessage());
-                return;
-            }
-        }
-
-        if ((session.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
-            // If rollback is enabled for this session, we call through to the RollbackManager
-            // with the list of sessions it must enable rollback for. Note that notifyStagedSession
-            // is a synchronous operation.
-            final IRollbackManager rm = IRollbackManager.Stub.asInterface(
-                    ServiceManager.getService(Context.ROLLBACK_SERVICE));
-            try {
-                // NOTE: To stay consistent with the non-staged install flow, we don't fail the
-                // entire install if rollbacks can't be enabled.
-                if (!rm.notifyStagedSession(session.sessionId)) {
-                    Slog.e(TAG, "Unable to enable rollback for session: " + session.sessionId);
-                }
-            } catch (RemoteException re) {
-                // Cannot happen, the rollback manager is in the same process.
-            }
-        }
-
-        // Proactively mark session as ready before calling apexd. Although this call order looks
-        // counter-intuitive, this is the easiest way to ensure that session won't end up in the
-        // inconsistent state:
-        //  - If device gets rebooted right before call to apexd, then apexd will never activate
-        //      apex files of this staged session. This will result in StagingManager failing the
-        //      session.
-        // On the other hand, if the order of the calls was inverted (first call apexd, then mark
-        // session as ready), then if a device gets rebooted right after the call to apexd, only
-        // apex part of the train will be applied, leaving device in an inconsistent state.
-        Slog.d(TAG, "Marking session " + session.sessionId + " as ready");
-        session.setStagedSessionReady();
-        if (!hasApex) {
-            // Session doesn't contain apex, nothing to do.
-            return;
-        }
-        try {
-            mApexManager.markStagedSessionReady(session.sessionId);
-        } catch (PackageManagerException e) {
-            session.setStagedSessionFailed(e.error, e.getMessage());
-        }
-    }
-
-
     private boolean sessionContains(@NonNull PackageInstallerSession session,
                                     Predicate<PackageInstallerSession> filter) {
         if (!session.isMultiPackage()) {
@@ -359,7 +295,7 @@
                 // Greedily re-trigger the pre-reboot verification.
                 Slog.d(TAG, "Found pending staged session " + session.sessionId + " still to be "
                         + "verified, resuming pre-reboot verification");
-                mBgHandler.post(() -> preRebootVerification(session));
+                mPreRebootVerificationHandler.startPreRebootVerification(session.sessionId);
                 return;
             }
             if (!apexSessionInfo.isActivated && !apexSessionInfo.isSuccess) {
@@ -376,7 +312,7 @@
         // The APEX part of the session is activated, proceed with the installation of APKs.
         try {
             Slog.d(TAG, "Installing APK packages in session " + session.sessionId);
-            installApksInSession(session, /* preReboot */ false);
+            installApksInSession(session);
         } catch (PackageManagerException e) {
             session.setStagedSessionFailed(e.error, e.getMessage());
 
@@ -467,53 +403,23 @@
         }
     }
 
-    private void commitApkSession(@NonNull PackageInstallerSession apkSession,
-            int originalSessionId, boolean preReboot) throws PackageManagerException {
-        final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED
-                : SessionInfo.STAGED_SESSION_ACTIVATION_FAILED;
-        if (!preReboot) {
-            if ((apkSession.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
-                // If rollback is available for this session, notify the rollback
-                // manager of the apk session so it can properly enable rollback.
-                final IRollbackManager rm = IRollbackManager.Stub.asInterface(
-                        ServiceManager.getService(Context.ROLLBACK_SERVICE));
-                try {
-                    rm.notifyStagedApkSession(originalSessionId, apkSession.sessionId);
-                } catch (RemoteException re) {
-                    // Cannot happen, the rollback manager is in the same process.
-                }
-            }
-        }
-
-        final LocalIntentReceiver receiver = new LocalIntentReceiver();
-        apkSession.commit(receiver.getIntentSender(), false);
-        final Intent result = receiver.getResult();
-        final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
-                PackageInstaller.STATUS_FAILURE);
-        if (status != PackageInstaller.STATUS_SUCCESS) {
-
-            final String errorMessage = result.getStringExtra(
-                    PackageInstaller.EXTRA_STATUS_MESSAGE);
-            Slog.e(TAG, "Failure to install APK staged session " + originalSessionId + " ["
-                    + errorMessage + "]");
-            throw new PackageManagerException(errorCode, errorMessage);
-        }
-    }
-
-    private void installApksInSession(@NonNull PackageInstallerSession session,
-                                         boolean preReboot) throws PackageManagerException {
+    /**
+     * Extract apks in the given session into a new session. Returns {@code null} if there is no
+     * apks in the given session. Only parent session is returned for multi-package session.
+     */
+    @Nullable
+    private PackageInstallerSession extractApksInSession(PackageInstallerSession session,
+            boolean preReboot) throws PackageManagerException {
         final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED
                 : SessionInfo.STAGED_SESSION_ACTIVATION_FAILED;
         if (!session.isMultiPackage() && !isApexSession(session)) {
-            // APK single-packaged staged session. Do a regular install.
-            PackageInstallerSession apkSession = createAndWriteApkSession(session, preReboot);
-            commitApkSession(apkSession, session.sessionId, preReboot);
+            return createAndWriteApkSession(session, preReboot);
         } else if (session.isMultiPackage()) {
             // For multi-package staged sessions containing APKs, we identify which child sessions
             // contain an APK, and with those then create a new multi-package group of sessions,
             // carrying over all the session parameters and unmarking them as staged. On commit the
             // sessions will be installed atomically.
-            List<PackageInstallerSession> childSessions;
+            final List<PackageInstallerSession> childSessions;
             synchronized (mStagedSessions) {
                 childSessions =
                         Arrays.stream(session.getChildSessionIds())
@@ -525,18 +431,18 @@
             }
             if (childSessions.isEmpty()) {
                 // APEX-only multi-package staged session, nothing to do.
-                return;
+                return null;
             }
-            PackageInstaller.SessionParams params = session.params.copy();
+            final PackageInstaller.SessionParams params = session.params.copy();
             params.isStaged = false;
             if (preReboot) {
                 params.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK;
             }
             // TODO(b/129744602): use the userid from the original session.
-            int apkParentSessionId = mPi.createSession(
+            final int apkParentSessionId = mPi.createSession(
                     params, session.getInstallerPackageName(),
                     0 /* UserHandle.SYSTEM */);
-            PackageInstallerSession apkParentSession = mPi.getSession(apkParentSessionId);
+            final PackageInstallerSession apkParentSession = mPi.getSession(apkParentSessionId);
             try {
                 apkParentSession.open();
             } catch (IOException e) {
@@ -557,35 +463,171 @@
                             "Failed to add a child session " + apkChildSession.sessionId);
                 }
             }
-            commitApkSession(apkParentSession, session.sessionId, preReboot);
+            return apkParentSession;
         }
-        // APEX single-package staged session, nothing to do.
+        return null;
+    }
+
+    private void verifyApksInSession(PackageInstallerSession session)
+            throws PackageManagerException {
+
+        final PackageInstallerSession apksToVerify = extractApksInSession(
+                session,  /* preReboot */ true);
+        if (apksToVerify == null) {
+            return;
+        }
+
+        final LocalIntentReceiverAsync receiver = new LocalIntentReceiverAsync(
+                (Intent result) -> {
+                    int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
+                            PackageInstaller.STATUS_FAILURE);
+                    if (status != PackageInstaller.STATUS_SUCCESS) {
+                        final String errorMessage = result.getStringExtra(
+                                PackageInstaller.EXTRA_STATUS_MESSAGE);
+                        Slog.e(TAG, "Failure to verify APK staged session "
+                                + session.sessionId + " [" + errorMessage + "]");
+                        session.setStagedSessionFailed(
+                                SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, errorMessage);
+                        return;
+                    }
+                    mPreRebootVerificationHandler.notifyPreRebootVerification_Apk_Complete(
+                            session.sessionId);
+                });
+
+        apksToVerify.commit(receiver.getIntentSender(), false);
+    }
+
+    private void installApksInSession(@NonNull PackageInstallerSession session)
+            throws PackageManagerException {
+
+        final PackageInstallerSession apksToInstall = extractApksInSession(
+                session, /* preReboot */ false);
+        if (apksToInstall == null) {
+            return;
+        }
+
+        if ((apksToInstall.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
+            // If rollback is available for this session, notify the rollback
+            // manager of the apk session so it can properly enable rollback.
+            final IRollbackManager rm = IRollbackManager.Stub.asInterface(
+                    ServiceManager.getService(Context.ROLLBACK_SERVICE));
+            try {
+                rm.notifyStagedApkSession(session.sessionId, apksToInstall.sessionId);
+            } catch (RemoteException re) {
+                Slog.e(TAG, "Failed to notifyStagedApkSession for session: "
+                        + session.sessionId, re);
+            }
+        }
+
+        final LocalIntentReceiverSync receiver = new LocalIntentReceiverSync();
+        apksToInstall.commit(receiver.getIntentSender(), false);
+        final Intent result = receiver.getResult();
+        final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
+                PackageInstaller.STATUS_FAILURE);
+        if (status != PackageInstaller.STATUS_SUCCESS) {
+            final String errorMessage = result.getStringExtra(
+                    PackageInstaller.EXTRA_STATUS_MESSAGE);
+            Slog.e(TAG, "Failure to install APK staged session "
+                    + session.sessionId + " [" + errorMessage + "]");
+            throw new PackageManagerException(
+                    SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, errorMessage);
+        }
     }
 
     void commitSession(@NonNull PackageInstallerSession session) {
         updateStoredSession(session);
-        mBgHandler.post(() -> preRebootVerification(session));
+        mPreRebootVerificationHandler.startPreRebootVerification(session.sessionId);
     }
 
-    @Nullable
-    PackageInstallerSession getActiveSession() {
+    /**
+     * <p> Check if the session provided is non-overlapping with the active staged sessions.
+     *
+     * <p> A session is non-overlapping if it meets one of the following conditions: </p>
+     * <ul>
+     *     <li>It is a parent session</li>
+     *     <li>It is already one of the active sessions</li>
+     *     <li>Its package name is not same as any of the active sessions</li>
+     * </ul>
+     * @throws PackageManagerException if session fails the check
+     */
+    void checkNonOverlappingWithStagedSessions(@NonNull PackageInstallerSession session)
+            throws PackageManagerException {
+        if (session.isMultiPackage()) {
+            // We cannot say a parent session overlaps until we process its children
+            return;
+        }
+        if (session.getPackageName() == null) {
+            throw new PackageManagerException(PackageManager.INSTALL_FAILED_INVALID_APK,
+                    "Cannot stage session " + session.sessionId + " with package name null");
+        }
+
         synchronized (mStagedSessions) {
             for (int i = 0; i < mStagedSessions.size(); i++) {
-                final PackageInstallerSession session = mStagedSessions.valueAt(i);
-                if (!session.isCommitted()) {
+                final PackageInstallerSession stagedSession = mStagedSessions.valueAt(i);
+                if (!stagedSession.isCommitted() || stagedSession.isStagedAndInTerminalState()) {
                     continue;
                 }
-                if (session.hasParentSessionId()) {
-                    // Staging manager will finalize only parent session. Ignore child sessions
-                    // picking the active.
+                if (stagedSession.isMultiPackage()) {
+                    // This active parent staged session is useless as it doesn't have a package
+                    // name and the session we are checking is not a parent session either.
                     continue;
                 }
-                if (!session.isStagedSessionApplied() && !session.isStagedSessionFailed()) {
-                    return session;
+
+                // From here on, stagedSession is a non-parent active staged session
+
+                // Check if stagedSession has an active parent session or not
+                if (stagedSession.hasParentSessionId()) {
+                    int parentId = stagedSession.getParentSessionId();
+                    PackageInstallerSession parentSession = mStagedSessions.get(parentId);
+                    if (parentSession == null || parentSession.isStagedAndInTerminalState()) {
+                        // Parent session has been abandoned or terminated already
+                        continue;
+                    }
+                }
+
+                // Check if session is one of the active sessions
+                if (session.sessionId == stagedSession.sessionId) {
+                    Slog.w(TAG, "Session " + session.sessionId + " is already staged");
+                    continue;
+                }
+
+                // If session is not among the active sessions, then it cannot have same package
+                // name as any of the active sessions.
+                if (session.getPackageName().equals(stagedSession.getPackageName())) {
+                    throw new PackageManagerException(
+                            PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
+                            "Package: " + session.getPackageName() + " in session: "
+                                    + session.sessionId + " has been staged already by session: "
+                                    + stagedSession.sessionId, null);
+                }
+
+                // TODO(b/141843321): Add support for staging multiple sessions in apexd
+                // Since apexd doesn't support multiple staged sessions yet, we have to careful how
+                // we handle apex sessions. We want to allow a set of apex sessions under the same
+                // parent to be staged when there is no previously staged apex sessions.
+                if (isApexSession(session) && isApexSession(stagedSession)) {
+                    // session is apex and it can co-exist with stagedSession only if they are from
+                    // same parent
+                    final boolean coExist;
+                    if (!session.hasParentSessionId() && !stagedSession.hasParentSessionId()) {
+                        // Both single package apex sessions. Cannot co-exist.
+                        coExist = false;
+                    } else {
+                        // At least one of the session has parent. Both must be from same parent.
+                        coExist =
+                                session.getParentSessionId() == stagedSession.getParentSessionId();
+                    }
+                    if (!coExist) {
+                        throw new PackageManagerException(
+                                PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
+                                "Package: " + session.getPackageName() + " in session: "
+                                        + session.sessionId + " cannot be staged as there is "
+                                        + "already another apex staged session: "
+                                        + stagedSession.sessionId, null);
+                    }
                 }
             }
         }
-        return null;
     }
 
     void createSession(@NonNull PackageInstallerSession sessionInfo) {
@@ -612,7 +654,8 @@
             ApexSessionInfo apexSession = mApexManager.getStagedSessionInfo(session.sessionId);
             if (apexSession == null || isApexSessionFinalized(apexSession)) {
                 Slog.w(TAG,
-                        "Cannot abort session because it is not active or APEXD is not reachable");
+                        "Cannot abort session " + session.sessionId
+                                + " because it is not active or APEXD is not reachable");
                 return;
             }
             mApexManager.abortActiveSession();
@@ -691,7 +734,7 @@
         if (!session.isStagedSessionReady()) {
             // The framework got restarted before the pre-reboot verification could complete,
             // restart the verification.
-            mBgHandler.post(() -> preRebootVerification(session));
+            mPreRebootVerificationHandler.startPreRebootVerification(session.sessionId);
         } else {
             // Session had already being marked ready. Start the checks to verify if there is any
             // follow-up work.
@@ -699,14 +742,34 @@
         }
     }
 
-    private static class LocalIntentReceiver {
+    private static class LocalIntentReceiverAsync {
+        final Consumer<Intent> mConsumer;
+
+        LocalIntentReceiverAsync(Consumer<Intent> consumer) {
+            mConsumer = consumer;
+        }
+
+        private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
+            @Override
+            public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
+                    IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
+                mConsumer.accept(intent);
+            }
+        };
+
+        public IntentSender getIntentSender() {
+            return new IntentSender((IIntentSender) mLocalSender);
+        }
+    }
+
+    private static class LocalIntentReceiverSync {
         private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>();
 
         private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
             @Override
             public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
-                             IIntentReceiver finishedReceiver, String requiredPermission,
-                             Bundle options) {
+                    IIntentReceiver finishedReceiver, String requiredPermission,
+                    Bundle options) {
                 try {
                     mResult.offer(intent, 5, TimeUnit.SECONDS);
                 } catch (InterruptedException e) {
@@ -727,4 +790,188 @@
             }
         }
     }
+
+    private final class PreRebootVerificationHandler extends Handler {
+
+        PreRebootVerificationHandler(Looper looper) {
+            super(looper);
+        }
+
+        /**
+         * Handler for states of pre reboot verification. The states are arranged linearly (shown
+         * below) with each state either calling the next state, or calling some other method that
+         * eventually calls the next state.
+         *
+         * <p><ul>
+         *     <li>MSG_PRE_REBOOT_VERIFICATION_START</li>
+         *     <li>MSG_PRE_REBOOT_VERIFICATION_APEX</li>
+         *     <li>MSG_PRE_REBOOT_VERIFICATION_APK</li>
+         *     <li>MSG_PRE_REBOOT_VERIFICATION_END</li>
+         * </ul></p>
+         *
+         * Details about each of state can be found in corresponding handler of node.
+         */
+        private static final int MSG_PRE_REBOOT_VERIFICATION_START = 1;
+        private static final int MSG_PRE_REBOOT_VERIFICATION_APEX = 2;
+        private static final int MSG_PRE_REBOOT_VERIFICATION_APK = 3;
+        private static final int MSG_PRE_REBOOT_VERIFICATION_END = 4;
+
+        @Override
+        public void handleMessage(Message msg) {
+            final int sessionId = msg.arg1;
+            final PackageInstallerSession session;
+            synchronized (mStagedSessions) {
+                session = mStagedSessions.get(sessionId);
+            }
+            // Maybe session was aborted before pre-reboot verification was complete
+            if (session == null) {
+                Slog.d(TAG, "Stopping pre-reboot verification for sessionId: " + sessionId);
+                return;
+            }
+            switch (msg.what) {
+                case MSG_PRE_REBOOT_VERIFICATION_START:
+                    handlePreRebootVerification_Start(session);
+                    break;
+                case MSG_PRE_REBOOT_VERIFICATION_APEX:
+                    handlePreRebootVerification_Apex(session);
+                    break;
+                case MSG_PRE_REBOOT_VERIFICATION_APK:
+                    handlePreRebootVerification_Apk(session);
+                    break;
+                case MSG_PRE_REBOOT_VERIFICATION_END:
+                    handlePreRebootVerification_End(session);
+                    break;
+            }
+        }
+
+        // Method for starting the pre-reboot verification
+        private void startPreRebootVerification(int sessionId) {
+            obtainMessage(MSG_PRE_REBOOT_VERIFICATION_START, sessionId, 0).sendToTarget();
+        }
+
+        private void notifyPreRebootVerification_Start_Complete(int sessionId) {
+            obtainMessage(MSG_PRE_REBOOT_VERIFICATION_APEX, sessionId, 0).sendToTarget();
+        }
+
+        private void notifyPreRebootVerification_Apex_Complete(int sessionId) {
+            obtainMessage(MSG_PRE_REBOOT_VERIFICATION_APK, sessionId, 0).sendToTarget();
+        }
+
+        private void notifyPreRebootVerification_Apk_Complete(int sessionId) {
+            obtainMessage(MSG_PRE_REBOOT_VERIFICATION_END, sessionId, 0).sendToTarget();
+        }
+
+        /**
+         * A dummy state for starting the pre reboot verification.
+         *
+         * See {@link PreRebootVerificationHandler} to see all nodes of pre reboot verification
+         */
+        private void handlePreRebootVerification_Start(@NonNull PackageInstallerSession session) {
+            Slog.d(TAG, "Starting preRebootVerification for session " + session.sessionId);
+            notifyPreRebootVerification_Start_Complete(session.sessionId);
+        }
+
+        /**
+         * Pre-reboot verification state for apex files:
+         *
+         * <p><ul>
+         *     <li>submits session to apex service</li>
+         *     <li>validates signatures of apex files</li>
+         * </ul></p>
+         */
+        private void handlePreRebootVerification_Apex(@NonNull PackageInstallerSession session) {
+            final boolean hasApex = sessionContainsApex(session);
+
+            // APEX checks. For single-package sessions, check if they contain an APEX. For
+            // multi-package sessions, find all the child sessions that contain an APEX.
+            if (hasApex) {
+                try {
+                    final List<PackageInfo> apexPackages =
+                            submitSessionToApexService(session);
+                    for (PackageInfo apexPackage : apexPackages) {
+                        validateApexSignature(apexPackage);
+                    }
+                } catch (PackageManagerException e) {
+                    session.setStagedSessionFailed(e.error, e.getMessage());
+                    return;
+                }
+            }
+
+            notifyPreRebootVerification_Apex_Complete(session.sessionId);
+        }
+
+        /**
+         * Pre-reboot verification state for apk files:
+         *   <p><ul>
+         *       <li>performs a dry-run install of apk</li>
+         *   </ul></p>
+         */
+        private void handlePreRebootVerification_Apk(@NonNull PackageInstallerSession session) {
+            if (!sessionContainsApk(session)) {
+                notifyPreRebootVerification_Apk_Complete(session.sessionId);
+                return;
+            }
+
+            try {
+                Slog.d(TAG, "Running a pre-reboot verification for APKs in session "
+                        + session.sessionId + " by performing a dry-run install");
+
+                // verifyApksInSession will notify the handler when APK verification is complete
+                verifyApksInSession(session);
+                // TODO(b/118865310): abort the session on apexd.
+            } catch (PackageManagerException e) {
+                session.setStagedSessionFailed(e.error, e.getMessage());
+            }
+        }
+
+        /**
+         * Pre-reboot verification state for wrapping up:
+         * <p><ul>
+         *     <li>enables rollback if required</li>
+         *     <li>marks session as ready</li>
+         * </ul></p>
+         */
+        private void handlePreRebootVerification_End(@NonNull PackageInstallerSession session) {
+            if ((session.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
+                // If rollback is enabled for this session, we call through to the RollbackManager
+                // with the list of sessions it must enable rollback for. Note that
+                // notifyStagedSession is a synchronous operation.
+                final IRollbackManager rm = IRollbackManager.Stub.asInterface(
+                        ServiceManager.getService(Context.ROLLBACK_SERVICE));
+                try {
+                    // NOTE: To stay consistent with the non-staged install flow, we don't fail the
+                    // entire install if rollbacks can't be enabled.
+                    if (!rm.notifyStagedSession(session.sessionId)) {
+                        Slog.e(TAG, "Unable to enable rollback for session: "
+                                + session.sessionId);
+                    }
+                } catch (RemoteException re) {
+                    Slog.e(TAG, "Failed to notifyStagedSession for session: "
+                            + session.sessionId, re);
+                }
+            }
+
+            // Proactively mark session as ready before calling apexd. Although this call order
+            // looks counter-intuitive, this is the easiest way to ensure that session won't end up
+            // in the inconsistent state:
+            //  - If device gets rebooted right before call to apexd, then apexd will never activate
+            //      apex files of this staged session. This will result in StagingManager failing
+            //      the session.
+            // On the other hand, if the order of the calls was inverted (first call apexd, then
+            // mark session as ready), then if a device gets rebooted right after the call to apexd,
+            // only apex part of the train will be applied, leaving device in an inconsistent state.
+            Slog.d(TAG, "Marking session " + session.sessionId + " as ready");
+            session.setStagedSessionReady();
+            final boolean hasApex = sessionContainsApex(session);
+            if (!hasApex) {
+                // Session doesn't contain apex, nothing to do.
+                return;
+            }
+            try {
+                mApexManager.markStagedSessionReady(session.sessionId);
+            } catch (PackageManagerException e) {
+                session.setStagedSessionFailed(e.error, e.getMessage());
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/role/OWNERS b/services/core/java/com/android/server/role/OWNERS
new file mode 100644
index 0000000..b94d988
--- /dev/null
+++ b/services/core/java/com/android/server/role/OWNERS
@@ -0,0 +1,6 @@
+svetoslavganov@google.com
+moltmann@google.com
+zhanghai@google.com
+evanseverson@google.com
+eugenesusla@google.com
+ntmyren@google.com
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java
index b051bab..8ff2a1b 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorShellCommand.java
@@ -37,9 +37,9 @@
         }
 
         switch (cmd) {
-            case "suggestTelephonyTimeZone":
+            case "suggest_telephony_time_zone":
                 return runSuggestTelephonyTimeZone();
-            case "suggestManualTimeZone":
+            case "suggest_manual_time_zone":
                 return runSuggestManualTimeZone();
             default: {
                 return handleDefaultCommands(cmd);
@@ -105,9 +105,9 @@
         pw.println("Time Zone Detector (time_zone_detector) commands:");
         pw.println("  help");
         pw.println("    Print this help text.");
-        pw.println("  suggestTelephonyTimeZone");
+        pw.println("  suggest_telephony_time_zone");
         pw.println("    --suggestion <telephony suggestion opts>");
-        pw.println("  suggestManualTimeZone");
+        pw.println("  suggest_manual_time_zone");
         pw.println("    --suggestion <manual suggestion opts>");
         pw.println();
         ManualTimeZoneSuggestion.printCommandLineOpts(pw);
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
index 0eb27cc..e0b3ad5 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
@@ -22,9 +22,12 @@
 import java.io.PrintWriter;
 
 /**
- * The interface for the class that implement the time detection algorithm used by the
+ * The interface for the class that implements the time detection algorithm used by the
  * {@link TimeZoneDetectorService}.
  *
+ * <p>The strategy uses suggestions to decide whether to modify the device's time zone setting
+ * and what to set it to.
+ *
  * <p>Most calls will be handled by a single thread but that is not true for all calls. For example
  * {@link #dump(PrintWriter, String[])}) may be called on a different thread so implementations must
  * handle thread safety.
@@ -33,7 +36,9 @@
  */
 public interface TimeZoneDetectorStrategy {
 
-    /** Process the suggested manually-entered (i.e. user sourced) time zone. */
+    /**
+     * Suggests a time zone for the device using manually-entered (i.e. user sourced) information.
+     */
     void suggestManualTimeZone(@NonNull ManualTimeZoneSuggestion suggestion);
 
     /**
@@ -41,8 +46,7 @@
      * {@link TelephonyTimeZoneSuggestion#getZoneId()} is {@code null}. The suggestion is scoped to
      * a specific {@link TelephonyTimeZoneSuggestion#getSlotIndex() slotIndex}.
      * See {@link TelephonyTimeZoneSuggestion} for an explanation of the metadata associated with a
-     * suggestion. The strategy uses suggestions to decide whether to modify the device's time zone
-     * setting and what to set it to.
+     * suggestion.
      */
     void suggestTelephonyTimeZone(@NonNull TelephonyTimeZoneSuggestion suggestion);
 
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
index cc33fb0..d318b1a 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
@@ -276,18 +276,6 @@
             return;
         }
 
-        // Special case handling for uninitialized devices. This should only happen once.
-        String newZoneId = bestTelephonySuggestion.suggestion.getZoneId();
-        if (newZoneId != null && !mCallback.isDeviceTimeZoneInitialized()) {
-            String cause = "Device has no time zone set. Attempting to set the device to the best"
-                    + " available suggestion."
-                    + " bestTelephonySuggestion=" + bestTelephonySuggestion
-                    + ", detectionReason=" + detectionReason;
-            Slog.i(LOG_TAG, cause);
-            setDeviceTimeZoneIfRequired(ORIGIN_TELEPHONY, newZoneId, cause);
-            return;
-        }
-
         boolean suggestionGoodEnough =
                 bestTelephonySuggestion.score >= TELEPHONY_SCORE_USAGE_THRESHOLD;
         if (!suggestionGoodEnough) {
@@ -301,6 +289,7 @@
 
         // Paranoia: Every suggestion above the SCORE_USAGE_THRESHOLD should have a non-null time
         // zone ID.
+        String newZoneId = bestTelephonySuggestion.suggestion.getZoneId();
         if (newZoneId == null) {
             Slog.w(LOG_TAG, "Empty zone suggestion scored higher than expected. This is an error:"
                     + " bestTelephonySuggestion=" + bestTelephonySuggestion
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 54ab906e..ba4e11a 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -343,7 +343,7 @@
      */
     final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
 
-    /** @see #computeCompatSmallestWidth(boolean, int, int, int, DisplayCutout) */
+    /** @see #computeCompatSmallestWidth(boolean, int, int, int) */
     private final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
 
     /**
@@ -1715,7 +1715,7 @@
         config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
         config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
         config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, config.uiMode, dw,
-                dh, displayInfo.displayCutout);
+                dh);
         config.densityDpi = displayInfo.logicalDensityDpi;
 
         config.colorMode =
@@ -1800,8 +1800,7 @@
         mWmService.mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
     }
 
-    private int computeCompatSmallestWidth(boolean rotated, int uiMode, int dw, int dh,
-            DisplayCutout displayCutout) {
+    private int computeCompatSmallestWidth(boolean rotated, int uiMode, int dw, int dh) {
         mTmpDisplayMetrics.setTo(mDisplayMetrics);
         final DisplayMetrics tmpDm = mTmpDisplayMetrics;
         final int unrotDw, unrotDh;
@@ -1812,19 +1811,21 @@
             unrotDw = dw;
             unrotDh = dh;
         }
-        int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw, unrotDh,
-                displayCutout);
-        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh, unrotDw,
-                displayCutout);
-        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw, unrotDh,
-                displayCutout);
-        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh, unrotDw,
-                displayCutout);
+        int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, uiMode, tmpDm, unrotDw,
+                unrotDh);
+        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, uiMode, tmpDm, unrotDh,
+                unrotDw);
+        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, uiMode, tmpDm, unrotDw,
+                unrotDh);
+        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, uiMode, tmpDm, unrotDh,
+                unrotDw);
         return sw;
     }
 
     private int reduceCompatConfigWidthSize(int curSize, int rotation, int uiMode,
-            DisplayMetrics dm, int dw, int dh, DisplayCutout displayCutout) {
+            DisplayMetrics dm, int dw, int dh) {
+        final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(
+                rotation).getDisplayCutout();
         dm.noncompatWidthPixels = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
                 displayCutout);
         dm.noncompatHeightPixels = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode,
@@ -1865,20 +1866,20 @@
             return;
         }
         int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
-        sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode,
-                displayInfo.displayCutout);
-        sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode,
-                displayInfo.displayCutout);
-        sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode,
-                displayInfo.displayCutout);
-        sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode,
-                displayInfo.displayCutout);
+        sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh, uiMode);
+        sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode);
+        sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode);
+        sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode);
         outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
         outConfig.screenLayout = sl;
     }
 
     private int reduceConfigLayout(int curLayout, int rotation, float density, int dw, int dh,
-            int uiMode, DisplayCutout displayCutout) {
+            int uiMode) {
+        // Get the display cutout at this rotation.
+        final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(
+                rotation).getDisplayCutout();
+
         // Get the app screen size at this rotation.
         int w = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, displayCutout);
         int h = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, displayCutout);
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index 0ab1a3e..4be4c89 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -10,3 +10,4 @@
 erosky@google.com
 riddlehsu@google.com
 louischang@google.com
+winsonc@google.com
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 03f64fc..cc8d258 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -78,6 +78,7 @@
 import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
 import static android.app.admin.DevicePolicyManager.WIPE_SILENTLY;
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
+import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
 import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
 import static android.provider.Telephony.Carriers.DPC_URI;
@@ -133,10 +134,6 @@
 import android.app.admin.SystemUpdateInfo;
 import android.app.admin.SystemUpdatePolicy;
 import android.app.backup.IBackupManager;
-import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timedetector.TimeDetector;
-import android.app.timezonedetector.ManualTimeZoneSuggestion;
-import android.app.timezonedetector.TimeZoneDetector;
 import android.app.trust.TrustManager;
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.ActivityNotFoundException;
@@ -1957,14 +1954,6 @@
             return mContext.getSystemService(AlarmManager.class);
         }
 
-        TimeDetector getTimeDetector() {
-            return mContext.getSystemService(TimeDetector.class);
-        }
-
-        TimeZoneDetector getTimeZoneDetector() {
-            return mContext.getSystemService(TimeZoneDetector.class);
-        }
-
         ConnectivityManager getConnectivityManager() {
             return mContext.getSystemService(ConnectivityManager.class);
         }
@@ -5558,6 +5547,14 @@
         }
     }
 
+    private void enforceNetworkStackOrProfileOrDeviceOwner(ComponentName who) {
+        if (mContext.checkCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK)
+                == PackageManager.PERMISSION_GRANTED) {
+            return;
+        }
+        enforceProfileOrDeviceOwner(who);
+    }
+
     @Override
     public boolean approveCaCert(String alias, int userId, boolean approval) {
         enforceManageUsers();
@@ -6485,7 +6482,7 @@
 
     @Override
     public boolean isAlwaysOnVpnLockdownEnabled(ComponentName admin) throws SecurityException {
-        enforceProfileOrDeviceOwner(admin);
+        enforceNetworkStackOrProfileOrDeviceOwner(admin);
 
         final int userId = mInjector.userHandleGetCallingUserId();
         final long token = mInjector.binderClearCallingIdentity();
@@ -10878,10 +10875,7 @@
         if (mInjector.settingsGlobalGetInt(Global.AUTO_TIME, 0) == 1) {
             return false;
         }
-        ManualTimeSuggestion manualTimeSuggestion = TimeDetector.createManualTimeSuggestion(
-                millis, "DevicePolicyManagerService: setTime");
-        mInjector.binderWithCleanCallingIdentity(
-                () -> mInjector.getTimeDetector().suggestManualTime(manualTimeSuggestion));
+        mInjector.binderWithCleanCallingIdentity(() -> mInjector.getAlarmManager().setTime(millis));
         return true;
     }
 
@@ -10893,11 +10887,8 @@
         if (mInjector.settingsGlobalGetInt(Global.AUTO_TIME_ZONE, 0) == 1) {
             return false;
         }
-        ManualTimeZoneSuggestion manualTimeZoneSuggestion =
-                TimeZoneDetector.createManualTimeZoneSuggestion(
-                        timeZone, "DevicePolicyManagerService: setTimeZone");
         mInjector.binderWithCleanCallingIdentity(() ->
-                mInjector.getTimeZoneDetector().suggestManualTimeZone(manualTimeZoneSuggestion));
+                mInjector.getAlarmManager().setTimeZone(timeZone));
         return true;
     }
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 2b28ca2..afa8c46 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1328,7 +1328,7 @@
 
             traceBeginAndSlog("StartIpSecService");
             try {
-                ipSecService = IpSecService.create(context);
+                ipSecService = IpSecService.create(context, networkManagement);
                 ServiceManager.addService(Context.IPSEC_SERVICE, ipSecService);
             } catch (Throwable e) {
                 reportWtf("starting IpSec Service", e);
diff --git a/services/net/Android.bp b/services/net/Android.bp
index dbc2df8..c54102f 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -20,6 +20,44 @@
     ],
 }
 
+// Version of services.net for usage by the wifi mainline module.
+// Note: This is compiled against module_current.
+// TODO(b/145825329): This should be moved to networkstack-client,
+// with dependencies moved to frameworks/libs/net right.
+java_library {
+    name: "services.net-module-wifi",
+    srcs: [
+        ":framework-services-net-module-wifi-shared-srcs",
+        ":net-module-utils-srcs",
+        "java/android/net/ip/IpClientCallbacks.java",
+        "java/android/net/ip/IpClientManager.java",
+        "java/android/net/ip/IpClientUtil.java",
+        "java/android/net/util/KeepalivePacketDataUtil.java",
+        "java/android/net/util/NetworkConstants.java",
+        "java/android/net/IpMemoryStore.java",
+        "java/android/net/NetworkMonitorManager.java",
+        "java/android/net/TcpKeepalivePacketData.java",
+    ],
+    sdk_version: "module_current",
+    libs: [
+        "unsupportedappusage",
+    ],
+    static_libs: [
+        "dnsresolver_aidl_interface-V2-java",
+        "netd_aidl_interface-unstable-java",
+        "netlink-client",
+        "networkstack-client",
+        "net-utils-services-common",
+    ],
+    apex_available: [
+        "com.android.wifi",
+    ],
+    visibility: [
+        "//frameworks/opt/net/wifi/service",
+        "//frameworks/opt/net/wifi/tests/wifitests",
+    ],
+}
+
 filegroup {
     name: "services-tethering-shared-srcs",
     srcs: [
diff --git a/services/net/java/android/net/IpMemoryStore.java b/services/net/java/android/net/IpMemoryStore.java
index dcefb53..8df2e0d 100644
--- a/services/net/java/android/net/IpMemoryStore.java
+++ b/services/net/java/android/net/IpMemoryStore.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.net.networkstack.ModuleNetworkStackClient;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -41,7 +42,7 @@
         super(context);
         mService = new CompletableFuture<>();
         mTailNode = new AtomicReference<CompletableFuture<IIpMemoryStore>>(mService);
-        getNetworkStackClient().fetchIpMemoryStore(
+        getModuleNetworkStackClient(context).fetchIpMemoryStore(
                 new IIpMemoryStoreCallbacks.Stub() {
                     @Override
                     public void onIpMemoryStoreFetched(@NonNull final IIpMemoryStore memoryStore) {
@@ -85,8 +86,8 @@
     }
 
     @VisibleForTesting
-    protected NetworkStackClient getNetworkStackClient() {
-        return NetworkStackClient.getInstance();
+    protected ModuleNetworkStackClient getModuleNetworkStackClient(Context context) {
+        return ModuleNetworkStackClient.getInstance(context);
     }
 
     /** Gets an instance of the memory store */
diff --git a/services/net/java/android/net/TcpKeepalivePacketData.java b/services/net/java/android/net/TcpKeepalivePacketData.java
index aad75ae..c0c386b 100644
--- a/services/net/java/android/net/TcpKeepalivePacketData.java
+++ b/services/net/java/android/net/TcpKeepalivePacketData.java
@@ -74,6 +74,19 @@
         ipTtl = tcpDetails.ttl;
     }
 
+    private TcpKeepalivePacketData(final InetAddress srcAddress, int srcPort,
+            final InetAddress dstAddress, int dstPort, final byte[] data, int tcpSeq,
+            int tcpAck, int tcpWnd, int tcpWndScale, int ipTos, int ipTtl)
+            throws InvalidPacketException {
+        super(srcAddress, srcPort, dstAddress, dstPort, data);
+        this.tcpSeq = tcpSeq;
+        this.tcpAck = tcpAck;
+        this.tcpWnd = tcpWnd;
+        this.tcpWndScale = tcpWndScale;
+        this.ipTos = ipTos;
+        this.ipTtl = ipTtl;
+    }
+
     /**
      * Factory method to create tcp keepalive packet structure.
      */
@@ -139,10 +152,12 @@
     public boolean equals(@Nullable final Object o) {
         if (!(o instanceof TcpKeepalivePacketData)) return false;
         final TcpKeepalivePacketData other = (TcpKeepalivePacketData) o;
-        return this.srcAddress.equals(other.srcAddress)
-                && this.dstAddress.equals(other.dstAddress)
-                && this.srcPort == other.srcPort
-                && this.dstPort == other.dstPort
+        final InetAddress srcAddress = getSrcAddress();
+        final InetAddress dstAddress = getDstAddress();
+        return srcAddress.equals(other.getSrcAddress())
+                && dstAddress.equals(other.getDstAddress())
+                && getSrcPort() == other.getSrcPort()
+                && getDstPort() == other.getDstPort()
                 && this.tcpAck == other.tcpAck
                 && this.tcpSeq == other.tcpSeq
                 && this.tcpWnd == other.tcpWnd
@@ -153,8 +168,8 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(srcAddress, dstAddress, srcPort, dstPort, tcpAck, tcpSeq, tcpWnd,
-                tcpWndScale, ipTos, ipTtl);
+        return Objects.hash(getSrcAddress(), getDstAddress(), getSrcPort(), getDstPort(),
+                tcpAck, tcpSeq, tcpWnd, tcpWndScale, ipTos, ipTtl);
     }
 
     /**
@@ -169,7 +184,11 @@
 
     /** Write to parcel. */
     public void writeToParcel(Parcel out, int flags) {
-        super.writeToParcel(out, flags);
+        out.writeString(getSrcAddress().getHostAddress());
+        out.writeString(getDstAddress().getHostAddress());
+        out.writeInt(getSrcPort());
+        out.writeInt(getDstPort());
+        out.writeByteArray(getPacket());
         out.writeInt(tcpSeq);
         out.writeInt(tcpAck);
         out.writeInt(tcpWnd);
@@ -178,21 +197,32 @@
         out.writeInt(ipTtl);
     }
 
-    private TcpKeepalivePacketData(Parcel in) {
-        super(in);
-        tcpSeq = in.readInt();
-        tcpAck = in.readInt();
-        tcpWnd = in.readInt();
-        tcpWndScale = in.readInt();
-        ipTos = in.readInt();
-        ipTtl = in.readInt();
+    private static TcpKeepalivePacketData readFromParcel(Parcel in) throws InvalidPacketException {
+        InetAddress srcAddress = InetAddresses.parseNumericAddress(in.readString());
+        InetAddress dstAddress = InetAddresses.parseNumericAddress(in.readString());
+        int srcPort = in.readInt();
+        int dstPort = in.readInt();
+        byte[] packet = in.createByteArray();
+        int tcpSeq = in.readInt();
+        int tcpAck = in.readInt();
+        int tcpWnd = in.readInt();
+        int tcpWndScale = in.readInt();
+        int ipTos = in.readInt();
+        int ipTtl = in.readInt();
+        return new TcpKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, packet, tcpSeq,
+                tcpAck, tcpWnd, tcpWndScale, ipTos, ipTtl);
     }
 
     /** Parcelable Creator. */
     public static final @NonNull Parcelable.Creator<TcpKeepalivePacketData> CREATOR =
             new Parcelable.Creator<TcpKeepalivePacketData>() {
                 public TcpKeepalivePacketData createFromParcel(Parcel in) {
-                    return new TcpKeepalivePacketData(in);
+                    try {
+                        return readFromParcel(in);
+                    } catch (InvalidPacketException e) {
+                        throw new IllegalArgumentException(
+                                "Invalid NAT-T keepalive data: " + e.getError());
+                    }
                 }
 
                 public TcpKeepalivePacketData[] newArray(int size) {
@@ -206,10 +236,12 @@
     @NonNull
     public TcpKeepalivePacketDataParcelable toStableParcelable() {
         final TcpKeepalivePacketDataParcelable parcel = new TcpKeepalivePacketDataParcelable();
+        final InetAddress srcAddress = getSrcAddress();
+        final InetAddress dstAddress = getDstAddress();
         parcel.srcAddress = srcAddress.getAddress();
-        parcel.srcPort = srcPort;
+        parcel.srcPort = getSrcPort();
         parcel.dstAddress = dstAddress.getAddress();
-        parcel.dstPort = dstPort;
+        parcel.dstPort = getDstPort();
         parcel.seq = tcpSeq;
         parcel.ack = tcpAck;
         parcel.rcvWnd = tcpWnd;
@@ -221,10 +253,10 @@
 
     @Override
     public String toString() {
-        return "saddr: " + srcAddress
-                + " daddr: " + dstAddress
-                + " sport: " + srcPort
-                + " dport: " + dstPort
+        return "saddr: " + getSrcAddress()
+                + " daddr: " + getDstAddress()
+                + " sport: " + getSrcPort()
+                + " dport: " + getDstPort()
                 + " seq: " + tcpSeq
                 + " ack: " + tcpAck
                 + " wnd: " + tcpWnd
diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java
index a3618b4..b329aee 100644
--- a/services/net/java/android/net/ip/IpClientUtil.java
+++ b/services/net/java/android/net/ip/IpClientUtil.java
@@ -22,7 +22,7 @@
 import android.net.DhcpResultsParcelable;
 import android.net.Layer2PacketParcelable;
 import android.net.LinkProperties;
-import android.net.NetworkStackClient;
+import android.net.networkstack.ModuleNetworkStackClient;
 import android.os.ConditionVariable;
 
 import java.io.FileDescriptor;
@@ -75,11 +75,11 @@
      *
      * <p>This is a convenience method to allow clients to use {@link IpClientCallbacks} instead of
      * {@link IIpClientCallbacks}.
-     * @see {@link NetworkStackClient#makeIpClient(String, IIpClientCallbacks)}
+     * @see {@link ModuleNetworkStackClient#makeIpClient(String, IIpClientCallbacks)}
      */
     public static void makeIpClient(Context context, String ifName, IpClientCallbacks callback) {
-        // TODO: migrate clients and remove context argument
-        NetworkStackClient.getInstance().makeIpClient(ifName, new IpClientCallbacksProxy(callback));
+        ModuleNetworkStackClient.getInstance(context)
+                .makeIpClient(ifName, new IpClientCallbacksProxy(callback));
     }
 
     /**
diff --git a/services/net/java/android/net/util/KeepalivePacketDataUtil.java b/services/net/java/android/net/util/KeepalivePacketDataUtil.java
index 9a51729..4466ea0 100644
--- a/services/net/java/android/net/util/KeepalivePacketDataUtil.java
+++ b/services/net/java/android/net/util/KeepalivePacketDataUtil.java
@@ -20,6 +20,8 @@
 import android.net.NattKeepalivePacketData;
 import android.net.NattKeepalivePacketDataParcelable;
 
+import java.net.InetAddress;
+
 /** @hide */
 public final class KeepalivePacketDataUtil {
      /**
@@ -29,11 +31,12 @@
     public static NattKeepalivePacketDataParcelable toStableParcelable(
             NattKeepalivePacketData pkt) {
         final NattKeepalivePacketDataParcelable parcel = new NattKeepalivePacketDataParcelable();
-
-        parcel.srcAddress = pkt.srcAddress.getAddress();
-        parcel.srcPort = pkt.srcPort;
-        parcel.dstAddress = pkt.dstAddress.getAddress();
-        parcel.dstPort = pkt.dstPort;
+        final InetAddress srcAddress = pkt.getSrcAddress();
+        final InetAddress dstAddress = pkt.getDstAddress();
+        parcel.srcAddress = srcAddress.getAddress();
+        parcel.srcPort = pkt.getSrcPort();
+        parcel.dstAddress = dstAddress.getAddress();
+        parcel.dstPort = pkt.getDstPort();
         return parcel;
     }
 }
diff --git a/services/robotests/Android.bp b/services/robotests/Android.bp
index a08b3e7..17d0bbf 100644
--- a/services/robotests/Android.bp
+++ b/services/robotests/Android.bp
@@ -27,7 +27,7 @@
         "services.net",
     ],
 
-    libs: ["ike-stubs"],
+    libs: ["android.net.ipsec.ike.stubs.system"],
 }
 
 //##################################################################
diff --git a/services/robotests/backup/Android.bp b/services/robotests/backup/Android.bp
index 6fcc242..a3ccc6e 100644
--- a/services/robotests/backup/Android.bp
+++ b/services/robotests/backup/Android.bp
@@ -29,7 +29,7 @@
         "services.net",
     ],
 
-    libs: ["ike-stubs"],
+    libs: ["android.net.ipsec.ike.stubs.system"],
 }
 
 //##################################################################
diff --git a/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java
deleted file mode 100644
index d192748..0000000
--- a/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2018 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;
-
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
-import android.os.storage.StorageManagerInternal;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class StorageManagerServiceTest {
-
-    private StorageManagerService mService;
-
-    @Mock private Context mContext;
-    @Mock private PackageManager mPm;
-    @Mock private PackageManagerInternal mPmi;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        LocalServices.removeServiceForTest(StorageManagerInternal.class);
-
-        LocalServices.removeServiceForTest(PackageManagerInternal.class);
-        LocalServices.addService(PackageManagerInternal.class, mPmi);
-
-        when(mContext.getPackageManager()).thenReturn(mPm);
-
-        mService = new StorageManagerService(mContext);
-    }
-}
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 0e24793..85e93df 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
@@ -249,6 +249,28 @@
     }
 
     @Test
+    public void testAllowRemoveOverrideNoOverride() throws Exception {
+        CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
+                .addDisabledChangeWithId(1234L)
+                .addLoggingOnlyChangeWithId(2L)
+                .build();
+        ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
+                .withPackageName("com.some.package")
+                .build();
+        when(mPackageManager.getApplicationInfo(eq("com.some.package"), anyInt()))
+                .thenReturn(applicationInfo);
+
+        // Reject all override attempts.
+        // Force the validator to prevent overriding the change by using a user build.
+        when(mBuildClassifier.isDebuggableBuild()).thenReturn(false);
+        when(mBuildClassifier.isFinalBuild()).thenReturn(true);
+        // Try to remove a non existing override, and it doesn't fail.
+        assertThat(compatConfig.removeOverride(1234L, "com.some.package")).isFalse();
+        assertThat(compatConfig.removeOverride(2L, "com.some.package")).isFalse();
+        compatConfig.removePackageOverrides("com.some.package");
+    }
+
+    @Test
     public void testRemovePackageOverride() throws Exception {
         CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
                 .addEnabledChangeWithId(1234L)
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 ce5d6d9..e295fee 100644
--- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
@@ -28,10 +28,12 @@
 
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.os.Build;
 
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.compat.AndroidBuildClassifier;
+import com.android.internal.compat.CompatibilityChangeInfo;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -68,6 +70,48 @@
     }
 
     @Test
+    public void testListAllChanges() {
+        mCompatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
+                .addEnabledChangeWithId(1L)
+                .addDisabledChangeWithIdAndName(2L, "change2")
+                .addTargetSdkChangeWithIdAndDescription(Build.VERSION_CODES.O, 3L, "description")
+                .addTargetSdkChangeWithId(Build.VERSION_CODES.P, 4L)
+                .addTargetSdkChangeWithId(Build.VERSION_CODES.Q, 5L)
+                .addTargetSdkChangeWithId(Build.VERSION_CODES.R, 6L)
+                .addLoggingOnlyChangeWithId(7L)
+                .build();
+        mPlatformCompat = new PlatformCompat(mContext, mCompatConfig);
+        assertThat(mPlatformCompat.listAllChanges()).asList().containsExactly(
+                new CompatibilityChangeInfo(1L, "", -1, false, false, ""),
+                new CompatibilityChangeInfo(2L, "change2", -1, true, false, ""),
+                new CompatibilityChangeInfo(3L, "", Build.VERSION_CODES.O, false, false,
+                        "description"),
+                new CompatibilityChangeInfo(4L, "", Build.VERSION_CODES.P, false, false, ""),
+                new CompatibilityChangeInfo(5L, "", Build.VERSION_CODES.Q, false, false, ""),
+                new CompatibilityChangeInfo(6L, "", Build.VERSION_CODES.R, false, false, ""),
+                new CompatibilityChangeInfo(7L, "", -1, false, true, ""));
+    }
+
+    @Test
+    public void testListUIChanges() {
+        mCompatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
+                .addEnabledChangeWithId(1L)
+                .addDisabledChangeWithIdAndName(2L, "change2")
+                .addTargetSdkChangeWithIdAndDescription(Build.VERSION_CODES.O, 3L, "description")
+                .addTargetSdkChangeWithId(Build.VERSION_CODES.P, 4L)
+                .addTargetSdkChangeWithId(Build.VERSION_CODES.Q, 5L)
+                .addTargetSdkChangeWithId(Build.VERSION_CODES.R, 6L)
+                .addLoggingOnlyChangeWithId(7L)
+                .build();
+        mPlatformCompat = new PlatformCompat(mContext, mCompatConfig);
+        assertThat(mPlatformCompat.listUIChanges()).asList().containsExactly(
+                new CompatibilityChangeInfo(1L, "", -1, false, false, ""),
+                new CompatibilityChangeInfo(2L, "change2", -1, true, false, ""),
+                new CompatibilityChangeInfo(4L, "", Build.VERSION_CODES.P, false, false, ""),
+                new CompatibilityChangeInfo(5L, "", Build.VERSION_CODES.Q, false, false, ""));
+    }
+
+    @Test
     public void testRegisterListenerToSameIdThrows() throws Exception {
         // Registering a listener to change 1 is successful.
         mPlatformCompat.registerListener(1, mListener1);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index 0763aa2..2ce4c54 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -22,8 +22,6 @@
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.backup.IBackupManager;
-import android.app.timedetector.TimeDetector;
-import android.app.timezonedetector.TimeZoneDetector;
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.Context;
 import android.content.Intent;
@@ -219,16 +217,6 @@
         AlarmManager getAlarmManager() {return services.alarmManager;}
 
         @Override
-        TimeDetector getTimeDetector() {
-            return services.timeDetector;
-        }
-
-        @Override
-        TimeZoneDetector getTimeZoneDetector() {
-            return services.timeZoneDetector;
-        }
-
-        @Override
         LockPatternUtils newLockPatternUtils() {
             return services.lockPatternUtils;
         }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 7c0afed..9ae9824 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -63,9 +63,6 @@
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.app.admin.PasswordMetrics;
-import android.app.timedetector.ManualTimeSuggestion;
-import android.app.timezonedetector.ManualTimeZoneSuggestion;
-import android.app.timezonedetector.TimeZoneDetector;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Intent;
@@ -3476,19 +3473,7 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
         dpm.setTime(admin1, 0);
-
-        BaseMatcher<ManualTimeSuggestion> hasZeroTime = new BaseMatcher<ManualTimeSuggestion>() {
-            @Override
-            public boolean matches(Object item) {
-                final ManualTimeSuggestion suggestion = (ManualTimeSuggestion) item;
-                return suggestion.getUtcTime().getValue() == 0;
-            }
-            @Override
-            public void describeTo(Description description) {
-                description.appendText("ManualTimeSuggestion{utcTime.value=0}");
-            }
-        };
-        verify(getServices().timeDetector).suggestManualTime(argThat(hasZeroTime));
+        verify(getServices().alarmManager).setTime(0);
     }
 
     public void testSetTimeFailWithPO() throws Exception {
@@ -3508,9 +3493,7 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
         dpm.setTimeZone(admin1, "Asia/Shanghai");
-        ManualTimeZoneSuggestion suggestion =
-                TimeZoneDetector.createManualTimeZoneSuggestion("Asia/Shanghai", "Test debug info");
-        verify(getServices().timeZoneDetector).suggestManualTimeZone(suggestion);
+        verify(getServices().alarmManager).setTimeZone("Asia/Shanghai");
     }
 
     public void testSetTimeZoneFailWithPO() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
index 960f670..35c1150 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -207,8 +207,6 @@
         switch (name) {
             case Context.ALARM_SERVICE:
                 return mMockSystemServices.alarmManager;
-            case Context.TIME_DETECTOR_SERVICE:
-                return mMockSystemServices.timeDetector;
             case Context.USER_SERVICE:
                 return mMockSystemServices.userManager;
             case Context.POWER_SERVICE:
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
index 16d5db9..8f0aeea 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -31,8 +31,6 @@
 import android.app.IActivityTaskManager;
 import android.app.NotificationManager;
 import android.app.backup.IBackupManager;
-import android.app.timedetector.TimeDetector;
-import android.app.timezonedetector.TimeZoneDetector;
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.BroadcastReceiver;
 import android.content.ContentValues;
@@ -109,8 +107,6 @@
     public final TelephonyManager telephonyManager;
     public final AccountManager accountManager;
     public final AlarmManager alarmManager;
-    public final TimeDetector timeDetector;
-    public final TimeZoneDetector timeZoneDetector;
     public final KeyChain.KeyChainConnection keyChainConnection;
     /** Note this is a partial mock, not a real mock. */
     public final PackageManager packageManager;
@@ -150,8 +146,6 @@
         telephonyManager = mock(TelephonyManager.class);
         accountManager = mock(AccountManager.class);
         alarmManager = mock(AlarmManager.class);
-        timeDetector = mock(TimeDetector.class);
-        timeZoneDetector = mock(TimeZoneDetector.class);
         keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS);
 
         // Package manager is huge, so we use a partial mock instead.
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index ece937a..f1662ff 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -1006,7 +1006,7 @@
 
         // pretend that 512 bytes total have happened
         stats = new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L);
+                .insertEntry(TEST_IFACE, 256L, 2L, 256L, 2L);
         when(mStatsService.getNetworkTotalBytes(sTemplateWifi, CYCLE_START, CYCLE_END))
                 .thenReturn(stats.getTotalBytes());
 
@@ -1198,11 +1198,11 @@
             history.recordData(start, end,
                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
             stats.clear();
-            stats.addEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
+            stats.insertEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
                     DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
-            stats.addEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
+            stats.insertEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
                     DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
-            stats.addEntry(IFACE_ALL, UID_C, SET_ALL, TAG_ALL,
+            stats.insertEntry(IFACE_ALL, UID_C, SET_ALL, TAG_ALL,
                     DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
 
             reset(mNotifManager);
@@ -1226,9 +1226,9 @@
             history.recordData(start, end,
                     new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(1440), 0L, 0L, 0L, 0));
             stats.clear();
-            stats.addEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
+            stats.insertEntry(IFACE_ALL, UID_A, SET_ALL, TAG_ALL,
                     DataUnit.MEGABYTES.toBytes(960), 0, 0, 0, 0);
-            stats.addEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
+            stats.insertEntry(IFACE_ALL, UID_B, SET_ALL, TAG_ALL,
                     DataUnit.MEGABYTES.toBytes(480), 0, 0, 0, 0);
 
             reset(mNotifManager);
@@ -1260,7 +1260,7 @@
         // bring up wifi network with metered policy
         state = new NetworkState[] { buildWifi() };
         stats = new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
+                .insertEntry(TEST_IFACE, 0L, 0L, 0L, 0L);
 
         {
             when(mConnManager.getAllNetworkState()).thenReturn(state);
@@ -1692,7 +1692,7 @@
         final int CYCLE_DAY = 15;
 
         final NetworkStats stats = new NetworkStats(0L, 1);
-        stats.addEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
+        stats.insertEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
                 2999, 1, 2000, 1, 0);
         when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
                 .thenReturn(stats.getTotalBytes());
@@ -1716,7 +1716,7 @@
         reset(mStatsService);
 
         // Increase the usage.
-        stats.addEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
+        stats.insertEntry(TEST_IFACE, UID_A, SET_ALL, TAG_NONE,
                 1000, 1, 999, 1, 0);
         when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
                 .thenReturn(stats.getTotalBytes());
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
index 039c2b4..da34e1b 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorServiceTest.java
@@ -76,39 +76,7 @@
     }
 
     @Test(expected = SecurityException.class)
-    public void testSuggestTelephonyTime_withoutPermission() {
-        doThrow(new SecurityException("Mock"))
-                .when(mMockContext).enforceCallingPermission(anyString(), any());
-        TelephonyTimeZoneSuggestion timeZoneSuggestion = createTelephonyTimeZoneSuggestion();
-
-        try {
-            mTimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion);
-            fail();
-        } finally {
-            verify(mMockContext).enforceCallingPermission(
-                    eq(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE),
-                    anyString());
-        }
-    }
-
-    @Test
-    public void testSuggestTelephonyTimeZone() throws Exception {
-        doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
-
-        TelephonyTimeZoneSuggestion timeZoneSuggestion = createTelephonyTimeZoneSuggestion();
-        mTimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion);
-        mTestHandler.assertTotalMessagesEnqueued(1);
-
-        verify(mMockContext).enforceCallingPermission(
-                eq(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE),
-                anyString());
-
-        mTestHandler.waitForMessagesToBeProcessed();
-        mStubbedTimeZoneDetectorStrategy.verifySuggestTelephonyTimeZoneCalled(timeZoneSuggestion);
-    }
-
-    @Test(expected = SecurityException.class)
-    public void testSuggestManualTime_withoutPermission() {
+    public void testSuggestManualTimeZone_withoutPermission() {
         doThrow(new SecurityException("Mock"))
                 .when(mMockContext).enforceCallingOrSelfPermission(anyString(), any());
         ManualTimeZoneSuggestion timeZoneSuggestion = createManualTimeZoneSuggestion();
@@ -139,6 +107,38 @@
         mStubbedTimeZoneDetectorStrategy.verifySuggestManualTimeZoneCalled(timeZoneSuggestion);
     }
 
+    @Test(expected = SecurityException.class)
+    public void testSuggestTelephonyTimeZone_withoutPermission() {
+        doThrow(new SecurityException("Mock"))
+                .when(mMockContext).enforceCallingPermission(anyString(), any());
+        TelephonyTimeZoneSuggestion timeZoneSuggestion = createTelephonyTimeZoneSuggestion();
+
+        try {
+            mTimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion);
+            fail();
+        } finally {
+            verify(mMockContext).enforceCallingPermission(
+                    eq(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE),
+                    anyString());
+        }
+    }
+
+    @Test
+    public void testSuggestTelephonyTimeZone() throws Exception {
+        doNothing().when(mMockContext).enforceCallingPermission(anyString(), any());
+
+        TelephonyTimeZoneSuggestion timeZoneSuggestion = createTelephonyTimeZoneSuggestion();
+        mTimeZoneDetectorService.suggestTelephonyTimeZone(timeZoneSuggestion);
+        mTestHandler.assertTotalMessagesEnqueued(1);
+
+        verify(mMockContext).enforceCallingPermission(
+                eq(android.Manifest.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE),
+                anyString());
+
+        mTestHandler.waitForMessagesToBeProcessed();
+        mStubbedTimeZoneDetectorStrategy.verifySuggestTelephonyTimeZoneCalled(timeZoneSuggestion);
+    }
+
     @Test
     public void testDump() {
         when(mMockContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP))
@@ -165,6 +165,10 @@
         mStubbedTimeZoneDetectorStrategy.verifyHandleAutoTimeZoneDetectionChangedCalled();
     }
 
+    private static ManualTimeZoneSuggestion createManualTimeZoneSuggestion() {
+        return new ManualTimeZoneSuggestion("TestZoneId");
+    }
+
     private static TelephonyTimeZoneSuggestion createTelephonyTimeZoneSuggestion() {
         int slotIndex = 1234;
         return new TelephonyTimeZoneSuggestion.Builder(slotIndex)
@@ -174,26 +178,22 @@
                 .build();
     }
 
-    private static ManualTimeZoneSuggestion createManualTimeZoneSuggestion() {
-        return new ManualTimeZoneSuggestion("TestZoneId");
-    }
-
     private static class StubbedTimeZoneDetectorStrategy implements TimeZoneDetectorStrategy {
 
         // Call tracking.
-        private TelephonyTimeZoneSuggestion mLastTelephonySuggestion;
         private ManualTimeZoneSuggestion mLastManualSuggestion;
+        private TelephonyTimeZoneSuggestion mLastTelephonySuggestion;
         private boolean mHandleAutoTimeZoneDetectionChangedCalled;
         private boolean mDumpCalled;
 
         @Override
-        public void suggestTelephonyTimeZone(TelephonyTimeZoneSuggestion timeZoneSuggestion) {
-            mLastTelephonySuggestion = timeZoneSuggestion;
+        public void suggestManualTimeZone(ManualTimeZoneSuggestion timeZoneSuggestion) {
+            mLastManualSuggestion = timeZoneSuggestion;
         }
 
         @Override
-        public void suggestManualTimeZone(ManualTimeZoneSuggestion timeZoneSuggestion) {
-            mLastManualSuggestion = timeZoneSuggestion;
+        public void suggestTelephonyTimeZone(TelephonyTimeZoneSuggestion timeZoneSuggestion) {
+            mLastTelephonySuggestion = timeZoneSuggestion;
         }
 
         @Override
@@ -207,18 +207,18 @@
         }
 
         void resetCallTracking() {
-            mLastTelephonySuggestion = null;
             mLastManualSuggestion = null;
+            mLastTelephonySuggestion = null;
             mHandleAutoTimeZoneDetectionChangedCalled = false;
             mDumpCalled = false;
         }
 
-        void verifySuggestTelephonyTimeZoneCalled(TelephonyTimeZoneSuggestion expectedSuggestion) {
-            assertEquals(expectedSuggestion, mLastTelephonySuggestion);
+        void verifySuggestManualTimeZoneCalled(ManualTimeZoneSuggestion expectedSuggestion) {
+            assertEquals(expectedSuggestion, mLastManualSuggestion);
         }
 
-        public void verifySuggestManualTimeZoneCalled(ManualTimeZoneSuggestion expectedSuggestion) {
-            assertEquals(expectedSuggestion, mLastManualSuggestion);
+        void verifySuggestTelephonyTimeZoneCalled(TelephonyTimeZoneSuggestion expectedSuggestion) {
+            assertEquals(expectedSuggestion, mLastTelephonySuggestion);
         }
 
         void verifyHandleAutoTimeZoneDetectionChangedCalled() {
@@ -229,5 +229,4 @@
             assertTrue(mDumpCalled);
         }
     }
-
 }
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
index ba30967..30bb12e 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
@@ -128,43 +128,69 @@
     }
 
     @Test
-    public void testFirstPlausibleTelephonySuggestionAcceptedWhenTimeZoneUninitialized() {
+    public void testTelephonySuggestionsWhenTimeZoneUninitialized() {
+        assertTrue(TELEPHONY_SCORE_LOW < TELEPHONY_SCORE_USAGE_THRESHOLD);
+        assertTrue(TELEPHONY_SCORE_HIGH >= TELEPHONY_SCORE_USAGE_THRESHOLD);
         SuggestionTestCase testCase = newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY,
                 QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS, TELEPHONY_SCORE_LOW);
-        TelephonyTimeZoneSuggestion lowQualitySuggestion =
-                testCase.createSuggestion(SLOT_INDEX1, "America/New_York");
+        SuggestionTestCase testCase2 = newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY,
+                QUALITY_SINGLE_ZONE, TELEPHONY_SCORE_HIGH);
 
-        // The device time zone setting is left uninitialized.
         Script script = new Script()
                 .initializeAutoTimeZoneDetection(true);
 
-        // The very first suggestion will be taken.
-        script.suggestTelephonyTimeZone(lowQualitySuggestion)
-                .verifyTimeZoneSetAndReset(lowQualitySuggestion);
+        // A low quality suggestions will not be taken: The device time zone setting is left
+        // uninitialized.
+        {
+            TelephonyTimeZoneSuggestion lowQualitySuggestion =
+                    testCase.createSuggestion(SLOT_INDEX1, "America/New_York");
 
-        // Assert internal service state.
-        QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion =
-                new QualifiedTelephonyTimeZoneSuggestion(
-                        lowQualitySuggestion, testCase.expectedScore);
-        assertEquals(expectedScoredSuggestion,
-                mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
-        assertEquals(expectedScoredSuggestion,
-                mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
+            script.suggestTelephonyTimeZone(lowQualitySuggestion)
+                    .verifyTimeZoneNotSet();
 
-        // Another low quality suggestion will be ignored now that the setting is initialized.
-        TelephonyTimeZoneSuggestion lowQualitySuggestion2 =
-                testCase.createSuggestion(SLOT_INDEX1, "America/Los_Angeles");
-        script.suggestTelephonyTimeZone(lowQualitySuggestion2)
-                .verifyTimeZoneNotSet();
+            // Assert internal service state.
+            QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion =
+                    new QualifiedTelephonyTimeZoneSuggestion(
+                            lowQualitySuggestion, testCase.expectedScore);
+            assertEquals(expectedScoredSuggestion,
+                    mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
+            assertEquals(expectedScoredSuggestion,
+                    mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
+        }
 
-        // Assert internal service state.
-        QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion2 =
-                new QualifiedTelephonyTimeZoneSuggestion(
-                        lowQualitySuggestion2, testCase.expectedScore);
-        assertEquals(expectedScoredSuggestion2,
-                mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
-        assertEquals(expectedScoredSuggestion2,
-                mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
+        // A good quality suggestion will be used.
+        {
+            TelephonyTimeZoneSuggestion goodQualitySuggestion =
+                    testCase2.createSuggestion(SLOT_INDEX1, "Europe/London");
+            script.suggestTelephonyTimeZone(goodQualitySuggestion)
+                    .verifyTimeZoneSetAndReset(goodQualitySuggestion);
+
+            // Assert internal service state.
+            QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion =
+                    new QualifiedTelephonyTimeZoneSuggestion(
+                            goodQualitySuggestion, testCase2.expectedScore);
+            assertEquals(expectedScoredSuggestion,
+                    mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
+            assertEquals(expectedScoredSuggestion,
+                    mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
+        }
+
+        // A low quality suggestion will be accepted, but not used to set the device time zone.
+        {
+            TelephonyTimeZoneSuggestion lowQualitySuggestion2 =
+                    testCase.createSuggestion(SLOT_INDEX1, "America/Los_Angeles");
+            script.suggestTelephonyTimeZone(lowQualitySuggestion2)
+                    .verifyTimeZoneNotSet();
+
+            // Assert internal service state.
+            QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion =
+                    new QualifiedTelephonyTimeZoneSuggestion(
+                            lowQualitySuggestion2, testCase.expectedScore);
+            assertEquals(expectedScoredSuggestion,
+                    mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1));
+            assertEquals(expectedScoredSuggestion,
+                    mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests());
+        }
     }
 
     /**
diff --git a/services/usb/OWNERS b/services/usb/OWNERS
index 7897a0c..8ee72b5 100644
--- a/services/usb/OWNERS
+++ b/services/usb/OWNERS
@@ -1,4 +1,6 @@
 badhri@google.com
 elaurent@google.com
 moltmann@google.com
-zhangjerry@google.com
+albertccwang@google.com
+jameswei@google.com
+howardyen@google.com
\ No newline at end of file
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index c5fcf67..ead90bb 100755
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -2075,6 +2075,17 @@
 
     /**
      * Returns the child {@link Call} in a generic conference that is currently active.
+     *
+     * A "generic conference" is the mechanism used to support two simultaneous calls on a device
+     * in CDMA networks. It is effectively equivalent to having one call active and one call on hold
+     * in GSM or IMS calls. This method returns the currently active call.
+     *
+     * In a generic conference, the network exposes the conference to us as a single call, and we
+     * switch between talking to the two participants using a CDMA flash command. Since the network
+     * exposes no additional information about the call, the only way we know which caller we're
+     * currently talking to is by keeping track of the flash commands that we've sent to the
+     * network.
+     *
      * For calls that are not generic conferences, or when the generic conference has more than
      * 2 children, returns {@code null}.
      * @see Details#PROPERTY_GENERIC_CONFERENCE
diff --git a/telecomm/java/android/telecom/CallRedirectionService.java b/telecomm/java/android/telecom/CallRedirectionService.java
index 36c6377..c832f53 100644
--- a/telecomm/java/android/telecom/CallRedirectionService.java
+++ b/telecomm/java/android/telecom/CallRedirectionService.java
@@ -38,16 +38,14 @@
  *
  * <p>
  * Below is an example manifest registration for a {@code CallRedirectionService}.
- * <pre>
  * {@code
  * <service android:name="your.package.YourCallRedirectionServiceImplementation"
- *          android:permission="android.permission.BIND_REDIRECTION_SERVICE">
+ *          android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE">
  *      <intent-filter>
  *          <action android:name="android.telecom.CallRedirectionService"/>
  *      </intent-filter>
  * </service>
  * }
- * </pre>
  */
 public abstract class CallRedirectionService extends Service {
     /**
diff --git a/telecomm/java/android/telecom/ParcelableCallAnalytics.java b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
index 2b9213b..b8ad9e2 100644
--- a/telecomm/java/android/telecom/ParcelableCallAnalytics.java
+++ b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
@@ -258,27 +258,6 @@
     public static final int SIP_PHONE = 0x8;
     public static final int THIRD_PARTY_PHONE = 0x10;
 
-    /**
-     * Indicating the call source is not specified.
-     *
-     * @hide
-     */
-    public static final int CALL_SOURCE_UNSPECIFIED = 0;
-
-    /**
-     * Indicating the call is initiated via emergency dialer's dialpad.
-     *
-     * @hide
-     */
-    public static final int CALL_SOURCE_EMERGENCY_DIALPAD = 1;
-
-    /**
-     * Indicating the call is initiated via emergency dialer's shortcut button.
-     *
-     * @hide
-     */
-    public static final int CALL_SOURCE_EMERGENCY_SHORTCUT = 2;
-
     public static final long MILLIS_IN_5_MINUTES = 1000 * 60 * 5;
     public static final long MILLIS_IN_1_SECOND = 1000;
 
@@ -343,7 +322,7 @@
     private List<VideoEvent> videoEvents;
 
     // The source where user initiated this call. ONE OF the CALL_SOURCE_* constants.
-    private int callSource = CALL_SOURCE_UNSPECIFIED;
+    private int callSource = TelecomManager.CALL_SOURCE_UNSPECIFIED;
 
     public ParcelableCallAnalytics(long startTimeMillis, long callDurationMillis, int callType,
             boolean isAdditionalCall, boolean isInterrupted, int callTechnologies,
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index 6ae4a08..768c8ee 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -82,8 +82,10 @@
     public static final String EXTRA_CALL_SUBJECT_CHARACTER_ENCODING =
             "android.telecom.extra.CALL_SUBJECT_CHARACTER_ENCODING";
 
-     /**
-     * Indicating flag for phone account whether to use voip audio mode for voip calls
+    /**
+     * Boolean {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which
+     * indicates that all calls from this {@link PhoneAccount} should be treated as VoIP calls
+     * rather than cellular calls.
      * @hide
      */
     public static final String EXTRA_ALWAYS_USE_VOIP_AUDIO_MODE =
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 19a1021e..8be146d 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -312,6 +312,9 @@
             "android.telecom.extra.IS_USER_INTENT_EMERGENCY_CALL";
 
     /**
+     * A mandatory extra containing a {@link Uri} to be passed in when calling
+     * {@link #addNewUnknownCall(PhoneAccountHandle, Bundle)}. The {@link Uri} value indicates
+     * the remote handle of the new call.
      * @hide
      */
     public static final String EXTRA_UNKNOWN_CALL_HANDLE =
@@ -373,8 +376,15 @@
             "android.telecom.extra.CONNECTION_SERVICE";
 
     /**
-     * Optional extra for communicating the call technology used by a
-     * {@link com.android.internal.telephony.Connection} to Telecom
+     * Optional extra for communicating the call technology used by a {@link ConnectionService}
+     * to Telecom. Valid values are:
+     * <ul>
+     *     <li>{@link TelephonyManager#PHONE_TYPE_CDMA}</li>
+     *     <li>{@link TelephonyManager#PHONE_TYPE_GSM}</li>
+     *     <li>{@link TelephonyManager#PHONE_TYPE_IMS}</li>
+     *     <li>{@link TelephonyManager#PHONE_TYPE_THIRD_PARTY}</li>
+     *     <li>{@link TelephonyManager#PHONE_TYPE_SIP}</li>
+     * </ul>
      * @hide
      */
     public static final String EXTRA_CALL_TECHNOLOGY_TYPE =
@@ -725,15 +735,16 @@
     /**
      * The lookup key for an int that indicates the current TTY mode.
      * Valid modes are:
-     * - {@link #TTY_MODE_OFF}
-     * - {@link #TTY_MODE_FULL}
-     * - {@link #TTY_MODE_HCO}
-     * - {@link #TTY_MODE_VCO}
-     *
+     * <ul>
+     *     <li>{@link #TTY_MODE_OFF}</li>
+     *     <li>{@link #TTY_MODE_FULL}</li>
+     *     <li>{@link #TTY_MODE_HCO}</li>
+     *     <li>{@link #TTY_MODE_VCO}</li>
+     * </ul>
      * @hide
      */
     public static final String EXTRA_CURRENT_TTY_MODE =
-            "android.telecom.intent.extra.CURRENT_TTY_MODE";
+            "android.telecom.extra.CURRENT_TTY_MODE";
 
     /**
      * Broadcast intent action indicating that the TTY preferred operating mode has changed. An
@@ -753,7 +764,7 @@
      * @hide
      */
     public static final String EXTRA_TTY_PREFERRED_MODE =
-            "android.telecom.intent.extra.TTY_PREFERRED";
+            "android.telecom.extra.TTY_PREFERRED_MODE";
 
     /**
      * Broadcast intent action for letting custom component know to show the missed call
@@ -822,16 +833,37 @@
     /**
      * Optional extra for {@link #placeCall(Uri, Bundle)} containing an integer that specifies
      * the source where user initiated this call. This data is used in metrics.
-     * Valid source are:
-     * {@link ParcelableCallAnalytics#CALL_SOURCE_UNSPECIFIED},
-     * {@link ParcelableCallAnalytics#CALL_SOURCE_EMERGENCY_DIALPAD},
-     * {@link ParcelableCallAnalytics#CALL_SOURCE_EMERGENCY_SHORTCUT}.
+     * Valid sources are:
+     * {@link TelecomManager#CALL_SOURCE_UNSPECIFIED},
+     * {@link TelecomManager#CALL_SOURCE_EMERGENCY_DIALPAD},
+     * {@link TelecomManager#CALL_SOURCE_EMERGENCY_SHORTCUT}.
      *
      * @hide
      */
     public static final String EXTRA_CALL_SOURCE = "android.telecom.extra.CALL_SOURCE";
 
     /**
+     * Indicating the call is initiated via emergency dialer's shortcut button.
+     *
+     * @hide
+     */
+    public static final int CALL_SOURCE_EMERGENCY_SHORTCUT = 2;
+
+    /**
+     * Indicating the call is initiated via emergency dialer's dialpad.
+     *
+     * @hide
+     */
+    public static final int CALL_SOURCE_EMERGENCY_DIALPAD = 1;
+
+    /**
+     * Indicating the call source is not specified.
+     *
+     * @hide
+     */
+    public static final int CALL_SOURCE_UNSPECIFIED = 0;
+
+    /**
      * The following 4 constants define how properties such as phone numbers and names are
      * displayed to the user.
      */
diff --git a/telephony/OWNERS b/telephony/OWNERS
index 58a7ea0..628c480 100644
--- a/telephony/OWNERS
+++ b/telephony/OWNERS
@@ -1,18 +1,16 @@
 set noparent
 
-tgunn@google.com
-breadley@google.com
-hallliu@google.com
-rgreenwalt@google.com
-mpq@google.com
 amitmahajan@google.com
+breadley@google.com
 fionaxu@google.com
 jackyu@google.com
+hallliu@google.com
+rgreenwalt@google.com
+tgunn@google.com
 jminjie@google.com
-satk@google.com
 shuoq@google.com
 refuhoo@google.com
-paulye@google.com
 nazaninb@google.com
 sarahchin@google.com
 dbright@google.com
+xiaotonj@google.com
diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt
new file mode 100644
index 0000000..efe586a
--- /dev/null
+++ b/telephony/api/system-current.txt
@@ -0,0 +1,2151 @@
+// Signature format: 2.0
+package android.telephony {
+
+  public final class AccessNetworkConstants {
+    field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff
+  }
+
+  public static final class AccessNetworkConstants.NgranBands {
+    method public static int getFrequencyRangeGroup(int);
+    field public static final int FREQUENCY_RANGE_GROUP_1 = 1; // 0x1
+    field public static final int FREQUENCY_RANGE_GROUP_2 = 2; // 0x2
+    field public static final int FREQUENCY_RANGE_GROUP_UNKNOWN = 0; // 0x0
+  }
+
+  public final class BarringInfo implements android.os.Parcelable {
+    ctor public BarringInfo();
+    method @NonNull public android.telephony.BarringInfo createLocationInfoSanitizedCopy();
+  }
+
+  public final class CallAttributes implements android.os.Parcelable {
+    ctor public CallAttributes(@NonNull android.telephony.PreciseCallState, int, @NonNull android.telephony.CallQuality);
+    method public int describeContents();
+    method @NonNull public android.telephony.CallQuality getCallQuality();
+    method public int getNetworkType();
+    method @NonNull public android.telephony.PreciseCallState getPreciseCallState();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
+  }
+
+  public final class CallQuality implements android.os.Parcelable {
+    ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int);
+    ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int, boolean, boolean, boolean);
+    method public int describeContents();
+    method public int getAverageRelativeJitter();
+    method public int getAverageRoundTripTime();
+    method public int getCallDuration();
+    method public int getCodecType();
+    method public int getDownlinkCallQualityLevel();
+    method public int getMaxRelativeJitter();
+    method public int getNumRtpPacketsNotReceived();
+    method public int getNumRtpPacketsReceived();
+    method public int getNumRtpPacketsTransmitted();
+    method public int getNumRtpPacketsTransmittedLost();
+    method public int getUplinkCallQualityLevel();
+    method public boolean isIncomingSilenceDetected();
+    method public boolean isOutgoingSilenceDetected();
+    method public boolean isRtpInactivityDetected();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CALL_QUALITY_BAD = 4; // 0x4
+    field public static final int CALL_QUALITY_EXCELLENT = 0; // 0x0
+    field public static final int CALL_QUALITY_FAIR = 2; // 0x2
+    field public static final int CALL_QUALITY_GOOD = 1; // 0x1
+    field public static final int CALL_QUALITY_NOT_AVAILABLE = 5; // 0x5
+    field public static final int CALL_QUALITY_POOR = 3; // 0x3
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallQuality> CREATOR;
+  }
+
+  public class CarrierConfigManager {
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDefaultCarrierServicePackageName();
+    method @NonNull public static android.os.PersistableBundle getDefaultConfig();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void updateConfigForPhoneId(int, String);
+    field public static final String KEY_CARRIER_SETUP_APP_STRING = "carrier_setup_app_string";
+    field public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool";
+  }
+
+  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.";
+  }
+
+  public final class CarrierRestrictionRules implements android.os.Parcelable {
+    method @NonNull public java.util.List<java.lang.Boolean> areCarrierIdentifiersAllowed(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
+    method public int describeContents();
+    method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers();
+    method public int getDefaultCarrierRestriction();
+    method @NonNull public java.util.List<android.service.carrier.CarrierIdentifier> getExcludedCarriers();
+    method public int getMultiSimPolicy();
+    method public boolean isAllCarriersAllowed();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CARRIER_RESTRICTION_DEFAULT_ALLOWED = 1; // 0x1
+    field public static final int CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED = 0; // 0x0
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CarrierRestrictionRules> CREATOR;
+    field public static final int MULTISIM_POLICY_NONE = 0; // 0x0
+    field public static final int MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT = 1; // 0x1
+  }
+
+  public static final class CarrierRestrictionRules.Builder {
+    ctor public CarrierRestrictionRules.Builder();
+    method @NonNull public android.telephony.CarrierRestrictionRules build();
+    method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllCarriersAllowed();
+    method @NonNull public android.telephony.CarrierRestrictionRules.Builder setAllowedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
+    method @NonNull public android.telephony.CarrierRestrictionRules.Builder setDefaultCarrierRestriction(int);
+    method @NonNull public android.telephony.CarrierRestrictionRules.Builder setExcludedCarriers(@NonNull java.util.List<android.service.carrier.CarrierIdentifier>);
+    method @NonNull public android.telephony.CarrierRestrictionRules.Builder setMultiSimPolicy(int);
+  }
+
+  public class CbGeoUtils {
+  }
+
+  public static class CbGeoUtils.Circle implements android.telephony.CbGeoUtils.Geometry {
+    ctor public CbGeoUtils.Circle(@NonNull android.telephony.CbGeoUtils.LatLng, double);
+    method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng);
+    method @NonNull public android.telephony.CbGeoUtils.LatLng getCenter();
+    method public double getRadius();
+  }
+
+  public static interface CbGeoUtils.Geometry {
+    method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng);
+  }
+
+  public static class CbGeoUtils.LatLng {
+    ctor public CbGeoUtils.LatLng(double, double);
+    method public double distance(@NonNull android.telephony.CbGeoUtils.LatLng);
+    method @NonNull public android.telephony.CbGeoUtils.LatLng subtract(@NonNull android.telephony.CbGeoUtils.LatLng);
+    field public final double lat;
+    field public final double lng;
+  }
+
+  public static class CbGeoUtils.Polygon implements android.telephony.CbGeoUtils.Geometry {
+    ctor public CbGeoUtils.Polygon(@NonNull java.util.List<android.telephony.CbGeoUtils.LatLng>);
+    method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng);
+    method @NonNull public java.util.List<android.telephony.CbGeoUtils.LatLng> getVertices();
+  }
+
+  public abstract class CellBroadcastService extends android.app.Service {
+    ctor public CellBroadcastService();
+    method @NonNull @WorkerThread public abstract CharSequence getCellBroadcastAreaInfo(int);
+    method public android.os.IBinder onBind(@Nullable android.content.Intent);
+    method public abstract void onCdmaCellBroadcastSms(int, @NonNull byte[], int);
+    method public abstract void onCdmaScpMessage(int, @NonNull java.util.List<android.telephony.cdma.CdmaSmsCbProgramData>, @NonNull String, @NonNull java.util.function.Consumer<android.os.Bundle>);
+    method public abstract void onGsmCellBroadcastSms(int, @NonNull byte[]);
+    field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService";
+  }
+
+  public abstract class CellIdentity implements android.os.Parcelable {
+    method @NonNull public abstract android.telephony.CellLocation asCellLocation();
+    method @NonNull public abstract android.telephony.CellIdentity sanitizeLocationInfo();
+  }
+
+  public final class CellIdentityCdma extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation();
+    method @NonNull public android.telephony.CellIdentityCdma sanitizeLocationInfo();
+  }
+
+  public final class CellIdentityGsm extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+    method @NonNull public android.telephony.CellIdentityGsm sanitizeLocationInfo();
+  }
+
+  public final class CellIdentityLte extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+    method @NonNull public android.telephony.CellIdentityLte sanitizeLocationInfo();
+  }
+
+  public final class CellIdentityNr extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.CellLocation asCellLocation();
+    method @NonNull public android.telephony.CellIdentityNr sanitizeLocationInfo();
+  }
+
+  public final class CellIdentityTdscdma extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+    method @NonNull public android.telephony.CellIdentityTdscdma sanitizeLocationInfo();
+  }
+
+  public final class CellIdentityWcdma extends android.telephony.CellIdentity {
+    method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+    method @NonNull public android.telephony.CellIdentityWcdma sanitizeLocationInfo();
+  }
+
+  public final class DataFailCause {
+    field @Deprecated public static final int VSNCP_APN_UNATHORIZED = 2238; // 0x8be
+  }
+
+  public final class DataSpecificRegistrationInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
+  }
+
+  public final class DisconnectCause {
+    field public static final int ALREADY_DIALING = 72; // 0x48
+    field public static final int ANSWERED_ELSEWHERE = 52; // 0x34
+    field public static final int BUSY = 4; // 0x4
+    field public static final int CALLING_DISABLED = 74; // 0x4a
+    field public static final int CALL_BARRED = 20; // 0x14
+    field public static final int CALL_PULLED = 51; // 0x33
+    field public static final int CANT_CALL_WHILE_RINGING = 73; // 0x49
+    field public static final int CDMA_ACCESS_BLOCKED = 35; // 0x23
+    field public static final int CDMA_ACCESS_FAILURE = 32; // 0x20
+    field public static final int CDMA_ALREADY_ACTIVATED = 49; // 0x31
+    field public static final int CDMA_DROP = 27; // 0x1b
+    field public static final int CDMA_INTERCEPT = 28; // 0x1c
+    field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 26; // 0x1a
+    field public static final int CDMA_NOT_EMERGENCY = 34; // 0x22
+    field public static final int CDMA_PREEMPTED = 33; // 0x21
+    field public static final int CDMA_REORDER = 29; // 0x1d
+    field public static final int CDMA_RETRY_ORDER = 31; // 0x1f
+    field public static final int CDMA_SO_REJECT = 30; // 0x1e
+    field public static final int CONGESTION = 5; // 0x5
+    field public static final int CS_RESTRICTED = 22; // 0x16
+    field public static final int CS_RESTRICTED_EMERGENCY = 24; // 0x18
+    field public static final int CS_RESTRICTED_NORMAL = 23; // 0x17
+    field public static final int DATA_DISABLED = 54; // 0x36
+    field public static final int DATA_LIMIT_REACHED = 55; // 0x37
+    field public static final int DIALED_CALL_FORWARDING_WHILE_ROAMING = 57; // 0x39
+    field public static final int DIALED_MMI = 39; // 0x27
+    field public static final int DIAL_LOW_BATTERY = 62; // 0x3e
+    field public static final int DIAL_MODIFIED_TO_DIAL = 48; // 0x30
+    field public static final int DIAL_MODIFIED_TO_DIAL_VIDEO = 66; // 0x42
+    field public static final int DIAL_MODIFIED_TO_SS = 47; // 0x2f
+    field public static final int DIAL_MODIFIED_TO_USSD = 46; // 0x2e
+    field public static final int DIAL_VIDEO_MODIFIED_TO_DIAL = 69; // 0x45
+    field public static final int DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 70; // 0x46
+    field public static final int DIAL_VIDEO_MODIFIED_TO_SS = 67; // 0x43
+    field public static final int DIAL_VIDEO_MODIFIED_TO_USSD = 68; // 0x44
+    field public static final int EMERGENCY_PERM_FAILURE = 64; // 0x40
+    field public static final int EMERGENCY_TEMP_FAILURE = 63; // 0x3f
+    field public static final int ERROR_UNSPECIFIED = 36; // 0x24
+    field public static final int FDN_BLOCKED = 21; // 0x15
+    field public static final int ICC_ERROR = 19; // 0x13
+    field public static final int IMEI_NOT_ACCEPTED = 58; // 0x3a
+    field public static final int IMS_ACCESS_BLOCKED = 60; // 0x3c
+    field public static final int IMS_MERGED_SUCCESSFULLY = 45; // 0x2d
+    field public static final int IMS_SIP_ALTERNATE_EMERGENCY_CALL = 71; // 0x47
+    field public static final int INCOMING_AUTO_REJECTED = 81; // 0x51
+    field public static final int INCOMING_MISSED = 1; // 0x1
+    field public static final int INCOMING_REJECTED = 16; // 0x10
+    field public static final int INVALID_CREDENTIALS = 10; // 0xa
+    field public static final int INVALID_NUMBER = 7; // 0x7
+    field public static final int LIMIT_EXCEEDED = 15; // 0xf
+    field public static final int LOCAL = 3; // 0x3
+    field public static final int LOST_SIGNAL = 14; // 0xe
+    field public static final int LOW_BATTERY = 61; // 0x3d
+    field public static final int MAXIMUM_NUMBER_OF_CALLS_REACHED = 53; // 0x35
+    field public static final int MMI = 6; // 0x6
+    field public static final int NORMAL = 2; // 0x2
+    field public static final int NORMAL_UNSPECIFIED = 65; // 0x41
+    field public static final int NOT_DISCONNECTED = 0; // 0x0
+    field public static final int NOT_VALID = -1; // 0xffffffff
+    field public static final int NO_PHONE_NUMBER_SUPPLIED = 38; // 0x26
+    field public static final int NUMBER_UNREACHABLE = 8; // 0x8
+    field public static final int OTASP_PROVISIONING_IN_PROCESS = 76; // 0x4c
+    field public static final int OUTGOING_CANCELED = 44; // 0x2c
+    field public static final int OUTGOING_EMERGENCY_CALL_PLACED = 80; // 0x50
+    field public static final int OUTGOING_FAILURE = 43; // 0x2b
+    field public static final int OUT_OF_NETWORK = 11; // 0xb
+    field public static final int OUT_OF_SERVICE = 18; // 0x12
+    field public static final int POWER_OFF = 17; // 0x11
+    field public static final int SERVER_ERROR = 12; // 0xc
+    field public static final int SERVER_UNREACHABLE = 9; // 0x9
+    field public static final int TIMED_OUT = 13; // 0xd
+    field public static final int TOO_MANY_ONGOING_CALLS = 75; // 0x4b
+    field public static final int UNOBTAINABLE_NUMBER = 25; // 0x19
+    field public static final int VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED = 50; // 0x32
+    field public static final int VOICEMAIL_NUMBER_MISSING = 40; // 0x28
+    field public static final int WIFI_LOST = 59; // 0x3b
+  }
+
+  public final class ImsiEncryptionInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public String getKeyIdentifier();
+    method @Nullable public java.security.PublicKey getPublicKey();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ImsiEncryptionInfo> CREATOR;
+  }
+
+  public final class LteVopsSupportInfo implements android.os.Parcelable {
+    ctor public LteVopsSupportInfo(int, int);
+    method public int describeContents();
+    method public int getEmcBearerSupport();
+    method public int getVopsSupport();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.LteVopsSupportInfo> CREATOR;
+    field public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1
+    field public static final int LTE_STATUS_NOT_SUPPORTED = 3; // 0x3
+    field public static final int LTE_STATUS_SUPPORTED = 2; // 0x2
+  }
+
+  public class MbmsDownloadSession implements java.lang.AutoCloseable {
+    field public static final String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload";
+  }
+
+  public class MbmsGroupCallSession implements java.lang.AutoCloseable {
+    field public static final String MBMS_GROUP_CALL_SERVICE_ACTION = "android.telephony.action.EmbmsGroupCall";
+  }
+
+  public class MbmsStreamingSession implements java.lang.AutoCloseable {
+    field public static final String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming";
+  }
+
+  public final class ModemActivityInfo implements android.os.Parcelable {
+    ctor public ModemActivityInfo(long, int, int, @NonNull int[], int);
+    method public int describeContents();
+    method public int getIdleTimeMillis();
+    method public int getReceiveTimeMillis();
+    method public int getSleepTimeMillis();
+    method public long getTimestamp();
+    method @NonNull public java.util.List<android.telephony.ModemActivityInfo.TransmitPower> getTransmitPowerInfo();
+    method public boolean isValid();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ModemActivityInfo> CREATOR;
+    field public static final int TX_POWER_LEVELS = 5; // 0x5
+    field public static final int TX_POWER_LEVEL_0 = 0; // 0x0
+    field public static final int TX_POWER_LEVEL_1 = 1; // 0x1
+    field public static final int TX_POWER_LEVEL_2 = 2; // 0x2
+    field public static final int TX_POWER_LEVEL_3 = 3; // 0x3
+    field public static final int TX_POWER_LEVEL_4 = 4; // 0x4
+  }
+
+  public class ModemActivityInfo.TransmitPower {
+    method @NonNull public android.util.Range<java.lang.Integer> getPowerRangeInDbm();
+    method public int getTimeInMillis();
+  }
+
+  public final class NetworkRegistrationInfo implements android.os.Parcelable {
+    method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
+    method public int getRegistrationState();
+    method public int getRejectCause();
+    method public int getRoamingType();
+    method public boolean isEmergencyEnabled();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3
+    field public static final int REGISTRATION_STATE_HOME = 1; // 0x1
+    field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0
+    field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2
+    field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5
+    field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4
+  }
+
+  public static final class NetworkRegistrationInfo.Builder {
+    ctor public NetworkRegistrationInfo.Builder();
+    method @NonNull public android.telephony.NetworkRegistrationInfo build();
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAccessNetworkTechnology(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAvailableServices(@NonNull java.util.List<java.lang.Integer>);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegisteredPlmn(@Nullable String);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int);
+  }
+
+  public abstract class NetworkService extends android.app.Service {
+    ctor public NetworkService();
+    method public android.os.IBinder onBind(android.content.Intent);
+    method @Nullable public abstract android.telephony.NetworkService.NetworkServiceProvider onCreateNetworkServiceProvider(int);
+    field public static final String SERVICE_INTERFACE = "android.telephony.NetworkService";
+  }
+
+  public abstract class NetworkService.NetworkServiceProvider implements java.lang.AutoCloseable {
+    ctor public NetworkService.NetworkServiceProvider(int);
+    method public abstract void close();
+    method public final int getSlotIndex();
+    method public final void notifyNetworkRegistrationInfoChanged();
+    method public void requestNetworkRegistrationInfo(int, @NonNull android.telephony.NetworkServiceCallback);
+  }
+
+  public class NetworkServiceCallback {
+    method public void onRequestNetworkRegistrationInfoComplete(int, @Nullable android.telephony.NetworkRegistrationInfo);
+    field public static final int RESULT_ERROR_BUSY = 3; // 0x3
+    field public static final int RESULT_ERROR_FAILED = 5; // 0x5
+    field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4
+    field public static final int RESULT_ERROR_INVALID_ARG = 2; // 0x2
+    field public static final int RESULT_ERROR_UNSUPPORTED = 1; // 0x1
+    field public static final int RESULT_SUCCESS = 0; // 0x0
+  }
+
+  public interface NumberVerificationCallback {
+    method public default void onCallReceived(@NonNull String);
+    method public default void onVerificationFailed(int);
+    field public static final int REASON_CONCURRENT_REQUESTS = 4; // 0x4
+    field public static final int REASON_IN_ECBM = 5; // 0x5
+    field public static final int REASON_IN_EMERGENCY_CALL = 6; // 0x6
+    field public static final int REASON_NETWORK_NOT_AVAILABLE = 2; // 0x2
+    field public static final int REASON_TIMED_OUT = 1; // 0x1
+    field public static final int REASON_TOO_MANY_CALLS = 3; // 0x3
+    field public static final int REASON_UNSPECIFIED = 0; // 0x0
+  }
+
+  public final class PhoneNumberRange implements android.os.Parcelable {
+    ctor public PhoneNumberRange(@NonNull String, @NonNull String, @NonNull String, @NonNull String);
+    method public int describeContents();
+    method public boolean matches(@NonNull String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhoneNumberRange> CREATOR;
+  }
+
+  public class PhoneNumberUtils {
+    method @NonNull public static String getUsernameFromUriNumber(@NonNull String);
+    method public static boolean isUriNumber(@Nullable String);
+    method public static boolean isVoiceMailNumber(@NonNull android.content.Context, int, @Nullable String);
+  }
+
+  public final class PreciseCallState implements android.os.Parcelable {
+    ctor public PreciseCallState(int, int, int, int, int);
+    method public int describeContents();
+    method public int getBackgroundCallState();
+    method public int getForegroundCallState();
+    method public int getRingingCallState();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseCallState> CREATOR;
+    field public static final int PRECISE_CALL_STATE_ACTIVE = 1; // 0x1
+    field public static final int PRECISE_CALL_STATE_ALERTING = 4; // 0x4
+    field public static final int PRECISE_CALL_STATE_DIALING = 3; // 0x3
+    field public static final int PRECISE_CALL_STATE_DISCONNECTED = 7; // 0x7
+    field public static final int PRECISE_CALL_STATE_DISCONNECTING = 8; // 0x8
+    field public static final int PRECISE_CALL_STATE_HOLDING = 2; // 0x2
+    field public static final int PRECISE_CALL_STATE_IDLE = 0; // 0x0
+    field public static final int PRECISE_CALL_STATE_INCOMING = 5; // 0x5
+    field public static final int PRECISE_CALL_STATE_NOT_VALID = -1; // 0xffffffff
+    field public static final int PRECISE_CALL_STATE_WAITING = 6; // 0x6
+  }
+
+  public final class PreciseDataConnectionState implements android.os.Parcelable {
+    method @Deprecated @NonNull public String getDataConnectionApn();
+    method @Deprecated public int getDataConnectionApnTypeBitMask();
+    method @Deprecated public int getDataConnectionFailCause();
+    method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties();
+    method @Deprecated public int getDataConnectionNetworkType();
+    method @Deprecated public int getDataConnectionState();
+  }
+
+  public final class PreciseDisconnectCause {
+    field public static final int ACCESS_CLASS_BLOCKED = 260; // 0x104
+    field public static final int ACCESS_INFORMATION_DISCARDED = 43; // 0x2b
+    field public static final int ACM_LIMIT_EXCEEDED = 68; // 0x44
+    field public static final int BEARER_CAPABILITY_NOT_AUTHORIZED = 57; // 0x39
+    field public static final int BEARER_NOT_AVAIL = 58; // 0x3a
+    field public static final int BEARER_SERVICE_NOT_IMPLEMENTED = 65; // 0x41
+    field public static final int BUSY = 17; // 0x11
+    field public static final int CALL_BARRED = 240; // 0xf0
+    field public static final int CALL_REJECTED = 21; // 0x15
+    field public static final int CDMA_ACCESS_BLOCKED = 1009; // 0x3f1
+    field public static final int CDMA_ACCESS_FAILURE = 1006; // 0x3ee
+    field public static final int CDMA_DROP = 1001; // 0x3e9
+    field public static final int CDMA_INTERCEPT = 1002; // 0x3ea
+    field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; // 0x3e8
+    field public static final int CDMA_NOT_EMERGENCY = 1008; // 0x3f0
+    field public static final int CDMA_PREEMPTED = 1007; // 0x3ef
+    field public static final int CDMA_REORDER = 1003; // 0x3eb
+    field public static final int CDMA_RETRY_ORDER = 1005; // 0x3ed
+    field public static final int CDMA_SO_REJECT = 1004; // 0x3ec
+    field public static final int CHANNEL_NOT_AVAIL = 44; // 0x2c
+    field public static final int CHANNEL_UNACCEPTABLE = 6; // 0x6
+    field public static final int CONDITIONAL_IE_ERROR = 100; // 0x64
+    field public static final int DESTINATION_OUT_OF_ORDER = 27; // 0x1b
+    field public static final int ERROR_UNSPECIFIED = 65535; // 0xffff
+    field public static final int FACILITY_REJECTED = 29; // 0x1d
+    field public static final int FDN_BLOCKED = 241; // 0xf1
+    field public static final int IMEI_NOT_ACCEPTED = 243; // 0xf3
+    field public static final int IMSI_UNKNOWN_IN_VLR = 242; // 0xf2
+    field public static final int INCOMING_CALLS_BARRED_WITHIN_CUG = 55; // 0x37
+    field public static final int INCOMPATIBLE_DESTINATION = 88; // 0x58
+    field public static final int INFORMATION_ELEMENT_NON_EXISTENT = 99; // 0x63
+    field public static final int INTERWORKING_UNSPECIFIED = 127; // 0x7f
+    field public static final int INVALID_MANDATORY_INFORMATION = 96; // 0x60
+    field public static final int INVALID_NUMBER_FORMAT = 28; // 0x1c
+    field public static final int INVALID_TRANSACTION_IDENTIFIER = 81; // 0x51
+    field public static final int MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101; // 0x65
+    field public static final int MESSAGE_TYPE_NON_IMPLEMENTED = 97; // 0x61
+    field public static final int MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98; // 0x62
+    field public static final int NETWORK_DETACH = 261; // 0x105
+    field public static final int NETWORK_OUT_OF_ORDER = 38; // 0x26
+    field public static final int NETWORK_REJECT = 252; // 0xfc
+    field public static final int NETWORK_RESP_TIMEOUT = 251; // 0xfb
+    field public static final int NORMAL = 16; // 0x10
+    field public static final int NORMAL_UNSPECIFIED = 31; // 0x1f
+    field public static final int NOT_VALID = -1; // 0xffffffff
+    field public static final int NO_ANSWER_FROM_USER = 19; // 0x13
+    field public static final int NO_CIRCUIT_AVAIL = 34; // 0x22
+    field public static final int NO_DISCONNECT_CAUSE_AVAILABLE = 0; // 0x0
+    field public static final int NO_ROUTE_TO_DESTINATION = 3; // 0x3
+    field public static final int NO_USER_RESPONDING = 18; // 0x12
+    field public static final int NO_VALID_SIM = 249; // 0xf9
+    field public static final int NUMBER_CHANGED = 22; // 0x16
+    field public static final int OEM_CAUSE_1 = 61441; // 0xf001
+    field public static final int OEM_CAUSE_10 = 61450; // 0xf00a
+    field public static final int OEM_CAUSE_11 = 61451; // 0xf00b
+    field public static final int OEM_CAUSE_12 = 61452; // 0xf00c
+    field public static final int OEM_CAUSE_13 = 61453; // 0xf00d
+    field public static final int OEM_CAUSE_14 = 61454; // 0xf00e
+    field public static final int OEM_CAUSE_15 = 61455; // 0xf00f
+    field public static final int OEM_CAUSE_2 = 61442; // 0xf002
+    field public static final int OEM_CAUSE_3 = 61443; // 0xf003
+    field public static final int OEM_CAUSE_4 = 61444; // 0xf004
+    field public static final int OEM_CAUSE_5 = 61445; // 0xf005
+    field public static final int OEM_CAUSE_6 = 61446; // 0xf006
+    field public static final int OEM_CAUSE_7 = 61447; // 0xf007
+    field public static final int OEM_CAUSE_8 = 61448; // 0xf008
+    field public static final int OEM_CAUSE_9 = 61449; // 0xf009
+    field public static final int ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70; // 0x46
+    field public static final int OPERATOR_DETERMINED_BARRING = 8; // 0x8
+    field public static final int OUT_OF_SRV = 248; // 0xf8
+    field public static final int PREEMPTION = 25; // 0x19
+    field public static final int PROTOCOL_ERROR_UNSPECIFIED = 111; // 0x6f
+    field public static final int QOS_NOT_AVAIL = 49; // 0x31
+    field public static final int RADIO_ACCESS_FAILURE = 253; // 0xfd
+    field public static final int RADIO_INTERNAL_ERROR = 250; // 0xfa
+    field public static final int RADIO_LINK_FAILURE = 254; // 0xfe
+    field public static final int RADIO_LINK_LOST = 255; // 0xff
+    field public static final int RADIO_OFF = 247; // 0xf7
+    field public static final int RADIO_RELEASE_ABNORMAL = 259; // 0x103
+    field public static final int RADIO_RELEASE_NORMAL = 258; // 0x102
+    field public static final int RADIO_SETUP_FAILURE = 257; // 0x101
+    field public static final int RADIO_UPLINK_FAILURE = 256; // 0x100
+    field public static final int RECOVERY_ON_TIMER_EXPIRED = 102; // 0x66
+    field public static final int REQUESTED_FACILITY_NOT_IMPLEMENTED = 69; // 0x45
+    field public static final int REQUESTED_FACILITY_NOT_SUBSCRIBED = 50; // 0x32
+    field public static final int RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47; // 0x2f
+    field public static final int SEMANTICALLY_INCORRECT_MESSAGE = 95; // 0x5f
+    field public static final int SERVICE_OPTION_NOT_AVAILABLE = 63; // 0x3f
+    field public static final int SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79; // 0x4f
+    field public static final int STATUS_ENQUIRY = 30; // 0x1e
+    field public static final int SWITCHING_CONGESTION = 42; // 0x2a
+    field public static final int TEMPORARY_FAILURE = 41; // 0x29
+    field public static final int UNOBTAINABLE_NUMBER = 1; // 0x1
+    field public static final int USER_NOT_MEMBER_OF_CUG = 87; // 0x57
+  }
+
+  public class ServiceState implements android.os.Parcelable {
+    method public void fillInNotifierBundle(@NonNull android.os.Bundle);
+    method @Nullable public android.telephony.NetworkRegistrationInfo getNetworkRegistrationInfo(int, int);
+    method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int);
+    method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int);
+    method @NonNull public static android.telephony.ServiceState newFromBundle(@NonNull android.os.Bundle);
+    field public static final int ROAMING_TYPE_DOMESTIC = 2; // 0x2
+    field public static final int ROAMING_TYPE_INTERNATIONAL = 3; // 0x3
+    field public static final int ROAMING_TYPE_NOT_ROAMING = 0; // 0x0
+    field public static final int ROAMING_TYPE_UNKNOWN = 1; // 0x1
+  }
+
+  public class SignalStrength implements android.os.Parcelable {
+    ctor public SignalStrength(@NonNull android.telephony.SignalStrength);
+  }
+
+  public final class SmsCbCmasInfo implements android.os.Parcelable {
+    ctor public SmsCbCmasInfo(int, int, int, int, int, int);
+    method public int describeContents();
+    method public int getCategory();
+    method public int getCertainty();
+    method public int getMessageClass();
+    method public int getResponseType();
+    method public int getSeverity();
+    method public int getUrgency();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CMAS_CATEGORY_CBRNE = 10; // 0xa
+    field public static final int CMAS_CATEGORY_ENV = 7; // 0x7
+    field public static final int CMAS_CATEGORY_FIRE = 5; // 0x5
+    field public static final int CMAS_CATEGORY_GEO = 0; // 0x0
+    field public static final int CMAS_CATEGORY_HEALTH = 6; // 0x6
+    field public static final int CMAS_CATEGORY_INFRA = 9; // 0x9
+    field public static final int CMAS_CATEGORY_MET = 1; // 0x1
+    field public static final int CMAS_CATEGORY_OTHER = 11; // 0xb
+    field public static final int CMAS_CATEGORY_RESCUE = 4; // 0x4
+    field public static final int CMAS_CATEGORY_SAFETY = 2; // 0x2
+    field public static final int CMAS_CATEGORY_SECURITY = 3; // 0x3
+    field public static final int CMAS_CATEGORY_TRANSPORT = 8; // 0x8
+    field public static final int CMAS_CATEGORY_UNKNOWN = -1; // 0xffffffff
+    field public static final int CMAS_CERTAINTY_LIKELY = 1; // 0x1
+    field public static final int CMAS_CERTAINTY_OBSERVED = 0; // 0x0
+    field public static final int CMAS_CERTAINTY_UNKNOWN = -1; // 0xffffffff
+    field public static final int CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY = 3; // 0x3
+    field public static final int CMAS_CLASS_CMAS_EXERCISE = 5; // 0x5
+    field public static final int CMAS_CLASS_EXTREME_THREAT = 1; // 0x1
+    field public static final int CMAS_CLASS_OPERATOR_DEFINED_USE = 6; // 0x6
+    field public static final int CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT = 0; // 0x0
+    field public static final int CMAS_CLASS_REQUIRED_MONTHLY_TEST = 4; // 0x4
+    field public static final int CMAS_CLASS_SEVERE_THREAT = 2; // 0x2
+    field public static final int CMAS_CLASS_UNKNOWN = -1; // 0xffffffff
+    field public static final int CMAS_RESPONSE_TYPE_ASSESS = 6; // 0x6
+    field public static final int CMAS_RESPONSE_TYPE_AVOID = 5; // 0x5
+    field public static final int CMAS_RESPONSE_TYPE_EVACUATE = 1; // 0x1
+    field public static final int CMAS_RESPONSE_TYPE_EXECUTE = 3; // 0x3
+    field public static final int CMAS_RESPONSE_TYPE_MONITOR = 4; // 0x4
+    field public static final int CMAS_RESPONSE_TYPE_NONE = 7; // 0x7
+    field public static final int CMAS_RESPONSE_TYPE_PREPARE = 2; // 0x2
+    field public static final int CMAS_RESPONSE_TYPE_SHELTER = 0; // 0x0
+    field public static final int CMAS_RESPONSE_TYPE_UNKNOWN = -1; // 0xffffffff
+    field public static final int CMAS_SEVERITY_EXTREME = 0; // 0x0
+    field public static final int CMAS_SEVERITY_SEVERE = 1; // 0x1
+    field public static final int CMAS_SEVERITY_UNKNOWN = -1; // 0xffffffff
+    field public static final int CMAS_URGENCY_EXPECTED = 1; // 0x1
+    field public static final int CMAS_URGENCY_IMMEDIATE = 0; // 0x0
+    field public static final int CMAS_URGENCY_UNKNOWN = -1; // 0xffffffff
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbCmasInfo> CREATOR;
+  }
+
+  public final class SmsCbEtwsInfo implements android.os.Parcelable {
+    ctor public SmsCbEtwsInfo(int, boolean, boolean, boolean, @Nullable byte[]);
+    method public int describeContents();
+    method @Nullable public byte[] getPrimaryNotificationSignature();
+    method public long getPrimaryNotificationTimestamp();
+    method public int getWarningType();
+    method public boolean isEmergencyUserAlert();
+    method public boolean isPopupAlert();
+    method public boolean isPrimary();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbEtwsInfo> CREATOR;
+    field public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0; // 0x0
+    field public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 2; // 0x2
+    field public static final int ETWS_WARNING_TYPE_OTHER_EMERGENCY = 4; // 0x4
+    field public static final int ETWS_WARNING_TYPE_TEST_MESSAGE = 3; // 0x3
+    field public static final int ETWS_WARNING_TYPE_TSUNAMI = 1; // 0x1
+    field public static final int ETWS_WARNING_TYPE_UNKNOWN = -1; // 0xffffffff
+  }
+
+  public final class SmsCbLocation implements android.os.Parcelable {
+    ctor public SmsCbLocation(@NonNull String, int, int);
+    method public int describeContents();
+    method public int getCid();
+    method public int getLac();
+    method @NonNull public String getPlmn();
+    method public boolean isInLocationArea(@NonNull android.telephony.SmsCbLocation);
+    method public boolean isInLocationArea(@Nullable String, int, int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbLocation> CREATOR;
+  }
+
+  public final class SmsCbMessage implements android.os.Parcelable {
+    ctor public SmsCbMessage(int, int, int, @NonNull android.telephony.SmsCbLocation, int, @Nullable String, int, @Nullable String, int, @Nullable android.telephony.SmsCbEtwsInfo, @Nullable android.telephony.SmsCbCmasInfo, int, @Nullable java.util.List<android.telephony.CbGeoUtils.Geometry>, long, int, int);
+    method @NonNull public static android.telephony.SmsCbMessage createFromCursor(@NonNull android.database.Cursor);
+    method public int describeContents();
+    method @Nullable public android.telephony.SmsCbCmasInfo getCmasWarningInfo();
+    method @NonNull public android.content.ContentValues getContentValues();
+    method public int getDataCodingScheme();
+    method @Nullable public android.telephony.SmsCbEtwsInfo getEtwsWarningInfo();
+    method public int getGeographicalScope();
+    method @NonNull public java.util.List<android.telephony.CbGeoUtils.Geometry> getGeometries();
+    method @Nullable public String getLanguageCode();
+    method @NonNull public android.telephony.SmsCbLocation getLocation();
+    method public int getMaximumWaitingDuration();
+    method @Nullable public String getMessageBody();
+    method public int getMessageFormat();
+    method public int getMessagePriority();
+    method public long getReceivedTime();
+    method public int getSerialNumber();
+    method public int getServiceCategory();
+    method public int getSlotIndex();
+    method public int getSubscriptionId();
+    method public boolean isCmasMessage();
+    method public boolean isEmergencyMessage();
+    method public boolean isEtwsMessage();
+    method public boolean needGeoFencingCheck();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SmsCbMessage> CREATOR;
+    field public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE = 3; // 0x3
+    field public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0; // 0x0
+    field public static final int GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE = 2; // 0x2
+    field public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1; // 0x1
+    field public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255; // 0xff
+    field public static final int MESSAGE_FORMAT_3GPP = 1; // 0x1
+    field public static final int MESSAGE_FORMAT_3GPP2 = 2; // 0x2
+    field public static final int MESSAGE_PRIORITY_EMERGENCY = 3; // 0x3
+    field public static final int MESSAGE_PRIORITY_INTERACTIVE = 1; // 0x1
+    field public static final int MESSAGE_PRIORITY_NORMAL = 0; // 0x0
+    field public static final int MESSAGE_PRIORITY_URGENT = 2; // 0x2
+  }
+
+  public final class SmsManager {
+    method @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean copyMessageToIcc(@Nullable byte[], @NonNull byte[], int);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean deleteMessageFromIcc(int);
+    method public boolean disableCellBroadcastRange(int, int, int);
+    method public boolean enableCellBroadcastRange(int, int, int);
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public java.util.List<android.telephony.SmsMessage> getMessagesFromIcc();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getPremiumSmsConsent(@NonNull String);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSmsCapacityOnIcc();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPremiumSmsConsent(@NonNull String, int);
+    field public static final int PREMIUM_SMS_CONSENT_ALWAYS_ALLOW = 3; // 0x3
+    field public static final int PREMIUM_SMS_CONSENT_ASK_USER = 1; // 0x1
+    field public static final int PREMIUM_SMS_CONSENT_NEVER_ALLOW = 2; // 0x2
+    field public static final int PREMIUM_SMS_CONSENT_UNKNOWN = 0; // 0x0
+  }
+
+  public class SmsMessage {
+    method @Nullable public static android.telephony.SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[], boolean);
+    method @Nullable public static android.telephony.SmsMessage.SubmitPdu getSmsPdu(int, int, @Nullable String, @NonNull String, @NonNull String, long);
+    method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static byte[] getSubmitPduEncodedMessage(boolean, @NonNull String, @NonNull String, int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0, to=255) int, @IntRange(from=1, to=255) int, @IntRange(from=1, to=255) int);
+  }
+
+  public class SubscriptionInfo implements android.os.Parcelable {
+    method public boolean areUiccApplicationsEnabled();
+    method @Nullable public java.util.List<android.telephony.UiccAccessRule> getAccessRules();
+    method public int getProfileClass();
+    method public boolean isGroupDisabled();
+  }
+
+  public class SubscriptionManager {
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean canDisablePhysicalSubscription();
+    method public boolean canManageSubscription(@NonNull android.telephony.SubscriptionInfo, @NonNull String);
+    method @NonNull public int[] getActiveAndHiddenSubscriptionIdList();
+    method @NonNull public int[] getActiveSubscriptionIdList();
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.SubscriptionInfo getActiveSubscriptionInfoForIcc(@NonNull String);
+    method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEnabledSubscriptionId(int);
+    method @NonNull public static android.content.res.Resources getResourcesForSubId(@NonNull android.content.Context, int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isSubscriptionEnabled(int);
+    method public void requestEmbeddedSubscriptionInfoListRefresh();
+    method public void requestEmbeddedSubscriptionInfoListRefresh(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultDataSubId(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultSmsSubId(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setDisplayName(@Nullable String, int, int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setIconTint(int, int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSubscriptionEnabled(int, boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUiccApplicationsEnabled(int, boolean);
+    field @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS) public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED";
+    field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI;
+    field @Deprecated public static final int PROFILE_CLASS_DEFAULT;
+    field public static final int PROFILE_CLASS_OPERATIONAL;
+    field public static final int PROFILE_CLASS_PROVISIONING;
+    field public static final int PROFILE_CLASS_TESTING;
+    field public static final int PROFILE_CLASS_UNSET;
+    field @NonNull public static final android.net.Uri VT_ENABLED_CONTENT_URI;
+    field @NonNull public static final android.net.Uri WFC_ENABLED_CONTENT_URI;
+    field @NonNull public static final android.net.Uri WFC_MODE_CONTENT_URI;
+    field @NonNull public static final android.net.Uri WFC_ROAMING_ENABLED_CONTENT_URI;
+    field @NonNull public static final android.net.Uri WFC_ROAMING_MODE_CONTENT_URI;
+  }
+
+  public class TelephonyFrameworkInitializer {
+    method public static void registerServiceWrappers();
+    method public static void setTelephonyServiceManager(@NonNull android.os.TelephonyServiceManager);
+  }
+
+  public final class TelephonyHistogram implements android.os.Parcelable {
+    ctor public TelephonyHistogram(int, int, int);
+    ctor public TelephonyHistogram(android.telephony.TelephonyHistogram);
+    ctor public TelephonyHistogram(android.os.Parcel);
+    method public void addTimeTaken(int);
+    method public int describeContents();
+    method public int getAverageTime();
+    method public int getBucketCount();
+    method public int[] getBucketCounters();
+    method public int[] getBucketEndPoints();
+    method public int getCategory();
+    method public int getId();
+    method public int getMaxTime();
+    method public int getMinTime();
+    method public int getSampleCount();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.TelephonyHistogram> CREATOR;
+    field public static final int TELEPHONY_CATEGORY_RIL = 1; // 0x1
+  }
+
+  public class TelephonyManager {
+    method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String);
+    method public int checkCarrierPrivilegesForPackage(String);
+    method public int checkCarrierPrivilegesForPackageAnyPhone(String);
+    method public void dial(String);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean disableDataConnectivity();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean enableDataConnectivity();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean enableModemForSlot(int, boolean);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void enableVideoCalling(boolean);
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getAidForAppType(int);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getAllowedNetworkTypes();
+    method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication();
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
+    method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
+    method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCarrierPrivilegeStatus(int);
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<java.lang.String> getCarrierPrivilegedPackagesForAllActiveSubscriptions();
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierRestrictionRules getCarrierRestrictionRules();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(int);
+    method public String getCdmaPrlVersion();
+    method public int getCurrentPhoneType();
+    method public int getCurrentPhoneType(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getDataActivationState();
+    method @Deprecated public boolean getDataEnabled();
+    method @Deprecated public boolean getDataEnabled(int);
+    method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getDefaultRespondViaMessageApplication();
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion();
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping();
+    method public int getMaxNumberOfSimultaneouslyActiveSims();
+    method public static long getMaxNumberVerificationTimeoutMillis();
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String[] getMergedImsisFromGroup();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getPreferredNetworkTypeBitmask();
+    method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public int getRadioPowerState();
+    method public int getSimApplicationState();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSimApplicationState(int);
+    method public int getSimCardState();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSimCardState(int);
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Locale getSimLocale();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getSupportedRadioAccessFamily();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.UiccSlotInfo[] getUiccSlotsInfo();
+    method @Nullable public android.os.Bundle getVisualVoicemailSettings();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoiceActivationState();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmi(String);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmiForSubscriber(int, String);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean iccCloseLogicalChannelBySlot(int, int);
+    method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(int, @Nullable String, int);
+    method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelBySlot(int, int, int, int, int, int, @Nullable String);
+    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAnyRadioPoweredOn();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApnMetered(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataConnectionAllowed();
+    method public boolean isDataConnectivityPossible();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isDataEnabledForApn(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled();
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isInEmergencySmsMode();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isLteCdmaEvdoGsmWcdmaEnabled();
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isOpportunisticNetworkEnabled();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String);
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRadioOn();
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isTetheringApnRequired();
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isVideoCallingEnabled();
+    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean matchesCurrentSimOperator(@NonNull String, int, @Nullable String);
+    method public boolean needsOtaServiceProvisioning();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyOtaEmergencyNumberDbInstalled();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyUserActivity();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean);
+    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
+    method public void requestModemActivityInfo(@NonNull android.os.ResultReceiver);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetAllCarrierActions();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void resetIms(int);
+    method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void resetOtaEmergencyNumberDbFilePath();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig();
+    method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void resetSettings();
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAllowedNetworkTypes(long);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAlwaysAllowMmsData(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRadioEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadioPower(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerState(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerStateForSlot(int, int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>);
+    method @Deprecated public void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoiceActivationState(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void shutdownAllRadios();
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPin(String);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPinReportResult(String);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPuk(String, String);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff();
+    method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor);
+    method public void updateServiceLocation();
+    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_ANOMALY_REPORTED = "android.telephony.action.ANOMALY_REPORTED";
+    field public static final String ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE = "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE";
+    field public static final String ACTION_CARRIER_SIGNAL_PCO_VALUE = "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE";
+    field public static final String ACTION_CARRIER_SIGNAL_REDIRECTED = "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED";
+    field public static final String ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED = "com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED";
+    field public static final String ACTION_CARRIER_SIGNAL_RESET = "com.android.internal.telephony.CARRIER_SIGNAL_RESET";
+    field public static final String ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED";
+    field public static final String ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED";
+    field public static final String ACTION_EMERGENCY_ASSISTANCE = "android.telephony.action.EMERGENCY_ASSISTANCE";
+    field public static final String ACTION_EMERGENCY_CALLBACK_MODE_CHANGED = "android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED";
+    field public static final String ACTION_EMERGENCY_CALL_STATE_CHANGED = "android.intent.action.EMERGENCY_CALL_STATE_CHANGED";
+    field public static final String ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE = "com.android.omadm.service.CONFIGURATION_UPDATE";
+    field public static final String ACTION_SERVICE_PROVIDERS_UPDATED = "android.telephony.action.SERVICE_PROVIDERS_UPDATED";
+    field public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS = "android.telephony.action.SHOW_NOTICE_ECM_BLOCK_OTHERS";
+    field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED";
+    field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED";
+    field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED";
+    field public static final int CARD_POWER_DOWN = 0; // 0x0
+    field public static final int CARD_POWER_UP = 1; // 0x1
+    field public static final int CARD_POWER_UP_PASS_THROUGH = 2; // 0x2
+    field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
+    field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
+    field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
+    field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff
+    field public static final String EXTRA_ANOMALY_DESCRIPTION = "android.telephony.extra.ANOMALY_DESCRIPTION";
+    field public static final String EXTRA_ANOMALY_ID = "android.telephony.extra.ANOMALY_ID";
+    field @Deprecated public static final String EXTRA_APN_PROTOCOL = "apnProto";
+    field public static final String EXTRA_APN_PROTOCOL_INT = "apnProtoInt";
+    field @Deprecated public static final String EXTRA_APN_TYPE = "apnType";
+    field public static final String EXTRA_APN_TYPE_INT = "apnTypeInt";
+    field public static final String EXTRA_DATA_SPN = "android.telephony.extra.DATA_SPN";
+    field public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable";
+    field public static final String EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE = "android.telephony.extra.DEFAULT_SUBSCRIPTION_SELECT_TYPE";
+    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL = 4; // 0x4
+    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA = 1; // 0x1
+    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE = 0; // 0x0
+    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_SMS = 3; // 0x3
+    field public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_VOICE = 2; // 0x2
+    field public static final String EXTRA_ERROR_CODE = "errorCode";
+    field public static final String EXTRA_PCO_ID = "pcoId";
+    field public static final String EXTRA_PCO_VALUE = "pcoValue";
+    field public static final String EXTRA_PHONE_IN_ECM_STATE = "android.telephony.extra.PHONE_IN_ECM_STATE";
+    field public static final String EXTRA_PHONE_IN_EMERGENCY_CALL = "android.telephony.extra.PHONE_IN_EMERGENCY_CALL";
+    field public static final String EXTRA_PLMN = "android.telephony.extra.PLMN";
+    field public static final String EXTRA_REDIRECTION_URL = "redirectionUrl";
+    field public static final String EXTRA_SHOW_PLMN = "android.telephony.extra.SHOW_PLMN";
+    field public static final String EXTRA_SHOW_SPN = "android.telephony.extra.SHOW_SPN";
+    field public static final String EXTRA_SIM_COMBINATION_NAMES = "android.telephony.extra.SIM_COMBINATION_NAMES";
+    field public static final String EXTRA_SIM_COMBINATION_WARNING_TYPE = "android.telephony.extra.SIM_COMBINATION_WARNING_TYPE";
+    field public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA = 1; // 0x1
+    field public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE = 0; // 0x0
+    field public static final String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
+    field public static final String EXTRA_SPN = "android.telephony.extra.SPN";
+    field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
+    field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
+    field public static final int INVALID_EMERGENCY_NUMBER_DB_VERSION = -1; // 0xffffffff
+    field public static final int KEY_TYPE_EPDG = 1; // 0x1
+    field public static final int KEY_TYPE_WLAN = 2; // 0x2
+    field public static final String MODEM_ACTIVITY_RESULT_KEY = "controller_activity";
+    field public static final long NETWORK_TYPE_BITMASK_1xRTT = 64L; // 0x40L
+    field public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L
+    field public static final long NETWORK_TYPE_BITMASK_EDGE = 2L; // 0x2L
+    field public static final long NETWORK_TYPE_BITMASK_EHRPD = 8192L; // 0x2000L
+    field public static final long NETWORK_TYPE_BITMASK_EVDO_0 = 16L; // 0x10L
+    field public static final long NETWORK_TYPE_BITMASK_EVDO_A = 32L; // 0x20L
+    field public static final long NETWORK_TYPE_BITMASK_EVDO_B = 2048L; // 0x800L
+    field public static final long NETWORK_TYPE_BITMASK_GPRS = 1L; // 0x1L
+    field public static final long NETWORK_TYPE_BITMASK_GSM = 32768L; // 0x8000L
+    field public static final long NETWORK_TYPE_BITMASK_HSDPA = 128L; // 0x80L
+    field public static final long NETWORK_TYPE_BITMASK_HSPA = 512L; // 0x200L
+    field public static final long NETWORK_TYPE_BITMASK_HSPAP = 16384L; // 0x4000L
+    field public static final long NETWORK_TYPE_BITMASK_HSUPA = 256L; // 0x100L
+    field public static final long NETWORK_TYPE_BITMASK_IWLAN = 131072L; // 0x20000L
+    field public static final long NETWORK_TYPE_BITMASK_LTE = 4096L; // 0x1000L
+    field public static final long NETWORK_TYPE_BITMASK_LTE_CA = 262144L; // 0x40000L
+    field public static final long NETWORK_TYPE_BITMASK_NR = 524288L; // 0x80000L
+    field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L
+    field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L
+    field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L
+    field public static final int RADIO_POWER_OFF = 0; // 0x0
+    field public static final int RADIO_POWER_ON = 1; // 0x1
+    field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2
+    field public static final int SET_CARRIER_RESTRICTION_ERROR = 2; // 0x2
+    field public static final int SET_CARRIER_RESTRICTION_NOT_SUPPORTED = 1; // 0x1
+    field public static final int SET_CARRIER_RESTRICTION_SUCCESS = 0; // 0x0
+    field public static final int SIM_ACTIVATION_STATE_ACTIVATED = 2; // 0x2
+    field public static final int SIM_ACTIVATION_STATE_ACTIVATING = 1; // 0x1
+    field public static final int SIM_ACTIVATION_STATE_DEACTIVATED = 3; // 0x3
+    field public static final int SIM_ACTIVATION_STATE_RESTRICTED = 4; // 0x4
+    field public static final int SIM_ACTIVATION_STATE_UNKNOWN = 0; // 0x0
+    field public static final int SIM_STATE_LOADED = 10; // 0xa
+    field public static final int SIM_STATE_PRESENT = 11; // 0xb
+    field public static final int SRVCC_STATE_HANDOVER_CANCELED = 3; // 0x3
+    field public static final int SRVCC_STATE_HANDOVER_COMPLETED = 1; // 0x1
+    field public static final int SRVCC_STATE_HANDOVER_FAILED = 2; // 0x2
+    field public static final int SRVCC_STATE_HANDOVER_NONE = -1; // 0xffffffff
+    field public static final int SRVCC_STATE_HANDOVER_STARTED = 0; // 0x0
+  }
+
+  public final class UiccAccessRule implements android.os.Parcelable {
+    ctor public UiccAccessRule(byte[], @Nullable String, long);
+    method public int describeContents();
+    method public int getCarrierPrivilegeStatus(android.content.pm.PackageInfo);
+    method public int getCarrierPrivilegeStatus(android.content.pm.Signature, String);
+    method public String getCertificateHexString();
+    method @Nullable public String getPackageName();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.UiccAccessRule> CREATOR;
+  }
+
+  public class UiccSlotInfo implements android.os.Parcelable {
+    ctor @Deprecated public UiccSlotInfo(boolean, boolean, String, int, int, boolean);
+    method public int describeContents();
+    method public String getCardId();
+    method public int getCardStateInfo();
+    method public boolean getIsActive();
+    method public boolean getIsEuicc();
+    method public boolean getIsExtendedApduSupported();
+    method public int getLogicalSlotIdx();
+    method public boolean isRemovable();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CARD_STATE_INFO_ABSENT = 1; // 0x1
+    field public static final int CARD_STATE_INFO_ERROR = 3; // 0x3
+    field public static final int CARD_STATE_INFO_PRESENT = 2; // 0x2
+    field public static final int CARD_STATE_INFO_RESTRICTED = 4; // 0x4
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.UiccSlotInfo> CREATOR;
+  }
+
+  public abstract class VisualVoicemailService extends android.app.Service {
+    method public static final void sendVisualVoicemailSms(android.content.Context, android.telecom.PhoneAccountHandle, String, short, String, android.app.PendingIntent);
+    method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings);
+  }
+
+}
+
+package android.telephony.cdma {
+
+  public final class CdmaSmsCbProgramData implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getCategory();
+    method public int getOperation();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 4099; // 0x1003
+    field public static final int CATEGORY_CMAS_EXTREME_THREAT = 4097; // 0x1001
+    field public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 4351; // 0x10ff
+    field public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 4096; // 0x1000
+    field public static final int CATEGORY_CMAS_SEVERE_THREAT = 4098; // 0x1002
+    field public static final int CATEGORY_CMAS_TEST_MESSAGE = 4100; // 0x1004
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.cdma.CdmaSmsCbProgramData> CREATOR;
+    field public static final int OPERATION_ADD_CATEGORY = 1; // 0x1
+    field public static final int OPERATION_CLEAR_CATEGORIES = 2; // 0x2
+    field public static final int OPERATION_DELETE_CATEGORY = 0; // 0x0
+  }
+
+}
+
+package android.telephony.data {
+
+  public final class DataCallResponse implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.List<android.net.LinkAddress> getAddresses();
+    method public int getCause();
+    method @NonNull public java.util.List<java.net.InetAddress> getDnsAddresses();
+    method @NonNull public java.util.List<java.net.InetAddress> getGatewayAddresses();
+    method public int getId();
+    method @NonNull public String getInterfaceName();
+    method public int getLinkStatus();
+    method @Deprecated public int getMtu();
+    method public int getMtuV4();
+    method public int getMtuV6();
+    method @NonNull public java.util.List<java.net.InetAddress> getPcscfAddresses();
+    method public int getProtocolType();
+    method public int getSuggestedRetryTime();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataCallResponse> CREATOR;
+    field public static final int LINK_STATUS_ACTIVE = 2; // 0x2
+    field public static final int LINK_STATUS_DORMANT = 1; // 0x1
+    field public static final int LINK_STATUS_INACTIVE = 0; // 0x0
+    field public static final int LINK_STATUS_UNKNOWN = -1; // 0xffffffff
+  }
+
+  public static final class DataCallResponse.Builder {
+    ctor public DataCallResponse.Builder();
+    method @NonNull public android.telephony.data.DataCallResponse build();
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setAddresses(@NonNull java.util.List<android.net.LinkAddress>);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setCause(int);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setDnsAddresses(@NonNull java.util.List<java.net.InetAddress>);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setGatewayAddresses(@NonNull java.util.List<java.net.InetAddress>);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setId(int);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setInterfaceName(@NonNull String);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setLinkStatus(int);
+    method @Deprecated @NonNull public android.telephony.data.DataCallResponse.Builder setMtu(int);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV4(int);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV6(int);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setPcscfAddresses(@NonNull java.util.List<java.net.InetAddress>);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setProtocolType(int);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setSuggestedRetryTime(int);
+  }
+
+  public final class DataProfile implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public String getApn();
+    method public int getAuthType();
+    method public int getBearerBitmask();
+    method @Deprecated public int getMtu();
+    method public int getMtuV4();
+    method public int getMtuV6();
+    method @Nullable public String getPassword();
+    method public int getProfileId();
+    method public int getProtocolType();
+    method public int getRoamingProtocolType();
+    method public int getSupportedApnTypesBitmask();
+    method public int getType();
+    method @Nullable public String getUserName();
+    method public boolean isEnabled();
+    method public boolean isPersistent();
+    method public boolean isPreferred();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.data.DataProfile> CREATOR;
+    field public static final int TYPE_3GPP = 1; // 0x1
+    field public static final int TYPE_3GPP2 = 2; // 0x2
+    field public static final int TYPE_COMMON = 0; // 0x0
+  }
+
+  public static final class DataProfile.Builder {
+    ctor public DataProfile.Builder();
+    method @NonNull public android.telephony.data.DataProfile build();
+    method @NonNull public android.telephony.data.DataProfile.Builder enable(boolean);
+    method @NonNull public android.telephony.data.DataProfile.Builder setApn(@NonNull String);
+    method @NonNull public android.telephony.data.DataProfile.Builder setAuthType(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setBearerBitmask(int);
+    method @Deprecated @NonNull public android.telephony.data.DataProfile.Builder setMtu(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setMtuV4(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setMtuV6(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setPassword(@NonNull String);
+    method @NonNull public android.telephony.data.DataProfile.Builder setPersistent(boolean);
+    method @NonNull public android.telephony.data.DataProfile.Builder setPreferred(boolean);
+    method @NonNull public android.telephony.data.DataProfile.Builder setProfileId(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setProtocolType(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setRoamingProtocolType(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setSupportedApnTypesBitmask(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setType(int);
+    method @NonNull public android.telephony.data.DataProfile.Builder setUserName(@NonNull String);
+  }
+
+  public abstract class DataService extends android.app.Service {
+    ctor public DataService();
+    method public android.os.IBinder onBind(android.content.Intent);
+    method @Nullable public abstract android.telephony.data.DataService.DataServiceProvider onCreateDataServiceProvider(int);
+    field public static final int REQUEST_REASON_HANDOVER = 3; // 0x3
+    field public static final int REQUEST_REASON_NORMAL = 1; // 0x1
+    field public static final int REQUEST_REASON_SHUTDOWN = 2; // 0x2
+    field public static final int REQUEST_REASON_UNKNOWN = 0; // 0x0
+    field public static final String SERVICE_INTERFACE = "android.telephony.data.DataService";
+  }
+
+  public abstract class DataService.DataServiceProvider implements java.lang.AutoCloseable {
+    ctor public DataService.DataServiceProvider(int);
+    method public abstract void close();
+    method public void deactivateDataCall(int, int, @Nullable android.telephony.data.DataServiceCallback);
+    method public final int getSlotIndex();
+    method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>);
+    method public void requestDataCallList(@NonNull android.telephony.data.DataServiceCallback);
+    method public void setDataProfile(@NonNull java.util.List<android.telephony.data.DataProfile>, boolean, @NonNull android.telephony.data.DataServiceCallback);
+    method public void setInitialAttachApn(@NonNull android.telephony.data.DataProfile, boolean, @NonNull android.telephony.data.DataServiceCallback);
+    method public void setupDataCall(int, @NonNull android.telephony.data.DataProfile, boolean, boolean, int, @Nullable android.net.LinkProperties, @NonNull android.telephony.data.DataServiceCallback);
+  }
+
+  public class DataServiceCallback {
+    method public void onDataCallListChanged(@NonNull java.util.List<android.telephony.data.DataCallResponse>);
+    method public void onDeactivateDataCallComplete(int);
+    method public void onRequestDataCallListComplete(int, @NonNull java.util.List<android.telephony.data.DataCallResponse>);
+    method public void onSetDataProfileComplete(int);
+    method public void onSetInitialAttachApnComplete(int);
+    method public void onSetupDataCallComplete(int, @Nullable android.telephony.data.DataCallResponse);
+    field public static final int RESULT_ERROR_BUSY = 3; // 0x3
+    field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4
+    field public static final int RESULT_ERROR_INVALID_ARG = 2; // 0x2
+    field public static final int RESULT_ERROR_UNSUPPORTED = 1; // 0x1
+    field public static final int RESULT_SUCCESS = 0; // 0x0
+  }
+
+  public abstract class QualifiedNetworksService extends android.app.Service {
+    ctor public QualifiedNetworksService();
+    method @NonNull public abstract android.telephony.data.QualifiedNetworksService.NetworkAvailabilityProvider onCreateNetworkAvailabilityProvider(int);
+    field public static final String QUALIFIED_NETWORKS_SERVICE_INTERFACE = "android.telephony.data.QualifiedNetworksService";
+  }
+
+  public abstract class QualifiedNetworksService.NetworkAvailabilityProvider implements java.lang.AutoCloseable {
+    ctor public QualifiedNetworksService.NetworkAvailabilityProvider(int);
+    method public abstract void close();
+    method public final int getSlotIndex();
+    method public final void updateQualifiedNetworkTypes(int, @NonNull java.util.List<java.lang.Integer>);
+  }
+
+}
+
+package android.telephony.euicc {
+
+  public final class DownloadableSubscription implements android.os.Parcelable {
+    method public java.util.List<android.telephony.UiccAccessRule> getAccessRules();
+    method @Nullable public String getCarrierName();
+  }
+
+  public static final class DownloadableSubscription.Builder {
+    ctor public DownloadableSubscription.Builder();
+    ctor public DownloadableSubscription.Builder(android.telephony.euicc.DownloadableSubscription);
+    method public android.telephony.euicc.DownloadableSubscription build();
+    method public android.telephony.euicc.DownloadableSubscription.Builder setAccessRules(java.util.List<android.telephony.UiccAccessRule>);
+    method public android.telephony.euicc.DownloadableSubscription.Builder setCarrierName(String);
+    method public android.telephony.euicc.DownloadableSubscription.Builder setConfirmationCode(String);
+    method public android.telephony.euicc.DownloadableSubscription.Builder setEncodedActivationCode(String);
+  }
+
+  public class EuiccCardManager {
+    method public void authenticateServer(String, String, byte[], byte[], byte[], byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+    method public void cancelSession(String, byte[], @android.telephony.euicc.EuiccCardManager.CancelReason int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+    method public void deleteProfile(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+    method public void disableProfile(String, String, boolean, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+    method public void listNotifications(String, @android.telephony.euicc.EuiccNotification.Event int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification[]>);
+    method public void loadBoundProfilePackage(String, byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+    method public void prepareDownload(String, @Nullable byte[], byte[], byte[], byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+    method public void removeNotificationFromList(String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+    method public void requestAllProfiles(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo[]>);
+    method public void requestDefaultSmdpAddress(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.String>);
+    method public void requestEuiccChallenge(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+    method public void requestEuiccInfo1(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+    method public void requestEuiccInfo2(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+    method public void requestProfile(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo>);
+    method public void requestRulesAuthTable(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccRulesAuthTable>);
+    method public void requestSmdsAddress(String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.String>);
+    method public void resetMemory(String, @android.telephony.euicc.EuiccCardManager.ResetOption int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+    method public void retrieveNotification(String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification>);
+    method public void retrieveNotificationList(String, @android.telephony.euicc.EuiccNotification.Event int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification[]>);
+    method public void setDefaultSmdpAddress(String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+    method public void setNickname(String, String, String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+    method public void switchToProfile(String, String, boolean, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo>);
+    field public static final int CANCEL_REASON_END_USER_REJECTED = 0; // 0x0
+    field public static final int CANCEL_REASON_POSTPONED = 1; // 0x1
+    field public static final int CANCEL_REASON_PPR_NOT_ALLOWED = 3; // 0x3
+    field public static final int CANCEL_REASON_TIMEOUT = 2; // 0x2
+    field public static final int RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES = 2; // 0x2
+    field public static final int RESET_OPTION_DELETE_OPERATIONAL_PROFILES = 1; // 0x1
+    field public static final int RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS = 4; // 0x4
+    field public static final int RESULT_CALLER_NOT_ALLOWED = -3; // 0xfffffffd
+    field public static final int RESULT_EUICC_NOT_FOUND = -2; // 0xfffffffe
+    field public static final int RESULT_OK = 0; // 0x0
+    field public static final int RESULT_UNKNOWN_ERROR = -1; // 0xffffffff
+  }
+
+  @IntDef(prefix={"CANCEL_REASON_"}, value={android.telephony.euicc.EuiccCardManager.CANCEL_REASON_END_USER_REJECTED, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_POSTPONED, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_TIMEOUT, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_PPR_NOT_ALLOWED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccCardManager.CancelReason {
+  }
+
+  @IntDef(flag=true, prefix={"RESET_OPTION_"}, value={android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_OPERATIONAL_PROFILES, android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES, android.telephony.euicc.EuiccCardManager.RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccCardManager.ResetOption {
+  }
+
+  public static interface EuiccCardManager.ResultCallback<T> {
+    method public void onComplete(int, T);
+  }
+
+  public class EuiccManager {
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void continueOperation(android.content.Intent, android.os.Bundle);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptions(@NonNull android.app.PendingIntent);
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void eraseSubscriptions(@android.telephony.euicc.EuiccCardManager.ResetOption int, @NonNull android.app.PendingIntent);
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDefaultDownloadableSubscriptionList(android.app.PendingIntent);
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void getDownloadableSubscriptionMetadata(android.telephony.euicc.DownloadableSubscription, android.app.PendingIntent);
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public int getOtaStatus();
+    method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public java.util.List<java.lang.String> getSupportedCountries();
+    method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public java.util.List<java.lang.String> getUnsupportedCountries();
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public boolean isSupportedCountry(@NonNull String);
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void setSupportedCountries(@NonNull java.util.List<java.lang.String>);
+    method @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void setUnsupportedCountries(@NonNull java.util.List<java.lang.String>);
+    field public static final String ACTION_DELETE_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.DELETE_SUBSCRIPTION_PRIVILEGED";
+    field @RequiresPermission(android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public static final String ACTION_OTA_STATUS_CHANGED = "android.telephony.euicc.action.OTA_STATUS_CHANGED";
+    field public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION = "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
+    field public static final String ACTION_RENAME_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED";
+    field public static final String ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED = "android.telephony.euicc.action.TOGGLE_SUBSCRIPTION_PRIVILEGED";
+    field public static final int EUICC_ACTIVATION_TYPE_ACCOUNT_REQUIRED = 4; // 0x4
+    field public static final int EUICC_ACTIVATION_TYPE_BACKUP = 2; // 0x2
+    field public static final int EUICC_ACTIVATION_TYPE_DEFAULT = 1; // 0x1
+    field public static final int EUICC_ACTIVATION_TYPE_TRANSFER = 3; // 0x3
+    field public static final int EUICC_OTA_FAILED = 2; // 0x2
+    field public static final int EUICC_OTA_IN_PROGRESS = 1; // 0x1
+    field public static final int EUICC_OTA_NOT_NEEDED = 4; // 0x4
+    field public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5; // 0x5
+    field public static final int EUICC_OTA_SUCCEEDED = 3; // 0x3
+    field public static final String EXTRA_ACTIVATION_TYPE = "android.telephony.euicc.extra.ACTIVATION_TYPE";
+    field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS";
+    field public static final String EXTRA_ENABLE_SUBSCRIPTION = "android.telephony.euicc.extra.ENABLE_SUBSCRIPTION";
+    field public static final String EXTRA_FORCE_PROVISION = "android.telephony.euicc.extra.FORCE_PROVISION";
+    field public static final String EXTRA_FROM_SUBSCRIPTION_ID = "android.telephony.euicc.extra.FROM_SUBSCRIPTION_ID";
+    field public static final String EXTRA_PHYSICAL_SLOT_ID = "android.telephony.euicc.extra.PHYSICAL_SLOT_ID";
+    field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.euicc.extra.SUBSCRIPTION_ID";
+    field public static final String EXTRA_SUBSCRIPTION_NICKNAME = "android.telephony.euicc.extra.SUBSCRIPTION_NICKNAME";
+  }
+
+  @IntDef(prefix={"EUICC_OTA_"}, value={android.telephony.euicc.EuiccManager.EUICC_OTA_IN_PROGRESS, android.telephony.euicc.EuiccManager.EUICC_OTA_FAILED, android.telephony.euicc.EuiccManager.EUICC_OTA_SUCCEEDED, android.telephony.euicc.EuiccManager.EUICC_OTA_NOT_NEEDED, android.telephony.euicc.EuiccManager.EUICC_OTA_STATUS_UNAVAILABLE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccManager.OtaStatus {
+  }
+
+  public final class EuiccNotification implements android.os.Parcelable {
+    ctor public EuiccNotification(int, String, @android.telephony.euicc.EuiccNotification.Event int, @Nullable byte[]);
+    method public int describeContents();
+    method @Nullable public byte[] getData();
+    method @android.telephony.euicc.EuiccNotification.Event public int getEvent();
+    method public int getSeq();
+    method public String getTargetAddr();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @android.telephony.euicc.EuiccNotification.Event public static final int ALL_EVENTS = 15; // 0xf
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccNotification> CREATOR;
+    field public static final int EVENT_DELETE = 8; // 0x8
+    field public static final int EVENT_DISABLE = 4; // 0x4
+    field public static final int EVENT_ENABLE = 2; // 0x2
+    field public static final int EVENT_INSTALL = 1; // 0x1
+  }
+
+  @IntDef(flag=true, prefix={"EVENT_"}, value={android.telephony.euicc.EuiccNotification.EVENT_INSTALL, android.telephony.euicc.EuiccNotification.EVENT_ENABLE, android.telephony.euicc.EuiccNotification.EVENT_DISABLE, android.telephony.euicc.EuiccNotification.EVENT_DELETE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccNotification.Event {
+  }
+
+  public final class EuiccRulesAuthTable implements android.os.Parcelable {
+    method public int describeContents();
+    method public int findIndex(@android.service.euicc.EuiccProfileInfo.PolicyRule int, android.service.carrier.CarrierIdentifier);
+    method public boolean hasPolicyRuleFlag(int, @android.telephony.euicc.EuiccRulesAuthTable.PolicyRuleFlag int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccRulesAuthTable> CREATOR;
+    field public static final int POLICY_RULE_FLAG_CONSENT_REQUIRED = 1; // 0x1
+  }
+
+  public static final class EuiccRulesAuthTable.Builder {
+    ctor public EuiccRulesAuthTable.Builder(int);
+    method public android.telephony.euicc.EuiccRulesAuthTable.Builder add(int, java.util.List<android.service.carrier.CarrierIdentifier>, int);
+    method public android.telephony.euicc.EuiccRulesAuthTable build();
+  }
+
+  @IntDef(flag=true, prefix={"POLICY_RULE_FLAG_"}, value={android.telephony.euicc.EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccRulesAuthTable.PolicyRuleFlag {
+  }
+
+}
+
+package android.telephony.ims {
+
+  public final class ImsCallForwardInfo implements android.os.Parcelable {
+    ctor public ImsCallForwardInfo(int, int, int, int, @NonNull String, int);
+    method public int describeContents();
+    method public int getCondition();
+    method public String getNumber();
+    method public int getServiceClass();
+    method public int getStatus();
+    method public int getTimeSeconds();
+    method public int getToA();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CDIV_CF_REASON_ALL = 4; // 0x4
+    field public static final int CDIV_CF_REASON_ALL_CONDITIONAL = 5; // 0x5
+    field public static final int CDIV_CF_REASON_BUSY = 1; // 0x1
+    field public static final int CDIV_CF_REASON_NOT_LOGGED_IN = 6; // 0x6
+    field public static final int CDIV_CF_REASON_NOT_REACHABLE = 3; // 0x3
+    field public static final int CDIV_CF_REASON_NO_REPLY = 2; // 0x2
+    field public static final int CDIV_CF_REASON_UNCONDITIONAL = 0; // 0x0
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallForwardInfo> CREATOR;
+    field public static final int STATUS_ACTIVE = 1; // 0x1
+    field public static final int STATUS_NOT_ACTIVE = 0; // 0x0
+    field public static final int TYPE_OF_ADDRESS_INTERNATIONAL = 145; // 0x91
+    field public static final int TYPE_OF_ADDRESS_UNKNOWN = 129; // 0x81
+  }
+
+  public final class ImsCallProfile implements android.os.Parcelable {
+    ctor public ImsCallProfile();
+    ctor public ImsCallProfile(int, int);
+    ctor public ImsCallProfile(int, int, android.os.Bundle, android.telephony.ims.ImsStreamMediaProfile);
+    method public int describeContents();
+    method public String getCallExtra(String);
+    method public String getCallExtra(String, String);
+    method public boolean getCallExtraBoolean(String);
+    method public boolean getCallExtraBoolean(String, boolean);
+    method public int getCallExtraInt(String);
+    method public int getCallExtraInt(String, int);
+    method public android.os.Bundle getCallExtras();
+    method public int getCallType();
+    method public static int getCallTypeFromVideoState(int);
+    method public int getCallerNumberVerificationStatus();
+    method public int getEmergencyCallRouting();
+    method public int getEmergencyServiceCategories();
+    method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
+    method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
+    method @NonNull public android.os.Bundle getProprietaryCallExtras();
+    method public int getRestrictCause();
+    method public int getServiceType();
+    method public static int getVideoStateFromCallType(int);
+    method public static int getVideoStateFromImsCallProfile(android.telephony.ims.ImsCallProfile);
+    method public boolean hasKnownUserIntentEmergency();
+    method public boolean isEmergencyCallTesting();
+    method public boolean isVideoCall();
+    method public boolean isVideoPaused();
+    method public static int presentationToOir(int);
+    method public void setCallExtra(String, String);
+    method public void setCallExtraBoolean(String, boolean);
+    method public void setCallExtraInt(String, int);
+    method public void setCallRestrictCause(int);
+    method public void setCallerNumberVerificationStatus(int);
+    method public void setEmergencyCallRouting(int);
+    method public void setEmergencyCallTesting(boolean);
+    method public void setEmergencyServiceCategories(int);
+    method public void setEmergencyUrns(@NonNull java.util.List<java.lang.String>);
+    method public void setHasKnownUserIntentEmergency(boolean);
+    method public void updateCallExtras(android.telephony.ims.ImsCallProfile);
+    method public void updateCallType(android.telephony.ims.ImsCallProfile);
+    method public void updateMediaProfile(android.telephony.ims.ImsCallProfile);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CALL_RESTRICT_CAUSE_DISABLED = 2; // 0x2
+    field public static final int CALL_RESTRICT_CAUSE_HD = 3; // 0x3
+    field public static final int CALL_RESTRICT_CAUSE_NONE = 0; // 0x0
+    field public static final int CALL_RESTRICT_CAUSE_RAT = 1; // 0x1
+    field public static final int CALL_TYPE_VIDEO_N_VOICE = 3; // 0x3
+    field public static final int CALL_TYPE_VOICE = 2; // 0x2
+    field public static final int CALL_TYPE_VOICE_N_VIDEO = 1; // 0x1
+    field public static final int CALL_TYPE_VS = 8; // 0x8
+    field public static final int CALL_TYPE_VS_RX = 10; // 0xa
+    field public static final int CALL_TYPE_VS_TX = 9; // 0x9
+    field public static final int CALL_TYPE_VT = 4; // 0x4
+    field public static final int CALL_TYPE_VT_NODIR = 7; // 0x7
+    field public static final int CALL_TYPE_VT_RX = 6; // 0x6
+    field public static final int CALL_TYPE_VT_TX = 5; // 0x5
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallProfile> CREATOR;
+    field public static final int DIALSTRING_NORMAL = 0; // 0x0
+    field public static final int DIALSTRING_SS_CONF = 1; // 0x1
+    field public static final int DIALSTRING_USSD = 2; // 0x2
+    field public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo";
+    field public static final String EXTRA_ADDITIONAL_SIP_INVITE_FIELDS = "android.telephony.ims.extra.ADDITIONAL_SIP_INVITE_FIELDS";
+    field public static final String EXTRA_CALL_DISCONNECT_CAUSE = "android.telephony.ims.extra.CALL_DISCONNECT_CAUSE";
+    field public static final String EXTRA_CALL_NETWORK_TYPE = "android.telephony.ims.extra.CALL_NETWORK_TYPE";
+    field @Deprecated public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech";
+    field public static final String EXTRA_CHILD_NUMBER = "ChildNum";
+    field public static final String EXTRA_CNA = "cna";
+    field public static final String EXTRA_CNAP = "cnap";
+    field public static final String EXTRA_CODEC = "Codec";
+    field public static final String EXTRA_DIALSTRING = "dialstring";
+    field public static final String EXTRA_DISPLAY_TEXT = "DisplayText";
+    field public static final String EXTRA_EMERGENCY_CALL = "e_call";
+    field public static final String EXTRA_FORWARDED_NUMBER = "android.telephony.ims.extra.FORWARDED_NUMBER";
+    field public static final String EXTRA_IS_CALL_PULL = "CallPull";
+    field public static final String EXTRA_OI = "oi";
+    field public static final String EXTRA_OIR = "oir";
+    field public static final String EXTRA_REMOTE_URI = "remote_uri";
+    field public static final String EXTRA_USSD = "ussd";
+    field public static final int OIR_DEFAULT = 0; // 0x0
+    field public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2; // 0x2
+    field public static final int OIR_PRESENTATION_PAYPHONE = 4; // 0x4
+    field public static final int OIR_PRESENTATION_RESTRICTED = 1; // 0x1
+    field public static final int OIR_PRESENTATION_UNKNOWN = 3; // 0x3
+    field public static final int SERVICE_TYPE_EMERGENCY = 2; // 0x2
+    field public static final int SERVICE_TYPE_NONE = 0; // 0x0
+    field public static final int SERVICE_TYPE_NORMAL = 1; // 0x1
+    field public static final int VERIFICATION_STATUS_FAILED = 2; // 0x2
+    field public static final int VERIFICATION_STATUS_NOT_VERIFIED = 0; // 0x0
+    field public static final int VERIFICATION_STATUS_PASSED = 1; // 0x1
+  }
+
+  public class ImsCallSessionListener {
+    method public void callQualityChanged(@NonNull android.telephony.CallQuality);
+    method public void callSessionConferenceExtendFailed(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
+    method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
+    method public void callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState);
+    method @Deprecated public void callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo);
+    method @Deprecated public void callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo);
+    method public void callSessionHeld(android.telephony.ims.ImsCallProfile);
+    method public void callSessionHoldFailed(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionHoldReceived(android.telephony.ims.ImsCallProfile);
+    method public void callSessionInitiated(android.telephony.ims.ImsCallProfile);
+    method public void callSessionInitiatedFailed(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionInviteParticipantsRequestDelivered();
+    method public void callSessionInviteParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo);
+    method @Deprecated public void callSessionMayHandover(int, int);
+    method public void callSessionMergeComplete(android.telephony.ims.stub.ImsCallSessionImplBase);
+    method public void callSessionMergeFailed(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
+    method public void callSessionMultipartyStateChanged(boolean);
+    method public void callSessionProgressing(android.telephony.ims.ImsStreamMediaProfile);
+    method public void callSessionRemoveParticipantsRequestDelivered();
+    method public void callSessionRemoveParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile);
+    method public void callSessionResumed(android.telephony.ims.ImsCallProfile);
+    method public void callSessionRttAudioIndicatorChanged(@NonNull android.telephony.ims.ImsStreamMediaProfile);
+    method public void callSessionRttMessageReceived(String);
+    method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile);
+    method public void callSessionRttModifyResponseReceived(int);
+    method public void callSessionSuppServiceReceived(android.telephony.ims.ImsSuppServiceNotification);
+    method public void callSessionTerminated(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionTtyModeReceived(int);
+    method public void callSessionUpdateFailed(android.telephony.ims.ImsReasonInfo);
+    method public void callSessionUpdateReceived(android.telephony.ims.ImsCallProfile);
+    method public void callSessionUpdated(android.telephony.ims.ImsCallProfile);
+    method public void callSessionUssdMessageReceived(int, String);
+    method public void onHandover(int, int, @Nullable android.telephony.ims.ImsReasonInfo);
+    method public void onHandoverFailed(int, int, @NonNull android.telephony.ims.ImsReasonInfo);
+    method public void onMayHandover(int, int);
+  }
+
+  public final class ImsConferenceState implements android.os.Parcelable {
+    method public int describeContents();
+    method public static int getConnectionStateForStatus(String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsConferenceState> CREATOR;
+    field public static final String DISPLAY_TEXT = "display-text";
+    field public static final String ENDPOINT = "endpoint";
+    field public static final String SIP_STATUS_CODE = "sipstatuscode";
+    field public static final String STATUS = "status";
+    field public static final String STATUS_ALERTING = "alerting";
+    field public static final String STATUS_CONNECTED = "connected";
+    field public static final String STATUS_CONNECT_FAIL = "connect-fail";
+    field public static final String STATUS_DIALING_IN = "dialing-in";
+    field public static final String STATUS_DIALING_OUT = "dialing-out";
+    field public static final String STATUS_DISCONNECTED = "disconnected";
+    field public static final String STATUS_DISCONNECTING = "disconnecting";
+    field public static final String STATUS_MUTED_VIA_FOCUS = "muted-via-focus";
+    field public static final String STATUS_ON_HOLD = "on-hold";
+    field public static final String STATUS_PENDING = "pending";
+    field public static final String STATUS_SEND_ONLY = "sendonly";
+    field public static final String STATUS_SEND_RECV = "sendrecv";
+    field public static final String USER = "user";
+    field public final java.util.HashMap<java.lang.String,android.os.Bundle> mParticipants;
+  }
+
+  public final class ImsException extends java.lang.Exception {
+    ctor public ImsException(@Nullable String);
+    ctor public ImsException(@Nullable String, int);
+    ctor public ImsException(@Nullable String, int, @Nullable Throwable);
+  }
+
+  public final class ImsExternalCallState implements android.os.Parcelable {
+    ctor public ImsExternalCallState(@NonNull String, @NonNull android.net.Uri, @Nullable android.net.Uri, boolean, int, int, boolean);
+    method public int describeContents();
+    method @NonNull public android.net.Uri getAddress();
+    method public int getCallId();
+    method public int getCallState();
+    method public int getCallType();
+    method @Nullable public android.net.Uri getLocalAddress();
+    method public boolean isCallHeld();
+    method public boolean isCallPullable();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CALL_STATE_CONFIRMED = 1; // 0x1
+    field public static final int CALL_STATE_TERMINATED = 2; // 0x2
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsExternalCallState> CREATOR;
+  }
+
+  public class ImsMmTelManager implements android.telephony.ims.RegistrationManager {
+    method @Deprecated @NonNull @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getFeatureState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws android.telephony.ims.ImsException;
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiRoamingModeSetting();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAvailable(int, int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isCapable(int, int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void isSupported(int, int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>) throws android.telephony.ims.ImsException;
+    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException;
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAdvancedCallingSettingEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRttCapabilitySetting(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiModeSetting(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiNonPersistent(boolean, int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingModeSetting(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingSettingEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiSettingEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVtSettingEnabled(boolean);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback);
+  }
+
+  @Deprecated public static class ImsMmTelManager.RegistrationCallback extends android.telephony.ims.RegistrationManager.RegistrationCallback {
+    ctor @Deprecated public ImsMmTelManager.RegistrationCallback();
+  }
+
+  public final class ImsReasonInfo implements android.os.Parcelable {
+    field public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED = "Forbidden. Not Authorized for Service";
+  }
+
+  public class ImsService extends android.app.Service {
+    ctor public ImsService();
+    method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int);
+    method public android.telephony.ims.feature.RcsFeature createRcsFeature(int);
+    method public void disableIms(int);
+    method public void enableIms(int);
+    method public android.telephony.ims.stub.ImsConfigImplBase getConfig(int);
+    method public android.telephony.ims.stub.ImsRegistrationImplBase getRegistration(int);
+    method public final void onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) throws android.os.RemoteException;
+    method public android.telephony.ims.stub.ImsFeatureConfiguration querySupportedImsFeatures();
+    method public void readyForFeatureCreation();
+  }
+
+  public final class ImsSsData implements android.os.Parcelable {
+    ctor public ImsSsData(int, int, int, int, int);
+    method public int describeContents();
+    method @Nullable public java.util.List<android.telephony.ims.ImsCallForwardInfo> getCallForwardInfo();
+    method public int getRequestType();
+    method public int getResult();
+    method public int getServiceClass();
+    method public int getServiceType();
+    method @NonNull public java.util.List<android.telephony.ims.ImsSsInfo> getSuppServiceInfo();
+    method public int getTeleserviceType();
+    method public boolean isTypeBarring();
+    method public boolean isTypeCf();
+    method public boolean isTypeClip();
+    method public boolean isTypeClir();
+    method public boolean isTypeColp();
+    method public boolean isTypeColr();
+    method public boolean isTypeCw();
+    method public boolean isTypeIcb();
+    method public boolean isTypeInterrogation();
+    method public boolean isTypeUnConditional();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsData> CREATOR;
+    field public static final int RESULT_SUCCESS = 0; // 0x0
+    field public static final int SERVICE_CLASS_DATA = 2; // 0x2
+    field public static final int SERVICE_CLASS_DATA_CIRCUIT_ASYNC = 32; // 0x20
+    field public static final int SERVICE_CLASS_DATA_CIRCUIT_SYNC = 16; // 0x10
+    field public static final int SERVICE_CLASS_DATA_PACKET_ACCESS = 64; // 0x40
+    field public static final int SERVICE_CLASS_DATA_PAD = 128; // 0x80
+    field public static final int SERVICE_CLASS_FAX = 4; // 0x4
+    field public static final int SERVICE_CLASS_NONE = 0; // 0x0
+    field public static final int SERVICE_CLASS_SMS = 8; // 0x8
+    field public static final int SERVICE_CLASS_VOICE = 1; // 0x1
+    field public static final int SS_ACTIVATION = 0; // 0x0
+    field public static final int SS_ALL_BARRING = 18; // 0x12
+    field public static final int SS_ALL_DATA_TELESERVICES = 3; // 0x3
+    field public static final int SS_ALL_TELESERVICES_EXCEPT_SMS = 5; // 0x5
+    field public static final int SS_ALL_TELESEVICES = 1; // 0x1
+    field public static final int SS_ALL_TELE_AND_BEARER_SERVICES = 0; // 0x0
+    field public static final int SS_BAIC = 16; // 0x10
+    field public static final int SS_BAIC_ROAMING = 17; // 0x11
+    field public static final int SS_BAOC = 13; // 0xd
+    field public static final int SS_BAOIC = 14; // 0xe
+    field public static final int SS_BAOIC_EXC_HOME = 15; // 0xf
+    field public static final int SS_CFU = 0; // 0x0
+    field public static final int SS_CFUT = 6; // 0x6
+    field public static final int SS_CF_ALL = 4; // 0x4
+    field public static final int SS_CF_ALL_CONDITIONAL = 5; // 0x5
+    field public static final int SS_CF_BUSY = 1; // 0x1
+    field public static final int SS_CF_NOT_REACHABLE = 3; // 0x3
+    field public static final int SS_CF_NO_REPLY = 2; // 0x2
+    field public static final int SS_CLIP = 7; // 0x7
+    field public static final int SS_CLIR = 8; // 0x8
+    field public static final int SS_CNAP = 11; // 0xb
+    field public static final int SS_COLP = 9; // 0x9
+    field public static final int SS_COLR = 10; // 0xa
+    field public static final int SS_DEACTIVATION = 1; // 0x1
+    field public static final int SS_ERASURE = 4; // 0x4
+    field public static final int SS_INCOMING_BARRING = 20; // 0x14
+    field public static final int SS_INCOMING_BARRING_ANONYMOUS = 22; // 0x16
+    field public static final int SS_INCOMING_BARRING_DN = 21; // 0x15
+    field public static final int SS_INTERROGATION = 2; // 0x2
+    field public static final int SS_OUTGOING_BARRING = 19; // 0x13
+    field public static final int SS_REGISTRATION = 3; // 0x3
+    field public static final int SS_SMS_SERVICES = 4; // 0x4
+    field public static final int SS_TELEPHONY = 2; // 0x2
+    field public static final int SS_WAIT = 12; // 0xc
+  }
+
+  public static final class ImsSsData.Builder {
+    ctor public ImsSsData.Builder(int, int, int, int, int);
+    method @NonNull public android.telephony.ims.ImsSsData build();
+    method @NonNull public android.telephony.ims.ImsSsData.Builder setCallForwardingInfo(@NonNull java.util.List<android.telephony.ims.ImsCallForwardInfo>);
+    method @NonNull public android.telephony.ims.ImsSsData.Builder setSuppServiceInfo(@NonNull java.util.List<android.telephony.ims.ImsSsInfo>);
+  }
+
+  public final class ImsSsInfo implements android.os.Parcelable {
+    ctor @Deprecated public ImsSsInfo(int, @Nullable String);
+    method public int describeContents();
+    method public int getClirInterrogationStatus();
+    method public int getClirOutgoingState();
+    method @Deprecated public String getIcbNum();
+    method @Nullable public String getIncomingCommunicationBarringNumber();
+    method public int getProvisionStatus();
+    method public int getStatus();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CLIR_OUTGOING_DEFAULT = 0; // 0x0
+    field public static final int CLIR_OUTGOING_INVOCATION = 1; // 0x1
+    field public static final int CLIR_OUTGOING_SUPPRESSION = 2; // 0x2
+    field public static final int CLIR_STATUS_NOT_PROVISIONED = 0; // 0x0
+    field public static final int CLIR_STATUS_PROVISIONED_PERMANENT = 1; // 0x1
+    field public static final int CLIR_STATUS_TEMPORARILY_ALLOWED = 4; // 0x4
+    field public static final int CLIR_STATUS_TEMPORARILY_RESTRICTED = 3; // 0x3
+    field public static final int CLIR_STATUS_UNKNOWN = 2; // 0x2
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsInfo> CREATOR;
+    field public static final int DISABLED = 0; // 0x0
+    field public static final int ENABLED = 1; // 0x1
+    field public static final int NOT_REGISTERED = -1; // 0xffffffff
+    field public static final int SERVICE_NOT_PROVISIONED = 0; // 0x0
+    field public static final int SERVICE_PROVISIONED = 1; // 0x1
+    field public static final int SERVICE_PROVISIONING_UNKNOWN = -1; // 0xffffffff
+  }
+
+  public static final class ImsSsInfo.Builder {
+    ctor public ImsSsInfo.Builder(int);
+    method @NonNull public android.telephony.ims.ImsSsInfo build();
+    method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirInterrogationStatus(int);
+    method @NonNull public android.telephony.ims.ImsSsInfo.Builder setClirOutgoingState(int);
+    method @NonNull public android.telephony.ims.ImsSsInfo.Builder setIncomingCommunicationBarringNumber(@NonNull String);
+    method @NonNull public android.telephony.ims.ImsSsInfo.Builder setProvisionStatus(int);
+  }
+
+  public final class ImsStreamMediaProfile implements android.os.Parcelable {
+    ctor public ImsStreamMediaProfile(int, int, int, int, int);
+    method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile);
+    method public int describeContents();
+    method public int getAudioDirection();
+    method public int getAudioQuality();
+    method public int getRttMode();
+    method public int getVideoDirection();
+    method public int getVideoQuality();
+    method public boolean isReceivingRttAudio();
+    method public boolean isRttCall();
+    method public void setReceivingRttAudio(boolean);
+    method public void setRttMode(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int AUDIO_QUALITY_AMR = 1; // 0x1
+    field public static final int AUDIO_QUALITY_AMR_WB = 2; // 0x2
+    field public static final int AUDIO_QUALITY_EVRC = 4; // 0x4
+    field public static final int AUDIO_QUALITY_EVRC_B = 5; // 0x5
+    field public static final int AUDIO_QUALITY_EVRC_NW = 7; // 0x7
+    field public static final int AUDIO_QUALITY_EVRC_WB = 6; // 0x6
+    field public static final int AUDIO_QUALITY_EVS_FB = 20; // 0x14
+    field public static final int AUDIO_QUALITY_EVS_NB = 17; // 0x11
+    field public static final int AUDIO_QUALITY_EVS_SWB = 19; // 0x13
+    field public static final int AUDIO_QUALITY_EVS_WB = 18; // 0x12
+    field public static final int AUDIO_QUALITY_G711A = 13; // 0xd
+    field public static final int AUDIO_QUALITY_G711AB = 15; // 0xf
+    field public static final int AUDIO_QUALITY_G711U = 11; // 0xb
+    field public static final int AUDIO_QUALITY_G722 = 14; // 0xe
+    field public static final int AUDIO_QUALITY_G723 = 12; // 0xc
+    field public static final int AUDIO_QUALITY_G729 = 16; // 0x10
+    field public static final int AUDIO_QUALITY_GSM_EFR = 8; // 0x8
+    field public static final int AUDIO_QUALITY_GSM_FR = 9; // 0x9
+    field public static final int AUDIO_QUALITY_GSM_HR = 10; // 0xa
+    field public static final int AUDIO_QUALITY_NONE = 0; // 0x0
+    field public static final int AUDIO_QUALITY_QCELP13K = 3; // 0x3
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsStreamMediaProfile> CREATOR;
+    field public static final int DIRECTION_INACTIVE = 0; // 0x0
+    field public static final int DIRECTION_INVALID = -1; // 0xffffffff
+    field public static final int DIRECTION_RECEIVE = 1; // 0x1
+    field public static final int DIRECTION_SEND = 2; // 0x2
+    field public static final int DIRECTION_SEND_RECEIVE = 3; // 0x3
+    field public static final int RTT_MODE_DISABLED = 0; // 0x0
+    field public static final int RTT_MODE_FULL = 1; // 0x1
+    field public static final int VIDEO_QUALITY_NONE = 0; // 0x0
+    field public static final int VIDEO_QUALITY_QCIF = 1; // 0x1
+    field public static final int VIDEO_QUALITY_QVGA_LANDSCAPE = 2; // 0x2
+    field public static final int VIDEO_QUALITY_QVGA_PORTRAIT = 4; // 0x4
+    field public static final int VIDEO_QUALITY_VGA_LANDSCAPE = 8; // 0x8
+    field public static final int VIDEO_QUALITY_VGA_PORTRAIT = 16; // 0x10
+  }
+
+  public final class ImsSuppServiceNotification implements android.os.Parcelable {
+    ctor public ImsSuppServiceNotification(int, int, int, int, String, String[]);
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSuppServiceNotification> CREATOR;
+    field public final int code;
+    field public final String[] history;
+    field public final int index;
+    field public final int notificationType;
+    field public final String number;
+    field public final int type;
+  }
+
+  public class ImsUtListener {
+    method public void onLineIdentificationSupplementaryServiceResponse(int, @NonNull android.telephony.ims.ImsSsInfo);
+    method public void onSupplementaryServiceIndication(android.telephony.ims.ImsSsData);
+    method public void onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]);
+    method public void onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]);
+    method public void onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]);
+    method @Deprecated public void onUtConfigurationQueried(int, android.os.Bundle);
+    method public void onUtConfigurationQueryFailed(int, android.telephony.ims.ImsReasonInfo);
+    method public void onUtConfigurationUpdateFailed(int, android.telephony.ims.ImsReasonInfo);
+    method public void onUtConfigurationUpdated(int);
+    field @Deprecated public static final String BUNDLE_KEY_CLIR = "queryClir";
+    field @Deprecated public static final String BUNDLE_KEY_SSINFO = "imsSsInfo";
+  }
+
+  public abstract class ImsVideoCallProvider {
+    ctor public ImsVideoCallProvider();
+    method public void changeCallDataUsage(long);
+    method public void changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities);
+    method public void changePeerDimensions(int, int);
+    method public void changeVideoQuality(int);
+    method public void handleCallSessionEvent(int);
+    method public abstract void onRequestCallDataUsage();
+    method public abstract void onRequestCameraCapabilities();
+    method public abstract void onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile);
+    method public abstract void onSendSessionModifyResponse(android.telecom.VideoProfile);
+    method public abstract void onSetCamera(String);
+    method public void onSetCamera(String, int);
+    method public abstract void onSetDeviceOrientation(int);
+    method public abstract void onSetDisplaySurface(android.view.Surface);
+    method public abstract void onSetPauseImage(android.net.Uri);
+    method public abstract void onSetPreviewSurface(android.view.Surface);
+    method public abstract void onSetZoom(float);
+    method public void receiveSessionModifyRequest(android.telecom.VideoProfile);
+    method public void receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile);
+  }
+
+  public class ProvisioningManager {
+    method @NonNull public static android.telephony.ims.ProvisioningManager createForSubscriptionId(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public int getProvisioningIntValue(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean getProvisioningStatusForCapability(int, int);
+    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public String getProvisioningStringValue(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean getRcsProvisioningStatusForCapability(int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerProvisioningChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.Callback) throws android.telephony.ims.ImsException;
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningIntValue(int, int);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setProvisioningStatusForCapability(int, int, boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setRcsProvisioningStatusForCapability(int, boolean);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
+    field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
+    field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a
+    field public static final int PROVISIONING_VALUE_DISABLED = 0; // 0x0
+    field public static final int PROVISIONING_VALUE_ENABLED = 1; // 0x1
+    field public static final String STRING_QUERY_RESULT_ERROR_GENERIC = "STRING_QUERY_RESULT_ERROR_GENERIC";
+    field public static final String STRING_QUERY_RESULT_ERROR_NOT_READY = "STRING_QUERY_RESULT_ERROR_NOT_READY";
+  }
+
+  public static class ProvisioningManager.Callback {
+    ctor public ProvisioningManager.Callback();
+    method public void onProvisioningIntChanged(int, int);
+    method public void onProvisioningStringChanged(int, @NonNull String);
+  }
+
+  public class RcsUceAdapter {
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
+  }
+
+}
+
+package android.telephony.ims.feature {
+
+  public final class CapabilityChangeRequest implements android.os.Parcelable {
+    method public void addCapabilitiesToDisableForTech(int, int);
+    method public void addCapabilitiesToEnableForTech(int, int);
+    method public int describeContents();
+    method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToDisable();
+    method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToEnable();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.feature.CapabilityChangeRequest> CREATOR;
+  }
+
+  public static class CapabilityChangeRequest.CapabilityPair {
+    ctor public CapabilityChangeRequest.CapabilityPair(int, int);
+    method public int getCapability();
+    method public int getRadioTech();
+  }
+
+  public abstract class ImsFeature {
+    ctor public ImsFeature();
+    method public abstract void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
+    method public int getFeatureState();
+    method public final int getSlotIndex();
+    method public abstract void onFeatureReady();
+    method public abstract void onFeatureRemoved();
+    method public final void setFeatureState(int);
+    field public static final int CAPABILITY_ERROR_GENERIC = -1; // 0xffffffff
+    field public static final int CAPABILITY_SUCCESS = 0; // 0x0
+    field public static final int FEATURE_EMERGENCY_MMTEL = 0; // 0x0
+    field public static final int FEATURE_MMTEL = 1; // 0x1
+    field public static final int FEATURE_RCS = 2; // 0x2
+    field public static final int STATE_INITIALIZING = 1; // 0x1
+    field public static final int STATE_READY = 2; // 0x2
+    field public static final int STATE_UNAVAILABLE = 0; // 0x0
+  }
+
+  @Deprecated public static class ImsFeature.Capabilities {
+    field @Deprecated protected int mCapabilities;
+  }
+
+  protected static class ImsFeature.CapabilityCallbackProxy {
+    method public void onChangeCapabilityConfigurationError(int, int, int);
+  }
+
+  public class MmTelFeature extends android.telephony.ims.feature.ImsFeature {
+    ctor public MmTelFeature();
+    method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
+    method @Nullable public android.telephony.ims.ImsCallProfile createCallProfile(int, int);
+    method @Nullable public android.telephony.ims.stub.ImsCallSessionImplBase createCallSession(@NonNull android.telephony.ims.ImsCallProfile);
+    method @NonNull public android.telephony.ims.stub.ImsEcbmImplBase getEcbm();
+    method @NonNull public android.telephony.ims.stub.ImsMultiEndpointImplBase getMultiEndpoint();
+    method @NonNull public android.telephony.ims.stub.ImsSmsImplBase getSmsImplementation();
+    method @NonNull public android.telephony.ims.stub.ImsUtImplBase getUt();
+    method public final void notifyCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
+    method public final void notifyIncomingCall(@NonNull android.telephony.ims.stub.ImsCallSessionImplBase, @NonNull android.os.Bundle);
+    method public final void notifyRejectedCall(@NonNull android.telephony.ims.ImsCallProfile, @NonNull android.telephony.ims.ImsReasonInfo);
+    method public final void notifyVoiceMessageCountUpdate(int);
+    method public void onFeatureReady();
+    method public void onFeatureRemoved();
+    method public boolean queryCapabilityConfiguration(int, int);
+    method @NonNull public final android.telephony.ims.feature.MmTelFeature.MmTelCapabilities queryCapabilityStatus();
+    method public void setUiTtyMode(int, @Nullable android.os.Message);
+    method public int shouldProcessCall(@NonNull String[]);
+    field public static final String EXTRA_IS_UNKNOWN_CALL = "android.telephony.ims.feature.extra.IS_UNKNOWN_CALL";
+    field public static final String EXTRA_IS_USSD = "android.telephony.ims.feature.extra.IS_USSD";
+    field public static final int PROCESS_CALL_CSFB = 1; // 0x1
+    field public static final int PROCESS_CALL_IMS = 0; // 0x0
+  }
+
+  public static class MmTelFeature.MmTelCapabilities extends android.telephony.ims.feature.ImsFeature.Capabilities {
+    ctor public MmTelFeature.MmTelCapabilities();
+    ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities);
+    ctor public MmTelFeature.MmTelCapabilities(int);
+    method public final void addCapabilities(int);
+    method public final boolean isCapable(int);
+    method public final void removeCapabilities(int);
+  }
+
+  public class RcsFeature extends android.telephony.ims.feature.ImsFeature {
+    ctor public RcsFeature();
+    method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
+    method public void onFeatureReady();
+    method public void onFeatureRemoved();
+  }
+
+}
+
+package android.telephony.ims.stub {
+
+  public class ImsCallSessionImplBase implements java.lang.AutoCloseable {
+    ctor public ImsCallSessionImplBase();
+    method public void accept(int, android.telephony.ims.ImsStreamMediaProfile);
+    method public void close();
+    method public void deflect(String);
+    method public void extendToConference(String[]);
+    method public String getCallId();
+    method public android.telephony.ims.ImsCallProfile getCallProfile();
+    method public android.telephony.ims.ImsVideoCallProvider getImsVideoCallProvider();
+    method public android.telephony.ims.ImsCallProfile getLocalCallProfile();
+    method public String getProperty(String);
+    method public android.telephony.ims.ImsCallProfile getRemoteCallProfile();
+    method public int getState();
+    method public void hold(android.telephony.ims.ImsStreamMediaProfile);
+    method public void inviteParticipants(String[]);
+    method public boolean isInCall();
+    method public boolean isMultiparty();
+    method public void merge();
+    method public void reject(int);
+    method public void removeParticipants(String[]);
+    method public void resume(android.telephony.ims.ImsStreamMediaProfile);
+    method public void sendDtmf(char, android.os.Message);
+    method public void sendRttMessage(String);
+    method public void sendRttModifyRequest(android.telephony.ims.ImsCallProfile);
+    method public void sendRttModifyResponse(boolean);
+    method public void sendUssd(String);
+    method public void setListener(android.telephony.ims.ImsCallSessionListener);
+    method public void setMute(boolean);
+    method public void start(String, android.telephony.ims.ImsCallProfile);
+    method public void startConference(String[], android.telephony.ims.ImsCallProfile);
+    method public void startDtmf(char);
+    method public void stopDtmf();
+    method public void terminate(int);
+    method public void update(int, android.telephony.ims.ImsStreamMediaProfile);
+    field public static final int USSD_MODE_NOTIFY = 0; // 0x0
+    field public static final int USSD_MODE_REQUEST = 1; // 0x1
+  }
+
+  public static class ImsCallSessionImplBase.State {
+    method public static String toString(int);
+    field public static final int ESTABLISHED = 4; // 0x4
+    field public static final int ESTABLISHING = 3; // 0x3
+    field public static final int IDLE = 0; // 0x0
+    field public static final int INITIATED = 1; // 0x1
+    field public static final int INVALID = -1; // 0xffffffff
+    field public static final int NEGOTIATING = 2; // 0x2
+    field public static final int REESTABLISHING = 6; // 0x6
+    field public static final int RENEGOTIATING = 5; // 0x5
+    field public static final int TERMINATED = 8; // 0x8
+    field public static final int TERMINATING = 7; // 0x7
+  }
+
+  public class ImsConfigImplBase {
+    ctor public ImsConfigImplBase();
+    method public int getConfigInt(int);
+    method public String getConfigString(int);
+    method public final void notifyProvisionedValueChanged(int, int);
+    method public final void notifyProvisionedValueChanged(int, String);
+    method public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean);
+    method public int setConfig(int, int);
+    method public int setConfig(int, String);
+    field public static final int CONFIG_RESULT_FAILED = 1; // 0x1
+    field public static final int CONFIG_RESULT_SUCCESS = 0; // 0x0
+    field public static final int CONFIG_RESULT_UNKNOWN = -1; // 0xffffffff
+  }
+
+  public class ImsEcbmImplBase {
+    ctor public ImsEcbmImplBase();
+    method public final void enteredEcbm();
+    method public void exitEmergencyCallbackMode();
+    method public final void exitedEcbm();
+  }
+
+  public final class ImsFeatureConfiguration implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.util.Set<android.telephony.ims.stub.ImsFeatureConfiguration.FeatureSlotPair> getServiceFeatures();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.stub.ImsFeatureConfiguration> CREATOR;
+  }
+
+  public static class ImsFeatureConfiguration.Builder {
+    ctor public ImsFeatureConfiguration.Builder();
+    method public android.telephony.ims.stub.ImsFeatureConfiguration.Builder addFeature(int, int);
+    method public android.telephony.ims.stub.ImsFeatureConfiguration build();
+  }
+
+  public static final class ImsFeatureConfiguration.FeatureSlotPair {
+    ctor public ImsFeatureConfiguration.FeatureSlotPair(int, int);
+    field public final int featureType;
+    field public final int slotId;
+  }
+
+  public class ImsMultiEndpointImplBase {
+    ctor public ImsMultiEndpointImplBase();
+    method public final void onImsExternalCallStateUpdate(java.util.List<android.telephony.ims.ImsExternalCallState>);
+    method public void requestImsExternalCallStateInfo();
+  }
+
+  public class ImsRegistrationImplBase {
+    ctor public ImsRegistrationImplBase();
+    method public final void onDeregistered(android.telephony.ims.ImsReasonInfo);
+    method public final void onRegistered(int);
+    method public final void onRegistering(int);
+    method public final void onSubscriberAssociatedUriChanged(android.net.Uri[]);
+    method public final void onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo);
+    field public static final int REGISTRATION_TECH_IWLAN = 1; // 0x1
+    field public static final int REGISTRATION_TECH_LTE = 0; // 0x0
+    field public static final int REGISTRATION_TECH_NONE = -1; // 0xffffffff
+  }
+
+  public class ImsSmsImplBase {
+    ctor public ImsSmsImplBase();
+    method public void acknowledgeSms(int, @IntRange(from=0, to=65535) int, int);
+    method public void acknowledgeSmsReport(int, @IntRange(from=0, to=65535) int, int);
+    method public String getSmsFormat();
+    method public void onReady();
+    method @Deprecated public final void onSendSmsResult(int, @IntRange(from=0, to=65535) int, int, int) throws java.lang.RuntimeException;
+    method public final void onSendSmsResultError(int, @IntRange(from=0, to=65535) int, int, int, int) throws java.lang.RuntimeException;
+    method public final void onSendSmsResultSuccess(int, @IntRange(from=0, to=65535) int) throws java.lang.RuntimeException;
+    method public final void onSmsReceived(int, String, byte[]) throws java.lang.RuntimeException;
+    method @Deprecated public final void onSmsStatusReportReceived(int, @IntRange(from=0, to=65535) int, String, byte[]) throws java.lang.RuntimeException;
+    method public final void onSmsStatusReportReceived(int, String, byte[]) throws java.lang.RuntimeException;
+    method public void sendSms(int, @IntRange(from=0, to=65535) int, String, String, boolean, byte[]);
+    field public static final int DELIVER_STATUS_ERROR_GENERIC = 2; // 0x2
+    field public static final int DELIVER_STATUS_ERROR_NO_MEMORY = 3; // 0x3
+    field public static final int DELIVER_STATUS_ERROR_REQUEST_NOT_SUPPORTED = 4; // 0x4
+    field public static final int DELIVER_STATUS_OK = 1; // 0x1
+    field public static final int RESULT_NO_NETWORK_ERROR = -1; // 0xffffffff
+    field public static final int SEND_STATUS_ERROR = 2; // 0x2
+    field public static final int SEND_STATUS_ERROR_FALLBACK = 4; // 0x4
+    field public static final int SEND_STATUS_ERROR_RETRY = 3; // 0x3
+    field public static final int SEND_STATUS_OK = 1; // 0x1
+    field public static final int STATUS_REPORT_STATUS_ERROR = 2; // 0x2
+    field public static final int STATUS_REPORT_STATUS_OK = 1; // 0x1
+  }
+
+  public class ImsUtImplBase {
+    ctor public ImsUtImplBase();
+    method public void close();
+    method public int queryCallBarring(int);
+    method public int queryCallBarringForServiceClass(int, int);
+    method public int queryCallForward(int, String);
+    method public int queryCallWaiting();
+    method public int queryClip();
+    method public int queryClir();
+    method public int queryColp();
+    method public int queryColr();
+    method public void setListener(android.telephony.ims.ImsUtListener);
+    method public int transact(android.os.Bundle);
+    method public int updateCallBarring(int, int, String[]);
+    method public int updateCallBarringForServiceClass(int, int, String[], int);
+    method public int updateCallForward(int, int, String, int, int);
+    method public int updateCallWaiting(boolean, int);
+    method public int updateClip(boolean);
+    method public int updateClir(int);
+    method public int updateColp(boolean);
+    method public int updateColr(int);
+  }
+
+}
+
+package android.telephony.mbms {
+
+  public static class DownloadRequest.Builder {
+    method public android.telephony.mbms.DownloadRequest.Builder setServiceId(String);
+  }
+
+  public final class FileInfo implements android.os.Parcelable {
+    ctor public FileInfo(android.net.Uri, String);
+  }
+
+  public final class FileServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable {
+    ctor public FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>);
+  }
+
+  public class MbmsDownloadReceiver extends android.content.BroadcastReceiver {
+    field public static final int RESULT_APP_NOTIFICATION_ERROR = 6; // 0x6
+    field public static final int RESULT_BAD_TEMP_FILE_ROOT = 3; // 0x3
+    field public static final int RESULT_DOWNLOAD_FINALIZATION_ERROR = 4; // 0x4
+    field public static final int RESULT_INVALID_ACTION = 1; // 0x1
+    field public static final int RESULT_MALFORMED_INTENT = 2; // 0x2
+    field public static final int RESULT_OK = 0; // 0x0
+    field public static final int RESULT_TEMP_FILE_GENERATION_ERROR = 5; // 0x5
+  }
+
+  public final class StreamingServiceInfo extends android.telephony.mbms.ServiceInfo implements android.os.Parcelable {
+    ctor public StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date);
+  }
+
+  public final class UriPathPair implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.net.Uri getContentUri();
+    method public android.net.Uri getFilePathUri();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.mbms.UriPathPair> CREATOR;
+  }
+
+}
+
+package android.telephony.mbms.vendor {
+
+  public class MbmsDownloadServiceBase extends android.os.Binder implements android.os.IInterface {
+    ctor public MbmsDownloadServiceBase();
+    method public int addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException;
+    method public int addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException;
+    method public android.os.IBinder asBinder();
+    method public int cancelDownload(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
+    method public void dispose(int) throws android.os.RemoteException;
+    method public int download(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
+    method public int initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback) throws android.os.RemoteException;
+    method @NonNull public java.util.List<android.telephony.mbms.DownloadRequest> listPendingDownloads(int) throws android.os.RemoteException;
+    method public void onAppCallbackDied(int, int);
+    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+    method public int removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) throws android.os.RemoteException;
+    method public int removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) throws android.os.RemoteException;
+    method public int requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) throws android.os.RemoteException;
+    method public int requestUpdateFileServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
+    method public int resetDownloadKnowledge(android.telephony.mbms.DownloadRequest) throws android.os.RemoteException;
+    method public int setTempFileRootDirectory(int, String) throws android.os.RemoteException;
+  }
+
+  public class MbmsGroupCallServiceBase extends android.app.Service {
+    ctor public MbmsGroupCallServiceBase();
+    method public void dispose(int) throws android.os.RemoteException;
+    method public int initialize(@NonNull android.telephony.mbms.MbmsGroupCallSessionCallback, int) throws android.os.RemoteException;
+    method public void onAppCallbackDied(int, int);
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public int startGroupCall(int, long, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>, @NonNull android.telephony.mbms.GroupCallCallback);
+    method public void stopGroupCall(int, long);
+    method public void updateGroupCall(int, long, @NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.lang.Integer>);
+  }
+
+  public class MbmsStreamingServiceBase extends android.os.Binder implements android.os.IInterface {
+    ctor public MbmsStreamingServiceBase();
+    method public android.os.IBinder asBinder();
+    method public void dispose(int) throws android.os.RemoteException;
+    method @Nullable public android.net.Uri getPlaybackUri(int, String) throws android.os.RemoteException;
+    method public int initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int) throws android.os.RemoteException;
+    method public void onAppCallbackDied(int, int);
+    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+    method public int requestUpdateStreamingServices(int, java.util.List<java.lang.String>) throws android.os.RemoteException;
+    method public int startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback) throws android.os.RemoteException;
+    method public void stopStreaming(int, String) throws android.os.RemoteException;
+  }
+
+  public class VendorUtils {
+    ctor public VendorUtils();
+    method public static android.content.ComponentName getAppReceiverFromPackageName(android.content.Context, String);
+    field public static final String ACTION_CLEANUP = "android.telephony.mbms.action.CLEANUP";
+    field public static final String ACTION_DOWNLOAD_RESULT_INTERNAL = "android.telephony.mbms.action.DOWNLOAD_RESULT_INTERNAL";
+    field public static final String ACTION_FILE_DESCRIPTOR_REQUEST = "android.telephony.mbms.action.FILE_DESCRIPTOR_REQUEST";
+    field public static final String EXTRA_FD_COUNT = "android.telephony.mbms.extra.FD_COUNT";
+    field public static final String EXTRA_FINAL_URI = "android.telephony.mbms.extra.FINAL_URI";
+    field public static final String EXTRA_FREE_URI_LIST = "android.telephony.mbms.extra.FREE_URI_LIST";
+    field public static final String EXTRA_PAUSED_LIST = "android.telephony.mbms.extra.PAUSED_LIST";
+    field public static final String EXTRA_PAUSED_URI_LIST = "android.telephony.mbms.extra.PAUSED_URI_LIST";
+    field public static final String EXTRA_SERVICE_ID = "android.telephony.mbms.extra.SERVICE_ID";
+    field public static final String EXTRA_TEMP_FILES_IN_USE = "android.telephony.mbms.extra.TEMP_FILES_IN_USE";
+    field public static final String EXTRA_TEMP_FILE_ROOT = "android.telephony.mbms.extra.TEMP_FILE_ROOT";
+    field public static final String EXTRA_TEMP_LIST = "android.telephony.mbms.extra.TEMP_LIST";
+  }
+
+}
+
diff --git a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
index de0221c..3c1e707 100644
--- a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
@@ -31,6 +31,7 @@
 import android.util.ArraySet;
 import android.util.Log;
 
+import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.util.ArrayUtils;
 import com.android.server.SystemConfig;
@@ -156,7 +157,7 @@
             for (ApplicationInfo ai : candidates) {
                 String packageName = ai.packageName;
                 String[] restrictedCarrierApps = Resources.getSystem().getStringArray(
-                        android.R.array.config_restrictedPreinstalledCarrierApps);
+                        R.array.config_restrictedPreinstalledCarrierApps);
                 boolean hasPrivileges = telephonyManager != null
                         && telephonyManager.checkCarrierPrivilegesForPackageAnyPhone(packageName)
                                 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
diff --git a/telephony/common/com/android/internal/telephony/GsmAlphabet.java b/telephony/common/com/android/internal/telephony/GsmAlphabet.java
index 2201452..60cd400 100644
--- a/telephony/common/com/android/internal/telephony/GsmAlphabet.java
+++ b/telephony/common/com/android/internal/telephony/GsmAlphabet.java
@@ -19,10 +19,12 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.res.Resources;
 import android.os.Build;
-import android.text.TextUtils;
 import android.util.Log;
+import android.text.TextUtils;
 import android.util.SparseIntArray;
 
+import com.android.internal.R;
+
 import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
@@ -1085,10 +1087,8 @@
     private static void enableCountrySpecificEncodings() {
         Resources r = Resources.getSystem();
         // See comments in frameworks/base/core/res/res/values/config.xml for allowed values
-        sEnabledSingleShiftTables = r.getIntArray(
-                android.R.array.config_sms_enabled_single_shift_tables);
-        sEnabledLockingShiftTables = r.getIntArray(
-                android.R.array.config_sms_enabled_locking_shift_tables);
+        sEnabledSingleShiftTables = r.getIntArray(R.array.config_sms_enabled_single_shift_tables);
+        sEnabledLockingShiftTables = r.getIntArray(R.array.config_sms_enabled_locking_shift_tables);
 
         if (sEnabledSingleShiftTables.length > 0) {
             sHighestEnabledSingleShiftCode =
diff --git a/telephony/common/com/android/internal/telephony/SmsApplication.java b/telephony/common/com/android/internal/telephony/SmsApplication.java
index 98a649f..1a049e6 100644
--- a/telephony/common/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/common/com/android/internal/telephony/SmsApplication.java
@@ -1051,8 +1051,7 @@
     }
 
     /**
-     * Check if a package is default sms app (or equivalent, like bluetooth), and verify that
-     * packageName belongs to the caller.
+     * Check if a package is default sms app (or equivalent, like bluetooth)
      *
      * @param context context from the calling app
      * @param packageName the name of the package to be checked
@@ -1061,22 +1060,8 @@
     @UnsupportedAppUsage
     public static boolean isDefaultSmsApplication(Context context, String packageName) {
         if (packageName == null) {
-            Log.e(LOG_TAG, "isDefaultSmsApplication: packageName is null");
             return false;
         }
-        try {
-            if (Binder.getCallingUid()
-                    == context.getPackageManager().getPackageUid(packageName, 0)) {
-                Log.e(LOG_TAG, "isDefaultSmsApplication: " + packageName + " calling uid "
-                        + context.getPackageManager().getPackageUid(packageName, 0)
-                        + " does not match calling uid " + Binder.getCallingUid());
-                return false;
-            }
-        } catch (NameNotFoundException ex) {
-            Log.e(LOG_TAG, "isDefaultSmsApplication: packageName " + packageName + " not found");
-            return false;
-        }
-
         final String defaultSmsPackage = getDefaultSmsApplicationPackageName(context);
         if ((defaultSmsPackage != null && defaultSmsPackage.equals(packageName))
                 || BLUETOOTH_PACKAGE_NAME.equals(packageName)) {
diff --git a/telephony/common/com/google/android/mms/pdu/PduComposer.java b/telephony/common/com/google/android/mms/pdu/PduComposer.java
index b8b212c..5e1f556 100644
--- a/telephony/common/com/google/android/mms/pdu/PduComposer.java
+++ b/telephony/common/com/google/android/mms/pdu/PduComposer.java
@@ -745,7 +745,9 @@
             return PDU_COMPOSE_CONTENT_ERROR;
         }
 
-        // X-Mms-Report-Allowed Optional (not support)
+        // X-Mms-Report-Allowed Optional
+        appendHeader(PduHeaders.REPORT_ALLOWED);
+
         return PDU_COMPOSE_SUCCESS;
     }
 
diff --git a/telephony/common/com/google/android/mms/util/SqliteWrapper.java b/telephony/common/com/google/android/mms/util/SqliteWrapper.java
index 4871434..31fe4d7 100644
--- a/telephony/common/com/google/android/mms/util/SqliteWrapper.java
+++ b/telephony/common/com/google/android/mms/util/SqliteWrapper.java
@@ -60,7 +60,8 @@
     @UnsupportedAppUsage
     public static void checkSQLiteException(Context context, SQLiteException e) {
         if (isLowMemory(e)) {
-            Toast.makeText(context, android.R.string.low_memory, Toast.LENGTH_SHORT).show();
+            Toast.makeText(context, com.android.internal.R.string.low_memory,
+                    Toast.LENGTH_SHORT).show();
         } else {
             throw e;
         }
diff --git a/telephony/java/android/service/carrier/CarrierService.java b/telephony/java/android/service/carrier/CarrierService.java
index eefc1b7..d06ec11 100644
--- a/telephony/java/android/service/carrier/CarrierService.java
+++ b/telephony/java/android/service/carrier/CarrierService.java
@@ -25,6 +25,9 @@
 import android.telephony.TelephonyRegistryManager;
 import android.util.Log;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
 /**
  * A service that exposes carrier-specific functionality to the system.
  * <p>
@@ -156,5 +159,10 @@
                 result.send(RESULT_ERROR, null);
             }
         }
+
+        @Override
+        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            CarrierService.this.dump(fd, pw, args);
+        }
     }
 }
diff --git a/telephony/java/android/service/euicc/EuiccService.java b/telephony/java/android/service/euicc/EuiccService.java
index ef11f46..ae2652e 100644
--- a/telephony/java/android/service/euicc/EuiccService.java
+++ b/telephony/java/android/service/euicc/EuiccService.java
@@ -31,7 +31,9 @@
 import android.telephony.TelephonyManager;
 import android.telephony.euicc.DownloadableSubscription;
 import android.telephony.euicc.EuiccInfo;
+import android.telephony.euicc.EuiccManager;
 import android.telephony.euicc.EuiccManager.OtaStatus;
+import android.text.TextUtils;
 import android.util.Log;
 
 import java.io.PrintWriter;
@@ -311,6 +313,64 @@
         mStubWrapper = new IEuiccServiceWrapper();
     }
 
+    /**
+     * Given a SubjectCode[5.2.6.1] and ReasonCode[5.2.6.2] from GSMA (SGP.22 v2.2), encode it to
+     * the format described in
+     * {@link android.telephony.euicc.EuiccManager#OPERATION_SMDX_SUBJECT_REASON_CODE}
+     *
+     * @param subjectCode SubjectCode[5.2.6.1] from GSMA (SGP.22 v2.2)
+     * @param reasonCode  ReasonCode[5.2.6.2] from GSMA (SGP.22 v2.2)
+     * @return encoded error code described in
+     * {@link android.telephony.euicc.EuiccManager#OPERATION_SMDX_SUBJECT_REASON_CODE}
+     * @throws NumberFormatException         when the Subject/Reason code contains non digits
+     * @throws IllegalArgumentException      when Subject/Reason code is null/empty
+     * @throws UnsupportedOperationException when sections has more than four layers (e.g 5.8.1.2)
+     *                                       or when an number is bigger than 15
+     */
+    public int encodeSmdxSubjectAndReasonCode(@NonNull String subjectCode,
+            @NonNull String reasonCode) {
+        final int maxSupportedSection = 3;
+        final int maxSupportedDigit = 15;
+        final int bitsPerSection = 4;
+
+        if (TextUtils.isEmpty(subjectCode) || TextUtils.isEmpty(reasonCode)) {
+            throw new IllegalArgumentException("SubjectCode/ReasonCode is empty");
+        }
+
+        final String[] subjectCodeToken = subjectCode.split("\\.");
+        final String[] reasonCodeToken = reasonCode.split("\\.");
+
+        if (subjectCodeToken.length > maxSupportedSection
+                || reasonCodeToken.length > maxSupportedSection) {
+            throw new UnsupportedOperationException("Only three nested layer is supported.");
+        }
+
+        int result = EuiccManager.OPERATION_SMDX_SUBJECT_REASON_CODE;
+
+        // Pad the 0s needed for subject code
+        result = result << (maxSupportedSection - subjectCodeToken.length) * bitsPerSection;
+
+        for (String digitString : subjectCodeToken) {
+            int num = Integer.parseInt(digitString);
+            if (num > maxSupportedDigit) {
+                throw new UnsupportedOperationException("SubjectCode exceeds " + maxSupportedDigit);
+            }
+            result = (result << bitsPerSection) + num;
+        }
+
+        // Pad the 0s needed for reason code
+        result = result << (maxSupportedSection - reasonCodeToken.length) * bitsPerSection;
+        for (String digitString : reasonCodeToken) {
+            int num = Integer.parseInt(digitString);
+            if (num > maxSupportedDigit) {
+                throw new UnsupportedOperationException("ReasonCode exceeds " + maxSupportedDigit);
+            }
+            result = (result << bitsPerSection) + num;
+        }
+
+        return result;
+    }
+
     @Override
     @CallSuper
     public void onCreate() {
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index 01abb26..558f4cd 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -19,6 +19,10 @@
 import android.annotation.IntDef;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.hardware.radio.V1_1.EutranBands;
+import android.hardware.radio.V1_1.GeranBands;
+import android.hardware.radio.V1_5.AccessNetwork;
+import android.hardware.radio.V1_5.UtranBands;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -84,13 +88,13 @@
     public @interface RadioAccessNetworkType {}
 
     public static final class AccessNetworkType {
-        public static final int UNKNOWN = 0;
-        public static final int GERAN = 1;
-        public static final int UTRAN = 2;
-        public static final int EUTRAN = 3;
-        public static final int CDMA2000 = 4;
-        public static final int IWLAN = 5;
-        public static final int NGRAN = 6;
+        public static final int UNKNOWN = AccessNetwork.UNKNOWN;
+        public static final int GERAN = AccessNetwork.GERAN;
+        public static final int UTRAN = AccessNetwork.UTRAN;
+        public static final int EUTRAN = AccessNetwork.EUTRAN;
+        public static final int CDMA2000 = AccessNetwork.CDMA2000;
+        public static final int IWLAN = AccessNetwork.IWLAN;
+        public static final int NGRAN = AccessNetwork.NGRAN;
 
         /** @hide */
         private AccessNetworkType() {}
@@ -115,20 +119,20 @@
      * http://www.etsi.org/deliver/etsi_ts/145000_145099/145005/14.00.00_60/ts_145005v140000p.pdf
      */
     public static final class GeranBand {
-        public static final int BAND_T380 = 1;
-        public static final int BAND_T410 = 2;
-        public static final int BAND_450 = 3;
-        public static final int BAND_480 = 4;
-        public static final int BAND_710 = 5;
-        public static final int BAND_750 = 6;
-        public static final int BAND_T810 = 7;
-        public static final int BAND_850 = 8;
-        public static final int BAND_P900 = 9;
-        public static final int BAND_E900 = 10;
-        public static final int BAND_R900 = 11;
-        public static final int BAND_DCS1800 = 12;
-        public static final int BAND_PCS1900 = 13;
-        public static final int BAND_ER900 = 14;
+        public static final int BAND_T380 = GeranBands.BAND_T380;
+        public static final int BAND_T410 = GeranBands.BAND_T410;
+        public static final int BAND_450 = GeranBands.BAND_450;
+        public static final int BAND_480 = GeranBands.BAND_480;
+        public static final int BAND_710 = GeranBands.BAND_710;
+        public static final int BAND_750 = GeranBands.BAND_750;
+        public static final int BAND_T810 = GeranBands.BAND_T810;
+        public static final int BAND_850 = GeranBands.BAND_850;
+        public static final int BAND_P900 = GeranBands.BAND_P900;
+        public static final int BAND_E900 = GeranBands.BAND_E900;
+        public static final int BAND_R900 = GeranBands.BAND_R900;
+        public static final int BAND_DCS1800 = GeranBands.BAND_DCS1800;
+        public static final int BAND_PCS1900 = GeranBands.BAND_PCS1900;
+        public static final int BAND_ER900 = GeranBands.BAND_ER900;
 
         /** @hide */
         private GeranBand() {}
@@ -139,28 +143,28 @@
      * http://www.etsi.org/deliver/etsi_ts/125100_125199/125104/13.03.00_60/ts_125104v130p.pdf
      */
     public static final class UtranBand {
-        public static final int BAND_1 = 1;
-        public static final int BAND_2 = 2;
-        public static final int BAND_3 = 3;
-        public static final int BAND_4 = 4;
-        public static final int BAND_5 = 5;
-        public static final int BAND_6 = 6;
-        public static final int BAND_7 = 7;
-        public static final int BAND_8 = 8;
-        public static final int BAND_9 = 9;
-        public static final int BAND_10 = 10;
-        public static final int BAND_11 = 11;
-        public static final int BAND_12 = 12;
-        public static final int BAND_13 = 13;
-        public static final int BAND_14 = 14;
+        public static final int BAND_1 = UtranBands.BAND_1;
+        public static final int BAND_2 = UtranBands.BAND_2;
+        public static final int BAND_3 = UtranBands.BAND_3;
+        public static final int BAND_4 = UtranBands.BAND_4;
+        public static final int BAND_5 = UtranBands.BAND_5;
+        public static final int BAND_6 = UtranBands.BAND_6;
+        public static final int BAND_7 = UtranBands.BAND_7;
+        public static final int BAND_8 = UtranBands.BAND_8;
+        public static final int BAND_9 = UtranBands.BAND_9;
+        public static final int BAND_10 = UtranBands.BAND_10;
+        public static final int BAND_11 = UtranBands.BAND_11;
+        public static final int BAND_12 = UtranBands.BAND_12;
+        public static final int BAND_13 = UtranBands.BAND_13;
+        public static final int BAND_14 = UtranBands.BAND_14;
         // band 15, 16, 17, 18 are reserved
-        public static final int BAND_19 = 19;
-        public static final int BAND_20 = 20;
-        public static final int BAND_21 = 21;
-        public static final int BAND_22 = 22;
+        public static final int BAND_19 = UtranBands.BAND_19;
+        public static final int BAND_20 = UtranBands.BAND_20;
+        public static final int BAND_21 = UtranBands.BAND_21;
+        public static final int BAND_22 = UtranBands.BAND_22;
         // band 23, 24 are reserved
-        public static final int BAND_25 = 25;
-        public static final int BAND_26 = 26;
+        public static final int BAND_25 = UtranBands.BAND_25;
+        public static final int BAND_26 = UtranBands.BAND_26;
 
         // Frequency bands for TD-SCDMA. Defined in 3GPP TS 25.102, Table 5.2.
 
@@ -169,38 +173,38 @@
          * 1900 - 1920 MHz: Uplink and downlink transmission
          * 2010 - 2025 MHz: Uplink and downlink transmission
          */
-        public static final int BAND_A = 101;
+        public static final int BAND_A = UtranBands.BAND_A;
 
         /**
          * Band B
          * 1850 - 1910 MHz: Uplink and downlink transmission
          * 1930 - 1990 MHz: Uplink and downlink transmission
          */
-        public static final int BAND_B = 102;
+        public static final int BAND_B = UtranBands.BAND_B;
 
         /**
          * Band C
          * 1910 - 1930 MHz: Uplink and downlink transmission
          */
-        public static final int BAND_C = 103;
+        public static final int BAND_C = UtranBands.BAND_C;
 
         /**
          * Band D
          * 2570 - 2620 MHz: Uplink and downlink transmission
          */
-        public static final int BAND_D = 104;
+        public static final int BAND_D = UtranBands.BAND_D;
 
         /**
          * Band E
          * 2300—2400 MHz: Uplink and downlink transmission
          */
-        public static final int BAND_E = 105;
+        public static final int BAND_E = UtranBands.BAND_E;
 
         /**
          * Band F
          * 1880 - 1920 MHz: Uplink and downlink transmission
          */
-        public static final int BAND_F = 106;
+        public static final int BAND_F = UtranBands.BAND_F;
 
         /** @hide */
         private UtranBand() {}
@@ -211,54 +215,54 @@
      * http://www.etsi.org/deliver/etsi_ts/136100_136199/136101/14.03.00_60/ts_136101v140p.pdf
      */
     public static final class EutranBand {
-        public static final int BAND_1 = 1;
-        public static final int BAND_2 = 2;
-        public static final int BAND_3 = 3;
-        public static final int BAND_4 = 4;
-        public static final int BAND_5 = 5;
-        public static final int BAND_6 = 6;
-        public static final int BAND_7 = 7;
-        public static final int BAND_8 = 8;
-        public static final int BAND_9 = 9;
-        public static final int BAND_10 = 10;
-        public static final int BAND_11 = 11;
-        public static final int BAND_12 = 12;
-        public static final int BAND_13 = 13;
-        public static final int BAND_14 = 14;
-        public static final int BAND_17 = 17;
-        public static final int BAND_18 = 18;
-        public static final int BAND_19 = 19;
-        public static final int BAND_20 = 20;
-        public static final int BAND_21 = 21;
-        public static final int BAND_22 = 22;
-        public static final int BAND_23 = 23;
-        public static final int BAND_24 = 24;
-        public static final int BAND_25 = 25;
-        public static final int BAND_26 = 26;
-        public static final int BAND_27 = 27;
-        public static final int BAND_28 = 28;
-        public static final int BAND_30 = 30;
-        public static final int BAND_31 = 31;
-        public static final int BAND_33 = 33;
-        public static final int BAND_34 = 34;
-        public static final int BAND_35 = 35;
-        public static final int BAND_36 = 36;
-        public static final int BAND_37 = 37;
-        public static final int BAND_38 = 38;
-        public static final int BAND_39 = 39;
-        public static final int BAND_40 = 40;
-        public static final int BAND_41 = 41;
-        public static final int BAND_42 = 42;
-        public static final int BAND_43 = 43;
-        public static final int BAND_44 = 44;
-        public static final int BAND_45 = 45;
-        public static final int BAND_46 = 46;
-        public static final int BAND_47 = 47;
-        public static final int BAND_48 = 48;
-        public static final int BAND_65 = 65;
-        public static final int BAND_66 = 66;
-        public static final int BAND_68 = 68;
-        public static final int BAND_70 = 70;
+        public static final int BAND_1 = EutranBands.BAND_1;
+        public static final int BAND_2 = EutranBands.BAND_2;
+        public static final int BAND_3 = EutranBands.BAND_3;
+        public static final int BAND_4 = EutranBands.BAND_4;
+        public static final int BAND_5 = EutranBands.BAND_5;
+        public static final int BAND_6 = EutranBands.BAND_6;
+        public static final int BAND_7 = EutranBands.BAND_7;
+        public static final int BAND_8 = EutranBands.BAND_8;
+        public static final int BAND_9 = EutranBands.BAND_9;
+        public static final int BAND_10 = EutranBands.BAND_10;
+        public static final int BAND_11 = EutranBands.BAND_11;
+        public static final int BAND_12 = EutranBands.BAND_12;
+        public static final int BAND_13 = EutranBands.BAND_13;
+        public static final int BAND_14 = EutranBands.BAND_14;
+        public static final int BAND_17 = EutranBands.BAND_17;
+        public static final int BAND_18 = EutranBands.BAND_18;
+        public static final int BAND_19 = EutranBands.BAND_19;
+        public static final int BAND_20 = EutranBands.BAND_20;
+        public static final int BAND_21 = EutranBands.BAND_21;
+        public static final int BAND_22 = EutranBands.BAND_22;
+        public static final int BAND_23 = EutranBands.BAND_23;
+        public static final int BAND_24 = EutranBands.BAND_24;
+        public static final int BAND_25 = EutranBands.BAND_25;
+        public static final int BAND_26 = EutranBands.BAND_26;
+        public static final int BAND_27 = EutranBands.BAND_27;
+        public static final int BAND_28 = EutranBands.BAND_28;
+        public static final int BAND_30 = EutranBands.BAND_30;
+        public static final int BAND_31 = EutranBands.BAND_31;
+        public static final int BAND_33 = EutranBands.BAND_33;
+        public static final int BAND_34 = EutranBands.BAND_34;
+        public static final int BAND_35 = EutranBands.BAND_35;
+        public static final int BAND_36 = EutranBands.BAND_36;
+        public static final int BAND_37 = EutranBands.BAND_37;
+        public static final int BAND_38 = EutranBands.BAND_38;
+        public static final int BAND_39 = EutranBands.BAND_39;
+        public static final int BAND_40 = EutranBands.BAND_40;
+        public static final int BAND_41 = EutranBands.BAND_41;
+        public static final int BAND_42 = EutranBands.BAND_42;
+        public static final int BAND_43 = EutranBands.BAND_43;
+        public static final int BAND_44 = EutranBands.BAND_44;
+        public static final int BAND_45 = EutranBands.BAND_45;
+        public static final int BAND_46 = EutranBands.BAND_46;
+        public static final int BAND_47 = EutranBands.BAND_47;
+        public static final int BAND_48 = EutranBands.BAND_48;
+        public static final int BAND_65 = EutranBands.BAND_65;
+        public static final int BAND_66 = EutranBands.BAND_66;
+        public static final int BAND_68 = EutranBands.BAND_68;
+        public static final int BAND_70 = EutranBands.BAND_70;
 
         /** @hide */
         private EutranBand() {};
@@ -304,51 +308,51 @@
      */
     public static final class NgranBands {
         /** FR1 bands */
-        public static final int BAND_1 = 1;
-        public static final int BAND_2 = 2;
-        public static final int BAND_3 = 3;
-        public static final int BAND_5 = 5;
-        public static final int BAND_7 = 7;
-        public static final int BAND_8 = 8;
-        public static final int BAND_12 = 12;
-        public static final int BAND_14 = 14;
-        public static final int BAND_18 = 18;
-        public static final int BAND_20 = 20;
-        public static final int BAND_25 = 25;
-        public static final int BAND_28 = 28;
-        public static final int BAND_29 = 29;
-        public static final int BAND_30 = 30;
-        public static final int BAND_34 = 34;
-        public static final int BAND_38 = 38;
-        public static final int BAND_39 = 39;
-        public static final int BAND_40 = 40;
-        public static final int BAND_41 = 41;
-        public static final int BAND_48 = 48;
-        public static final int BAND_50 = 50;
-        public static final int BAND_51 = 51;
-        public static final int BAND_65 = 65;
-        public static final int BAND_66 = 66;
-        public static final int BAND_70 = 70;
-        public static final int BAND_71 = 71;
-        public static final int BAND_74 = 74;
-        public static final int BAND_75 = 75;
-        public static final int BAND_76 = 76;
-        public static final int BAND_77 = 77;
-        public static final int BAND_78 = 78;
-        public static final int BAND_79 = 79;
-        public static final int BAND_80 = 80;
-        public static final int BAND_81 = 81;
-        public static final int BAND_82 = 82;
-        public static final int BAND_83 = 83;
-        public static final int BAND_84 = 84;
-        public static final int BAND_86 = 86;
-        public static final int BAND_90 = 90;
+        public static final int BAND_1 = android.hardware.radio.V1_5.NgranBands.BAND_1;
+        public static final int BAND_2 = android.hardware.radio.V1_5.NgranBands.BAND_2;
+        public static final int BAND_3 = android.hardware.radio.V1_5.NgranBands.BAND_3;
+        public static final int BAND_5 = android.hardware.radio.V1_5.NgranBands.BAND_5;
+        public static final int BAND_7 = android.hardware.radio.V1_5.NgranBands.BAND_7;
+        public static final int BAND_8 = android.hardware.radio.V1_5.NgranBands.BAND_8;
+        public static final int BAND_12 = android.hardware.radio.V1_5.NgranBands.BAND_12;
+        public static final int BAND_14 = android.hardware.radio.V1_5.NgranBands.BAND_14;
+        public static final int BAND_18 = android.hardware.radio.V1_5.NgranBands.BAND_18;
+        public static final int BAND_20 = android.hardware.radio.V1_5.NgranBands.BAND_20;
+        public static final int BAND_25 = android.hardware.radio.V1_5.NgranBands.BAND_25;
+        public static final int BAND_28 = android.hardware.radio.V1_5.NgranBands.BAND_28;
+        public static final int BAND_29 = android.hardware.radio.V1_5.NgranBands.BAND_29;
+        public static final int BAND_30 = android.hardware.radio.V1_5.NgranBands.BAND_30;
+        public static final int BAND_34 = android.hardware.radio.V1_5.NgranBands.BAND_34;
+        public static final int BAND_38 = android.hardware.radio.V1_5.NgranBands.BAND_38;
+        public static final int BAND_39 = android.hardware.radio.V1_5.NgranBands.BAND_39;
+        public static final int BAND_40 = android.hardware.radio.V1_5.NgranBands.BAND_40;
+        public static final int BAND_41 = android.hardware.radio.V1_5.NgranBands.BAND_41;
+        public static final int BAND_48 = android.hardware.radio.V1_5.NgranBands.BAND_48;
+        public static final int BAND_50 = android.hardware.radio.V1_5.NgranBands.BAND_50;
+        public static final int BAND_51 = android.hardware.radio.V1_5.NgranBands.BAND_51;
+        public static final int BAND_65 = android.hardware.radio.V1_5.NgranBands.BAND_65;
+        public static final int BAND_66 = android.hardware.radio.V1_5.NgranBands.BAND_66;
+        public static final int BAND_70 = android.hardware.radio.V1_5.NgranBands.BAND_70;
+        public static final int BAND_71 = android.hardware.radio.V1_5.NgranBands.BAND_71;
+        public static final int BAND_74 = android.hardware.radio.V1_5.NgranBands.BAND_74;
+        public static final int BAND_75 = android.hardware.radio.V1_5.NgranBands.BAND_75;
+        public static final int BAND_76 = android.hardware.radio.V1_5.NgranBands.BAND_76;
+        public static final int BAND_77 = android.hardware.radio.V1_5.NgranBands.BAND_77;
+        public static final int BAND_78 = android.hardware.radio.V1_5.NgranBands.BAND_78;
+        public static final int BAND_79 = android.hardware.radio.V1_5.NgranBands.BAND_79;
+        public static final int BAND_80 = android.hardware.radio.V1_5.NgranBands.BAND_80;
+        public static final int BAND_81 = android.hardware.radio.V1_5.NgranBands.BAND_81;
+        public static final int BAND_82 = android.hardware.radio.V1_5.NgranBands.BAND_82;
+        public static final int BAND_83 = android.hardware.radio.V1_5.NgranBands.BAND_83;
+        public static final int BAND_84 = android.hardware.radio.V1_5.NgranBands.BAND_84;
+        public static final int BAND_86 = android.hardware.radio.V1_5.NgranBands.BAND_86;
+        public static final int BAND_90 = android.hardware.radio.V1_5.NgranBands.BAND_90;
 
         /** FR2 bands */
-        public static final int BAND_257 = 257;
-        public static final int BAND_258 = 258;
-        public static final int BAND_260 = 260;
-        public static final int BAND_261 = 261;
+        public static final int BAND_257 = android.hardware.radio.V1_5.NgranBands.BAND_257;
+        public static final int BAND_258 = android.hardware.radio.V1_5.NgranBands.BAND_258;
+        public static final int BAND_260 = android.hardware.radio.V1_5.NgranBands.BAND_260;
+        public static final int BAND_261 = android.hardware.radio.V1_5.NgranBands.BAND_261;
 
         /**
          * NR Bands
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 0325c36..ccda88f 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -571,6 +571,19 @@
     public @interface PreciseDisconnectCauses {
     }
 
+    /**
+     * Carrier Privilege Status.
+     */
+    @IntDef(prefix = { "CARRIER_PRIVILEGE_STATUS_" }, value = {
+        TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS,
+        TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS,
+        TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED,
+        TelephonyManager.CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CarrierPrivilegeStatus {
+    }
+
     @IntDef({
             Connection.AUDIO_CODEC_NONE,
             Connection.AUDIO_CODEC_AMR,
@@ -598,48 +611,6 @@
     }
 
     /**
-     * Call forwarding function status
-     */
-    @IntDef(prefix = { "STATUS_" }, value = {
-        CallForwardingInfo.STATUS_ACTIVE,
-        CallForwardingInfo.STATUS_INACTIVE,
-        CallForwardingInfo.STATUS_UNKNOWN_ERROR,
-        CallForwardingInfo.STATUS_NOT_SUPPORTED,
-        CallForwardingInfo.STATUS_FDN_CHECK_FAILURE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CallForwardingStatus {
-    }
-
-    /**
-     * Call forwarding reason types
-     */
-    @IntDef(flag = true, prefix = { "REASON_" }, value = {
-        CallForwardingInfo.REASON_UNCONDITIONAL,
-        CallForwardingInfo.REASON_BUSY,
-        CallForwardingInfo.REASON_NO_REPLY,
-        CallForwardingInfo.REASON_NOT_REACHABLE,
-        CallForwardingInfo.REASON_ALL,
-        CallForwardingInfo.REASON_ALL_CONDITIONAL
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CallForwardingReason {
-    }
-
-    /**
-     * Call waiting function status
-     */
-    @IntDef(prefix = { "CALL_WAITING_STATUS_" }, value = {
-        TelephonyManager.CALL_WAITING_STATUS_ACTIVE,
-        TelephonyManager.CALL_WAITING_STATUS_INACTIVE,
-        TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED,
-        TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CallWaitingStatus {
-    }
-
-    /**
      * UICC SIM Application Types
      */
     @IntDef(prefix = { "APPTYPE_" }, value = {
diff --git a/telephony/java/android/telephony/BarringInfo.aidl b/telephony/java/android/telephony/BarringInfo.aidl
new file mode 100644
index 0000000..50ddf6b
--- /dev/null
+++ b/telephony/java/android/telephony/BarringInfo.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** @hide */
+package android.telephony;
+
+parcelable BarringInfo;
diff --git a/telephony/java/android/telephony/BarringInfo.java b/telephony/java/android/telephony/BarringInfo.java
new file mode 100644
index 0000000..92423a2
--- /dev/null
+++ b/telephony/java/android/telephony/BarringInfo.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.SparseArray;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Provides the barring configuration for a particular service type.
+ *
+ * Provides indication about the barring of a particular service for use. Certain barring types
+ * are only valid for certain technology families. Any service that does not have a barring
+ * configuration is unbarred by default.
+ */
+public final class BarringInfo implements Parcelable {
+
+    /**
+     * Barring Service Type
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "BARRING_SERVICE_TYPE_", value = {
+            BARRING_SERVICE_TYPE_CS_SERVICE,
+            BARRING_SERVICE_TYPE_PS_SERVICE,
+            BARRING_SERVICE_TYPE_CS_VOICE,
+            BARRING_SERVICE_TYPE_MO_SIGNALLING,
+            BARRING_SERVICE_TYPE_MO_DATA,
+            BARRING_SERVICE_TYPE_CS_FALLBACK,
+            BARRING_SERVICE_TYPE_MMTEL_VOICE,
+            BARRING_SERVICE_TYPE_MMTEL_VIDEO,
+            BARRING_SERVICE_TYPE_EMERGENCY,
+            BARRING_SERVICE_TYPE_SMS})
+    public @interface BarringServiceType {}
+
+    /* Applicabe to UTRAN */
+    /** Barring indicator for circuit-switched service; applicable to UTRAN */
+    public static final int BARRING_SERVICE_TYPE_CS_SERVICE =
+            android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_SERVICE;
+    /** Barring indicator for packet-switched service; applicable to UTRAN */
+    public static final int BARRING_SERVICE_TYPE_PS_SERVICE =
+            android.hardware.radio.V1_5.BarringInfo.ServiceType.PS_SERVICE;
+    /** Barring indicator for circuit-switched voice service; applicable to UTRAN */
+    public static final int BARRING_SERVICE_TYPE_CS_VOICE =
+            android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_VOICE;
+
+    /* Applicable to EUTRAN, NGRAN */
+    /** Barring indicator for mobile-originated signalling; applicable to EUTRAN and NGRAN */
+    public static final int BARRING_SERVICE_TYPE_MO_SIGNALLING =
+            android.hardware.radio.V1_5.BarringInfo.ServiceType.MO_SIGNALLING;
+    /** Barring indicator for mobile-originated data traffic; applicable to EUTRAN and NGRAN */
+    public static final int BARRING_SERVICE_TYPE_MO_DATA =
+            android.hardware.radio.V1_5.BarringInfo.ServiceType.MO_DATA;
+    /** Barring indicator for circuit-switched fallback for voice; applicable to EUTRAN and NGRAN */
+    public static final int BARRING_SERVICE_TYPE_CS_FALLBACK =
+            android.hardware.radio.V1_5.BarringInfo.ServiceType.CS_FALLBACK;
+    /** Barring indicator for MMTEL (IMS) voice; applicable to EUTRAN and NGRAN */
+    public static final int BARRING_SERVICE_TYPE_MMTEL_VOICE =
+            android.hardware.radio.V1_5.BarringInfo.ServiceType.MMTEL_VOICE;
+    /** Barring indicator for MMTEL (IMS) video; applicable to EUTRAN and NGRAN */
+    public static final int BARRING_SERVICE_TYPE_MMTEL_VIDEO =
+            android.hardware.radio.V1_5.BarringInfo.ServiceType.MMTEL_VIDEO;
+
+    /* Applicable to UTRAN, EUTRAN, NGRAN */
+    /** Barring indicator for emergency services; applicable to UTRAN, EUTRAN, and NGRAN */
+    public static final int BARRING_SERVICE_TYPE_EMERGENCY =
+            android.hardware.radio.V1_5.BarringInfo.ServiceType.EMERGENCY;
+    /** Barring indicator for SMS sending; applicable to UTRAN, EUTRAN, and NGRAN */
+    public static final int BARRING_SERVICE_TYPE_SMS =
+            android.hardware.radio.V1_5.BarringInfo.ServiceType.SMS;
+
+    //TODO: add barring constants for Operator-Specific barring codes
+
+    /** Describe the current barring configuration of a cell */
+    public static final class BarringServiceInfo implements Parcelable {
+        /**
+         * Barring Type
+         * @hide
+         */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(prefix = "BARRING_TYPE_", value =
+                    {BARRING_TYPE_NONE,
+                    BARRING_TYPE_UNCONDITIONAL,
+                    BARRING_TYPE_CONDITIONAL,
+                    BARRING_TYPE_UNKNOWN})
+        public @interface BarringType {}
+
+        /** Barring is inactive */
+        public static final int BARRING_TYPE_NONE =
+                android.hardware.radio.V1_5.BarringInfo.BarringType.NONE;
+        /** The service is barred */
+        public static final int BARRING_TYPE_UNCONDITIONAL =
+                android.hardware.radio.V1_5.BarringInfo.BarringType.UNCONDITIONAL;
+        /** The service may be barred based on additional factors */
+        public static final int BARRING_TYPE_CONDITIONAL =
+                android.hardware.radio.V1_5.BarringInfo.BarringType.CONDITIONAL;
+
+        /** If a modem does not report barring info, then the barring type will be UNKNOWN */
+        public static final int BARRING_TYPE_UNKNOWN = -1;
+
+        private final @BarringType int mBarringType;
+
+        private final boolean mIsConditionallyBarred;
+        private final int mConditionalBarringFactor;
+        private final int mConditionalBarringTimeSeconds;
+
+        /** @hide */
+        public BarringServiceInfo(@BarringType int type) {
+            this(type, false, 0, 0);
+        }
+
+        /** @hide */
+        @TestApi
+        public BarringServiceInfo(@BarringType int barringType, boolean isConditionallyBarred,
+                int conditionalBarringFactor, int conditionalBarringTimeSeconds) {
+            mBarringType = barringType;
+            mIsConditionallyBarred = isConditionallyBarred;
+            mConditionalBarringFactor = conditionalBarringFactor;
+            mConditionalBarringTimeSeconds = conditionalBarringTimeSeconds;
+        }
+
+        public @BarringType int getBarringType() {
+            return mBarringType;
+        }
+
+        /**
+         * @return true if the conditional barring parameters have resulted in the service being
+         *         barred; false if the service has either not been evaluated for conditional
+         *         barring or has been evaluated and isn't barred.
+         */
+        public boolean isConditionallyBarred() {
+            return mIsConditionallyBarred;
+        }
+
+        /**
+         * @return the conditional barring factor as a percentage 0-100, which is the probability of
+         *         a random device being barred for the service type.
+         */
+        public int getConditionalBarringFactor() {
+            return mConditionalBarringFactor;
+        }
+
+        /**
+         * @return the conditional barring time seconds, which is the interval between successive
+         *         evaluations for conditional barring based on the barring factor.
+         */
+        @SuppressLint("MethodNameUnits")
+        public int getConditionalBarringTimeSeconds() {
+            return mConditionalBarringTimeSeconds;
+        }
+
+        /**
+         * Return whether a service is currently barred based on the BarringInfo
+         *
+         * @return true if the service is currently being barred, otherwise false
+         */
+        public boolean isBarred() {
+            return mBarringType == BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL
+                    || (mBarringType == BarringServiceInfo.BARRING_TYPE_CONDITIONAL
+                            && mIsConditionallyBarred);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mBarringType, mIsConditionallyBarred,
+                    mConditionalBarringFactor, mConditionalBarringTimeSeconds);
+        }
+
+        @Override
+        public boolean equals(Object rhs) {
+            if (!(rhs instanceof BarringServiceInfo)) return false;
+
+            BarringServiceInfo other = (BarringServiceInfo) rhs;
+            return mBarringType == other.mBarringType
+                    && mIsConditionallyBarred == other.mIsConditionallyBarred
+                    && mConditionalBarringFactor == other.mConditionalBarringFactor
+                    && mConditionalBarringTimeSeconds == other.mConditionalBarringTimeSeconds;
+        }
+
+        /** @hide */
+        public BarringServiceInfo(Parcel p) {
+            mBarringType = p.readInt();
+            mIsConditionallyBarred = p.readBoolean();
+            mConditionalBarringFactor = p.readInt();
+            mConditionalBarringTimeSeconds = p.readInt();
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            dest.writeInt(mBarringType);
+            dest.writeBoolean(mIsConditionallyBarred);
+            dest.writeInt(mConditionalBarringFactor);
+            dest.writeInt(mConditionalBarringTimeSeconds);
+        }
+
+        /* @inheritDoc */
+        public static final @NonNull Parcelable.Creator<BarringServiceInfo> CREATOR =
+                new Parcelable.Creator<BarringServiceInfo>() {
+                    @Override
+                    public BarringServiceInfo createFromParcel(Parcel source) {
+                        return new BarringServiceInfo(source);
+                    }
+
+                    @Override
+                    public BarringServiceInfo[] newArray(int size) {
+                        return new BarringServiceInfo[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+    }
+
+    private static final BarringServiceInfo BARRING_SERVICE_INFO_UNKNOWN =
+            new BarringServiceInfo(BarringServiceInfo.BARRING_TYPE_UNKNOWN);
+
+    private static final BarringServiceInfo BARRING_SERVICE_INFO_UNBARRED =
+            new BarringServiceInfo(BarringServiceInfo.BARRING_TYPE_NONE);
+
+    private CellIdentity mCellIdentity;
+
+    // A SparseArray potentially mapping each BarringService type to a BarringServiceInfo config
+    // that describes the current barring status of that particular service.
+    private SparseArray<BarringServiceInfo> mBarringServiceInfos;
+
+    /** @hide */
+    @TestApi
+    @SystemApi
+    public BarringInfo() {
+        mBarringServiceInfos = new SparseArray<>();
+    }
+
+    /**
+     * Constructor for new BarringInfo instances.
+     *
+     * @hide
+     */
+    @TestApi
+    public BarringInfo(@Nullable CellIdentity barringCellId,
+            @NonNull SparseArray<BarringServiceInfo> barringServiceInfos) {
+        mCellIdentity = barringCellId;
+        mBarringServiceInfos = barringServiceInfos;
+    }
+
+    /** @hide */
+    public static BarringInfo create(
+            @NonNull android.hardware.radio.V1_5.CellIdentity halBarringCellId,
+            @NonNull List<android.hardware.radio.V1_5.BarringInfo> halBarringInfos) {
+        CellIdentity ci = CellIdentity.create(halBarringCellId);
+        SparseArray<BarringServiceInfo> serviceInfos = new SparseArray<>();
+
+        for (android.hardware.radio.V1_5.BarringInfo halBarringInfo : halBarringInfos) {
+            if (halBarringInfo.barringType
+                    == android.hardware.radio.V1_5.BarringInfo.BarringType.CONDITIONAL) {
+                if (halBarringInfo.barringTypeSpecificInfo.getDiscriminator()
+                        != android.hardware.radio.V1_5.BarringInfo.BarringTypeSpecificInfo
+                                .hidl_discriminator.conditional) {
+                    // this is an error case where the barring info is conditional but the
+                    // conditional barring fields weren't included
+                    continue;
+                }
+                android.hardware.radio.V1_5.BarringInfo.BarringTypeSpecificInfo
+                        .Conditional conditionalInfo =
+                        halBarringInfo.barringTypeSpecificInfo.conditional();
+                serviceInfos.put(
+                        halBarringInfo.serviceType, new BarringServiceInfo(
+                                halBarringInfo.barringType, // will always be CONDITIONAL here
+                                conditionalInfo.isBarred,
+                                conditionalInfo.factor,
+                                conditionalInfo.timeSeconds));
+            } else {
+                // Barring type is either NONE or UNCONDITIONAL
+                serviceInfos.put(
+                        halBarringInfo.serviceType, new BarringServiceInfo(
+                                halBarringInfo.barringType, false, 0, 0));
+            }
+        }
+        return new BarringInfo(ci, serviceInfos);
+    }
+
+    /**
+     * Get the BarringServiceInfo for a specified service.
+     *
+     * @return a BarringServiceInfo struct describing the current barring status for a service
+     */
+    public @NonNull BarringServiceInfo getBarringServiceInfo(@BarringServiceType int service) {
+        BarringServiceInfo bsi = mBarringServiceInfos.get(service);
+        // If barring is reported but not for a particular service, then we report the barring
+        // type as UNKNOWN; if the modem reports barring info but doesn't report for a particular
+        // service then we can safely assume that the service isn't barred (for instance because
+        // that particular service isn't applicable to the current RAN).
+        return (bsi != null) ? bsi : mBarringServiceInfos.size() > 0
+                ? BARRING_SERVICE_INFO_UNBARRED : BARRING_SERVICE_INFO_UNKNOWN;
+    }
+
+    /** @hide */
+    @SystemApi
+    public @NonNull BarringInfo createLocationInfoSanitizedCopy() {
+        // The only thing that would need sanitizing is the CellIdentity
+        if (mCellIdentity == null) return this;
+
+        return new BarringInfo(mCellIdentity.sanitizeLocationInfo(), mBarringServiceInfos);
+    }
+
+    /** @hide */
+    public BarringInfo(Parcel p) {
+        mCellIdentity = p.readParcelable(CellIdentity.class.getClassLoader());
+        mBarringServiceInfos = p.readSparseArray(BarringServiceInfo.class.getClassLoader());
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeParcelable(mCellIdentity, flags);
+        dest.writeSparseArray(mBarringServiceInfos);
+    }
+
+    public static final @NonNull Parcelable.Creator<BarringInfo> CREATOR =
+            new Parcelable.Creator<BarringInfo>() {
+                @Override
+                public BarringInfo createFromParcel(Parcel source) {
+                    return new BarringInfo(source);
+                }
+
+                @Override
+                public BarringInfo[] newArray(int size) {
+                    return new BarringInfo[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = mCellIdentity != null ? mCellIdentity.hashCode() : 7;
+        for (int i = 0; i < mBarringServiceInfos.size(); i++) {
+            hash = hash + 15 * mBarringServiceInfos.keyAt(i);
+            hash = hash + 31 * mBarringServiceInfos.valueAt(i).hashCode();
+        }
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object rhs) {
+        if (!(rhs instanceof BarringInfo)) return false;
+
+        BarringInfo bi = (BarringInfo) rhs;
+
+        if (hashCode() != bi.hashCode()) return false;
+
+        if (mBarringServiceInfos.size() != bi.mBarringServiceInfos.size()) return false;
+
+        for (int i = 0; i < mBarringServiceInfos.size(); i++) {
+            if (mBarringServiceInfos.keyAt(i) != bi.mBarringServiceInfos.keyAt(i)) return false;
+            if (!Objects.equals(mBarringServiceInfos.valueAt(i),
+                        bi.mBarringServiceInfos.valueAt(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "BarringInfo {mCellIdentity=" + mCellIdentity
+               + ", mBarringServiceInfos=" + mBarringServiceInfos + "}";
+    }
+}
diff --git a/telephony/java/android/telephony/CallForwardingInfo.java b/telephony/java/android/telephony/CallForwardingInfo.java
index 1dd7539..7e777fa 100644
--- a/telephony/java/android/telephony/CallForwardingInfo.java
+++ b/telephony/java/android/telephony/CallForwardingInfo.java
@@ -15,24 +15,24 @@
  */
 
 package android.telephony;
+
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.telephony.Annotation.CallForwardingReason;
-import android.telephony.Annotation.CallForwardingStatus;
 
 import com.android.telephony.Rlog;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
 
 /**
  * Defines the call forwarding information.
  * @hide
  */
-@SystemApi
 public final class CallForwardingInfo implements Parcelable {
     private static final String TAG = "CallForwardingInfo";
 
@@ -41,7 +41,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int STATUS_INACTIVE = 0;
 
     /**
@@ -49,7 +48,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int STATUS_ACTIVE = 1;
 
     /**
@@ -58,7 +56,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int STATUS_FDN_CHECK_FAILURE = 2;
 
     /**
@@ -66,7 +63,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int STATUS_UNKNOWN_ERROR = 3;
 
     /**
@@ -74,7 +70,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int STATUS_NOT_SUPPORTED = 4;
 
     /**
@@ -83,7 +78,6 @@
      *            and conditions +CCFC
      * @hide
      */
-    @SystemApi
     public static final int REASON_UNCONDITIONAL = 0;
 
     /**
@@ -92,7 +86,6 @@
      *            and conditions +CCFC
      * @hide
      */
-    @SystemApi
     public static final int REASON_BUSY = 1;
 
     /**
@@ -101,7 +94,6 @@
      *            and conditions +CCFC
      * @hide
      */
-    @SystemApi
     public static final int REASON_NO_REPLY = 2;
 
     /**
@@ -110,7 +102,6 @@
      *            and conditions +CCFC
      * @hide
      */
-    @SystemApi
     public static final int REASON_NOT_REACHABLE = 3;
 
     /**
@@ -120,7 +111,6 @@
      *            and conditions +CCFC
      * @hide
      */
-    @SystemApi
     public static final int REASON_ALL = 4;
 
     /**
@@ -130,20 +120,48 @@
      *            and conditions +CCFC
      * @hide
      */
-    @SystemApi
     public static final int REASON_ALL_CONDITIONAL = 5;
 
     /**
+     * Call forwarding function status
+     */
+    @IntDef(prefix = { "STATUS_" }, value = {
+        STATUS_ACTIVE,
+        STATUS_INACTIVE,
+        STATUS_UNKNOWN_ERROR,
+        STATUS_NOT_SUPPORTED,
+        STATUS_FDN_CHECK_FAILURE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CallForwardingStatus {
+    }
+
+    /**
+     * Call forwarding reason types
+     */
+    @IntDef(flag = true, prefix = { "REASON_" }, value = {
+        REASON_UNCONDITIONAL,
+        REASON_BUSY,
+        REASON_NO_REPLY,
+        REASON_NOT_REACHABLE,
+        REASON_ALL,
+        REASON_ALL_CONDITIONAL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CallForwardingReason {
+    }
+
+    /**
      * The call forwarding status.
      */
-    private @CallForwardingStatus int mStatus;
+    private int mStatus;
 
     /**
      * The call forwarding reason indicates the condition under which calls will be forwarded.
      * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number
      *            and conditions +CCFC
      */
-    private @CallForwardingReason int mReason;
+    private int mReason;
 
     /**
      * The phone number to which calls will be forwarded.
@@ -166,7 +184,6 @@
      * @param timeSeconds the timeout (in seconds) before the forwarding is attempted
      * @hide
      */
-    @SystemApi
     public CallForwardingInfo(@CallForwardingStatus int status, @CallForwardingReason int reason,
             @Nullable String number, int timeSeconds) {
         mStatus = status;
@@ -182,7 +199,6 @@
      *
      * @hide
      */
-    @SystemApi
     public @CallForwardingStatus int getStatus() {
         return mStatus;
     }
@@ -196,7 +212,6 @@
      *
      * @hide
      */
-    @SystemApi
     public @CallForwardingReason int getReason() {
         return mReason;
     }
@@ -209,7 +224,6 @@
      *
      * @hide
      */
-    @SystemApi
     @Nullable
     public String getNumber() {
         return mNumber;
@@ -227,7 +241,6 @@
      *
      * @hide
      */
-    @SystemApi
     @SuppressLint("MethodNameUnits")
     public int getTimeoutSeconds() {
         return mTimeSeconds;
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 57a47d3..8cbeba1 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -37,6 +37,8 @@
 import com.android.internal.telephony.ICarrierConfigLoader;
 import com.android.telephony.Rlog;
 
+import java.util.concurrent.TimeUnit;
+
 /**
  * Provides access to telephony configuration values that are carrier-specific.
  */
@@ -1551,6 +1553,7 @@
     /**
      * The string is used to compare with operator name.
      * If it matches the pattern then show specific data icon.
+     * @hide
      */
     public static final String KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING =
             "show_carrier_data_icon_pattern_string";
@@ -2362,17 +2365,16 @@
      * <p> If a measure is not set, signal criteria reporting from modem will not be triggered and
      * not be used for calculating signal level. If multiple measures are set bit, the parameter
      * whose value is smallest is used to indicate the signal level.
+     * <UL>
+     *  <LI>RSRP = 1 << 0</LI>
+     *  <LI>RSRQ = 1 << 1</LI>
+     *  <LI>RSSNR = 1 << 2</LI>
+     * </UL>
+     * <p> The value of this key must be bitwise OR of {@link CellSignalStrengthLte#USE_RSRP},
+     * {@link CellSignalStrengthLte#USE_RSRQ}, {@link CellSignalStrengthLte#USE_RSSNR}.
      *
-     *  RSRP = 1 << 0,
-     *  RSRQ = 1 << 1,
-     *  RSSNR = 1 << 2,
-     *
-     *  The value of this key must be bitwise OR of {@link CellSignalStrengthLte#USE_RSRP},
-     *  {@link CellSignalStrengthLte#USE_RSRQ}, {@link CellSignalStrengthLte#USE_RSSNR}.
-     *
-     * For example, if both RSRP and RSRQ are used, the value of key is 3 (1 << 0 | 1 << 1).
-     * If the key is invalid or not configured, a default value (RSRP = 1 << 0)
-     * will apply.
+     * <p> For example, if both RSRP and RSRQ are used, the value of key is 3 (1 << 0 | 1 << 1).
+     * If the key is invalid or not configured, a default value (RSRP = 1 << 0) will apply.
      *
      * @hide
      */
@@ -2381,16 +2383,18 @@
 
     /**
      * List of 4 customized 5G SS reference signal received power (SSRSRP) thresholds.
-     *
+     * <p>
      * Reference: 3GPP TS 38.215
-     *
+     * <p>
      * 4 threshold integers must be within the boundaries [-140 dB, -44 dB], and the levels are:
-     *     "NONE: [-140, threshold1]"
-     *     "POOR: (threshold1, threshold2]"
-     *     "MODERATE: (threshold2, threshold3]"
-     *     "GOOD:  (threshold3, threshold4]"
-     *     "EXCELLENT:  (threshold4, -44]"
-     *
+     * <UL>
+     *     <LI>"NONE: [-140, threshold1]"</LI>
+     *     <LI>"POOR: (threshold1, threshold2]"</LI>
+     *     <LI>"MODERATE: (threshold2, threshold3]"</LI>
+     *     <LI>"GOOD:  (threshold3, threshold4]"</LI>
+     *     <LI>"EXCELLENT:  (threshold4, -44]"</LI>
+     * </UL>
+     * <p>
      * This key is considered invalid if the format is violated. If the key is invalid or
      * not configured, a default value set will apply.
      */
@@ -2399,16 +2403,18 @@
 
     /**
      * List of 4 customized 5G SS reference signal received quality (SSRSRQ) thresholds.
-     *
+     * <p>
      * Reference: 3GPP TS 38.215
-     *
+     * <p>
      * 4 threshold integers must be within the boundaries [-20 dB, -3 dB], and the levels are:
-     *     "NONE: [-20, threshold1]"
-     *     "POOR: (threshold1, threshold2]"
-     *     "MODERATE: (threshold2, threshold3]"
-     *     "GOOD:  (threshold3, threshold4]"
-     *     "EXCELLENT:  (threshold4, -3]"
-     *
+     * <UL>
+     *     <LI>"NONE: [-20, threshold1]"</LI>
+     *     <LI>"POOR: (threshold1, threshold2]"</LI>
+     *     <LI>"MODERATE: (threshold2, threshold3]"</LI>
+     *     <LI>"GOOD:  (threshold3, threshold4]"</LI>
+     *     <LI>"EXCELLENT:  (threshold4, -3]"</LI>
+     * </UL>
+     * <p>
      * This key is considered invalid if the format is violated. If the key is invalid or
      * not configured, a default value set will apply.
      */
@@ -2417,17 +2423,19 @@
 
     /**
      * List of 4 customized 5G SS signal-to-noise and interference ratio (SSSINR) thresholds.
-     *
+     * <p>
      * Reference: 3GPP TS 38.215,
      *            3GPP TS 38.133 10.1.16.1
-     *
+     * <p>
      * 4 threshold integers must be within the boundaries [-23 dB, 40 dB], and the levels are:
-     *     "NONE: [-23, threshold1]"
-     *     "POOR: (threshold1, threshold2]"
-     *     "MODERATE: (threshold2, threshold3]"
-     *     "GOOD:  (threshold3, threshold4]"
-     *     "EXCELLENT:  (threshold4, 40]"
-     *
+     * <UL>
+     *     <LI>"NONE: [-23, threshold1]"</LI>
+     *     <LI>"POOR: (threshold1, threshold2]"</LI>
+     *     <LI>"MODERATE: (threshold2, threshold3]"</LI>
+     *     <LI>"GOOD:  (threshold3, threshold4]"</LI>
+     *     <LI>"EXCELLENT:  (threshold4, 40]"</LI>
+     * </UL>
+     * <p>
      * This key is considered invalid if the format is violated. If the key is invalid or
      * not configured, a default value set will apply.
      */
@@ -2442,19 +2450,19 @@
      * <p> If a measure is not set, signal criteria reporting from modem will not be triggered and
      * not be used for calculating signal level. If multiple measures are set bit, the parameter
      * whose value is smallest is used to indicate the signal level.
-     *
-     *  SSRSRP = 1 << 0,
-     *  SSRSRQ = 1 << 1,
-     *  SSSINR = 1 << 2,
-     *
+     * <UL>
+     *  <LI>SSRSRP = 1 << 0</LI>
+     *  <LI>SSRSRQ = 1 << 1</LI>
+     *  <LI>SSSINR = 1 << 2</LI>
+     * </UL>
      *  The value of this key must be bitwise OR of {@link CellSignalStrengthNr#USE_SSRSRP},
      *  {@link CellSignalStrengthNr#USE_SSRSRQ}, {@link CellSignalStrengthNr#USE_SSSINR}.
      *
-     * For example, if both SSRSRP and SSSINR are used, the value of key is 5 (1 << 0 | 1 << 2).
+     * <p> For example, if both SSRSRP and SSSINR are used, the value of key is 5 (1 << 0 | 1 << 2).
      * If the key is invalid or not configured, a default value (SSRSRP = 1 << 0) will apply.
      *
-     *  Reference: 3GPP TS 38.215,
-     *             3GPP TS 38.133 10.1.16.1
+     * <p> Reference: 3GPP TS 38.215,
+     *                3GPP TS 38.133 10.1.16.1
      *
      * @hide
      */
@@ -2960,9 +2968,9 @@
      * UE wants to display 5G_Plus icon for scenario#1, and 5G icon for scenario#2; otherwise not
      * define.
      * The configuration is: "connected_mmwave:5G_Plus,connected:5G"
+     * @hide
      */
-    public static final String KEY_5G_ICON_CONFIGURATION_STRING =
-            "5g_icon_configuration_string";
+    public static final String KEY_5G_ICON_CONFIGURATION_STRING = "5g_icon_configuration_string";
 
     /**
      * Timeout in seconds for displaying 5G icon, default value is 0 which means the timer is
@@ -2974,12 +2982,14 @@
      *
      * If 5G is reacquired during this timer, the timer is canceled and restarted when 5G is next
      * lost. Allows us to momentarily lose 5G without blinking the icon.
+     * @hide
      */
     public static final String KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT =
             "5g_icon_display_grace_period_sec_int";
 
     /**
      * Controls time in milliseconds until DcTracker reevaluates 5G connection state.
+     * @hide
      */
     public static final String KEY_5G_WATCHDOG_TIME_MS_LONG = "5g_watchdog_time_long";
 
@@ -3716,7 +3726,7 @@
         sDefaults.putInt(KEY_IMS_DTMF_TONE_DELAY_INT, 0);
         sDefaults.putInt(KEY_CDMA_DTMF_TONE_DELAY_INT, 100);
         sDefaults.putBoolean(KEY_CALL_FORWARDING_MAP_NON_NUMBER_TO_VOICEMAIL_BOOL, false);
-        sDefaults.putBoolean(KEY_IGNORE_RTT_MODE_SETTING_BOOL, false);
+        sDefaults.putBoolean(KEY_IGNORE_RTT_MODE_SETTING_BOOL, true);
         sDefaults.putInt(KEY_CDMA_3WAYCALL_FLASH_DELAY_INT , 0);
         sDefaults.putBoolean(KEY_SUPPORT_ADHOC_CONFERENCE_CALLS_BOOL, false);
         sDefaults.putBoolean(KEY_SUPPORT_ADD_CONFERENCE_PARTICIPANTS_BOOL, false);
@@ -3990,7 +4000,8 @@
         sDefaults.putBoolean(KEY_USE_CALLER_ID_USSD_BOOL, false);
         sDefaults.putInt(KEY_CALL_WAITING_SERVICE_CLASS_INT, 1 /* SERVICE_CLASS_VOICE */);
         sDefaults.putString(KEY_5G_ICON_CONFIGURATION_STRING,
-                "connected_mmwave:5G,connected:5G");
+                "connected_mmwave:5G,connected:5G,not_restricted_rrc_idle:5G,"
+                        + "not_restricted_rrc_con:5G");
         sDefaults.putInt(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 0);
         /* Default value is 1 hour. */
         sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000);
@@ -4054,7 +4065,7 @@
         sDefaults.putLong(KEY_DATA_SWITCH_VALIDATION_TIMEOUT_LONG, 2000);
         sDefaults.putInt(KEY_PARAMETERS_USED_FOR_LTE_SIGNAL_BAR_INT,
                 CellSignalStrengthLte.USE_RSRP);
-        sDefaults.putLong(KEY_DATA_SWITCH_VALIDATION_MIN_GAP_LONG, 0);
+        sDefaults.putLong(KEY_DATA_SWITCH_VALIDATION_MIN_GAP_LONG, TimeUnit.DAYS.toMillis(1));
         sDefaults.putStringArray(KEY_MISSED_INCOMING_CALL_SMS_ORIGINATOR_STRING_ARRAY,
                 new String[0]);
         sDefaults.putStringArray(KEY_MISSED_INCOMING_CALL_SMS_PATTERN_STRING_ARRAY, new String[0]);
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index 9f2537c..203047f 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -22,11 +22,12 @@
 import android.os.Parcel;
 import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
+import android.util.ArraySet;
 
-import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * CellIdentity to represent a unique GSM cell
@@ -50,7 +51,7 @@
     private final int mBsic;
 
     // a list of additional PLMN-IDs reported for this cell
-    private final List<String> mAdditionalPlmns;
+    private final ArraySet<String> mAdditionalPlmns;
 
     /**
      * @hide
@@ -62,7 +63,7 @@
         mCid = CellInfo.UNAVAILABLE;
         mArfcn = CellInfo.UNAVAILABLE;
         mBsic = CellInfo.UNAVAILABLE;
-        mAdditionalPlmns = Collections.emptyList();
+        mAdditionalPlmns = new ArraySet<>();
     }
 
     /**
@@ -81,13 +82,13 @@
      */
     public CellIdentityGsm(int lac, int cid, int arfcn, int bsic, @Nullable String mccStr,
             @Nullable String mncStr, @Nullable String alphal, @Nullable String alphas,
-            @NonNull List<String> additionalPlmns) {
+            @NonNull Collection<String> additionalPlmns) {
         super(TAG, CellInfo.TYPE_GSM, mccStr, mncStr, alphal, alphas);
         mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
         mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
         mArfcn = inRangeOrUnavailable(arfcn, 0, MAX_ARFCN);
         mBsic = inRangeOrUnavailable(bsic, 0, MAX_BSIC);
-        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        mAdditionalPlmns = new ArraySet<>(additionalPlmns.size());
         for (String plmn : additionalPlmns) {
             if (isValidPlmn(plmn)) {
                 mAdditionalPlmns.add(plmn);
@@ -99,7 +100,7 @@
     public CellIdentityGsm(@NonNull android.hardware.radio.V1_0.CellIdentityGsm cid) {
         this(cid.lac, cid.cid, cid.arfcn,
                 cid.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.bsic,
-                cid.mcc, cid.mnc, "", "", Collections.emptyList());
+                cid.mcc, cid.mnc, "", "", new ArraySet<>());
     }
 
     /** @hide */
@@ -107,7 +108,7 @@
         this(cid.base.lac, cid.base.cid, cid.base.arfcn,
                 cid.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.base.bsic, cid.base.mcc,
                 cid.base.mnc, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
-                Collections.emptyList());
+                new ArraySet<>());
     }
 
     /** @hide */
@@ -221,8 +222,8 @@
      * @return a list of additional PLMN IDs supported by this cell.
      */
     @NonNull
-    public List<String> getAdditionalPlmns() {
-        return mAdditionalPlmns;
+    public Set<String> getAdditionalPlmns() {
+        return Collections.unmodifiableSet(mAdditionalPlmns);
     }
 
     /**
@@ -296,7 +297,7 @@
         dest.writeInt(mCid);
         dest.writeInt(mArfcn);
         dest.writeInt(mBsic);
-        dest.writeList(mAdditionalPlmns);
+        dest.writeArraySet(mAdditionalPlmns);
     }
 
     /** Construct from Parcel, type has already been processed */
@@ -306,7 +307,7 @@
         mCid = in.readInt();
         mArfcn = in.readInt();
         mBsic = in.readInt();
-        mAdditionalPlmns = in.readArrayList(null);
+        mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
 
         if (DBG) log(toString());
     }
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index a194ae3..b4ce162 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -23,11 +23,13 @@
 import android.os.Parcel;
 import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
+import android.util.ArraySet;
 
-import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * CellIdentity is to represent a unique LTE cell
@@ -52,9 +54,11 @@
     private final int mEarfcn;
     // cell bandwidth, in kHz
     private final int mBandwidth;
+    // cell bands
+    private final int[] mBands;
 
     // a list of additional PLMN-IDs reported for this cell
-    private final List<String> mAdditionalPlmns;
+    private final ArraySet<String> mAdditionalPlmns;
 
     private ClosedSubscriberGroupInfo mCsgInfo;
 
@@ -68,8 +72,9 @@
         mPci = CellInfo.UNAVAILABLE;
         mTac = CellInfo.UNAVAILABLE;
         mEarfcn = CellInfo.UNAVAILABLE;
+        mBands = new int[] {};
         mBandwidth = CellInfo.UNAVAILABLE;
-        mAdditionalPlmns = Collections.emptyList();
+        mAdditionalPlmns = new ArraySet<>();
         mCsgInfo = null;
     }
 
@@ -85,8 +90,9 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public CellIdentityLte(int mcc, int mnc, int ci, int pci, int tac) {
-        this(ci, pci, tac, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, String.valueOf(mcc),
-                String.valueOf(mnc), null, null, Collections.emptyList(), null);
+        this(ci, pci, tac, CellInfo.UNAVAILABLE, new int[] {}, CellInfo.UNAVAILABLE,
+                String.valueOf(mcc), String.valueOf(mnc), null, null, new ArraySet<>(),
+                null);
     }
 
     /**
@@ -105,17 +111,19 @@
      *
      * @hide
      */
-    public CellIdentityLte(int ci, int pci, int tac, int earfcn, int bandwidth,
-            @Nullable String mccStr, @Nullable String mncStr, @Nullable String alphal,
-            @Nullable String alphas, @NonNull List<String> additionalPlmns,
+    public CellIdentityLte(int ci, int pci, int tac, int earfcn, @NonNull int[] bands,
+            int bandwidth, @Nullable String mccStr, @Nullable String mncStr,
+            @Nullable String alphal, @Nullable String alphas,
+            @NonNull Collection<String> additionalPlmns,
             @Nullable ClosedSubscriberGroupInfo csgInfo) {
         super(TAG, CellInfo.TYPE_LTE, mccStr, mncStr, alphal, alphas);
         mCi = inRangeOrUnavailable(ci, 0, MAX_CI);
         mPci = inRangeOrUnavailable(pci, 0, MAX_PCI);
         mTac = inRangeOrUnavailable(tac, 0, MAX_TAC);
         mEarfcn = inRangeOrUnavailable(earfcn, 0, MAX_EARFCN);
+        mBands = bands;
         mBandwidth = inRangeOrUnavailable(bandwidth, 0, MAX_BANDWIDTH);
-        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        mAdditionalPlmns = new ArraySet<>(additionalPlmns.size());
         for (String plmn : additionalPlmns) {
             if (isValidPlmn(plmn)) {
                 mAdditionalPlmns.add(plmn);
@@ -126,28 +134,29 @@
 
     /** @hide */
     public CellIdentityLte(@NonNull android.hardware.radio.V1_0.CellIdentityLte cid) {
-        this(cid.ci, cid.pci, cid.tac, cid.earfcn,
-                CellInfo.UNAVAILABLE, cid.mcc, cid.mnc, "", "", Collections.emptyList(), null);
+        this(cid.ci, cid.pci, cid.tac, cid.earfcn, new int[] {},
+                CellInfo.UNAVAILABLE, cid.mcc, cid.mnc, "", "", new ArraySet<>(), null);
     }
 
     /** @hide */
     public CellIdentityLte(@NonNull android.hardware.radio.V1_2.CellIdentityLte cid) {
-        this(cid.base.ci, cid.base.pci, cid.base.tac, cid.base.earfcn, cid.bandwidth,
-                cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong,
-                cid.operatorNames.alphaShort, Collections.emptyList(), null);
+        this(cid.base.ci, cid.base.pci, cid.base.tac, cid.base.earfcn, new int[] {},
+                cid.bandwidth, cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong,
+                cid.operatorNames.alphaShort, new ArraySet<>(), null);
     }
 
     /** @hide */
     public CellIdentityLte(@NonNull android.hardware.radio.V1_5.CellIdentityLte cid) {
         this(cid.base.base.ci, cid.base.base.pci, cid.base.base.tac, cid.base.base.earfcn,
-                cid.base.bandwidth, cid.base.base.mcc, cid.base.base.mnc,
-                cid.base.operatorNames.alphaLong, cid.base.operatorNames.alphaShort,
-                cid.additionalPlmns, cid.optionalCsgInfo.csgInfo() != null
+                cid.bands.stream().mapToInt(Integer::intValue).toArray(), cid.base.bandwidth,
+                cid.base.base.mcc, cid.base.base.mnc, cid.base.operatorNames.alphaLong,
+                cid.base.operatorNames.alphaShort, cid.additionalPlmns,
+                cid.optionalCsgInfo.csgInfo() != null
                         ? new ClosedSubscriberGroupInfo(cid.optionalCsgInfo.csgInfo()) : null);
     }
 
     private CellIdentityLte(@NonNull CellIdentityLte cid) {
-        this(cid.mCi, cid.mPci, cid.mTac, cid.mEarfcn, cid.mBandwidth, cid.mMccStr,
+        this(cid.mCi, cid.mPci, cid.mTac, cid.mEarfcn, cid.mBands, cid.mBandwidth, cid.mMccStr,
                 cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo);
     }
 
@@ -155,7 +164,7 @@
     @Override
     public @NonNull CellIdentityLte sanitizeLocationInfo() {
         return new CellIdentityLte(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
-                CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
+                CellInfo.UNAVAILABLE, mBands, CellInfo.UNAVAILABLE,
                 mMccStr, mMncStr, mAlphaLong, mAlphaShort, mAdditionalPlmns, null);
     }
 
@@ -220,12 +229,11 @@
      *
      * Reference: 3GPP TS 36.101 section 5.5
      *
-     * @return List of band number or empty list if not available.
+     * @return Array of band number or empty array if not available.
      */
     @NonNull
-    public List<Integer> getBands() {
-        // Todo: Add actual support
-        return Collections.emptyList();
+    public int[] getBands() {
+        return Arrays.copyOf(mBands, mBands.length);
     }
 
     /**
@@ -270,8 +278,8 @@
      * @return a list of additional PLMN IDs supported by this cell.
      */
     @NonNull
-    public List<String> getAdditionalPlmns() {
-        return mAdditionalPlmns;
+    public Set<String> getAdditionalPlmns() {
+        return Collections.unmodifiableSet(mAdditionalPlmns);
     }
 
     /**
@@ -307,8 +315,8 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mCi, mPci, mTac,
-                mAdditionalPlmns.hashCode(), mCsgInfo, super.hashCode());
+        return Objects.hash(mCi, mPci, mTac, mEarfcn, Arrays.hashCode(mBands),
+                mBandwidth, mAdditionalPlmns.hashCode(), mCsgInfo, super.hashCode());
     }
 
     @Override
@@ -326,6 +334,7 @@
                 && mPci == o.mPci
                 && mTac == o.mTac
                 && mEarfcn == o.mEarfcn
+                && Arrays.equals(mBands, o.mBands)
                 && mBandwidth == o.mBandwidth
                 && TextUtils.equals(mMccStr, o.mMccStr)
                 && TextUtils.equals(mMncStr, o.mMncStr)
@@ -341,6 +350,7 @@
         .append(" mPci=").append(mPci)
         .append(" mTac=").append(mTac)
         .append(" mEarfcn=").append(mEarfcn)
+        .append(" mBands=").append(mBands)
         .append(" mBandwidth=").append(mBandwidth)
         .append(" mMcc=").append(mMccStr)
         .append(" mMnc=").append(mMncStr)
@@ -360,8 +370,9 @@
         dest.writeInt(mPci);
         dest.writeInt(mTac);
         dest.writeInt(mEarfcn);
+        dest.writeIntArray(mBands);
         dest.writeInt(mBandwidth);
-        dest.writeList(mAdditionalPlmns);
+        dest.writeArraySet(mAdditionalPlmns);
         dest.writeParcelable(mCsgInfo, flags);
     }
 
@@ -372,8 +383,9 @@
         mPci = in.readInt();
         mTac = in.readInt();
         mEarfcn = in.readInt();
+        mBands = in.createIntArray();
         mBandwidth = in.readInt();
-        mAdditionalPlmns = in.readArrayList(null);
+        mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
         mCsgInfo = in.readParcelable(null);
         if (DBG) log(toString());
     }
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index a0ef5aa..69cf7e7d 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -22,11 +22,13 @@
 import android.os.Parcel;
 import android.telephony.AccessNetworkConstants.NgranBands.NgranBand;
 import android.telephony.gsm.GsmCellLocation;
+import android.util.ArraySet;
 
-import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * Information to represent a unique NR(New Radio 5G) cell.
@@ -43,10 +45,10 @@
     private final int mPci;
     private final int mTac;
     private final long mNci;
-    private final List<Integer> mBands;
+    private final int[] mBands;
 
     // a list of additional PLMN-IDs reported for this cell
-    private final List<String> mAdditionalPlmns;
+    private final ArraySet<String> mAdditionalPlmns;
 
     /**
      *
@@ -63,17 +65,18 @@
      *
      * @hide
      */
-    public CellIdentityNr(int pci, int tac, int nrArfcn, @NgranBand List<Integer> bands,
+    public CellIdentityNr(int pci, int tac, int nrArfcn, @NonNull @NgranBand int[] bands,
                           @Nullable String mccStr, @Nullable String mncStr, long nci,
                           @Nullable String alphal, @Nullable String alphas,
-                          @NonNull List<String> additionalPlmns) {
+                          @NonNull Collection<String> additionalPlmns) {
         super(TAG, CellInfo.TYPE_NR, mccStr, mncStr, alphal, alphas);
         mPci = inRangeOrUnavailable(pci, 0, MAX_PCI);
         mTac = inRangeOrUnavailable(tac, 0, MAX_TAC);
         mNrArfcn = inRangeOrUnavailable(nrArfcn, 0, MAX_NRARFCN);
-        mBands = new ArrayList<>(bands);
+        // TODO: input validation for bands
+        mBands = bands;
         mNci = inRangeOrUnavailable(nci, 0, MAX_NCI);
-        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        mAdditionalPlmns = new ArraySet<>(additionalPlmns.size());
         for (String plmn : additionalPlmns) {
             if (isValidPlmn(plmn)) {
                 mAdditionalPlmns.add(plmn);
@@ -83,15 +86,16 @@
 
     /** @hide */
     public CellIdentityNr(@NonNull android.hardware.radio.V1_4.CellIdentityNr cid) {
-        this(cid.pci, cid.tac, cid.nrarfcn, Collections.emptyList(), cid.mcc, cid.mnc, cid.nci,
+        this(cid.pci, cid.tac, cid.nrarfcn, new int[] {}, cid.mcc, cid.mnc, cid.nci,
                 cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
-                Collections.emptyList());
+                new ArraySet<>());
     }
 
     /** @hide */
     public CellIdentityNr(@NonNull android.hardware.radio.V1_5.CellIdentityNr cid) {
-        this(cid.base.pci, cid.base.tac, cid.base.nrarfcn, cid.bands, cid.base.mcc, cid.base.mnc,
-                cid.base.nci, cid.base.operatorNames.alphaLong,
+        this(cid.base.pci, cid.base.tac, cid.base.nrarfcn,
+                cid.bands.stream().mapToInt(Integer::intValue).toArray(), cid.base.mcc,
+                cid.base.mnc, cid.base.nci, cid.base.operatorNames.alphaLong,
                 cid.base.operatorNames.alphaShort, cid.additionalPlmns);
     }
 
@@ -116,18 +120,22 @@
     @Override
     public int hashCode() {
         return Objects.hash(super.hashCode(), mPci, mTac,
-                mNrArfcn, mBands.hashCode(), mNci, mAdditionalPlmns.hashCode());
+                mNrArfcn, Arrays.hashCode(mBands), mNci, mAdditionalPlmns.hashCode());
     }
 
     @Override
     public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+
         if (!(other instanceof CellIdentityNr)) {
             return false;
         }
 
         CellIdentityNr o = (CellIdentityNr) other;
         return super.equals(o) && mPci == o.mPci && mTac == o.mTac && mNrArfcn == o.mNrArfcn
-                && mBands.equals(o.mBands) && mNci == o.mNci
+                && Arrays.equals(mBands, o.mBands) && mNci == o.mNci
                 && mAdditionalPlmns.equals(o.mAdditionalPlmns);
     }
 
@@ -160,12 +168,12 @@
      * Reference: TS 38.101-1 table 5.2-1
      * Reference: TS 38.101-2 table 5.2-1
      *
-     * @return List of band number or empty list if not available.
+     * @return Array of band number or empty array if not available.
      */
     @NgranBand
     @NonNull
-    public List<Integer> getBands() {
-        return Collections.unmodifiableList(mBands);
+    public int[] getBands() {
+        return Arrays.copyOf(mBands, mBands.length);
     }
 
     /**
@@ -212,8 +220,8 @@
      * @return a list of additional PLMN IDs supported by this cell.
      */
     @NonNull
-    public List<String> getAdditionalPlmns() {
-        return Collections.unmodifiableList(mAdditionalPlmns);
+    public Set<String> getAdditionalPlmns() {
+        return Collections.unmodifiableSet(mAdditionalPlmns);
     }
 
     @Override
@@ -239,9 +247,9 @@
         dest.writeInt(mPci);
         dest.writeInt(mTac);
         dest.writeInt(mNrArfcn);
-        dest.writeList(mBands);
+        dest.writeIntArray(mBands);
         dest.writeLong(mNci);
-        dest.writeList(mAdditionalPlmns);
+        dest.writeArraySet(mAdditionalPlmns);
     }
 
     /** Construct from Parcel, type has already been processed */
@@ -250,9 +258,9 @@
         mPci = in.readInt();
         mTac = in.readInt();
         mNrArfcn = in.readInt();
-        mBands = in.readArrayList(null);
+        mBands = in.createIntArray();
         mNci = in.readLong();
-        mAdditionalPlmns = in.readArrayList(null);
+        mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
     }
 
     /** Implement the Parcelable interface */
diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java
index 531487a..30f98bc 100644
--- a/telephony/java/android/telephony/CellIdentityTdscdma.java
+++ b/telephony/java/android/telephony/CellIdentityTdscdma.java
@@ -20,11 +20,12 @@
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.telephony.gsm.GsmCellLocation;
+import android.util.ArraySet;
 
-import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * CellIdentity is to represent a unique TD-SCDMA cell
@@ -50,7 +51,7 @@
     private final int mUarfcn;
 
     // a list of additional PLMN-IDs reported for this cell
-    private final List<String> mAdditionalPlmns;
+    private final ArraySet<String> mAdditionalPlmns;
 
     private ClosedSubscriberGroupInfo mCsgInfo;
 
@@ -63,7 +64,7 @@
         mCid = CellInfo.UNAVAILABLE;
         mCpid = CellInfo.UNAVAILABLE;
         mUarfcn = CellInfo.UNAVAILABLE;
-        mAdditionalPlmns = Collections.emptyList();
+        mAdditionalPlmns = new ArraySet<>();
         mCsgInfo = null;
     }
 
@@ -85,13 +86,14 @@
      */
     public CellIdentityTdscdma(@Nullable String mcc, @Nullable String mnc, int lac, int cid,
             int cpid, int uarfcn, @Nullable String alphal, @Nullable String alphas,
-            @NonNull List<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo) {
+            @NonNull Collection<String> additionalPlmns,
+            @Nullable ClosedSubscriberGroupInfo csgInfo) {
         super(TAG, CellInfo.TYPE_TDSCDMA, mcc, mnc, alphal, alphas);
         mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
         mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
         mCpid = inRangeOrUnavailable(cpid, 0, MAX_CPID);
         mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN);
-        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        mAdditionalPlmns = new ArraySet<>(additionalPlmns.size());
         for (String plmn : additionalPlmns) {
             if (isValidPlmn(plmn)) {
                 mAdditionalPlmns.add(plmn);
@@ -208,8 +210,8 @@
      * @return a list of additional PLMN IDs supported by this cell.
      */
     @NonNull
-    public List<String> getAdditionalPlmns() {
-        return mAdditionalPlmns;
+    public Set<String> getAdditionalPlmns() {
+        return Collections.unmodifiableSet(mAdditionalPlmns);
     }
 
     /**
@@ -289,7 +291,7 @@
         dest.writeInt(mCid);
         dest.writeInt(mCpid);
         dest.writeInt(mUarfcn);
-        dest.writeList(mAdditionalPlmns);
+        dest.writeArraySet(mAdditionalPlmns);
         dest.writeParcelable(mCsgInfo, flags);
     }
 
@@ -300,7 +302,7 @@
         mCid = in.readInt();
         mCpid = in.readInt();
         mUarfcn = in.readInt();
-        mAdditionalPlmns = in.readArrayList(null);
+        mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
         mCsgInfo = in.readParcelable(null);
         if (DBG) log(toString());
     }
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index 15e491b..9d2cb74 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -22,11 +22,12 @@
 import android.os.Parcel;
 import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
+import android.util.ArraySet;
 
-import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * CellIdentity to represent a unique UMTS cell
@@ -51,7 +52,7 @@
     private final int mUarfcn;
 
     // a list of additional PLMN-IDs reported for this cell
-    private final List<String> mAdditionalPlmns;
+    private final ArraySet<String> mAdditionalPlmns;
 
     @Nullable
     private final ClosedSubscriberGroupInfo mCsgInfo;
@@ -65,7 +66,7 @@
         mCid = CellInfo.UNAVAILABLE;
         mPsc = CellInfo.UNAVAILABLE;
         mUarfcn = CellInfo.UNAVAILABLE;
-        mAdditionalPlmns = Collections.emptyList();
+        mAdditionalPlmns = new ArraySet<>();
         mCsgInfo = null;
     }
 
@@ -86,13 +87,14 @@
      */
     public CellIdentityWcdma(int lac, int cid, int psc, int uarfcn, @Nullable String mccStr,
             @Nullable String mncStr, @Nullable String alphal, @Nullable String alphas,
-            @NonNull List<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo) {
+            @NonNull Collection<String> additionalPlmns,
+            @Nullable ClosedSubscriberGroupInfo csgInfo) {
         super(TAG, CellInfo.TYPE_WCDMA, mccStr, mncStr, alphal, alphas);
         mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
         mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
         mPsc = inRangeOrUnavailable(psc, 0, MAX_PSC);
         mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN);
-        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        mAdditionalPlmns = new ArraySet<>(additionalPlmns.size());
         for (String plmn : additionalPlmns) {
             if (isValidPlmn(plmn)) {
                 mAdditionalPlmns.add(plmn);
@@ -104,14 +106,14 @@
     /** @hide */
     public CellIdentityWcdma(@NonNull android.hardware.radio.V1_0.CellIdentityWcdma cid) {
         this(cid.lac, cid.cid, cid.psc, cid.uarfcn, cid.mcc, cid.mnc, "", "",
-                Collections.emptyList(), null);
+                new ArraySet<>(), null);
     }
 
     /** @hide */
     public CellIdentityWcdma(@NonNull android.hardware.radio.V1_2.CellIdentityWcdma cid) {
         this(cid.base.lac, cid.base.cid, cid.base.psc, cid.base.uarfcn,
                 cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong,
-                cid.operatorNames.alphaShort, Collections.emptyList(), null);
+                cid.operatorNames.alphaShort, new ArraySet<>(), null);
     }
 
     /** @hide */
@@ -232,8 +234,8 @@
      * @return a list of additional PLMN IDs supported by this cell.
      */
     @NonNull
-    public List<String> getAdditionalPlmns() {
-        return mAdditionalPlmns;
+    public Set<String> getAdditionalPlmns() {
+        return Collections.unmodifiableSet(mAdditionalPlmns);
     }
 
     /**
@@ -305,7 +307,7 @@
         dest.writeInt(mCid);
         dest.writeInt(mPsc);
         dest.writeInt(mUarfcn);
-        dest.writeList(mAdditionalPlmns);
+        dest.writeArraySet(mAdditionalPlmns);
         dest.writeParcelable(mCsgInfo, flags);
     }
 
@@ -316,7 +318,7 @@
         mCid = in.readInt();
         mPsc = in.readInt();
         mUarfcn = in.readInt();
-        mAdditionalPlmns = in.readArrayList(null);
+        mAdditionalPlmns = (ArraySet<String>) in.readArraySet(null);
         mCsgInfo = in.readParcelable(null);
         if (DBG) log(toString());
     }
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
index bfa209b..b381cce 100644
--- a/telephony/java/android/telephony/CellInfo.java
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -21,6 +21,7 @@
 import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.hardware.radio.V1_4.CellInfo.Info;
+import android.hardware.radio.V1_5.CellInfo.CellInfoRatSpecificInfo;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -28,6 +29,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
 
 /**
  * Immutable cell information from a point in time.
@@ -152,7 +154,7 @@
     protected CellInfo() {
         this.mRegistered = false;
         this.mTimeStamp = Long.MAX_VALUE;
-        mCellConnectionStatus = CONNECTION_NONE;
+        this.mCellConnectionStatus = CONNECTION_NONE;
     }
 
     /** @hide */
@@ -240,27 +242,17 @@
 
     @Override
     public int hashCode() {
-        int primeNum = 31;
-        return ((mRegistered ? 0 : 1) * primeNum) + ((int)(mTimeStamp / 1000) * primeNum)
-                + (mCellConnectionStatus * primeNum);
+        return Objects.hash(mCellConnectionStatus, mRegistered, mTimeStamp);
     }
 
     @Override
-    public boolean equals(Object other) {
-        if (other == null) {
-            return false;
-        }
-        if (this == other) {
-            return true;
-        }
-        try {
-            CellInfo o = (CellInfo) other;
-            return mRegistered == o.mRegistered
-                    && mTimeStamp == o.mTimeStamp
-                    && mCellConnectionStatus == o.mCellConnectionStatus;
-        } catch (ClassCastException e) {
-            return false;
-        }
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof CellInfo)) return false;
+        CellInfo cellInfo = (CellInfo) o;
+        return mCellConnectionStatus == cellInfo.mCellConnectionStatus
+                && mRegistered == cellInfo.mRegistered
+                && mTimeStamp == cellInfo.mTimeStamp;
     }
 
     @Override
@@ -353,6 +345,13 @@
     }
 
     /** @hide */
+    protected CellInfo(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) {
+        this.mRegistered = ci.registered;
+        this.mTimeStamp = timeStamp;
+        this.mCellConnectionStatus = ci.connectionStatus;
+    }
+
+    /** @hide */
     public static CellInfo create(android.hardware.radio.V1_0.CellInfo ci) {
         if (ci == null) return null;
         switch(ci.cellInfoType) {
@@ -391,4 +390,24 @@
             default: return null;
         }
     }
+
+    /** @hide */
+    public static CellInfo create(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) {
+        if (ci == null) return null;
+        switch (ci.ratSpecificInfo.getDiscriminator()) {
+            case CellInfoRatSpecificInfo.hidl_discriminator.gsm:
+                return new CellInfoGsm(ci, timeStamp);
+            case CellInfoRatSpecificInfo.hidl_discriminator.cdma:
+                return new CellInfoCdma(ci, timeStamp);
+            case CellInfoRatSpecificInfo.hidl_discriminator.lte:
+                return new CellInfoLte(ci, timeStamp);
+            case CellInfoRatSpecificInfo.hidl_discriminator.wcdma:
+                return new CellInfoWcdma(ci, timeStamp);
+            case CellInfoRatSpecificInfo.hidl_discriminator.tdscdma:
+                return new CellInfoTdscdma(ci, timeStamp);
+            case CellInfoRatSpecificInfo.hidl_discriminator.nr:
+                return new CellInfoNr(ci, timeStamp);
+            default: return null;
+        }
+    }
 }
diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java
index 0edb4a4..1bef681 100644
--- a/telephony/java/android/telephony/CellInfoCdma.java
+++ b/telephony/java/android/telephony/CellInfoCdma.java
@@ -78,6 +78,15 @@
                 new CellSignalStrengthCdma(cic.signalStrengthCdma, cic.signalStrengthEvdo);
     }
 
+    /** @hide */
+    public CellInfoCdma(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) {
+        super(ci, timeStamp);
+        final android.hardware.radio.V1_2.CellInfoCdma cic = ci.ratSpecificInfo.cdma();
+        mCellIdentityCdma = new CellIdentityCdma(cic.cellIdentityCdma);
+        mCellSignalStrengthCdma =
+                new CellSignalStrengthCdma(cic.signalStrengthCdma, cic.signalStrengthEvdo);
+    }
+
     /**
      * @return a {@link CellIdentityCdma} instance.
      */
diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java
index 2dddd3f..c19521f 100644
--- a/telephony/java/android/telephony/CellInfoGsm.java
+++ b/telephony/java/android/telephony/CellInfoGsm.java
@@ -73,6 +73,14 @@
         mCellSignalStrengthGsm = new CellSignalStrengthGsm(cig.signalStrengthGsm);
     }
 
+    /** @hide */
+    public CellInfoGsm(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) {
+        super(ci, timeStamp);
+        final android.hardware.radio.V1_5.CellInfoGsm cig = ci.ratSpecificInfo.gsm();
+        mCellIdentityGsm = new CellIdentityGsm(cig.cellIdentityGsm);
+        mCellSignalStrengthGsm = new CellSignalStrengthGsm(cig.signalStrengthGsm);
+    }
+
     /**
      * @return a {@link CellIdentityGsm} instance.
      */
diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java
index a57c7cd..320925e 100644
--- a/telephony/java/android/telephony/CellInfoLte.java
+++ b/telephony/java/android/telephony/CellInfoLte.java
@@ -82,6 +82,15 @@
         mCellConfig = new CellConfigLte(cil.cellConfig);
     }
 
+    /** @hide */
+    public CellInfoLte(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) {
+        super(ci, timeStamp);
+        final android.hardware.radio.V1_5.CellInfoLte cil = ci.ratSpecificInfo.lte();
+        mCellIdentityLte = new CellIdentityLte(cil.cellIdentityLte);
+        mCellSignalStrengthLte = new CellSignalStrengthLte(cil.signalStrengthLte);
+        mCellConfig = new CellConfigLte();
+    }
+
     /**
      * @return a {@link CellIdentityLte} instance.
      */
diff --git a/telephony/java/android/telephony/CellInfoNr.java b/telephony/java/android/telephony/CellInfoNr.java
index 8b41b8b..a7e79f9 100644
--- a/telephony/java/android/telephony/CellInfoNr.java
+++ b/telephony/java/android/telephony/CellInfoNr.java
@@ -53,6 +53,14 @@
         mCellSignalStrength = new CellSignalStrengthNr(cil.signalStrength);
     }
 
+    /** @hide */
+    public CellInfoNr(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) {
+        super(ci, timeStamp);
+        final android.hardware.radio.V1_5.CellInfoNr cil = ci.ratSpecificInfo.nr();
+        mCellIdentity = new CellIdentityNr(cil.cellIdentityNr);
+        mCellSignalStrength = new CellSignalStrengthNr(cil.signalStrengthNr);
+    }
+
     /**
      * @return a {@link CellIdentityNr} instance.
      */
diff --git a/telephony/java/android/telephony/CellInfoTdscdma.java b/telephony/java/android/telephony/CellInfoTdscdma.java
index d2cc9c6c..038c49a 100644
--- a/telephony/java/android/telephony/CellInfoTdscdma.java
+++ b/telephony/java/android/telephony/CellInfoTdscdma.java
@@ -77,6 +77,14 @@
         mCellSignalStrengthTdscdma = new CellSignalStrengthTdscdma(cit.signalStrengthTdscdma);
     }
 
+    /** @hide */
+    public CellInfoTdscdma(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) {
+        super(ci, timeStamp);
+        final android.hardware.radio.V1_5.CellInfoTdscdma cit = ci.ratSpecificInfo.tdscdma();
+        mCellIdentityTdscdma = new CellIdentityTdscdma(cit.cellIdentityTdscdma);
+        mCellSignalStrengthTdscdma = new CellSignalStrengthTdscdma(cit.signalStrengthTdscdma);
+    }
+
     /**
      * @return a {@link CellIdentityTdscdma} instance.
      */
diff --git a/telephony/java/android/telephony/CellInfoWcdma.java b/telephony/java/android/telephony/CellInfoWcdma.java
index 3f792d1..c74955f 100644
--- a/telephony/java/android/telephony/CellInfoWcdma.java
+++ b/telephony/java/android/telephony/CellInfoWcdma.java
@@ -72,6 +72,14 @@
         mCellSignalStrengthWcdma = new CellSignalStrengthWcdma(ciw.signalStrengthWcdma);
     }
 
+    /** @hide */
+    public CellInfoWcdma(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) {
+        super(ci, timeStamp);
+        final android.hardware.radio.V1_5.CellInfoWcdma ciw = ci.ratSpecificInfo.wcdma();
+        mCellIdentityWcdma = new CellIdentityWcdma(ciw.cellIdentityWcdma);
+        mCellSignalStrengthWcdma = new CellSignalStrengthWcdma(ciw.signalStrengthWcdma);
+    }
+
     /**
      * @return a {@link CellIdentityWcdma} instance.
      */
diff --git a/telephony/java/android/telephony/CellSignalStrengthCdma.java b/telephony/java/android/telephony/CellSignalStrengthCdma.java
index 1c92705b..d00049c 100644
--- a/telephony/java/android/telephony/CellSignalStrengthCdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java
@@ -314,6 +314,8 @@
 
     /**
      * Get the signal strength as dBm
+     *
+     * @return min(CDMA RSSI, EVDO RSSI) of the measured cell.
      */
     @Override
     public int getDbm() {
diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java
index 76d2df9..9d55f10 100644
--- a/telephony/java/android/telephony/CellSignalStrengthGsm.java
+++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java
@@ -145,6 +145,8 @@
 
     /**
      * Get the signal strength as dBm.
+     *
+     * @return the RSSI of the measured cell.
      */
     @Override
     public int getDbm() {
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index 270eafe..c667165 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -208,7 +208,6 @@
      * @return {@code true} if using carrier aggregation.
      * @hide
      */
-    @SystemApi
     public boolean isUsingCarrierAggregation() {
         return mIsUsingCarrierAggregation;
     }
diff --git a/telephony/java/android/telephony/ImsManager.java b/telephony/java/android/telephony/ImsManager.java
index 704e5aa..34bac5d 100644
--- a/telephony/java/android/telephony/ImsManager.java
+++ b/telephony/java/android/telephony/ImsManager.java
@@ -34,8 +34,9 @@
     private Context mContext;
 
     /**
-     * <p>Broadcast Action: Indicates that an IMS operation was rejected by the network due to it
-     * not being authorized on the network.
+     * <p>Broadcast Action: Indicates that a previously allowed IMS operation was rejected by the
+     * network due to the network returning a "forbidden" response. This may be due to a
+     * provisioning change from the network.
      * May include the {@link SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX} extra to also specify
      * which subscription the operation was rejected for.
      * <p class="note">
@@ -74,17 +75,17 @@
             "android.telephony.ims.action.WFC_IMS_REGISTRATION_ERROR";
 
     /**
-     * An extra key corresponding to a String value which contains the carrier specific title to be
-     * displayed as part of the message shown to the user when there is an error registering for
-     * WiFi calling.
+     * An extra key corresponding to a {@link CharSequence} value which contains the carrier
+     * specific title to be displayed as part of the message shown to the user when there is an
+     * error registering for WiFi calling.
      */
     public static final String EXTRA_WFC_REGISTRATION_FAILURE_TITLE =
             "android.telephony.ims.extra.WFC_REGISTRATION_FAILURE_TITLE";
 
     /**
-     * An extra key corresponding to a String value which contains the carrier specific message to
-     * be displayed as part of the message shown to the user when there is an error registering for
-     * WiFi calling.
+     * An extra key corresponding to a {@link CharSequence} value which contains the carrier
+     * specific message to  be displayed as part of the message shown to the user when there is an
+     * error registering for WiFi calling.
      */
     public static final String EXTRA_WFC_REGISTRATION_FAILURE_MESSAGE =
             "android.telephony.ims.extra.WFC_REGISTRATION_FAILURE_MESSAGE";
@@ -103,10 +104,7 @@
      * @param subscriptionId The ID of the subscription that this ImsRcsManager will use.
      * @throws IllegalArgumentException if the subscription is invalid.
      * @return a ImsRcsManager instance with the specific subscription ID.
-     * @hide
      */
-    @SystemApi
-    @TestApi
     @NonNull
     public ImsRcsManager getImsRcsManager(int subscriptionId) {
         if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 32ffb75..93fbb00 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -25,6 +25,7 @@
 import android.os.Parcelable;
 import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.Annotation.NetworkType;
+import android.text.TextUtils;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -214,6 +215,9 @@
     @Nullable
     private DataSpecificRegistrationInfo mDataSpecificInfo;
 
+    @NonNull
+    private String mRplmn;
+
     /**
      * @param domain Network domain. Must be a {@link Domain}. For transport type
      * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, this must set to {@link #DOMAIN_PS}.
@@ -234,13 +238,14 @@
      * @param availableServices The list of the supported services.
      * @param cellIdentity The identity representing a unique cell or wifi AP. Set to null if the
      * information is not available.
+     * @param rplmn the registered plmn or the last plmn for attempted registration if reg failed.
      */
     private NetworkRegistrationInfo(@Domain int domain, @TransportType int transportType,
                                    @RegistrationState int registrationState,
                                    @NetworkType int accessNetworkTechnology, int rejectCause,
                                    boolean emergencyOnly,
                                    @Nullable @ServiceType List<Integer> availableServices,
-                                   @Nullable CellIdentity cellIdentity) {
+                                   @Nullable CellIdentity cellIdentity, @Nullable String rplmn) {
         mDomain = domain;
         mTransportType = transportType;
         mRegistrationState = registrationState;
@@ -253,6 +258,7 @@
         mCellIdentity = cellIdentity;
         mEmergencyOnly = emergencyOnly;
         mNrState = NR_STATE_NONE;
+        mRplmn = rplmn;
     }
 
     /**
@@ -263,11 +269,11 @@
                                    int registrationState, int accessNetworkTechnology,
                                    int rejectCause, boolean emergencyOnly,
                                    @Nullable List<Integer> availableServices,
-                                   @Nullable CellIdentity cellIdentity, boolean cssSupported,
-                                   int roamingIndicator, int systemIsInPrl,
+                                   @Nullable CellIdentity cellIdentity, @Nullable String rplmn,
+                                   boolean cssSupported, int roamingIndicator, int systemIsInPrl,
                                    int defaultRoamingIndicator) {
         this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
-                emergencyOnly, availableServices, cellIdentity);
+                emergencyOnly, availableServices, cellIdentity, rplmn);
 
         mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator,
                 systemIsInPrl, defaultRoamingIndicator);
@@ -281,17 +287,17 @@
                                    int registrationState, int accessNetworkTechnology,
                                    int rejectCause, boolean emergencyOnly,
                                    @Nullable List<Integer> availableServices,
-                                   @Nullable CellIdentity cellIdentity, int maxDataCalls,
-                                   boolean isDcNrRestricted, boolean isNrAvailable,
-                                   boolean isEndcAvailable,
+                                   @Nullable CellIdentity cellIdentity, @Nullable String rplmn,
+                                   int maxDataCalls, boolean isDcNrRestricted,
+                                   boolean isNrAvailable, boolean isEndcAvailable,
                                    LteVopsSupportInfo lteVopsSupportInfo,
                                    boolean isUsingCarrierAggregation) {
         this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
-                emergencyOnly, availableServices, cellIdentity);
+                emergencyOnly, availableServices, cellIdentity, rplmn);
         mDataSpecificInfo = new DataSpecificRegistrationInfo(
                 maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo,
                 isUsingCarrierAggregation);
-        updateNrState(mDataSpecificInfo);
+        updateNrState();
     }
 
     private NetworkRegistrationInfo(Parcel source) {
@@ -310,6 +316,7 @@
         mDataSpecificInfo = source.readParcelable(
                 DataSpecificRegistrationInfo.class.getClassLoader());
         mNrState = source.readInt();
+        mRplmn = source.readString();
     }
 
     /**
@@ -343,6 +350,7 @@
             mDataSpecificInfo = new DataSpecificRegistrationInfo(nri.mDataSpecificInfo);
         }
         mNrState = nri.mNrState;
+        mRplmn = nri.mRplmn;
     }
 
     /**
@@ -359,6 +367,7 @@
      * Get the 5G NR connection state.
      *
      * @return the 5G NR connection state.
+     * @hide
      */
     public @NRState int getNrState() {
         return mNrState;
@@ -395,6 +404,22 @@
     }
 
     /**
+     * Get the PLMN-ID for this Network Registration, also known as the RPLMN.
+     *
+     * <p>If the device is registered, this will return the registered PLMN-ID. If registration
+     * has failed, then this will return the PLMN ID of the last attempted registration. If the
+     * device is not registered, or if is registered to a non-3GPP radio technology, then this
+     * will return null.
+     *
+     * <p>See 3GPP TS 23.122 for further information about the Registered PLMN.
+     *
+     * @return the registered PLMN-ID or null.
+     */
+    @Nullable public String getRegisteredPlmn() {
+        return mRplmn;
+    }
+
+    /**
      * @return {@code true} if registered on roaming network, {@code false} otherwise.
      */
     public boolean isRoaming() {
@@ -590,6 +615,7 @@
                 .append(" voiceSpecificInfo=").append(mVoiceSpecificInfo)
                 .append(" dataSpecificInfo=").append(mDataSpecificInfo)
                 .append(" nrState=").append(nrStateToString(mNrState))
+                .append(" rRplmn=").append(mRplmn)
                 .append("}").toString();
     }
 
@@ -597,7 +623,7 @@
     public int hashCode() {
         return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType,
                 mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
-                mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState);
+                mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState, mRplmn);
     }
 
     @Override
@@ -620,6 +646,7 @@
                 && Objects.equals(mCellIdentity, other.mCellIdentity)
                 && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo)
                 && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo)
+                && TextUtils.equals(mRplmn, other.mRplmn)
                 && mNrState == other.mNrState;
     }
 
@@ -641,6 +668,7 @@
         dest.writeParcelable(mVoiceSpecificInfo, 0);
         dest.writeParcelable(mDataSpecificInfo, 0);
         dest.writeInt(mNrState);
+        dest.writeString(mRplmn);
     }
 
     /**
@@ -658,12 +686,12 @@
      * DCNR is not restricted and NR is supported by the selected PLMN. Otherwise the use of 5G
      * NR is restricted.
      *
-     * @param state data specific registration state contains the 5G NR indicators.
+     * @hide
      */
-    private void updateNrState(DataSpecificRegistrationInfo state) {
+    public void updateNrState() {
         mNrState = NR_STATE_NONE;
-        if (state.isEnDcAvailable) {
-            if (!state.isDcNrRestricted && state.isNrAvailable) {
+        if (mDataSpecificInfo != null && mDataSpecificInfo.isEnDcAvailable) {
+            if (!mDataSpecificInfo.isDcNrRestricted && mDataSpecificInfo.isNrAvailable) {
                 mNrState = NR_STATE_NOT_RESTRICTED;
             } else {
                 mNrState = NR_STATE_RESTRICTED;
@@ -741,6 +769,9 @@
         @Nullable
         private CellIdentity mCellIdentity;
 
+        @NonNull
+        private String mRplmn = "";
+
         /**
          * Default constructor for Builder.
          */
@@ -855,6 +886,18 @@
         }
 
         /**
+         * Set the registered PLMN.
+         *
+         * @param rplmn the registered plmn.
+         *
+         * @return The same instance of the builder.
+         */
+        public @NonNull Builder setRegisteredPlmn(@Nullable String rplmn) {
+            mRplmn = rplmn;
+            return this;
+        }
+
+        /**
          * Build the NetworkRegistrationInfo.
          * @return the NetworkRegistrationInfo object.
          * @hide
@@ -863,7 +906,7 @@
         public @NonNull NetworkRegistrationInfo build() {
             return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState,
                     mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
-                    mCellIdentity);
+                    mCellIdentity, mRplmn);
         }
     }
 }
diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java
index 87d94bfd..c75de42 100644
--- a/telephony/java/android/telephony/NetworkService.java
+++ b/telephony/java/android/telephony/NetworkService.java
@@ -234,6 +234,9 @@
      * this method to facilitate the creation of {@link NetworkServiceProvider} instances. The system
      * will call this method after binding the network service for each active SIM slot id.
      *
+     * This methead is guaranteed to be invoked in {@link NetworkService}'s internal handler thread
+     * whose looper can be retrieved with {@link Looper.myLooper()} when override this method.
+     *
      * @param slotIndex SIM slot id the network service associated with.
      * @return Network service object. Null if failed to create the provider (e.g. invalid slot
      * index)
diff --git a/telephony/java/android/telephony/PinResult.java b/telephony/java/android/telephony/PinResult.java
index 683e853..68c9d99 100644
--- a/telephony/java/android/telephony/PinResult.java
+++ b/telephony/java/android/telephony/PinResult.java
@@ -19,7 +19,6 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -32,7 +31,6 @@
  *
  * @hide
  */
-@SystemApi
 public final class PinResult implements Parcelable {
     /** @hide */
     @IntDef({
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java
index 54c22ae..a9abe89 100644
--- a/telephony/java/android/telephony/PreciseDataConnectionState.java
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.java
@@ -95,7 +95,6 @@
      *        if there is no valid APN setting for the specific type, then this will be null
      * @hide
      */
-    @SystemApi
     public PreciseDataConnectionState(@DataState int state,
                                       @NetworkType int networkType,
                                       @ApnType int apnTypes, @NonNull String apn,
@@ -265,10 +264,10 @@
     /**
      * Return the APN Settings for this data connection.
      *
-     * Returns the ApnSetting that was used to configure this data connection.
+     * @return the ApnSetting that was used to configure this data connection.
      */
     // FIXME: This shouldn't be nullable; update once the ApnSetting is supplied correctly
-    @Nullable ApnSetting getApnSetting() {
+    public @Nullable ApnSetting getApnSetting() {
         return mApnSetting;
     }
 
diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java
index bc84738..90ddf2c 100644
--- a/telephony/java/android/telephony/RadioAccessFamily.java
+++ b/telephony/java/android/telephony/RadioAccessFamily.java
@@ -260,24 +260,6 @@
         return raf;
     }
 
-    /**
-     * Returns the highest capability of the RadioAccessFamily (4G > 3G > 2G).
-     * @param raf The RadioAccessFamily that we wish to filter
-     * @return The highest radio capability
-     */
-    public static int getHighestRafCapability(int raf) {
-        if ((LTE & raf) > 0) {
-            return TelephonyManager.NETWORK_CLASS_4_G;
-        }
-        if ((EVDO|HS|WCDMA & raf) > 0) {
-            return TelephonyManager.NETWORK_CLASS_3_G;
-        }
-        if((GSM|CDMA & raf) > 0) {
-            return TelephonyManager.NETWORK_CLASS_2_G;
-        }
-        return TelephonyManager.NETWORK_CLASS_UNKNOWN;
-    }
-
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     @PrefNetworkMode
     public static int getNetworkTypeFromRaf(int raf) {
@@ -395,4 +377,34 @@
         }
         return result;
     }
+
+    /**
+     * Compare two sets of network types to see which is more capable.
+     *
+     * This algorithm first tries to see see if a set has a strict superset of RAT support for
+     * each generation, from newest to oldest; if that results in a tie, then it returns the set
+     * that supports the most RAT types.
+     */
+    public static int compare(long networkTypeBitmaskL, long networkTypeBitmaskR) {
+        final long[] prioritizedNetworkClassBitmasks = new long[] {
+            TelephonyManager.NETWORK_CLASS_BITMASK_5G,
+            TelephonyManager.NETWORK_CLASS_BITMASK_4G,
+            TelephonyManager.NETWORK_CLASS_BITMASK_3G,
+            TelephonyManager.NETWORK_CLASS_BITMASK_2G,
+        };
+
+        long lhsUnique = networkTypeBitmaskL & ~networkTypeBitmaskR;
+        long rhsUnique = networkTypeBitmaskR & ~networkTypeBitmaskL;
+
+        // See if one has a strict super-set of capabilities, generation by generation.
+        for (long classBitmask : prioritizedNetworkClassBitmasks) {
+            int result = 0;
+            if ((lhsUnique & classBitmask) != 0) ++result;
+            if ((rhsUnique & classBitmask) != 0) --result;
+            if (result != 0) return result;
+        }
+
+        // Without a clear winner, return the one that supports the most types.
+        return Long.bitCount(networkTypeBitmaskL) - Long.bitCount(networkTypeBitmaskR);
+    }
 }
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index f8e4bea..82470d4 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -580,7 +580,6 @@
      *
      * @hide
      */
-    @SystemApi
     public @RegState int getDataRegistrationState() {
         return getDataRegState();
     }
@@ -1422,7 +1421,6 @@
      * @return the frequency range of 5G NR.
      * @hide
      */
-    @SystemApi
     public @FrequencyRange int getNrFrequencyRange() {
         return mNrFrequencyRange;
     }
@@ -1993,7 +1991,6 @@
      * @return the copied ServiceState with location info sanitized.
      * @hide
      */
-    @SystemApi
     @NonNull
     public ServiceState createLocationInfoSanitizedCopy(boolean removeCoarseLocation) {
         ServiceState state = new ServiceState(this);
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index fe78588..0f52ba7 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -389,7 +389,7 @@
             String destinationAddress, String scAddress, String text,
             PendingIntent sentIntent, PendingIntent deliveryIntent) {
         sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
-                true /* persistMessage*/, null);
+                true /* persistMessage*/, null, null);
     }
 
     /**
@@ -507,7 +507,7 @@
 
     private void sendTextMessageInternal(String destinationAddress, String scAddress,
             String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
-            boolean persistMessage, String packageName) {
+            boolean persistMessage, String packageName, String attributionTag) {
         if (TextUtils.isEmpty(destinationAddress)) {
             throw new IllegalArgumentException("Invalid destinationAddress");
         }
@@ -532,7 +532,7 @@
                 public void onSuccess(int subId) {
                     ISms iSms = getISmsServiceOrThrow();
                     try {
-                        iSms.sendTextForSubscriber(subId, packageName,
+                        iSms.sendTextForSubscriber(subId, packageName, attributionTag,
                                 destinationAddress, scAddress, text, sentIntent, deliveryIntent,
                                 persistMessage);
                     } catch (RemoteException e) {
@@ -552,7 +552,7 @@
             // visible to the user.
             ISms iSms = getISmsServiceOrThrow();
             try {
-                iSms.sendTextForSubscriber(getSubscriptionId(), packageName,
+                iSms.sendTextForSubscriber(getSubscriptionId(), packageName, attributionTag,
                         destinationAddress, scAddress, text, sentIntent, deliveryIntent,
                         persistMessage);
             } catch (RemoteException e) {
@@ -599,7 +599,7 @@
             String destinationAddress, String scAddress, String text,
             PendingIntent sentIntent, PendingIntent deliveryIntent) {
         sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
-                false /* persistMessage */, null);
+                false /* persistMessage */, null, null);
     }
 
     private void sendTextMessageInternal(
@@ -642,7 +642,7 @@
                         ISms iSms = getISmsServiceOrThrow();
                         if (iSms != null) {
                             iSms.sendTextForSubscriberWithOptions(subId,
-                                    null, destinationAddress,
+                                    null, null, destinationAddress,
                                     scAddress,
                                     text, sentIntent, deliveryIntent, persistMessage, finalPriority,
                                     expectMore, finalValidity);
@@ -664,7 +664,7 @@
                 ISms iSms = getISmsServiceOrThrow();
                 if (iSms != null) {
                     iSms.sendTextForSubscriberWithOptions(getSubscriptionId(),
-                            null, destinationAddress,
+                            null, null, destinationAddress,
                             scAddress,
                             text, sentIntent, deliveryIntent, persistMessage, finalPriority,
                             expectMore, finalValidity);
@@ -882,7 +882,24 @@
             String destinationAddress, String scAddress, ArrayList<String> parts,
             ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
-                deliveryIntents, true /* persistMessage*/, null);
+                deliveryIntents, true /* persistMessage*/, null, null);
+    }
+
+    /**
+     * @deprecated Use {@link #sendMultipartTextMessage(String, String, List, List, List, String,
+     * String)} instead.
+     *
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    @TestApi
+    public void sendMultipartTextMessage(
+            @NonNull String destinationAddress, @NonNull String scAddress,
+            @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
+            @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName) {
+        sendMultipartTextMessage(destinationAddress, scAddress, parts, sentIntents, deliveryIntents,
+                packageName, null);
     }
 
     /**
@@ -909,15 +926,16 @@
     public void sendMultipartTextMessage(
             @NonNull String destinationAddress, @NonNull String scAddress,
             @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
-            @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName) {
+            @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName,
+            @Nullable String attributionTag) {
         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
-                deliveryIntents, true /* persistMessage*/, packageName);
+                deliveryIntents, true /* persistMessage*/, packageName, attributionTag);
     }
 
     private void sendMultipartTextMessageInternal(
             String destinationAddress, String scAddress, List<String> parts,
             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
-            boolean persistMessage, String packageName) {
+            boolean persistMessage, String packageName, String attributionTag) {
         if (TextUtils.isEmpty(destinationAddress)) {
             throw new IllegalArgumentException("Invalid destinationAddress");
         }
@@ -942,7 +960,7 @@
                     public void onSuccess(int subId) {
                         try {
                             ISms iSms = getISmsServiceOrThrow();
-                            iSms.sendMultipartTextForSubscriber(subId, packageName,
+                            iSms.sendMultipartTextForSubscriber(subId, packageName, attributionTag,
                                     destinationAddress, scAddress, parts, sentIntents,
                                     deliveryIntents, persistMessage);
                         } catch (RemoteException e) {
@@ -963,8 +981,8 @@
                     ISms iSms = getISmsServiceOrThrow();
                     if (iSms != null) {
                         iSms.sendMultipartTextForSubscriber(getSubscriptionId(), packageName,
-                                destinationAddress, scAddress, parts, sentIntents, deliveryIntents,
-                                persistMessage);
+                                attributionTag, destinationAddress, scAddress, parts, sentIntents,
+                                deliveryIntents, persistMessage);
                     }
                 } catch (RemoteException e) {
                     Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - "
@@ -982,7 +1000,7 @@
                 deliveryIntent = deliveryIntents.get(0);
             }
             sendTextMessageInternal(destinationAddress, scAddress, parts.get(0),
-                    sentIntent, deliveryIntent, true, packageName);
+                    sentIntent, deliveryIntent, true, packageName, attributionTag);
         }
     }
 
@@ -1012,7 +1030,7 @@
             String destinationAddress, String scAddress, List<String> parts,
             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
-                deliveryIntents, false /* persistMessage*/, null);
+                deliveryIntents, false /* persistMessage*/, null, null);
     }
 
     /**
@@ -1174,7 +1192,7 @@
                             ISms iSms = getISmsServiceOrThrow();
                             if (iSms != null) {
                                 iSms.sendMultipartTextForSubscriberWithOptions(subId,
-                                        null, destinationAddress,
+                                        null, null, destinationAddress,
                                         scAddress, parts, sentIntents, deliveryIntents,
                                         persistMessage, finalPriority, expectMore, finalValidity);
                             }
@@ -1196,7 +1214,7 @@
                     ISms iSms = getISmsServiceOrThrow();
                     if (iSms != null) {
                         iSms.sendMultipartTextForSubscriberWithOptions(getSubscriptionId(),
-                                null, destinationAddress,
+                                null, null, destinationAddress,
                                 scAddress, parts, sentIntents, deliveryIntents,
                                 persistMessage, finalPriority, expectMore, finalValidity);
                     }
@@ -1327,9 +1345,8 @@
             public void onSuccess(int subId) {
                 try {
                     ISms iSms = getISmsServiceOrThrow();
-                    iSms.sendDataForSubscriber(subId, null,
-                            destinationAddress, scAddress, destinationPort & 0xFFFF, data,
-                            sentIntent, deliveryIntent);
+                    iSms.sendDataForSubscriber(subId, null, null, destinationAddress, scAddress,
+                            destinationPort & 0xFFFF, data, sentIntent, deliveryIntent);
                 } catch (RemoteException e) {
                     Log.e(TAG, "sendDataMessage: Couldn't send SMS - Exception: " + e.getMessage());
                     notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
@@ -1481,7 +1498,7 @@
             // it here because we do not have access to the activity context that is performing this
             // operation.
             // Requires that the calling process has the SEND_SMS permission.
-            getITelephony().enqueueSmsPickResult(null,
+            getITelephony().enqueueSmsPickResult(null, null,
                     new IIntegerConsumer.Stub() {
                         @Override
                         public void accept(int subId) {
@@ -2751,7 +2768,7 @@
                         getSubscriptionId(), null);
             }
         } catch (RemoteException ex) {
-            throw new RuntimeException(ex);
+            // ignore it
         }
         return smsc;
     }
@@ -2773,8 +2790,7 @@
      * </p>
      *
      * @param smsc the SMSC address string.
-     * @return true for success, false otherwise. Failure can be due to caller not having the
-     * appropriate permission, or modem returning an error.
+     * @return true for success, false otherwise.
      */
     @SuppressAutoDoc // for carrier privileges and default SMS application.
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
@@ -2786,7 +2802,7 @@
                         smsc, getSubscriptionId(), null);
             }
         } catch (RemoteException ex) {
-            throw new RuntimeException(ex);
+            // ignore it
         }
         return false;
     }
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 832771d..dc75c58 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -226,7 +226,7 @@
         this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number,
                 roaming, icon, mcc, mnc, countryIso, isEmbedded, nativeAccessRules, cardString, -1,
                 false, null, false, TelephonyManager.UNKNOWN_CARRIER_ID,
-                SubscriptionManager.PROFILE_CLASS_DEFAULT,
+                SubscriptionManager.PROFILE_CLASS_UNSET,
                 SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null, null, true);
     }
 
@@ -798,7 +798,7 @@
                 + " hplmns=" + Arrays.toString(mHplmns)
                 + " subscriptionType=" + mSubscriptionType
                 + " mGroupOwner=" + mGroupOwner
-                + " carrierConfigAccessRules=" + mCarrierConfigAccessRules
+                + " carrierConfigAccessRules=" + Arrays.toString(mCarrierConfigAccessRules)
                 + " mAreUiccApplicationsEnabled=" + mAreUiccApplicationsEnabled + "}";
     }
 
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index d8cebfb..d4a76b7 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -265,7 +265,8 @@
      * <P>Type: TEXT (String)</P>
      */
     /** @hide */
-    public static final String UNIQUE_KEY_SUBSCRIPTION_ID = SimInfo.UNIQUE_KEY_SUBSCRIPTION_ID;
+    public static final String UNIQUE_KEY_SUBSCRIPTION_ID =
+            SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID;
 
     /**
      * TelephonyProvider column name for a unique identifier for the subscription within the
@@ -274,14 +275,14 @@
      * <P>Type: TEXT (String)</P>
      */
     /** @hide */
-    public static final String ICC_ID = SimInfo.ICC_ID;
+    public static final String ICC_ID = SimInfo.COLUMN_ICC_ID;
 
     /**
      * TelephonyProvider column name for user SIM_SlOT_INDEX
      * <P>Type: INTEGER (int)</P>
      */
     /** @hide */
-    public static final String SIM_SLOT_INDEX = SimInfo.SIM_SLOT_INDEX;
+    public static final String SIM_SLOT_INDEX = SimInfo.COLUMN_SIM_SLOT_INDEX;
 
     /** SIM is not inserted */
     /** @hide */
@@ -300,7 +301,7 @@
      * Default value is 0.
      */
     /** @hide */
-    public static final String SUBSCRIPTION_TYPE = SimInfo.SUBSCRIPTION_TYPE;
+    public static final String SUBSCRIPTION_TYPE = SimInfo.COLUMN_SUBSCRIPTION_TYPE;
 
     /**
      * TelephonyProvider column name data_enabled_override_rules.
@@ -313,7 +314,8 @@
      *
      * @hide
      */
-    public static final String DATA_ENABLED_OVERRIDE_RULES = SimInfo.DATA_ENABLED_OVERRIDE_RULES;
+    public static final String DATA_ENABLED_OVERRIDE_RULES =
+            SimInfo.COLUMN_DATA_ENABLED_OVERRIDE_RULES;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -362,14 +364,14 @@
      * <P>Type: TEXT (String)</P>
      */
     /** @hide */
-    public static final String DISPLAY_NAME = SimInfo.DISPLAY_NAME;
+    public static final String DISPLAY_NAME = SimInfo.COLUMN_DISPLAY_NAME;
 
     /**
      * TelephonyProvider column name for the service provider name for the SIM.
      * <P>Type: TEXT (String)</P>
      */
     /** @hide */
-    public static final String CARRIER_NAME = SimInfo.CARRIER_NAME;
+    public static final String CARRIER_NAME = SimInfo.COLUMN_CARRIER_NAME;
 
     /**
      * Default name resource
@@ -383,13 +385,13 @@
      *
      * @hide
      */
-    public static final String NAME_SOURCE = SimInfo.NAME_SOURCE;
+    public static final String NAME_SOURCE = SimInfo.COLUMN_NAME_SOURCE;
 
     /**
-     * The name_source is the default, which is from the carrier id.
+     * The name_source is from the carrier id.
      * @hide
      */
-    public static final int NAME_SOURCE_DEFAULT = SimInfo.NAME_SOURCE_DEFAULT;
+    public static final int NAME_SOURCE_CARRIER_ID = SimInfo.NAME_SOURCE_CARRIER_ID;
 
     /**
      * The name_source is from SIM EF_SPN.
@@ -420,7 +422,7 @@
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"NAME_SOURCE_"},
             value = {
-                    NAME_SOURCE_DEFAULT,
+                    NAME_SOURCE_CARRIER_ID,
                     NAME_SOURCE_SIM_SPN,
                     NAME_SOURCE_USER_INPUT,
                     NAME_SOURCE_CARRIER,
@@ -433,21 +435,21 @@
      * <P>Type: INTEGER (int)</P>
      */
     /** @hide */
-    public static final String COLOR = SimInfo.COLOR;
+    public static final String HUE = SimInfo.COLUMN_COLOR;
 
     /**
      * TelephonyProvider column name for the phone number of a SIM.
      * <P>Type: TEXT (String)</P>
      */
     /** @hide */
-    public static final String NUMBER = SimInfo.NUMBER;
+    public static final String NUMBER = SimInfo.COLUMN_NUMBER;
 
     /**
      * TelephonyProvider column name for whether data roaming is enabled.
      * <P>Type: INTEGER (int)</P>
      */
     /** @hide */
-    public static final String DATA_ROAMING = SimInfo.DATA_ROAMING;
+    public static final String DATA_ROAMING = SimInfo.COLUMN_DATA_ROAMING;
 
     /** Indicates that data roaming is enabled for a subscription */
     public static final int DATA_ROAMING_ENABLE = SimInfo.DATA_ROAMING_ENABLE;
@@ -455,63 +457,60 @@
     /** Indicates that data roaming is disabled for a subscription */
     public static final int DATA_ROAMING_DISABLE = SimInfo.DATA_ROAMING_DISABLE;
 
-    /** @hide */
-    public static final int DATA_ROAMING_DEFAULT = SimInfo.DATA_ROAMING_DEFAULT;
-
     /**
      * TelephonyProvider column name for subscription carrier id.
      * @see TelephonyManager#getSimCarrierId()
      * <p>Type: INTEGER (int) </p>
      * @hide
      */
-    public static final String CARRIER_ID = SimInfo.CARRIER_ID;
+    public static final String CARRIER_ID = SimInfo.COLUMN_CARRIER_ID;
 
     /**
      * @hide A comma-separated list of EHPLMNs associated with the subscription
      * <P>Type: TEXT (String)</P>
      */
-    public static final String EHPLMNS = SimInfo.EHPLMNS;
+    public static final String EHPLMNS = SimInfo.COLUMN_EHPLMNS;
 
     /**
      * @hide A comma-separated list of HPLMNs associated with the subscription
      * <P>Type: TEXT (String)</P>
      */
-    public static final String HPLMNS = SimInfo.HPLMNS;
+    public static final String HPLMNS = SimInfo.COLUMN_HPLMNS;
 
     /**
      * TelephonyProvider column name for the MCC associated with a SIM, stored as a string.
      * <P>Type: TEXT (String)</P>
      * @hide
      */
-    public static final String MCC_STRING = SimInfo.MCC_STRING;
+    public static final String MCC_STRING = SimInfo.COLUMN_MCC_STRING;
 
     /**
      * TelephonyProvider column name for the MNC associated with a SIM, stored as a string.
      * <P>Type: TEXT (String)</P>
      * @hide
      */
-    public static final String MNC_STRING = SimInfo.MNC_STRING;
+    public static final String MNC_STRING = SimInfo.COLUMN_MNC_STRING;
 
     /**
      * TelephonyProvider column name for the MCC associated with a SIM.
      * <P>Type: INTEGER (int)</P>
      * @hide
      */
-    public static final String MCC = SimInfo.MCC;
+    public static final String MCC = SimInfo.COLUMN_MCC;
 
     /**
      * TelephonyProvider column name for the MNC associated with a SIM.
      * <P>Type: INTEGER (int)</P>
      * @hide
      */
-    public static final String MNC = SimInfo.MNC;
+    public static final String MNC = SimInfo.COLUMN_MNC;
 
     /**
      * TelephonyProvider column name for the iso country code associated with a SIM.
      * <P>Type: TEXT (String)</P>
      * @hide
      */
-    public static final String ISO_COUNTRY_CODE = SimInfo.ISO_COUNTRY_CODE;
+    public static final String ISO_COUNTRY_CODE = SimInfo.COLUMN_ISO_COUNTRY_CODE;
 
     /**
      * TelephonyProvider column name for whether a subscription is embedded (that is, present on an
@@ -519,7 +518,7 @@
      * <p>Type: INTEGER (int), 1 for embedded or 0 for non-embedded.
      * @hide
      */
-    public static final String IS_EMBEDDED = SimInfo.IS_EMBEDDED;
+    public static final String IS_EMBEDDED = SimInfo.COLUMN_IS_EMBEDDED;
 
     /**
      * TelephonyProvider column name for SIM card identifier. For UICC card it is the ICCID of the
@@ -527,7 +526,7 @@
      * <P>Type: TEXT (String)</P>
      * @hide
      */
-    public static final String CARD_ID = SimInfo.CARD_ID;
+    public static final String CARD_ID = SimInfo.COLUMN_CARD_ID;
 
     /**
      * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from
@@ -535,7 +534,7 @@
      * <p>TYPE: BLOB
      * @hide
      */
-    public static final String ACCESS_RULES = SimInfo.ACCESS_RULES;
+    public static final String ACCESS_RULES = SimInfo.COLUMN_ACCESS_RULES;
 
     /**
      * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from
@@ -545,7 +544,7 @@
      * @hide
      */
     public static final String ACCESS_RULES_FROM_CARRIER_CONFIGS =
-            SimInfo.ACCESS_RULES_FROM_CARRIER_CONFIGS;
+            SimInfo.COLUMN_ACCESS_RULES_FROM_CARRIER_CONFIGS;
 
     /**
      * TelephonyProvider column name identifying whether an embedded subscription is on a removable
@@ -555,79 +554,82 @@
      * <p>TYPE: INTEGER (int), 1 for removable or 0 for non-removable.
      * @hide
      */
-    public static final String IS_REMOVABLE = SimInfo.IS_REMOVABLE;
+    public static final String IS_REMOVABLE = SimInfo.COLUMN_IS_REMOVABLE;
 
     /**
      *  TelephonyProvider column name for extreme threat in CB settings
      * @hide
      */
-    public static final String CB_EXTREME_THREAT_ALERT = SimInfo.CB_EXTREME_THREAT_ALERT;
+    public static final String CB_EXTREME_THREAT_ALERT =
+            SimInfo.COLUMN_CB_EXTREME_THREAT_ALERT;
 
     /**
      * TelephonyProvider column name for severe threat in CB settings
      *@hide
      */
-    public static final String CB_SEVERE_THREAT_ALERT = SimInfo.CB_SEVERE_THREAT_ALERT;
+    public static final String CB_SEVERE_THREAT_ALERT = SimInfo.COLUMN_CB_SEVERE_THREAT_ALERT;
 
     /**
      * TelephonyProvider column name for amber alert in CB settings
      *@hide
      */
-    public static final String CB_AMBER_ALERT = SimInfo.CB_AMBER_ALERT;
+    public static final String CB_AMBER_ALERT = SimInfo.COLUMN_CB_AMBER_ALERT;
 
     /**
      * TelephonyProvider column name for emergency alert in CB settings
      *@hide
      */
-    public static final String CB_EMERGENCY_ALERT = SimInfo.CB_EMERGENCY_ALERT;
+    public static final String CB_EMERGENCY_ALERT = SimInfo.COLUMN_CB_EMERGENCY_ALERT;
 
     /**
      * TelephonyProvider column name for alert sound duration in CB settings
      *@hide
      */
-    public static final String CB_ALERT_SOUND_DURATION = SimInfo.CB_ALERT_SOUND_DURATION;
+    public static final String CB_ALERT_SOUND_DURATION =
+            SimInfo.COLUMN_CB_ALERT_SOUND_DURATION;
 
     /**
      * TelephonyProvider column name for alert reminder interval in CB settings
      *@hide
      */
-    public static final String CB_ALERT_REMINDER_INTERVAL = SimInfo.CB_ALERT_REMINDER_INTERVAL;
+    public static final String CB_ALERT_REMINDER_INTERVAL =
+            SimInfo.COLUMN_CB_ALERT_REMINDER_INTERVAL;
 
     /**
      * TelephonyProvider column name for enabling vibrate in CB settings
      *@hide
      */
-    public static final String CB_ALERT_VIBRATE = SimInfo.CB_ALERT_VIBRATE;
+    public static final String CB_ALERT_VIBRATE = SimInfo.COLUMN_CB_ALERT_VIBRATE;
 
     /**
      * TelephonyProvider column name for enabling alert speech in CB settings
      *@hide
      */
-    public static final String CB_ALERT_SPEECH = SimInfo.CB_ALERT_SPEECH;
+    public static final String CB_ALERT_SPEECH = SimInfo.COLUMN_CB_ALERT_SPEECH;
 
     /**
      * TelephonyProvider column name for ETWS test alert in CB settings
      *@hide
      */
-    public static final String CB_ETWS_TEST_ALERT = SimInfo.CB_ETWS_TEST_ALERT;
+    public static final String CB_ETWS_TEST_ALERT = SimInfo.COLUMN_CB_ETWS_TEST_ALERT;
 
     /**
      * TelephonyProvider column name for enable channel50 alert in CB settings
      *@hide
      */
-    public static final String CB_CHANNEL_50_ALERT = SimInfo.CB_CHANNEL_50_ALERT;
+    public static final String CB_CHANNEL_50_ALERT = SimInfo.COLUMN_CB_CHANNEL_50_ALERT;
 
     /**
      * TelephonyProvider column name for CMAS test alert in CB settings
      *@hide
      */
-    public static final String CB_CMAS_TEST_ALERT = SimInfo.CB_CMAS_TEST_ALERT;
+    public static final String CB_CMAS_TEST_ALERT = SimInfo.COLUMN_CB_CMAS_TEST_ALERT;
 
     /**
      * TelephonyProvider column name for Opt out dialog in CB settings
      *@hide
      */
-    public static final String CB_OPT_OUT_DIALOG = SimInfo.CB_OPT_OUT_DIALOG;
+    public static final String CB_OPT_OUT_DIALOG = SimInfo.COLUMN_CB_OPT_OUT_DIALOG;
 
     /**
      * TelephonyProvider column name for enable Volte.
@@ -636,44 +638,45 @@
      * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
      *@hide
      */
-    public static final String ENHANCED_4G_MODE_ENABLED = SimInfo.ENHANCED_4G_MODE_ENABLED;
+    public static final String ENHANCED_4G_MODE_ENABLED =
+            SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED;
 
     /**
      * TelephonyProvider column name for enable VT (Video Telephony over IMS)
      *@hide
      */
-    public static final String VT_IMS_ENABLED = SimInfo.VT_IMS_ENABLED;
+    public static final String VT_IMS_ENABLED = SimInfo.COLUMN_VT_IMS_ENABLED;
 
     /**
      * TelephonyProvider column name for enable Wifi calling
      *@hide
      */
-    public static final String WFC_IMS_ENABLED = SimInfo.WFC_IMS_ENABLED;
+    public static final String WFC_IMS_ENABLED = SimInfo.COLUMN_WFC_IMS_ENABLED;
 
     /**
      * TelephonyProvider column name for Wifi calling mode
      *@hide
      */
-    public static final String WFC_IMS_MODE = SimInfo.WFC_IMS_MODE;
+    public static final String WFC_IMS_MODE = SimInfo.COLUMN_WFC_IMS_MODE;
 
     /**
      * TelephonyProvider column name for Wifi calling mode in roaming
      *@hide
      */
-    public static final String WFC_IMS_ROAMING_MODE = SimInfo.WFC_IMS_ROAMING_MODE;
+    public static final String WFC_IMS_ROAMING_MODE = SimInfo.COLUMN_WFC_IMS_ROAMING_MODE;
 
     /**
      * TelephonyProvider column name for enable Wifi calling in roaming
      *@hide
      */
-    public static final String WFC_IMS_ROAMING_ENABLED = SimInfo.WFC_IMS_ROAMING_ENABLED;
+    public static final String WFC_IMS_ROAMING_ENABLED = SimInfo.COLUMN_WFC_IMS_ROAMING_ENABLED;
 
     /**
      * Determines if the user has enabled IMS RCS User Capability Exchange (UCE) for this
      * subscription.
      * @hide
      */
-    public static final String IMS_RCS_UCE_ENABLED = SimInfo.IMS_RCS_UCE_ENABLED;
+    public static final String IMS_RCS_UCE_ENABLED = SimInfo.COLUMN_IMS_RCS_UCE_ENABLED;
 
     /**
      * TelephonyProvider column name for whether a subscription is opportunistic, that is,
@@ -682,7 +685,7 @@
      * <p>Type: INTEGER (int), 1 for opportunistic or 0 for non-opportunistic.
      * @hide
      */
-    public static final String IS_OPPORTUNISTIC = SimInfo.IS_OPPORTUNISTIC;
+    public static final String IS_OPPORTUNISTIC = SimInfo.COLUMN_IS_OPPORTUNISTIC;
 
     /**
      * TelephonyProvider column name for group ID. Subscriptions with same group ID
@@ -691,7 +694,7 @@
      *
      * @hide
      */
-    public static final String GROUP_UUID = SimInfo.GROUP_UUID;
+    public static final String GROUP_UUID = SimInfo.COLUMN_GROUP_UUID;
 
     /**
      * TelephonyProvider column name for group owner. It's the package name who created
@@ -699,7 +702,7 @@
      *
      * @hide
      */
-    public static final String GROUP_OWNER = SimInfo.GROUP_OWNER;
+    public static final String GROUP_OWNER = SimInfo.COLUMN_GROUP_OWNER;
 
     /**
      * TelephonyProvider column name for the profile class of a subscription
@@ -707,7 +710,7 @@
      * <P>Type: INTEGER (int)</P>
      * @hide
      */
-    public static final String PROFILE_CLASS = SimInfo.PROFILE_CLASS;
+    public static final String PROFILE_CLASS = SimInfo.COLUMN_PROFILE_CLASS;
 
     /**
      * Profile class of the subscription
@@ -719,7 +722,6 @@
             SimInfo.PROFILE_CLASS_PROVISIONING,
             SimInfo.PROFILE_CLASS_OPERATIONAL,
             SimInfo.PROFILE_CLASS_UNSET,
-            SimInfo.PROFILE_CLASS_DEFAULT
     })
     public @interface ProfileClass {}
 
@@ -765,7 +767,8 @@
      * @hide
      */
     @SystemApi
-    public static final int PROFILE_CLASS_DEFAULT = SimInfo.PROFILE_CLASS_DEFAULT;
+    @Deprecated
+    public static final int PROFILE_CLASS_DEFAULT = SimInfo.PROFILE_CLASS_UNSET;
 
     /**
      * IMSI (International Mobile Subscriber Identity).
@@ -773,19 +776,19 @@
      * @hide
      */
     //TODO: add @SystemApi
-    public static final String IMSI = SimInfo.IMSI;
+    public static final String IMSI = SimInfo.COLUMN_IMSI;
 
     /**
      * Whether uicc applications is set to be enabled or disabled. By default it's enabled.
      * @hide
      */
-    public static final String UICC_APPLICATIONS_ENABLED = SimInfo.UICC_APPLICATIONS_ENABLED;
+    public static final String UICC_APPLICATIONS_ENABLED = SimInfo.COLUMN_UICC_APPLICATIONS_ENABLED;
 
     /**
      * Indicate which network type is allowed. By default it's enabled.
      * @hide
      */
-    public static final String ALLOWED_NETWORK_TYPES = SimInfo.ALLOWED_NETWORK_TYPES;
+    public static final String ALLOWED_NETWORK_TYPES = SimInfo.COLUMN_ALLOWED_NETWORK_TYPES;
 
     /**
      * Broadcast Action: The user has changed one of the default subs related to
@@ -2680,8 +2683,8 @@
      * @hide
      */
     @SystemApi
-    public boolean canManageSubscription(@Nullable SubscriptionInfo info,
-            @Nullable String packageName) {
+    public boolean canManageSubscription(@NonNull SubscriptionInfo info,
+            @NonNull String packageName) {
         if (info == null || info.getAllAccessRules() == null || packageName == null) {
             return false;
         }
@@ -3186,13 +3189,13 @@
      *
      * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
      *
-     * @param enabled whether uicc applications are enabled or disabled.
      * @param subscriptionId which subscription to operate on.
+     * @param enabled whether uicc applications are enabled or disabled.
      * @hide
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
-    public void setUiccApplicationsEnabled(boolean enabled, int subscriptionId) {
+    public void setUiccApplicationsEnabled(int subscriptionId, boolean enabled) {
         if (VDBG) {
             logd("setUiccApplicationsEnabled subId= " + subscriptionId + " enable " + enabled);
         }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c2b4ec9..c37262c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -53,6 +53,7 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
@@ -69,13 +70,13 @@
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telephony.Annotation.ApnType;
-import android.telephony.Annotation.CallForwardingReason;
 import android.telephony.Annotation.CallState;
-import android.telephony.Annotation.CallWaitingStatus;
+import android.telephony.Annotation.CarrierPrivilegeStatus;
 import android.telephony.Annotation.NetworkType;
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SimActivationState;
 import android.telephony.Annotation.UiccAppType;
+import android.telephony.CallForwardingInfo.CallForwardingReason;
 import android.telephony.VisualVoicemailService.VisualVoicemailTask;
 import android.telephony.data.ApnSetting;
 import android.telephony.data.ApnSetting.MvnoType;
@@ -1030,7 +1031,7 @@
      * or that all steps during multi-SIM change are done. To know those information you still need
      * to listen to SIM_STATE changes or active subscription changes.
      *
-     * See extra of {@link #EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED} for updated value.
+     * See extra of {@link #EXTRA_ACTIVE_SIM_SUPPORTED_COUNT} for updated value.
      */
     public static final String ACTION_MULTI_SIM_CONFIG_CHANGED =
             "android.telephony.action.MULTI_SIM_CONFIG_CHANGED";
@@ -1040,6 +1041,8 @@
      * The number of active SIM supported by current multi-SIM config. It's not related to how many
      * SIM/subscriptions are currently active.
      *
+     * Same value will be returned by {@link #getActiveModemCount()}.
+     *
      * For single SIM mode, it's 1.
      * For DSDS or DSDA mode, it's 2.
      * For triple-SIM mode, it's 3.
@@ -1048,8 +1051,8 @@
      *
      * type: integer
      */
-    public static final String EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED =
-            "android.telephony.extra.NUM_OF_ACTIVE_SIM_SUPPORTED";
+    public static final String EXTRA_ACTIVE_SIM_SUPPORTED_COUNT =
+            "android.telephony.extra.ACTIVE_SIM_SUPPORTED_COUNT";
 
     /**
      * @hide
@@ -2300,7 +2303,12 @@
     public static final int PHONE_TYPE_CDMA = PhoneConstants.PHONE_TYPE_CDMA;
     /** Phone is via SIP. */
     public static final int PHONE_TYPE_SIP = PhoneConstants.PHONE_TYPE_SIP;
-    /** Phone is via IMS. */
+
+    /**
+     * Phone is via IMS.
+     *
+     * @hide
+     */
     public static final int PHONE_TYPE_IMS = PhoneConstants.PHONE_TYPE_IMS;
 
     /**
@@ -2308,7 +2316,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int PHONE_TYPE_THIRD_PARTY = PhoneConstants.PHONE_TYPE_THIRD_PARTY;
 
     /**
@@ -2705,39 +2712,22 @@
     /**
      * Returns the ISO-3166 country code equivalent of the MCC (Mobile Country Code) of the current
      * registered operator or the cell nearby, if available.
-     * <p>
-     * The ISO-3166 country code is provided in lowercase 2 character format.
-     * <p>
-     * Note: In multi-sim, this returns a shared emergency network country iso from other
-     * subscription if the subscription used to create the TelephonyManager doesn't camp on
-     * a network due to some reason (e.g. pin/puk locked), or sim is absent in the corresponding
-     * slot.
+     *
      * Note: Result may be unreliable on CDMA networks (use {@link #getPhoneType()} to determine
      * if on a CDMA network).
      * <p>
      * @return the lowercase 2 character ISO-3166 country code, or empty string if not available.
      */
     public String getNetworkCountryIso() {
-        try {
-            ITelephony telephony = getITelephony();
-            if (telephony == null) return "";
-            return telephony.getNetworkCountryIsoForPhone(getPhoneId(),
-                    null /* no permission check */, null);
-        } catch (RemoteException ex) {
-            return "";
-        }
+        return getNetworkCountryIso(getSlotIndex());
     }
 
     /**
      * Returns the ISO-3166 country code equivalent of the MCC (Mobile Country Code) of the current
-     * registered operator or the cell nearby, if available.
-     * <p>
-     * The ISO-3166 country code is provided in lowercase 2 character format.
-     * <p>
-     * Note: In multi-sim, this returns a shared emergency network country iso from other
-     * subscription if the subscription used to create the TelephonyManager doesn't camp on
-     * a network due to some reason (e.g. pin/puk locked), or sim is absent in the corresponding
-     * slot.
+     * registered operator or the cell nearby, if available. This is same as
+     * {@link #getNetworkCountryIso()} but allowing specifying the SIM slot index. This is used for
+     * accessing network country info from the SIM slot that does not have SIM inserted.
+     *
      * Note: Result may be unreliable on CDMA networks (use {@link #getPhoneType()} to determine
      * if on a CDMA network).
      * <p>
@@ -2748,27 +2738,34 @@
      *
      * @throws IllegalArgumentException when the slotIndex is invalid.
      *
-     * {@hide}
      */
-    @SystemApi
-    @TestApi
     @NonNull
-    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public String getNetworkCountryIso(int slotIndex) {
         try {
-            if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
+            if (slotIndex != SubscriptionManager.DEFAULT_SIM_SLOT_INDEX
+                    && !SubscriptionManager.isValidSlotIndex(slotIndex)) {
                 throw new IllegalArgumentException("invalid slot index " + slotIndex);
             }
 
             ITelephony telephony = getITelephony();
             if (telephony == null) return "";
-            return telephony.getNetworkCountryIsoForPhone(slotIndex, getOpPackageName(),
-                    getFeatureId());
+            return telephony.getNetworkCountryIsoForPhone(slotIndex);
         } catch (RemoteException ex) {
             return "";
         }
     }
 
+    /**
+     * @hide
+     * @deprecated Use {@link #getNetworkCountryIso(int)} instead.
+     */
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
+            publicAlternatives = "Use {@link #getNetworkCountryIso(int)} instead.")
+    public String getNetworkCountryIsoForPhone(int phoneId) {
+        return getNetworkCountryIso(phoneId);
+    }
+
     /*
      * When adding a network type to the list below, make sure to add the correct icon to
      * MobileSignalController.mapIconSets() as well as NETWORK_TYPES
@@ -3013,64 +3010,6 @@
     }
 
     /**
-     * Network Class Definitions.
-     * Do not change this order, it is used for sorting during emergency calling in
-     * {@link TelephonyConnectionService#getFirstPhoneForEmergencyCall()}. Any newer technologies
-     * should be added after the current definitions.
-     */
-    /** Unknown network class. {@hide} */
-    public static final int NETWORK_CLASS_UNKNOWN = 0;
-    /** Class of broadly defined "2G" networks. {@hide} */
-    @UnsupportedAppUsage
-    public static final int NETWORK_CLASS_2_G = 1;
-    /** Class of broadly defined "3G" networks. {@hide} */
-    @UnsupportedAppUsage
-    public static final int NETWORK_CLASS_3_G = 2;
-    /** Class of broadly defined "4G" networks. {@hide} */
-    @UnsupportedAppUsage
-    public static final int NETWORK_CLASS_4_G = 3;
-    /** Class of broadly defined "5G" networks. {@hide} */
-    public static final int NETWORK_CLASS_5_G = 4;
-
-    /**
-     * Return general class of network type, such as "3G" or "4G". In cases
-     * where classification is contentious, this method is conservative.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static int getNetworkClass(int networkType) {
-        switch (networkType) {
-            case NETWORK_TYPE_GPRS:
-            case NETWORK_TYPE_GSM:
-            case NETWORK_TYPE_EDGE:
-            case NETWORK_TYPE_CDMA:
-            case NETWORK_TYPE_1xRTT:
-            case NETWORK_TYPE_IDEN:
-                return NETWORK_CLASS_2_G;
-            case NETWORK_TYPE_UMTS:
-            case NETWORK_TYPE_EVDO_0:
-            case NETWORK_TYPE_EVDO_A:
-            case NETWORK_TYPE_HSDPA:
-            case NETWORK_TYPE_HSUPA:
-            case NETWORK_TYPE_HSPA:
-            case NETWORK_TYPE_EVDO_B:
-            case NETWORK_TYPE_EHRPD:
-            case NETWORK_TYPE_HSPAP:
-            case NETWORK_TYPE_TD_SCDMA:
-                return NETWORK_CLASS_3_G;
-            case NETWORK_TYPE_LTE:
-            case NETWORK_TYPE_IWLAN:
-            case NETWORK_TYPE_LTE_CA:
-                return NETWORK_CLASS_4_G;
-            case NETWORK_TYPE_NR:
-                return NETWORK_CLASS_5_G;
-            default:
-                return NETWORK_CLASS_UNKNOWN;
-        }
-    }
-
-    /**
      * Returns a string representation of the radio technology (network type)
      * currently in use on the device.
      * @return the name of the radio technology
@@ -4877,7 +4816,7 @@
             ITelephony telephony = getITelephony();
             if (telephony != null) {
                 telephony.sendVisualVoicemailSmsForSubscriber(
-                        mContext.getOpPackageName(), subId, number, port, text, sentIntent);
+                        mContext.getOpPackageName(), null, subId, number, port, text, sentIntent);
             }
         } catch (RemoteException ex) {
         }
@@ -7935,21 +7874,19 @@
      * app has carrier privileges (see {@link #hasCarrierPrivileges}).
      *
      * @param operatorNumeric the PLMN ID of the network to select.
-     * @param ran the initial suggested radio access network type.
-     *         If registration fails, the RAN is not available after, the RAN is not within the
-     *         network types specified by {@link #setPreferredNetworkTypeBitmask}, or the value is
-     *         {@link AccessNetworkConstants.AccessNetworkType#UNKNOWN}, modem will select
-     *         the next best RAN for network registration.
      * @param persistSelection whether the selection will persist until reboot.
      *         If true, only allows attaching to the selected PLMN until reboot; otherwise,
      *         attach to the chosen PLMN and resume normal network selection next time.
+     * @param ran the initial suggested radio access network type.
+     *         If registration fails, the RAN is not available after, the RAN is not within the
+     *         network types specified by the preferred network types, or the value is
+     *         {@link AccessNetworkConstants.AccessNetworkType#UNKNOWN}, modem will select
+     *         the next best RAN for network registration.
      * @return {@code true} on success; {@code false} on any failure.
-     * @hide
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-    @SystemApi
     public boolean setNetworkSelectionModeManual(@NonNull String operatorNumeric,
-            @AccessNetworkConstants.RadioAccessNetworkType int ran, boolean persistSelection) {
+            boolean persistSelection, @AccessNetworkConstants.RadioAccessNetworkType int ran) {
         return setNetworkSelectionModeManual(new OperatorInfo("" /* operatorAlphaLong */,
                 "" /* operatorAlphaShort */, operatorNumeric, ran), persistSelection);
     }
@@ -8691,7 +8628,6 @@
      *
      * @hide
      */
-    @SystemApi
     @Nullable
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public PinResult supplyPinReportPinResult(@NonNull String pin) {
@@ -8716,7 +8652,6 @@
      *
      * @hide
      */
-    @SystemApi
     @Nullable
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public PinResult supplyPukReportPinResult(@NonNull String puk, @NonNull String pin) {
@@ -8908,7 +8843,10 @@
     }
 
     /**
-     * Shut down all the live radios over all the slot index.
+     * Shut down all the live radios over all the slot indexes.
+     *
+     * <p>To know when the radio has completed powering off, use
+     * {@link PhoneStateListener#LISTEN_SERVICE_STATE LISTEN_SERVICE_STATE}.
      *
      * @hide
      */
@@ -8921,7 +8859,8 @@
                 telephony.shutdownMobileRadios();
             }
         } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#shutdownMobileRadios", e);
+            Log.e(TAG, "Error calling ITelephony#shutdownAllRadios", e);
+            e.rethrowAsRuntimeException();
         }
     }
 
@@ -8940,7 +8879,8 @@
                 return telephony.needMobileRadioShutdown();
             }
         } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#needMobileRadioShutdown", e);
+            Log.e(TAG, "Error calling ITelephony#isAnyRadioPoweredOn", e);
+            e.rethrowAsRuntimeException();
         }
         return false;
     }
@@ -9170,7 +9110,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public @CdmaRoamingMode int getCdmaRoamingMode() {
         int mode = CDMA_ROAMING_MODE_RADIO_DEFAULT;
@@ -9199,7 +9138,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public boolean setCdmaRoamingMode(@CdmaRoamingMode int mode) {
         try {
@@ -9225,19 +9163,16 @@
     /** Used for CDMA subscription mode, it'll be UNKNOWN if there is no Subscription source.
      * @hide
      */
-    @SystemApi
     public static final int CDMA_SUBSCRIPTION_UNKNOWN  = -1;
 
     /** Used for CDMA subscription mode: RUIM/SIM (default)
      * @hide
      */
-    @SystemApi
     public static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0;
 
     /** Used for CDMA subscription mode: NV -> non-volatile memory
      * @hide
      */
-    @SystemApi
     public static final int CDMA_SUBSCRIPTION_NV       = 1;
 
     /** @hide */
@@ -9256,7 +9191,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public boolean setCdmaSubscriptionMode(@CdmaSubscription int mode) {
         try {
@@ -9813,32 +9747,12 @@
     }
 
     /**
-     * Get baseband version for the default phone using the legacy approach.
-     * This change was added in P, to ensure backward compatiblity.
-     *
-     * @return baseband version.
-     * @hide
-     */
-    private String getBasebandVersionLegacy(int phoneId) {
-        if (SubscriptionManager.isValidPhoneId(phoneId)) {
-            String prop = "gsm.version.baseband"
-                    + ((phoneId == 0) ? "" : Integer.toString(phoneId));
-            return SystemProperties.get(prop);
-        }
-        return null;
-    }
-
-    /**
      * Get baseband version by phone id.
      *
      * @return baseband version.
      * @hide
      */
     public String getBasebandVersionForPhone(int phoneId) {
-        String version = getBasebandVersionLegacy(phoneId);
-        if (version != null && !version.isEmpty()) {
-            setBasebandVersionForPhone(phoneId, version);
-        }
         return getTelephonyProperty(phoneId, TelephonyProperties.baseband_version(), "");
     }
 
@@ -11074,7 +10988,6 @@
      * @param isEnabled {@code true} for enabling; {@code false} for disabling.
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public void setAlwaysReportSignalStrength(boolean isEnabled) {
         try {
@@ -11109,21 +11022,21 @@
     }
 
     /**
-     * Checks whether cellular data connection is enabled in the device.
+     * Checks whether cellular data connection is allowed in the device.
      *
-     * Whether cellular data connection is enabled, meaning upon request whether will try to setup
-     * metered data connection considering all factors below:
-     * 1) User turned on data setting {@link #isDataEnabled}.
-     * 2) Carrier allows data to be on.
-     * 3) Network policy.
-     * And possibly others.
-     *
-     * @return {@code true} if the overall data connection is capable; {@code false} if not.
+     * <p>Whether cellular data connection is allowed considers all factors below:
+     * <UL>
+     *   <LI>User turned on data setting {@link #isDataEnabled}.</LI>
+     *   <LI>Carrier allows data to be on.</LI>
+     *   <LI>Network policy.</LI>
+     *   <LI>And possibly others.</LI>
+     * </UL>
+     * @return {@code true} if the overall data connection is allowed; {@code false} if not.
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public boolean isDataConnectionEnabled() {
+    public boolean isDataConnectionAllowed() {
         boolean retVal = false;
         try {
             int subId = getSubId(SubscriptionManager.getDefaultDataSubscriptionId());
@@ -11131,8 +11044,7 @@
             if (telephony != null)
                 retVal = telephony.isDataEnabled(subId);
         } catch (RemoteException e) {
-            Log.e(TAG, "Error isDataConnectionEnabled", e);
-        } catch (NullPointerException e) {
+            Log.e(TAG, "Error isDataConnectionAllowed", e);
         }
         return retVal;
     }
@@ -11502,6 +11414,55 @@
     @SystemApi
     public static final long NETWORK_TYPE_BITMASK_IWLAN = (1 << (NETWORK_TYPE_IWLAN -1));
 
+    /** @hide */
+    public static final long NETWORK_CLASS_BITMASK_2G = NETWORK_TYPE_BITMASK_GSM
+                | NETWORK_TYPE_BITMASK_GPRS
+                | NETWORK_TYPE_BITMASK_EDGE
+                | NETWORK_TYPE_BITMASK_CDMA
+                | NETWORK_TYPE_BITMASK_1xRTT;
+
+    /** @hide */
+    public static final long NETWORK_CLASS_BITMASK_3G = NETWORK_TYPE_BITMASK_EVDO_0
+            | NETWORK_TYPE_BITMASK_EVDO_A
+            | NETWORK_TYPE_BITMASK_EVDO_B
+            | NETWORK_TYPE_BITMASK_EHRPD
+            | NETWORK_TYPE_BITMASK_HSUPA
+            | NETWORK_TYPE_BITMASK_HSDPA
+            | NETWORK_TYPE_BITMASK_HSPA
+            | NETWORK_TYPE_BITMASK_HSPAP
+            | NETWORK_TYPE_BITMASK_UMTS
+            | NETWORK_TYPE_BITMASK_TD_SCDMA;
+
+    /** @hide */
+    public static final long NETWORK_CLASS_BITMASK_4G = NETWORK_TYPE_BITMASK_LTE
+            | NETWORK_TYPE_BITMASK_LTE_CA
+            | NETWORK_TYPE_BITMASK_IWLAN;
+
+    /** @hide */
+    public static final long NETWORK_CLASS_BITMASK_5G = NETWORK_TYPE_BITMASK_NR;
+
+    /** @hide */
+    public static final long NETWORK_STANDARDS_FAMILY_BITMASK_3GPP = NETWORK_TYPE_BITMASK_GSM
+            | NETWORK_TYPE_BITMASK_GPRS
+            | NETWORK_TYPE_BITMASK_EDGE
+            | NETWORK_TYPE_BITMASK_HSUPA
+            | NETWORK_TYPE_BITMASK_HSDPA
+            | NETWORK_TYPE_BITMASK_HSPA
+            | NETWORK_TYPE_BITMASK_HSPAP
+            | NETWORK_TYPE_BITMASK_UMTS
+            | NETWORK_TYPE_BITMASK_TD_SCDMA
+            | NETWORK_TYPE_BITMASK_LTE
+            | NETWORK_TYPE_BITMASK_LTE_CA
+            | NETWORK_TYPE_BITMASK_NR;
+
+    /** @hide */
+    public static final long NETWORK_STANDARDS_FAMILY_BITMASK_3GPP2 = NETWORK_TYPE_BITMASK_CDMA
+            | NETWORK_TYPE_BITMASK_1xRTT
+            | NETWORK_TYPE_BITMASK_EVDO_0
+            | NETWORK_TYPE_BITMASK_EVDO_A
+            | NETWORK_TYPE_BITMASK_EVDO_B
+            | NETWORK_TYPE_BITMASK_EHRPD;
+
     /**
      * @return Modem supported radio access family bitmask
      *
@@ -11563,11 +11524,9 @@
     }
 
     /**
-     * Override the file path for testing OTA emergency number database in a file partition.
+     * Override the file path for OTA emergency number database in a file partition.
      *
-     * @param otaFilePath The test OTA emergency number database file path;
-     *                    if "RESET", recover the original database file partition.
-     *                    Format: <root file folder>@<file path>
+     * @param otaParcelFileDescriptor parcelable file descriptor for OTA emergency number database.
      *
      * <p> Requires permission:
      * {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION}
@@ -11577,16 +11536,42 @@
     @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
     @SystemApi
     @TestApi
-    public void updateTestOtaEmergencyNumberDbFilePath(@NonNull String otaFilePath) {
+    public void updateOtaEmergencyNumberDbFilePath(
+            @NonNull ParcelFileDescriptor otaParcelFileDescriptor) {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                telephony.updateTestOtaEmergencyNumberDbFilePath(otaFilePath);
+                telephony.updateOtaEmergencyNumberDbFilePath(otaParcelFileDescriptor);
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
         } catch (RemoteException ex) {
-            Log.e(TAG, "notifyOtaEmergencyNumberDatabaseInstalled RemoteException", ex);
+            Log.e(TAG, "updateOtaEmergencyNumberDbFilePath RemoteException", ex);
+            ex.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Reset the file path to default for OTA emergency number database in a file partition.
+     *
+     * <p> Requires permission:
+     * {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION}
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
+    @SystemApi
+    @TestApi
+    public void resetOtaEmergencyNumberDbFilePath() {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                telephony.resetOtaEmergencyNumberDbFilePath();
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            Log.e(TAG, "resetOtaEmergencyNumberDbFilePath RemoteException", ex);
             ex.rethrowAsRuntimeException();
         }
     }
@@ -11790,7 +11775,7 @@
     }
 
     /**
-     * A test API to return the emergency number db version.
+     * Returns the emergency number database version.
      *
      * <p>Requires Permission:
      *   {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE}
@@ -11799,6 +11784,7 @@
      */
     @TestApi
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public int getEmergencyNumberDbVersion() {
         try {
             ITelephony telephony = getITelephony();
@@ -12171,6 +12157,17 @@
             "android.telephony.extra.NETWORK_COUNTRY";
 
     /**
+     * The extra used with an {@link #ACTION_NETWORK_COUNTRY_CHANGED} to specify the
+     * last known the country code in ISO-3166-1 alpha-2 format.
+     * <p class="note">
+     * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_LAST_KNOWN_NETWORK_COUNTRY =
+            "android.telephony.extra.LAST_KNOWN_NETWORK_COUNTRY";
+
+    /**
      * Indicate if the user is allowed to use multiple SIM cards at the same time to register
      * on the network (e.g. Dual Standby or Dual Active) when the device supports it, or if the
      * usage is restricted. This API is used to prevent usage of multiple SIM card, based on
@@ -12342,7 +12339,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public int getCarrierPrivilegeStatus(int uid) {
+    public @CarrierPrivilegeStatus int getCarrierPrivilegeStatus(int uid) {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
@@ -12588,7 +12585,6 @@
     }
 
     /**
-<<<<<<< HEAD
      * Gets the voice call forwarding info {@link CallForwardingInfo}, given the call forward
      * reason.
      *
@@ -12608,7 +12604,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @NonNull
     public CallForwardingInfo getCallForwarding(@CallForwardingReason int callForwardingReason) {
@@ -12655,7 +12650,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public boolean setCallForwarding(@NonNull CallForwardingInfo callForwardingInfo) {
         if (callForwardingInfo == null) {
@@ -12696,7 +12690,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int CALL_WAITING_STATUS_ACTIVE = 1;
 
     /**
@@ -12704,7 +12697,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int CALL_WAITING_STATUS_INACTIVE = 2;
 
     /**
@@ -12712,7 +12704,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3;
 
     /**
@@ -12720,10 +12711,24 @@
      *
      * @hide
      */
-    @SystemApi
     public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4;
 
     /**
+     * Call waiting function status
+     *
+     * @hide
+     */
+    @IntDef(prefix = { "CALL_WAITING_STATUS_" }, value = {
+        CALL_WAITING_STATUS_ACTIVE,
+        CALL_WAITING_STATUS_INACTIVE,
+        CALL_WAITING_STATUS_NOT_SUPPORTED,
+        CALL_WAITING_STATUS_UNKNOWN_ERROR
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CallWaitingStatus {
+    }
+
+    /**
      * Gets the status of voice call waiting function. Call waiting function enables the waiting
      * for the incoming call when it reaches the user who is busy to make another call and allows
      * users to decide whether to switch to the incoming call.
@@ -12731,7 +12736,6 @@
      * @return the status of call waiting function.
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public @CallWaitingStatus int getCallWaitingStatus() {
         try {
@@ -12757,7 +12761,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public boolean setCallWaitingStatus(boolean isEnable) {
         try {
@@ -12788,7 +12791,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public boolean setDataAllowedDuringVoiceCall(boolean allow) {
         try {
@@ -12817,7 +12819,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public boolean isDataAllowedInVoiceCall() {
         try {
@@ -12864,7 +12865,6 @@
      * The IccLock state or password was changed successfully.
      * @hide
      */
-    @SystemApi
     public static final int CHANGE_ICC_LOCK_SUCCESS = Integer.MAX_VALUE;
 
     /**
@@ -12877,7 +12877,6 @@
      *
      * @hide
      */
-    @SystemApi
     @WorkerThread
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public boolean isIccLockEnabled() {
@@ -12914,7 +12913,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public int setIccLockEnabled(boolean enabled, @NonNull String password) {
         checkNotNull(password, "setIccLockEnabled password can't be null.");
@@ -12948,7 +12946,6 @@
      *
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public int changeIccLockPassword(@NonNull String oldPassword, @NonNull String newPassword) {
         checkNotNull(oldPassword, "changeIccLockPassword oldPassword can't be null.");
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 6e630e3..158ada9 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -18,7 +18,6 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.content.ContentValues;
 import android.database.Cursor;
 import android.hardware.radio.V1_5.ApnTypes;
@@ -125,6 +124,15 @@
     /** Authentication type for PAP or CHAP. */
     public static final int AUTH_TYPE_PAP_OR_CHAP = 3;
 
+    /** @hide */
+    @IntDef({
+            Telephony.Carriers.SKIP_464XLAT_DEFAULT,
+            Telephony.Carriers.SKIP_464XLAT_DISABLE,
+            Telephony.Carriers.SKIP_464XLAT_ENABLE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Skip464XlatStatus {}
+
     /**
      * APN types for data connections.  These are usage categories for an APN
      * entry.  One APN entry may support multiple APN types, eg, a single APN
@@ -138,7 +146,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String TYPE_ALL_STRING = "*";
 
     /**
@@ -146,7 +153,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String TYPE_DEFAULT_STRING = "default";
 
 
@@ -155,7 +161,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String TYPE_MMS_STRING = "mms";
 
 
@@ -164,7 +169,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String TYPE_SUPL_STRING = "supl";
 
     /**
@@ -172,7 +176,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String TYPE_DUN_STRING = "dun";
 
     /**
@@ -180,7 +183,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String TYPE_HIPRI_STRING = "hipri";
 
     /**
@@ -188,7 +190,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String TYPE_FOTA_STRING = "fota";
 
     /**
@@ -196,7 +197,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String TYPE_IMS_STRING = "ims";
 
     /**
@@ -204,7 +204,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String TYPE_CBS_STRING = "cbs";
 
     /**
@@ -212,7 +211,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String TYPE_IA_STRING = "ia";
 
     /**
@@ -221,7 +219,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String TYPE_EMERGENCY_STRING = "emergency";
 
     /**
@@ -229,7 +226,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String TYPE_MCX_STRING = "mcx";
 
     /**
@@ -237,7 +233,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String TYPE_XCAP_STRING = "xcap";
 
 
@@ -741,7 +736,7 @@
      * @return SKIP_464XLAT_DEFAULT, SKIP_464XLAT_DISABLE or SKIP_464XLAT_ENABLE
      * @hide
      */
-    @Carriers.Skip464XlatStatus
+    @Skip464XlatStatus
     public int getSkip464Xlat() {
         return mSkip464Xlat;
     }
@@ -1412,7 +1407,6 @@
      * @return comma delimited list of APN types.
      * @hide
      */
-    @SystemApi
     @NonNull
     public static String getApnTypesStringFromBitmask(int apnTypeBitmask) {
         List<String> types = new ArrayList<>();
@@ -2061,7 +2055,7 @@
          * @param skip464xlat skip464xlat for this APN
          * @hide
          */
-        public Builder setSkip464Xlat(@Carriers.Skip464XlatStatus int skip464xlat) {
+        public Builder setSkip464Xlat(@Skip464XlatStatus int skip464xlat) {
             this.mSkip464Xlat = skip464xlat;
             return this;
         }
diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java
index 6c4e7ce..f56bbe1 100644
--- a/telephony/java/android/telephony/data/DataService.java
+++ b/telephony/java/android/telephony/data/DataService.java
@@ -458,6 +458,9 @@
      * this method to facilitate the creation of {@link DataServiceProvider} instances. The system
      * will call this method after binding the data service for each active SIM slot id.
      *
+     * This methead is guaranteed to be invoked in {@link DataService}'s internal handler thread
+     * whose looper can be retrieved with {@link Looper.myLooper()} when override this method.
+     *
      * @param slotIndex SIM slot id the data service associated with.
      * @return Data service object. Null if failed to create the provider (e.g. invalid slot index)
      */
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index ccd28f4..44b0968 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -249,13 +249,69 @@
      * Key for an extra set on {@link PendingIntent} result callbacks providing a detailed result
      * code.
      *
-     * <p>This code is an implementation detail of the embedded subscription manager and is only
-     * intended for logging or debugging purposes.
+     * <p>The value of this key is an integer and contains two portions. The first byte is
+     * OperationCode and the reaming three bytes is the ErrorCode.
+     *
+     * OperationCode is the first byte of the result code and is a categorization which defines what
+     * type of operation took place when an error occurred. e.g {@link #OPERATION_DOWNLOAD} means
+     * the error is related to download.Since the OperationCode only uses at most one byte, the
+     * maximum allowed quantity is 255(0xFF).
+     *
+     * ErrorCode is the remaining three bytes of the result code, and it denotes what happened.
+     * e.g a combination of {@link #OPERATION_DOWNLOAD} and {@link #ERROR_TIME_OUT} will suggest the
+     * download operation has timed out. The only exception here is
+     * {@link #OPERATION_SMDX_SUBJECT_REASON_CODE}, where instead of ErrorCode, SubjectCode[5.2.6.1
+     * from GSMA (SGP.22 v2.2) and ReasonCode[5.2.6.2] from GSMA (SGP.22 v2.2) are encoded. @see
+     * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE} and
+     * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE}
+     *
+     * In the case where ErrorCode contains a value of 0, it means it's an unknown error. E.g Intent
+     * only contains {@link #OPERATION_DOWNLOAD} and ErrorCode is 0 implies this is an unknown
+     * Download error.
+     *
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE}
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE}
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE}
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE}
      */
     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE =
             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE";
 
     /**
+     * Key for an extra set on {@link PendingIntent} result callbacks providing a
+     * OperationCode of {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE},
+     * value will be an int.
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_OPERATION_CODE";
+
+    /**
+     * Key for an extra set on {@link PendingIntent} result callbacks providing a
+     * ErrorCode of {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE},
+     * value will be an int.
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_ERROR_CODE";
+
+    /**
+     * Key for an extra set on {@link PendingIntent} result callbacks providing a
+     * SubjectCode[5.2.6.1] from GSMA (SGP.22 v2.2) decoded from
+     * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}.
+     * The value of this extra will be a String.
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE";
+
+    /**
+     * Key for an extra set on {@link PendingIntent} result callbacks providing a
+     * ReasonCode[5.2.6.2] from GSMA (SGP.22 v2.2) decoded from
+     * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}.
+     * The value of this extra will be a String.
+     */
+    public static final String EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE =
+            "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE";
+
+    /**
      * Key for an extra set on {@code #getDownloadableSubscriptionMetadata} PendingIntent result
      * callbacks providing the downloadable subscription metadata.
      */
@@ -494,6 +550,259 @@
     @SystemApi
     public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5;
 
+    /**
+     * List of OperationCode corresponding to {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}'s
+     * value, an integer. @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"OPERATION_"}, value = {
+            OPERATION_SYSTEM,
+            OPERATION_SIM_SLOT,
+            OPERATION_EUICC_CARD,
+            OPERATION_SWITCH,
+            OPERATION_DOWNLOAD,
+            OPERATION_METADATA,
+            OPERATION_EUICC_GSMA,
+            OPERATION_APDU,
+            OPERATION_SMDX,
+            OPERATION_HTTP,
+            OPERATION_SMDX_SUBJECT_REASON_CODE,
+    })
+    public @interface OperationCode {
+    }
+
+    /**
+     * Internal system error.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int OPERATION_SYSTEM = 1;
+
+    /**
+     * SIM slot error. Failed to switch slot, failed to access the physical slot etc.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int OPERATION_SIM_SLOT = 2;
+
+    /**
+     * eUICC card error.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int OPERATION_EUICC_CARD = 3;
+
+    /**
+     * Generic switching profile error
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int OPERATION_SWITCH = 4;
+
+    /**
+     * Download profile error.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int OPERATION_DOWNLOAD = 5;
+
+    /**
+     * Subscription's metadata error
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int OPERATION_METADATA = 6;
+
+    /**
+     * eUICC returned an error defined in GSMA (SGP.22 v2.2) while running one of the ES10x
+     * functions.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int OPERATION_EUICC_GSMA = 7;
+
+    /**
+     * The exception of failing to execute an APDU command. It can be caused by an error
+     * happening on opening the basic or logical channel, or the response of the APDU command is
+     * not success (0x9000).
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int OPERATION_APDU = 8;
+
+    /**
+     * SMDX(SMDP/SMDS) error
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int OPERATION_SMDX = 9;
+
+    /**
+     * SubjectCode[5.2.6.1] and ReasonCode[5.2.6.2] error from GSMA (SGP.22 v2.2)
+     * When {@link #OPERATION_SMDX_SUBJECT_REASON_CODE} is used as the
+     * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}, the remaining three bytes of the integer
+     * result from {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} will be used to stored the
+     * SubjectCode and ReasonCode from the GSMA spec and NOT ErrorCode.
+     *
+     * The encoding will follow the format of:
+     * 1. The first byte of the result will be 255(0xFF).
+     * 2. Remaining three bytes(24 bits) will be split into six sections, 4 bits in each section.
+     * 3. A SubjectCode/ReasonCode will take 12 bits each.
+     * 4. The maximum number can be represented per section is 15, as that is the maximum number
+     * allowed to be stored into 4 bits
+     * 5. Maximum supported nested category from GSMA is three layers. E.g 8.11.1.2 is not
+     * supported.
+     *
+     * E.g given SubjectCode(8.11.1) and ReasonCode(5.1)
+     *
+     * Base10:  0       10      8       11      1       0       5       1
+     * Base2:   0000    1010    1000    1011    0001    0000    0101    0001
+     * Base16:  0       A       8       B       1       0       5       1
+     *
+     * Thus the integer stored in {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} is
+     * 0xA8B1051(176885841)
+     *
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int OPERATION_SMDX_SUBJECT_REASON_CODE = 10;
+
+    /**
+     * HTTP error
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int OPERATION_HTTP = 11;
+
+    /**
+     * List of ErrorCode corresponding to {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"ERROR_"}, value = {
+            ERROR_CARRIER_LOCKED,
+            ERROR_INVALID_ACTIVATION_CODE,
+            ERROR_INVALID_CONFIRMATION_CODE,
+            ERROR_INCOMPATIBLE_CARRIER,
+            ERROR_EUICC_INSUFFICIENT_MEMORY,
+            ERROR_TIME_OUT,
+            ERROR_EUICC_MISSING,
+            ERROR_UNSUPPORTED_VERSION,
+            ERROR_SIM_MISSING,
+            ERROR_INSTALL_PROFILE,
+            ERROR_DISALLOWED_BY_PPR,
+            ERROR_ADDRESS_MISSING,
+            ERROR_CERTIFICATE_ERROR,
+            ERROR_NO_PROFILES_AVAILABLE,
+            ERROR_CONNECTION_ERROR,
+            ERROR_INVALID_RESPONSE,
+            ERROR_OPERATION_BUSY,
+    })
+    public @interface ErrorCode{}
+
+    /**
+     * Operation such as downloading/switching to another profile failed due to device being
+     * carrier locked.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_CARRIER_LOCKED = 10000;
+
+    /**
+     * The activation code(SGP.22 v2.2 section[4.1]) is invalid.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_INVALID_ACTIVATION_CODE = 10001;
+
+    /**
+     * The confirmation code(SGP.22 v2.2 section[4.7]) is invalid.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_INVALID_CONFIRMATION_CODE = 10002;
+
+    /**
+     * The profile's carrier is incompatible with the LPA.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_INCOMPATIBLE_CARRIER = 10003;
+
+    /**
+     * There is no more space available on the eUICC for new profiles.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_EUICC_INSUFFICIENT_MEMORY = 10004;
+
+    /**
+     * Timed out while waiting for an operation to complete. i.e restart, disable,
+     * switch reset etc.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_TIME_OUT = 10005;
+
+    /**
+     * eUICC is missing or defective on the device.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_EUICC_MISSING = 10006;
+
+    /**
+     * The eUICC card(hardware) version is incompatible with the software
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_UNSUPPORTED_VERSION = 10007;
+
+    /**
+     * No SIM card is available in the device.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_SIM_MISSING = 10008;
+
+    /**
+     * Failure to load the profile onto the eUICC card. e.g
+     * 1. iccid of the profile already exists on the eUICC.
+     * 2. GSMA(.22 v2.2) Profile Install Result - installFailedDueToDataMismatch
+     * 3. operation was interrupted
+     * 4. SIMalliance error in PEStatus(SGP.22 v2.2 section 2.5.6.1)
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_INSTALL_PROFILE = 10009;
+
+    /**
+     * Failed to load profile onto eUICC due to Profile Poicly Rules.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_DISALLOWED_BY_PPR = 10010;
+
+
+    /**
+     * Address is missing e.g SMDS/SMDP address is missing.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_ADDRESS_MISSING = 10011;
+
+    /**
+     * Certificate needed for authentication is not valid or missing. E.g  SMDP/SMDS authentication
+     * failed.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_CERTIFICATE_ERROR = 10012;
+
+
+    /**
+     * No profiles available.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_NO_PROFILES_AVAILABLE = 10013;
+
+    /**
+     * Failure to create a connection.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_CONNECTION_ERROR = 10014;
+
+    /**
+     * Response format is invalid. e.g SMDP/SMDS response contains invalid json, header or/and ASN1.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_INVALID_RESPONSE = 10015;
+
+    /**
+     * The operation is currently busy, try again later.
+     * @see {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} for details
+     */
+    public static final int ERROR_OPERATION_BUSY = 10016;
+
     private final Context mContext;
     private int mCardId;
 
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index a7d553b..1e8fdce 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -18,7 +18,6 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -182,6 +181,25 @@
      *      {@link ImsCallProfile#DIALSTRING_USSD}
      */
     public static final String EXTRA_DIALSTRING = "dialstring";
+    /**
+     * This extra holds call fail cause because of which redial is attempted.
+     * see {@link android.telephony.ims.ImsReasonInfo} {@code CODE_*}
+     * for possible values this extra can hold.
+     *
+     * @hide
+     */
+    public static final String EXTRA_RETRY_CALL_FAIL_REASON =
+            "android.telephony.ims.extra.RETRY_CALL_FAIL_REASON";
+    /**
+     * This extra holds call network type on which lower layers
+     * may try attempting redial.
+     * See {@link TelephonyManager} {@code NETWORK_TYPE_*}
+     * for possible values this extra can hold.
+     *
+     * @hide
+     */
+    public static final String EXTRA_RETRY_CALL_FAIL_NETWORKTYPE =
+            "android.telephony.ims.extra.RETRY_CALL_FAIL_NETWORKTYPE";
 
     /**
      * Values for EXTRA_OIR / EXTRA_CNAP
@@ -702,11 +720,16 @@
      * @return A {@link Bundle} containing proprietary call extras that were not set by the
      * platform.
      */
-    public @Nullable Bundle getProprietaryCallExtras() {
+    public @NonNull Bundle getProprietaryCallExtras() {
         if (mCallExtras == null) {
-            return null;
+            return new Bundle();
         }
-        return mCallExtras.getBundle(EXTRA_OEM_EXTRAS);
+        Bundle proprietaryExtras = mCallExtras.getBundle(EXTRA_OEM_EXTRAS);
+        if (proprietaryExtras == null) {
+            return new Bundle();
+        }
+        // Make a copy so users do not accidentally change this copy of the extras.
+        return new Bundle(proprietaryExtras);
     }
 
     public ImsStreamMediaProfile getMediaProfile() {
diff --git a/telephony/java/android/telephony/ims/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
index 025721c..81af99f 100644
--- a/telephony/java/android/telephony/ims/ImsCallSessionListener.java
+++ b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
@@ -58,7 +58,7 @@
         try {
             mListener.callSessionProgressing(profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -71,7 +71,7 @@
         try {
             mListener.callSessionInitiated(profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -85,7 +85,7 @@
         try {
             mListener.callSessionInitiatedFailed(reasonInfo);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -98,7 +98,7 @@
         try {
             mListener.callSessionTerminated(reasonInfo);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -115,7 +115,7 @@
         try {
             mListener.callSessionHeld(profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -128,7 +128,7 @@
         try {
             mListener.callSessionHoldFailed(reasonInfo);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -141,7 +141,7 @@
         try {
             mListener.callSessionHoldReceived(profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -155,7 +155,7 @@
         try {
             mListener.callSessionResumed(profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -169,7 +169,7 @@
         try {
             mListener.callSessionResumeFailed(reasonInfo);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -182,7 +182,7 @@
         try {
             mListener.callSessionResumeReceived(profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -201,7 +201,7 @@
             mListener.callSessionMergeStarted(newSession != null ?
                             newSession.getServiceImpl() : null, profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -216,7 +216,7 @@
         try {
             mListener.callSessionMergeStarted(newSession, profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -232,7 +232,7 @@
             mListener.callSessionMergeComplete(newSession != null ?
                     newSession.getServiceImpl() : null);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -247,7 +247,7 @@
         try {
             mListener.callSessionMergeComplete(newSession);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -260,7 +260,7 @@
         try {
             mListener.callSessionMergeFailed(reasonInfo);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -273,7 +273,7 @@
         try {
             mListener.callSessionUpdated(profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -286,7 +286,7 @@
         try {
             mListener.callSessionUpdateFailed(reasonInfo);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -299,7 +299,7 @@
         try {
             mListener.callSessionUpdateReceived(profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -319,7 +319,7 @@
             mListener.callSessionConferenceExtended(
                     newSession != null ? newSession.getServiceImpl() : null, profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -333,7 +333,7 @@
         try {
             mListener.callSessionConferenceExtended(newSession, profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -347,7 +347,7 @@
         try {
             mListener.callSessionConferenceExtendFailed(reasonInfo);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -364,7 +364,7 @@
             mListener.callSessionConferenceExtendReceived(newSession != null
                     ? newSession.getServiceImpl() : null, profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -379,7 +379,7 @@
         try {
             mListener.callSessionConferenceExtendReceived(newSession, profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -391,7 +391,7 @@
         try {
             mListener.callSessionInviteParticipantsRequestDelivered();
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -407,7 +407,7 @@
         try {
             mListener.callSessionInviteParticipantsRequestFailed(reasonInfo);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -419,7 +419,7 @@
         try {
             mListener.callSessionRemoveParticipantsRequestDelivered();
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -435,7 +435,7 @@
         try {
             mListener.callSessionInviteParticipantsRequestFailed(reasonInfo);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -448,7 +448,7 @@
         try {
             mListener.callSessionConferenceStateUpdated(state);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -465,7 +465,7 @@
         try {
             mListener.callSessionUssdMessageReceived(mode, ussdMessage);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -501,7 +501,7 @@
         try {
             mListener.callSessionMayHandover(srcNetworkType, targetNetworkType);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -537,7 +537,7 @@
         try {
             mListener.callSessionHandover(srcNetworkType, targetNetworkType, reasonInfo);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -570,7 +570,7 @@
         try {
             mListener.callSessionHandoverFailed(srcNetworkType, targetNetworkType, reasonInfo);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -587,7 +587,7 @@
         try {
             mListener.callSessionTtyModeReceived(mode);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -600,7 +600,7 @@
         try {
             mListener.callSessionMultipartyStateChanged(isMultiParty);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -614,7 +614,7 @@
         try {
             mListener.callSessionSuppServiceReceived(suppSrvNotification);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -628,7 +628,7 @@
         try {
             mListener.callSessionRttModifyRequestReceived(callProfile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -641,7 +641,7 @@
         try {
             mListener.callSessionRttModifyResponseReceived(status);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -654,7 +654,7 @@
         try {
             mListener.callSessionRttMessageReceived(rttMessage);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -667,7 +667,7 @@
         try {
             mListener.callSessionRttAudioIndicatorChanged(profile);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -680,7 +680,7 @@
         try {
             mListener.callQualityChanged(callQuality);
         } catch (RemoteException e) {
-            throw new RuntimeException(e);
+            e.rethrowFromSystemServer();
         }
     }
 }
diff --git a/telephony/java/android/telephony/ims/ImsException.java b/telephony/java/android/telephony/ims/ImsException.java
index 643f452..1c3d58d 100644
--- a/telephony/java/android/telephony/ims/ImsException.java
+++ b/telephony/java/android/telephony/ims/ImsException.java
@@ -47,11 +47,12 @@
     public static final int CODE_ERROR_SERVICE_UNAVAILABLE = 1;
 
     /**
-     * This device or carrier configuration does not support IMS for this subscription.
+     * This device or carrier configuration does not support this feature for this subscription.
      * <p>
-     * This is a permanent configuration error and there should be no retry. Usually this is
-     * because {@link PackageManager#FEATURE_TELEPHONY_IMS} is not available
-     * or the device has no ImsService implementation to service this request.
+     * This is a permanent configuration error and there should be no retry until the subscription
+     * changes if this operation is denied due to a carrier configuration. If this is due to a
+     * device configuration, the feature {@link PackageManager#FEATURE_TELEPHONY_IMS} is not
+     * available or the device has no ImsService implementation to service this request.
      */
     public static final int CODE_ERROR_UNSUPPORTED_OPERATION = 2;
 
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index 494009f..dc8d750 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -21,7 +21,6 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SuppressAutoDoc;
 import android.annotation.SuppressLint;
@@ -125,7 +124,7 @@
          * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
          */
         @Override
-        public void onUnregistered(@Nullable ImsReasonInfo info) {
+        public void onUnregistered(@NonNull ImsReasonInfo info) {
         }
 
         /**
@@ -137,7 +136,7 @@
         @Override
         public void onTechnologyChangeFailed(
                 @AccessNetworkConstants.TransportType int imsTransportType,
-                @Nullable ImsReasonInfo info) {
+                @NonNull ImsReasonInfo info) {
         }
     }
 
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index a2ad21c..ed9b94b 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -20,14 +20,16 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.annotation.TestApi;
+import android.annotation.SdkConstant;
 import android.content.Context;
+import android.content.Intent;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.provider.Settings;
 import android.telephony.AccessNetworkConstants;
+import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsRcsController;
@@ -46,14 +48,34 @@
  * (UCE) service, as well as managing user settings.
  *
  * Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this manager.
- * @hide
  */
-@SystemApi
-@TestApi
 public class ImsRcsManager implements RegistrationManager {
     private static final String TAG = "ImsRcsManager";
 
     /**
+     * Activity Action: Show the opt-in dialog for enabling or disabling RCS contact discovery
+     * using User Capability Exchange (UCE).
+     * <p>
+     * An application that depends on contact discovery being enabled may send this intent
+     * using {@link Context#startActivity(Intent)} to ask the user to opt-in for contacts upload for
+     * capability exchange if it is currently disabled. Whether or not this setting has been enabled
+     * can be queried using {@link RcsUceAdapter#isUceSettingEnabled()}.
+     * <p>
+     * This intent should only be sent if the carrier supports RCS capability exchange, which can be
+     * queried using the key {@link CarrierConfigManager#KEY_USE_RCS_PRESENCE_BOOL}. Otherwise, the
+     * setting will not be present.
+     * <p>
+     * Input: A mandatory {@link Settings#EXTRA_SUB_ID} extra containing the subscription that the
+     * setting will be be shown for.
+     * <p>
+     * Output: Nothing
+     * @see RcsUceAdapter
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN =
+            "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN";
+
+    /**
      * Receives RCS availability status updates from the ImsService.
      *
      * @see #isAvailable(int)
@@ -145,11 +167,10 @@
      */
     @NonNull
     public RcsUceAdapter getUceAdapter() {
-        return new RcsUceAdapter(mSubId);
+        return new RcsUceAdapter(mContext, mSubId);
     }
 
     /**
-     * {@inheritDoc}
      * @hide
      */
     @Override
@@ -181,7 +202,6 @@
     }
 
     /**
-     * {@inheritDoc
      * @hide
      */
     @Override
@@ -206,7 +226,6 @@
     }
 
     /**
-     * {@inheritDoc}
      * @hide
      */
     @Override
@@ -239,7 +258,6 @@
     }
 
     /**
-     * {@inheritDoc}
      * @hide
      */
     @Override
diff --git a/telephony/java/android/telephony/ims/ImsUtListener.java b/telephony/java/android/telephony/ims/ImsUtListener.java
index bc124044..460a032 100644
--- a/telephony/java/android/telephony/ims/ImsUtListener.java
+++ b/telephony/java/android/telephony/ims/ImsUtListener.java
@@ -49,7 +49,8 @@
      * {@link ImsSsInfo#CLIR_STATUS_TEMPORARILY_RESTRICTED}, and
      * {@link ImsSsInfo#CLIR_STATUS_TEMPORARILY_ALLOWED}.
      * @deprecated Use {@link #onLineIdentificationSupplementaryServiceResponse(int, ImsSsInfo)}
-     * instead.
+     * instead, this key has been added for backwards compatibility with older proprietary
+     * implementations only and is being phased out.
      */
     @Deprecated
     public static final String BUNDLE_KEY_CLIR = "queryClir";
@@ -60,7 +61,8 @@
      * response. The value will be an instance of {@link ImsSsInfo}, which contains the response to
      * the query.
      * @deprecated Use {@link #onLineIdentificationSupplementaryServiceResponse(int, ImsSsInfo)}
-     * instead.
+     * instead, this key has been added for backwards compatibility with older proprietary
+     * implementations only and is being phased out.
      */
     @Deprecated
     public static final String BUNDLE_KEY_SSINFO = "imsSsInfo";
@@ -123,7 +125,7 @@
         try {
             mServiceInterface.lineIdentificationSupplementaryServiceResponse(id, configuration);
         } catch (RemoteException e) {
-            Log.w(LOG_TAG, "onLineIdentificationSupplementaryServicesResponse: remote exception");
+            e.rethrowFromSystemServer();
         }
     }
 
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 6125001..ad54cbf 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -306,13 +306,13 @@
 
     /**
      * An integer key associated with the carrier configured expiration time in seconds for
-     * RCS presence published offline availability in RCS presence.
+     * published offline availability in RCS presence provided, which is provided to the network.
      * <p>
      * Value is in Integer format.
      * @see #setProvisioningIntValue(int, int)
      * @see #getProvisioningIntValue(int)
      */
-    public static final int KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC = 16;
+    public static final int KEY_RCS_PUBLISH_OFFLINE_AVAILABILITY_TIMER_SEC = 16;
 
     /**
      * An integer key associated with whether or not capability discovery is provisioned for this
@@ -327,8 +327,10 @@
     public static final int KEY_RCS_CAPABILITY_DISCOVERY_ENABLED = 17;
 
     /**
-     * An integer key associated with the period of time the capability information of each contact
-     * is cached on the device.
+     * An integer key associated with the period of time in seconds the capability information of
+     * each contact is cached on the device.
+     * <p>
+     * Seconds are used because this is usually measured in the span of days.
      * <p>
      * Value is in Integer format.
      * @see #setProvisioningIntValue(int, int)
@@ -338,7 +340,8 @@
 
     /**
      * An integer key associated with the period of time in seconds that the availability
-     * information of a contact is cached on the device.
+     * information of a contact is cached on the device, which is based on the carrier provisioning
+     * configuration from the network.
      * <p>
      * Value is in Integer format.
      * @see #setProvisioningIntValue(int, int)
@@ -348,7 +351,8 @@
 
     /**
      * An integer key associated with the carrier configured interval in seconds expected between
-     * successive capability polling attempts.
+     * successive capability polling attempts, which is based on the carrier provisioning
+     * configuration from the network.
      * <p>
      * Value is in Integer format.
      * @see #setProvisioningIntValue(int, int)
@@ -358,7 +362,7 @@
 
     /**
      * An integer key representing the minimum time allowed between two consecutive presence publish
-     * messages from the device.
+     * messages from the device in milliseconds.
      * <p>
      * Value is in Integer format.
      * @see #setProvisioningIntValue(int, int)
@@ -379,7 +383,7 @@
     /**
      * An integer associated with the expiration timer used during the SIP subscription of a
      * Request Contained List (RCL), which is used to retrieve the RCS capabilities of the contact
-     * book.
+     * book. This timer value is sent in seconds to the network.
      * <p>
      * Value is in Integer format.
      * @see #setProvisioningIntValue(int, int)
@@ -471,7 +475,8 @@
     public static final int KEY_SIP_KEEP_ALIVE_ENABLED = 32;
 
     /**
-     * Registration retry Base Time value in seconds.
+     * Registration retry Base Time value in seconds, which is based off of the carrier
+     * configuration.
      * Value is in Integer format.
      * @see #setProvisioningIntValue(int, int)
      * @see #getProvisioningIntValue(int)
@@ -479,7 +484,8 @@
     public static final int KEY_REGISTRATION_RETRY_BASE_TIME_SEC = 33;
 
     /**
-     * Registration retry Max Time value in seconds.
+     * Registration retry Max Time value in seconds, which is based off of the carrier
+     * configuration.
      * Value is in Integer format.
      * @see #setProvisioningIntValue(int, int)
      * @see #getProvisioningIntValue(int)
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 6974420..70edb75 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -43,10 +43,7 @@
  * Manages RCS User Capability Exchange for the subscription specified.
  *
  * @see ImsRcsManager#getUceAdapter() for information on creating an instance of this class.
- * @hide
  */
-@SystemApi
-@TestApi
 public class RcsUceAdapter {
     private static final String TAG = "RcsUceAdapter";
 
@@ -139,7 +136,7 @@
      * UCE.
      * @hide
      */
-    public static final int PUBLISH_STATE_200_OK = 1;
+    public static final int PUBLISH_STATE_OK = 1;
 
     /**
      * The hasn't published its capabilities since boot or hasn't gotten any publish response yet.
@@ -179,7 +176,7 @@
     /**@hide*/
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = "PUBLISH_STATE_", value = {
-            PUBLISH_STATE_200_OK,
+            PUBLISH_STATE_OK,
             PUBLISH_STATE_NOT_PUBLISHED,
             PUBLISH_STATE_VOLTE_PROVISION_ERROR,
             PUBLISH_STATE_RCS_PROVISION_ERROR,
@@ -216,6 +213,7 @@
         }
     }
 
+    private final Context mContext;
     private final int mSubId;
 
     /**
@@ -223,7 +221,8 @@
      * {@link ImsRcsManager#getUceAdapter()} to instantiate this manager class.
      * @hide
      */
-    RcsUceAdapter(int subId) {
+    RcsUceAdapter(Context context, int subId) {
+        mContext = context;
         mSubId = subId;
     }
 
@@ -291,7 +290,8 @@
         };
 
         try {
-            imsRcsController.requestCapabilities(mSubId, contactNumbers, internalCallback);
+            imsRcsController.requestCapabilities(mSubId, mContext.getOpPackageName(),
+                    null /*featureId*/, contactNumbers, internalCallback);
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling IImsRcsController#requestCapabilities", e);
             throw new ImsException("Remote IMS Service is not available",
@@ -303,7 +303,7 @@
      * Gets the last publish result from the UCE service if the device is using an RCS presence
      * server.
      * @return The last publish result from the UCE service. If the device is using SIP OPTIONS,
-     * this method will return {@link #PUBLISH_STATE_200_OK} as well.
+     * this method will return {@link #PUBLISH_STATE_OK} as well.
      * @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
@@ -341,7 +341,7 @@
      * 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.
      */
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
     public boolean isUceSettingEnabled() throws ImsException {
         IImsRcsController imsRcsController = getIImsRcsController();
         if (imsRcsController == null) {
@@ -349,9 +349,10 @@
             throw new ImsException("Can not find remote IMS service",
                     ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
         }
-
         try {
-            return imsRcsController.isUceSettingEnabled(mSubId);
+            // Telephony.SimInfo#IMS_RCS_UCE_ENABLED can also be used to listen to changes to this.
+            return imsRcsController.isUceSettingEnabled(mSubId, mContext.getOpPackageName(),
+                    null /*featureId*/);
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling IImsRcsController#isUceSettingEnabled", e);
             throw new ImsException("Remote IMS Service is not available",
@@ -362,6 +363,10 @@
     /**
      * Change the user’s setting for whether or not UCE is enabled for the associated subscription.
      * <p>
+     * If an application Requires UCE, they may launch an Activity using the Intent
+     * {@link ImsRcsManager#ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN}, which will ask the user if
+     * they wish to enable this feature.
+     * <p>
      * Note: This setting does not affect whether or not the device publishes its service
      * capabilities if the subscription supports presence publication.
      *
@@ -371,7 +376,10 @@
      * {@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
+    @TestApi
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public void setUceSettingEnabled(boolean isEnabled) throws ImsException {
         IImsRcsController imsRcsController = getIImsRcsController();
diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java
index 5c86ba7..1dbaff5 100644
--- a/telephony/java/android/telephony/ims/RegistrationManager.java
+++ b/telephony/java/android/telephony/ims/RegistrationManager.java
@@ -196,11 +196,11 @@
         }
 
         /**
-         * Notifies the framework when the IMS Provider is deregistered from the IMS network.
+         * Notifies the framework when the IMS Provider is unregistered from the IMS network.
          *
          * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
          */
-        public void onUnregistered(@Nullable ImsReasonInfo info) {
+        public void onUnregistered(@NonNull ImsReasonInfo info) {
         }
 
         /**
@@ -211,7 +211,7 @@
          */
         public void onTechnologyChangeFailed(
                 @AccessNetworkConstants.TransportType int imsTransportType,
-                @Nullable ImsReasonInfo info) {
+                @NonNull ImsReasonInfo info) {
         }
 
         /**
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
index 6f6aa44..483c66e 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
@@ -42,8 +42,9 @@
     boolean isAvailable(int subId, int capability);
 
     // ImsUceAdapter specific
-    void requestCapabilities(int subId, in List<Uri> contactNumbers, IRcsUceControllerCallback c);
+    void requestCapabilities(int subId, String callingPackage, String callingFeatureId,
+            in List<Uri> contactNumbers, IRcsUceControllerCallback c);
     int getUcePublishState(int subId);
-    boolean isUceSettingEnabled(int subId);
+    boolean isUceSettingEnabled(int subId, String callingPackage, String callingFeatureId);
     void setUceSettingEnabled(int subId, boolean isEnabled);
 }
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index 14a64d2..7069e0a 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -175,9 +175,11 @@
      */
     public final void onDeregistered(ImsReasonInfo info) {
         updateToDisconnectedState(info);
+        // ImsReasonInfo should never be null.
+        final ImsReasonInfo reasonInfo = (info != null) ? info : new ImsReasonInfo();
         mCallbacks.broadcastAction((c) -> {
             try {
-                c.onDeregistered(info);
+                c.onDeregistered(reasonInfo);
             } catch (RemoteException e) {
                 Log.w(LOG_TAG, e + " " + "onRegistrationDisconnected() - Skipping " +
                         "callback.");
@@ -194,9 +196,10 @@
      */
     public final void onTechnologyChangeFailed(@ImsRegistrationTech int imsRadioTech,
             ImsReasonInfo info) {
+        final ImsReasonInfo reasonInfo = (info != null) ? info : new ImsReasonInfo();
         mCallbacks.broadcastAction((c) -> {
             try {
-                c.onTechnologyChangeFailed(imsRadioTech, info);
+                c.onTechnologyChangeFailed(imsRadioTech, reasonInfo);
             } catch (RemoteException e) {
                 Log.w(LOG_TAG, e + " " + "onRegistrationChangeFailed() - Skipping " +
                         "callback.");
diff --git a/telephony/java/com/android/ims/ImsConfig.java b/telephony/java/com/android/ims/ImsConfig.java
index 96f77d8..d0cec52d 100644
--- a/telephony/java/com/android/ims/ImsConfig.java
+++ b/telephony/java/com/android/ims/ImsConfig.java
@@ -270,11 +270,12 @@
         /**
          * Requested expiration for Published Offline availability.
          * Value is in Integer format.
-         * @deprecated use {@link ProvisioningManager#KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC}.
+         * @deprecated use
+         *     {@link ProvisioningManager#KEY_RCS_PUBLISH_OFFLINE_AVAILABILITY_TIMER_SEC}.
          */
         @Deprecated
         public static final int PUBLISH_TIMER_EXTENDED =
-                ProvisioningManager.KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC;
+                ProvisioningManager.KEY_RCS_PUBLISH_OFFLINE_AVAILABILITY_TIMER_SEC;
 
         /**
          *
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index c07a171..88da3c9 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -86,37 +86,9 @@
      *  raw pdu of the status report is in the extended data ("pdu").
      * @param subId the subId id.
      */
-    void sendDataForSubscriber(int subId, String callingPkg, in String destAddr,
-            in String scAddr, in int destPort, in byte[] data, in PendingIntent sentIntent,
-            in PendingIntent deliveryIntent);
-
-    /**
-     * Send a data SMS. Only for use internally.
-     *
-     * @param smsc the SMSC to send the message through, or NULL for the
-     *  default SMSC
-     * @param data the body of the message to send
-     * @param sentIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is sucessfully sent, or failed.
-     *  The result code will be <code>Activity.RESULT_OK<code> for success,
-     *  or one of these errors:<br>
-     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
-     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
-     *  <code>RESULT_ERROR_NULL_PDU</code><br>
-     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
-     *  the extra "errorCode" containing a radio technology specific value,
-     *  generally only useful for troubleshooting.<br>
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applicaitons,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is delivered to the recipient.  The
-     *  raw pdu of the status report is in the extended data ("pdu").
-     * @param subId the subId id.
-     */
-    void sendDataForSubscriberWithSelfPermissions(int subId, String callingPkg, in String destAddr,
-            in String scAddr, in int destPort, in byte[] data, in PendingIntent sentIntent,
-            in PendingIntent deliveryIntent);
+    void sendDataForSubscriber(int subId, String callingPkg, String callingattributionTag,
+            in String destAddr, in String scAddr, in int destPort,in byte[] data,
+            in PendingIntent sentIntent, in PendingIntent deliveryIntent);
 
     /**
      * Send an SMS.
@@ -146,37 +118,9 @@
      *   by a non-default SMS app. Currently only the carrier app can set this
      *   parameter to false to skip auto message persistence.
      */
-    void sendTextForSubscriber(in int subId, String callingPkg, in String destAddr,
-            in String scAddr, in String text, in PendingIntent sentIntent,
-            in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp);
-
-    /**
-     * Send an SMS. Internal use only.
-     *
-     * @param smsc the SMSC to send the message through, or NULL for the
-     *  default SMSC
-     * @param text the body of the message to send
-     * @param sentIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is sucessfully sent, or failed.
-     *  The result code will be <code>Activity.RESULT_OK<code> for success,
-     *  or one of these errors:<br>
-     *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
-     *  <code>RESULT_ERROR_RADIO_OFF</code><br>
-     *  <code>RESULT_ERROR_NULL_PDU</code><br>
-     *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
-     *  the extra "errorCode" containing a radio technology specific value,
-     *  generally only useful for troubleshooting.<br>
-     *  The per-application based SMS control checks sentIntent. If sentIntent
-     *  is NULL the caller will be checked against all unknown applications,
-     *  which cause smaller number of SMS to be sent in checking period.
-     * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
-     *  broadcast when the message is delivered to the recipient.  The
-     *  raw pdu of the status report is in the extended data ("pdu").
-     * @param subId the subId on which the SMS has to be sent.
-     */
-    void sendTextForSubscriberWithSelfPermissions(in int subId, String callingPkg,
+    void sendTextForSubscriber(in int subId, String callingPkg, String callingAttributionTag,
             in String destAddr, in String scAddr, in String text, in PendingIntent sentIntent,
-            in PendingIntent deliveryIntent, in boolean persistMessage);
+            in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp);
 
     /**
      * Send an SMS with options using Subscription Id.
@@ -224,10 +168,11 @@
      *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
      *  Any Other values included Negative considered as Invalid Validity Period of the message.
      */
-    void sendTextForSubscriberWithOptions(in int subId, String callingPkg, in String destAddr,
-            in String scAddr, in String text, in PendingIntent sentIntent,
-            in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp,
-            in int priority, in boolean expectMore, in int validityPeriod);
+    void sendTextForSubscriberWithOptions(in int subId, String callingPkg,
+            String callingAttributionTag, in String destAddr, in String scAddr, in String text,
+            in PendingIntent sentIntent, in PendingIntent deliveryIntent,
+            in boolean persistMessageForNonDefaultSmsApp, in int priority, in boolean expectMore,
+            in int validityPeriod);
 
     /**
      * Inject an SMS PDU into the android platform.
@@ -272,7 +217,7 @@
      *   parameter to false to skip auto message persistence.
      */
     void sendMultipartTextForSubscriber(in int subId, String callingPkg,
-            in String destinationAddress, in String scAddress,
+            String callingAttributionTag, in String destinationAddress, in String scAddress,
             in List<String> parts, in List<PendingIntent> sentIntents,
             in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp);
 
@@ -321,10 +266,10 @@
      *  Any Other values included Negative considered as Invalid Validity Period of the message.
      */
     void sendMultipartTextForSubscriberWithOptions(in int subId, String callingPkg,
-            in String destinationAddress, in String scAddress, in List<String> parts,
-            in List<PendingIntent> sentIntents, in List<PendingIntent> deliveryIntents,
-            in boolean persistMessageForNonDefaultSmsApp, in int priority, in boolean expectMore,
-            in int validityPeriod);
+            String callingAttributionTag, in String destinationAddress, in String scAddress,
+            in List<String> parts, in List<PendingIntent> sentIntents,
+            in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp,
+            in int priority, in boolean expectMore, in int validityPeriod);
 
     /**
      * Enable reception of cell broadcast (SMS-CB) messages with the given
@@ -482,6 +427,7 @@
      *
      * @param subId the SIM id.
      * @param callingPkg the package name of the calling app
+     * @param callingAttributionTag the attribution tag of calling context
      * @param messageUri the URI of the stored message
      * @param scAddress is the service center address or null to use the current default SMSC
      * @param sentIntent if not NULL this <code>PendingIntent</code> is
@@ -501,8 +447,9 @@
      *  broadcast when the message is delivered to the recipient.  The
      *  raw pdu of the status report is in the extended data ("pdu").
      */
-    void sendStoredText(int subId, String callingPkg, in Uri messageUri, String scAddress,
-            in PendingIntent sentIntent, in PendingIntent deliveryIntent);
+    void sendStoredText(int subId, String callingPkg, String callingAttributionTag,
+            in Uri messageUri, String scAddress, in PendingIntent sentIntent,
+            in PendingIntent deliveryIntent);
 
     /**
      * Send a system stored multi-part text message.
@@ -514,6 +461,7 @@
      *
      * @param subId the SIM id.
      * @param callingPkg the package name of the calling app
+     * @param callingAttributeTag the attribute tag of the calling context
      * @param messageUri the URI of the stored message
      * @param scAddress is the service center address or null to use
      *   the current default SMSC
@@ -537,8 +485,8 @@
      *   to the recipient.  The raw pdu of the status report is in the
      *   extended data ("pdu").
      */
-    void sendStoredMultipartText(int subId, String callingPkg, in Uri messageUri,
-                String scAddress, in List<PendingIntent> sentIntents,
+    void sendStoredMultipartText(int subId, String callingPkg, String callingAttributeTag,
+                in Uri messageUri, String scAddress, in List<PendingIntent> sentIntents,
                 in List<PendingIntent> deliveryIntents);
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index ddd3457..51af6de 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -45,38 +45,25 @@
     }
 
     @Override
-    public void sendDataForSubscriber(int subId, String callingPkg, String destAddr,
-            String scAddr, int destPort, byte[] data, PendingIntent sentIntent,
-            PendingIntent deliveryIntent) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void sendDataForSubscriberWithSelfPermissions(int subId, String callingPkg,
+    public void sendDataForSubscriber(int subId, String callingPkg, String callingAttributionTag,
             String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent,
             PendingIntent deliveryIntent) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public void sendTextForSubscriber(int subId, String callingPkg, String destAddr,
-            String scAddr, String text, PendingIntent sentIntent,
+    public void sendTextForSubscriber(int subId, String callingPkg, String callingAttributionTag,
+            String destAddr, String scAddr, String text, PendingIntent sentIntent,
             PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public void sendTextForSubscriberWithSelfPermissions(int subId, String callingPkg,
-            String destAddr, String scAddr, String text, PendingIntent sentIntent,
-            PendingIntent deliveryIntent, boolean persistMessage) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void sendTextForSubscriberWithOptions(int subId, String callingPkg, String destAddr,
-            String scAddr, String text, PendingIntent sentIntent,
-            PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp,
-            int priority, boolean expectMore, int validityPeriod) {
+    public void sendTextForSubscriberWithOptions(int subId, String callingPkg,
+            String callingAttributionTag, String destAddr, String scAddr, String text,
+            PendingIntent sentIntent, PendingIntent deliveryIntent,
+            boolean persistMessageForNonDefaultSmsApp, int priority, boolean expectMore,
+            int validityPeriod) {
         throw new UnsupportedOperationException();
     }
 
@@ -88,7 +75,7 @@
 
     @Override
     public void sendMultipartTextForSubscriber(int subId, String callingPkg,
-            String destinationAddress, String scAddress,
+            String callingAttributionTag, String destinationAddress, String scAddress,
             List<String> parts, List<PendingIntent> sentIntents,
             List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp) {
         throw new UnsupportedOperationException();
@@ -96,7 +83,7 @@
 
     @Override
     public void sendMultipartTextForSubscriberWithOptions(int subId, String callingPkg,
-            String destinationAddress, String scAddress,
+            String callingAttributionTag, String destinationAddress, String scAddress,
             List<String> parts, List<PendingIntent> sentIntents,
             List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp,
             int priority, boolean expectMore, int validityPeriod) {
@@ -173,14 +160,15 @@
     }
 
     @Override
-    public void sendStoredText(int subId, String callingPkg, Uri messageUri, String scAddress,
-            PendingIntent sentIntent, PendingIntent deliveryIntent) {
+    public void sendStoredText(int subId, String callingPkg, String callingAttributionTag,
+            Uri messageUri, String scAddress, PendingIntent sentIntent,
+            PendingIntent deliveryIntent) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public void sendStoredMultipartText(int subId, String callingPkg, Uri messageUri,
-            String scAddress, List<PendingIntent> sentIntents,
+    public void sendStoredMultipartText(int subId, String callingPkg, String callingAttributionTag,
+            Uri messageUri, String scAddress, List<PendingIntent> sentIntents,
             List<PendingIntent> deliveryIntents) {
         throw new UnsupportedOperationException();
     }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 123096c..1face6c 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -22,6 +22,7 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Messenger;
+import android.os.ParcelFileDescriptor;
 import android.os.ResultReceiver;
 import android.os.WorkSource;
 import android.net.NetworkStats;
@@ -281,7 +282,7 @@
      * operator's MCC (Mobile Country Code).
      * @see android.telephony.TelephonyManager#getNetworkCountryIso
      */
-    String getNetworkCountryIsoForPhone(int phoneId, String callingPkg, String callingFeatureId);
+    String getNetworkCountryIsoForPhone(int phoneId);
 
     /**
      * Returns the neighboring cell information of the device.
@@ -472,8 +473,8 @@
      * Send a visual voicemail SMS. Internal use only.
      * Requires caller to be the default dialer and have SEND_SMS permission
      */
-    void sendVisualVoicemailSmsForSubscriber(in String callingPackage, in int subId,
-            in String number, in int port, in String text, in PendingIntent sentIntent);
+    void sendVisualVoicemailSmsForSubscriber(in String callingPackage, String callingAttributeTag,
+            in int subId, in String number, in int port, in String text, in PendingIntent sentIntent);
 
     // Send the special dialer code. The IPC caller must be the current default dialer.
     void sendDialerSpecialCode(String callingPackageName, String inputCode);
@@ -2121,9 +2122,14 @@
     void notifyOtaEmergencyNumberDbInstalled();
 
     /**
-     * Override the file partition name for testing OTA emergency number database.
+     * Override a customized file partition name for OTA emergency number database.
      */
-    void updateTestOtaEmergencyNumberDbFilePath(String otaFilePath);
+    void updateOtaEmergencyNumberDbFilePath(in ParcelFileDescriptor otaParcelFileDescriptor);
+
+    /**
+     * Reset file partition to default for OTA emergency number database.
+     */
+    void resetOtaEmergencyNumberDbFilePath();
 
     /**
      * Enable or disable a logical modem stack associated with the slotIndex.
@@ -2198,7 +2204,8 @@
      * Enqueue a pending sms Consumer, which will answer with the user specified selection for an
      * outgoing SmsManager operation.
      */
-    oneway void enqueueSmsPickResult(String callingPackage, IIntegerConsumer subIdResult);
+    oneway void enqueueSmsPickResult(String callingPackage, String callingAttributeTag,
+        IIntegerConsumer subIdResult);
 
     /**
      * Returns the MMS user agent.
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 53ad70a..6fdc13e 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -492,6 +492,7 @@
     int RIL_REQUEST_ENABLE_UICC_APPLICATIONS = 208;
     int RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT = 209;
     int RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS = 210;
+    int RIL_REQUEST_GET_BARRING_INFO = 211;
 
     /* Responses begin */
     int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;
@@ -557,4 +558,5 @@
     int RIL_UNSOL_EMERGENCY_NUMBER_LIST = 1102;
     int RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED = 1103;
     int RIL_UNSOL_REGISTRATION_FAILED = 1104;
+    int RIL_UNSOL_BARRING_INFO_CHANGED = 1105;
 }
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 95b8f67..8b182b7 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -71,6 +71,7 @@
     // with the app launch
     private static final String KEY_REQUIRED_ACCOUNTS = "required_accounts";
     private static final String KEY_APPS = "apps";
+    private static final String KEY_IORAP_TRIAL_LAUNCH = "iorap_trial_launch";
     private static final String KEY_TRIAL_LAUNCH = "trial_launch";
     private static final String KEY_LAUNCH_ITERATIONS = "launch_iterations";
     private static final String KEY_LAUNCH_ORDER = "launch_order";
@@ -98,6 +99,9 @@
     private static final int BEFORE_KILL_APP_SLEEP_TIMEOUT = 1000; // 1s before killing
     private static final int BETWEEN_LAUNCH_SLEEP_TIMEOUT = 3000; // 3s between launching apps
     private static final int PROFILE_SAVE_SLEEP_TIMEOUT = 1000; // Allow 1s for the profile to save
+    private static final int IORAP_TRACE_DURATION_TIMEOUT = 7000; // Allow 7s for trace to complete.
+    private static final int IORAP_TRIAL_LAUNCH_ITERATIONS = 3;  // min 3 launches to merge traces.
+    private static final int IORAP_COMPILE_CMD_TIMEOUT = 600;  // in seconds: 10 minutes
     private static final String LAUNCH_SUB_DIRECTORY = "launch_logs";
     private static final String LAUNCH_FILE = "applaunch.txt";
     private static final String TRACE_SUB_DIRECTORY = "atrace_logs";
@@ -106,6 +110,9 @@
     private static final String DEFAULT_TRACE_BUFFER_SIZE = "20000";
     private static final String DEFAULT_TRACE_DUMP_INTERVAL = "10";
     private static final String TRIAL_LAUNCH = "TRIAL_LAUNCH";
+    private static final String IORAP_TRIAL_LAUNCH = "IORAP_TRIAL_LAUNCH";
+    private static final String IORAP_TRIAL_LAUNCH_FIRST = "IORAP_TRIAL_LAUNCH_FIRST";
+    private static final String IORAP_TRIAL_LAUNCH_LAST = "IORAP_TRIAL_LAUNCH_LAST";
     private static final String DELIMITER = ",";
     private static final String DROP_CACHE_SCRIPT = "/data/local/tmp/dropCache.sh";
     private static final String APP_LAUNCH_CMD = "am start -W -n";
@@ -119,6 +126,10 @@
     private static final String LAUNCH_ORDER_CYCLIC = "cyclic";
     private static final String LAUNCH_ORDER_SEQUENTIAL = "sequential";
     private static final String COMPILE_CMD = "cmd package compile -f -m %s %s";
+    private static final String IORAP_COMPILE_CMD = "cmd jobscheduler run -f android 283673059";
+    private static final String IORAP_MAINTENANCE_CMD =
+            "iorap.cmd.maintenance --purge-package %s /data/misc/iorapd/sqlite.db";
+    private static final String IORAP_DUMPSYS_CMD = "dumpsys iorapd";
     private static final String SPEED_PROFILE_FILTER = "speed-profile";
     private static final String VERIFY_FILTER = "verify";
     private static final String LAUNCH_SCRIPT_NAME = "appLaunch";
@@ -138,6 +149,7 @@
     private Bundle mResult = new Bundle();
     private Set<String> mRequiredAccounts;
     private boolean mTrialLaunch = false;
+    private boolean mIorapTrialLaunch = false;
     private BufferedWriter mBufferedWriter = null;
     private boolean mSimplePerfAppOnly = false;
     private String[] mCompilerFilters = null;
@@ -145,6 +157,13 @@
     private boolean mCycleCleanUp = false;
     private boolean mTraceAll = false;
     private boolean mIterationCycle = false;
+
+    enum IorapStatus {
+        UNDEFINED,
+        ENABLED,
+        DISABLED
+    }
+    private IorapStatus mIorapStatus = IorapStatus.UNDEFINED;
     private long mCycleTime = 0;
     private StringBuilder mCycleTimes = new StringBuilder();
 
@@ -243,7 +262,10 @@
             setLaunchOrder();
 
             for (LaunchOrder launch : mLaunchOrderList) {
-                dropCache();
+                toggleIorapStatus(launch.getIorapEnabled());
+                dropCache(/*override*/false);
+
+                Log.v(TAG, "Launch reason: " + launch.getLaunchReason());
 
                 // App launch times for trial launch will not be used for final
                 // launch time calculations.
@@ -289,6 +311,43 @@
                               compileApp(launch.getCompilerFilter(), appPkgName));
                     }
                 }
+                else if (launch.getLaunchReason().startsWith(IORAP_TRIAL_LAUNCH)) {
+                    mIterationCycle = false;
+
+                    // In the "applaunch.txt" file, iorap-trial launches is referenced using
+                    // "IORAP_TRIAL_LAUNCH" or "IORAP_TRIAL_LAUNCH_LAST"
+                    Intent startIntent = mNameToIntent.get(launch.getApp());
+                    if (startIntent == null) {
+                        Log.w(TAG, "App does not exist: " + launch.getApp());
+                        mResult.putString(mNameToResultKey.get(launch.getApp()),
+                            "App does not exist");
+                        continue;
+                    }
+                    String appPkgName = startIntent.getComponent().getPackageName();
+
+                    if (launch.getLaunchReason().equals(IORAP_TRIAL_LAUNCH_FIRST)) {
+                        // delete any iorap-traces associated with this package.
+                        purgeIorapPackage(appPkgName);
+                    }
+                    dropCache(/*override*/true);  // iorap-trial runs must have drop cache.
+
+                    AppLaunchResult launchResult =
+                        startApp(launch.getApp(), launch.getLaunchReason());
+                    if (launchResult.mLaunchTime < 0) {
+                        addLaunchResult(launch, new AppLaunchResult());
+                        // simply pass the app if launch isn't successful
+                        // error should have already been logged by startApp
+                        continue;
+                    }
+                    // wait for slightly more than 5s (iorapd.perfetto.trace_duration_ms) for the trace buffers to complete.
+                    sleep(IORAP_TRACE_DURATION_TIMEOUT);
+
+                    if (launch.getLaunchReason().equals(IORAP_TRIAL_LAUNCH_LAST)) {
+                        // run the iorap job scheduler and wait for iorap to compile fully.
+                        assertTrue(String.format("Not able to iorap-compile the app : %s", appPkgName),
+                                compileAppForIorap(appPkgName));
+                    }
+                }
 
                 // App launch times used for final calculation
                 else if (launch.getLaunchReason().contains(LAUNCH_ITERATION_PREFIX)) {
@@ -438,6 +497,74 @@
     }
 
     /**
+     * Compile the app package using compilerFilter and return true or false
+     * based on status of the compilation command.
+     */
+    private boolean compileAppForIorap(String appPkgName) throws IOException {
+        getInstrumentation().getUiAutomation().
+                executeShellCommand(IORAP_COMPILE_CMD);
+
+        for (int i = 0; i < IORAP_COMPILE_CMD_TIMEOUT; ++i) {
+            IorapCompilationStatus status = waitForIorapCompiled(appPkgName);
+            if (status == IorapCompilationStatus.COMPLETE) {
+                return true;
+            } else if (status == IorapCompilationStatus.INSUFFICIENT_TRACES) {
+                return false;
+            } // else INCOMPLETE. keep asking iorapd if it's done yet.
+            sleep(1000);
+        }
+
+        return false;
+    }
+
+    enum IorapCompilationStatus {
+        INCOMPLETE,
+        COMPLETE,
+        INSUFFICIENT_TRACES,
+    }
+    private IorapCompilationStatus waitForIorapCompiled(String appPkgName) throws IOException {
+        try (ParcelFileDescriptor result = getInstrumentation().getUiAutomation().
+                executeShellCommand(IORAP_DUMPSYS_CMD);
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
+                        new FileInputStream(result.getFileDescriptor())))) {
+            String line;
+            String prevLine = "";
+            while ((line = bufferedReader.readLine()) != null) {
+                // Match the indented VersionedComponentName string.
+                // "  com.google.android.deskclock/com.android.deskclock.DeskClock@62000712"
+                // Note: spaces are meaningful here.
+                if (prevLine.contains("  " + appPkgName) && prevLine.contains("@")) {
+                    // pre-requisite:
+                    // Compiled Status: Raw traces pending compilation (3)
+                    if (line.contains("Compiled Status: Usable compiled trace")) {
+                        return IorapCompilationStatus.COMPLETE;
+                    } else if (line.contains("Compiled Status: ") &&
+                            line.contains("more traces for compilation")) {
+                        //      Compiled Status: Need 1 more traces for compilation
+                        // No amount of waiting will help here because there were
+                        // insufficient traces made.
+                        return IorapCompilationStatus.INSUFFICIENT_TRACES;
+                    }
+                }
+
+                prevLine = line;
+            }
+            return IorapCompilationStatus.INCOMPLETE;
+        }
+    }
+
+    private String makeReasonForIorapTrialLaunch(int launchCount) {
+        String reason = IORAP_TRIAL_LAUNCH;
+        if (launchCount == 0) {
+            reason = IORAP_TRIAL_LAUNCH_FIRST;
+        }
+        if (launchCount == IORAP_TRIAL_LAUNCH_ITERATIONS - 1) {
+            reason = IORAP_TRIAL_LAUNCH_LAST;
+        }
+        return reason;
+    }
+
+    /**
      * If launch order is "cyclic" then apps will be launched one after the
      * other for each iteration count.
      * If launch order is "sequential" then each app will be launched for given number
@@ -448,20 +575,31 @@
             for (String compilerFilter : mCompilerFilters) {
                 if (mTrialLaunch) {
                     for (String app : mNameToResultKey.keySet()) {
-                        mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, TRIAL_LAUNCH));
+                        mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, TRIAL_LAUNCH, /*iorapEnabled*/false));
+                    }
+                }
+                if (mIorapTrialLaunch) {
+                    for (int launchCount = 0; launchCount < IORAP_TRIAL_LAUNCH_ITERATIONS; ++launchCount) {
+                        for (String app : mNameToResultKey.keySet()) {
+                            String reason = makeReasonForIorapTrialLaunch(launchCount);
+                            mLaunchOrderList.add(
+                                    new LaunchOrder(app, compilerFilter,
+                                            reason,
+                                            /*iorapEnabled*/true));
+                        }
                     }
                 }
                 for (int launchCount = 0; launchCount < mLaunchIterations; launchCount++) {
                     for (String app : mNameToResultKey.keySet()) {
                         mLaunchOrderList.add(new LaunchOrder(app, compilerFilter,
-                                  String.format(LAUNCH_ITERATION, launchCount)));
+                                  String.format(LAUNCH_ITERATION, launchCount), mIorapTrialLaunch));
                     }
                 }
                 if (mTraceDirectoryStr != null && !mTraceDirectoryStr.isEmpty()) {
                     for (int traceCount = 0; traceCount < mTraceLaunchCount; traceCount++) {
                         for (String app : mNameToResultKey.keySet()) {
                             mLaunchOrderList.add(new LaunchOrder(app, compilerFilter,
-                                      String.format(TRACE_ITERATION, traceCount)));
+                                      String.format(TRACE_ITERATION, traceCount), mIorapTrialLaunch));
                         }
                     }
                 }
@@ -470,16 +608,25 @@
             for (String compilerFilter : mCompilerFilters) {
                 for (String app : mNameToResultKey.keySet()) {
                     if (mTrialLaunch) {
-                        mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, TRIAL_LAUNCH));
+                        mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, TRIAL_LAUNCH, /*iorapEnabled*/false));
+                    }
+                    if (mIorapTrialLaunch) {
+                        for (int launchCount = 0; launchCount < IORAP_TRIAL_LAUNCH_ITERATIONS; ++launchCount) {
+                            String reason = makeReasonForIorapTrialLaunch(launchCount);
+                            mLaunchOrderList.add(
+                                    new LaunchOrder(app, compilerFilter,
+                                            reason,
+                                            /*iorapEnabled*/true));
+                        }
                     }
                     for (int launchCount = 0; launchCount < mLaunchIterations; launchCount++) {
                         mLaunchOrderList.add(new LaunchOrder(app, compilerFilter,
-                                String.format(LAUNCH_ITERATION, launchCount)));
+                                String.format(LAUNCH_ITERATION, launchCount), mIorapTrialLaunch));
                     }
                     if (mTraceDirectoryStr != null && !mTraceDirectoryStr.isEmpty()) {
                         for (int traceCount = 0; traceCount < mTraceLaunchCount; traceCount++) {
                             mLaunchOrderList.add(new LaunchOrder(app, compilerFilter,
-                                    String.format(TRACE_ITERATION, traceCount)));
+                                    String.format(TRACE_ITERATION, traceCount), mIorapTrialLaunch));
                         }
                     }
                 }
@@ -489,14 +636,92 @@
         }
     }
 
-    private void dropCache() {
-        if (mDropCache) {
+    private void dropCache(boolean override) {
+        if (mDropCache || override) {
             assertNotNull("Issue in dropping the cache",
                     getInstrumentation().getUiAutomation()
                             .executeShellCommand(DROP_CACHE_SCRIPT));
         }
     }
 
+    // [[ $(adb shell whoami) == "root" ]]
+    private boolean checkIfRoot() throws IOException {
+        String total = "";
+        try (ParcelFileDescriptor result = getInstrumentation().getUiAutomation().
+                executeShellCommand("whoami");
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
+                        new FileInputStream(result.getFileDescriptor())))) {
+            String line;
+            while ((line = bufferedReader.readLine()) != null) {
+                total = total + line;
+            }
+        }
+        return total.contains("root");
+    }
+
+    // Delete all db rows and files associated with a package in iorapd.
+    // Effectively deletes any raw or compiled trace files, unoptimizing the package in iorap.
+    private void purgeIorapPackage(String packageName) {
+        try {
+            if (!checkIfRoot()) {
+                throw new AssertionError("must be root to toggle iorapd; try adb root?");
+            }
+        } catch (IOException e) {
+            throw new AssertionError(e);
+        }
+
+        getInstrumentation().getUiAutomation()
+                .executeShellCommand("stop iorapd");
+        sleep(100);  // give iorapd enough time to stop.
+        getInstrumentation().getUiAutomation()
+                .executeShellCommand(String.format(IORAP_MAINTENANCE_CMD, packageName));
+        Log.v(TAG, "Executed: " + String.format(IORAP_MAINTENANCE_CMD, packageName));
+        getInstrumentation().getUiAutomation()
+                .executeShellCommand("start iorapd");
+        sleep(2000);  // give iorapd enough time to start up.
+    }
+
+    /**
+     * Toggle iorapd-based readahead and trace-collection.
+     * If iorapd is already enabled and enable is true, does nothing.
+     * If iorapd is already disabled and enable is false, does nothing.
+     */
+    private void toggleIorapStatus(boolean enable) {
+        boolean currentlyEnabled = false;
+        Log.v(TAG, "toggleIorapStatus " + Boolean.toString(enable));
+
+        // Do nothing if we are already enabled or disabled.
+        if (mIorapStatus == IorapStatus.ENABLED && enable) {
+            return;
+        } else if (mIorapStatus == IorapStatus.DISABLED && !enable) {
+            return;
+        }
+
+        try {
+            if (!checkIfRoot()) {
+                throw new AssertionError("must be root to toggle iorapd; try adb root?");
+            }
+        } catch (IOException e) {
+            throw new AssertionError(e);
+        }
+
+        getInstrumentation().getUiAutomation()
+                .executeShellCommand("stop iorapd");
+        getInstrumentation().getUiAutomation()
+                .executeShellCommand(String.format("setprop iorapd.perfetto.enable %b", enable));
+        getInstrumentation().getUiAutomation()
+                .executeShellCommand(String.format("setprop iorapd.readahead.enable %b", enable));
+        getInstrumentation().getUiAutomation()
+                .executeShellCommand("start iorapd");
+        sleep(2000);  // give enough time for iorapd to start back up.
+
+        if (enable) {
+            mIorapStatus = IorapStatus.ENABLED;
+        } else {
+            mIorapStatus = IorapStatus.DISABLED;
+        }
+    }
+
     private void parseArgs(Bundle args) {
         mNameToResultKey = new LinkedHashMap<String, String>();
         mNameToLaunchTime = new HashMap<>();
@@ -560,6 +785,8 @@
         mCycleCleanUp = Boolean.parseBoolean(args.getString(KEY_CYCLE_CLEAN));
         mTraceAll = Boolean.parseBoolean(args.getString(KEY_TRACE_ALL));
         mTrialLaunch = mTrialLaunch || Boolean.parseBoolean(args.getString(KEY_TRIAL_LAUNCH));
+        mIorapTrialLaunch = mIorapTrialLaunch ||
+                Boolean.parseBoolean(args.getString(KEY_IORAP_TRIAL_LAUNCH));
 
         if (mSimplePerfCmd != null && mSimplePerfAppOnly) {
             Log.w(TAG, String.format("Passing both %s and %s is not supported, ignoring %s",
@@ -738,11 +965,13 @@
         private String mApp;
         private String mCompilerFilter;
         private String mLaunchReason;
+        private boolean mIorapEnabled;
 
-        LaunchOrder(String app, String compilerFilter, String launchReason){
+        LaunchOrder(String app, String compilerFilter, String launchReason, boolean iorapEnabled) {
             mApp = app;
             mCompilerFilter = compilerFilter;
             mLaunchReason = launchReason;
+            mIorapEnabled = iorapEnabled;
         }
 
         public String getApp() {
@@ -764,6 +993,14 @@
         public void setLaunchReason(String launchReason) {
             mLaunchReason = launchReason;
         }
+
+        public void setIorapEnabled(boolean iorapEnabled) {
+            mIorapEnabled = iorapEnabled;
+        }
+
+        public boolean getIorapEnabled() {
+            return mIorapEnabled;
+        }
     }
 
     private class AppLaunchResult {
diff --git a/tests/net/AndroidManifest.xml b/tests/net/AndroidManifest.xml
index 480b12b..009f817 100644
--- a/tests/net/AndroidManifest.xml
+++ b/tests/net/AndroidManifest.xml
@@ -47,6 +47,7 @@
     <uses-permission android:name="android.permission.NETWORK_STACK" />
     <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" />
     <uses-permission android:name="android.permission.NETWORK_FACTORY" />
+    <uses-permission android:name="android.permission.NETWORK_STATS_PROVIDER" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/tests/net/common/Android.bp b/tests/net/common/Android.bp
index e44d460..46d680f 100644
--- a/tests/net/common/Android.bp
+++ b/tests/net/common/Android.bp
@@ -20,6 +20,7 @@
     name: "FrameworksNetCommonTests",
     srcs: ["java/**/*.java", "java/**/*.kt"],
     static_libs: [
+        "androidx.core_core",
         "androidx.test.rules",
         "junit",
         "mockito-target-minus-junit4",
diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java
index 48b65e5..8de27e8 100644
--- a/tests/net/common/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/common/java/android/net/LinkPropertiesTest.java
@@ -29,12 +29,19 @@
 
 import android.net.LinkProperties.ProvisioningChange;
 import android.net.util.LinkPropertiesUtils.CompareResult;
+import android.os.Build;
 import android.system.OsConstants;
 import android.util.ArraySet;
 
+import androidx.core.os.BuildCompat;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -50,6 +57,9 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class LinkPropertiesTest {
+    @Rule
+    public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
+
     private static final InetAddress ADDRV4 = address("75.208.6.1");
     private static final InetAddress ADDRV6 = address("2001:0db8:85a3:0000:0000:8a2e:0370:7334");
     private static final InetAddress DNS1 = address("75.208.7.1");
@@ -76,13 +86,23 @@
     private static final LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128);
     private static final LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64");
     private static final Uri CAPPORT_API_URL = Uri.parse("https://test.example.com/capportapi");
-    private static final CaptivePortalData CAPPORT_DATA = new CaptivePortalData.Builder()
-            .setVenueInfoUrl(Uri.parse("https://test.example.com/venue")).build();
+
+    // CaptivePortalData cannot be in a constant as it does not exist on Q.
+    // The test runner also crashes when scanning for tests if it is a return type.
+    private static Object getCaptivePortalData() {
+        return new CaptivePortalData.Builder()
+                .setVenueInfoUrl(Uri.parse("https://test.example.com/venue")).build();
+    }
 
     private static InetAddress address(String addrString) {
         return InetAddresses.parseNumericAddress(addrString);
     }
 
+    private static boolean isAtLeastR() {
+        // BuildCompat.isAtLeastR is documented to return false on release SDKs (including R)
+        return Build.VERSION.SDK_INT > Build.VERSION_CODES.Q || BuildCompat.isAtLeastR();
+    }
+
     private void checkEmpty(final LinkProperties lp) {
         assertEquals(0, lp.getAllInterfaceNames().size());
         assertEquals(0, lp.getAllAddresses().size());
@@ -98,14 +118,17 @@
         assertNull(lp.getHttpProxy());
         assertNull(lp.getTcpBufferSizes());
         assertNull(lp.getNat64Prefix());
-        assertNull(lp.getDhcpServerAddress());
         assertFalse(lp.isProvisioned());
         assertFalse(lp.isIpv4Provisioned());
         assertFalse(lp.isIpv6Provisioned());
         assertFalse(lp.isPrivateDnsActive());
-        assertFalse(lp.isWakeOnLanSupported());
-        assertNull(lp.getCaptivePortalApiUrl());
-        assertNull(lp.getCaptivePortalData());
+
+        if (isAtLeastR()) {
+            assertNull(lp.getDhcpServerAddress());
+            assertFalse(lp.isWakeOnLanSupported());
+            assertNull(lp.getCaptivePortalApiUrl());
+            assertNull(lp.getCaptivePortalData());
+        }
     }
 
     private LinkProperties makeTestObject() {
@@ -127,10 +150,12 @@
         lp.setMtu(MTU);
         lp.setTcpBufferSizes(TCP_BUFFER_SIZES);
         lp.setNat64Prefix(new IpPrefix("2001:db8:0:64::/96"));
-        lp.setDhcpServerAddress(DHCPSERVER);
-        lp.setWakeOnLanSupported(true);
-        lp.setCaptivePortalApiUrl(CAPPORT_API_URL);
-        lp.setCaptivePortalData(CAPPORT_DATA);
+        if (isAtLeastR()) {
+            lp.setDhcpServerAddress(DHCPSERVER);
+            lp.setWakeOnLanSupported(true);
+            lp.setCaptivePortalApiUrl(CAPPORT_API_URL);
+            lp.setCaptivePortalData((CaptivePortalData) getCaptivePortalData());
+        }
         return lp;
     }
 
@@ -169,14 +194,19 @@
         assertTrue(source.isIdenticalTcpBufferSizes(target));
         assertTrue(target.isIdenticalTcpBufferSizes(source));
 
-        assertTrue(source.isIdenticalWakeOnLan(target));
-        assertTrue(target.isIdenticalWakeOnLan(source));
+        if (isAtLeastR()) {
+            assertTrue(source.isIdenticalDhcpServerAddress(target));
+            assertTrue(source.isIdenticalDhcpServerAddress(source));
 
-        assertTrue(source.isIdenticalCaptivePortalApiUrl(target));
-        assertTrue(target.isIdenticalCaptivePortalApiUrl(source));
+            assertTrue(source.isIdenticalWakeOnLan(target));
+            assertTrue(target.isIdenticalWakeOnLan(source));
 
-        assertTrue(source.isIdenticalCaptivePortalData(target));
-        assertTrue(target.isIdenticalCaptivePortalData(source));
+            assertTrue(source.isIdenticalCaptivePortalApiUrl(target));
+            assertTrue(target.isIdenticalCaptivePortalApiUrl(source));
+
+            assertTrue(source.isIdenticalCaptivePortalData(target));
+            assertTrue(target.isIdenticalCaptivePortalData(source));
+        }
 
         // Check result of equals().
         assertTrue(source.equals(target));
@@ -415,14 +445,20 @@
         // Check comparisons work.
         LinkProperties lp2 = new LinkProperties(lp);
         assertAllRoutesHaveInterface("wlan0", lp2);
-        assertEquals(0, lp.compareAllRoutes(lp2).added.size());
-        assertEquals(0, lp.compareAllRoutes(lp2).removed.size());
+        // LinkProperties#compareAllRoutes exists both in R and before R, but the return type
+        // changed in R, so a test compiled with the R version of LinkProperties cannot run on Q.
+        if (isAtLeastR()) {
+            assertEquals(0, lp.compareAllRoutes(lp2).added.size());
+            assertEquals(0, lp.compareAllRoutes(lp2).removed.size());
+        }
 
         lp2.setInterfaceName("p2p0");
         assertAllRoutesHaveInterface("p2p0", lp2);
         assertAllRoutesNotHaveInterface("wlan0", lp2);
-        assertEquals(3, lp.compareAllRoutes(lp2).added.size());
-        assertEquals(3, lp.compareAllRoutes(lp2).removed.size());
+        if (isAtLeastR()) {
+            assertEquals(3, lp.compareAllRoutes(lp2).added.size());
+            assertEquals(3, lp.compareAllRoutes(lp2).removed.size());
+        }
 
         // Remove route with incorrect interface, no route removed.
         lp.removeRoute(new RouteInfo(prefix2, null, null));
@@ -450,6 +486,8 @@
         assertEquals(1, rmnet0.getLinkAddresses().size());
         assertEquals(1, rmnet0.getAllAddresses().size());
         assertEquals(1, rmnet0.getAllLinkAddresses().size());
+        assertEquals(1, rmnet0.getAllInterfaceNames().size());
+        assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0));
 
         rmnet0.addStackedLink(clat4);
         assertEquals(1, rmnet0.getStackedLinks().size());
@@ -457,6 +495,9 @@
         assertEquals(1, rmnet0.getLinkAddresses().size());
         assertEquals(2, rmnet0.getAllAddresses().size());
         assertEquals(2, rmnet0.getAllLinkAddresses().size());
+        assertEquals(2, rmnet0.getAllInterfaceNames().size());
+        assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0));
+        assertEquals("clat4", rmnet0.getAllInterfaceNames().get(1));
 
         rmnet0.addStackedLink(clat4);
         assertEquals(1, rmnet0.getStackedLinks().size());
@@ -464,6 +505,9 @@
         assertEquals(1, rmnet0.getLinkAddresses().size());
         assertEquals(2, rmnet0.getAllAddresses().size());
         assertEquals(2, rmnet0.getAllLinkAddresses().size());
+        assertEquals(2, rmnet0.getAllInterfaceNames().size());
+        assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0));
+        assertEquals("clat4", rmnet0.getAllInterfaceNames().get(1));
 
         assertEquals(0, clat4.getStackedLinks().size());
 
@@ -483,6 +527,8 @@
         assertEquals(1, rmnet0.getLinkAddresses().size());
         assertEquals(1, rmnet0.getAllAddresses().size());
         assertEquals(1, rmnet0.getAllLinkAddresses().size());
+        assertEquals(1, rmnet0.getAllInterfaceNames().size());
+        assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0));
 
         assertFalse(rmnet0.removeStackedLink("clat4"));
     }
@@ -906,7 +952,7 @@
 
     }
 
-    @Test
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
     public void testCompareResult() {
         // Either adding or removing items
         compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(1),
@@ -943,8 +989,7 @@
         assertEquals(new ArraySet<>(expectRemoved), (new ArraySet<>(result.removed)));
     }
 
-    @Test
-    public void testLinkPropertiesParcelable() throws Exception {
+    private static LinkProperties makeLinkPropertiesForParceling() {
         LinkProperties source = new LinkProperties();
         source.setInterfaceName(NAME);
 
@@ -978,17 +1023,29 @@
 
         source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96"));
 
-        source.setWakeOnLanSupported(true);
-        source.setCaptivePortalApiUrl(CAPPORT_API_URL);
-        source.setCaptivePortalData(CAPPORT_DATA);
-
-        source.setDhcpServerAddress((Inet4Address) GATEWAY1);
-
         final LinkProperties stacked = new LinkProperties();
         stacked.setInterfaceName("test-stacked");
         source.addStackedLink(stacked);
 
-        assertParcelSane(source.makeSensitiveFieldsParcelingCopy(), 18 /* fieldCount */);
+        return source;
+    }
+
+    @Test @IgnoreAfter(Build.VERSION_CODES.Q)
+    public void testLinkPropertiesParcelable_Q() throws Exception {
+        final LinkProperties source = makeLinkPropertiesForParceling();
+        assertParcelSane(source, 14 /* fieldCount */);
+    }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    public void testLinkPropertiesParcelable() throws Exception {
+        final LinkProperties source = makeLinkPropertiesForParceling();
+
+        source.setWakeOnLanSupported(true);
+        source.setCaptivePortalApiUrl(CAPPORT_API_URL);
+        source.setCaptivePortalData((CaptivePortalData) getCaptivePortalData());
+        source.setDhcpServerAddress((Inet4Address) GATEWAY1);
+        assertParcelSane(new LinkProperties(source, true /* parcelSensitiveFields */),
+                18 /* fieldCount */);
 
         // Verify that without using a sensitiveFieldsParcelingCopy, sensitive fields are cleared.
         final LinkProperties sanitized = new LinkProperties(source);
@@ -997,7 +1054,8 @@
         assertEquals(sanitized, parcelingRoundTrip(source));
     }
 
-    @Test
+    // Parceling of the scope was broken until Q-QPR2
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
     public void testLinkLocalDnsServerParceling() throws Exception {
         final String strAddress = "fe80::1%lo";
         final LinkProperties lp = new LinkProperties();
@@ -1120,7 +1178,7 @@
         assertFalse(lp.isPrivateDnsActive());
     }
 
-    @Test
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
     public void testDhcpServerAddress() {
         final LinkProperties lp = makeTestObject();
         assertEquals(DHCPSERVER, lp.getDhcpServerAddress());
@@ -1129,7 +1187,7 @@
         assertNull(lp.getDhcpServerAddress());
     }
 
-    @Test
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
     public void testWakeOnLanSupported() {
         final LinkProperties lp = makeTestObject();
         assertTrue(lp.isWakeOnLanSupported());
@@ -1138,7 +1196,7 @@
         assertFalse(lp.isWakeOnLanSupported());
     }
 
-    @Test
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
     public void testCaptivePortalApiUrl() {
         final LinkProperties lp = makeTestObject();
         assertEquals(CAPPORT_API_URL, lp.getCaptivePortalApiUrl());
@@ -1147,12 +1205,56 @@
         assertNull(lp.getCaptivePortalApiUrl());
     }
 
-    @Test
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
     public void testCaptivePortalData() {
         final LinkProperties lp = makeTestObject();
-        assertEquals(CAPPORT_DATA, lp.getCaptivePortalData());
+        assertEquals(getCaptivePortalData(), lp.getCaptivePortalData());
 
         lp.clear();
         assertNull(lp.getCaptivePortalData());
     }
+
+    private LinkProperties makeIpv4LinkProperties() {
+        final LinkProperties linkProperties = new LinkProperties();
+        linkProperties.setInterfaceName(NAME);
+        linkProperties.addLinkAddress(LINKADDRV4);
+        linkProperties.addDnsServer(DNS1);
+        linkProperties.addRoute(new RouteInfo(GATEWAY1));
+        linkProperties.addRoute(new RouteInfo(GATEWAY2));
+        return linkProperties;
+    }
+
+    private LinkProperties makeIpv6LinkProperties() {
+        final LinkProperties linkProperties = new LinkProperties();
+        linkProperties.setInterfaceName(NAME);
+        linkProperties.addLinkAddress(LINKADDRV6);
+        linkProperties.addDnsServer(DNS6);
+        linkProperties.addRoute(new RouteInfo(GATEWAY61));
+        linkProperties.addRoute(new RouteInfo(GATEWAY62));
+        return linkProperties;
+    }
+
+    @Test
+    public void testHasIpv4DefaultRoute() {
+        final LinkProperties Ipv4 = makeIpv4LinkProperties();
+        assertTrue(Ipv4.hasIpv4DefaultRoute());
+        final LinkProperties Ipv6 = makeIpv6LinkProperties();
+        assertFalse(Ipv6.hasIpv4DefaultRoute());
+    }
+
+    @Test
+    public void testHasIpv4DnsServer() {
+        final LinkProperties Ipv4 = makeIpv4LinkProperties();
+        assertTrue(Ipv4.hasIpv4DnsServer());
+        final LinkProperties Ipv6 = makeIpv6LinkProperties();
+        assertFalse(Ipv6.hasIpv4DnsServer());
+    }
+
+    @Test
+    public void testHasIpv6DnsServer() {
+        final LinkProperties Ipv4 = makeIpv4LinkProperties();
+        assertFalse(Ipv4.hasIpv6DnsServer());
+        final LinkProperties Ipv6 = makeIpv6LinkProperties();
+        assertTrue(Ipv6.hasIpv6DnsServer());
+    }
 }
diff --git a/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
new file mode 100644
index 0000000..ef15b66
--- /dev/null
+++ b/tests/net/common/java/android/net/MatchAllNetworkSpecifierTest.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net
+
+import android.net.wifi.aware.DiscoverySession
+import android.net.wifi.aware.PeerHandle
+import android.net.wifi.aware.WifiAwareNetworkSpecifier
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+
+import com.android.testutils.assertParcelSane
+
+import java.lang.IllegalStateException
+
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class MatchAllNetworkSpecifierTest {
+    @Test
+    fun testParcel() {
+        assertParcelSane(MatchAllNetworkSpecifier(), 0)
+    }
+
+    @Test(expected = IllegalStateException::class)
+    fun testSatisfiedBy() {
+        val specifier = MatchAllNetworkSpecifier()
+        val discoverySession = Mockito.mock(DiscoverySession::class.java)
+        val peerHandle = Mockito.mock(PeerHandle::class.java)
+        val wifiAwareNetworkSpecifier = WifiAwareNetworkSpecifier.Builder(discoverySession,
+                peerHandle).build()
+        specifier.satisfiedBy(wifiAwareNetworkSpecifier)
+    }
+}
diff --git a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
index 173dbd1..de65ba2 100644
--- a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
+++ b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
@@ -22,6 +22,9 @@
 import com.android.testutils.DevSdkIgnoreRule
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
 import com.android.testutils.assertParcelSane
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -43,4 +46,27 @@
         }.build()
         assertParcelSane(config, 9)
     }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    fun testBuilder() {
+        val config = NetworkAgentConfig.Builder().apply {
+            setExplicitlySelected(true)
+            setLegacyType(ConnectivityManager.TYPE_ETHERNET)
+            setSubscriberId("MySubId")
+            setPartialConnectivityAcceptable(false)
+            setUnvalidatedConnectivityAcceptable(true)
+            setLegacyTypeName("TEST_NETWORK")
+            disableNat64Detection()
+            disableProvisioningNotification()
+        }.build()
+
+        assertTrue(config.isExplicitlySelected())
+        assertEquals(ConnectivityManager.TYPE_ETHERNET, config.getLegacyType())
+        assertEquals("MySubId", config.getSubscriberId())
+        assertFalse(config.isPartialConnectivityAcceptable())
+        assertTrue(config.isUnvalidatedConnectivityAcceptable())
+        assertEquals("TEST_NETWORK", config.getLegacyTypeName())
+        assertFalse(config.isNat64DetectionEnabled())
+        assertFalse(config.isProvisioningNotificationEnabled())
+    }
 }
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index efea91a..916c339 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -48,9 +48,11 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.os.Build;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.ArraySet;
 
+import androidx.core.os.BuildCompat;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
@@ -64,6 +66,13 @@
     private static final String TEST_SSID = "TEST_SSID";
     private static final String DIFFERENT_TEST_SSID = "DIFFERENT_TEST_SSID";
 
+    private boolean isAtLeastR() {
+        // BuildCompat.isAtLeastR() is used to check the Android version before releasing Android R.
+        // Build.VERSION.SDK_INT > Build.VERSION_CODES.Q is used to check the Android version after
+        // releasing Android R.
+        return BuildCompat.isAtLeastR() || Build.VERSION.SDK_INT > Build.VERSION_CODES.Q;
+    }
+
     @Test
     public void testMaybeMarkCapabilitiesRestricted() {
         // verify EIMS is restricted
@@ -269,25 +278,36 @@
             .setUids(uids)
             .addCapability(NET_CAPABILITY_EIMS)
             .addCapability(NET_CAPABILITY_NOT_METERED);
-        netCap.setOwnerUid(123);
+        if (isAtLeastR()) {
+            netCap.setOwnerUid(123);
+        }
         assertParcelingIsLossless(netCap);
         netCap.setSSID(TEST_SSID);
-        assertParcelSane(netCap, 15);
+        testParcelSane(netCap);
     }
 
     @Test
     public void testParcelNetworkCapabilitiesWithRequestorUidAndPackageName() {
         final NetworkCapabilities netCap = new NetworkCapabilities()
                 .addCapability(NET_CAPABILITY_INTERNET)
-                .setRequestorUid(9304)
-                .setRequestorPackageName("com.android.test")
                 .addCapability(NET_CAPABILITY_EIMS)
                 .addCapability(NET_CAPABILITY_NOT_METERED);
+        if (isAtLeastR()) {
+            netCap.setRequestorPackageName("com.android.test");
+            netCap.setRequestorUid(9304);
+        }
         assertParcelingIsLossless(netCap);
         netCap.setSSID(TEST_SSID);
-        assertParcelSane(netCap, 15);
+        testParcelSane(netCap);
     }
 
+    private void testParcelSane(NetworkCapabilities cap) {
+        if (isAtLeastR()) {
+            assertParcelSane(cap, 15);
+        } else {
+            assertParcelSane(cap, 11);
+        }
+    }
 
     @Test
     public void testOemPaid() {
@@ -443,7 +463,9 @@
 
         nc1.setSSID(TEST_SSID);
         nc2.combineCapabilities(nc1);
-        assertTrue(TEST_SSID.equals(nc2.getSSID()));
+        if (isAtLeastR()) {
+            assertTrue(TEST_SSID.equals(nc2.getSsid()));
+        }
 
         // Because they now have the same SSID, the following call should not throw
         nc2.combineCapabilities(nc1);
@@ -581,12 +603,16 @@
         // from nc2.
         assertFalse(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING));
         assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_NOT_ROAMING));
-        assertTrue(TEST_SSID.equals(nc2.getSSID()));
+        if (isAtLeastR()) {
+            assertTrue(TEST_SSID.equals(nc2.getSsid()));
+        }
 
         nc1.setSSID(DIFFERENT_TEST_SSID);
         nc2.set(nc1);
         assertEquals(nc1, nc2);
-        assertTrue(DIFFERENT_TEST_SSID.equals(nc2.getSSID()));
+        if (isAtLeastR()) {
+            assertTrue(DIFFERENT_TEST_SSID.equals(nc2.getSsid()));
+        }
 
         nc1.setUids(uidRange(10, 13));
         nc2.set(nc1);  // Overwrites, as opposed to combineCapabilities
diff --git a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
index f4f804a..8480544 100644
--- a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
@@ -21,17 +21,31 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Arrays;
+
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class ApfCapabilitiesTest {
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getContext();
+    }
+
     @Test
     public void testConstructAndParcel() {
         final ApfCapabilities caps = new ApfCapabilities(123, 456, 789);
@@ -59,4 +73,27 @@
         caps = new ApfCapabilities(4 /* apfVersionSupported */, 5, 6);
         assertTrue(caps.hasDataAccess());
     }
+
+    @Test
+    public void testGetApfDrop8023Frames() {
+        // Get com.android.internal.R.bool.config_apfDrop802_3Frames. The test cannot directly
+        // use R.bool.config_apfDrop802_3Frames because that is not a stable resource ID.
+        final int resId = mContext.getResources().getIdentifier("config_apfDrop802_3Frames",
+                "bool", "android");
+        final boolean shouldDrop8023Frames = mContext.getResources().getBoolean(resId);
+        final boolean actual = ApfCapabilities.getApfDrop8023Frames();
+        assertEquals(shouldDrop8023Frames, actual);
+    }
+
+    @Test
+    public void testGetApfEtherTypeBlackList() {
+        // Get com.android.internal.R.array.config_apfEthTypeBlackList. The test cannot directly
+        // use R.array.config_apfEthTypeBlackList because that is not a stable resource ID.
+        final int resId = mContext.getResources().getIdentifier("config_apfEthTypeBlackList",
+                "array", "android");
+        final int[] blacklistedEtherTypeArray = mContext.getResources().getIntArray(resId);
+        final int[] actual = ApfCapabilities.getApfEtherTypeBlackList();
+        assertNotNull(actual);
+        assertTrue(Arrays.equals(blacklistedEtherTypeArray, actual));
+    }
 }
diff --git a/tests/net/common/java/android/net/util/SocketUtilsTest.kt b/tests/net/common/java/android/net/util/SocketUtilsTest.kt
index 9c7cfb0..aaf97f3 100644
--- a/tests/net/common/java/android/net/util/SocketUtilsTest.kt
+++ b/tests/net/common/java/android/net/util/SocketUtilsTest.kt
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package android.net.util;
+package android.net.util
 
+import android.os.Build
 import android.system.NetlinkSocketAddress
 import android.system.Os
 import android.system.OsConstants.AF_INET
@@ -26,18 +27,26 @@
 import android.system.PacketSocketAddress
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.Assert.fail
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 
 private const val TEST_INDEX = 123
 private const val TEST_PORT = 555
+private const val FF_BYTE = 0xff.toByte()
+
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class SocketUtilsTest {
+    @Rule @JvmField
+    val ignoreRule = DevSdkIgnoreRule()
+
     @Test
     fun testMakeNetlinkSocketAddress() {
         val nlAddress = SocketUtils.makeNetlinkSocketAddress(TEST_PORT, RTMGRP_NEIGH)
@@ -50,16 +59,21 @@
     }
 
     @Test
-    fun testMakePacketSocketAddress() {
+    fun testMakePacketSocketAddress_Q() {
         val pkAddress = SocketUtils.makePacketSocketAddress(ETH_P_ALL, TEST_INDEX)
         assertTrue("Not PacketSocketAddress object", pkAddress is PacketSocketAddress)
 
-        val ff = 0xff.toByte()
-        val pkAddress2 = SocketUtils.makePacketSocketAddress(TEST_INDEX,
-                byteArrayOf(ff, ff, ff, ff, ff, ff))
+        val pkAddress2 = SocketUtils.makePacketSocketAddress(TEST_INDEX, ByteArray(6) { FF_BYTE })
         assertTrue("Not PacketSocketAddress object", pkAddress2 is PacketSocketAddress)
     }
 
+    @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+    fun testMakePacketSocketAddress() {
+        val pkAddress = SocketUtils.makePacketSocketAddress(
+                ETH_P_ALL, TEST_INDEX, ByteArray(6) { FF_BYTE })
+        assertTrue("Not PacketSocketAddress object", pkAddress is PacketSocketAddress)
+    }
+
     @Test
     fun testCloseSocket() {
         // Expect no exception happening with null object.
diff --git a/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java b/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java
index 8eb5cfa..1d6c107 100644
--- a/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java
@@ -304,12 +304,12 @@
     }
 
     @Test
-    public void testConnectivityDiagnosticsCallbackOnConnectivityReport() {
-        mBinder.onConnectivityReport(createSampleConnectivityReport());
+    public void testConnectivityDiagnosticsCallbackOnConnectivityReportAvailable() {
+        mBinder.onConnectivityReportAvailable(createSampleConnectivityReport());
 
         // The callback will be invoked synchronously by inline executor. Immediately check the
         // latch without waiting.
-        verify(mCb).onConnectivityReport(eq(createSampleConnectivityReport()));
+        verify(mCb).onConnectivityReportAvailable(eq(createSampleConnectivityReport()));
     }
 
     @Test
diff --git a/tests/net/java/android/net/IpMemoryStoreTest.java b/tests/net/java/android/net/IpMemoryStoreTest.java
index b81ca36..442ac56 100644
--- a/tests/net/java/android/net/IpMemoryStoreTest.java
+++ b/tests/net/java/android/net/IpMemoryStoreTest.java
@@ -35,6 +35,7 @@
 import android.net.ipmemorystore.NetworkAttributes;
 import android.net.ipmemorystore.NetworkAttributesParcelable;
 import android.net.ipmemorystore.Status;
+import android.net.networkstack.ModuleNetworkStackClient;
 import android.os.RemoteException;
 
 import androidx.test.filters.SmallTest;
@@ -67,7 +68,7 @@
     @Mock
     Context mMockContext;
     @Mock
-    NetworkStackClient mNetworkStackClient;
+    ModuleNetworkStackClient mModuleNetworkStackClient;
     @Mock
     IIpMemoryStore mMockService;
     @Mock
@@ -90,14 +91,14 @@
                 ((IIpMemoryStoreCallbacks) invocation.getArgument(0))
                         .onIpMemoryStoreFetched(mMockService);
                 return null;
-            }).when(mNetworkStackClient).fetchIpMemoryStore(any());
+            }).when(mModuleNetworkStackClient).fetchIpMemoryStore(any());
         } else {
-            doNothing().when(mNetworkStackClient).fetchIpMemoryStore(mCbCaptor.capture());
+            doNothing().when(mModuleNetworkStackClient).fetchIpMemoryStore(mCbCaptor.capture());
         }
         mStore = new IpMemoryStore(mMockContext) {
             @Override
-            protected NetworkStackClient getNetworkStackClient() {
-                return mNetworkStackClient;
+            protected ModuleNetworkStackClient getModuleNetworkStackClient(Context ctx) {
+                return mModuleNetworkStackClient;
             }
         };
     }
diff --git a/tests/net/java/android/net/NetworkStatsTest.java b/tests/net/java/android/net/NetworkStatsTest.java
index 33d77d2..e71d599 100644
--- a/tests/net/java/android/net/NetworkStatsTest.java
+++ b/tests/net/java/android/net/NetworkStatsTest.java
@@ -64,15 +64,15 @@
     @Test
     public void testFindIndex() throws Exception {
         final NetworkStats stats = new NetworkStats(TEST_START, 5)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 1024L, 8L, 0L, 0L, 10)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 0L, 0L, 1024L, 8L, 11)
-                .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 1024L, 8L, 1024L, 8L, 12)
-                .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
+                .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
                         DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12);
 
         assertEquals(4, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES,
@@ -94,21 +94,21 @@
     @Test
     public void testFindIndexHinted() {
         final NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 1024L, 8L, 0L, 0L, 10)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11)
-                .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12)
-                .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 1024L, 8L, 0L, 0L, 10)
-                .addEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 0L, 0L, 1024L, 8L, 11)
-                .addEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 0L, 0L, 1024L, 8L, 11)
-                .addEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 1024L, 8L, 1024L, 8L, 12)
-                .addEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
+                .insertEntry(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
                         DEFAULT_NETWORK_NO, 1024L, 8L, 1024L, 8L, 12);
 
         // verify that we correctly find across regardless of hinting
@@ -143,27 +143,27 @@
         assertEquals(0, stats.size());
         assertEquals(4, stats.internalSize());
 
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 DEFAULT_NETWORK_YES, 1L, 1L, 2L, 2L, 3);
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 DEFAULT_NETWORK_NO, 2L, 2L, 2L, 2L, 4);
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
                 DEFAULT_NETWORK_YES, 3L, 3L, 2L, 2L, 5);
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
                 DEFAULT_NETWORK_NO, 3L, 3L, 2L, 2L, 5);
 
         assertEquals(4, stats.size());
         assertEquals(4, stats.internalSize());
 
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 DEFAULT_NETWORK_NO, 4L, 40L, 4L, 40L, 7);
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 DEFAULT_NETWORK_YES, 5L, 50L, 4L, 40L, 8);
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 DEFAULT_NETWORK_NO, 6L, 60L, 5L, 50L, 10);
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
                 DEFAULT_NETWORK_YES, 7L, 70L, 5L, 50L, 11);
-        stats.addEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
+        stats.insertEntry(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES,
                 DEFAULT_NETWORK_NO, 7L, 70L, 5L, 50L, 11);
 
         assertEquals(9, stats.size());
@@ -193,8 +193,8 @@
     public void testCombineExisting() throws Exception {
         final NetworkStats stats = new NetworkStats(TEST_START, 10);
 
-        stats.addEntry(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 10);
-        stats.addEntry(TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2);
+        stats.insertEntry(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 10);
+        stats.insertEntry(TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2);
         stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L,
                 -128L, -1L, -1);
 
@@ -215,12 +215,12 @@
     @Test
     public void testSubtractIdenticalData() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
 
         final NetworkStats after = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
 
         final NetworkStats result = after.subtract(before);
 
@@ -234,12 +234,12 @@
     @Test
     public void testSubtractIdenticalRows() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
 
         final NetworkStats after = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1025L, 9L, 2L, 1L, 15)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 1028L, 9L, 20);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1025L, 9L, 2L, 1L, 15)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 1028L, 9L, 20);
 
         final NetworkStats result = after.subtract(before);
 
@@ -253,13 +253,13 @@
     @Test
     public void testSubtractNewRows() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
 
         final NetworkStats after = new NetworkStats(TEST_START, 3)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12)
-                .addEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12)
+                .insertEntry(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20);
 
         final NetworkStats result = after.subtract(before);
 
@@ -275,11 +275,11 @@
     @Test
     public void testSubtractMissingRows() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0)
-                .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2048L, 0L, 0L, 0L, 0);
+                .insertEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 0L, 0L, 0L, 0)
+                .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2048L, 0L, 0L, 0L, 0);
 
         final NetworkStats after = new NetworkStats(TEST_START, 1)
-                .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2049L, 2L, 3L, 4L, 0);
+                .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 2049L, 2L, 3L, 4L, 0);
 
         final NetworkStats result = after.subtract(before);
 
@@ -293,40 +293,40 @@
     @Test
     public void testTotalBytes() throws Exception {
         final NetworkStats iface = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 256L, 0L, 0L, 0L, 0L);
+                .insertEntry(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, 128L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 256L, 0L, 0L, 0L, 0L);
         assertEquals(384L, iface.getTotalBytes());
 
         final NetworkStats uidSet = new NetworkStats(TEST_START, 3)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE, 101, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
         assertEquals(96L, uidSet.getTotalBytes());
 
         final NetworkStats uidTag = new NetworkStats(TEST_START, 6)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L);
         assertEquals(64L, uidTag.getTotalBytes());
 
         final NetworkStats uidMetered = new NetworkStats(TEST_START, 3)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L);
         assertEquals(96L, uidMetered.getTotalBytes());
 
         final NetworkStats uidRoaming = new NetworkStats(TEST_START, 3)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L);
         assertEquals(96L, uidRoaming.getTotalBytes());
     }
@@ -343,11 +343,11 @@
     @Test
     public void testGroupedByIfaceAll() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
-                .addEntry(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L)
-                .addEntry(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 128L, 8L, 0L, 2L, 20L)
-                .addEntry(IFACE_ALL, 101, SET_ALL, TAG_NONE, METERED_NO, ROAMING_YES,
+                .insertEntry(IFACE_ALL, 101, SET_ALL, TAG_NONE, METERED_NO, ROAMING_YES,
                         DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L);
         final NetworkStats grouped = uidStats.groupedByIface();
 
@@ -361,19 +361,19 @@
     @Test
     public void testGroupedByIface() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 7)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 64L, 4L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
                         DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L);
 
         final NetworkStats grouped = uidStats.groupedByIface();
@@ -390,19 +390,19 @@
     @Test
     public void testAddAllValues() {
         final NetworkStats first = new NetworkStats(TEST_START, 5)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
+                .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L);
 
         final NetworkStats second = new NetworkStats(TEST_START, 2)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 32L, 0L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
+                .insertEntry(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
                         DEFAULT_NETWORK_YES, 32L, 0L, 0L, 0L, 0L);
 
         first.combineAllValues(second);
@@ -421,19 +421,19 @@
     @Test
     public void testGetTotal() {
         final NetworkStats stats = new NetworkStats(TEST_START, 7)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 128L, 8L, 0L, 2L, 20L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 64L, 4L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 512L,32L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 128L, 8L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
                         DEFAULT_NETWORK_NO, 128L, 8L, 0L, 0L, 0L);
 
         assertValues(stats.getTotal(null), 1408L, 88L, 0L, 2L, 20L);
@@ -459,7 +459,7 @@
         assertEquals(0, after.size());
 
         // Test 1 item stats.
-        before.addEntry(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, 1L, 128L, 0L, 2L, 20L);
+        before.insertEntry(TEST_IFACE, 99, SET_DEFAULT, TAG_NONE, 1L, 128L, 0L, 2L, 20L);
         after = before.clone();
         after.removeUids(new int[0]);
         assertEquals(1, after.size());
@@ -469,12 +469,12 @@
         assertEquals(0, after.size());
 
         // Append remaining test items.
-        before.addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 2L, 64L, 0L, 2L, 20L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 4L, 32L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 16L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 8L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 4L, 0L, 0L, 0L)
-                .addEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 64L, 2L, 0L, 0L, 0L);
+        before.insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 2L, 64L, 0L, 2L, 20L)
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 4L, 32L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 16L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 16L, 8L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 32L, 4L, 0L, 0L, 0L)
+                .insertEntry(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 64L, 2L, 0L, 0L, 0L);
         assertEquals(7, before.size());
 
         // Test remove with empty uid list.
@@ -505,12 +505,12 @@
     @Test
     public void testClone() throws Exception {
         final NetworkStats original = new NetworkStats(TEST_START, 5)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L);
 
         // make clone and mutate original
         final NetworkStats clone = original.clone();
-        original.addEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L);
+        original.insertEntry(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L);
 
         assertEquals(3, original.size());
         assertEquals(2, clone.size());
@@ -523,8 +523,8 @@
     public void testAddWhenEmpty() throws Exception {
         final NetworkStats red = new NetworkStats(TEST_START, -1);
         final NetworkStats blue = new NetworkStats(TEST_START, 5)
-                .addEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
-                .addEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L);
+                .insertEntry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
+                .insertEntry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L);
 
         // We're mostly checking that we don't crash
         red.combineAllValues(blue);
@@ -537,37 +537,37 @@
         final String underlyingIface = "wlan0";
         final int testTag1 = 8888;
         NetworkStats delta = new NetworkStats(TEST_START, 17)
-                .addEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 39605L, 46L, 12259L, 55L, 0L)
-                .addEntry(tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L)
-                .addEntry(tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 72667L, 197L, 43909L, 241L, 0L)
-                .addEntry(tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 9297L, 17L, 4128L, 21L, 0L)
                 // VPN package also uses some traffic through unprotected network.
-                .addEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 4983L, 10L, 1801L, 12L, 0L)
-                .addEntry(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L)
                 // Tag entries
-                .addEntry(tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 21691L, 41L, 13820L, 51L, 0L)
-                .addEntry(tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 1281L, 2L, 665L, 2L, 0L)
                 // Irrelevant entries
-                .addEntry(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 1685L, 5L, 2070L, 6L, 0L)
                 // Underlying Iface entries
-                .addEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 5178L, 8L, 2139L, 11L, 0L)
-                .addEntry(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
-                        DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L)
-                .addEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO,
+                        ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L)
+                .insertEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 149873L, 287L, 59217L /* smaller than sum(tun0) */,
                         299L /* smaller than sum(tun0) */, 0L)
-                .addEntry(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
-                        DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L);
+                .insertEntry(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO,
+                        ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L);
 
         delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface});
         assertEquals(20, delta.size());
@@ -635,19 +635,19 @@
         final String underlyingIface = "wlan0";
         NetworkStats delta = new NetworkStats(TEST_START, 9)
                 // 2 different apps sent/receive data via tun0.
-                .addEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L)
-                .addEntry(tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 500L, 2L, 200L, 5L, 0L)
                 // VPN package resends data through the tunnel (with exaggerated overhead)
-                .addEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 240000, 100L, 120000L, 60L, 0L)
                 // 1 app already has some traffic on the underlying interface, the other doesn't yet
-                .addEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 1000L, 10L, 2000L, 20L, 0L)
                 // Traffic through the underlying interface via the vpn app.
                 // This test should redistribute this data correctly.
-                .addEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, 75500L, 37L, 130000L, 70L, 0L);
 
         delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface});
@@ -697,9 +697,9 @@
                 DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
 
         NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addEntry(entry1)
-                .addEntry(entry2)
-                .addEntry(entry3);
+                .insertEntry(entry1)
+                .insertEntry(entry2)
+                .insertEntry(entry3);
 
         stats.filter(UID_ALL, INTERFACES_ALL, TAG_ALL);
         assertEquals(3, stats.size());
@@ -724,9 +724,9 @@
                 DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
 
         NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addEntry(entry1)
-                .addEntry(entry2)
-                .addEntry(entry3);
+                .insertEntry(entry1)
+                .insertEntry(entry2)
+                .insertEntry(entry3);
 
         stats.filter(testUid, INTERFACES_ALL, TAG_ALL);
         assertEquals(2, stats.size());
@@ -755,10 +755,10 @@
                 DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
 
         NetworkStats stats = new NetworkStats(TEST_START, 4)
-                .addEntry(entry1)
-                .addEntry(entry2)
-                .addEntry(entry3)
-                .addEntry(entry4);
+                .insertEntry(entry1)
+                .insertEntry(entry2)
+                .insertEntry(entry3)
+                .insertEntry(entry4);
 
         stats.filter(UID_ALL, new String[] { testIf1, testIf2 }, TAG_ALL);
         assertEquals(3, stats.size());
@@ -778,8 +778,8 @@
                 DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
 
         NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addEntry(entry1)
-                .addEntry(entry2);
+                .insertEntry(entry1)
+                .insertEntry(entry2);
 
         stats.filter(UID_ALL, new String[] { }, TAG_ALL);
         assertEquals(0, stats.size());
@@ -802,9 +802,9 @@
                 DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
 
         NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addEntry(entry1)
-                .addEntry(entry2)
-                .addEntry(entry3);
+                .insertEntry(entry1)
+                .insertEntry(entry2)
+                .insertEntry(entry3);
 
         stats.filter(UID_ALL, INTERFACES_ALL, testTag);
         assertEquals(2, stats.size());
@@ -831,10 +831,10 @@
                 DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
 
         NetworkStats stats = new NetworkStats(TEST_START, 4)
-                .addEntry(entry1)
-                .addEntry(entry2)
-                .addEntry(entry3)
-                .addEntry(entry4);
+                .insertEntry(entry1)
+                .insertEntry(entry2)
+                .insertEntry(entry3)
+                .insertEntry(entry4);
 
         stats.filterDebugEntries();
 
@@ -891,14 +891,14 @@
                 0 /* operations */);
 
         final NetworkStats statsXt = new NetworkStats(TEST_START, 3)
-                .addEntry(appEntry)
-                .addEntry(xtRootUidEntry)
-                .addEntry(otherEntry);
+                .insertEntry(appEntry)
+                .insertEntry(xtRootUidEntry)
+                .insertEntry(otherEntry);
 
         final NetworkStats statsEbpf = new NetworkStats(TEST_START, 3)
-                .addEntry(appEntry)
-                .addEntry(ebpfRootUidEntry)
-                .addEntry(otherEntry);
+                .insertEntry(appEntry)
+                .insertEntry(ebpfRootUidEntry)
+                .insertEntry(otherEntry);
 
         statsXt.apply464xlatAdjustments(stackedIface, false);
         statsEbpf.apply464xlatAdjustments(stackedIface, true);
@@ -945,8 +945,8 @@
                 0 /* operations */);
 
         NetworkStats stats = new NetworkStats(TEST_START, 2)
-                .addEntry(firstEntry)
-                .addEntry(secondEntry);
+                .insertEntry(firstEntry)
+                .insertEntry(secondEntry);
 
         // Empty map: no adjustment
         stats.apply464xlatAdjustments(new ArrayMap<>(), false);
diff --git a/tests/net/java/android/net/NetworkTemplateTest.kt b/tests/net/java/android/net/NetworkTemplateTest.kt
new file mode 100644
index 0000000..5dd0fda
--- /dev/null
+++ b/tests/net/java/android/net/NetworkTemplateTest.kt
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net
+
+import android.content.Context
+import android.net.ConnectivityManager.TYPE_MOBILE
+import android.net.ConnectivityManager.TYPE_WIFI
+import android.net.NetworkIdentity.SUBTYPE_COMBINED
+import android.net.NetworkIdentity.buildNetworkIdentity
+import android.net.NetworkStats.DEFAULT_NETWORK_ALL
+import android.net.NetworkStats.METERED_ALL
+import android.net.NetworkStats.ROAMING_ALL
+import android.net.NetworkTemplate.MATCH_MOBILE
+import android.net.NetworkTemplate.MATCH_WIFI
+import android.net.NetworkTemplate.NETWORK_TYPE_ALL
+import android.net.NetworkTemplate.buildTemplateMobileWithRatType
+import android.telephony.TelephonyManager
+import com.android.testutils.assertParcelSane
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.mock
+import org.mockito.MockitoAnnotations
+import kotlin.test.assertFalse
+import kotlin.test.assertNotEquals
+import kotlin.test.assertTrue
+
+private const val TEST_IMSI1 = "imsi1"
+private const val TEST_IMSI2 = "imsi2"
+private const val TEST_SSID1 = "ssid1"
+
+@RunWith(JUnit4::class)
+class NetworkTemplateTest {
+    private val mockContext = mock(Context::class.java)
+
+    private fun buildMobileNetworkState(subscriberId: String): NetworkState =
+            buildNetworkState(TYPE_MOBILE, subscriberId = subscriberId)
+    private fun buildWifiNetworkState(ssid: String): NetworkState =
+            buildNetworkState(TYPE_WIFI, ssid = ssid)
+
+    private fun buildNetworkState(
+        type: Int,
+        subscriberId: String? = null,
+        ssid: String? = null
+    ): NetworkState {
+        val info = mock(NetworkInfo::class.java)
+        doReturn(type).`when`(info).type
+        doReturn(NetworkInfo.State.CONNECTED).`when`(info).state
+        val lp = LinkProperties()
+        val caps = NetworkCapabilities().apply {
+            setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false)
+            setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true)
+        }
+        return NetworkState(info, lp, caps, mock(Network::class.java), subscriberId, ssid)
+    }
+
+    private fun NetworkTemplate.assertMatches(ident: NetworkIdentity) =
+            assertTrue(matches(ident), "$this does not match $ident")
+
+    private fun NetworkTemplate.assertDoesNotMatch(ident: NetworkIdentity) =
+            assertFalse(matches(ident), "$this should match $ident")
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+    }
+
+    @Test
+    fun testRatTypeGroupMatches() {
+        val stateMobile = buildMobileNetworkState(TEST_IMSI1)
+        // Build UMTS template that matches mobile identities with RAT in the same
+        // group with any IMSI. See {@link NetworkTemplate#getCollapsedRatType}.
+        val templateUmts = buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UMTS)
+        // Build normal template that matches mobile identities with any RAT and IMSI.
+        val templateAll = buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL)
+        // Build template with UNKNOWN RAT that matches mobile identities with RAT that
+        // cannot be determined.
+        val templateUnknown =
+                buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UNKNOWN)
+
+        val identUmts = buildNetworkIdentity(
+                mockContext, stateMobile, false, TelephonyManager.NETWORK_TYPE_UMTS)
+        val identHsdpa = buildNetworkIdentity(
+                mockContext, stateMobile, false, TelephonyManager.NETWORK_TYPE_HSDPA)
+        val identLte = buildNetworkIdentity(
+                mockContext, stateMobile, false, TelephonyManager.NETWORK_TYPE_LTE)
+        val identCombined = buildNetworkIdentity(
+                mockContext, stateMobile, false, SUBTYPE_COMBINED)
+        val identImsi2 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI2),
+                false, TelephonyManager.NETWORK_TYPE_UMTS)
+        val identWifi = buildNetworkIdentity(
+                mockContext, buildWifiNetworkState(TEST_SSID1), true, 0)
+
+        // Assert that identity with the same RAT matches.
+        templateUmts.assertMatches(identUmts)
+        templateAll.assertMatches(identUmts)
+        templateUnknown.assertDoesNotMatch(identUmts)
+        // Assert that identity with the RAT within the same group matches.
+        templateUmts.assertMatches(identHsdpa)
+        templateAll.assertMatches(identHsdpa)
+        templateUnknown.assertDoesNotMatch(identHsdpa)
+        // Assert that identity with the RAT out of the same group only matches template with
+        // NETWORK_TYPE_ALL.
+        templateUmts.assertDoesNotMatch(identLte)
+        templateAll.assertMatches(identLte)
+        templateUnknown.assertDoesNotMatch(identLte)
+        // Assert that identity with combined RAT only matches with template with NETWORK_TYPE_ALL
+        // and NETWORK_TYPE_UNKNOWN.
+        templateUmts.assertDoesNotMatch(identCombined)
+        templateAll.assertMatches(identCombined)
+        templateUnknown.assertMatches(identCombined)
+        // Assert that identity with different IMSI matches.
+        templateUmts.assertMatches(identImsi2)
+        templateAll.assertMatches(identImsi2)
+        templateUnknown.assertDoesNotMatch(identImsi2)
+        // Assert that wifi identity does not match.
+        templateUmts.assertDoesNotMatch(identWifi)
+        templateAll.assertDoesNotMatch(identWifi)
+        templateUnknown.assertDoesNotMatch(identWifi)
+    }
+
+    @Test
+    fun testParcelUnparcel() {
+        val templateMobile = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1, null, null, METERED_ALL,
+                ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE)
+        val templateWifi = NetworkTemplate(MATCH_WIFI, null, null, TEST_SSID1, METERED_ALL,
+                ROAMING_ALL, DEFAULT_NETWORK_ALL, 0)
+        assertParcelSane(templateMobile, 8)
+        assertParcelSane(templateWifi, 8)
+    }
+
+    // Verify NETWORK_TYPE_ALL does not conflict with TelephonyManager#NETWORK_TYPE_* constants.
+    @Test
+    fun testNetworkTypeAll() {
+        for (ratType in TelephonyManager.getAllNetworkTypes()) {
+            assertNotEquals(NETWORK_TYPE_ALL, ratType)
+        }
+    }
+}
diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
index e632aaf..cea8c57 100644
--- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
+++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
@@ -66,10 +66,10 @@
             fail("InvalidPacketException: " + e);
         }
 
-        assertEquals(InetAddress.getByAddress(testInfo.srcAddress), resultData.srcAddress);
-        assertEquals(InetAddress.getByAddress(testInfo.dstAddress), resultData.dstAddress);
-        assertEquals(testInfo.srcPort, resultData.srcPort);
-        assertEquals(testInfo.dstPort, resultData.dstPort);
+        assertEquals(InetAddress.getByAddress(testInfo.srcAddress), resultData.getSrcAddress());
+        assertEquals(InetAddress.getByAddress(testInfo.dstAddress), resultData.getDstAddress());
+        assertEquals(testInfo.srcPort, resultData.getSrcPort());
+        assertEquals(testInfo.dstPort, resultData.getDstPort());
         assertEquals(testInfo.seq, resultData.tcpSeq);
         assertEquals(testInfo.ack, resultData.tcpAck);
         assertEquals(testInfo.rcvWnd, resultData.tcpWnd);
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index c1999db..83399b8 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -25,7 +25,6 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
-import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_SUPL;
 import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO;
 import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE;
 import static android.net.ConnectivityManager.NETID_UNSET;
@@ -175,6 +174,7 @@
 import android.net.ProxyInfo;
 import android.net.ResolverParamsParcel;
 import android.net.RouteInfo;
+import android.net.RouteInfoParcel;
 import android.net.SocketKeepalive;
 import android.net.UidRange;
 import android.net.Uri;
@@ -307,6 +307,8 @@
 
     private static final long TIMESTAMP = 1234L;
 
+    private static final int NET_ID = 110;
+
     private static final String CLAT_PREFIX = "v4-";
     private static final String MOBILE_IFNAME = "test_rmnet_data0";
     private static final String WIFI_IFNAME = "test_wlan0";
@@ -427,7 +429,6 @@
         public Object getSystemService(String name) {
             if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
             if (Context.NOTIFICATION_SERVICE.equals(name)) return mNotificationManager;
-            if (Context.NETWORK_STACK_SERVICE.equals(name)) return mNetworkStack;
             if (Context.USER_SERVICE.equals(name)) return mUserManager;
             if (Context.ALARM_SERVICE.equals(name)) return mAlarmManager;
             if (Context.LOCATION_SERVICE.equals(name)) return mLocationManager;
@@ -1016,6 +1017,7 @@
         private int mVpnType = VpnManager.TYPE_VPN_SERVICE;
 
         private VpnInfo mVpnInfo;
+        private Network[] mUnderlyingNetworks;
 
         public MockVpn(int userId) {
             super(startHandlerThreadAndReturnLooper(), mServiceContext, mNetworkManagementService,
@@ -1105,9 +1107,21 @@
             return super.getVpnInfo();
         }
 
-        private void setVpnInfo(VpnInfo vpnInfo) {
+        private synchronized void setVpnInfo(VpnInfo vpnInfo) {
             mVpnInfo = vpnInfo;
         }
+
+        @Override
+        public synchronized Network[] getUnderlyingNetworks() {
+            if (mUnderlyingNetworks != null) return mUnderlyingNetworks;
+
+            return super.getUnderlyingNetworks();
+        }
+
+        /** Don't override behavior for {@link Vpn#setUnderlyingNetworks}. */
+        private synchronized void overrideUnderlyingNetworks(Network[] underlyingNetworks) {
+            mUnderlyingNetworks = underlyingNetworks;
+        }
     }
 
     private void mockVpn(int uid) {
@@ -1374,7 +1388,6 @@
             @NonNull final Predicate<Intent> filter) {
         final ConditionVariable cv = new ConditionVariable();
         final IntentFilter intentFilter = new IntentFilter(CONNECTIVITY_ACTION);
-        intentFilter.addAction(CONNECTIVITY_ACTION_SUPL);
         final BroadcastReceiver receiver = new BroadcastReceiver() {
                     private int remaining = count;
                     public void onReceive(Context context, Intent intent) {
@@ -1422,56 +1435,28 @@
         final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL,
                 ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST);
 
-        // Send request and check that the legacy broadcast for SUPL is sent correctly.
+        // File request, withdraw it and make sure no broadcast is sent
+        final ConditionVariable cv2 = registerConnectivityBroadcast(1);
         final TestNetworkCallback callback = new TestNetworkCallback();
-        final ConditionVariable cv2 = registerConnectivityBroadcastThat(1,
-                intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL);
         mCm.requestNetwork(legacyRequest, callback);
         callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
-        waitFor(cv2);
-
-        // File another request, withdraw it and make sure no broadcast is sent
-        final ConditionVariable cv3 = registerConnectivityBroadcast(1);
-        final TestNetworkCallback callback2 = new TestNetworkCallback();
-        mCm.requestNetwork(legacyRequest, callback2);
-        callback2.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
-        mCm.unregisterNetworkCallback(callback2);
-        assertFalse(cv3.block(800)); // 800ms long enough to at least flake if this is sent
+        mCm.unregisterNetworkCallback(callback);
+        assertFalse(cv2.block(800)); // 800ms long enough to at least flake if this is sent
         // As the broadcast did not fire, the receiver was not unregistered. Do this now.
         mServiceContext.clearRegisteredReceivers();
 
-        // Withdraw the request and check that the broadcast for disconnection is sent.
-        final ConditionVariable cv4 = registerConnectivityBroadcastThat(1, intent ->
-                !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected()
-                        && intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL);
-        mCm.unregisterNetworkCallback(callback);
-        waitFor(cv4);
-
-        // Re-file the request and expect the connected broadcast again
-        final ConditionVariable cv5 = registerConnectivityBroadcastThat(1,
-                intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL);
-        final TestNetworkCallback callback3 = new TestNetworkCallback();
-        mCm.requestNetwork(legacyRequest, callback3);
-        callback3.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
-        waitFor(cv5);
-
-        // Disconnect the network and expect two disconnected broadcasts, one for SUPL and one
-        // for mobile. Use a small hack to check that both have been sent, but the order is
-        // not contractual.
+        // Disconnect the network and expect mobile disconnected broadcast. Use a small hack to
+        // check that has been sent.
         final AtomicBoolean vanillaAction = new AtomicBoolean(false);
-        final AtomicBoolean suplAction = new AtomicBoolean(false);
-        final ConditionVariable cv6 = registerConnectivityBroadcastThat(2, intent -> {
+        final ConditionVariable cv3 = registerConnectivityBroadcastThat(1, intent -> {
             if (intent.getAction().equals(CONNECTIVITY_ACTION)) {
                 vanillaAction.set(true);
-            } else if (intent.getAction().equals(CONNECTIVITY_ACTION_SUPL)) {
-                suplAction.set(true);
             }
             return !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected();
         });
         mCellNetworkAgent.disconnect();
-        waitFor(cv6);
+        waitFor(cv3);
         assertTrue(vanillaAction.get());
-        assertTrue(suplAction.get());
     }
 
     @Test
@@ -2425,7 +2410,7 @@
         assertEquals(expectedRequestCount, testFactory.getMyRequestCount());
         assertTrue(testFactory.getMyStartRequested());
 
-        testFactory.unregister();
+        testFactory.terminate();
         if (networkCallback != null) mCm.unregisterNetworkCallback(networkCallback);
         handlerThread.quit();
     }
@@ -2451,6 +2436,38 @@
     }
 
     @Test
+    public void testNetworkFactoryUnregister() throws Exception {
+        final NetworkCapabilities filter = new NetworkCapabilities();
+        filter.clearAll();
+
+        final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests");
+        handlerThread.start();
+
+        // Checks that calling setScoreFilter on a NetworkFactory immediately before closing it
+        // does not crash.
+        for (int i = 0; i < 100; i++) {
+            final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
+                    mServiceContext, "testFactory", filter);
+            // Register the factory and don't be surprised when the default request arrives.
+            testFactory.expectAddRequestsWithScores(0);
+            testFactory.register();
+            testFactory.waitForNetworkRequests(1);
+
+            testFactory.setScoreFilter(42);
+            testFactory.terminate();
+
+            if (i % 2 == 0) {
+                try {
+                    testFactory.register();
+                    fail("Re-registering terminated NetworkFactory should throw");
+                } catch (IllegalStateException expected) {
+                }
+            }
+        }
+        handlerThread.quit();
+    }
+
+    @Test
     public void testNoMutableNetworkRequests() throws Exception {
         PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0);
         NetworkRequest request1 = new NetworkRequest.Builder()
@@ -2750,9 +2767,6 @@
 
         // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
         validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
-        // Expect no notification to be shown when captive portal disappears by itself
-        verify(mNotificationManager, never()).notifyAsUser(
-                anyString(), eq(NotificationType.LOGGED_IN.eventId), any(), any());
 
         // Break network connectivity.
         // Expect NET_CAPABILITY_VALIDATED onLost callback.
@@ -2814,8 +2828,6 @@
         mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid());
         validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
         captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
-        verify(mNotificationManager, times(1)).notifyAsUser(anyString(),
-                eq(NotificationType.LOGGED_IN.eventId), any(), eq(UserHandle.ALL));
 
         mCm.unregisterNetworkCallback(validatedCallback);
         mCm.unregisterNetworkCallback(captivePortalCallback);
@@ -3487,7 +3499,7 @@
         cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
         assertLength(1, mCm.getAllNetworks());
 
-        testFactory.unregister();
+        testFactory.terminate();
         mCm.unregisterNetworkCallback(cellNetworkCallback);
         handlerThread.quit();
     }
@@ -3728,7 +3740,7 @@
         mCm.requestNetwork(nr, networkCallback, timeoutMs);
 
         // pass timeout and validate that UNAVAILABLE is called
-        networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, null);
+        networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null);
 
         // create a network satisfying request - validate that request not triggered
         mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
@@ -3819,7 +3831,7 @@
             // Simulate the factory releasing the request as unfulfillable and expect onUnavailable!
             testFactory.triggerUnfulfillable(requests.get(newRequestId));
 
-            networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, null);
+            networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null);
             testFactory.waitForRequests();
 
             // unregister network callback - a no-op (since already freed by the
@@ -3827,7 +3839,7 @@
             mCm.unregisterNetworkCallback(networkCallback);
         }
 
-        testFactory.unregister();
+        testFactory.terminate();
         handlerThread.quit();
     }
 
@@ -6037,6 +6049,7 @@
             verify(mBatteryStatsService).noteNetworkInterfaceType(stackedLp.getInterfaceName(),
                     TYPE_MOBILE);
         }
+        reset(mMockNetd);
 
         // Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked
         // linkproperties are cleaned up.
@@ -6088,7 +6101,6 @@
         networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
         verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString());
 
-
         // Clat iface comes up. Expect stacked link to be added.
         clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true);
         networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
@@ -6674,17 +6686,45 @@
         }
     }
 
+    private void assertRouteInfoParcelMatches(RouteInfo route, RouteInfoParcel parcel) {
+        assertEquals(route.getDestination().toString(), parcel.destination);
+        assertEquals(route.getInterface(), parcel.ifName);
+        assertEquals(route.getMtu(), parcel.mtu);
+
+        switch (route.getType()) {
+            case RouteInfo.RTN_UNICAST:
+                if (route.hasGateway()) {
+                    assertEquals(route.getGateway().getHostAddress(), parcel.nextHop);
+                } else {
+                    assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop);
+                }
+                break;
+            case RouteInfo.RTN_UNREACHABLE:
+                assertEquals(INetd.NEXTHOP_UNREACHABLE, parcel.nextHop);
+                break;
+            case RouteInfo.RTN_THROW:
+                assertEquals(INetd.NEXTHOP_THROW, parcel.nextHop);
+                break;
+            default:
+                assertEquals(INetd.NEXTHOP_NONE, parcel.nextHop);
+                break;
+        }
+    }
+
     private void assertRoutesAdded(int netId, RouteInfo... routes) throws Exception {
-        InOrder inOrder = inOrder(mNetworkManagementService);
+        ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class);
+        verify(mMockNetd, times(routes.length)).networkAddRouteParcel(eq(netId), captor.capture());
         for (int i = 0; i < routes.length; i++) {
-            inOrder.verify(mNetworkManagementService).addRoute(eq(netId), eq(routes[i]));
+            assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i));
         }
     }
 
     private void assertRoutesRemoved(int netId, RouteInfo... routes) throws Exception {
-        InOrder inOrder = inOrder(mNetworkManagementService);
+        ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class);
+        verify(mMockNetd, times(routes.length)).networkRemoveRouteParcel(eq(netId),
+                captor.capture());
         for (int i = 0; i < routes.length; i++) {
-            inOrder.verify(mNetworkManagementService).removeRoute(eq(netId), eq(routes[i]));
+            assertRouteInfoParcelMatches(routes[i], captor.getAllValues().get(i));
         }
     }
 
@@ -6762,6 +6802,22 @@
     }
 
     @Test
+    public void testCheckConnectivityDiagnosticsPermissionsWrongUidPackageName() throws Exception {
+        final NetworkAgentInfo naiWithoutUid =
+                new NetworkAgentInfo(
+                        null, null, null, null, null, new NetworkCapabilities(), 0,
+                        mServiceContext, null, null, mService, null, null, null, 0);
+
+        mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
+
+        assertFalse(
+                "Mismatched uid/package name should not pass the location permission check",
+                mService.checkConnectivityDiagnosticsPermissions(
+                        Process.myPid() + 1, Process.myUid() + 1, naiWithoutUid,
+                        mContext.getOpPackageName()));
+    }
+
+    @Test
     public void testCheckConnectivityDiagnosticsPermissionsNoLocationPermission() throws Exception {
         final NetworkAgentInfo naiWithoutUid =
                 new NetworkAgentInfo(
@@ -6779,9 +6835,10 @@
 
     @Test
     public void testCheckConnectivityDiagnosticsPermissionsActiveVpn() throws Exception {
+        final Network network = new Network(NET_ID);
         final NetworkAgentInfo naiWithoutUid =
                 new NetworkAgentInfo(
-                        null, null, null, null, null, new NetworkCapabilities(), 0,
+                        null, null, network, null, null, new NetworkCapabilities(), 0,
                         mServiceContext, null, null, mService, null, null, null, 0);
 
         setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
@@ -6794,17 +6851,25 @@
         info.ownerUid = Process.myUid();
         info.vpnIface = "interface";
         mMockVpn.setVpnInfo(info);
+        mMockVpn.overrideUnderlyingNetworks(new Network[] {network});
         assertTrue(
                 "Active VPN permission not applied",
                 mService.checkConnectivityDiagnosticsPermissions(
                         Process.myPid(), Process.myUid(), naiWithoutUid,
                         mContext.getOpPackageName()));
+
+        mMockVpn.overrideUnderlyingNetworks(null);
+        assertFalse(
+                "VPN shouldn't receive callback on non-underlying network",
+                mService.checkConnectivityDiagnosticsPermissions(
+                        Process.myPid(), Process.myUid(), naiWithoutUid,
+                        mContext.getOpPackageName()));
     }
 
     @Test
     public void testCheckConnectivityDiagnosticsPermissionsNetworkAdministrator() throws Exception {
         final NetworkCapabilities nc = new NetworkCapabilities();
-        nc.setAdministratorUids(Arrays.asList(Process.myUid()));
+        nc.setAdministratorUids(new int[] {Process.myUid()});
         final NetworkAgentInfo naiWithUid =
                 new NetworkAgentInfo(
                         null, null, null, null, null, nc, 0, mServiceContext, null, null,
@@ -6826,7 +6891,7 @@
     public void testCheckConnectivityDiagnosticsPermissionsFails() throws Exception {
         final NetworkCapabilities nc = new NetworkCapabilities();
         nc.setOwnerUid(Process.myUid());
-        nc.setAdministratorUids(Arrays.asList(Process.myUid()));
+        nc.setAdministratorUids(new int[] {Process.myUid()});
         final NetworkAgentInfo naiWithUid =
                 new NetworkAgentInfo(
                         null, null, null, null, null, nc, 0, mServiceContext, null, null,
@@ -6867,18 +6932,19 @@
     }
 
     @Test
-    public void testConnectivityDiagnosticsCallbackOnConnectivityReport() throws Exception {
+    public void testConnectivityDiagnosticsCallbackOnConnectivityReportAvailable()
+            throws Exception {
         setUpConnectivityDiagnosticsCallback();
 
         // Block until all other events are done processing.
         HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
 
         // Verify onConnectivityReport fired
-        verify(mConnectivityDiagnosticsCallback).onConnectivityReport(
+        verify(mConnectivityDiagnosticsCallback).onConnectivityReportAvailable(
                 argThat(report -> {
                     final NetworkCapabilities nc = report.getNetworkCapabilities();
                     return nc.getUids() == null
-                            && nc.getAdministratorUids().isEmpty()
+                            && nc.getAdministratorUids().length == 0
                             && nc.getOwnerUid() == Process.INVALID_UID;
                 }));
     }
@@ -6899,7 +6965,7 @@
                 argThat(report -> {
                     final NetworkCapabilities nc = report.getNetworkCapabilities();
                     return nc.getUids() == null
-                            && nc.getAdministratorUids().isEmpty()
+                            && nc.getAdministratorUids().length == 0
                             && nc.getOwnerUid() == Process.INVALID_UID;
                 }));
     }
@@ -6929,4 +6995,60 @@
         verify(mConnectivityDiagnosticsCallback)
                 .onNetworkConnectivityReported(eq(n), eq(noConnectivity));
     }
+
+    @Test
+    public void testRouteAddDeleteUpdate() throws Exception {
+        final NetworkRequest request = new NetworkRequest.Builder().build();
+        final TestNetworkCallback networkCallback = new TestNetworkCallback();
+        mCm.registerNetworkCallback(request, networkCallback);
+        mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+        reset(mMockNetd);
+        mCellNetworkAgent.connect(false);
+        networkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
+        final int netId = mCellNetworkAgent.getNetwork().netId;
+
+        final String iface = "rmnet_data0";
+        final InetAddress gateway = InetAddress.getByName("fe80::5678");
+        RouteInfo direct = RouteInfo.makeHostRoute(gateway, iface);
+        RouteInfo rio1 = new RouteInfo(new IpPrefix("2001:db8:1::/48"), gateway, iface);
+        RouteInfo rio2 = new RouteInfo(new IpPrefix("2001:db8:2::/48"), gateway, iface);
+        RouteInfo defaultRoute = new RouteInfo((IpPrefix) null, gateway, iface);
+        RouteInfo defaultWithMtu = new RouteInfo(null, gateway, iface, RouteInfo.RTN_UNICAST,
+                                                 1280 /* mtu */);
+
+        // Send LinkProperties and check that we ask netd to add routes.
+        LinkProperties lp = new LinkProperties();
+        lp.setInterfaceName(iface);
+        lp.addRoute(direct);
+        lp.addRoute(rio1);
+        lp.addRoute(defaultRoute);
+        mCellNetworkAgent.sendLinkProperties(lp);
+        networkCallback.expectLinkPropertiesThat(mCellNetworkAgent, x -> x.getRoutes().size() == 3);
+
+        assertRoutesAdded(netId, direct, rio1, defaultRoute);
+        reset(mMockNetd);
+
+        // Send updated LinkProperties and check that we ask netd to add, remove, update routes.
+        assertTrue(lp.getRoutes().contains(defaultRoute));
+        lp.removeRoute(rio1);
+        lp.addRoute(rio2);
+        lp.addRoute(defaultWithMtu);
+        // Ensure adding the same route with a different MTU replaces the previous route.
+        assertFalse(lp.getRoutes().contains(defaultRoute));
+        assertTrue(lp.getRoutes().contains(defaultWithMtu));
+
+        mCellNetworkAgent.sendLinkProperties(lp);
+        networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
+                x -> x.getRoutes().contains(rio2));
+
+        assertRoutesRemoved(netId, rio1);
+        assertRoutesAdded(netId, rio2);
+
+        ArgumentCaptor<RouteInfoParcel> captor = ArgumentCaptor.forClass(RouteInfoParcel.class);
+        verify(mMockNetd).networkUpdateRouteParcel(eq(netId), captor.capture());
+        assertRouteInfoParcelMatches(defaultWithMtu, captor.getValue());
+
+
+        mCm.unregisterNetworkCallback(networkCallback);
+    }
 }
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 71b72b8..23098ec 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -46,6 +46,7 @@
 import android.net.Network;
 import android.net.NetworkUtils;
 import android.os.Binder;
+import android.os.INetworkManagementService;
 import android.os.ParcelFileDescriptor;
 import android.system.Os;
 import android.test.mock.MockContext;
@@ -135,6 +136,7 @@
     };
 
     INetd mMockNetd;
+    INetworkManagementService mNetworkManager;
     PackageManager mMockPkgMgr;
     IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
     IpSecService mIpSecService;
@@ -160,9 +162,10 @@
     @Before
     public void setUp() throws Exception {
         mMockNetd = mock(INetd.class);
+        mNetworkManager = mock(INetworkManagementService.class);
         mMockPkgMgr = mock(PackageManager.class);
         mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
-        mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
+        mIpSecService = new IpSecService(mMockContext, mNetworkManager, mMockIpSecSrvConfig);
 
         // Injecting mock netd
         when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
@@ -609,6 +612,7 @@
                         anyInt(),
                         anyInt(),
                         anyInt());
+        verify(mNetworkManager).setInterfaceUp(createTunnelResp.interfaceName);
     }
 
     @Test
diff --git a/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java b/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java
index 22a2c94..788e4ef 100644
--- a/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java
@@ -31,6 +31,7 @@
 import android.content.Context;
 import android.os.Binder;
 import android.os.IBinder;
+import android.os.INetworkManagementService;
 import android.os.RemoteException;
 
 import androidx.test.filters.SmallTest;
@@ -61,7 +62,8 @@
     public void setUp() throws Exception {
         mMockContext = mock(Context.class);
         mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
-        mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
+        mIpSecService = new IpSecService(
+                mMockContext, mock(INetworkManagementService.class), mMockIpSecSrvConfig);
     }
 
     private void assertResourceState(
diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java
index 4a35015..536e983 100644
--- a/tests/net/java/com/android/server/IpSecServiceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceTest.java
@@ -42,6 +42,7 @@
 import android.net.IpSecSpiResponse;
 import android.net.IpSecUdpEncapResponse;
 import android.os.Binder;
+import android.os.INetworkManagementService;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.system.ErrnoException;
@@ -115,6 +116,7 @@
     }
 
     Context mMockContext;
+    INetworkManagementService mMockNetworkManager;
     INetd mMockNetd;
     IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
     IpSecService mIpSecService;
@@ -122,9 +124,10 @@
     @Before
     public void setUp() throws Exception {
         mMockContext = mock(Context.class);
+        mMockNetworkManager = mock(INetworkManagementService.class);
         mMockNetd = mock(INetd.class);
         mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
-        mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
+        mIpSecService = new IpSecService(mMockContext, mMockNetworkManager, mMockIpSecSrvConfig);
 
         // Injecting mock netd
         when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
@@ -132,7 +135,7 @@
 
     @Test
     public void testIpSecServiceCreate() throws InterruptedException {
-        IpSecService ipSecSrv = IpSecService.create(mMockContext);
+        IpSecService ipSecSrv = IpSecService.create(mMockContext, mMockNetworkManager);
         assertNotNull(ipSecSrv);
     }
 
@@ -604,8 +607,8 @@
     @Test
     public void testOpenUdpEncapSocketTagsSocket() throws Exception {
         IpSecService.UidFdTagger mockTagger = mock(IpSecService.UidFdTagger.class);
-        IpSecService testIpSecService =
-                new IpSecService(mMockContext, mMockIpSecSrvConfig, mockTagger);
+        IpSecService testIpSecService = new IpSecService(
+                mMockContext, mMockNetworkManager, mMockIpSecSrvConfig, mockTagger);
 
         IpSecUdpEncapResponse udpEncapResp =
                 testIpSecService.openUdpEncapsulationSocket(0, new Binder());
diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index d57f225..47db5d4 100644
--- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -238,20 +238,6 @@
     }
 
     @Test
-    public void testSameLevelNotifications() {
-        final int id = 101;
-        final String tag = NetworkNotificationManager.tagFor(id);
-
-        mManager.showNotification(id, LOGGED_IN, mWifiNai, mCellNai, null, false);
-        verify(mNotificationManager, times(1))
-                .notifyAsUser(eq(tag), eq(LOGGED_IN.eventId), any(), any());
-
-        mManager.showNotification(id, LOST_INTERNET, mWifiNai, mCellNai, null, false);
-        verify(mNotificationManager, times(1))
-                .notifyAsUser(eq(tag), eq(LOST_INTERNET.eventId), any(), any());
-    }
-
-    @Test
     public void testClearNotificationByType() {
         final int id = 101;
         final String tag = NetworkNotificationManager.tagFor(id);
@@ -259,31 +245,25 @@
         // clearNotification(int id, NotificationType notifyType) will check if given type is equal
         // to previous type or not. If they are equal then clear the notification; if they are not
         // equal then return.
-
-        mManager.showNotification(id, LOGGED_IN, mWifiNai, mCellNai, null, false);
+        mManager.showNotification(id, NO_INTERNET, mWifiNai, mCellNai, null, false);
         verify(mNotificationManager, times(1))
-                .notifyAsUser(eq(tag), eq(LOGGED_IN.eventId), any(), any());
+                .notifyAsUser(eq(tag), eq(NO_INTERNET.eventId), any(), any());
 
-        // Previous notification is LOGGED_IN and given type is LOGGED_IN too. The notification
+        // Previous notification is NO_INTERNET and given type is NO_INTERNET too. The notification
         // should be cleared.
-        mManager.clearNotification(id, LOGGED_IN);
+        mManager.clearNotification(id, NO_INTERNET);
         verify(mNotificationManager, times(1))
-                .cancelAsUser(eq(tag), eq(LOGGED_IN.eventId), any());
+                .cancelAsUser(eq(tag), eq(NO_INTERNET.eventId), any());
 
-        mManager.showNotification(id, LOGGED_IN, mWifiNai, mCellNai, null, false);
-        verify(mNotificationManager, times(2))
-                .notifyAsUser(eq(tag), eq(LOGGED_IN.eventId), any(), any());
-
-        // LOST_INTERNET notification popup after LOGGED_IN notification.
-        mManager.showNotification(id, LOST_INTERNET, mWifiNai, mCellNai, null, false);
+        // SIGN_IN is popped-up.
+        mManager.showNotification(id, SIGN_IN, mWifiNai, mCellNai, null, false);
         verify(mNotificationManager, times(1))
-                .notifyAsUser(eq(tag), eq(LOST_INTERNET.eventId), any(), any());
+                .notifyAsUser(eq(tag), eq(SIGN_IN.eventId), any(), any());
 
-        // Previous notification is LOST_INTERNET and given type is LOGGED_IN. The notification
-        // shouldn't be cleared.
-        mManager.clearNotification(id, LOGGED_IN);
-        // LOST_INTERNET shouldn't be cleared.
+        // The notification type is not matching previous one, PARTIAL_CONNECTIVITY won't be
+        // cleared.
+        mManager.clearNotification(id, PARTIAL_CONNECTIVITY);
         verify(mNotificationManager, never())
-                .cancelAsUser(eq(tag), eq(LOST_INTERNET.eventId), any());
+                .cancelAsUser(eq(tag), eq(PARTIAL_CONNECTIVITY.eventId), any());
     }
 }
diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
index 8f90f13..551498f 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
@@ -319,33 +319,33 @@
             assertEntry(18322, 75, 15031, 75, history.getValues(i++, null));
             assertEntry(527798, 761, 78570, 652, history.getValues(i++, null));
             assertEntry(527797, 760, 78570, 651, history.getValues(i++, null));
-            assertEntry(10747, 50, 16838, 55, history.getValues(i++, null));
-            assertEntry(10747, 49, 16838, 54, history.getValues(i++, null));
+            assertEntry(10747, 50, 16839, 55, history.getValues(i++, null));
+            assertEntry(10747, 49, 16837, 54, history.getValues(i++, null));
             assertEntry(89191, 151, 18021, 140, history.getValues(i++, null));
             assertEntry(89190, 150, 18020, 139, history.getValues(i++, null));
-            assertEntry(3821, 22, 4525, 26, history.getValues(i++, null));
-            assertEntry(3820, 22, 4524, 26, history.getValues(i++, null));
-            assertEntry(91686, 159, 18575, 146, history.getValues(i++, null));
-            assertEntry(91685, 159, 18575, 146, history.getValues(i++, null));
-            assertEntry(8289, 35, 6863, 38, history.getValues(i++, null));
-            assertEntry(8289, 35, 6863, 38, history.getValues(i++, null));
+            assertEntry(3821, 23, 4525, 26, history.getValues(i++, null));
+            assertEntry(3820, 21, 4524, 26, history.getValues(i++, null));
+            assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
+            assertEntry(91685, 159, 18574, 146, history.getValues(i++, null));
+            assertEntry(8289, 36, 6864, 39, history.getValues(i++, null));
+            assertEntry(8289, 34, 6862, 37, history.getValues(i++, null));
             assertEntry(113914, 174, 18364, 157, history.getValues(i++, null));
             assertEntry(113913, 173, 18364, 157, history.getValues(i++, null));
-            assertEntry(11378, 49, 9261, 49, history.getValues(i++, null));
-            assertEntry(11377, 48, 9261, 49, history.getValues(i++, null));
-            assertEntry(201765, 328, 41808, 291, history.getValues(i++, null));
-            assertEntry(201765, 328, 41807, 290, history.getValues(i++, null));
-            assertEntry(106106, 218, 39917, 201, history.getValues(i++, null));
-            assertEntry(106105, 217, 39917, 201, history.getValues(i++, null));
+            assertEntry(11378, 49, 9261, 50, history.getValues(i++, null));
+            assertEntry(11377, 48, 9261, 48, history.getValues(i++, null));
+            assertEntry(201766, 328, 41808, 291, history.getValues(i++, null));
+            assertEntry(201764, 328, 41807, 290, history.getValues(i++, null));
+            assertEntry(106106, 219, 39918, 202, history.getValues(i++, null));
+            assertEntry(106105, 216, 39916, 200, history.getValues(i++, null));
             assertEquals(history.size(), i);
 
             // Slice from middle should be untouched
             history = getHistory(collection, plan, TIME_B - HOUR_IN_MILLIS,
                     TIME_B + HOUR_IN_MILLIS); i = 0;
-            assertEntry(3821, 22, 4525, 26, history.getValues(i++, null));
-            assertEntry(3820, 22, 4524, 26, history.getValues(i++, null));
-            assertEntry(91686, 159, 18575, 146, history.getValues(i++, null));
-            assertEntry(91685, 159, 18575, 146, history.getValues(i++, null));
+            assertEntry(3821, 23, 4525, 26, history.getValues(i++, null));
+            assertEntry(3820, 21, 4524, 26, history.getValues(i++, null));
+            assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
+            assertEntry(91685, 159, 18574, 146, history.getValues(i++, null));
             assertEquals(history.size(), i);
         }
 
@@ -373,25 +373,25 @@
             assertEntry(527797, 760, 78570, 651, history.getValues(i++, null));
             // Cycle point; start data normalization
             assertEntry(7507, 0, 11763, 0, history.getValues(i++, null));
-            assertEntry(7507, 0, 11763, 0, history.getValues(i++, null));
+            assertEntry(7507, 0, 11762, 0, history.getValues(i++, null));
             assertEntry(62309, 0, 12589, 0, history.getValues(i++, null));
             assertEntry(62309, 0, 12588, 0, history.getValues(i++, null));
             assertEntry(2669, 0, 3161, 0, history.getValues(i++, null));
             assertEntry(2668, 0, 3160, 0, history.getValues(i++, null));
             // Anchor point; end data normalization
-            assertEntry(91686, 159, 18575, 146, history.getValues(i++, null));
-            assertEntry(91685, 159, 18575, 146, history.getValues(i++, null));
-            assertEntry(8289, 35, 6863, 38, history.getValues(i++, null));
-            assertEntry(8289, 35, 6863, 38, history.getValues(i++, null));
+            assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
+            assertEntry(91685, 159, 18574, 146, history.getValues(i++, null));
+            assertEntry(8289, 36, 6864, 39, history.getValues(i++, null));
+            assertEntry(8289, 34, 6862, 37, history.getValues(i++, null));
             assertEntry(113914, 174, 18364, 157, history.getValues(i++, null));
             assertEntry(113913, 173, 18364, 157, history.getValues(i++, null));
             // Cycle point
-            assertEntry(11378, 49, 9261, 49, history.getValues(i++, null));
-            assertEntry(11377, 48, 9261, 49, history.getValues(i++, null));
-            assertEntry(201765, 328, 41808, 291, history.getValues(i++, null));
-            assertEntry(201765, 328, 41807, 290, history.getValues(i++, null));
-            assertEntry(106106, 218, 39917, 201, history.getValues(i++, null));
-            assertEntry(106105, 217, 39917, 201, history.getValues(i++, null));
+            assertEntry(11378, 49, 9261, 50, history.getValues(i++, null));
+            assertEntry(11377, 48, 9261, 48, history.getValues(i++, null));
+            assertEntry(201766, 328, 41808, 291, history.getValues(i++, null));
+            assertEntry(201764, 328, 41807, 290, history.getValues(i++, null));
+            assertEntry(106106, 219, 39918, 202, history.getValues(i++, null));
+            assertEntry(106105, 216, 39916, 200, history.getValues(i++, null));
             assertEquals(history.size(), i);
 
             // Slice from middle should be augmented
@@ -399,8 +399,8 @@
                     TIME_B + HOUR_IN_MILLIS); i = 0;
             assertEntry(2669, 0, 3161, 0, history.getValues(i++, null));
             assertEntry(2668, 0, 3160, 0, history.getValues(i++, null));
-            assertEntry(91686, 159, 18575, 146, history.getValues(i++, null));
-            assertEntry(91685, 159, 18575, 146, history.getValues(i++, null));
+            assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
+            assertEntry(91685, 159, 18574, 146, history.getValues(i++, null));
             assertEquals(history.size(), i);
         }
 
@@ -427,34 +427,34 @@
             assertEntry(527798, 761, 78570, 652, history.getValues(i++, null));
             assertEntry(527797, 760, 78570, 651, history.getValues(i++, null));
             // Cycle point; start data normalization
-            assertEntry(15015, 0, 23526, 0, history.getValues(i++, null));
-            assertEntry(15015, 0, 23526, 0, history.getValues(i++, null));
+            assertEntry(15015, 0, 23527, 0, history.getValues(i++, null));
+            assertEntry(15015, 0, 23524, 0, history.getValues(i++, null));
             assertEntry(124619, 0, 25179, 0, history.getValues(i++, null));
             assertEntry(124618, 0, 25177, 0, history.getValues(i++, null));
             assertEntry(5338, 0, 6322, 0, history.getValues(i++, null));
             assertEntry(5337, 0, 6320, 0, history.getValues(i++, null));
             // Anchor point; end data normalization
-            assertEntry(91686, 159, 18575, 146, history.getValues(i++, null));
-            assertEntry(91685, 159, 18575, 146, history.getValues(i++, null));
-            assertEntry(8289, 35, 6863, 38, history.getValues(i++, null));
-            assertEntry(8289, 35, 6863, 38, history.getValues(i++, null));
+            assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
+            assertEntry(91685, 159, 18574, 146, history.getValues(i++, null));
+            assertEntry(8289, 36, 6864, 39, history.getValues(i++, null));
+            assertEntry(8289, 34, 6862, 37, history.getValues(i++, null));
             assertEntry(113914, 174, 18364, 157, history.getValues(i++, null));
             assertEntry(113913, 173, 18364, 157, history.getValues(i++, null));
             // Cycle point
-            assertEntry(11378, 49, 9261, 49, history.getValues(i++, null));
-            assertEntry(11377, 48, 9261, 49, history.getValues(i++, null));
-            assertEntry(201765, 328, 41808, 291, history.getValues(i++, null));
-            assertEntry(201765, 328, 41807, 290, history.getValues(i++, null));
-            assertEntry(106106, 218, 39917, 201, history.getValues(i++, null));
-            assertEntry(106105, 217, 39917, 201, history.getValues(i++, null));
+            assertEntry(11378, 49, 9261, 50, history.getValues(i++, null));
+            assertEntry(11377, 48, 9261, 48, history.getValues(i++, null));
+            assertEntry(201766, 328, 41808, 291, history.getValues(i++, null));
+            assertEntry(201764, 328, 41807, 290, history.getValues(i++, null));
+            assertEntry(106106, 219, 39918, 202, history.getValues(i++, null));
+            assertEntry(106105, 216, 39916, 200, history.getValues(i++, null));
 
             // Slice from middle should be augmented
             history = getHistory(collection, plan, TIME_B - HOUR_IN_MILLIS,
                     TIME_B + HOUR_IN_MILLIS); i = 0;
             assertEntry(5338, 0, 6322, 0, history.getValues(i++, null));
             assertEntry(5337, 0, 6320, 0, history.getValues(i++, null));
-            assertEntry(91686, 159, 18575, 146, history.getValues(i++, null));
-            assertEntry(91685, 159, 18575, 146, history.getValues(i++, null));
+            assertEntry(91686, 159, 18576, 146, history.getValues(i++, null));
+            assertEntry(91685, 159, 18574, 146, history.getValues(i++, null));
             assertEquals(history.size(), i);
         }
     }
diff --git a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
index f0e5774..a6f7a36 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
@@ -240,7 +240,7 @@
 
         // Baseline
         NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
-                .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
+                .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
         NetworkStats uidSnapshot = null;
 
         mStatsObservers.updateStats(
@@ -264,14 +264,14 @@
 
         // Baseline
         NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
-                .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
+                .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
         NetworkStats uidSnapshot = null;
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
-                .addIfaceValues(TEST_IFACE, BASE_BYTES + 1024L, 10L, BASE_BYTES + 2048L, 20L);
+                .insertEntry(TEST_IFACE, BASE_BYTES + 1024L, 10L, BASE_BYTES + 2048L, 20L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
         waitForObserverToIdle();
@@ -294,14 +294,14 @@
 
         // Baseline
         NetworkStats xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
-                .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
+                .insertEntry(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
         NetworkStats uidSnapshot = null;
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         xtSnapshot = new NetworkStats(TEST_START + MINUTE_IN_MILLIS, 1 /* initialSize */)
-                .addIfaceValues(TEST_IFACE, BASE_BYTES + THRESHOLD_BYTES, 12L,
+                .insertEntry(TEST_IFACE, BASE_BYTES + THRESHOLD_BYTES, 12L,
                         BASE_BYTES + THRESHOLD_BYTES, 22L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
@@ -326,14 +326,14 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
@@ -359,14 +359,14 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
@@ -391,14 +391,14 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, BASE_BYTES + THRESHOLD_BYTES, 2L,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
@@ -424,14 +424,14 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
+                .insertEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
                         ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
+                .insertEntry(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
                         ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 36deca3..6e63313 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -42,6 +42,7 @@
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.NetworkStatsHistory.FIELD_ALL;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
+import static android.net.NetworkTemplate.buildTemplateMobileWithRatType;
 import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
 import static android.net.TrafficStats.MB_IN_BYTES;
 import static android.net.TrafficStats.UID_REMOVED;
@@ -60,11 +61,13 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
+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.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.AlarmManager;
 import android.app.usage.NetworkStatsManager;
 import android.content.Context;
@@ -92,6 +95,8 @@
 import android.os.Messenger;
 import android.os.PowerManager;
 import android.os.SimpleClock;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 
 import androidx.test.InstrumentationRegistry;
@@ -163,11 +168,14 @@
     private @Mock NetworkStatsSettings mSettings;
     private @Mock IBinder mBinder;
     private @Mock AlarmManager mAlarmManager;
+    private @Mock TelephonyManager mTelephonyManager;
     private HandlerThread mHandlerThread;
 
     private NetworkStatsService mService;
     private INetworkStatsSession mSession;
     private INetworkManagementEventObserver mNetworkObserver;
+    @Nullable
+    private PhoneStateListener mPhoneStateListener;
 
     private final Clock mClock = new SimpleClock(ZoneOffset.UTC) {
         @Override
@@ -195,7 +203,7 @@
         mHandlerThread = new HandlerThread("HandlerThread");
         final NetworkStatsService.Dependencies deps = makeDependencies();
         mService = new NetworkStatsService(mServiceContext, mNetManager, mAlarmManager, wakeLock,
-                mClock, mServiceContext.getSystemService(TelephonyManager.class), mSettings,
+                mClock, mTelephonyManager, mSettings,
                 mStatsFactory, new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir), deps);
 
         mElapsedRealtime = 0L;
@@ -216,6 +224,12 @@
                 ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
         verify(mNetManager).registerObserver(networkObserver.capture());
         mNetworkObserver = networkObserver.getValue();
+
+        // Capture the phone state listener that created by service.
+        final ArgumentCaptor<PhoneStateListener> phoneStateListenerCaptor =
+                ArgumentCaptor.forClass(PhoneStateListener.class);
+        verify(mTelephonyManager).listen(phoneStateListenerCaptor.capture(), anyInt());
+        mPhoneStateListener = phoneStateListenerCaptor.getValue();
     }
 
     @NonNull
@@ -263,7 +277,7 @@
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
+                .insertEntry(TEST_IFACE, 1024L, 1L, 2048L, 2L));
         expectNetworkStatsUidDetail(buildEmptyStats());
         forcePollAndWaitForIdle();
 
@@ -276,7 +290,7 @@
         incrementCurrentTime(DAY_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 4096L, 4L, 8192L, 8L));
+                .insertEntry(TEST_IFACE, 4096L, 4L, 8192L, 8L));
         expectNetworkStatsUidDetail(buildEmptyStats());
         forcePollAndWaitForIdle();
 
@@ -306,13 +320,13 @@
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 1024L, 8L, 2048L, 16L));
+                .insertEntry(TEST_IFACE, 1024L, 8L, 2048L, 16L));
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
         mService.setUidForeground(UID_RED, false);
         mService.incrementOperationCount(UID_RED, 0xFAAD, 4);
         mService.setUidForeground(UID_RED, true);
@@ -375,7 +389,7 @@
         incrementCurrentTime(2 * HOUR_IN_MILLIS);
         expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 512L, 4L, 512L, 4L));
+                .insertEntry(TEST_IFACE, 512L, 4L, 512L, 4L));
         expectNetworkStatsUidDetail(buildEmptyStats());
         forcePollAndWaitForIdle();
 
@@ -415,11 +429,11 @@
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
+                .insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L));
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
         mService.incrementOperationCount(UID_RED, 0xF00D, 10);
 
         forcePollAndWaitForIdle();
@@ -437,11 +451,11 @@
         expectDefaultSettings();
         states = new NetworkState[] {buildMobile3gState(IMSI_2)};
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
+                .insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L));
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
 
         mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
         forcePollAndWaitForIdle();
@@ -451,12 +465,12 @@
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 2176L, 17L, 1536L, 12L));
+                .insertEntry(TEST_IFACE, 2176L, 17L, 1536L, 12L));
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L));
         mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10);
 
         forcePollAndWaitForIdle();
@@ -488,12 +502,13 @@
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
+                .insertEntry(TEST_IFACE, 4128L, 258L, 544L, 34L));
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
-                .addEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
+                        4096L, 258L, 512L, 32L, 0L)
+                .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
         mService.incrementOperationCount(UID_RED, 0xFAAD, 10);
 
         forcePollAndWaitForIdle();
@@ -509,12 +524,13 @@
         // special "removed" bucket.
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
+                .insertEntry(TEST_IFACE, 4128L, 258L, 544L, 34L));
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
-                .addEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
+                        4096L, 258L, 512L, 32L, 0L)
+                .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
         final Intent intent = new Intent(ACTION_UID_REMOVED);
         intent.putExtra(EXTRA_UID, UID_BLUE);
         mServiceContext.sendBroadcast(intent);
@@ -532,7 +548,7 @@
     }
 
     @Test
-    public void testUid3g4gCombinedByTemplate() throws Exception {
+    public void testUid3gWimaxCombinedByTemplate() throws Exception {
         // pretend that network comes online
         expectDefaultSettings();
         NetworkState[] states = new NetworkState[] {buildMobile3gState(IMSI_1)};
@@ -546,8 +562,8 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
         mService.incrementOperationCount(UID_RED, 0xF00D, 5);
 
         forcePollAndWaitForIdle();
@@ -556,14 +572,14 @@
         assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 8L, 1024L, 8L, 5);
 
 
-        // now switch over to 4g network
+        // now switch over to wimax network
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
-        states = new NetworkState[] {buildMobile4gState(TEST_IFACE2)};
+        states = new NetworkState[] {buildWimaxState(TEST_IFACE2)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
 
         mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
         forcePollAndWaitForIdle();
@@ -574,10 +590,10 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
-                .addEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
-                .addEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
+                .insertEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
+                .insertEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L));
         mService.incrementOperationCount(UID_RED, 0xFAAD, 5);
 
         forcePollAndWaitForIdle();
@@ -587,6 +603,89 @@
     }
 
     @Test
+    public void testMobileStatsByRatType() throws Exception {
+        final NetworkTemplate template3g =
+                buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UMTS);
+        final NetworkTemplate template4g =
+                buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_LTE);
+        final NetworkTemplate template5g =
+                buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_NR);
+        final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)};
+
+        // 3G network comes online.
+        expectNetworkStatsSummary(buildEmptyStats());
+        expectNetworkStatsUidDetail(buildEmptyStats());
+
+        setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS);
+        mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
+                new VpnInfo[0]);
+
+        // Create some traffic.
+        incrementCurrentTime(MINUTE_IN_MILLIS);
+        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
+                        12L, 18L, 14L, 1L, 0L)));
+        forcePollAndWaitForIdle();
+
+        // Verify 3g templates gets stats.
+        assertUidTotal(sTemplateImsi1, UID_RED, 12L, 18L, 14L, 1L, 0);
+        assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0);
+        assertUidTotal(template4g, UID_RED, 0L, 0L, 0L, 0L, 0);
+        assertUidTotal(template5g, UID_RED, 0L, 0L, 0L, 0L, 0);
+
+        // 4G network comes online.
+        incrementCurrentTime(MINUTE_IN_MILLIS);
+        setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_LTE);
+        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+                // Append more traffic on existing 3g stats entry.
+                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
+                        16L, 22L, 17L, 2L, 0L))
+                // Add entry that is new on 4g.
+                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE,
+                        33L, 27L, 8L, 10L, 1L)));
+        forcePollAndWaitForIdle();
+
+        // Verify ALL_MOBILE template gets all. 3g template counters do not increase.
+        assertUidTotal(sTemplateImsi1, UID_RED, 49L, 49L, 25L, 12L, 1);
+        assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0);
+        // Verify 4g template counts appended stats on existing entry and newly created entry.
+        assertUidTotal(template4g, UID_RED, 4L + 33L, 4L + 27L, 3L + 8L, 1L + 10L, 1);
+        // Verify 5g template doesn't get anything since no traffic is generated on 5g.
+        assertUidTotal(template5g, UID_RED, 0L, 0L, 0L, 0L, 0);
+
+        // 5g network comes online.
+        incrementCurrentTime(MINUTE_IN_MILLIS);
+        setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_NR);
+        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+                // Existing stats remains.
+                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
+                        16L, 22L, 17L, 2L, 0L))
+                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE,
+                        33L, 27L, 8L, 10L, 1L))
+                // Add some traffic on 5g.
+                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
+                5L, 13L, 31L, 9L, 2L)));
+        forcePollAndWaitForIdle();
+
+        // Verify ALL_MOBILE template gets all.
+        assertUidTotal(sTemplateImsi1, UID_RED, 54L, 62L, 56L, 21L, 3);
+        // 3g/4g template counters do not increase.
+        assertUidTotal(template3g, UID_RED, 12L, 18L, 14L, 1L, 0);
+        assertUidTotal(template4g, UID_RED, 4L + 33L, 4L + 27L, 3L + 8L, 1L + 10L, 1);
+        // Verify 5g template gets the 5g count.
+        assertUidTotal(template5g, UID_RED, 5L, 13L, 31L, 9L, 2);
+    }
+
+    // TODO: support per IMSI state
+    private void setMobileRatTypeAndWaitForIdle(int ratType) {
+        final ServiceState mockSs = mock(ServiceState.class);
+        when(mockSs.getDataNetworkType()).thenReturn(ratType);
+        mPhoneStateListener.onServiceStateChanged(mockSs);
+
+        HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
+    }
+
+    @Test
     public void testSummaryForAllUid() throws Exception {
         // pretend that network comes online
         expectDefaultSettings();
@@ -601,9 +700,9 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
         mService.incrementOperationCount(UID_RED, 0xF00D, 1);
 
         forcePollAndWaitForIdle();
@@ -618,9 +717,10 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
+                        2048L, 16L, 1024L, 8L, 0L));
         forcePollAndWaitForIdle();
 
         // first verify entire history present
@@ -664,9 +764,9 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
-                .addEntry(entry1)
-                .addEntry(entry2)
-                .addEntry(entry3));
+                .insertEntry(entry1)
+                .insertEntry(entry2)
+                .insertEntry(entry3));
         mService.incrementOperationCount(UID_RED, 0xF00D, 1);
 
         NetworkStats stats = mService.getDetailedUidStats(INTERFACES_ALL);
@@ -714,11 +814,11 @@
                 .thenReturn(augmentedIfaceFilter);
         when(mStatsFactory.readNetworkStatsDetail(eq(UID_ALL), any(), eq(TAG_ALL)))
                 .thenReturn(new NetworkStats(getElapsedRealtime(), 1)
-                        .addEntry(uidStats));
+                        .insertEntry(uidStats));
         when(mNetManager.getNetworkStatsTethering(STATS_PER_UID))
                 .thenReturn(new NetworkStats(getElapsedRealtime(), 2)
-                        .addEntry(tetheredStats1)
-                        .addEntry(tetheredStats2));
+                        .insertEntry(tetheredStats1)
+                        .insertEntry(tetheredStats2));
 
         NetworkStats stats = mService.getDetailedUidStats(ifaceFilter);
 
@@ -755,8 +855,8 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
         mService.incrementOperationCount(UID_RED, 0xF00D, 1);
 
         forcePollAndWaitForIdle();
@@ -770,10 +870,10 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
+                .insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
         mService.setUidForeground(UID_RED, true);
         mService.incrementOperationCount(UID_RED, 0xFAAD, 1);
 
@@ -814,9 +914,9 @@
         // and DEFAULT_NETWORK_YES, because these three properties aren't tracked at that layer.
         // We layer them on top by inspecting the iface properties.
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0L));
         mService.incrementOperationCount(UID_RED, 0xF00D, 1);
 
@@ -853,9 +953,9 @@
         // ROAMING_NO, because metered and roaming isn't tracked at that layer. We layer it
         // on top by inspecting the iface properties.
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO,
                         DEFAULT_NETWORK_YES,  128L, 2L, 128L, 2L, 0L)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO,
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO,
                         DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 0L));
         forcePollAndWaitForIdle();
 
@@ -888,17 +988,17 @@
 
         // Traffic seen by kernel counters (includes software tethering).
         final NetworkStats ifaceStats = new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 1536L, 12L, 384L, 3L);
+                .insertEntry(TEST_IFACE, 1536L, 12L, 384L, 3L);
         // Hardware tethering traffic, not seen by kernel counters.
         final NetworkStats tetherStatsHardware = new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 512L, 4L, 128L, 1L);
+                .insertEntry(TEST_IFACE, 512L, 4L, 128L, 1L);
 
         // Traffic for UID_RED.
         final NetworkStats uidStats = new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
+                .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
         // All tethering traffic, both hardware and software.
         final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1)
-                .addEntry(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L,
+                .insertEntry(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L,
                         0L);
 
         expectNetworkStatsSummary(ifaceStats, tetherStatsHardware);
@@ -957,7 +1057,7 @@
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
+                .insertEntry(TEST_IFACE, 1024L, 1L, 2048L, 2L));
         expectNetworkStatsUidDetail(buildEmptyStats());
         forcePollAndWaitForIdle();
 
@@ -972,7 +1072,7 @@
         incrementCurrentTime(DAY_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
-                .addIfaceValues(TEST_IFACE, 4096000L, 4L, 8192000L, 8L));
+                .insertEntry(TEST_IFACE, 4096000L, 4L, 8192000L, 8L));
         expectNetworkStatsUidDetail(buildEmptyStats());
         forcePollAndWaitForIdle();
 
@@ -1026,18 +1126,18 @@
         mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
 
         // Verifies that one requestStatsUpdate will be called during iface update.
-        provider.expectStatsUpdate(0 /* unused */);
+        provider.expectOnRequestStatsUpdate(0 /* unused */);
 
         // Create some initial traffic and report to the service.
         incrementCurrentTime(HOUR_IN_MILLIS);
         final NetworkStats expectedStats = new NetworkStats(0L, 1)
-                .addValues(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT,
+                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT,
                         TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
                         128L, 2L, 128L, 2L, 1L))
-                .addValues(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT,
+                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT,
                         0xF00D, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES,
                         64L, 1L, 64L, 1L, 1L));
-        cb.onStatsUpdated(0 /* unused */, expectedStats, expectedStats);
+        cb.notifyStatsUpdated(0 /* unused */, expectedStats, expectedStats);
 
         // Make another empty mutable stats object. This is necessary since the new NetworkStats
         // object will be used to compare with the old one in NetworkStatsRecoder, two of them
@@ -1047,8 +1147,8 @@
         forcePollAndWaitForIdle();
 
         // Verifies that one requestStatsUpdate and setAlert will be called during polling.
-        provider.expectStatsUpdate(0 /* unused */);
-        provider.expectSetAlert(MB_IN_BYTES);
+        provider.expectOnRequestStatsUpdate(0 /* unused */);
+        provider.expectOnSetAlert(MB_IN_BYTES);
 
         // Verifies that service recorded history, does not verify uid tag part.
         assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1);
@@ -1082,13 +1182,13 @@
         assertNotNull(cb);
 
         // Simulates alert quota of the provider has been reached.
-        cb.onAlertReached();
+        cb.notifyAlertReached();
         HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
 
         // Verifies that polling is triggered by alert reached.
-        provider.expectStatsUpdate(0 /* unused */);
+        provider.expectOnRequestStatsUpdate(0 /* unused */);
         // Verifies that global alert will be re-armed.
-        provider.expectSetAlert(MB_IN_BYTES);
+        provider.expectOnSetAlert(MB_IN_BYTES);
     }
 
     private static File getBaseDir(File statsDir) {
@@ -1194,6 +1294,7 @@
         when(mSettings.getPollInterval()).thenReturn(HOUR_IN_MILLIS);
         when(mSettings.getPollDelay()).thenReturn(0L);
         when(mSettings.getSampleEnabled()).thenReturn(true);
+        when(mSettings.getCombineSubtypeEnabled()).thenReturn(false);
 
         final Config config = new Config(bucketDuration, deleteAge, deleteAge);
         when(mSettings.getDevConfig()).thenReturn(config);
@@ -1239,6 +1340,7 @@
         final NetworkCapabilities capabilities = new NetworkCapabilities();
         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !isMetered);
         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
+        capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
         return new NetworkState(info, prop, capabilities, WIFI_NETWORK, null, TEST_SSID);
     }
 
@@ -1256,10 +1358,11 @@
         final NetworkCapabilities capabilities = new NetworkCapabilities();
         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
+        capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
         return new NetworkState(info, prop, capabilities, MOBILE_NETWORK, subscriberId, null);
     }
 
-    private static NetworkState buildMobile4gState(String iface) {
+    private static NetworkState buildWimaxState(@NonNull String iface) {
         final NetworkInfo info = new NetworkInfo(TYPE_WIMAX, 0, null, null);
         info.setDetailedState(DetailedState.CONNECTED, null, null);
         final LinkProperties prop = new LinkProperties();
diff --git a/tools/aapt/ConfigDescription.h b/tools/aapt/ConfigDescription.h
index b4ea624..6e9dc3d 100644
--- a/tools/aapt/ConfigDescription.h
+++ b/tools/aapt/ConfigDescription.h
@@ -34,8 +34,8 @@
         size = sizeof(android::ResTable_config);
     }
 
-    ConfigDescription(const ConfigDescription&o) {
-        *static_cast<android::ResTable_config*>(this) = o;
+    ConfigDescription(const ConfigDescription&o)
+        : android::ResTable_config(o) {
     }
 
     ConfigDescription& operator=(const android::ResTable_config& o) {