Merge "MediaRouter: don't scanPackages if unnecessary" into rvc-dev am: ce4cd092d9 am: 500f793194

Change-Id: I31b8d3c1ed55da68f2073dce3d52149db9140ca7
diff --git a/Android.bp b/Android.bp
index 89f1499..6daadd34e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -536,6 +536,9 @@
     static_libs: [
         "exoplayer2-extractor",
         "android.hardware.wifi-V1.0-java-constants",
+
+        // Additional dependencies needed to build the ike API classes.
+        "ike-internals",
     ],
     apex_available: ["//apex_available:platform"],
     visibility: [
@@ -1037,13 +1040,13 @@
     name: "base_default",
     version: {
         py2: {
-            enabled: true,
-            embedded_launcher: true,
-        },
-        py3: {
             enabled: false,
             embedded_launcher: false,
         },
+        py3: {
+            enabled: true,
+            embedded_launcher: true,
+        },
     },
 }
 
diff --git a/ApiDocs.bp b/ApiDocs.bp
index 04ddc50..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",
     ],
@@ -356,10 +357,10 @@
     dist: {
         targets: ["docs"],
     },
-    cmd: "unzip $(location :ds-docs-java{.docs.zip}) -d $(genDir) && " +
-         "unzip $(location :ds-docs-kt{.docs.zip}) -d $(genDir)/en/reference/kotlin && " +
+    cmd: "unzip -q $(location :ds-docs-java{.docs.zip}) -d $(genDir) && " +
+         "unzip -q $(location :ds-docs-kt{.docs.zip}) -d $(genDir)/en/reference/kotlin && " +
          "SWITCHER=$$(cd $$(dirname $(location switcher4)) && pwd)/$$(basename $(location switcher4)) && " +
-         "(cd $(genDir)/en/reference && $$SWITCHER --work platform) && " +
+         "(cd $(genDir)/en/reference && $$SWITCHER --work platform) > /dev/null && " +
          "$(location soong_zip) -o $(out) -C $(genDir) -D $(genDir)",
 }
 
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 60f6174..0fd6db0 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -47,8 +47,9 @@
         "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",
     ],
     // TODO(b/147699819): remove below aidl includes.
     aidl: {
@@ -140,7 +141,6 @@
     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",
     removed_dex_api_filename: "system-removed-dex.txt",
     arg_files: [
@@ -215,6 +215,10 @@
     api_tag_name: "MODULE_LIB",
     arg_files: ["core/res/AndroidManifest.xml"],
     args: metalava_framework_docs_args + module_libs,
+
+    // Do not generate stubs as they are not needed
+    generate_stubs: false,
+
     check_api: {
         current: {
             api_file: "api/module-lib-current.txt",
@@ -256,18 +260,20 @@
 /////////////////////////////////////////////////////////////////////
 
 java_defaults {
-    name: "framework-stubs-default",
+    name: "android_defaults_stubs_current",
     libs: [ "stub-annotations" ],
-    static_libs: [ "private-stub-annotations-jar" ],
-    sdk_version: "core_current",
+    static_libs: [
+        "private-stub-annotations-jar",
+
+        // License notices from art module
+        "art-notices-for-framework-stubs-jar",
+    ],
     errorprone: {
         javacflags: [
             "-XepDisableAllChecks",
         ],
     },
-    java_resources: [
-        ":notices-for-framework-stubs",
-    ],
+    sdk_version: "none",
     system_modules: "none",
     java_version: "1.8",
     compile_dex: true,
@@ -276,25 +282,25 @@
 java_library_static {
     name: "android_stubs_current",
     srcs: [ ":api-stubs-docs" ],
-    defaults: ["framework-stubs-default"],
+    defaults: ["android_defaults_stubs_current"],
 }
 
 java_library_static {
     name: "android_system_stubs_current",
     srcs: [ ":system-api-stubs-docs" ],
-    defaults: ["framework-stubs-default"],
+    defaults: ["android_defaults_stubs_current"],
 }
 
 java_library_static {
     name: "android_test_stubs_current",
     srcs: [ ":test-api-stubs-docs" ],
-    defaults: ["framework-stubs-default"],
+    defaults: ["android_defaults_stubs_current"],
 }
 
 java_library_static {
     name: "android_module_lib_stubs_current",
     srcs: [ ":module-lib-api-stubs-docs" ],
-    defaults: ["framework-stubs-default"],
+    defaults: ["android_defaults_stubs_current"],
     libs: ["android_system_stubs_current"],
 }
 
diff --git a/apex/Android.bp b/apex/Android.bp
index 67cd0d7..23d360b 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -142,6 +142,10 @@
     installable: false,
     sdk_version: "module_current",
     filter_packages: framework_packages_to_document,
+
+    // Do not generate stubs as they are not needed
+    generate_stubs: false,
+
     check_api: {
         current: {
             api_file: "api/module-lib-current.txt",
diff --git a/apex/sdkextensions/Android.bp b/apex/sdkextensions/Android.bp
index fc26e08..dbb5bd3d 100644
--- a/apex/sdkextensions/Android.bp
+++ b/apex/sdkextensions/Android.bp
@@ -22,6 +22,7 @@
     binaries: [ "derive_sdk" ],
     prebuilts: [ "cur_sdkinfo" ],
     manifest: "manifest.json",
+    min_sdk_version: "current",
 }
 
 apex_defaults {
diff --git a/apex/sdkextensions/derive_sdk/Android.bp b/apex/sdkextensions/derive_sdk/Android.bp
index cf49902..c419b51 100644
--- a/apex/sdkextensions/derive_sdk/Android.bp
+++ b/apex/sdkextensions/derive_sdk/Android.bp
@@ -20,13 +20,13 @@
     ],
     proto: {
         type: "lite",
+        static: true,
     },
     sdk_version: "current",
     stl: "c++_static",
     shared_libs: [ "liblog" ],
     static_libs: [
         "libbase_ndk",
-        "libprotobuf-cpp-lite-ndk",
     ],
 }
 
@@ -45,7 +45,8 @@
     compile_multilib: "prefer32",
     stem: "derive_sdk",
     apex_available: [ "test_com.android.sdkext" ],
-    visibility: [ "//frameworks/base/apex/sdkextensions/testing" ]
+    visibility: [ "//frameworks/base/apex/sdkextensions/testing" ],
+    installable: false,
 }
 
 prebuilt_etc {
diff --git a/api/current.txt b/api/current.txt
index 80e2d00..01ee6d3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -47916,6 +47916,7 @@
     method public static int[] calculateLength(String, boolean);
     method @Deprecated public static android.telephony.SmsMessage createFromPdu(byte[]);
     method public static android.telephony.SmsMessage createFromPdu(byte[], String);
+    method @Nullable public static android.telephony.SmsMessage createSmsSubmitPdu(@NonNull byte[], boolean);
     method public String getDisplayMessageBody();
     method public String getDisplayOriginatingAddress();
     method public String getEmailBody();
@@ -47998,7 +47999,7 @@
 
   public class SubscriptionManager {
     method public void addOnOpportunisticSubscriptionsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
-    method public void addOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
+    method @Deprecated public void addOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
     method public void addOnSubscriptionsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void addSubscriptionsIntoGroup(@NonNull java.util.List<java.lang.Integer>, @NonNull android.os.ParcelUuid);
     method public boolean canManageSubscription(android.telephony.SubscriptionInfo);
diff --git a/api/system-current.txt b/api/system-current.txt
index c5d319c..0bc3cf3 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9766,7 +9766,7 @@
   public abstract class EuiccService extends android.app.Service {
     ctor public EuiccService();
     method public void dump(@NonNull java.io.PrintWriter);
-    method public int encodeSmdxSubjectAndReasonCode(@Nullable String, @Nullable String) throws java.lang.IllegalArgumentException, java.lang.NumberFormatException, java.lang.UnsupportedOperationException;
+    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);
@@ -10203,7 +10203,7 @@
   }
 
   public static class CallScreeningService.CallResponse.Builder {
-    method @NonNull public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallViaAudioProcessing(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT) public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallViaAudioProcessing(boolean);
   }
 
   public abstract class Conference extends android.telecom.Conferenceable {
@@ -11138,7 +11138,6 @@
   }
 
   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);
   }
diff --git a/api/test-current.txt b/api/test-current.txt
index 641767c..d43f564 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3572,7 +3572,7 @@
   }
 
   public static class CallScreeningService.CallResponse.Builder {
-    method @NonNull public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallViaAudioProcessing(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT) public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallViaAudioProcessing(boolean);
   }
 
   public abstract class Conference extends android.telecom.Conferenceable {
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index 645dc93..02e514e 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -25,7 +25,7 @@
     ],
     tidy_flags: [
         "-system-headers",
-        "-warnings-as-errors=*",
+        "-warnings-as-errors=*,-bugprone*",
     ],
 }
 
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp
index e55ea6c..9cae926 100644
--- a/cmds/idmap2/idmap2d/Idmap2Service.cpp
+++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp
@@ -122,7 +122,7 @@
                                   aidl::nullable<std::string>* _aidl_return) {
   assert(_aidl_return);
   SYSTRACE << "Idmap2Service::createIdmap " << target_apk_path << " " << overlay_apk_path;
-  _aidl_return->reset(nullptr);
+  _aidl_return->reset();
 
   const PolicyBitmask policy_bitmask = ConvertAidlArgToPolicyBitmask(fulfilled_policies);
 
diff --git a/cmds/incidentd/src/Section.h b/cmds/incidentd/src/Section.h
index 2ce45ed..bf915c4 100644
--- a/cmds/incidentd/src/Section.h
+++ b/cmds/incidentd/src/Section.h
@@ -164,8 +164,8 @@
     // global last log retrieved timestamp for each log_id_t.
     static map<log_id_t, log_time> gLastLogsRetrieved;
 
-    // log mode: read only & non blocking.
-    const static int logModeBase = ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK;
+    // log mode: non blocking.
+    const static int logModeBase = ANDROID_LOG_NONBLOCK;
 
 public:
     LogSection(int id, const char* logID, ...);
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 9169eb17..dd6d4b5 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -1077,36 +1077,26 @@
     }
 }
 
-Status StatsService::getData(int64_t key, const int32_t callingUid, vector<int8_t>* output) {
+Status StatsService::getData(int64_t key, const int32_t callingUid, vector<uint8_t>* output) {
     ENFORCE_UID(AID_SYSTEM);
 
     VLOG("StatsService::getData with Uid %i", callingUid);
     ConfigKey configKey(callingUid, key);
-    // TODO(b/149254662): Since libbinder_ndk uses int8_t instead of uint8_t,
-    // there are inconsistencies with internal statsd logic. Instead of
-    // modifying lots of files, we create a temporary output array of int8_t and
-    // copy its data into output. This is a bad hack, but hopefully
-    // libbinder_ndk will transition to using uint8_t soon: progress is tracked
-    // in b/144957764. Same applies to StatsService::getMetadata.
-    vector<uint8_t> unsignedOutput;
     // The dump latency does not matter here since we do not include the current bucket, we do not
     // need to pull any new data anyhow.
     mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), false /* include_current_bucket*/,
-                             true /* erase_data */, GET_DATA_CALLED, FAST, &unsignedOutput);
-    *output = vector<int8_t>(unsignedOutput.begin(), unsignedOutput.end());
+                             true /* erase_data */, GET_DATA_CALLED, FAST, output);
     return Status::ok();
 }
 
-Status StatsService::getMetadata(vector<int8_t>* output) {
+Status StatsService::getMetadata(vector<uint8_t>* output) {
     ENFORCE_UID(AID_SYSTEM);
 
-    vector<uint8_t> unsignedOutput;
-    StatsdStats::getInstance().dumpStats(&unsignedOutput, false); // Don't reset the counters.
-    *output = vector<int8_t>(unsignedOutput.begin(), unsignedOutput.end());
+    StatsdStats::getInstance().dumpStats(output, false); // Don't reset the counters.
     return Status::ok();
 }
 
-Status StatsService::addConfiguration(int64_t key, const vector <int8_t>& config,
+Status StatsService::addConfiguration(int64_t key, const vector <uint8_t>& config,
                                       const int32_t callingUid) {
     ENFORCE_UID(AID_SYSTEM);
 
@@ -1117,7 +1107,7 @@
     }
 }
 
-bool StatsService::addConfigurationChecked(int uid, int64_t key, const vector<int8_t>& config) {
+bool StatsService::addConfigurationChecked(int uid, int64_t key, const vector<uint8_t>& config) {
     ConfigKey configKey(uid, key);
     StatsdConfig cfg;
     if (config.size() > 0) {  // If the config is empty, skip parsing.
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 114c84f..460015c 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -94,13 +94,13 @@
      */
     virtual Status getData(int64_t key,
                            const int32_t callingUid,
-                           vector<int8_t>* output) override;
+                           vector<uint8_t>* output) override;
 
 
     /**
      * Binder call for clients to get metadata across all configs in statsd.
      */
-    virtual Status getMetadata(vector<int8_t>* output) override;
+    virtual Status getMetadata(vector<uint8_t>* output) override;
 
 
     /**
@@ -108,7 +108,7 @@
      * should requestData for this configuration.
      */
     virtual Status addConfiguration(int64_t key,
-                                    const vector<int8_t>& config,
+                                    const vector<uint8_t>& config,
                                     const int32_t callingUid) override;
 
     /**
@@ -318,7 +318,7 @@
     /**
      * Adds a configuration after checking permissions and obtaining UID from binder call.
      */
-    bool addConfigurationChecked(int uid, int64_t key, const vector<int8_t>& config);
+    bool addConfigurationChecked(int uid, int64_t key, const vector<uint8_t>& config);
 
     /**
      * Update a configuration.
diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
index b173ee0..4bf3197 100644
--- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
@@ -39,7 +39,7 @@
 void SendConfig(shared_ptr<StatsService>& service, const StatsdConfig& config) {
     string str;
     config.SerializeToString(&str);
-    std::vector<int8_t> configAsVec(str.begin(), str.end());
+    std::vector<uint8_t> configAsVec(str.begin(), str.end());
     service->addConfiguration(kConfigKey, configAsVec, kCallingUid);
 }
 
diff --git a/config/preloaded-classes b/config/preloaded-classes
index d5fba70..7ffedb7 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -11732,6 +11732,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 353f786d..cf242d3 100644
--- a/config/preloaded-classes-blacklist
+++ b/config/preloaded-classes-blacklist
@@ -3,4 +3,4 @@
 android.os.FileObserver
 android.speech.tts.TextToSpeech$Connection$SetupConnectionAsyncTask
 android.widget.Magnifier
-sun.nio.fs.UnixChannelFactory
+
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 @@
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 594e5ff..dc7d053 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1031,7 +1031,11 @@
         try {
             String name = service.getRemoteName(this);
             if (name != null) {
-                return name.replaceAll("[\\t\\n\\r]+", " ");
+                // remove whitespace characters from the name
+                return name
+                        .replace('\t', ' ')
+                        .replace('\n', ' ')
+                        .replace('\r', ' ');
             }
             return null;
         } catch (RemoteException e) {
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 @@
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
\ No newline at end of file
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index f807a49..b872617 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;
 
@@ -70,9 +71,9 @@
     // 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
@@ -295,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;
     }
 
     /**
@@ -365,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/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/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 @@
 [email protected]
 [email protected]
 
-per-file SSL*, Uri*, Url* = [email protected], [email protected], [email protected], [email protected]
+per-file SSL*, Uri*, Url* = [email protected], [email protected], [email protected], [email protected]
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index 2041cfb..c87b827 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -75,7 +75,7 @@
     }
 
     /**
-     * Create an instance of the VpnManger with the given context.
+     * Create an instance of the VpnManager with the given context.
      *
      * <p>Internal only. Applications are expected to obtain an instance of the VpnManager via the
      * {@link Context.getSystemService()} method call.
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 @@
 [email protected]
[email protected]
[email protected]
 include platform/libcore:/OWNERS
 include platform/external/conscrypt:/OWNERS
diff --git a/core/java/android/os/BadParcelableException.java b/core/java/android/os/BadParcelableException.java
index 7e0b1a5..9b1343c 100644
--- a/core/java/android/os/BadParcelableException.java
+++ b/core/java/android/os/BadParcelableException.java
@@ -32,4 +32,8 @@
     public BadParcelableException(Exception cause) {
         super(cause);
     }
+    /** @hide */
+    public BadParcelableException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
 }
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index c889ee6..e6988a3 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -284,6 +284,8 @@
      * system services to determine its identity and check permissions.
      * If the current thread is not currently executing an incoming transaction,
      * then its own pid is returned.
+     *
+     * Warning: oneway transactions do not receive PID.
      */
     @CriticalNative
     public static final native int getCallingPid();
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index af776d1..24aaa58 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -796,6 +796,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.
@@ -805,6 +816,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.
      */
@@ -829,6 +850,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/HandlerThread.java b/core/java/android/os/HandlerThread.java
index 92fcbb6..4dd797a 100644
--- a/core/java/android/os/HandlerThread.java
+++ b/core/java/android/os/HandlerThread.java
@@ -71,23 +71,35 @@
     /**
      * This method returns the Looper associated with this thread. If this thread not been started
      * or for any reason isAlive() returns false, this method will return null. If this thread
-     * has been started, this method will block until the looper has been initialized.  
+     * has been started, this method will block until the looper has been initialized.
      * @return The looper.
      */
     public Looper getLooper() {
         if (!isAlive()) {
             return null;
         }
-        
+
+        boolean wasInterrupted = false;
+
         // If the thread has been started, wait until the looper has been created.
         synchronized (this) {
             while (isAlive() && mLooper == null) {
                 try {
                     wait();
                 } catch (InterruptedException e) {
+                    wasInterrupted = true;
                 }
             }
         }
+
+        /*
+         * We may need to restore the thread's interrupted flag, because it may
+         * have been cleared above since we eat InterruptedExceptions
+         */
+        if (wasInterrupted) {
+            Thread.currentThread().interrupt();
+        }
+
         return mLooper;
     }
 
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index 486ec2a..8a8a6af 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -313,13 +313,16 @@
      * then the given {@link DeathRecipient}'s
      * {@link DeathRecipient#binderDied DeathRecipient.binderDied()} method
      * will be called.
-     * 
+     *
+     * <p>This will automatically be unlinked when all references to the linked
+     * binder proxy are dropped.</p>
+     *
      * <p>You will only receive death notifications for remote binders,
-     * as local binders by definition can't die without you dying as well.
-     * 
+     * as local binders by definition can't die without you dying as well.</p>
+     *
      * @throws RemoteException if the target IBinder's
      * process has already died.
-     * 
+     *
      * @see #unlinkToDeath
      */
     public void linkToDeath(@NonNull DeathRecipient recipient, int flags)
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index a72795d..2a82263 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/Parcel.java b/core/java/android/os/Parcel.java
index f0b7b5f..b6fe5147 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -3264,15 +3264,15 @@
         } catch (IllegalAccessException e) {
             Log.e(TAG, "Illegal access when unmarshalling: " + name, e);
             throw new BadParcelableException(
-                    "IllegalAccessException when unmarshalling: " + name);
+                    "IllegalAccessException when unmarshalling: " + name, e);
         } catch (ClassNotFoundException e) {
             Log.e(TAG, "Class not found when unmarshalling: " + name, e);
             throw new BadParcelableException(
-                    "ClassNotFoundException when unmarshalling: " + name);
+                    "ClassNotFoundException when unmarshalling: " + name, e);
         } catch (NoSuchFieldException e) {
             throw new BadParcelableException("Parcelable protocol requires a "
                     + "Parcelable.Creator object called "
-                    + "CREATOR on class " + name);
+                    + "CREATOR on class " + name, e);
         }
         if (creator == null) {
             throw new BadParcelableException("Parcelable protocol requires a "
diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java
index 82c7ea7..a7ddfa9 100644
--- a/core/java/android/text/util/Linkify.java
+++ b/core/java/android/text/util/Linkify.java
@@ -304,7 +304,7 @@
 
         if ((mask & WEB_URLS) != 0) {
             gatherLinks(links, text, Patterns.AUTOLINK_WEB_URL,
-                new String[] { "http://", "https://", "rtsp://" },
+                new String[] { "http://", "https://", "rtsp://", "ftp://" },
                 sUrlMatchFilter, null);
         }
 
diff --git a/core/java/android/timezone/CountryTimeZones.java b/core/java/android/timezone/CountryTimeZones.java
index a8db50e..8fd303b 100644
--- a/core/java/android/timezone/CountryTimeZones.java
+++ b/core/java/android/timezone/CountryTimeZones.java
@@ -158,7 +158,7 @@
      * supplied.
      */
     public boolean matchesCountryCode(@NonNull String countryIso) {
-        return mDelegate.isForCountryCode(countryIso);
+        return mDelegate.matchesCountryCode(countryIso);
     }
 
     /**
diff --git a/core/java/android/util/Patterns.java b/core/java/android/util/Patterns.java
index 50cd7b1..7ad16ff 100644
--- a/core/java/android/util/Patterns.java
+++ b/core/java/android/util/Patterns.java
@@ -301,7 +301,7 @@
     private static final String DOMAIN_NAME_STR = "(" + HOST_NAME + "|" + IP_ADDRESS_STRING + ")";
     public static final Pattern DOMAIN_NAME = Pattern.compile(DOMAIN_NAME_STR);
 
-    private static final String PROTOCOL = "(?i:http|https|rtsp)://";
+    private static final String PROTOCOL = "(?i:http|https|rtsp|ftp)://";
 
     /* A word boundary or end of input.  This is to stop foo.sure from matching as foo.su */
     private static final String WORD_BOUNDARY = "(?:\\b|$|^)";
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/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 43bd4a6..c0430c3 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -5428,7 +5428,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/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index 7a9b659..8e0546e 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -945,8 +945,11 @@
 
     private void getName(Stats st, String cmdlineFile) {
         String newName = st.name;
-        if (st.name == null || st.name.equals("app_process")
-                || st.name.equals("<pre-initialized>")) {
+        if (st.name == null
+                || st.name.equals("app_process")
+                || st.name.equals("<pre-initialized>")
+                || st.name.equals("usap32")
+                || st.name.equals("usap64")) {
             String cmdName = ProcStatsUtil.readTerminatedProcFile(cmdlineFile, (byte) '\0');
             if (cmdName != null && cmdName.length() > 1) {
                 newName = cmdName;
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 505a05e..93dc6ae 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -1079,6 +1079,11 @@
     public static native int nativeParseSigChld(byte[] in, int length, int[] out);
 
     /**
+     * Returns whether the hardware supports memory tagging (ARM MTE).
+     */
+    public static native boolean nativeSupportsMemoryTagging();
+
+    /**
      * Returns whether the kernel supports tagged pointers. Present in the
      * Android Common Kernel from 4.14 and up. By default, you should prefer
      * fully-feature Memory Tagging, rather than the static Tagged Pointers.
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index c2b13c9..02e3fb9 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -757,7 +757,11 @@
             Zygote.applyDebuggerSystemProperty(parsedArgs);
             Zygote.applyInvokeWithSystemProperty(parsedArgs);
 
-            if (Zygote.nativeSupportsTaggedPointers()) {
+            if (Zygote.nativeSupportsMemoryTagging()) {
+                /* The system server is more privileged than regular app processes, so it has async
+                 * tag checks enabled on hardware that supports memory tagging. */
+                parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_ASYNC;
+            } else if (Zygote.nativeSupportsTaggedPointers()) {
                 /* Enable pointer tagging in the system server. Hardware support for this is present
                  * in all ARMv8 CPUs. */
                 parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI;
diff --git a/core/java/com/android/internal/util/ContrastColorUtil.java b/core/java/com/android/internal/util/ContrastColorUtil.java
index bf088e0a..8508a8d 100644
--- a/core/java/com/android/internal/util/ContrastColorUtil.java
+++ b/core/java/com/android/internal/util/ContrastColorUtil.java
@@ -73,7 +73,7 @@
 
     private ContrastColorUtil(Context context) {
         mGrayscaleIconMaxSize = context.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_large_icon_width);
+                com.android.internal.R.dimen.notification_grayscale_icon_max_size);
     }
 
     /**
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 189a0a7..a390060 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -304,4 +304,10 @@
             ],
         },
     },
+
+    product_variables: {
+        experimental_mte: {
+            cflags: ["-DANDROID_EXPERIMENTAL_MTE"],
+        },
+    },
 }
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_os_HwParcel.cpp b/core/jni/android_os_HwParcel.cpp
index 151dbfce..a88f891 100644
--- a/core/jni/android_os_HwParcel.cpp
+++ b/core/jni/android_os_HwParcel.cpp
@@ -292,19 +292,11 @@
         return;
     }
 
-    const jchar *interfaceName = env->GetStringCritical(interfaceNameObj, NULL);
+    const char *interfaceName = env->GetStringUTFChars(interfaceNameObj, NULL);
     if (interfaceName) {
-        String8 interfaceNameCopy = String8(String16(
-                reinterpret_cast<const char16_t *>(interfaceName),
-                env->GetStringLength(interfaceNameObj)));
-
-        env->ReleaseStringCritical(interfaceNameObj, interfaceName);
-        interfaceName = NULL;
-
         hardware::Parcel *parcel =
             JHwParcel::GetNativeContext(env, thiz)->getParcel();
-
-        bool valid = parcel->enforceInterface(interfaceNameCopy.string());
+        bool valid = parcel->enforceInterface(interfaceName);
 
         if (!valid) {
             jniThrowException(
@@ -312,6 +304,7 @@
                     "java/lang/SecurityException",
                     "HWBinder invocation to an incorrect interface");
         }
+        env->ReleaseStringUTFChars(interfaceNameObj, interfaceName);
     }
 }
 
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 483b455..e7eeb4e 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -625,8 +625,8 @@
             IPCThreadState* threadState = IPCThreadState::self();
             const int32_t oldPolicy = threadState->getStrictModePolicy();
             const bool isValid = parcel->enforceInterface(
-                String16(reinterpret_cast<const char16_t*>(str),
-                         env->GetStringLength(name)),
+                reinterpret_cast<const char16_t*>(str),
+                env->GetStringLength(name),
                 threadState);
             env->ReleaseStringCritical(name, str);
             if (isValid) {
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index bf3fc57..83fffe2 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -18,14 +18,13 @@
 #define LOG_TAG "asset"
 
 #include <inttypes.h>
+#include <linux/capability.h>
 #include <stdio.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
 
-#include <private/android_filesystem_config.h> // for AID_SYSTEM
-
 #include <sstream>
 #include <string>
 
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 924dc4b..4dd30d8 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -55,6 +55,7 @@
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/auxv.h>
 #include <sys/capability.h>
 #include <sys/cdefs.h>
 #include <sys/eventfd.h>
@@ -76,6 +77,8 @@
 #include <android-base/stringprintf.h>
 #include <android-base/unique_fd.h>
 #include <bionic/malloc.h>
+#include <bionic/mte.h>
+#include <bionic/mte_kernel.h>
 #include <cutils/fs.h>
 #include <cutils/multiuser.h>
 #include <cutils/sockets.h>
@@ -342,6 +345,8 @@
     PROFILE_FROM_SHELL = 1 << 15,
     MEMORY_TAG_LEVEL_MASK = (1 << 19) | (1 << 20),
     MEMORY_TAG_LEVEL_TBI = 1 << 19,
+    MEMORY_TAG_LEVEL_ASYNC = 2 << 19,
+    MEMORY_TAG_LEVEL_SYNC = 3 << 19,
     GWP_ASAN_LEVEL_MASK = (1 << 21) | (1 << 22),
     GWP_ASAN_LEVEL_NEVER = 0 << 21,
     GWP_ASAN_LEVEL_LOTTERY = 1 << 21,
@@ -1604,6 +1609,28 @@
   }
 }
 
+#ifdef ANDROID_EXPERIMENTAL_MTE
+static void SetTagCheckingLevel(int level) {
+#ifdef __aarch64__
+  if (!(getauxval(AT_HWCAP2) & HWCAP2_MTE)) {
+    return;
+  }
+
+  int tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
+  if (tagged_addr_ctrl < 0) {
+    ALOGE("prctl(PR_GET_TAGGED_ADDR_CTRL) failed: %s", strerror(errno));
+    return;
+  }
+
+  tagged_addr_ctrl = (tagged_addr_ctrl & ~PR_MTE_TCF_MASK) | level;
+  if (prctl(PR_SET_TAGGED_ADDR_CTRL, tagged_addr_ctrl, 0, 0, 0) < 0) {
+    ALOGE("prctl(PR_SET_TAGGED_ADDR_CTRL, %d) failed: %s", tagged_addr_ctrl,
+          strerror(errno));
+  }
+#endif
+}
+#endif
+
 // Utility routine to specialize a zygote child process.
 static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
                              jint runtime_flags, jobjectArray rlimits,
@@ -1737,7 +1764,23 @@
     case RuntimeFlags::MEMORY_TAG_LEVEL_TBI:
       heap_tagging_level = M_HEAP_TAGGING_LEVEL_TBI;
       break;
+    case RuntimeFlags::MEMORY_TAG_LEVEL_ASYNC:
+#ifdef ANDROID_EXPERIMENTAL_MTE
+      SetTagCheckingLevel(PR_MTE_TCF_ASYNC);
+#endif
+      heap_tagging_level = M_HEAP_TAGGING_LEVEL_ASYNC;
+      break;
+    case RuntimeFlags::MEMORY_TAG_LEVEL_SYNC:
+#ifdef ANDROID_EXPERIMENTAL_MTE
+      SetTagCheckingLevel(PR_MTE_TCF_SYNC);
+#endif
+      // TODO(pcc): Use SYNC here once the allocator supports it.
+      heap_tagging_level = M_HEAP_TAGGING_LEVEL_ASYNC;
+      break;
     default:
+#ifdef ANDROID_EXPERIMENTAL_MTE
+      SetTagCheckingLevel(PR_MTE_TCF_NONE);
+#endif
       heap_tagging_level = M_HEAP_TAGGING_LEVEL_NONE;
   }
   android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &heap_tagging_level, sizeof(heap_tagging_level));
@@ -2432,6 +2475,14 @@
     return -1;
 }
 
+static jboolean com_android_internal_os_Zygote_nativeSupportsMemoryTagging(JNIEnv* env, jclass) {
+#if defined(__aarch64__)
+  return mte_supported();
+#else
+  return false;
+#endif
+}
+
 static jboolean com_android_internal_os_Zygote_nativeSupportsTaggedPointers(JNIEnv* env, jclass) {
 #ifdef __aarch64__
   int res = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
@@ -2476,6 +2527,8 @@
          (void*)com_android_internal_os_Zygote_nativeBoostUsapPriority},
         {"nativeParseSigChld", "([BI[I)I",
          (void*)com_android_internal_os_Zygote_nativeParseSigChld},
+        {"nativeSupportsMemoryTagging", "()Z",
+         (void*)com_android_internal_os_Zygote_nativeSupportsMemoryTagging},
         {"nativeSupportsTaggedPointers", "()Z",
          (void*)com_android_internal_os_Zygote_nativeSupportsTaggedPointers},
 };
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 7edb86b..c44c116 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -681,6 +681,8 @@
     <dimen name="notification_media_image_max_width_low_ram">100dp</dimen>
     <!-- The size of the right icon image when on low ram -->
     <dimen name="notification_right_icon_size_low_ram">@dimen/notification_right_icon_size</dimen>
+    <!-- The maximum size of the grayscale icon -->
+    <dimen name="notification_grayscale_icon_max_size">256dp</dimen>
 
     <dimen name="messaging_avatar_size">@dimen/notification_right_icon_size</dimen>
     <dimen name="conversation_avatar_size">52dp</dimen>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ef1e8b7..9c70a3e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3325,6 +3325,7 @@
   <java-symbol type="dimen" name="notification_media_image_max_width_low_ram"/>
   <java-symbol type="dimen" name="notification_media_image_max_height_low_ram"/>
   <java-symbol type="dimen" name="notification_right_icon_size_low_ram"/>
+  <java-symbol type="dimen" name="notification_grayscale_icon_max_size"/>
   <java-symbol type="dimen" name="notification_custom_view_max_image_height_low_ram"/>
   <java-symbol type="dimen" name="notification_custom_view_max_image_width_low_ram"/>
 
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
 [email protected]
[email protected]
 [email protected]
 [email protected]
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 @@
 [email protected]
 
 per-file [email protected]
-per-file [email protected],[email protected],[email protected]
+per-file [email protected],[email protected],[email protected]
diff --git a/libs/androidfw/ZipUtils.cpp b/libs/androidfw/ZipUtils.cpp
index 5be2105..568e3b6 100644
--- a/libs/androidfw/ZipUtils.cpp
+++ b/libs/androidfw/ZipUtils.cpp
@@ -40,7 +40,7 @@
     explicit FileReader(FILE* fp) : Reader(), mFp(fp), mCurrentOffset(0) {
     }
 
-    bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const {
+    bool ReadAtOffset(uint8_t* buf, size_t len, off64_t offset) const {
         // Data is usually requested sequentially, so this helps avoid pointless
         // fseeks every time we perform a read. There's an impedence mismatch
         // here because the original API was designed around pread and pwrite.
@@ -63,7 +63,7 @@
 
   private:
     FILE* mFp;
-    mutable uint32_t mCurrentOffset;
+    mutable off64_t mCurrentOffset;
 };
 
 class FdReader : public zip_archive::Reader {
@@ -71,8 +71,8 @@
     explicit FdReader(int fd) : mFd(fd) {
     }
 
-    bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const {
-      return android::base::ReadFullyAtOffset(mFd, buf, len, static_cast<off_t>(offset));
+    bool ReadAtOffset(uint8_t* buf, size_t len, off64_t offset) const {
+      return android::base::ReadFullyAtOffset(mFd, buf, len, offset);
     }
 
   private:
@@ -86,8 +86,8 @@
         mInputSize(inputSize) {
     }
 
-    bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const {
-        if (offset + len > mInputSize) {
+    bool ReadAtOffset(uint8_t* buf, size_t len, off64_t offset) const {
+        if (mInputSize < len || offset > mInputSize - len) {
             return false;
         }
 
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/libs/androidfw/tests/CommonHelpers.h b/libs/androidfw/tests/CommonHelpers.h
index 8af13f2..316a57a 100644
--- a/libs/androidfw/tests/CommonHelpers.h
+++ b/libs/androidfw/tests/CommonHelpers.h
@@ -21,8 +21,6 @@
 #include <string>
 
 #include "androidfw/ResourceTypes.h"
-#include "utils/String16.h"
-#include "utils/String8.h"
 
 namespace android {
 
@@ -40,10 +38,6 @@
   return a.compare(b) == 0;
 }
 
-static inline ::std::ostream& operator<<(::std::ostream& out, const String8& str) {
-  return out << str.string();
-}
-
 static inline ::std::ostream& operator<<(::std::ostream& out, const ResTable_config& c) {
   return out << c.toString();
 }
diff --git a/media/OWNERS b/media/OWNERS
index be60583..242ff28 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -14,6 +14,7 @@
 [email protected]
 [email protected]
 [email protected]
[email protected]
 [email protected]
 [email protected]
 
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/tools/aapt/tests/TestHelper.h b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstance.java
similarity index 61%
copy from tools/aapt/tests/TestHelper.h
copy to media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstance.java
index 79174832..817bd3d 100644
--- a/tools/aapt/tests/TestHelper.h
+++ b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstance.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * 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.
@@ -14,20 +14,12 @@
  * limitations under the License.
  */
 
-#ifndef __TEST_HELPER_H
-#define __TEST_HELPER_H
+package com.android.effectstest;
 
-#include <utils/String8.h>
-
-namespace android {
-
-/**
- * Stream operator for nicely printing String8's in gtest output.
- */
-inline std::ostream& operator<<(std::ostream& stream, const String8& str) {
-    return stream << str.string();
+interface VisualizerInstance {
+    void enableDataCaptureListener(boolean enable);
+    boolean getEnabled();
+    void release();
+    void setEnabled(boolean enabled);
+    void startStopCapture(boolean start);
 }
-
-}
-
-#endif
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/CarrierDefaultApp/OWNERS b/packages/CarrierDefaultApp/OWNERS
index 0d8e69b..5668840 100644
--- a/packages/CarrierDefaultApp/OWNERS
+++ b/packages/CarrierDefaultApp/OWNERS
@@ -1,8 +1,8 @@
+set noparent
 [email protected]
 [email protected]
 [email protected]
 [email protected]
[email protected]
 [email protected]
 [email protected]
 [email protected]
@@ -12,3 +12,6 @@
 [email protected]
 [email protected]
 [email protected]
[email protected]
[email protected]
+
diff --git a/packages/InputDevices/res/raw/keyboard_layout_belarusian.kcm b/packages/InputDevices/res/raw/keyboard_layout_belarusian.kcm
new file mode 100644
index 0000000..3deb9dd
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_belarusian.kcm
@@ -0,0 +1,343 @@
+# 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.
+
+# Belarusian keyboard layout.
+# This is a typical Belarusian PC keyboard layout.
+# As an added convenience, English characters are accessible using ralt (Alt Gr).
+#
+
+type OVERLAY
+map key 86 BACKSLASH
+### ROW 1
+key GRAVE {
+    label:                              '\u0401'
+    base:                               '\u0451'
+    shift, capslock:                    '\u0401'
+    ralt:                               '`'
+    ralt+shift:                         '~'
+}
+key 1 {
+    label:                              '1'
+    base:                               '1'
+    shift:                              '!'
+    ralt:                               '!'
+}
+key 2 {
+    label:                              '2'
+    base:                               '2'
+    shift:                              '"'
+    ralt:                               '@'
+}
+key 3 {
+    label:                              '3'
+    base:                               '3'
+    shift:                              '\u2116'
+    ralt:                               '#'
+}
+key 4 {
+    label:                              '4'
+    base:                               '4'
+    shift:                              ';'
+    ralt:                               '$'
+}
+key 5 {
+    label:                              '5'
+    base:                               '5'
+    shift:                              '%'
+    ralt:                               '%'
+}
+key 6 {
+    label:                              '6'
+    base:                               '6'
+    shift:                              ':'
+    ralt:                               '^'
+}
+key 7 {
+    label:                              '7'
+    base:                               '7'
+    shift:                              '?'
+    ralt:                               '&'
+}
+key 8 {
+    label:                              '8'
+    base:                               '8'
+    shift:                              '*'
+    ralt:                               '*'
+}
+key 9 {
+    label:                              '9'
+    base:                               '9'
+    shift:                              '('
+    ralt:                               '('
+}
+key 0 {
+    label:                              '0'
+    base:                               '0'
+    shift:                              ')'
+    ralt:                               ')'
+}
+key MINUS {
+    label:                              '-'
+    base:                               '-'
+    shift:                              '_'
+    ralt:                               '-'
+    ralt+shift:                         '_'
+}
+key EQUALS {
+    label:                              '='
+    base:                               '='
+    shift:                              '+'
+    ralt:                               '='
+    ralt+shift:                         '+'
+}
+### ROW 2
+key Q {
+    label:                              '\u0419'
+    base:                               '\u0439'
+    shift, capslock:                    '\u0419'
+    ralt:                               'q'
+    ralt+shift, ralt+capslock:          'Q'
+}
+key W {
+    label:                              '\u0426'
+    base:                               '\u0446'
+    shift, capslock:                    '\u0426'
+    ralt:                               'w'
+    ralt+shift, ralt+capslock:          'W'
+}
+key E {
+    label:                              '\u0423'
+    base:                               '\u0443'
+    shift, capslock:                    '\u0423'
+    ralt:                               'e'
+    ralt+shift, ralt+capslock:          'E'
+}
+key R {
+    label:                              '\u041a'
+    base:                               '\u043a'
+    shift, capslock:                    '\u041a'
+    ralt:                               'r'
+    ralt+shift, ralt+capslock:          'R'
+}
+key T {
+    label:                              '\u0415'
+    base:                               '\u0435'
+    shift, capslock:                    '\u0415'
+    ralt:                               't'
+    ralt+shift, ralt+capslock:          'T'
+}
+key Y {
+    label:                              '\u041d'
+    base:                               '\u043d'
+    shift, capslock:                    '\u041d'
+    ralt:                               'y'
+    ralt+shift, ralt+capslock:          'Y'
+}
+key U {
+    label:                              '\u0413'
+    base:                               '\u0433'
+    shift, capslock:                    '\u0413'
+    ralt:                               'u'
+    ralt+shift, ralt+capslock:          'U'
+}
+key I {
+    label:                              '\u0428'
+    base:                               '\u0448'
+    shift, capslock:                    '\u0428'
+    ralt:                               'i'
+    ralt+shift, ralt+capslock:          'I'
+}
+key O {
+    label:                              '\u040E'
+    base:                               '\u045E'
+    shift, capslock:                    '\u040E'
+    ralt:                               'o'
+    ralt+shift, ralt+capslock:          'O'
+}
+key P {
+    label:                              '\u0417'
+    base:                               '\u0437'
+    shift, capslock:                    '\u0417'
+    ralt:                               'p'
+    ralt+shift, ralt+capslock:          'P'
+}
+key LEFT_BRACKET {
+    label:                              '\u0425'
+    base:                               '\u0445'
+    shift, capslock:                    '\u0425'
+    ralt:                               '['
+    ralt+shift:                         '{'
+}
+key RIGHT_BRACKET {
+    label:                              '\u0027'
+    base:                               '\u0027'
+    shift, capslock:                    '\u0027'
+    ralt:                               ']'
+    ralt+shift:                         '}'
+}
+### ROW 3
+key A {
+    label:                              '\u0424'
+    base:                               '\u0444'
+    shift, capslock:                    '\u0424'
+    ralt:                               'a'
+    ralt+shift, ralt+capslock:          'A'
+}
+key S {
+    label:                              '\u042b'
+    base:                               '\u044b'
+    shift, capslock:                    '\u042b'
+    ralt:                               's'
+    ralt+shift, ralt+capslock:          'S'
+}
+key D {
+    label:                              '\u0412'
+    base:                               '\u0432'
+    shift, capslock:                    '\u0412'
+    ralt:                               'd'
+    ralt+shift, ralt+capslock:          'D'
+}
+key F {
+    label:                              '\u0410'
+    base:                               '\u0430'
+    shift, capslock:                    '\u0410'
+    ralt:                               'f'
+    ralt+shift, ralt+capslock:          'F'
+}
+key G {
+    label:                              '\u041f'
+    base:                               '\u043f'
+    shift, capslock:                    '\u041f'
+    ralt:                               'g'
+    ralt+shift, ralt+capslock:          'G'
+}
+key H {
+    label:                              '\u0420'
+    base:                               '\u0440'
+    shift, capslock:                    '\u0420'
+    ralt:                               'h'
+    ralt+shift, ralt+capslock:          'H'
+}
+key J {
+    label:                              '\u041e'
+    base:                               '\u043e'
+    shift, capslock:                    '\u041e'
+    ralt:                               'j'
+    ralt+shift, ralt+capslock:          'J'
+}
+key K {
+    label:                              '\u041b'
+    base:                               '\u043b'
+    shift, capslock:                    '\u041b'
+    ralt:                               'k'
+    ralt+shift, ralt+capslock:          'K'
+}
+key L {
+    label:                              '\u0414'
+    base:                               '\u0434'
+    shift, capslock:                    '\u0414'
+    ralt:                               'l'
+    ralt+shift, ralt+capslock:          'L'
+}
+key SEMICOLON {
+    label:                              '\u0416'
+    base:                               '\u0436'
+    shift, capslock:                    '\u0416'
+    ralt:                               ';'
+    ralt+shift:                         ':'
+}
+key APOSTROPHE {
+    label:                              '\u042d'
+    base:                               '\u044d'
+    shift, capslock:                    '\u042d'
+    ralt:                               '\''
+    ralt+shift:                         '"'
+}
+key BACKSLASH {
+    label:                              '\\'
+    base:                               '\\'
+    shift:                              '/'
+    ralt:                               '|'
+}
+### ROW 4
+key Z {
+    label:                              '\u042f'
+    base:                               '\u044f'
+    shift, capslock:                    '\u042f'
+    ralt:                               'z'
+    ralt+shift, ralt+capslock:          'Z'
+}
+key X {
+    label:                              '\u0427'
+    base:                               '\u0447'
+    shift, capslock:                    '\u0427'
+    ralt:                               'x'
+    ralt+shift, ralt+capslock:          'X'
+}
+key C {
+    label:                              '\u0421'
+    base:                               '\u0441'
+    shift, capslock:                    '\u0421'
+    ralt:                               'c'
+    ralt+shift, ralt+capslock:          'C'
+}
+key V {
+    label:                              '\u041c'
+    base:                               '\u043c'
+    shift, capslock:                    '\u041c'
+    ralt:                               'v'
+    ralt+shift, ralt+capslock:          'V'
+}
+key B {
+    label:                              '\u0406'
+    base:                               '\u0456'
+    shift, capslock:                    '\u0406'
+    ralt:                               'b'
+    ralt+shift, ralt+capslock:          'B'
+}
+key N {
+    label:                              '\u0422'
+    base:                               '\u0442'
+    shift, capslock:                    '\u0422'
+    ralt:                               'n'
+    ralt+shift, ralt+capslock:          'N'
+}
+key M {
+    label:                              '\u042c'
+    base:                               '\u044c'
+    shift, capslock:                    '\u042c'
+    ralt:                               'm'
+    ralt+shift, ralt+capslock:          'M'
+}
+key COMMA {
+    label:                              '\u0411'
+    base:                               '\u0431'
+    shift, capslock:                    '\u0411'
+    ralt:                               ','
+    ralt+shift:                         '<'
+}
+key PERIOD {
+    label:                              '\u042e'
+    base:                               '\u044e'
+    shift, capslock:                    '\u042e'
+    ralt:                               '.'
+    ralt+shift:                         '>'
+}
+key SLASH {
+    label:                              '.'
+    base:                               '.'
+    shift:                              ','
+    ralt:                               '/'
+    ralt+shift:                         '?'
+}
diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml
index 5fdc4a6..ac70c94 100644
--- a/packages/InputDevices/res/values/strings.xml
+++ b/packages/InputDevices/res/values/strings.xml
@@ -128,4 +128,7 @@
 
     <!-- Polish keyboard layout label. [CHAR LIMIT=35] -->
     <string name="keyboard_layout_polish">Polish</string>
+
+    <!-- Belarusian keyboard layout label. [CHAR LIMIT=35] -->
+    <string name="keyboard_layout_belarusian">Belarusian</string>
 </resources>
diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml
index 1807aea..68ca093 100644
--- a/packages/InputDevices/res/xml/keyboard_layouts.xml
+++ b/packages/InputDevices/res/xml/keyboard_layouts.xml
@@ -163,4 +163,8 @@
     <keyboard-layout android:name="keyboard_layout_polish"
             android:label="@string/keyboard_layout_polish"
             android:keyboardLayout="@raw/keyboard_layout_polish" />
+
+    <keyboard-layout android:name="keyboard_layout_belarusian"
+            android:label="@string/keyboard_layout_belarusian"
+            android:keyboardLayout="@raw/keyboard_layout_belarusian" />
 </keyboard-layouts>
diff --git a/packages/SettingsLib/OWNERS b/packages/SettingsLib/OWNERS
index a28ba85..cb36c4c 100644
--- a/packages/SettingsLib/OWNERS
+++ b/packages/SettingsLib/OWNERS
@@ -4,10 +4,8 @@
 [email protected]
 [email protected]
 [email protected]
[email protected]
 [email protected]
 [email protected]
[email protected]
 
 # Exempt resource files (because they are in a flat directory and too hard to manage via OWNERS)
 per-file *.xml=*
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index db219c9..287f804 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -688,8 +688,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/SettingsProvider/OWNERS b/packages/SettingsProvider/OWNERS
index 2054129..b2ac4f4 100644
--- a/packages/SettingsProvider/OWNERS
+++ b/packages/SettingsProvider/OWNERS
@@ -1,3 +1,5 @@
 [email protected]
[email protected]
 [email protected]
[email protected]
[email protected]
[email protected]
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/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index 8ba6084..7ae8fbc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -66,11 +66,13 @@
         dialog.setTitle(com.android.internal.R.string.data_saver_enable_title);
         dialog.setMessage(com.android.internal.R.string.data_saver_description);
         dialog.setPositiveButton(com.android.internal.R.string.data_saver_enable_button,
-                (OnClickListener) (dialogInterface, which) -> toggleDataSaver());
+                (OnClickListener) (dialogInterface, which) -> {
+                    toggleDataSaver();
+                    Prefs.putBoolean(mContext, Prefs.Key.QS_DATA_SAVER_DIALOG_SHOWN, true);
+                });
         dialog.setNegativeButton(com.android.internal.R.string.cancel, null);
         dialog.setShowForAllUsers(true);
         dialog.show();
-        Prefs.putBoolean(mContext, Prefs.Key.QS_DATA_SAVER_DIALOG_SHOWN, true);
     }
 
     private void toggleDataSaver() {
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 4bee075..7da9135 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
@@ -39,6 +39,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 BroadcastDispatcher mBroadcastDispatcher;
 
@@ -109,8 +111,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/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 8dd4fa6..65ac784 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -166,6 +166,7 @@
     private int mLastInvalidCharger;
 
     private int mLowBatteryWarningLevel;
+    private int mLastLowBatteryWarningLevel;
     private int mLowBatteryCloseWarningLevel;
     private int mShutdownBatteryTemperature;
 
@@ -314,6 +315,7 @@
         final ContentResolver resolver = mContext.getContentResolver();
         int defWarnLevel = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_lowBatteryWarningLevel);
+        mLastLowBatteryWarningLevel = mLowBatteryWarningLevel;
         mLowBatteryWarningLevel = Settings.Global.getInt(resolver,
                 Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel);
         if (mLowBatteryWarningLevel == 0) {
@@ -358,7 +360,8 @@
         return !plugged
                 && mHealthInfo.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
                 && mHealthInfo.batteryLevel <= mLowBatteryWarningLevel
-                && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel);
+                && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel
+                    || mHealthInfo.batteryLevel > mLastLowBatteryWarningLevel);
     }
 
     private boolean shouldShutdownLocked() {
diff --git a/services/core/java/com/android/server/accounts/TokenCache.java b/services/core/java/com/android/server/accounts/TokenCache.java
index e38cf5f..66e550f 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 89fa02b..acc82fe 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -110,6 +110,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.ProcessMap;
 import com.android.internal.app.procstats.ProcessStats;
+import com.android.internal.os.RuntimeInit;
 import com.android.internal.os.Zygote;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FrameworkStatsLog;
@@ -123,7 +124,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;
@@ -344,10 +344,18 @@
      * 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.
 
     /**
+     * Enable memory tag checks in non-system apps. This flag will only have an effect on
+     * hardware supporting the ARM Memory Tagging Extension (MTE).
+     */
+    @ChangeId
+    @Disabled
+    private static final long NATIVE_MEMORY_TAGGING = 135772972; // This is a bug id.
+
+    /**
      * Enable sampled memory bug detection in the app.
      * @see <a href="https://source.android.com/devices/tech/debug/gwp-asan">GWP-ASan</a>.
      */
@@ -360,7 +368,7 @@
      * app has made them world-readable.
      */
     @ChangeId
-    @EnabledAfter(targetSdkVersion = VersionCodes.Q)
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
     private static final long APP_DATA_DIRECTORY_ISOLATION = 143937733; // See b/143937733
 
     ActivityManagerService mService = null;
@@ -1856,7 +1864,15 @@
                 runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
             }
 
-            if (Zygote.nativeSupportsTaggedPointers()) {
+            if (Zygote.nativeSupportsMemoryTagging()) {
+                // System apps are generally more privileged than regular apps, and don't have the
+                // same app compat concerns as regular apps, so we enable async tag checks for all
+                // of their processes.
+                if ((app.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0
+                        || mPlatformCompat.isChangeEnabled(NATIVE_MEMORY_TAGGING, app.info)) {
+                    runtimeFlags |= Zygote.MEMORY_TAG_LEVEL_ASYNC;
+                }
+            } else if (Zygote.nativeSupportsTaggedPointers()) {
                 // Enable heap pointer tagging if supported by the kernel, unless disabled by the
                 // app manifest, target sdk level, or compat feature.
                 if (app.info.allowsNativeHeapPointerTagging()
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 02d8571..661abc8 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -3624,7 +3624,7 @@
                 iter.remove();
                 try {
                     hdlr.getBinder().unlinkToDeath(hdlr, 0);
-                    if (cb != hdlr.getBinder()) {
+                    if (cb != hdlr.getBinder()){
                         hdlr = null;
                     }
                 } catch (NoSuchElementException e) {
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 8ed864c..b694fc3 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -20,6 +20,7 @@
 import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG;
 import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.Process.SYSTEM_UID;
 
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
@@ -326,6 +327,10 @@
     }
 
     private void checkCompatChangeLogPermission() throws SecurityException {
+        // Don't check for permissions within the system process
+        if (Binder.getCallingUid() == SYSTEM_UID) {
+            return;
+        }
         if (mContext.checkCallingOrSelfPermission(LOG_COMPAT_CHANGE)
                 != PERMISSION_GRANTED) {
             throw new SecurityException("Cannot log compat change usage");
@@ -333,6 +338,10 @@
     }
 
     private void checkCompatChangeReadPermission() throws SecurityException {
+        // Don't check for permissions within the system process
+        if (Binder.getCallingUid() == SYSTEM_UID) {
+            return;
+        }
         if (mContext.checkCallingOrSelfPermission(READ_COMPAT_CHANGE_CONFIG)
                 != PERMISSION_GRANTED) {
             throw new SecurityException("Cannot read compat change");
@@ -340,6 +349,10 @@
     }
 
     private void checkCompatChangeOverridePermission() throws SecurityException {
+        // Don't check for permissions within the system process
+        if (Binder.getCallingUid() == SYSTEM_UID) {
+            return;
+        }
         if (mContext.checkCallingOrSelfPermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
                 != PERMISSION_GRANTED) {
             throw new SecurityException("Cannot override compat change");
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 15628f0..2d1f553 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -653,19 +653,22 @@
     // 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 + "} "
-                + "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/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index a702ce5..0086402 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -1092,10 +1092,11 @@
         HdmiDeviceInfo avr = getAvrDeviceInfo();
         if (avr != null
                 && (avrAddress == avr.getLogicalAddress())
-                && isConnectedToArcPort(avr.getPhysicalAddress())
-                && isDirectConnectAddress(avr.getPhysicalAddress())) {
+                && isConnectedToArcPort(avr.getPhysicalAddress())) {
             if (enabled) {
-                return isConnected(avr.getPortId()) && isArcFeatureEnabled(avr.getPortId());
+                return isConnected(avr.getPortId())
+                    && isArcFeatureEnabled(avr.getPortId())
+                    && isDirectConnectAddress(avr.getPhysicalAddress());
             } else {
                 return true;
             }
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index d862e4f..8a2202c 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -861,13 +861,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/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index f8c173f..0d7494c 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -32,6 +32,7 @@
 per-file CrossProfileIntentResolver.java = [email protected], [email protected]
 per-file UserManagerService.java = [email protected], [email protected]
 per-file UserRestrictionsUtils.java = [email protected], [email protected], [email protected], [email protected]
+per-file RestrictionsSet.java = [email protected], [email protected], [email protected], [email protected], [email protected]
 per-file UserSystemPackageInstaller.java = [email protected], [email protected], [email protected]
 per-file UserTypeDetails.java = [email protected], [email protected], [email protected]
 per-file UserTypeFactory.java = [email protected], [email protected], [email protected]
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 @@
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e2a2473..23254d3 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -190,12 +190,6 @@
     private static final String ENCRYPTING_STATE = "trigger_restart_min_framework";
     private static final String ENCRYPTED_STATE = "1";
 
-    private static final long SNAPSHOT_INTERVAL = 60 * 60 * 1000; // 1hr
-
-    // The earliest supported time.  We pick one day into 1970, to
-    // give any timezone code room without going into negative time.
-    private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000;
-
     private static final long SLOW_DISPATCH_THRESHOLD_MS = 100;
     private static final long SLOW_DELIVERY_THRESHOLD_MS = 200;
 
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/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
index 69ef499..a6fa0ac 100644
--- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
@@ -38,6 +38,7 @@
 import com.android.server.twilight.TwilightState;
 import com.android.server.wm.WindowManagerInternal;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -158,6 +159,7 @@
         LocalServices.addService(clazz, service);
     }
 
+    @Ignore // b/152719290 - Fails on stage-aosp-master
     @Test
     public void setAutoMode_screenOffRegistered() throws RemoteException {
         try {
@@ -167,6 +169,7 @@
         verify(mContext, atLeastOnce()).registerReceiver(any(BroadcastReceiver.class), any());
     }
 
+    @Ignore // b/152719290 - Fails on stage-aosp-master
     @Test
     public void setAutoMode_screenOffUnRegistered() throws RemoteException {
         try {
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 @@
 [email protected]
 [email protected]
 [email protected]
[email protected]
[email protected]
[email protected]
[email protected]
\ No newline at end of file
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index f8722f4..6bb4905 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -16,7 +16,9 @@
 
 package android.telecom;
 
+import android.Manifest;
 import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
@@ -290,6 +292,7 @@
              */
             @SystemApi
             @TestApi
+            @RequiresPermission(Manifest.permission.CAPTURE_AUDIO_OUTPUT)
             public @NonNull Builder setShouldScreenCallViaAudioProcessing(
                     boolean shouldScreenCallViaAudioProcessing) {
                 mShouldScreenCallViaAudioProcessing = shouldScreenCallViaAudioProcessing;
diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt
index 8ce4b0d..d704398 100644
--- a/telephony/api/system-current.txt
+++ b/telephony/api/system-current.txt
@@ -641,7 +641,6 @@
   }
 
   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);
   }
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/java/android/service/euicc/EuiccService.java b/telephony/java/android/service/euicc/EuiccService.java
index 9315586..ae2652e 100644
--- a/telephony/java/android/service/euicc/EuiccService.java
+++ b/telephony/java/android/service/euicc/EuiccService.java
@@ -327,9 +327,8 @@
      * @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(@Nullable String subjectCode,
-            @Nullable String reasonCode)
-            throws NumberFormatException, IllegalArgumentException, UnsupportedOperationException {
+    public int encodeSmdxSubjectAndReasonCode(@NonNull String subjectCode,
+            @NonNull String reasonCode) {
         final int maxSupportedSection = 3;
         final int maxSupportedDigit = 15;
         final int bitsPerSection = 4;
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 56f3c3e..c7702bf 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -328,6 +328,34 @@
             "only_auto_select_in_home_network";
 
     /**
+     * Flag indicating whether to show single operator row in the choose network setting.
+     *
+     * The device configuration value {@code config_enableNewAutoSelectNetworkUI} ultimately
+     * controls whether this carrier configuration option is used.  Where
+     * {@code config_enableNewAutoSelectNetworkUI} is false, the value of the
+     * {@link #KEY_SHOW_SINGLE_OPERATOR_ROW_IN_CHOOSE_NETWORK_SETTING_BOOL} carrier configuration
+     * option is ignored.
+     *
+     * If {@code true}, default value, merge the duplicate networks which with the same plmn, keep
+     * the one that with the higher signal strength level.
+     * If {@code false}, show all operators without merging.
+     * @hide
+     */
+    public static final String KEY_SHOW_SINGLE_OPERATOR_ROW_IN_CHOOSE_NETWORK_SETTING_BOOL =
+            "show_single_operator_row_in_choose_network_setting_bool";
+
+    /**
+     * Flag indicating whether to display SPN as network name for home network in choose
+     * network setting.
+     *
+     * If {@code true}, display SPN as network name in choose network setting.
+     * If {@code false}, display PLMN in choose network setting.
+     * @hide
+     */
+    public static final String KEY_SHOW_SPN_FOR_HOME_IN_CHOOSE_NETWORK_SETTING_BOOL =
+            "show_spn_for_home_in_choose_network_setting_bool";
+
+    /**
      * Control whether users receive a simplified network settings UI and improved network
      * selection.
      */
@@ -3593,6 +3621,15 @@
             "carrier_certificate_string_array";
 
     /**
+     * Flag specifying whether the incoming call number should be formatted to national number
+     * for Japan. @return {@code true} convert to the national format, {@code false} otherwise.
+     * e.g. "+819012345678" -> "09012345678"
+     * @hide
+     */
+    public static final String KEY_FORMAT_INCOMING_NUMBER_TO_NATIONAL_FOR_JP_BOOL =
+            "format_incoming_number_to_national_for_jp_bool";
+
+    /**
      * DisconnectCause array to play busy tone. Value should be array of
      * {@link android.telephony.DisconnectCause}.
      */
@@ -3703,6 +3740,8 @@
         sDefaults.putBoolean(KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL, false);
         sDefaults.putBoolean(KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL, false);
         sDefaults.putBoolean(KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL, false);
+        sDefaults.putBoolean(KEY_SHOW_SINGLE_OPERATOR_ROW_IN_CHOOSE_NETWORK_SETTING_BOOL, true);
+        sDefaults.putBoolean(KEY_SHOW_SPN_FOR_HOME_IN_CHOOSE_NETWORK_SETTING_BOOL, false);
         sDefaults.putBoolean(KEY_SIMPLIFIED_NETWORK_SETTINGS_BOOL, false);
         sDefaults.putBoolean(KEY_HIDE_SIM_LOCK_SETTINGS_BOOL, false);
 
@@ -4140,6 +4179,7 @@
         sDefaults.putBoolean(KEY_SUPPORT_WPS_OVER_IMS_BOOL, true);
         sDefaults.putAll(Ims.getDefaults());
         sDefaults.putStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY, null);
+         sDefaults.putBoolean(KEY_FORMAT_INCOMING_NUMBER_TO_NATIONAL_FOR_JP_BOOL, false);
         sDefaults.putIntArray(KEY_DISCONNECT_CAUSE_PLAY_BUSYTONE_INT_ARRAY,
                 new int[] {4 /* BUSY */});
         sDefaults.putBoolean(KEY_PREVENT_CLIR_ACTIVATION_AND_DEACTIVATION_CODE_BOOL, false);
@@ -4398,6 +4438,7 @@
         } catch (RemoteException ex) {
             Rlog.e(TAG, "getDefaultCarrierServicePackageName ICarrierConfigLoader is null"
                     + ex.toString());
+            ex.rethrowAsRuntimeException();
         }
         return "";
     }
diff --git a/telephony/java/android/telephony/ModemActivityInfo.java b/telephony/java/android/telephony/ModemActivityInfo.java
index 2b72ab7..debb119 100644
--- a/telephony/java/android/telephony/ModemActivityInfo.java
+++ b/telephony/java/android/telephony/ModemActivityInfo.java
@@ -234,7 +234,7 @@
     }
 
     /**
-     * Indicate if the ModemActivityInfo is invalid due to modem's invalid reporting.
+     * Indicates if the modem has reported valid {@link ModemActivityInfo}.
      *
      * @return {@code true} if this {@link ModemActivityInfo} record is valid,
      * {@code false} otherwise.
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index e537f66..e7a92e8 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -321,12 +321,9 @@
      * @param data Message data.
      * @param isCdma Indicates weather the type of the SMS is CDMA.
      * @return An SmsMessage representing the message.
-     *
-     * @hide
      */
-    @SystemApi
     @Nullable
-    public static SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[] data, boolean isCdma) {
+    public static SmsMessage createSmsSubmitPdu(@NonNull byte[] data, boolean isCdma) {
         SmsMessageBase wrappedMessage;
 
         if (isCdma) {
@@ -496,7 +493,10 @@
         String newMsgBody = null;
         Resources r = Resources.getSystem();
         if (r.getBoolean(com.android.internal.R.bool.config_sms_force_7bit_encoding)) {
-            newMsgBody = Sms7BitEncodingTranslator.translate(text, isCdma);
+            // 7-bit ASCII table based translation is required only for CDMA single-part SMS since
+            // ENCODING_7BIT_ASCII is used for CDMA single-part SMS and ENCODING_GSM_7BIT_ALPHABET
+            // is used for CDMA multi-part SMS.
+            newMsgBody = Sms7BitEncodingTranslator.translate(text, isCdma && ted.msgCount == 1);
         }
         if (TextUtils.isEmpty(newMsgBody)) {
             newMsgBody = text;
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 2facd5a..54cc244 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -988,11 +988,15 @@
      * individual records themselves. When a change occurs the onSubscriptionsChanged method of
      * the listener will be invoked immediately if there has been a notification. The
      * onSubscriptionChanged method will also be triggered once initially when calling this
-     * function.
+     * function. The callback will be invoked on the looper specified in the listener's constructor.
      *
      * @param listener an instance of {@link OnSubscriptionsChangedListener} with
      *                 onSubscriptionsChanged overridden.
+     *
+     * @deprecated Will get exception if the parameter listener is not initialized with a Looper.
+     * Use {@link #addOnSubscriptionsChangedListener(Executor, OnSubscriptionsChangedListener)}.
      */
+    @Deprecated
     public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
         if (listener == null) return;
         addOnSubscriptionsChangedListener(listener.mExecutor, listener);
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 05ab6bd..5569d30 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -31,7 +31,7 @@
 import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.ims.aidl.IImsRcsController;
 import android.telephony.ims.aidl.IRcsUceControllerCallback;
-import android.telephony.ims.feature.RcsFeature;
+import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
 import android.util.Log;
 
 import java.lang.annotation.Retention;
@@ -185,6 +185,58 @@
     })
     public @interface PublishState {}
 
+    /**
+     * An application can use {@link #registerPublishStateCallback} to register a
+     * {@link PublishStateCallback), which will notify the user when the publish state to the
+     * network changes.
+     * @hide
+     */
+    public static class PublishStateCallback {
+
+        private static class PublishStateBinder extends IRcsUcePublishStateCallback.Stub {
+
+            private final PublishStateCallback mLocalCallback;
+            private Executor mExecutor;
+
+            PublishStateBinder(PublishStateCallback c) {
+                mLocalCallback = c;
+            }
+
+            @Override
+            public void onPublishStateChanged(int publishState) {
+                if (mLocalCallback == null) return;
+
+                long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() -> mLocalCallback.onChanged(publishState));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
+            }
+
+            private void setExecutor(Executor executor) {
+                mExecutor = executor;
+            }
+        }
+
+        private final PublishStateBinder mBinder = new PublishStateBinder(this);
+
+        /**@hide*/
+        public final IRcsUcePublishStateCallback getBinder() {
+            return mBinder;
+        }
+
+        private void setExecutor(Executor executor) {
+            mBinder.setExecutor(executor);
+        }
+
+        /**
+         * Notifies the callback when the publish state has changed.
+         * @param publishState The latest update to the publish state.
+         */
+        public void onChanged(@PublishState int publishState) {
+        }
+    }
 
     /**
      * Provides a one-time callback for the response to a UCE request. After this callback is called
@@ -321,6 +373,8 @@
 
         try {
             return imsRcsController.getUcePublishState(mSubId);
+        } catch (android.os.ServiceSpecificException e) {
+            throw new ImsException(e.getMessage(), e.errorCode);
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling IImsRcsController#getUcePublishState", e);
             throw new ImsException("Remote IMS Service is not available",
@@ -329,6 +383,91 @@
     }
 
     /**
+     * Registers a {@link PublishStateCallback} with the system, which will provide publish state
+     * updates for the subscription specified in {@link ImsManager@getRcsManager(subid)}.
+     * <p>
+     * Use {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to subscription
+     * changed events and call {@link #unregisterPublishStateCallback} to clean up.
+     * <p>
+     * The registered {@link PublishStateCallback} will also receive a callback when it is
+     * registered with the current publish state.
+     *
+     * @param executor The executor the listener callback events should be run on.
+     * @param c The {@link PublishStateCallback} to be added.
+     * @throws ImsException if the subscription associated with this callback is valid, but
+     * the {@link ImsService} associated with the subscription is not available. This can happen if
+     * the service crashed, for example. See {@link ImsException#getCode()} for a more detailed
+     * reason.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public void registerPublishStateCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull PublishStateCallback c) throws ImsException {
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null PublishStateCallback.");
+        }
+        if (executor == null) {
+            throw new IllegalArgumentException("Must include a non-null Executor.");
+        }
+
+        IImsRcsController imsRcsController = getIImsRcsController();
+        if (imsRcsController == null) {
+            Log.e(TAG, "registerPublishStateCallback : IImsRcsController is null");
+            throw new ImsException("Cannot find remote IMS service",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+
+        c.setExecutor(executor);
+        try {
+            imsRcsController.registerUcePublishStateCallback(mSubId, c.getBinder());
+        } catch (android.os.ServiceSpecificException e) {
+            throw new ImsException(e.getMessage(), e.errorCode);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IImsRcsController#registerUcePublishStateCallback", e);
+            throw new ImsException("Remote IMS Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+    }
+
+    /**
+     * Removes an existing {@link PublishStateCallback}.
+     * <p>
+     * When the subscription associated with this callback is removed
+     * (SIM removed, ESIM swap,etc...), this callback will automatically be removed. If this method
+     * is called for an inactive subscription, it will result in a no-op.
+     *
+     * @param c The callback to be unregistered.
+     * @throws ImsException if the subscription associated with this callback is valid, but
+     * the {@link ImsService} associated with the subscription is not available. This can happen if
+     * the service crashed, for example. See {@link ImsException#getCode()} for a more detailed
+     * reason.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public void unregisterPublishStateCallback(@NonNull PublishStateCallback c)
+            throws ImsException {
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null PublishStateCallback.");
+        }
+        IImsRcsController imsRcsController = getIImsRcsController();
+        if (imsRcsController == null) {
+            Log.e(TAG, "unregisterPublishStateCallback: IImsRcsController is null");
+            throw new ImsException("Cannot find remote IMS service",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+
+        try {
+            imsRcsController.unregisterUcePublishStateCallback(mSubId, c.getBinder());
+        } catch (android.os.ServiceSpecificException e) {
+            throw new ImsException(e.getMessage(), e.errorCode);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IImsRcsController#unregisterUcePublishStateCallback", e);
+            throw new ImsException("Remote IMS Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+    }
+
+    /**
      * The user’s setting for whether or not User Capability Exchange (UCE) is enabled for the
      * associated subscription.
      * <p>
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
index 483c66e..9e46142 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
@@ -19,6 +19,7 @@
 import android.net.Uri;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IRcsUceControllerCallback;
+import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
 import android.telephony.ims.aidl.IImsRegistrationCallback;
 
 import com.android.internal.telephony.IIntegerConsumer;
@@ -47,4 +48,6 @@
     int getUcePublishState(int subId);
     boolean isUceSettingEnabled(int subId, String callingPackage, String callingFeatureId);
     void setUceSettingEnabled(int subId, boolean isEnabled);
+    void registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c);
+    void unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c);
 }
diff --git a/tools/aapt/tests/TestHelper.h b/telephony/java/android/telephony/ims/aidl/IRcsUcePublishStateCallback.aidl
similarity index 62%
rename from tools/aapt/tests/TestHelper.h
rename to telephony/java/android/telephony/ims/aidl/IRcsUcePublishStateCallback.aidl
index 79174832..b6e8415 100644
--- a/tools/aapt/tests/TestHelper.h
+++ b/telephony/java/android/telephony/ims/aidl/IRcsUcePublishStateCallback.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * 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.
@@ -14,20 +14,13 @@
  * limitations under the License.
  */
 
-#ifndef __TEST_HELPER_H
-#define __TEST_HELPER_H
-
-#include <utils/String8.h>
-
-namespace android {
+package android.telephony.ims.aidl;
 
 /**
- * Stream operator for nicely printing String8's in gtest output.
+ * Interface for RCS UCE publish state change callbacks.
+ *
+ * {@hide}
  */
-inline std::ostream& operator<<(std::ostream& stream, const String8& str) {
-    return stream << str.string();
+oneway interface IRcsUcePublishStateCallback {
+    void onPublishStateChanged(int publishState);
 }
-
-}
-
-#endif
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 6ed0be2..542e08d 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -17,7 +17,7 @@
 package com.android.internal.telephony.cdma;
 
 import android.compat.annotation.UnsupportedAppUsage;
-import android.content.res.Resources;
+import android.os.Build;
 import android.sysprop.TelephonyProperties;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.SmsCbLocation;
@@ -27,7 +27,6 @@
 import android.util.Log;
 
 import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
-import com.android.internal.telephony.Sms7BitEncodingTranslator;
 import com.android.internal.telephony.SmsAddress;
 import com.android.internal.telephony.SmsConstants;
 import com.android.internal.telephony.SmsHeader;
@@ -156,7 +155,8 @@
      *
      * @hide
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
+            + "android.telephony.SmsMessage} API instead")
     public static SmsMessage createFromEfRecord(int index, byte[] data) {
         try {
             SmsMessage msg = new SmsMessage();
@@ -414,15 +414,7 @@
     @UnsupportedAppUsage
     public static TextEncodingDetails calculateLength(CharSequence messageBody,
             boolean use7bitOnly, boolean isEntireMsg) {
-        CharSequence newMsgBody = null;
-        Resources r = Resources.getSystem();
-        if (r.getBoolean(com.android.internal.R.bool.config_sms_force_7bit_encoding)) {
-            newMsgBody = Sms7BitEncodingTranslator.translate(messageBody, true /* isCdmaFormat */);
-        }
-        if (TextUtils.isEmpty(newMsgBody)) {
-            newMsgBody = messageBody;
-        }
-        return BearerData.calcTextEncodingDetails(newMsgBody, use7bitOnly, isEntireMsg);
+        return BearerData.calcTextEncodingDetails(messageBody, use7bitOnly, isEntireMsg);
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
index c074e6e..4fbafb7 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -21,9 +21,11 @@
 import android.telephony.SmsCbCmasInfo;
 import android.telephony.cdma.CdmaSmsCbProgramData;
 import android.telephony.cdma.CdmaSmsCbProgramResults;
+import android.text.TextUtils;
 
 import com.android.internal.telephony.GsmAlphabet;
 import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
+import com.android.internal.telephony.Sms7BitEncodingTranslator;
 import com.android.internal.telephony.SmsConstants;
 import com.android.internal.telephony.SmsHeader;
 import com.android.internal.telephony.SmsMessageBase;
@@ -540,8 +542,17 @@
      */
     public static TextEncodingDetails calcTextEncodingDetails(CharSequence msg,
             boolean force7BitEncoding, boolean isEntireMsg) {
+        CharSequence newMsg = null;
+        Resources r = Resources.getSystem();
+        if (r.getBoolean(com.android.internal.R.bool.config_sms_force_7bit_encoding)) {
+            newMsg = Sms7BitEncodingTranslator.translate(msg, true /* isCdmaFormat */);
+        }
+        if (TextUtils.isEmpty(newMsg)) {
+            newMsg = msg;
+        }
+
         TextEncodingDetails ted;
-        int septets = countAsciiSeptets(msg, force7BitEncoding);
+        int septets = countAsciiSeptets(newMsg, force7BitEncoding);
         if (septets != -1 && septets <= SmsConstants.MAX_USER_DATA_SEPTETS) {
             ted = new TextEncodingDetails();
             ted.msgCount = 1;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 08580012..ccb1474 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -27,6 +27,7 @@
 
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.res.Resources;
+import android.os.Build;
 import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
 
@@ -178,7 +179,8 @@
      *
      * @hide
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
+            + "android.telephony.SmsMessage} API instead")
     public static SmsMessage createFromEfRecord(int index, byte[] data) {
         try {
             SmsMessage msg = new SmsMessage();
diff --git a/tests/FlickerTests/AndroidTest.xml b/tests/FlickerTests/AndroidTest.xml
index d1da47f..a331ec5 100644
--- a/tests/FlickerTests/AndroidTest.xml
+++ b/tests/FlickerTests/AndroidTest.xml
@@ -9,6 +9,14 @@
         <option name="screen-always-on" value="on" />
         <!-- prevents the phone from restarting -->
         <option name="force-skip-system-props" value="true" />
+        <!-- set WM tracing verbose level to all -->
+        <option name="run-command" value="adb shell cmd window tracing level all" />
+        <!-- inform WM to log all transactions -->
+        <option name="run-command" value="adb shell cmd window tracing transaction" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.DeviceCleaner">
+        <!-- keeps the screen on during tests -->
+        <option name="cleanup-action" value="REBOOT" />
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true"/>
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
index 5a66e80..ad64840 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
@@ -144,6 +144,19 @@
         );
     }
 
+    @Test
+    public void checkVisibility_screenshotLayerBecomesInvisible() {
+        checkResults(result -> LayersTraceSubject.assertThat(result)
+                .showsLayer(mTestApp.getPackage())
+                .then()
+                .replaceVisibleLayer(mTestApp.getPackage(), "Screenshot")
+                .then()
+                .showsLayer(mTestApp.getPackage()).and().showsLayer("Screenshot")
+                .then()
+                .replaceVisibleLayer("Screenshot", mTestApp.getPackage())
+                .forAllEntries());
+    }
+
     @FlakyTest(bugId = 140855415)
     @Ignore("Waiting bug feedback")
     @Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
index e033d0a..0201a95 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
@@ -20,7 +20,6 @@
 import static android.view.Surface.rotationToString;
 
 import static com.android.server.wm.flicker.helpers.AutomationUtils.clearRecents;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.closePipWindow;
 import static com.android.server.wm.flicker.helpers.AutomationUtils.exitSplitScreen;
 import static com.android.server.wm.flicker.helpers.AutomationUtils.expandPipWindow;
 import static com.android.server.wm.flicker.helpers.AutomationUtils.launchSplitScreen;
@@ -176,11 +175,15 @@
                 .repeat(ITERATIONS);
     }
 
-    static TransitionBuilder appToSplitScreen(IAppHelper testApp, UiDevice device) {
+    static TransitionBuilder appToSplitScreen(IAppHelper testApp, UiDevice device,
+            int beginRotation) {
+        final String testTag = "appToSplitScreen_" + testApp.getLauncherName() + "_"
+                + rotationToString(beginRotation);
         return TransitionRunner.newBuilder()
-                .withTag("appToSplitScreen_" + testApp.getLauncherName())
+                .withTag(testTag)
                 .recordAllRuns()
                 .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
+                .runBeforeAll(() -> setRotation(device, beginRotation))
                 .runBefore(testApp::open)
                 .runBefore(device::waitForIdle)
                 .runBefore(() -> sleep(500))
@@ -285,41 +288,52 @@
                 .repeat(ITERATIONS);
     }
 
-    static TransitionBuilder enterPipMode(PipAppHelper testApp, UiDevice device) {
+    static TransitionBuilder enterPipMode(PipAppHelper testApp, UiDevice device,
+            int beginRotation) {
         return TransitionRunner.newBuilder()
-                .withTag("enterPipMode_" + testApp.getLauncherName())
+                .withTag("enterPipMode_" + testApp.getLauncherName()
+                        + rotationToString(beginRotation))
                 .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
                 .runBefore(device::pressHome)
+                .runBefore(() -> setRotation(device, beginRotation))
                 .runBefore(testApp::open)
                 .run(() -> testApp.clickEnterPipButton(device))
-                .runAfter(() -> closePipWindow(device))
+                .runAfter(() -> testApp.closePipWindow(device))
                 .runAfterAll(testApp::exit)
                 .repeat(ITERATIONS);
     }
 
-    static TransitionBuilder exitPipModeToHome(PipAppHelper testApp, UiDevice device) {
+    static TransitionBuilder exitPipModeToHome(PipAppHelper testApp, UiDevice device,
+            int beginRotation) {
         return TransitionRunner.newBuilder()
-                .withTag("exitPipModeToHome_" + testApp.getLauncherName())
+                .withTag("exitPipModeToHome_" + testApp.getLauncherName()
+                        + rotationToString(beginRotation))
+                .recordAllRuns()
                 .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
                 .runBefore(device::pressHome)
+                .runBefore(() -> setRotation(device, beginRotation))
                 .runBefore(testApp::open)
-                .runBefore(() -> testApp.clickEnterPipButton(device))
-                .run(() -> closePipWindow(device))
+                .run(() -> testApp.clickEnterPipButton(device))
+                .run(() -> testApp.closePipWindow(device))
                 .run(device::waitForIdle)
-                .runAfterAll(testApp::exit)
+                .run(testApp::exit)
                 .repeat(ITERATIONS);
     }
 
-    static TransitionBuilder exitPipModeToApp(PipAppHelper testApp, UiDevice device) {
+    static TransitionBuilder exitPipModeToApp(PipAppHelper testApp, UiDevice device,
+            int beginRotation) {
         return TransitionRunner.newBuilder()
-                .withTag("exitPipModeToApp_" + testApp.getLauncherName())
+                .withTag("exitPipModeToApp_" + testApp.getLauncherName()
+                        + rotationToString(beginRotation))
+                .recordAllRuns()
                 .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBefore(device::pressHome)
-                .runBefore(testApp::open)
-                .runBefore(() -> testApp.clickEnterPipButton(device))
+                .run(device::pressHome)
+                .run(() -> setRotation(device, beginRotation))
+                .run(testApp::open)
+                .run(() -> testApp.clickEnterPipButton(device))
                 .run(() -> expandPipWindow(device))
                 .run(device::waitForIdle)
-                .runAfterAll(testApp::exit)
+                .run(testApp::exit)
                 .repeat(ITERATIONS);
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java
index 8f0177c..666a0b9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java
@@ -94,7 +94,8 @@
      */
     @Test
     public void openAppToSplitScreen() {
-        CommonTransitions.appToSplitScreen(testApp, uiDevice).includeJankyRuns().recordAllRuns()
+        CommonTransitions.appToSplitScreen(testApp, uiDevice,
+                Surface.ROTATION_0).includeJankyRuns().recordAllRuns()
                 .build().run();
     }
 
@@ -116,7 +117,7 @@
         ImeAppHelper bottomApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
         CommonTransitions.resizeSplitScreen(testApp, bottomApp, uiDevice, Surface.ROTATION_0,
                 new Rational(1, 3), new Rational(2, 3))
-                .includeJankyRuns().recordEachRun().build().run();
+                .includeJankyRuns().build().run();
     }
 
     // IME tests
@@ -128,7 +129,7 @@
     public void editTextSetFocus() {
         ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
         CommonTransitions.editTextSetFocus(testApp, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns().recordEachRun()
+                .includeJankyRuns()
                 .build().run();
     }
 
@@ -139,7 +140,7 @@
     public void editTextLoseFocusToHome() {
         ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
         CommonTransitions.editTextLoseFocusToHome(testApp, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns().recordEachRun()
+                .includeJankyRuns()
                 .build().run();
     }
 
@@ -150,7 +151,7 @@
     public void editTextLoseFocusToApp() {
         ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
         CommonTransitions.editTextLoseFocusToHome(testApp, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns().recordEachRun()
+                .includeJankyRuns()
                 .build().run();
     }
 
@@ -162,7 +163,7 @@
     @Test
     public void enterPipMode() {
         PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.enterPipMode(testApp, uiDevice).includeJankyRuns().recordEachRun()
+        CommonTransitions.enterPipMode(testApp, uiDevice, Surface.ROTATION_0).includeJankyRuns()
                 .build().run();
     }
 
@@ -172,7 +173,8 @@
     @Test
     public void exitPipModeToHome() {
         PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.exitPipModeToHome(testApp, uiDevice).includeJankyRuns().recordEachRun()
+        CommonTransitions.exitPipModeToHome(testApp, uiDevice, Surface.ROTATION_0)
+                .includeJankyRuns()
                 .build().run();
     }
 
@@ -182,7 +184,7 @@
     @Test
     public void exitPipModeToApp() {
         PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.exitPipModeToApp(testApp, uiDevice).includeJankyRuns().recordEachRun()
+        CommonTransitions.exitPipModeToApp(testApp, uiDevice, Surface.ROTATION_0).includeJankyRuns()
                 .build().run();
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java
index 883d59e..4578fa3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java
@@ -89,7 +89,7 @@
                         }
                         if (result.screenCaptureVideoExists()) {
                             Log.e(TAG, "Screen capture video saved to " + result
-                                    .screenCaptureVideo.toString());
+                                    .screenCaptureVideoPath().toString());
                         }
                     }
                 });
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java
index efdfaee..2981ff9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java
@@ -19,6 +19,8 @@
 import static com.android.server.wm.flicker.CommonTransitions.openAppCold;
 import static com.android.server.wm.flicker.WmTraceSubject.assertThat;
 
+import android.view.Surface;
+
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.FlakyTest;
 import androidx.test.filters.LargeTest;
@@ -76,10 +78,20 @@
 
     @Test
     public void checkVisibility_wallpaperLayerBecomesInvisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer("Wallpaper")
-                .then()
-                .hidesLayer("Wallpaper")
-                .forAllEntries());
+        if (mBeginRotation == Surface.ROTATION_0) {
+            checkResults(result -> LayersTraceSubject.assertThat(result)
+                    .showsLayer("Wallpaper")
+                    .then()
+                    .replaceVisibleLayer("Wallpaper", mTestApp.getPackage())
+                    .forAllEntries());
+        } else {
+            checkResults(result -> LayersTraceSubject.assertThat(result)
+                    .showsLayer("Wallpaper")
+                    .then()
+                    .replaceVisibleLayer("Wallpaper", "Screenshot")
+                    .then()
+                    .showsLayer(mTestApp.getPackage())
+                    .forAllEntries());
+        }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java
index f8b7938..ddead6d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java
@@ -17,35 +17,38 @@
 package com.android.server.wm.flicker;
 
 import static com.android.server.wm.flicker.CommonTransitions.appToSplitScreen;
-import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
 
 /**
  * Test open app to split screen.
  * To run this test: {@code atest FlickerTests:OpenAppToSplitScreenTest}
  */
 @LargeTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class OpenAppToSplitScreenTest extends FlickerTestBase {
+public class OpenAppToSplitScreenTest extends NonRotationTestBase {
 
-    public OpenAppToSplitScreenTest() {
+    public OpenAppToSplitScreenTest(String beginRotationName, int beginRotation) {
+        super(beginRotationName, beginRotation);
+
         this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
                 "com.android.server.wm.flicker.testapp", "SimpleApp");
     }
 
     @Before
     public void runTransition() {
-        super.runTransition(appToSplitScreen(mTestApp, mUiDevice).includeJankyRuns().build());
+        super.runTransition(appToSplitScreen(mTestApp, mUiDevice, mBeginRotation)
+                .includeJankyRuns()
+                .build());
     }
 
     @Test
@@ -70,25 +73,6 @@
     }
 
     @Test
-    public void checkCoveredRegion_noUncoveredRegions() {
-        checkResults(result ->
-                LayersTraceSubject.assertThat(result)
-                        .coversRegion(getDisplayBounds()).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_navBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_statusBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
     public void checkVisibility_dividerLayerBecomesVisible() {
         checkResults(result -> LayersTraceSubject.assertThat(result)
                 .hidesLayer(DOCKED_STACK_DIVIDER)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java
index 7ce6315..bb684d1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java
@@ -19,6 +19,8 @@
 import static com.android.server.wm.flicker.CommonTransitions.openAppWarm;
 import static com.android.server.wm.flicker.WmTraceSubject.assertThat;
 
+import android.view.Surface;
+
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.FlakyTest;
 import androidx.test.filters.LargeTest;
@@ -76,10 +78,20 @@
 
     @Test
     public void checkVisibility_wallpaperLayerBecomesInvisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer("Wallpaper")
-                .then()
-                .hidesLayer("Wallpaper")
-                .forAllEntries());
+        if (mBeginRotation == Surface.ROTATION_0) {
+            checkResults(result -> LayersTraceSubject.assertThat(result)
+                    .showsLayer("Wallpaper")
+                    .then()
+                    .replaceVisibleLayer("Wallpaper", mTestApp.getPackage())
+                    .forAllEntries());
+        } else {
+            checkResults(result -> LayersTraceSubject.assertThat(result)
+                    .showsLayer("Wallpaper")
+                    .then()
+                    .replaceVisibleLayer("Wallpaper", "Screenshot")
+                    .then()
+                    .showsLayer(mTestApp.getPackage())
+                    .forAllEntries());
+        }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java
new file mode 100644
index 0000000..85706bd
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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 com.android.server.wm.flicker;
+
+import static com.android.server.wm.flicker.CommonTransitions.exitPipModeToApp;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+
+import com.android.server.wm.flicker.helpers.PipAppHelper;
+
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+
+/**
+ * Test Pip launch.
+ * To run this test: {@code atest FlickerTests:PipToAppTest}
+ */
+@LargeTest
+@RunWith(Parameterized.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class PipToAppTest extends NonRotationTestBase {
+
+    static final String sPipWindowTitle = "PipMenuActivity";
+
+    public PipToAppTest(String beginRotationName, int beginRotation) {
+        super(beginRotationName, beginRotation);
+
+        this.mTestApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
+    }
+
+    @Before
+    public void runTransition() {
+        run(exitPipModeToApp((PipAppHelper) mTestApp, mUiDevice, mBeginRotation)
+                .includeJankyRuns().build());
+    }
+
+    @Test
+    public void checkVisibility_pipWindowBecomesVisible() {
+        checkResults(result -> WmTraceSubject.assertThat(result)
+                .skipUntilFirstAssertion()
+                .showsAppWindowOnTop(sPipWindowTitle)
+                .then()
+                .hidesAppWindow(sPipWindowTitle)
+                .forAllEntries());
+    }
+
+    @Test
+    public void checkVisibility_pipLayerBecomesVisible() {
+        checkResults(result -> LayersTraceSubject.assertThat(result)
+                .skipUntilFirstAssertion()
+                .showsLayer(sPipWindowTitle)
+                .then()
+                .hidesLayer(sPipWindowTitle)
+                .forAllEntries());
+    }
+
+    @Test
+    public void checkVisibility_backgroundWindowVisibleBehindPipLayer() {
+        checkResults(result -> WmTraceSubject.assertThat(result)
+                .skipUntilFirstAssertion()
+                .showsAppWindowOnTop(sPipWindowTitle)
+                .then()
+                .showsBelowAppWindow("Wallpaper")
+                .then()
+                .showsAppWindowOnTop(mTestApp.getPackage())
+                .then()
+                .hidesAppWindowOnTop(mTestApp.getPackage())
+                .forAllEntries());
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java
new file mode 100644
index 0000000..ef856dc
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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 com.android.server.wm.flicker;
+
+import static com.android.server.wm.flicker.CommonTransitions.exitPipModeToHome;
+
+import android.view.Surface;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.wm.flicker.helpers.PipAppHelper;
+
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+
+/**
+ * Test Pip launch.
+ * To run this test: {@code atest FlickerTests:PipToHomeTest}
+ */
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class PipToHomeTest extends FlickerTestBase {
+
+    static final String sPipWindowTitle = "PipActivity";
+
+    // public PipToHomeTest(String beginRotationName, int beginRotation) {
+    public PipToHomeTest() {
+        // super(beginRotationName, beginRotation);
+
+        this.mTestApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
+    }
+
+    @Before
+    public void runTransition() {
+        // run(exitPipModeToHome((PipAppHelper) mTestApp, mUiDevice, mBeginRotation)
+        run(exitPipModeToHome((PipAppHelper) mTestApp, mUiDevice, Surface.ROTATION_0)
+                .includeJankyRuns().build());
+    }
+
+    @Ignore
+    @Test
+    public void checkVisibility_pipWindowBecomesVisible() {
+        checkResults(result -> WmTraceSubject.assertThat(result)
+                .skipUntilFirstAssertion()
+                .showsAppWindowOnTop(sPipWindowTitle)
+                .then()
+                .hidesAppWindow(sPipWindowTitle)
+                .forAllEntries());
+    }
+
+    @Test
+    public void checkVisibility_pipLayerBecomesVisible() {
+        checkResults(result -> LayersTraceSubject.assertThat(result)
+                .skipUntilFirstAssertion()
+                .showsLayer(sPipWindowTitle)
+                .then()
+                .hidesLayer(sPipWindowTitle)
+                .forAllEntries());
+    }
+
+    @Ignore
+    @Test
+    public void checkVisibility_backgroundWindowVisibleBehindPipLayer() {
+        checkResults(result -> WmTraceSubject.assertThat(result)
+                .showsAppWindowOnTop(sPipWindowTitle)
+                .then()
+                .showsBelowAppWindow("Wallpaper")
+                .then()
+                .showsAppWindowOnTop("Wallpaper")
+                .forAllEntries());
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java
index 29b6240..e36701b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java
@@ -95,7 +95,7 @@
         Rect displayBounds = getDisplayBounds();
         checkResults(result -> {
             LayersTrace entries = LayersTrace.parseFrom(result.getLayersTrace(),
-                    result.getLayersTracePath());
+                    result.getLayersTracePath(), result.getLayersTraceChecksum());
 
             assertThat(entries.getEntries()).isNotEmpty();
             Rect startingDividerBounds = entries.getEntries().get(0).getVisibleBounds
@@ -124,7 +124,7 @@
         Rect displayBounds = getDisplayBounds();
         checkResults(result -> {
             LayersTrace entries = LayersTrace.parseFrom(result.getLayersTrace(),
-                    result.getLayersTracePath());
+                    result.getLayersTracePath(), result.getLayersTraceChecksum());
 
             assertThat(entries.getEntries()).isNotEmpty();
             Rect endingDividerBounds = entries.getEntries().get(
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java
index d00e11b..d5f9a20 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java
@@ -40,4 +40,8 @@
         }
     }
 
+    public void closePipWindow(UiDevice device) {
+        AutomationUtils.closePipWindow(device);
+    }
+
 }
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) {
diff --git a/tools/aapt/tests/AaptConfig_test.cpp b/tools/aapt/tests/AaptConfig_test.cpp
index 4f22fa5..b7c6bd2 100644
--- a/tools/aapt/tests/AaptConfig_test.cpp
+++ b/tools/aapt/tests/AaptConfig_test.cpp
@@ -20,7 +20,6 @@
 #include "AaptConfig.h"
 #include "ConfigDescription.h"
 #include "SdkConstants.h"
-#include "TestHelper.h"
 
 using android::String8;
 
@@ -127,4 +126,4 @@
               config.colorMode & android::ResTable_config::MASK_HDR);
     EXPECT_EQ(SDK_O, config.sdkVersion);
     EXPECT_EQ(String8("lowdr-v26"), config.toString());
-}
\ No newline at end of file
+}
diff --git a/tools/aapt/tests/AaptGroupEntry_test.cpp b/tools/aapt/tests/AaptGroupEntry_test.cpp
index 7348a08..bf5ca59 100644
--- a/tools/aapt/tests/AaptGroupEntry_test.cpp
+++ b/tools/aapt/tests/AaptGroupEntry_test.cpp
@@ -19,7 +19,6 @@
 
 #include "AaptAssets.h"
 #include "ResourceFilter.h"
-#include "TestHelper.h"
 
 using android::String8;
 
diff --git a/tools/aapt/tests/ResourceTable_test.cpp b/tools/aapt/tests/ResourceTable_test.cpp
index f2c696b..0d550df 100644
--- a/tools/aapt/tests/ResourceTable_test.cpp
+++ b/tools/aapt/tests/ResourceTable_test.cpp
@@ -19,7 +19,6 @@
 
 #include "ConfigDescription.h"
 #include "ResourceTable.h"
-#include "TestHelper.h"
 
 using android::String16;
 
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 234cbc4..931a14b 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -449,6 +449,7 @@
     ParsedResource parsed_resource;
     parsed_resource.config = config_;
     parsed_resource.source = source_.WithLine(parser->line_number());
+    // NOLINTNEXTLINE(bugprone-use-after-move) move+reset comment
     parsed_resource.comment = std::move(comment);
     if (options_.visibility) {
       parsed_resource.visibility_level = options_.visibility.value();
@@ -979,6 +980,7 @@
       child_resource.name.type = *parsed_type;
       child_resource.name.entry = maybe_name.value().to_string();
       child_resource.id = next_id;
+      // NOLINTNEXTLINE(bugprone-use-after-move) move+reset comment
       child_resource.comment = std::move(comment);
       child_resource.source = item_source;
       child_resource.visibility_level = Visibility::Level::kPublic;
@@ -1698,6 +1700,7 @@
       ParsedResource child_resource;
       child_resource.name = child_ref.name.value();
       child_resource.source = item_source;
+      // NOLINTNEXTLINE(bugprone-use-after-move) move+reset comment
       child_resource.comment = std::move(comment);
       if (options_.visibility) {
         child_resource.visibility_level = options_.visibility.value();
diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp
index 0db1807..d9a4caa 100644
--- a/tools/aapt2/java/ProguardRules.cpp
+++ b/tools/aapt2/java/ProguardRules.cpp
@@ -115,15 +115,10 @@
 
   void Visit(xml::Element* node) override {
     bool is_view = false;
-    bool is_fragment = false;
     if (node->namespace_uri.empty()) {
       if (node->name == "view") {
         is_view = true;
-      } else if (node->name == "fragment") {
-        is_fragment = true;
       }
-    } else if (node->namespace_uri == xml::kSchemaAndroid) {
-      is_fragment = node->name == "fragment";
     }
 
     for (const auto& attr : node->attributes) {
@@ -132,12 +127,12 @@
           if (is_view) {
             AddClass(node->line_number, attr.value,
                 "android.content.Context, android.util.AttributeSet");
-          } else if (is_fragment) {
+          } else {
             AddClass(node->line_number, attr.value, "");
           }
         }
       } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "name") {
-        if (is_fragment && util::IsJavaClassName(attr.value)) {
+        if (util::IsJavaClassName(attr.value)) {
           AddClass(node->line_number, attr.value, "");
         }
       } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "onClick") {
diff --git a/tools/aapt2/java/ProguardRules_test.cpp b/tools/aapt2/java/ProguardRules_test.cpp
index b6e7602..c7ae0b6 100644
--- a/tools/aapt2/java/ProguardRules_test.cpp
+++ b/tools/aapt2/java/ProguardRules_test.cpp
@@ -131,6 +131,61 @@
   EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(); }"));
 }
 
+TEST(ProguardRulesTest, FragmentContainerViewNameRuleIsEmitted) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"(
+      <androidx.fragment.app.FragmentContainerView
+          xmlns:android="http://schemas.android.com/apk/res/android"
+          android:name="com.foo.Bar"/>)");
+  layout->file.name = test::ParseNameOrDie("layout/foo");
+
+  proguard::KeepSet set;
+  ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set));
+
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
+
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }"));
+}
+
+TEST(ProguardRulesTest, FragmentContainerViewClassRuleIsEmitted) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> layout =
+      test::BuildXmlDom(R"(<androidx.fragment.app.FragmentContainerView class="com.foo.Bar"/>)");
+  layout->file.name = test::ParseNameOrDie("layout/foo");
+
+  proguard::KeepSet set;
+  ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set));
+
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
+
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }"));
+}
+
+TEST(ProguardRulesTest, FragmentContainerViewNameAndClassRulesAreEmitted) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"(
+      <androidx.fragment.app.FragmentContainerView
+          xmlns:android="http://schemas.android.com/apk/res/android"
+          android:name="com.foo.Baz"
+          class="com.foo.Bar"/>)");
+  layout->file.name = test::ParseNameOrDie("layout/foo");
+
+  proguard::KeepSet set;
+  ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set));
+
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(...); }"));
+
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(); }"));
+}
+
 TEST(ProguardRulesTest, NavigationFragmentNameAndClassRulesAreEmitted) {
   std::unique_ptr<IAaptContext> context = test::ContextBuilder()
       .SetCompilationPackage("com.base").Build();
diff --git a/tools/aapt2/util/BigBuffer_test.cpp b/tools/aapt2/util/BigBuffer_test.cpp
index a7776e3..64dcc1d 100644
--- a/tools/aapt2/util/BigBuffer_test.cpp
+++ b/tools/aapt2/util/BigBuffer_test.cpp
@@ -62,7 +62,7 @@
     *b1 = 44;
 
     buffer.AppendBuffer(std::move(buffer2));
-    EXPECT_EQ(0u, buffer2.size());
+    EXPECT_EQ(0u, buffer2.size()); // NOLINT
     EXPECT_EQ(buffer2.begin(), buffer2.end());
   }
 
diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp
index 9a725fa..005eeb9 100644
--- a/tools/aapt2/xml/XmlDom.cpp
+++ b/tools/aapt2/xml/XmlDom.cpp
@@ -305,6 +305,8 @@
         if (pending_element == nullptr) {
           pending_element = util::make_unique<Element>();
         }
+        // pending_element is not nullptr
+        // NOLINTNEXTLINE(bugprone-use-after-move)
         pending_element->namespace_decls.push_back(std::move(decl));
         break;
       }
diff --git a/tools/fonts/fontchain_linter.py b/tools/fonts/fontchain_linter.py
index 6683e2a..a4a315b 100755
--- a/tools/fonts/fontchain_linter.py
+++ b/tools/fonts/fontchain_linter.py
@@ -286,7 +286,7 @@
 
             if not fallback_for:
                 if not name or name == 'sans-serif':
-                    for _, fallback in _fallback_chains.iteritems():
+                    for _, fallback in _fallback_chains.items():
                         fallback.append(record)
                 else:
                     _fallback_chains[name].append(record)
@@ -327,7 +327,7 @@
         assert sequence in all_emoji, (
             'Emoji font should not support %s.' % printable(sequence))
 
-    for first, second in sorted(equivalent_emoji.items()):
+    for first, second in equivalent_emoji.items():
         assert coverage[first] == coverage[second], (
             '%s and %s should map to the same glyph.' % (
                 printable(first),
@@ -352,7 +352,7 @@
 
 def check_emoji_defaults(default_emoji):
     missing_text_chars = _emoji_properties['Emoji'] - default_emoji
-    for name, fallback_chain in _fallback_chains.iteritems():
+    for name, fallback_chain in _fallback_chains.items():
         emoji_font_seen = False
         for record in fallback_chain:
             if 'Zsye' in record.scripts:
@@ -369,7 +369,7 @@
                 continue
 
             # Check default emoji-style characters
-            assert_font_supports_none_of_chars(record.font, sorted(default_emoji), name)
+            assert_font_supports_none_of_chars(record.font, default_emoji, name)
 
             # Mark default text-style characters appearing in fonts above the emoji
             # font as seen
@@ -412,7 +412,7 @@
                 char_start, char_end = chars.split('..')
                 char_start = int(char_start, 16)
                 char_end = int(char_end, 16)
-                additions = xrange(char_start, char_end+1)
+                additions = range(char_start, char_end+1)
             else:  # singe character
                 additions = [int(chars, 16)]
             if reverse:
@@ -478,7 +478,7 @@
     # Unicode 12.0 adds Basic_Emoji in emoji-sequences.txt. We ignore them here since we are already
     # checking the emoji presentations with emoji-variation-sequences.txt.
     # Please refer to http://unicode.org/reports/tr51/#def_basic_emoji_set .
-    _emoji_sequences = {k: v for k, v in _emoji_sequences.iteritems() if not v == 'Basic_Emoji' }
+    _emoji_sequences = {k: v for k, v in _emoji_sequences.items() if not v == 'Basic_Emoji' }
 
 
 def remove_emoji_variation_exclude(source, items):
@@ -551,7 +551,7 @@
     rev = list(reversed(seq))
     # if there are fitzpatrick modifiers in the sequence, keep them after
     # the emoji they modify
-    for i in xrange(1, len(rev)):
+    for i in range(1, len(rev)):
         if is_fitzpatrick_modifier(rev[i-1]):
             rev[i], rev[i-1] = rev[i-1], rev[i]
     return tuple(rev)
@@ -620,7 +620,7 @@
 
 
 def check_compact_only_fallback():
-    for name, fallback_chain in _fallback_chains.iteritems():
+    for name, fallback_chain in _fallback_chains.items():
         for record in fallback_chain:
             if record.variant == 'compact':
                 same_script_elegants = [x for x in fallback_chain
@@ -650,7 +650,7 @@
 def check_cjk_punctuation():
     cjk_scripts = {'Hans', 'Hant', 'Jpan', 'Kore'}
     cjk_punctuation = range(0x3000, 0x301F + 1)
-    for name, fallback_chain in _fallback_chains.iteritems():
+    for name, fallback_chain in _fallback_chains.items():
         for record in fallback_chain:
             if record.scripts.intersection(cjk_scripts):
                 # CJK font seen. Stop checking the rest of the fonts.