Merge "Add 'ss' trace category in app launch test."
diff --git a/Android.bp b/Android.bp
index add6117..25eb2bd 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1107,6 +1107,25 @@
     ],
 }
 
+droiddoc {
+    name: "hiddenapi-lists",
+    defaults: ["framework-docs-default"],
+    arg_files: [
+        "core/res/AndroidManifest.xml",
+        ":api-version-xml",
+        "core/java/overview.html",
+        ":current-support-api",
+    ],
+    private_dex_api_filename: "private-dex.txt",
+    removed_dex_api_filename: "removed-dex.txt",
+    args: framework_docs_args +
+          " -referenceonly" +
+          " -nodocs" +
+          " -showUnannotated" +
+          " -showAnnotation android.annotation.SystemApi" +
+          " -showAnnotation android.annotation.TestApi",
+}
+
 filegroup {
     name: "apache-http-stubs-sources",
     srcs: [
diff --git a/Android.mk b/Android.mk
index 5a2e79d..360ce75 100644
--- a/Android.mk
+++ b/Android.mk
@@ -309,38 +309,6 @@
 $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_SYSTEM_API_FILE))
 $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_TEST_API_FILE))
 
-# ====  the complete hidden api list ===================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=$(framework_docs_LOCAL_API_CHECK_SRC_FILES)
-LOCAL_GENERATED_SOURCES:=$(framework_docs_LOCAL_GENERATED_SOURCES)
-LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS)
-LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES)
-LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
-LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
-LOCAL_DROIDDOC_HTML_DIR:=$(framework_docs_LOCAL_DROIDDOC_HTML_DIR)
-LOCAL_ADDITIONAL_JAVA_DIR:=$(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR)
-LOCAL_ADDITIONAL_DEPENDENCIES:=$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES)
-
-LOCAL_MODULE := hidden-api-list
-
-LOCAL_DROIDDOC_OPTIONS:=\
-		$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
-		-referenceonly \
-		-showUnannotated \
-		-showAnnotation android.annotation.SystemApi \
-		-showAnnotation android.annotation.TestApi \
-		-privateDexApi $(INTERNAL_PLATFORM_PRIVATE_DEX_API_FILE) \
-		-nodocs
-
-LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=external/doclava/res/assets/templates-sdk
-
-LOCAL_UNINSTALLABLE_MODULE := true
-
-include $(BUILD_DROIDDOC)
-
-$(full_target): .KATI_IMPLICIT_OUTPUTS := $(INTERNAL_PLATFORM_PRIVATE_DEX_API_FILE)
-
 # ====  check javadoc comments but don't generate docs ========
 include $(CLEAR_VARS)
 
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 8a47f2d..1f8ab21 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -12,3 +12,5 @@
 api_lint_hook = ${REPO_ROOT}/frameworks/base/tools/apilint/apilint_sha.sh ${PREUPLOAD_COMMIT}
 
 strings_lint_hook = ${REPO_ROOT}/frameworks/base/tools/stringslint/stringslint_sha.sh ${PREUPLOAD_COMMIT}
+
+hidden_api_txt_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
diff --git a/api/current.txt b/api/current.txt
index 1bf03d5..cbff777 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -32755,6 +32755,7 @@
     method public java.util.ArrayList readArrayList(java.lang.ClassLoader);
     method public void readBinderArray(android.os.IBinder[]);
     method public void readBinderList(java.util.List<android.os.IBinder>);
+    method public boolean readBoolean();
     method public void readBooleanArray(boolean[]);
     method public android.os.Bundle readBundle();
     method public android.os.Bundle readBundle(java.lang.ClassLoader);
@@ -32800,6 +32801,7 @@
     method public void writeArray(java.lang.Object[]);
     method public void writeBinderArray(android.os.IBinder[]);
     method public void writeBinderList(java.util.List<android.os.IBinder>);
+    method public void writeBoolean(boolean);
     method public void writeBooleanArray(boolean[]);
     method public void writeBundle(android.os.Bundle);
     method public void writeByte(byte);
diff --git a/api/removed.txt b/api/removed.txt
index 3649ab2..b6dabcd 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -326,14 +326,6 @@
   public static abstract class NetworkBadging.Badging implements java.lang.annotation.Annotation {
   }
 
-  public class NetworkRequest implements android.os.Parcelable {
-    method public boolean hasUnwantedCapability(int);
-  }
-
-  public static class NetworkRequest.Builder {
-    method public android.net.NetworkRequest.Builder addUnwantedCapability(int);
-  }
-
   public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
     method public static deprecated org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, android.net.SSLSessionCache);
   }
diff --git a/api/test-current.txt b/api/test-current.txt
index 12adde5..61b4a75 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1,10 +1,13 @@
 package android {
 
   public static final class Manifest.permission {
+    field public static final java.lang.String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS";
     field public static final java.lang.String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING";
     field public static final java.lang.String BRIGHTNESS_SLIDER_USAGE = "android.permission.BRIGHTNESS_SLIDER_USAGE";
+    field public static final java.lang.String CHANGE_APP_IDLE_STATE = "android.permission.CHANGE_APP_IDLE_STATE";
     field public static final java.lang.String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS";
     field public static final java.lang.String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS";
+    field public static final java.lang.String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS";
   }
 
 }
@@ -61,9 +64,12 @@
   public class AppOpsManager {
     method public static java.lang.String[] getOpStrs();
     method public boolean isOperationActive(int, int, java.lang.String);
+    method public static java.lang.String opToPermission(int);
+    method public static int permissionToOpCode(java.lang.String);
     method public void setMode(int, int, java.lang.String, int);
     method public void startWatchingActive(int[], android.app.AppOpsManager.OnOpActiveChangedListener);
     method public void stopWatchingActive(android.app.AppOpsManager.OnOpActiveChangedListener);
+    method public static int strOpToOp(java.lang.String);
     field public static final java.lang.String OPSTR_ACCEPT_HANDOVER = "android:accept_handover";
     field public static final java.lang.String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
     field public static final java.lang.String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
@@ -109,6 +115,7 @@
     field public static final java.lang.String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
     field public static final int OP_RECORD_AUDIO = 27; // 0x1b
     field public static final int OP_SYSTEM_ALERT_WINDOW = 24; // 0x18
+    field public static final int _NUM_OP = 77; // 0x4d
   }
 
   public static abstract interface AppOpsManager.OnOpActiveChangedListener {
@@ -222,11 +229,16 @@
   }
 
   public abstract class Context {
+    method public abstract java.lang.String getOpPackageName();
     method public android.os.UserHandle getUser();
     method public int getUserId();
     method public void setAutofillCompatibilityEnabled(boolean);
   }
 
+  public class ContextWrapper extends android.content.Context {
+    method public java.lang.String getOpPackageName();
+  }
+
 }
 
 package android.content.pm {
@@ -471,6 +483,10 @@
     method public void setType(int);
   }
 
+  public class Location implements android.os.Parcelable {
+    method public void makeComplete();
+  }
+
   public class LocationManager {
     method public java.lang.String[] getBackgroundThrottlingWhitelist();
   }
@@ -667,6 +683,7 @@
   public final class UserHandle implements android.os.Parcelable {
     method public static int getAppId(int);
     method public int getIdentifier();
+    method public static boolean isApp(int);
     field public static final android.os.UserHandle SYSTEM;
   }
 
@@ -737,6 +754,14 @@
 
 package android.provider {
 
+  public static final class ContactsContract.CommonDataKinds.Phone implements android.provider.ContactsContract.CommonDataKinds.CommonColumns android.provider.ContactsContract.DataColumnsWithJoins {
+    field public static final android.net.Uri ENTERPRISE_CONTENT_URI;
+  }
+
+  public static final class ContactsContract.RawContactsEntity implements android.provider.BaseColumns android.provider.ContactsContract.DataColumns android.provider.ContactsContract.RawContactsColumns {
+    field public static final android.net.Uri CORP_CONTENT_URI;
+  }
+
   public final class Settings {
     field public static final java.lang.String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS";
   }
@@ -962,12 +987,7 @@
 
   public class TelephonyManager {
     method public int getCarrierIdListVersion();
-    method public void setCarrierTestOverride(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
-    field public static final int UNKNOWN_CARRIER_ID_LIST_VERSION = -1; // 0xffffffff
-  }
-
-  public class TelephonyManager {
-    method public int getCarrierIdListVersion();
+    method public void refreshUiccProfile();
     method public void setCarrierTestOverride(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
     field public static final int UNKNOWN_CARRIER_ID_LIST_VERSION = -1; // 0xffffffff
   }
@@ -1259,6 +1279,10 @@
     method public void enable();
   }
 
+  public class KeyEvent extends android.view.InputEvent implements android.os.Parcelable {
+    method public static java.lang.String actionToString(int);
+  }
+
   public final class KeyboardShortcutGroup implements android.os.Parcelable {
     ctor public KeyboardShortcutGroup(java.lang.CharSequence, java.util.List<android.view.KeyboardShortcutInfo>, boolean);
     ctor public KeyboardShortcutGroup(java.lang.CharSequence, boolean);
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index e5d35b3..a7349ee 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -94,3 +94,5 @@
 endif
 
 include ${BUILD_SHARED_LIBRARY}
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/cmds/bootanimation/iot/Android.mk b/cmds/bootanimation/iot/Android.mk
new file mode 100644
index 0000000..8f5cfb37
--- /dev/null
+++ b/cmds/bootanimation/iot/Android.mk
@@ -0,0 +1,38 @@
+# 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(PRODUCT_IOT),true)
+
+# libbootanimation_iot_test
+# ===========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libbootanimation_iot_test
+LOCAL_CFLAGS := -Wall -Werror -Wunused -Wunreachable-code
+
+LOCAL_SHARED_LIBRARIES := \
+    libandroidthings \
+    libbase \
+    libchrome \
+    liblog \
+
+LOCAL_SRC_FILES := \
+    BootParameters.cpp \
+    BootParameters_test.cpp \
+
+include $(BUILD_NATIVE_TEST)
+
+endif # PRODUCT_IOT
diff --git a/cmds/bootanimation/iot/BootParameters.cpp b/cmds/bootanimation/iot/BootParameters.cpp
index da6ad0d..06cdbf8 100644
--- a/cmds/bootanimation/iot/BootParameters.cpp
+++ b/cmds/bootanimation/iot/BootParameters.cpp
@@ -20,8 +20,6 @@
 
 #include <fcntl.h>
 
-#include <string>
-
 #include <android-base/file.h>
 #include <base/json/json_parser.h>
 #include <base/json/json_reader.h>
@@ -98,7 +96,11 @@
         return;
     }
 
-    std::unique_ptr<Value> json = JSONReader::Read(contents);
+    loadParameters(contents);
+}
+
+void BootParameters::loadParameters(const std::string& raw_json) {
+    std::unique_ptr<Value> json = JSONReader::Read(raw_json);
     if (json.get() == nullptr) {
         return;
     }
diff --git a/cmds/bootanimation/iot/BootParameters.h b/cmds/bootanimation/iot/BootParameters.h
index c10bd44..50e5d57 100644
--- a/cmds/bootanimation/iot/BootParameters.h
+++ b/cmds/bootanimation/iot/BootParameters.h
@@ -18,6 +18,7 @@
 #define _BOOTANIMATION_BOOT_PARAMETERS_H_
 
 #include <list>
+#include <string>
 #include <vector>
 
 #include <base/json/json_value_converter.h>
@@ -43,6 +44,8 @@
     // Returns the additional boot parameters that were set on reboot.
     const std::vector<ABootActionParameter>& getParameters() const { return mParameters; }
 
+    // Exposed for testing. Updates the parameters with new JSON values.
+    void loadParameters(const std::string& raw_json);
 private:
     // Raw boot saved_parameters loaded from .json.
     struct SavedBootParameters {
diff --git a/cmds/bootanimation/iot/BootParameters_test.cpp b/cmds/bootanimation/iot/BootParameters_test.cpp
new file mode 100644
index 0000000..431563c
--- /dev/null
+++ b/cmds/bootanimation/iot/BootParameters_test.cpp
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+#include "BootParameters.h"
+
+#include <gtest/gtest.h>
+
+namespace android {
+
+namespace {
+
+TEST(BootParametersTest, TestParseValidParameters) {
+  BootParameters boot_parameters = BootParameters();
+  boot_parameters.loadParameters(R"(
+    {
+      "brightness":200,
+      "volume":100,
+      "param_names":["key1","key2"],
+      "param_values":["value1","value2"]
+    }
+  )");
+
+  EXPECT_TRUE(boot_parameters.hasBrightness());
+  EXPECT_TRUE(boot_parameters.hasVolume());
+  EXPECT_FLOAT_EQ(0.2f, boot_parameters.getBrightness());
+  EXPECT_FLOAT_EQ(0.1f, boot_parameters.getVolume());
+
+  auto parameters = boot_parameters.getParameters();
+  ASSERT_EQ(2u, parameters.size());
+  ASSERT_STREQ(parameters[0].key, "key1");
+  ASSERT_STREQ(parameters[0].value, "value1");
+  ASSERT_STREQ(parameters[1].key, "key2");
+  ASSERT_STREQ(parameters[1].value, "value2");
+}
+
+TEST(BootParametersTest, TestMismatchedParameters) {
+  BootParameters boot_parameters = BootParameters();
+  boot_parameters.loadParameters(R"(
+    {
+      "brightness":500,
+      "volume":500,
+      "param_names":["key1","key2"],
+      "param_values":["value1"]
+    }
+  )");
+
+  EXPECT_TRUE(boot_parameters.hasBrightness());
+  EXPECT_TRUE(boot_parameters.hasVolume());
+  EXPECT_FLOAT_EQ(0.5f, boot_parameters.getBrightness());
+  EXPECT_FLOAT_EQ(0.5f, boot_parameters.getVolume());
+
+  auto parameters = boot_parameters.getParameters();
+  ASSERT_EQ(0u, parameters.size());
+}
+
+TEST(BootParametersTest, TestMissingParameters) {
+  BootParameters boot_parameters = BootParameters();
+  boot_parameters.loadParameters(R"(
+    {
+      "brightness":500
+    }
+  )");
+
+  EXPECT_TRUE(boot_parameters.hasBrightness());
+  EXPECT_FALSE(boot_parameters.hasVolume());
+  EXPECT_FLOAT_EQ(0.5f, boot_parameters.getBrightness());
+  EXPECT_FLOAT_EQ(-1.0f, boot_parameters.getVolume());
+
+  auto parameters = boot_parameters.getParameters();
+  ASSERT_EQ(0u, parameters.size());
+}
+
+}  // namespace
+
+}  // namespace android
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index e8904c6..6aa68da 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -29,6 +29,8 @@
 #include <utils/Looper.h>
 #include <utils/StrongPointer.h>
 
+#include <memory>
+
 #include <stdio.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -72,7 +74,7 @@
     pthread_t thread;
 
     // Thread data.
-    log_reader_thread_data* data = new log_reader_thread_data();
+    std::unique_ptr<log_reader_thread_data> data = std::make_unique<log_reader_thread_data>();
     data->service = service;
 
     // Create the thread
@@ -86,11 +88,15 @@
         pthread_attr_destroy(&attr);
         return err;
     }
-    err = pthread_create(&thread, &attr, log_reader_thread_func, static_cast<void*>(data));
+    err = pthread_create(&thread, &attr, log_reader_thread_func,
+                         static_cast<void*>(data.get()));
     if (err != NO_ERROR) {
         pthread_attr_destroy(&attr);
         return err;
     }
+    // Release here rather than in pthread_create, since an error creating the
+    // thread leaves `data` ownerless.
+    data.release();
     pthread_attr_destroy(&attr);
 
     return NO_ERROR;
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index e21392c..511aec3 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -122,6 +122,12 @@
     VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
 }
 
+
+void CountMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
+    flushIfNeededLocked(dumpTimeNs);
+    mPastBuckets.clear();
+}
+
 void CountMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
                                              const bool include_current_partial_bucket,
                                              ProtoOutputStream* protoOutput) {
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index cafc882..8e94a75 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -59,6 +59,8 @@
                             const bool include_current_partial_bucket,
                             android::util::ProtoOutputStream* protoOutput) override;
 
+    void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
+
     // Internal interface to handle condition change.
     void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
 
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 3661b31..5610492 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -438,6 +438,11 @@
     mPastBuckets.clear();
 }
 
+void DurationMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
+    flushIfNeededLocked(dumpTimeNs);
+    mPastBuckets.clear();
+}
+
 void DurationMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
                                                 const bool include_current_partial_bucket,
                                                 ProtoOutputStream* protoOutput) {
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index 80fbdde..f755294 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -65,6 +65,8 @@
                             const bool include_current_partial_bucket,
                             android::util::ProtoOutputStream* protoOutput) override;
 
+    void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
+
     // Internal interface to handle condition change.
     void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
 
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index 2f2679e..23f780a 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -100,6 +100,10 @@
     return buffer;
 }
 
+void EventMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
+    mProto->clear();
+}
+
 void EventMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
                                              const bool include_current_partial_bucket,
                                              ProtoOutputStream* protoOutput) {
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
index 5c29174..23302c4 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ b/cmds/statsd/src/metrics/EventMetricProducer.h
@@ -49,6 +49,7 @@
     void onDumpReportLocked(const int64_t dumpTimeNs,
                             const bool include_current_partial_bucket,
                             android::util::ProtoOutputStream* protoOutput) override;
+    void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
 
     // Internal interface to handle condition change.
     void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index 1270856..005cb71 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -160,6 +160,12 @@
     }
 }
 
+void GaugeMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
+    flushIfNeededLocked(dumpTimeNs);
+    mPastBuckets.clear();
+    mSkippedBuckets.clear();
+}
+
 void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
                                              const bool include_current_partial_bucket,
                                              ProtoOutputStream* protoOutput) {
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index 71d5912..8af2f36 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -91,6 +91,7 @@
     void onDumpReportLocked(const int64_t dumpTimeNs,
                             const bool include_current_partial_bucket,
                             android::util::ProtoOutputStream* protoOutput) override;
+    void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
 
     // for testing
     GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& gaugeMetric,
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 532ecbf..4239649 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -119,6 +119,11 @@
         return onDumpReportLocked(dumpTimeNs, include_current_partial_bucket, protoOutput);
     }
 
+    void clearPastBuckets(const int64_t dumpTimeNs) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return clearPastBucketsLocked(dumpTimeNs);
+    }
+
     void dumpStates(FILE* out, bool verbose) const {
         std::lock_guard<std::mutex> lock(mMutex);
         dumpStatesLocked(out, verbose);
@@ -177,6 +182,7 @@
     virtual void onDumpReportLocked(const int64_t dumpTimeNs,
                                     const bool include_current_partial_bucket,
                                     android::util::ProtoOutputStream* protoOutput) = 0;
+    virtual void clearPastBucketsLocked(const int64_t dumpTimeNs) = 0;
     virtual size_t byteSizeLocked() const = 0;
     virtual void dumpStatesLocked(FILE* out, bool verbose) const = 0;
 
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 47a1a86..0d3aebf 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -201,6 +201,8 @@
                     protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_METRICS);
             producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, protoOutput);
             protoOutput->end(token);
+        } else {
+            producer->clearPastBuckets(dumpTimeStampNs);
         }
     }
     for (const auto& annotation : mAnnotations) {
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 27fd78f..506cf38 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -151,6 +151,12 @@
     mPastBuckets.clear();
 }
 
+void ValueMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
+    flushIfNeededLocked(dumpTimeNs);
+    mPastBuckets.clear();
+    mSkippedBuckets.clear();
+}
+
 void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
                                              const bool include_current_partial_bucket,
                                              ProtoOutputStream* protoOutput) {
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 8df30d3..64604c2 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -89,6 +89,7 @@
     void onDumpReportLocked(const int64_t dumpTimeNs,
                             const bool include_current_partial_bucket,
                             android::util::ProtoOutputStream* protoOutput) override;
+    void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
 
     // Internal interface to handle condition change.
     void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 6588af8..3d17ad7 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -1,44 +1,38 @@
 Landroid/accounts/AccountManager;->mContext:Landroid/content/Context;
+Landroid/accounts/IAccountAuthenticator$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/accounts/IAccountAuthenticator$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/accounts/IAccountAuthenticator$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountAuthenticator;
+Landroid/accounts/IAccountAuthenticator;->addAccount(Landroid/accounts/IAccountAuthenticatorResponse;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Landroid/os/Bundle;)V
+Landroid/accounts/IAccountAuthenticator;->confirmCredentials(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;Landroid/os/Bundle;)V
+Landroid/accounts/IAccountAuthenticator;->editProperties(Landroid/accounts/IAccountAuthenticatorResponse;Ljava/lang/String;)V
+Landroid/accounts/IAccountAuthenticator;->getAccountRemovalAllowed(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;)V
+Landroid/accounts/IAccountAuthenticator;->getAuthToken(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;Ljava/lang/String;Landroid/os/Bundle;)V
+Landroid/accounts/IAccountAuthenticator;->getAuthTokenLabel(Landroid/accounts/IAccountAuthenticatorResponse;Ljava/lang/String;)V
+Landroid/accounts/IAccountAuthenticator;->hasFeatures(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;[Ljava/lang/String;)V
+Landroid/accounts/IAccountAuthenticator;->updateCredentials(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;Ljava/lang/String;Landroid/os/Bundle;)V
+Landroid/accounts/IAccountAuthenticatorResponse$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/accounts/IAccountAuthenticatorResponse$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/accounts/IAccountAuthenticatorResponse$Stub;-><init>()V
-Landroid/accounts/IAccountManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountManager;
+Landroid/accounts/IAccountAuthenticatorResponse$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountAuthenticatorResponse;
 Landroid/accounts/IAccountManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/animation/LayoutTransition;->cancel(I)V
+Landroid/accounts/IAccountManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountManager;
+Landroid/accounts/IAccountManagerResponse$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/accounts/IAccountManagerResponse$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/accounts/IAccountManagerResponse$Stub;-><init>()V
+Landroid/accounts/IAccountManagerResponse$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountManagerResponse;
+Landroid/accounts/IAccountManagerResponse;->onError(ILjava/lang/String;)V
+Landroid/accounts/IAccountManagerResponse;->onResult(Landroid/os/Bundle;)V
 Landroid/animation/LayoutTransition;->cancel()V
+Landroid/animation/LayoutTransition;->cancel(I)V
 Landroid/animation/ValueAnimator;->animateValue(F)V
 Landroid/animation/ValueAnimator;->sDurationScale:F
+Landroid/app/ActionBar;->setShowHideAnimationEnabled(Z)V
 Landroid/app/Activity;->getActivityOptions()Landroid/app/ActivityOptions;
 Landroid/app/Activity;->getActivityToken()Landroid/os/IBinder;
-Landroid/app/ActivityGroup;->mLocalActivityManager:Landroid/app/LocalActivityManager;
 Landroid/app/Activity;->mActivityInfo:Landroid/content/pm/ActivityInfo;
-Landroid/app/ActivityManager;->clearApplicationUserData(Ljava/lang/String;Landroid/content/pm/IPackageDataObserver;)Z
-Landroid/app/ActivityManager;->getMaxRecentTasksStatic()I
-Landroid/app/ActivityManager;->getService()Landroid/app/IActivityManager;
-Landroid/app/ActivityManager;->IActivityManagerSingleton:Landroid/util/Singleton;
-Landroid/app/ActivityManager;->isHighEndGfx()Z
-Landroid/app/ActivityManager;->isLowRamDeviceStatic()Z
-Landroid/app/ActivityManager;->isUserRunning(I)Z
-Landroid/app/ActivityManager;->mContext:Landroid/content/Context;
-Landroid/app/ActivityManagerNative;->asInterface(Landroid/os/IBinder;)Landroid/app/IActivityManager;
-Landroid/app/ActivityManagerNative;->getDefault()Landroid/app/IActivityManager;
-Landroid/app/ActivityManager;->PROCESS_STATE_IMPORTANT_BACKGROUND:I
-Landroid/app/ActivityManager;->PROCESS_STATE_TOP:I
-Landroid/app/ActivityManager$RecentTaskInfo;->firstActiveTime:J
-Landroid/app/ActivityManager$RecentTaskInfo;->lastActiveTime:J
-Landroid/app/ActivityManager$RecentTaskInfo;->resizeMode:I
-Landroid/app/ActivityManager$RecentTaskInfo;->supportsSplitScreenMultiWindow:Z
-Landroid/app/ActivityManager$RecentTaskInfo;->userId:I
-Landroid/app/ActivityManager$RunningAppProcessInfo;->flags:I
-Landroid/app/ActivityManager$RunningAppProcessInfo;->processState:I
-Landroid/app/ActivityManager;->setPersistentVrThread(I)V
-Landroid/app/ActivityManager$TaskDescription;->getBackgroundColor()I
-Landroid/app/ActivityManager$TaskDescription;->getInMemoryIcon()Landroid/graphics/Bitmap;
-Landroid/app/ActivityManager$TaskSnapshot;->getContentInsets()Landroid/graphics/Rect;
-Landroid/app/ActivityManager$TaskSnapshot;->getOrientation()I
-Landroid/app/ActivityManager$TaskSnapshot;->getScale()F
-Landroid/app/ActivityManager$TaskSnapshot;->isRealSnapshot()Z
-Landroid/app/ActivityManager$TaskSnapshot;->isReducedResolution()Z
 Landroid/app/Activity;->mApplication:Landroid/app/Application;
 Landroid/app/Activity;->mComponent:Landroid/content/ComponentName;
+Landroid/app/Activity;->mFinished:Z
 Landroid/app/Activity;->mFragments:Landroid/app/FragmentController;
 Landroid/app/Activity;->mHandler:Landroid/os/Handler;
 Landroid/app/Activity;->mInstrumentation:Landroid/app/Instrumentation;
@@ -50,11 +44,39 @@
 Landroid/app/Activity;->mToken:Landroid/os/IBinder;
 Landroid/app/Activity;->mWindow:Landroid/view/Window;
 Landroid/app/Activity;->mWindowManager:Landroid/view/WindowManager;
-Landroid/app/ActivityOptions;->makeMultiThumbFutureAspectScaleAnimation(Landroid/content/Context;Landroid/os/Handler;Landroid/view/IAppTransitionAnimationSpecsFuture;Landroid/app/ActivityOptions$OnAnimationStartedListener;Z)Landroid/app/ActivityOptions;
 Landroid/app/Activity;->setDisablePreviewScreenshots(Z)V
 Landroid/app/Activity;->setPersistent(Z)V
-Landroid/app/ActivityThread$ActivityClientRecord;->activityInfo:Landroid/content/pm/ActivityInfo;
+Landroid/app/ActivityGroup;->mLocalActivityManager:Landroid/app/LocalActivityManager;
+Landroid/app/ActivityManager$RecentTaskInfo;->firstActiveTime:J
+Landroid/app/ActivityManager$RecentTaskInfo;->lastActiveTime:J
+Landroid/app/ActivityManager$RecentTaskInfo;->resizeMode:I
+Landroid/app/ActivityManager$RecentTaskInfo;->supportsSplitScreenMultiWindow:Z
+Landroid/app/ActivityManager$RecentTaskInfo;->userId:I
+Landroid/app/ActivityManager$RunningAppProcessInfo;->flags:I
+Landroid/app/ActivityManager$RunningAppProcessInfo;->processState:I
+Landroid/app/ActivityManager$TaskDescription;->getBackgroundColor()I
+Landroid/app/ActivityManager$TaskDescription;->getInMemoryIcon()Landroid/graphics/Bitmap;
+Landroid/app/ActivityManager$TaskSnapshot;->getContentInsets()Landroid/graphics/Rect;
+Landroid/app/ActivityManager$TaskSnapshot;->getOrientation()I
+Landroid/app/ActivityManager$TaskSnapshot;->getScale()F
+Landroid/app/ActivityManager$TaskSnapshot;->isRealSnapshot()Z
+Landroid/app/ActivityManager$TaskSnapshot;->isReducedResolution()Z
+Landroid/app/ActivityManager;->clearApplicationUserData(Ljava/lang/String;Landroid/content/pm/IPackageDataObserver;)Z
+Landroid/app/ActivityManager;->getMaxRecentTasksStatic()I
+Landroid/app/ActivityManager;->getService()Landroid/app/IActivityManager;
+Landroid/app/ActivityManager;->IActivityManagerSingleton:Landroid/util/Singleton;
+Landroid/app/ActivityManager;->isHighEndGfx()Z
+Landroid/app/ActivityManager;->isLowRamDeviceStatic()Z
+Landroid/app/ActivityManager;->isUserRunning(I)Z
+Landroid/app/ActivityManager;->mContext:Landroid/content/Context;
+Landroid/app/ActivityManager;->PROCESS_STATE_IMPORTANT_BACKGROUND:I
+Landroid/app/ActivityManager;->PROCESS_STATE_TOP:I
+Landroid/app/ActivityManager;->setPersistentVrThread(I)V
+Landroid/app/ActivityManagerNative;->asInterface(Landroid/os/IBinder;)Landroid/app/IActivityManager;
+Landroid/app/ActivityManagerNative;->getDefault()Landroid/app/IActivityManager;
+Landroid/app/ActivityOptions;->makeMultiThumbFutureAspectScaleAnimation(Landroid/content/Context;Landroid/os/Handler;Landroid/view/IAppTransitionAnimationSpecsFuture;Landroid/app/ActivityOptions$OnAnimationStartedListener;Z)Landroid/app/ActivityOptions;
 Landroid/app/ActivityThread$ActivityClientRecord;->activity:Landroid/app/Activity;
+Landroid/app/ActivityThread$ActivityClientRecord;->activityInfo:Landroid/content/pm/ActivityInfo;
 Landroid/app/ActivityThread$ActivityClientRecord;->compatInfo:Landroid/content/res/CompatibilityInfo;
 Landroid/app/ActivityThread$ActivityClientRecord;->intent:Landroid/content/Intent;
 Landroid/app/ActivityThread$ActivityClientRecord;->mPreserveWindow:Z
@@ -71,10 +93,32 @@
 Landroid/app/ActivityThread$AppBindData;->restrictedBackupMode:Z
 Landroid/app/ActivityThread$BindServiceData;->intent:Landroid/content/Intent;
 Landroid/app/ActivityThread$BindServiceData;->token:Landroid/os/IBinder;
+Landroid/app/ActivityThread$CreateServiceData;-><init>()V
 Landroid/app/ActivityThread$CreateServiceData;->compatInfo:Landroid/content/res/CompatibilityInfo;
 Landroid/app/ActivityThread$CreateServiceData;->info:Landroid/content/pm/ServiceInfo;
 Landroid/app/ActivityThread$CreateServiceData;->intent:Landroid/content/Intent;
 Landroid/app/ActivityThread$CreateServiceData;->token:Landroid/os/IBinder;
+Landroid/app/ActivityThread$H;->BIND_SERVICE:I
+Landroid/app/ActivityThread$H;->CREATE_SERVICE:I
+Landroid/app/ActivityThread$H;->DUMP_PROVIDER:I
+Landroid/app/ActivityThread$H;->ENTER_ANIMATION_COMPLETE:I
+Landroid/app/ActivityThread$H;->EXIT_APPLICATION:I
+Landroid/app/ActivityThread$H;->GC_WHEN_IDLE:I
+Landroid/app/ActivityThread$H;->INSTALL_PROVIDER:I
+Landroid/app/ActivityThread$H;->RECEIVER:I
+Landroid/app/ActivityThread$H;->REMOVE_PROVIDER:I
+Landroid/app/ActivityThread$H;->SCHEDULE_CRASH:I
+Landroid/app/ActivityThread$H;->SERVICE_ARGS:I
+Landroid/app/ActivityThread$H;->STOP_SERVICE:I
+Landroid/app/ActivityThread$H;->UNBIND_SERVICE:I
+Landroid/app/ActivityThread$ProviderClientRecord;->mHolder:Landroid/app/ContentProviderHolder;
+Landroid/app/ActivityThread$ProviderClientRecord;->mLocalProvider:Landroid/content/ContentProvider;
+Landroid/app/ActivityThread$ProviderClientRecord;->mProvider:Landroid/content/IContentProvider;
+Landroid/app/ActivityThread$ReceiverData;->compatInfo:Landroid/content/res/CompatibilityInfo;
+Landroid/app/ActivityThread$ReceiverData;->info:Landroid/content/pm/ActivityInfo;
+Landroid/app/ActivityThread$ReceiverData;->intent:Landroid/content/Intent;
+Landroid/app/ActivityThread$ServiceArgsData;->args:Landroid/content/Intent;
+Landroid/app/ActivityThread$ServiceArgsData;->token:Landroid/os/IBinder;
 Landroid/app/ActivityThread;->currentActivityThread()Landroid/app/ActivityThread;
 Landroid/app/ActivityThread;->currentApplication()Landroid/app/Application;
 Landroid/app/ActivityThread;->currentPackageName()Ljava/lang/String;
@@ -90,31 +134,19 @@
 Landroid/app/ActivityThread;->getProcessName()Ljava/lang/String;
 Landroid/app/ActivityThread;->getSystemContext()Landroid/app/ContextImpl;
 Landroid/app/ActivityThread;->handleBindApplication(Landroid/app/ActivityThread$AppBindData;)V
-Landroid/app/ActivityThread$H;->BIND_SERVICE:I
-Landroid/app/ActivityThread$H;->CREATE_SERVICE:I
-Landroid/app/ActivityThread$H;->DUMP_PROVIDER:I
-Landroid/app/ActivityThread$H;->ENTER_ANIMATION_COMPLETE:I
-Landroid/app/ActivityThread$H;->EXIT_APPLICATION:I
-Landroid/app/ActivityThread$H;->GC_WHEN_IDLE:I
-Landroid/app/ActivityThread$H;->INSTALL_PROVIDER:I
-Landroid/app/ActivityThread$H;->RECEIVER:I
-Landroid/app/ActivityThread$H;->REMOVE_PROVIDER:I
-Landroid/app/ActivityThread$H;->SCHEDULE_CRASH:I
-Landroid/app/ActivityThread$H;->SERVICE_ARGS:I
-Landroid/app/ActivityThread$H;->STOP_SERVICE:I
-Landroid/app/ActivityThread$H;->UNBIND_SERVICE:I
 Landroid/app/ActivityThread;->installContentProviders(Landroid/content/Context;Ljava/util/List;)V
 Landroid/app/ActivityThread;->installProvider(Landroid/content/Context;Landroid/app/ContentProviderHolder;Landroid/content/pm/ProviderInfo;ZZZ)Landroid/app/ContentProviderHolder;
 Landroid/app/ActivityThread;->mActivities:Landroid/util/ArrayMap;
 Landroid/app/ActivityThread;->mAllApplications:Ljava/util/ArrayList;
 Landroid/app/ActivityThread;->mBoundApplication:Landroid/app/ActivityThread$AppBindData;
 Landroid/app/ActivityThread;->mConfiguration:Landroid/content/res/Configuration;
+Landroid/app/ActivityThread;->mCurDefaultDisplayDpi:I
 Landroid/app/ActivityThread;->mDensityCompatMode:Z
 Landroid/app/ActivityThread;->mH:Landroid/app/ActivityThread$H;
 Landroid/app/ActivityThread;->mInitialApplication:Landroid/app/Application;
 Landroid/app/ActivityThread;->mInstrumentation:Landroid/app/Instrumentation;
-Landroid/app/ActivityThread;->mLocalProvidersByName:Landroid/util/ArrayMap;
 Landroid/app/ActivityThread;->mLocalProviders:Landroid/util/ArrayMap;
+Landroid/app/ActivityThread;->mLocalProvidersByName:Landroid/util/ArrayMap;
 Landroid/app/ActivityThread;->mNumVisibleActivities:I
 Landroid/app/ActivityThread;->mPackages:Landroid/util/ArrayMap;
 Landroid/app/ActivityThread;->mPendingConfiguration:Landroid/content/res/Configuration;
@@ -124,30 +156,22 @@
 Landroid/app/ActivityThread;->mServices:Landroid/util/ArrayMap;
 Landroid/app/ActivityThread;->performNewIntents(Landroid/os/IBinder;Ljava/util/List;Z)V
 Landroid/app/ActivityThread;->performStopActivity(Landroid/os/IBinder;ZLjava/lang/String;)V
-Landroid/app/ActivityThread$ProviderClientRecord;->mHolder:Landroid/app/ContentProviderHolder;
-Landroid/app/ActivityThread$ProviderClientRecord;->mLocalProvider:Landroid/content/ContentProvider;
-Landroid/app/ActivityThread$ProviderClientRecord;->mProvider:Landroid/content/IContentProvider;
-Landroid/app/ActivityThread$ReceiverData;->compatInfo:Landroid/content/res/CompatibilityInfo;
-Landroid/app/ActivityThread$ReceiverData;->info:Landroid/content/pm/ActivityInfo;
-Landroid/app/ActivityThread$ReceiverData;->intent:Landroid/content/Intent;
 Landroid/app/ActivityThread;->sCurrentActivityThread:Landroid/app/ActivityThread;
 Landroid/app/ActivityThread;->sendActivityResult(Landroid/os/IBinder;Ljava/lang/String;IILandroid/content/Intent;)V
-Landroid/app/ActivityThread$ServiceArgsData;->args:Landroid/content/Intent;
-Landroid/app/ActivityThread$ServiceArgsData;->token:Landroid/os/IBinder;
 Landroid/app/ActivityThread;->sPackageManager:Landroid/content/pm/IPackageManager;
 Landroid/app/ActivityThread;->startActivityNow(Landroid/app/Activity;Ljava/lang/String;Landroid/content/Intent;Landroid/content/pm/ActivityInfo;Landroid/os/IBinder;Landroid/os/Bundle;Landroid/app/Activity$NonConfigurationInstances;)Landroid/app/Activity;
 Landroid/app/admin/DevicePolicyManager;->getMandatoryBackupTransport()Landroid/content/ComponentName;
 Landroid/app/admin/DevicePolicyManager;->getProfileOwnerAsUser(I)Landroid/content/ComponentName;
 Landroid/app/admin/DevicePolicyManager;->getTrustAgentConfiguration(Landroid/content/ComponentName;Landroid/content/ComponentName;I)Ljava/util/List;
 Landroid/app/admin/DevicePolicyManager;->packageHasActiveAdmins(Ljava/lang/String;I)Z
-Landroid/app/admin/DevicePolicyManager;->setActiveAdmin(Landroid/content/ComponentName;ZI)V
 Landroid/app/admin/DevicePolicyManager;->setActiveAdmin(Landroid/content/ComponentName;Z)V
+Landroid/app/admin/DevicePolicyManager;->setActiveAdmin(Landroid/content/ComponentName;ZI)V
 Landroid/app/admin/DevicePolicyManager;->setDefaultSmsApplication(Landroid/content/ComponentName;Ljava/lang/String;)V
 Landroid/app/admin/DevicePolicyManager;->throwIfParentInstance(Ljava/lang/String;)V
+Landroid/app/admin/IDevicePolicyManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/admin/IDevicePolicyManager;
 Landroid/app/admin/IDevicePolicyManager$Stub;->TRANSACTION_packageHasActiveAdmins:I
 Landroid/app/admin/IDevicePolicyManager$Stub;->TRANSACTION_removeActiveAdmin:I
 Landroid/app/admin/SecurityLog$SecurityEvent;-><init>([B)V
-Landroid/app/ActionBar;->setShowHideAnimationEnabled(Z)V
 Landroid/app/AlarmManager;->FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED:I
 Landroid/app/AlarmManager;->FLAG_IDLE_UNTIL:I
 Landroid/app/AlarmManager;->FLAG_STANDALONE:I
@@ -171,17 +195,19 @@
 Landroid/app/Application;->dispatchActivitySaveInstanceState(Landroid/app/Activity;Landroid/os/Bundle;)V
 Landroid/app/Application;->dispatchActivityStarted(Landroid/app/Activity;)V
 Landroid/app/Application;->dispatchActivityStopped(Landroid/app/Activity;)V
-Landroid/app/ApplicationLoaders;->getDefault()Landroid/app/ApplicationLoaders;
-Landroid/app/ApplicationLoaders;->mLoaders:Landroid/util/ArrayMap;
 Landroid/app/Application;->mComponentCallbacks:Ljava/util/ArrayList;
 Landroid/app/Application;->mLoadedApk:Landroid/app/LoadedApk;
+Landroid/app/ApplicationLoaders;->getDefault()Landroid/app/ApplicationLoaders;
+Landroid/app/ApplicationLoaders;->mLoaders:Landroid/util/ArrayMap;
+Landroid/app/ApplicationPackageManager;-><init>(Landroid/app/ContextImpl;Landroid/content/pm/IPackageManager;)V
 Landroid/app/ApplicationPackageManager;->configurationChanged()V
 Landroid/app/ApplicationPackageManager;->deletePackage(Ljava/lang/String;Landroid/content/pm/IPackageDeleteObserver;I)V
 Landroid/app/ApplicationPackageManager;->getPackageCurrentVolume(Landroid/content/pm/ApplicationInfo;)Landroid/os/storage/VolumeInfo;
 Landroid/app/ApplicationPackageManager;->getPackageSizeInfoAsUser(Ljava/lang/String;ILandroid/content/pm/IPackageStatsObserver;)V
-Landroid/app/ApplicationPackageManager;-><init>(Landroid/app/ContextImpl;Landroid/content/pm/IPackageManager;)V
 Landroid/app/ApplicationPackageManager;->mPM:Landroid/content/pm/IPackageManager;
 Landroid/app/ApplicationPackageManager;->shouldShowRequestPermissionRationale(Ljava/lang/String;)Z
+Landroid/app/AppOpsManager$OpEntry;->getDuration()I
+Landroid/app/AppOpsManager$OpEntry;->getRejectTime()J
 Landroid/app/AppOpsManager;->checkOp(IILjava/lang/String;)I
 Landroid/app/AppOpsManager;->checkOpNoThrow(IILjava/lang/String;)I
 Landroid/app/AppOpsManager;->getOpsForPackage(ILjava/lang/String;[I)Ljava/util/List;
@@ -190,8 +216,6 @@
 Landroid/app/AppOpsManager;->noteOp(IILjava/lang/String;)I
 Landroid/app/AppOpsManager;->OP_AUDIO_NOTIFICATION_VOLUME:I
 Landroid/app/AppOpsManager;->OP_COARSE_LOCATION:I
-Landroid/app/AppOpsManager$OpEntry;->getDuration()I
-Landroid/app/AppOpsManager$OpEntry;->getRejectTime()J
 Landroid/app/AppOpsManager;->OP_FINE_LOCATION:I
 Landroid/app/AppOpsManager;->OP_GET_USAGE_STATS:I
 Landroid/app/AppOpsManager;->OP_POST_NOTIFICATION:I
@@ -204,8 +228,8 @@
 Landroid/app/AppOpsManager;->OP_WIFI_SCAN:I
 Landroid/app/AppOpsManager;->OP_WRITE_CONTACTS:I
 Landroid/app/AppOpsManager;->OP_WRITE_SMS:I
-Landroid/app/AppOpsManager;->permissionToOpCode(Ljava/lang/String;)I
-Landroid/app/AppOpsManager;->strOpToOp(Ljava/lang/String;)I
+Landroid/app/AppOpsManager;->setRestriction(III[Ljava/lang/String;)V
+Landroid/app/AppOpsManager;->sOpPerms:[Ljava/lang/String;
 Landroid/app/backup/BackupDataInput$EntityHeader;->dataSize:I
 Landroid/app/backup/BackupDataInput$EntityHeader;->key:Ljava/lang/String;
 Landroid/app/backup/BackupDataInputStream;->dataSize:I
@@ -215,11 +239,12 @@
 Landroid/app/backup/BackupHelperDispatcher$Header;->keyPrefix:Ljava/lang/String;
 Landroid/app/backup/FileBackupHelperBase;->writeNewStateDescription(Landroid/os/ParcelFileDescriptor;)V
 Landroid/app/backup/FullBackup;->backupToTar(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/backup/FullBackupDataOutput;)I
-Landroid/app/backup/FullBackupDataOutput;->addSize(J)V
 Landroid/app/backup/FullBackupDataOutput;-><init>(Landroid/os/ParcelFileDescriptor;)V
+Landroid/app/backup/FullBackupDataOutput;->addSize(J)V
 Landroid/app/backup/FullBackupDataOutput;->mData:Landroid/app/backup/BackupDataOutput;
-Landroid/app/ContentProviderHolder;->info:Landroid/content/pm/ProviderInfo;
+Landroid/app/backup/IBackupManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/backup/IBackupManager;
 Landroid/app/ContentProviderHolder;-><init>(Landroid/content/pm/ProviderInfo;)V
+Landroid/app/ContentProviderHolder;->info:Landroid/content/pm/ProviderInfo;
 Landroid/app/ContentProviderHolder;->provider:Landroid/content/IContentProvider;
 Landroid/app/ContextImpl;->createActivityContext(Landroid/app/ActivityThread;Landroid/app/LoadedApk;Landroid/content/pm/ActivityInfo;Landroid/os/IBinder;ILandroid/content/res/Configuration;)Landroid/app/ContextImpl;
 Landroid/app/ContextImpl;->getActivityToken()Landroid/os/IBinder;
@@ -249,13 +274,20 @@
 Landroid/app/Dialog;->mListenersHandler:Landroid/os/Handler;
 Landroid/app/Dialog;->mOwnerActivity:Landroid/app/Activity;
 Landroid/app/Dialog;->mShowMessage:Landroid/os/Message;
+Landroid/app/DialogFragment;->showAllowingStateLoss(Landroid/app/FragmentManager;Ljava/lang/String;)V
 Landroid/app/DownloadManager$Request;->mUri:Landroid/net/Uri;
 Landroid/app/DownloadManager;->setAccessFilename(Z)V
+Landroid/app/Fragment;->mChildFragmentManager:Landroid/app/FragmentManagerImpl;
+Landroid/app/Fragment;->mWho:Ljava/lang/String;
 Landroid/app/FragmentManagerImpl;->mAdded:Ljava/util/ArrayList;
 Landroid/app/FragmentManagerImpl;->mStateSaved:Z
 Landroid/app/FragmentManagerImpl;->noteStateNotSaved()V
-Landroid/app/Fragment;->mChildFragmentManager:Landroid/app/FragmentManagerImpl;
-Landroid/app/Fragment;->mWho:Ljava/lang/String;
+Landroid/app/IActivityManager$Stub$Proxy;->getConfiguration()Landroid/content/res/Configuration;
+Landroid/app/IActivityManager$Stub$Proxy;->getLaunchedFromUid(Landroid/os/IBinder;)I
+Landroid/app/IActivityManager$Stub$Proxy;->getProcessLimit()I
+Landroid/app/IActivityManager$Stub$Proxy;->getProcessPss([I)[J
+Landroid/app/IActivityManager$Stub$Proxy;->isAppForeground(I)Z
+Landroid/app/IActivityManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/app/IActivityManager;->bindService(Landroid/app/IApplicationThread;Landroid/os/IBinder;Landroid/content/Intent;Ljava/lang/String;Landroid/app/IServiceConnection;ILjava/lang/String;I)I
 Landroid/app/IActivityManager;->broadcastIntent(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I
 Landroid/app/IActivityManager;->finishActivity(Landroid/os/IBinder;ILandroid/content/Intent;I)Z
@@ -266,6 +298,7 @@
 Landroid/app/IActivityManager;->getLaunchedFromPackage(Landroid/os/IBinder;)Ljava/lang/String;
 Landroid/app/IActivityManager;->getProviderMimeType(Landroid/net/Uri;I)Ljava/lang/String;
 Landroid/app/IActivityManager;->getTaskForActivity(Landroid/os/IBinder;Z)I
+Landroid/app/IActivityManager;->moveActivityTaskToBack(Landroid/os/IBinder;Z)Z
 Landroid/app/IActivityManager;->moveTaskToFront(IILandroid/os/Bundle;)V
 Landroid/app/IActivityManager;->publishContentProviders(Landroid/app/IApplicationThread;Ljava/util/List;)V
 Landroid/app/IActivityManager;->requestBugReport(I)V
@@ -274,39 +307,68 @@
 Landroid/app/IActivityManager;->setRequestedOrientation(Landroid/os/IBinder;I)V
 Landroid/app/IActivityManager;->setTaskResizeable(II)V
 Landroid/app/IActivityManager;->stopService(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;I)I
-Landroid/app/IActivityManager$Stub$Proxy;->getConfiguration()Landroid/content/res/Configuration;
-Landroid/app/IActivityManager$Stub$Proxy;->getLaunchedFromUid(Landroid/os/IBinder;)I
-Landroid/app/IActivityManager$Stub$Proxy;->getProcessLimit()I
-Landroid/app/IActivityManager$Stub$Proxy;->getProcessPss([I)[J
-Landroid/app/IActivityManager$Stub$Proxy;->isAppForeground(I)Z
-Landroid/app/IActivityManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/app/IActivityManager;->unbindService(Landroid/app/IServiceConnection;)Z
 Landroid/app/IActivityManager;->unstableProviderDied(Landroid/os/IBinder;)V
 Landroid/app/IAlarmManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/app/IAlarmManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IAlarmManager;
 Landroid/app/IAlarmManager$Stub;->TRANSACTION_remove:I
 Landroid/app/IAlarmManager$Stub;->TRANSACTION_set:I
 Landroid/app/IApplicationThread;->scheduleTrimMemory(I)V
+Landroid/app/IAppTask;->getTaskInfo()Landroid/app/ActivityManager$RecentTaskInfo;
+Landroid/app/INotificationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/app/INotificationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/INotificationManager;
 Landroid/app/INotificationManager;->cancelAllNotifications(Ljava/lang/String;I)V
 Landroid/app/INotificationManager;->cancelNotificationWithTag(Ljava/lang/String;Ljava/lang/String;II)V
 Landroid/app/INotificationManager;->cancelToast(Ljava/lang/String;Landroid/app/ITransientNotification;)V
 Landroid/app/INotificationManager;->enqueueToast(Ljava/lang/String;Landroid/app/ITransientNotification;I)V
-Landroid/app/INotificationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/INotificationManager;
-Landroid/app/INotificationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/app/Instrumentation;->execStartActivities(Landroid/content/Context;Landroid/os/IBinder;Landroid/os/IBinder;Landroid/app/Activity;[Landroid/content/Intent;Landroid/os/Bundle;)V
 Landroid/app/Instrumentation;->execStartActivity(Landroid/content/Context;Landroid/os/IBinder;Landroid/os/IBinder;Landroid/app/Activity;Landroid/content/Intent;ILandroid/os/Bundle;)Landroid/app/Instrumentation$ActivityResult;
 Landroid/app/Instrumentation;->execStartActivity(Landroid/content/Context;Landroid/os/IBinder;Landroid/os/IBinder;Ljava/lang/String;Landroid/content/Intent;ILandroid/os/Bundle;)Landroid/app/Instrumentation$ActivityResult;
 Landroid/app/Instrumentation;->execStartActivity(Landroid/content/Context;Landroid/os/IBinder;Landroid/os/IBinder;Ljava/lang/String;Landroid/content/Intent;ILandroid/os/Bundle;Landroid/os/UserHandle;)Landroid/app/Instrumentation$ActivityResult;
 Landroid/app/IntentService;->mServiceHandler:Landroid/app/IntentService$ServiceHandler;
 Landroid/app/IProcessObserver$Stub;-><init>()V
-Landroid/app/ISearchManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/ISearchManager;
 Landroid/app/ISearchManager$Stub$Proxy;->getGlobalSearchActivity()Landroid/content/ComponentName;
 Landroid/app/ISearchManager$Stub$Proxy;->getWebSearchActivity()Landroid/content/ComponentName;
+Landroid/app/ISearchManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/ISearchManager;
+Landroid/app/IServiceConnection$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/app/IServiceConnection$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/app/IServiceConnection$Stub;-><init>()V
 Landroid/app/IServiceConnection$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IServiceConnection;
+Landroid/app/IStopUserCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/app/IStopUserCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/app/IStopUserCallback$Stub;-><init>()V
 Landroid/app/IStopUserCallback;->userStopped(I)V
 Landroid/app/IUiModeManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/app/IWallpaperManager;->getWallpaper(Ljava/lang/String;Landroid/app/IWallpaperManagerCallback;ILandroid/os/Bundle;I)Landroid/os/ParcelFileDescriptor;
-Landroid/app/job/IJobScheduler$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/job/IJobScheduler;
+Landroid/app/job/IJobCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/app/job/IJobCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/app/job/IJobCallback$Stub;-><init>()V
+Landroid/app/job/IJobCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/job/IJobCallback;
+Landroid/app/job/IJobCallback;->acknowledgeStartMessage(IZ)V
+Landroid/app/job/IJobCallback;->acknowledgeStopMessage(IZ)V
+Landroid/app/job/IJobCallback;->jobFinished(IZ)V
 Landroid/app/job/IJobScheduler$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/app/job/IJobScheduler$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/job/IJobScheduler;
+Landroid/app/job/IJobService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/app/job/IJobService$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/app/job/IJobService$Stub;-><init>()V
+Landroid/app/job/IJobService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/job/IJobService;
+Landroid/app/job/IJobService;->startJob(Landroid/app/job/JobParameters;)V
+Landroid/app/job/IJobService;->stopJob(Landroid/app/job/JobParameters;)V
+Landroid/app/job/JobInfo;->flags:I
+Landroid/app/job/JobInfo;->jobId:I
+Landroid/app/job/JobInfo;->service:Landroid/content/ComponentName;
+Landroid/app/job/JobParameters;->callback:Landroid/os/IBinder;
+Landroid/app/job/JobParameters;->jobId:I
+Landroid/app/LoadedApk$ReceiverDispatcher;->getIIntentReceiver()Landroid/content/IIntentReceiver;
+Landroid/app/LoadedApk$ReceiverDispatcher;->getIntentReceiver()Landroid/content/BroadcastReceiver;
+Landroid/app/LoadedApk$ReceiverDispatcher;->mContext:Landroid/content/Context;
+Landroid/app/LoadedApk$ReceiverDispatcher;->mReceiver:Landroid/content/BroadcastReceiver;
+Landroid/app/LoadedApk$ServiceDispatcher$InnerConnection;->mDispatcher:Ljava/lang/ref/WeakReference;
+Landroid/app/LoadedApk$ServiceDispatcher;-><init>(Landroid/content/ServiceConnection;Landroid/content/Context;Landroid/os/Handler;I)V
+Landroid/app/LoadedApk$ServiceDispatcher;->getIServiceConnection()Landroid/app/IServiceConnection;
+Landroid/app/LoadedApk$ServiceDispatcher;->mConnection:Landroid/content/ServiceConnection;
+Landroid/app/LoadedApk$ServiceDispatcher;->mContext:Landroid/content/Context;
 Landroid/app/LoadedApk;->getAssets()Landroid/content/res/AssetManager;
 Landroid/app/LoadedApk;->getClassLoader()Ljava/lang/ClassLoader;
 Landroid/app/LoadedApk;->getCompatibilityInfo()Landroid/content/res/CompatibilityInfo;
@@ -315,18 +377,19 @@
 Landroid/app/LoadedApk;->mActivityThread:Landroid/app/ActivityThread;
 Landroid/app/LoadedApk;->makeApplication(ZLandroid/app/Instrumentation;)Landroid/app/Application;
 Landroid/app/LoadedApk;->mAppDir:Ljava/lang/String;
-Landroid/app/LoadedApk;->mApplicationInfo:Landroid/content/pm/ApplicationInfo;
 Landroid/app/LoadedApk;->mApplication:Landroid/app/Application;
+Landroid/app/LoadedApk;->mApplicationInfo:Landroid/content/pm/ApplicationInfo;
 Landroid/app/LoadedApk;->mBaseClassLoader:Ljava/lang/ClassLoader;
 Landroid/app/LoadedApk;->mClassLoader:Ljava/lang/ClassLoader;
-Landroid/app/LoadedApk;->mDataDirFile:Ljava/io/File;
 Landroid/app/LoadedApk;->mDataDir:Ljava/lang/String;
+Landroid/app/LoadedApk;->mDataDirFile:Ljava/io/File;
 Landroid/app/LoadedApk;->mDisplayAdjustments:Landroid/view/DisplayAdjustments;
 Landroid/app/LoadedApk;->mLibDir:Ljava/lang/String;
 Landroid/app/LoadedApk;->mPackageName:Ljava/lang/String;
 Landroid/app/LoadedApk;->mReceivers:Landroid/util/ArrayMap;
 Landroid/app/LoadedApk;->mResDir:Ljava/lang/String;
 Landroid/app/LoadedApk;->mResources:Landroid/content/res/Resources;
+Landroid/app/LoadedApk;->mServices:Landroid/util/ArrayMap;
 Landroid/app/LoadedApk;->mSplitResDirs:[Ljava/lang/String;
 Landroid/app/LoadedApk;->rewriteRValues(Ljava/lang/ClassLoader;Ljava/lang/String;I)V
 Landroid/app/LocalActivityManager;->mActivities:Ljava/util/Map;
@@ -338,23 +401,25 @@
 Landroid/app/NativeActivity;->setWindowFlags(II)V
 Landroid/app/NativeActivity;->setWindowFormat(I)V
 Landroid/app/NativeActivity;->showIme(I)V
+Landroid/app/Notification$Action;->mIcon:Landroid/graphics/drawable/Icon;
 Landroid/app/Notification$Builder;->mActions:Ljava/util/ArrayList;
 Landroid/app/Notification$Builder;->makePublicContentView()Landroid/widget/RemoteViews;
 Landroid/app/Notification$Builder;->setChannel(Ljava/lang/String;)Landroid/app/Notification$Builder;
 Landroid/app/Notification;-><init>(Landroid/content/Context;ILjava/lang/CharSequence;JLjava/lang/CharSequence;Ljava/lang/CharSequence;Landroid/content/Intent;)V
 Landroid/app/Notification;->isGroupSummary()Z
-Landroid/app/NotificationManager;->getService()Landroid/app/INotificationManager;
-Landroid/app/NotificationManager;->notifyAsUser(Ljava/lang/String;ILandroid/app/Notification;Landroid/os/UserHandle;)V
-Landroid/app/NotificationManager;->sService:Landroid/app/INotificationManager;
 Landroid/app/Notification;->mChannelId:Ljava/lang/String;
 Landroid/app/Notification;->mGroupKey:Ljava/lang/String;
 Landroid/app/Notification;->mLargeIcon:Landroid/graphics/drawable/Icon;
 Landroid/app/Notification;->mSmallIcon:Landroid/graphics/drawable/Icon;
 Landroid/app/Notification;->setLatestEventInfo(Landroid/content/Context;Ljava/lang/CharSequence;Ljava/lang/CharSequence;Landroid/app/PendingIntent;)V
 Landroid/app/Notification;->setSmallIcon(Landroid/graphics/drawable/Icon;)V
+Landroid/app/NotificationManager;->getService()Landroid/app/INotificationManager;
+Landroid/app/NotificationManager;->notifyAsUser(Ljava/lang/String;ILandroid/app/Notification;Landroid/os/UserHandle;)V
+Landroid/app/NotificationManager;->sService:Landroid/app/INotificationManager;
 Landroid/app/PendingIntent;->getActivityAsUser(Landroid/content/Context;ILandroid/content/Intent;ILandroid/os/Bundle;Landroid/os/UserHandle;)Landroid/app/PendingIntent;
 Landroid/app/PendingIntent;->getIntent()Landroid/content/Intent;
 Landroid/app/PendingIntent;->isActivity()Z
+Landroid/app/PictureInPictureParams;->getAspectRatio()F
 Landroid/app/Presentation;->createPresentationContext(Landroid/content/Context;Landroid/view/Display;I)Landroid/content/Context;
 Landroid/app/ProgressDialog;->mProgressNumber:Landroid/widget/TextView;
 Landroid/app/QueuedWork;->addFinisher(Ljava/lang/Runnable;)V
@@ -363,8 +428,11 @@
 Landroid/app/ResourcesManager;->appendLibAssetForMainAssetPath(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/app/ResourcesManager;->getInstance()Landroid/app/ResourcesManager;
 Landroid/app/ResourcesManager;->mActivityResourceReferences:Ljava/util/WeakHashMap;
+Landroid/app/ResourcesManager;->mResConfiguration:Landroid/content/res/Configuration;
 Landroid/app/ResourcesManager;->mResourceImpls:Landroid/util/ArrayMap;
 Landroid/app/ResourcesManager;->mResourceReferences:Ljava/util/ArrayList;
+Landroid/app/ResultInfo;->mData:Landroid/content/Intent;
+Landroid/app/ResultInfo;->mResultWho:Ljava/lang/String;
 Landroid/app/Service;->attach(Landroid/content/Context;Landroid/app/ActivityThread;Ljava/lang/String;Landroid/os/IBinder;Landroid/app/Application;Ljava/lang/Object;)V
 Landroid/app/Service;->mActivityManager:Landroid/app/IActivityManager;
 Landroid/app/Service;->mApplication:Landroid/app/Application;
@@ -384,18 +452,18 @@
 Landroid/app/StatusBarManager;->collapsePanels()V
 Landroid/app/StatusBarManager;->disable(I)V
 Landroid/app/StatusBarManager;->expandNotificationsPanel()V
-Landroid/app/StatusBarManager;->expandSettingsPanel(Ljava/lang/String;)V
 Landroid/app/StatusBarManager;->expandSettingsPanel()V
+Landroid/app/StatusBarManager;->expandSettingsPanel(Ljava/lang/String;)V
 Landroid/app/StatusBarManager;->getService()Lcom/android/internal/statusbar/IStatusBarService;
 Landroid/app/TaskStackListener;-><init>()V
 Landroid/app/TimePickerDialog;->mTimePicker:Landroid/widget/TimePicker;
 Landroid/app/trust/ITrustManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/app/usage/UsageStatsManager;->mService:Landroid/app/usage/IUsageStatsManager;
 Landroid/app/usage/UsageStats;->mLastEvent:I
 Landroid/app/usage/UsageStats;->mLaunchCount:I
 Landroid/app/usage/UsageStats;->mTotalTimeInForeground:J
-Landroid/app/Vr2dDisplayProperties$Builder;->build()Landroid/app/Vr2dDisplayProperties;
+Landroid/app/usage/UsageStatsManager;->mService:Landroid/app/usage/IUsageStatsManager;
 Landroid/app/Vr2dDisplayProperties$Builder;-><init>()V
+Landroid/app/Vr2dDisplayProperties$Builder;->build()Landroid/app/Vr2dDisplayProperties;
 Landroid/app/Vr2dDisplayProperties$Builder;->setEnabled(Z)Landroid/app/Vr2dDisplayProperties$Builder;
 Landroid/app/Vr2dDisplayProperties;-><init>(III)V
 Landroid/app/VrManager;->getPersistentVrModeEnabled()Z
@@ -410,15 +478,17 @@
 Landroid/app/WallpaperManager;->openDefaultWallpaper(Landroid/content/Context;I)Ljava/io/InputStream;
 Landroid/app/WallpaperManager;->setBitmap(Landroid/graphics/Bitmap;Landroid/graphics/Rect;ZII)I
 Landroid/app/WallpaperManager;->sGlobals:Landroid/app/WallpaperManager$Globals;
-Landroid/appwidget/AppWidgetManager;->bindAppWidgetIdIfAllowed(IILandroid/content/ComponentName;Landroid/os/Bundle;)Z
-Landroid/appwidget/AppWidgetManager;->bindAppWidgetId(ILandroid/content/ComponentName;Landroid/os/Bundle;)V
+Landroid/appwidget/AppWidgetHost;->sService:Lcom/android/internal/appwidget/IAppWidgetService;
 Landroid/appwidget/AppWidgetManager;->bindAppWidgetId(ILandroid/content/ComponentName;)V
+Landroid/appwidget/AppWidgetManager;->bindAppWidgetId(ILandroid/content/ComponentName;Landroid/os/Bundle;)V
+Landroid/appwidget/AppWidgetManager;->bindAppWidgetIdIfAllowed(IILandroid/content/ComponentName;Landroid/os/Bundle;)Z
 Landroid/appwidget/AppWidgetManager;->mService:Lcom/android/internal/appwidget/IAppWidgetService;
 Landroid/appwidget/AppWidgetProviderInfo;->providerInfo:Landroid/content/pm/ActivityInfo;
 Landroid/bluetooth/BluetoothA2dp;->ACTION_ACTIVE_DEVICE_CHANGED:Ljava/lang/String;
 Landroid/bluetooth/BluetoothA2dp;->ACTION_CODEC_CONFIG_CHANGED:Ljava/lang/String;
 Landroid/bluetooth/BluetoothA2dp;->connect(Landroid/bluetooth/BluetoothDevice;)Z
 Landroid/bluetooth/BluetoothA2dp;->disableOptionalCodecs(Landroid/bluetooth/BluetoothDevice;)V
+Landroid/bluetooth/BluetoothA2dp;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
 Landroid/bluetooth/BluetoothA2dp;->enableOptionalCodecs(Landroid/bluetooth/BluetoothDevice;)V
 Landroid/bluetooth/BluetoothA2dp;->getActiveDevice()Landroid/bluetooth/BluetoothDevice;
 Landroid/bluetooth/BluetoothA2dp;->getCodecStatus(Landroid/bluetooth/BluetoothDevice;)Landroid/bluetooth/BluetoothCodecStatus;
@@ -438,9 +508,10 @@
 Landroid/bluetooth/BluetoothAdapter;->getDiscoverableTimeout()I
 Landroid/bluetooth/BluetoothAdapter;->getLeState()I
 Landroid/bluetooth/BluetoothAdapter;->mService:Landroid/bluetooth/IBluetooth;
-Landroid/bluetooth/BluetoothAdapter;->setScanMode(II)Z
 Landroid/bluetooth/BluetoothAdapter;->setScanMode(I)Z
+Landroid/bluetooth/BluetoothAdapter;->setScanMode(II)Z
 Landroid/bluetooth/BluetoothCodecConfig;
+Landroid/bluetooth/BluetoothCodecConfig;-><init>(IIIIIJJJJ)V
 Landroid/bluetooth/BluetoothCodecConfig;->BITS_PER_SAMPLE_16:I
 Landroid/bluetooth/BluetoothCodecConfig;->BITS_PER_SAMPLE_24:I
 Landroid/bluetooth/BluetoothCodecConfig;->BITS_PER_SAMPLE_32:I
@@ -460,7 +531,6 @@
 Landroid/bluetooth/BluetoothCodecConfig;->getCodecSpecific4()J
 Landroid/bluetooth/BluetoothCodecConfig;->getCodecType()I
 Landroid/bluetooth/BluetoothCodecConfig;->getSampleRate()I
-Landroid/bluetooth/BluetoothCodecConfig;-><init>(IIIIIJJJJ)V
 Landroid/bluetooth/BluetoothCodecConfig;->SAMPLE_RATE_176400:I
 Landroid/bluetooth/BluetoothCodecConfig;->SAMPLE_RATE_192000:I
 Landroid/bluetooth/BluetoothCodecConfig;->SAMPLE_RATE_44100:I
@@ -470,8 +540,8 @@
 Landroid/bluetooth/BluetoothCodecConfig;->SAMPLE_RATE_NONE:I
 Landroid/bluetooth/BluetoothCodecConfig;->setCodecPriority(I)V
 Landroid/bluetooth/BluetoothCodecConfig;->SOURCE_CODEC_TYPE_AAC:I
-Landroid/bluetooth/BluetoothCodecConfig;->SOURCE_CODEC_TYPE_APTX_HD:I
 Landroid/bluetooth/BluetoothCodecConfig;->SOURCE_CODEC_TYPE_APTX:I
+Landroid/bluetooth/BluetoothCodecConfig;->SOURCE_CODEC_TYPE_APTX_HD:I
 Landroid/bluetooth/BluetoothCodecConfig;->SOURCE_CODEC_TYPE_INVALID:I
 Landroid/bluetooth/BluetoothCodecConfig;->SOURCE_CODEC_TYPE_LDAC:I
 Landroid/bluetooth/BluetoothCodecConfig;->SOURCE_CODEC_TYPE_MAX:I
@@ -484,13 +554,13 @@
 Landroid/bluetooth/BluetoothDevice;->createBond(I)Z
 Landroid/bluetooth/BluetoothDevice;->getAlias()Ljava/lang/String;
 Landroid/bluetooth/BluetoothDevice;->getAliasName()Ljava/lang/String;
+Landroid/bluetooth/BluetoothGatt;->mAuthRetryState:I
+Landroid/bluetooth/BluetoothGatt;->mClientIf:I
+Landroid/bluetooth/BluetoothGatt;->refresh()Z
 Landroid/bluetooth/BluetoothGattCharacteristic;->mInstance:I
 Landroid/bluetooth/BluetoothGattCharacteristic;->mService:Landroid/bluetooth/BluetoothGattService;
 Landroid/bluetooth/BluetoothGattDescriptor;->mCharacteristic:Landroid/bluetooth/BluetoothGattCharacteristic;
 Landroid/bluetooth/BluetoothGattDescriptor;->mInstance:I
-Landroid/bluetooth/BluetoothGatt;->mAuthRetryState:I
-Landroid/bluetooth/BluetoothGatt;->mClientIf:I
-Landroid/bluetooth/BluetoothGatt;->refresh()Z
 Landroid/bluetooth/BluetoothHeadset;->ACTION_ACTIVE_DEVICE_CHANGED:Ljava/lang/String;
 Landroid/bluetooth/BluetoothHeadset;->close()V
 Landroid/bluetooth/BluetoothHeadset;->connectAudio()Z
@@ -503,11 +573,11 @@
 Landroid/bluetooth/BluetoothHearingAid;->getActiveDevices()Ljava/util/List;
 Landroid/bluetooth/BluetoothHearingAid;->setActiveDevice(Landroid/bluetooth/BluetoothDevice;)Z
 Landroid/bluetooth/BluetoothMapClient;->sendMessage(Landroid/bluetooth/BluetoothDevice;[Landroid/net/Uri;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)Z
+Landroid/bluetooth/BluetoothPan;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
 Landroid/bluetooth/BluetoothPan;->close()V
 Landroid/bluetooth/BluetoothPan;->connect(Landroid/bluetooth/BluetoothDevice;)Z
 Landroid/bluetooth/BluetoothPan;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
 Landroid/bluetooth/BluetoothPan;->doBind()Z
-Landroid/bluetooth/BluetoothPan;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
 Landroid/bluetooth/BluetoothPan;->isEnabled()Z
 Landroid/bluetooth/BluetoothPan;->isTetheringOn()Z
 Landroid/bluetooth/BluetoothPan;->isValidDevice(Landroid/bluetooth/BluetoothDevice;)Z
@@ -516,28 +586,43 @@
 Landroid/bluetooth/BluetoothProfile;->PAN:I
 Landroid/bluetooth/BluetoothSocket;->mPfd:Landroid/os/ParcelFileDescriptor;
 Landroid/bluetooth/BluetoothUuid;->RESERVED_UUIDS:[Landroid/os/ParcelUuid;
-Landroid/bluetooth/IBluetooth;->getAddress()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetooth$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetooth;
 Landroid/bluetooth/IBluetooth$Stub$Proxy;->getAddress()Ljava/lang/String;
 Landroid/bluetooth/IBluetooth$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
+Landroid/bluetooth/IBluetooth$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetooth;
+Landroid/bluetooth/IBluetooth;->getAddress()Ljava/lang/String;
+Landroid/bluetooth/IBluetoothManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/bluetooth/IBluetoothManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothManager;
 Landroid/bluetooth/le/ScanRecord;->parseFromBytes([B)Landroid/bluetooth/le/ScanRecord;
 Landroid/content/AsyncTaskLoader;->mExecutor:Ljava/util/concurrent/Executor;
 Landroid/content/BroadcastReceiver$PendingResult;-><init>(ILjava/lang/String;Landroid/os/Bundle;IZZLandroid/os/IBinder;II)V
+Landroid/content/BroadcastReceiver$PendingResult;->mAbortBroadcast:Z
+Landroid/content/BroadcastReceiver$PendingResult;->mFinished:Z
+Landroid/content/BroadcastReceiver$PendingResult;->mFlags:I
+Landroid/content/BroadcastReceiver$PendingResult;->mInitialStickyHint:Z
+Landroid/content/BroadcastReceiver$PendingResult;->mOrderedHint:Z
+Landroid/content/BroadcastReceiver$PendingResult;->mResultCode:I
+Landroid/content/BroadcastReceiver$PendingResult;->mResultData:Ljava/lang/String;
+Landroid/content/BroadcastReceiver$PendingResult;->mResultExtras:Landroid/os/Bundle;
+Landroid/content/BroadcastReceiver$PendingResult;->mSendingUser:I
+Landroid/content/BroadcastReceiver$PendingResult;->mToken:Landroid/os/IBinder;
+Landroid/content/BroadcastReceiver$PendingResult;->mType:I
+Landroid/content/BroadcastReceiver;->getPendingResult()Landroid/content/BroadcastReceiver$PendingResult;
 Landroid/content/BroadcastReceiver;->setPendingResult(Landroid/content/BroadcastReceiver$PendingResult;)V
-Landroid/content/ContentProviderClient;->mContentProvider:Landroid/content/IContentProvider;
-Landroid/content/ContentProviderClient;->mPackageName:Ljava/lang/String;
+Landroid/content/ClipData$Item;->mUri:Landroid/net/Uri;
 Landroid/content/ContentProvider;->coerceToLocalContentProvider(Landroid/content/IContentProvider;)Landroid/content/ContentProvider;
 Landroid/content/ContentProvider;->mContext:Landroid/content/Context;
 Landroid/content/ContentProvider;->mPathPermissions:[Landroid/content/pm/PathPermission;
 Landroid/content/ContentProvider;->mReadPermission:Ljava/lang/String;
 Landroid/content/ContentProvider;->mWritePermission:Ljava/lang/String;
+Landroid/content/ContentProvider;->setAppOps(II)V
+Landroid/content/ContentProviderClient;->mContentProvider:Landroid/content/IContentProvider;
+Landroid/content/ContentProviderClient;->mPackageName:Ljava/lang/String;
 Landroid/content/ContentProviderOperation;->mSelection:Ljava/lang/String;
 Landroid/content/ContentProviderOperation;->mType:I
+Landroid/content/ContentProviderOperation;->mUri:Landroid/net/Uri;
 Landroid/content/ContentProviderOperation;->TYPE_DELETE:I
 Landroid/content/ContentProviderOperation;->TYPE_INSERT:I
 Landroid/content/ContentProviderOperation;->TYPE_UPDATE:I
-Landroid/content/ContentProvider;->setAppOps(II)V
 Landroid/content/ContentResolver;->acquireExistingProvider(Landroid/content/Context;Ljava/lang/String;)Landroid/content/IContentProvider;
 Landroid/content/ContentResolver;->acquireProvider(Landroid/content/Context;Ljava/lang/String;)Landroid/content/IContentProvider;
 Landroid/content/ContentResolver;->acquireProvider(Landroid/net/Uri;)Landroid/content/IContentProvider;
@@ -563,19 +648,36 @@
 Landroid/content/ContextWrapper;->mBase:Landroid/content/Context;
 Landroid/content/CursorLoader;->mCancellationSignal:Landroid/os/CancellationSignal;
 Landroid/content/CursorLoader;->mObserver:Landroid/content/Loader$ForceLoadContentObserver;
-Landroid/content/IClipboard$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IClipboard;
 Landroid/content/IClipboard$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/IClipboard$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IClipboard;
 Landroid/content/IContentProvider;->call(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/Bundle;)Landroid/os/Bundle;
+Landroid/content/IContentService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/IContentService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IContentService;
 Landroid/content/IContentService;->cancelSync(Landroid/accounts/Account;Ljava/lang/String;Landroid/content/ComponentName;)V
 Landroid/content/IContentService;->getMasterSyncAutomatically()Z
 Landroid/content/IContentService;->setMasterSyncAutomatically(Z)V
-Landroid/content/IContentService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IContentService;
-Landroid/content/IContentService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/IIntentReceiver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/IIntentReceiver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/content/IIntentReceiver$Stub;-><init>()V
+Landroid/content/IIntentReceiver;->performReceive(Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZI)V
 Landroid/content/Intent;->ACTION_ALARM_CHANGED:Ljava/lang/String;
-Landroid/content/IntentFilter;->mActions:Ljava/util/ArrayList;
 Landroid/content/Intent;->mExtras:Landroid/os/Bundle;
+Landroid/content/Intent;->prepareToLeaveProcess(Landroid/content/Context;)V
 Landroid/content/Intent;->putExtra(Ljava/lang/String;Landroid/os/IBinder;)Landroid/content/Intent;
+Landroid/content/Intent;->setAllowFds(Z)V
 Landroid/content/Intent;->toInsecureString()Ljava/lang/String;
+Landroid/content/IntentFilter;->mActions:Ljava/util/ArrayList;
+Landroid/content/IntentSender;-><init>(Landroid/content/IIntentSender;)V
+Landroid/content/IntentSender;->mTarget:Landroid/content/IIntentSender;
+Landroid/content/IRestrictionsManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IRestrictionsManager;
+Landroid/content/ISyncAdapter$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/ISyncAdapter$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/content/ISyncContext$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/ISyncContext$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/content/ISyncContext$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/ISyncContext;
+Landroid/content/ISyncStatusObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/ISyncStatusObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/content/pm/ActivityInfo;->isResizeableMode(I)Z
 Landroid/content/pm/ActivityInfo;->resizeMode:I
 Landroid/content/pm/ActivityInfo;->supportsPictureInPicture()Z
 Landroid/content/pm/ApplicationInfo;->enabledSetting:I
@@ -590,9 +692,37 @@
 Landroid/content/pm/ApplicationInfo;->secondaryNativeLibraryDir:Ljava/lang/String;
 Landroid/content/pm/ApplicationInfo;->versionCode:I
 Landroid/content/pm/ComponentInfo;->getComponentName()Landroid/content/ComponentName;
+Landroid/content/pm/IPackageDataObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/pm/IPackageDataObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/content/pm/IPackageDataObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDataObserver;
-Landroid/content/pm/IPackageManager;->addPermissionAsync(Landroid/content/pm/PermissionInfo;)Z
+Landroid/content/pm/IPackageDataObserver;->onRemoveCompleted(Ljava/lang/String;Z)V
+Landroid/content/pm/IPackageDeleteObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDeleteObserver;
+Landroid/content/pm/IPackageDeleteObserver2$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/pm/IPackageDeleteObserver2$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/content/pm/IPackageDeleteObserver2;->onPackageDeleted(Ljava/lang/String;ILjava/lang/String;)V
+Landroid/content/pm/IPackageInstallerCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/pm/IPackageInstallerCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/content/pm/IPackageInstallerCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageInstallerCallback;
+Landroid/content/pm/IPackageInstallerCallback;->onSessionActiveChanged(IZ)V
+Landroid/content/pm/IPackageInstallerCallback;->onSessionBadgingChanged(I)V
+Landroid/content/pm/IPackageInstallerCallback;->onSessionCreated(I)V
+Landroid/content/pm/IPackageInstallerCallback;->onSessionFinished(IZ)V
+Landroid/content/pm/IPackageInstallerCallback;->onSessionProgressChanged(IF)V
+Landroid/content/pm/IPackageInstallerSession$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/pm/IPackageInstallerSession$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/content/pm/IPackageInstallerSession$Stub;-><init>()V
+Landroid/content/pm/IPackageInstallerSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageInstallerSession;
+Landroid/content/pm/IPackageInstallObserver2$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/pm/IPackageInstallObserver2$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/content/pm/IPackageInstallObserver2$Stub;-><init>()V
+Landroid/content/pm/IPackageInstallObserver2;->onPackageInstalled(Ljava/lang/String;ILjava/lang/String;Landroid/os/Bundle;)V
+Landroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledPackages(II)Landroid/content/pm/ParceledListSlice;
+Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;II)Landroid/content/pm/PackageInfo;
+Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackagesForUid(I)[Ljava/lang/String;
+Landroid/content/pm/IPackageManager$Stub$Proxy;->getSystemSharedLibraryNames()[Ljava/lang/String;
+Landroid/content/pm/IPackageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageManager;
 Landroid/content/pm/IPackageManager;->addPermission(Landroid/content/pm/PermissionInfo;)Z
+Landroid/content/pm/IPackageManager;->addPermissionAsync(Landroid/content/pm/PermissionInfo;)Z
 Landroid/content/pm/IPackageManager;->getComponentEnabledSetting(Landroid/content/ComponentName;I)I
 Landroid/content/pm/IPackageManager;->getInstalledPackages(II)Landroid/content/pm/ParceledListSlice;
 Landroid/content/pm/IPackageManager;->getInstallerPackageName(Ljava/lang/String;)Ljava/lang/String;
@@ -605,26 +735,44 @@
 Landroid/content/pm/IPackageManager;->setComponentEnabledSetting(Landroid/content/ComponentName;III)V
 Landroid/content/pm/IPackageManager;->setInstallerPackageName(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/content/pm/IPackageManager;->setLastChosenActivity(Landroid/content/Intent;Ljava/lang/String;ILandroid/content/IntentFilter;ILandroid/content/ComponentName;)V
-Landroid/content/pm/IPackageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageManager;
-Landroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledPackages(II)Landroid/content/pm/ParceledListSlice;
-Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;II)Landroid/content/pm/PackageInfo;
-Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackagesForUid(I)[Ljava/lang/String;
-Landroid/content/pm/IPackageManager$Stub$Proxy;->getSystemSharedLibraryNames()[Ljava/lang/String;
-Landroid/content/pm/IPackageMoveObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageMoveObserver;
 Landroid/content/pm/IPackageMoveObserver$Stub;-><init>()V
+Landroid/content/pm/IPackageMoveObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageMoveObserver;
+Landroid/content/pm/IPackageStatsObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/pm/IPackageStatsObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/content/pm/IPackageStatsObserver$Stub;-><init>()V
+Landroid/content/pm/IPackageStatsObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageStatsObserver;
 Landroid/content/pm/IShortcutService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/pm/IShortcutService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IShortcutService;
 Landroid/content/pm/LauncherActivityInfo;->mActivityInfo:Landroid/content/pm/ActivityInfo;
 Landroid/content/pm/LauncherApps;->mPm:Landroid/content/pm/PackageManager;
 Landroid/content/pm/LauncherApps;->startShortcut(Ljava/lang/String;Ljava/lang/String;Landroid/graphics/Rect;Landroid/os/Bundle;I)V
 Landroid/content/pm/PackageInfo;->INSTALL_LOCATION_UNSPECIFIED:I
+Landroid/content/pm/PackageInstaller$SessionInfo;-><init>()V
+Landroid/content/pm/PackageInstaller$SessionInfo;->active:Z
+Landroid/content/pm/PackageInstaller$SessionInfo;->appIcon:Landroid/graphics/Bitmap;
+Landroid/content/pm/PackageInstaller$SessionInfo;->appLabel:Ljava/lang/CharSequence;
+Landroid/content/pm/PackageInstaller$SessionInfo;->appPackageName:Ljava/lang/String;
+Landroid/content/pm/PackageInstaller$SessionInfo;->installerPackageName:Ljava/lang/String;
+Landroid/content/pm/PackageInstaller$SessionInfo;->mode:I
+Landroid/content/pm/PackageInstaller$SessionInfo;->progress:F
+Landroid/content/pm/PackageInstaller$SessionInfo;->resolvedBaseCodePath:Ljava/lang/String;
+Landroid/content/pm/PackageInstaller$SessionInfo;->sealed:Z
+Landroid/content/pm/PackageInstaller$SessionInfo;->sessionId:I
+Landroid/content/pm/PackageInstaller$SessionInfo;->sizeBytes:J
+Landroid/content/pm/PackageInstaller$SessionParams;->appIcon:Landroid/graphics/Bitmap;
+Landroid/content/pm/PackageInstaller$SessionParams;->appLabel:Ljava/lang/String;
+Landroid/content/pm/PackageInstaller$SessionParams;->appPackageName:Ljava/lang/String;
+Landroid/content/pm/PackageInstaller$SessionParams;->installFlags:I
+Landroid/content/pm/PackageInstaller$SessionParams;->mode:I
+Landroid/content/pm/PackageInstaller$SessionParams;->sizeBytes:J
 Landroid/content/pm/PackageItemInfo;->setForceSafeLabels(Z)V
 Landroid/content/pm/PackageManager;->buildRequestPermissionsIntent([Ljava/lang/String;)Landroid/content/Intent;
-Landroid/content/pm/PackageManager;->freeStorageAndNotify(JLandroid/content/pm/IPackageDataObserver;)V
-Landroid/content/pm/PackageManager;->freeStorageAndNotify(Ljava/lang/String;JLandroid/content/pm/IPackageDataObserver;)V
 Landroid/content/pm/PackageManager;->freeStorage(JLandroid/content/IntentSender;)V
 Landroid/content/pm/PackageManager;->freeStorage(Ljava/lang/String;JLandroid/content/IntentSender;)V
+Landroid/content/pm/PackageManager;->freeStorageAndNotify(JLandroid/content/pm/IPackageDataObserver;)V
+Landroid/content/pm/PackageManager;->freeStorageAndNotify(Ljava/lang/String;JLandroid/content/pm/IPackageDataObserver;)V
 Landroid/content/pm/PackageManager;->getApplicationInfoAsUser(Ljava/lang/String;II)Landroid/content/pm/ApplicationInfo;
+Landroid/content/pm/PackageManager;->getHomeActivities(Ljava/util/List;)Landroid/content/ComponentName;
 Landroid/content/pm/PackageManager;->getPackageCandidateVolumes(Landroid/content/pm/ApplicationInfo;)Ljava/util/List;
 Landroid/content/pm/PackageManager;->getPackageInfoAsUser(Ljava/lang/String;II)Landroid/content/pm/PackageInfo;
 Landroid/content/pm/PackageManager;->getPackageSizeInfo(Ljava/lang/String;Landroid/content/pm/IPackageStatsObserver;)V
@@ -634,29 +782,28 @@
 Landroid/content/pm/PackageManager;->queryBroadcastReceivers(Landroid/content/Intent;II)Ljava/util/List;
 Landroid/content/pm/PackageParser$Activity;->info:Landroid/content/pm/ActivityInfo;
 Landroid/content/pm/PackageParser$ActivityIntentInfo;->activity:Landroid/content/pm/PackageParser$Activity;
-Landroid/content/pm/PackageParser;->collectCertificates(Landroid/content/pm/PackageParser$Package;Ljava/io/File;Z)V
-Landroid/content/pm/PackageParser;->collectCertificates(Landroid/content/pm/PackageParser$Package;Z)V
 Landroid/content/pm/PackageParser$Component;->className:Ljava/lang/String;
 Landroid/content/pm/PackageParser$Component;->getComponentName()Landroid/content/ComponentName;
 Landroid/content/pm/PackageParser$Component;->intents:Ljava/util/ArrayList;
-Landroid/content/pm/PackageParser;->generateActivityInfo(Landroid/content/pm/PackageParser$Activity;ILandroid/content/pm/PackageUserState;I)Landroid/content/pm/ActivityInfo;
-Landroid/content/pm/PackageParser;->generatePackageInfo(Landroid/content/pm/PackageParser$Package;[IIJJLjava/util/Set;Landroid/content/pm/PackageUserState;I)Landroid/content/pm/PackageInfo;
-Landroid/content/pm/PackageParser;->generatePackageInfo(Landroid/content/pm/PackageParser$Package;[IIJJLjava/util/Set;Landroid/content/pm/PackageUserState;)Landroid/content/pm/PackageInfo;
-Landroid/content/pm/PackageParser;->generateProviderInfo(Landroid/content/pm/PackageParser$Provider;ILandroid/content/pm/PackageUserState;I)Landroid/content/pm/ProviderInfo;
-Landroid/content/pm/PackageParser;->generateServiceInfo(Landroid/content/pm/PackageParser$Service;ILandroid/content/pm/PackageUserState;I)Landroid/content/pm/ServiceInfo;
-Landroid/content/pm/PackageParser;-><init>()V
+Landroid/content/pm/PackageParser$Component;->metaData:Landroid/os/Bundle;
 Landroid/content/pm/PackageParser$Instrumentation;->info:Landroid/content/pm/InstrumentationInfo;
+Landroid/content/pm/PackageParser$IntentInfo;-><init>()V
 Landroid/content/pm/PackageParser$IntentInfo;->banner:I
 Landroid/content/pm/PackageParser$IntentInfo;->hasDefault:Z
 Landroid/content/pm/PackageParser$IntentInfo;->icon:I
-Landroid/content/pm/PackageParser$IntentInfo;-><init>()V
 Landroid/content/pm/PackageParser$IntentInfo;->labelRes:I
 Landroid/content/pm/PackageParser$IntentInfo;->logo:I
 Landroid/content/pm/PackageParser$IntentInfo;->nonLocalizedLabel:Ljava/lang/CharSequence;
 Landroid/content/pm/PackageParser$Package;->activities:Ljava/util/ArrayList;
 Landroid/content/pm/PackageParser$Package;->applicationInfo:Landroid/content/pm/ApplicationInfo;
+Landroid/content/pm/PackageParser$Package;->configPreferences:Ljava/util/ArrayList;
 Landroid/content/pm/PackageParser$Package;->instrumentation:Ljava/util/ArrayList;
 Landroid/content/pm/PackageParser$Package;->mAppMetaData:Landroid/os/Bundle;
+Landroid/content/pm/PackageParser$Package;->mKeySetMapping:Landroid/util/ArrayMap;
+Landroid/content/pm/PackageParser$Package;->mPreferredOrder:I
+Landroid/content/pm/PackageParser$Package;->mSharedUserId:Ljava/lang/String;
+Landroid/content/pm/PackageParser$Package;->mSharedUserLabel:I
+Landroid/content/pm/PackageParser$Package;->mSigningDetails:Landroid/content/pm/PackageParser$SigningDetails;
 Landroid/content/pm/PackageParser$Package;->mVersionCode:I
 Landroid/content/pm/PackageParser$Package;->mVersionName:Ljava/lang/String;
 Landroid/content/pm/PackageParser$Package;->packageName:Ljava/lang/String;
@@ -664,29 +811,48 @@
 Landroid/content/pm/PackageParser$Package;->permissions:Ljava/util/ArrayList;
 Landroid/content/pm/PackageParser$Package;->providers:Ljava/util/ArrayList;
 Landroid/content/pm/PackageParser$Package;->receivers:Ljava/util/ArrayList;
+Landroid/content/pm/PackageParser$Package;->reqFeatures:Ljava/util/ArrayList;
 Landroid/content/pm/PackageParser$Package;->requestedPermissions:Ljava/util/ArrayList;
 Landroid/content/pm/PackageParser$Package;->services:Ljava/util/ArrayList;
-Landroid/content/pm/PackageParser;->parseBaseApk(Ljava/lang/String;Landroid/content/res/Resources;Landroid/content/res/XmlResourceParser;I[Ljava/lang/String;)Landroid/content/pm/PackageParser$Package;
-Landroid/content/pm/PackageParser;->parseMonolithicPackage(Ljava/io/File;I)Landroid/content/pm/PackageParser$Package;
-Landroid/content/pm/PackageParser;->parsePackage(Ljava/io/File;I)Landroid/content/pm/PackageParser$Package;
-Landroid/content/pm/PackageParser;->parsePackage(Ljava/io/File;IZ)Landroid/content/pm/PackageParser$Package;
+Landroid/content/pm/PackageParser$Package;->usesLibraries:Ljava/util/ArrayList;
+Landroid/content/pm/PackageParser$Package;->usesOptionalLibraries:Ljava/util/ArrayList;
 Landroid/content/pm/PackageParser$Provider;->info:Landroid/content/pm/ProviderInfo;
 Landroid/content/pm/PackageParser$ProviderIntentInfo;->provider:Landroid/content/pm/PackageParser$Provider;
 Landroid/content/pm/PackageParser$Service;->info:Landroid/content/pm/ServiceInfo;
 Landroid/content/pm/PackageParser$ServiceIntentInfo;->service:Landroid/content/pm/PackageParser$Service;
+Landroid/content/pm/PackageParser$SigningDetails;->signatures:[Landroid/content/pm/Signature;
+Landroid/content/pm/PackageParser;-><init>()V
+Landroid/content/pm/PackageParser;->collectCertificates(Landroid/content/pm/PackageParser$Package;Ljava/io/File;Z)V
+Landroid/content/pm/PackageParser;->collectCertificates(Landroid/content/pm/PackageParser$Package;Z)V
+Landroid/content/pm/PackageParser;->generateActivityInfo(Landroid/content/pm/PackageParser$Activity;ILandroid/content/pm/PackageUserState;I)Landroid/content/pm/ActivityInfo;
+Landroid/content/pm/PackageParser;->generateApplicationInfo(Landroid/content/pm/PackageParser$Package;ILandroid/content/pm/PackageUserState;I)Landroid/content/pm/ApplicationInfo;
+Landroid/content/pm/PackageParser;->generateInstrumentationInfo(Landroid/content/pm/PackageParser$Instrumentation;I)Landroid/content/pm/InstrumentationInfo;
+Landroid/content/pm/PackageParser;->generatePackageInfo(Landroid/content/pm/PackageParser$Package;[IIJJLjava/util/Set;Landroid/content/pm/PackageUserState;)Landroid/content/pm/PackageInfo;
+Landroid/content/pm/PackageParser;->generatePackageInfo(Landroid/content/pm/PackageParser$Package;[IIJJLjava/util/Set;Landroid/content/pm/PackageUserState;I)Landroid/content/pm/PackageInfo;
+Landroid/content/pm/PackageParser;->generatePermissionGroupInfo(Landroid/content/pm/PackageParser$PermissionGroup;I)Landroid/content/pm/PermissionGroupInfo;
+Landroid/content/pm/PackageParser;->generatePermissionInfo(Landroid/content/pm/PackageParser$Permission;I)Landroid/content/pm/PermissionInfo;
+Landroid/content/pm/PackageParser;->generateProviderInfo(Landroid/content/pm/PackageParser$Provider;ILandroid/content/pm/PackageUserState;I)Landroid/content/pm/ProviderInfo;
+Landroid/content/pm/PackageParser;->generateServiceInfo(Landroid/content/pm/PackageParser$Service;ILandroid/content/pm/PackageUserState;I)Landroid/content/pm/ServiceInfo;
+Landroid/content/pm/PackageParser;->parseBaseApk(Ljava/lang/String;Landroid/content/res/Resources;Landroid/content/res/XmlResourceParser;I[Ljava/lang/String;)Landroid/content/pm/PackageParser$Package;
+Landroid/content/pm/PackageParser;->parseMonolithicPackage(Ljava/io/File;I)Landroid/content/pm/PackageParser$Package;
+Landroid/content/pm/PackageParser;->parsePackage(Ljava/io/File;I)Landroid/content/pm/PackageParser$Package;
+Landroid/content/pm/PackageParser;->parsePackage(Ljava/io/File;IZ)Landroid/content/pm/PackageParser$Package;
 Landroid/content/pm/PackageUserState;-><init>()V
 Landroid/content/pm/ParceledListSlice;-><init>(Ljava/util/List;)V
 Landroid/content/pm/ResolveInfo;->instantAppAvailable:Z
 Landroid/content/pm/ShortcutManager;->mService:Landroid/content/pm/IShortcutService;
 Landroid/content/pm/Signature;->getPublicKey()Ljava/security/PublicKey;
+Landroid/content/pm/UserInfo;-><init>(ILjava/lang/String;I)V
+Landroid/content/pm/UserInfo;->FLAG_PRIMARY:I
 Landroid/content/pm/UserInfo;->id:I
 Landroid/content/pm/UserInfo;->isPrimary()Z
 Landroid/content/pm/UserInfo;->serialNumber:I
 Landroid/content/res/AssetFileDescriptor;->mFd:Landroid/os/ParcelFileDescriptor;
 Landroid/content/res/AssetFileDescriptor;->mLength:J
 Landroid/content/res/AssetFileDescriptor;->mStartOffset:J
-Landroid/content/res/AssetManager;->addAssetPathAsSharedLibrary(Ljava/lang/String;)I
+Landroid/content/res/AssetManager;-><init>()V
 Landroid/content/res/AssetManager;->addAssetPath(Ljava/lang/String;)I
+Landroid/content/res/AssetManager;->addAssetPathAsSharedLibrary(Ljava/lang/String;)I
 Landroid/content/res/AssetManager;->applyStyle(JIILandroid/content/res/XmlBlock$Parser;[IJJ)V
 Landroid/content/res/AssetManager;->createTheme()J
 Landroid/content/res/AssetManager;->getAssignedPackageIdentifiers()Landroid/util/SparseArray;
@@ -696,13 +862,12 @@
 Landroid/content/res/AssetManager;->getResourceName(I)Ljava/lang/String;
 Landroid/content/res/AssetManager;->getResourcePackageName(I)Ljava/lang/String;
 Landroid/content/res/AssetManager;->getResourceTypeName(I)Ljava/lang/String;
-Landroid/content/res/AssetManager;-><init>()V
 Landroid/content/res/AssetManager;->isUpToDate()Z
 Landroid/content/res/AssetManager;->mObject:J
-Landroid/content/res/AssetManager;->openNonAsset(ILjava/lang/String;I)Ljava/io/InputStream;
 Landroid/content/res/AssetManager;->openNonAsset(ILjava/lang/String;)Ljava/io/InputStream;
-Landroid/content/res/AssetManager;->openNonAsset(Ljava/lang/String;I)Ljava/io/InputStream;
+Landroid/content/res/AssetManager;->openNonAsset(ILjava/lang/String;I)Ljava/io/InputStream;
 Landroid/content/res/AssetManager;->openNonAsset(Ljava/lang/String;)Ljava/io/InputStream;
+Landroid/content/res/AssetManager;->openNonAsset(Ljava/lang/String;I)Ljava/io/InputStream;
 Landroid/content/res/AssetManager;->resolveAttrs(JII[I[I[I[I)Z
 Landroid/content/res/AssetManager;->retrieveAttributes(Landroid/content/res/XmlBlock$Parser;[I[I[I)Z
 Landroid/content/res/AssetManager;->setConfiguration(IILjava/lang/String;IIIIIIIIIIIIIII)V
@@ -713,13 +878,27 @@
 Landroid/content/res/ColorStateList;->mFactory:Landroid/content/res/ColorStateList$ColorStateListFactory;
 Landroid/content/res/ColorStateList;->mStateSpecs:[[I
 Landroid/content/res/ColorStateList;->onColorsChanged()V
+Landroid/content/res/CompatibilityInfo;-><init>(Landroid/content/pm/ApplicationInfo;IIZ)V
 Landroid/content/res/CompatibilityInfo;->applicationScale:F
 Landroid/content/res/CompatibilityInfo;->DEFAULT_COMPATIBILITY_INFO:Landroid/content/res/CompatibilityInfo;
-Landroid/content/res/DrawableCache;->getInstance(JLandroid/content/res/Resources;Landroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
 Landroid/content/res/DrawableCache;-><init>()V
+Landroid/content/res/DrawableCache;->getInstance(JLandroid/content/res/Resources;Landroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
 Landroid/content/res/ObbInfo;->salt:[B
+Landroid/content/res/Resources$Theme;->mThemeImpl:Landroid/content/res/ResourcesImpl$ThemeImpl;
 Landroid/content/res/Resources;->getCompatibilityInfo()Landroid/content/res/CompatibilityInfo;
+Landroid/content/res/Resources;->loadXmlResourceParser(ILjava/lang/String;)Landroid/content/res/XmlResourceParser;
+Landroid/content/res/Resources;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;
+Landroid/content/res/Resources;->mClassLoader:Ljava/lang/ClassLoader;
+Landroid/content/res/Resources;->mDrawableInflater:Landroid/graphics/drawable/DrawableInflater;
+Landroid/content/res/Resources;->mResourcesImpl:Landroid/content/res/ResourcesImpl;
+Landroid/content/res/Resources;->mSystem:Landroid/content/res/Resources;
+Landroid/content/res/Resources;->mTmpValue:Landroid/util/TypedValue;
+Landroid/content/res/Resources;->mTypedArrayPool:Landroid/util/Pools$SynchronizedPool;
+Landroid/content/res/Resources;->selectDefaultTheme(II)I
+Landroid/content/res/Resources;->setCompatibilityInfo(Landroid/content/res/CompatibilityInfo;)V
+Landroid/content/res/Resources;->updateSystemConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;)V
 Landroid/content/res/ResourcesImpl;->getAssets()Landroid/content/res/AssetManager;
+Landroid/content/res/ResourcesImpl;->getValue(ILandroid/util/TypedValue;Z)V
 Landroid/content/res/ResourcesImpl;->mAccessLock:Ljava/lang/Object;
 Landroid/content/res/ResourcesImpl;->mAnimatorCache:Landroid/content/res/ConfigurationBoundResourceCache;
 Landroid/content/res/ResourcesImpl;->mAssets:Landroid/content/res/AssetManager;
@@ -734,15 +913,6 @@
 Landroid/content/res/ResourcesImpl;->TRACE_FOR_MISS_PRELOAD:Z
 Landroid/content/res/ResourcesImpl;->TRACE_FOR_PRELOAD:Z
 Landroid/content/res/ResourcesKey;->mSplitResDirs:[Ljava/lang/String;
-Landroid/content/res/Resources;->loadXmlResourceParser(ILjava/lang/String;)Landroid/content/res/XmlResourceParser;
-Landroid/content/res/Resources;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;
-Landroid/content/res/Resources;->mResourcesImpl:Landroid/content/res/ResourcesImpl;
-Landroid/content/res/Resources;->mSystem:Landroid/content/res/Resources;
-Landroid/content/res/Resources;->mTmpValue:Landroid/util/TypedValue;
-Landroid/content/res/Resources;->mTypedArrayPool:Landroid/util/Pools$SynchronizedPool;
-Landroid/content/res/Resources;->selectDefaultTheme(II)I
-Landroid/content/res/Resources;->setCompatibilityInfo(Landroid/content/res/CompatibilityInfo;)V
-Landroid/content/res/Resources;->updateSystemConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;)V
 Landroid/content/res/StringBlock;-><init>(JZ)V
 Landroid/content/res/ThemedResourceCache;->onConfigurationChange(I)V
 Landroid/content/res/TypedArray;->extractThemeAttrs()[I
@@ -758,13 +928,35 @@
 Landroid/content/res/TypedArray;->mTheme:Landroid/content/res/Resources$Theme;
 Landroid/content/res/TypedArray;->mValue:Landroid/util/TypedValue;
 Landroid/content/res/TypedArray;->mXml:Landroid/content/res/XmlBlock$Parser;
-Landroid/content/res/XmlBlock;-><init>([B)V
-Landroid/content/res/XmlBlock;->newParser()Landroid/content/res/XmlResourceParser;
 Landroid/content/res/XmlBlock$Parser;->mBlock:Landroid/content/res/XmlBlock;
 Landroid/content/res/XmlBlock$Parser;->mParseState:J
+Landroid/content/res/XmlBlock;-><init>([B)V
+Landroid/content/res/XmlBlock;->newParser()Landroid/content/res/XmlResourceParser;
+Landroid/content/RestrictionsManager;->mService:Landroid/content/IRestrictionsManager;
 Landroid/content/SearchRecentSuggestionsProvider;->mSuggestionProjection:[Ljava/lang/String;
+Landroid/content/SyncAdapterType;->allowParallelSyncs:Z
+Landroid/content/SyncAdapterType;->isAlwaysSyncable:Z
+Landroid/content/SyncAdapterType;->settingsActivity:Ljava/lang/String;
 Landroid/content/SyncContext;->setStatusText(Ljava/lang/String;)V
+Landroid/content/SyncInfo;-><init>(ILandroid/accounts/Account;Ljava/lang/String;J)V
+Landroid/content/SyncRequest;->mAccountToSync:Landroid/accounts/Account;
+Landroid/content/SyncRequest;->mAuthority:Ljava/lang/String;
+Landroid/content/SyncRequest;->mExtras:Landroid/os/Bundle;
+Landroid/content/SyncRequest;->mIsPeriodic:Z
+Landroid/content/SyncRequest;->mSyncRunTimeSecs:J
+Landroid/content/SyncStatusInfo;-><init>(Landroid/os/Parcel;)V
+Landroid/content/SyncStatusInfo;->authorityId:I
+Landroid/content/SyncStatusInfo;->CREATOR:Landroid/os/Parcelable$Creator;
+Landroid/content/SyncStatusInfo;->ensurePeriodicSyncTimeSize(I)V
+Landroid/content/SyncStatusInfo;->initialFailureTime:J
+Landroid/content/SyncStatusInfo;->initialize:Z
+Landroid/content/SyncStatusInfo;->lastFailureMesg:Ljava/lang/String;
+Landroid/content/SyncStatusInfo;->lastFailureSource:I
+Landroid/content/SyncStatusInfo;->lastFailureTime:J
+Landroid/content/SyncStatusInfo;->lastSuccessSource:I
 Landroid/content/SyncStatusInfo;->lastSuccessTime:J
+Landroid/content/SyncStatusInfo;->pending:Z
+Landroid/content/SyncStatusInfo;->periodicSyncTimes:Ljava/util/ArrayList;
 Landroid/content/UriMatcher;->mChildren:Ljava/util/ArrayList;
 Landroid/content/UriMatcher;->mText:Ljava/lang/String;
 Landroid/database/AbstractCursor;->mExtras:Landroid/os/Bundle;
@@ -778,35 +970,37 @@
 Landroid/database/sqlite/SQLiteCustomFunction;->dispatchCallback([Ljava/lang/String;)V
 Landroid/database/sqlite/SQLiteCustomFunction;->name:Ljava/lang/String;
 Landroid/database/sqlite/SQLiteCustomFunction;->numArgs:I
-Landroid/database/sqlite/SQLiteDatabaseConfiguration;->maxSqlCacheSize:I
 Landroid/database/sqlite/SQLiteDatabase;->CONFLICT_VALUES:[Ljava/lang/String;
 Landroid/database/sqlite/SQLiteDatabase;->mConfigurationLocked:Landroid/database/sqlite/SQLiteDatabaseConfiguration;
 Landroid/database/sqlite/SQLiteDatabase;->mConnectionPoolLocked:Landroid/database/sqlite/SQLiteConnectionPool;
 Landroid/database/sqlite/SQLiteDatabase;->reopenReadWrite()V
+Landroid/database/sqlite/SQLiteDatabaseConfiguration;->maxSqlCacheSize:I
 Landroid/database/sqlite/SQLiteDebug$PagerStats;->largestMemAlloc:I
 Landroid/database/sqlite/SQLiteDebug$PagerStats;->memoryUsed:I
 Landroid/database/sqlite/SQLiteDebug$PagerStats;->pageCacheOverflow:I
 Landroid/database/sqlite/SQLiteOpenHelper;->mName:Ljava/lang/String;
 Landroid/database/sqlite/SQLiteStatement;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;)V
 Landroid/ddm/DdmHandleAppName;->getAppName()Ljava/lang/String;
+Landroid/ddm/DdmHandleAppName;->setAppName(Ljava/lang/String;I)V
 Landroid/graphics/AvoidXfermode$Mode;->AVOID:Landroid/graphics/AvoidXfermode$Mode;
 Landroid/graphics/AvoidXfermode$Mode;->TARGET:Landroid/graphics/AvoidXfermode$Mode;
 Landroid/graphics/BaseCanvas;->mNativeCanvasWrapper:J
 Landroid/graphics/Bitmap$Config;->nativeInt:I
 Landroid/graphics/Bitmap$Config;->nativeToConfig(I)Landroid/graphics/Bitmap$Config;
+Landroid/graphics/Bitmap;-><init>(JIIIZ[BLandroid/graphics/NinePatch$InsetStruct;)V
 Landroid/graphics/Bitmap;->createAshmemBitmap()Landroid/graphics/Bitmap;
 Landroid/graphics/Bitmap;->createAshmemBitmap(Landroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;
+Landroid/graphics/Bitmap;->getDefaultDensity()I
+Landroid/graphics/Bitmap;->mNativePtr:J
+Landroid/graphics/Bitmap;->mNinePatchChunk:[B
+Landroid/graphics/Bitmap;->mNinePatchInsets:Landroid/graphics/NinePatch$InsetStruct;
+Landroid/graphics/Bitmap;->reinit(IIZ)V
+Landroid/graphics/Bitmap;->setDefaultDensity(I)V
 Landroid/graphics/BitmapFactory;->nativeDecodeAsset(JLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
 Landroid/graphics/BitmapFactory;->nativeDecodeByteArray([BIILandroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
 Landroid/graphics/BitmapFactory;->nativeDecodeFileDescriptor(Ljava/io/FileDescriptor;Landroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
 Landroid/graphics/BitmapFactory;->nativeDecodeStream(Ljava/io/InputStream;[BLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
-Landroid/graphics/Bitmap;->getDefaultDensity()I
-Landroid/graphics/Bitmap;-><init>(JIIIZ[BLandroid/graphics/NinePatch$InsetStruct;)V
-Landroid/graphics/Bitmap;->mNativePtr:J
-Landroid/graphics/Bitmap;->mNinePatchChunk:[B
-Landroid/graphics/Bitmap;->mNinePatchInsets:Landroid/graphics/NinePatch$InsetStruct;
 Landroid/graphics/BitmapRegionDecoder;-><init>(J)V
-Landroid/graphics/Bitmap;->reinit(IIZ)V
 Landroid/graphics/Camera;->native_instance:J
 Landroid/graphics/Canvas;-><init>(J)V
 Landroid/graphics/Canvas;->release()V
@@ -824,26 +1018,26 @@
 Landroid/graphics/drawable/BitmapDrawable;->mTargetDensity:I
 Landroid/graphics/drawable/BitmapDrawable;->setBitmap(Landroid/graphics/Bitmap;)V
 Landroid/graphics/drawable/ColorDrawable$ColorState;->mUseColor:I
-Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;->mConstantPadding:Landroid/graphics/Rect;
-Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;->mDrawables:[Landroid/graphics/drawable/Drawable;
-Landroid/graphics/drawable/DrawableContainer;->getOpticalInsets()Landroid/graphics/Insets;
-Landroid/graphics/drawable/DrawableContainer;->mDrawableContainerState:Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;
 Landroid/graphics/drawable/Drawable;->getOpticalInsets()Landroid/graphics/Insets;
 Landroid/graphics/drawable/Drawable;->inflateWithAttributes(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/TypedArray;I)V
 Landroid/graphics/drawable/Drawable;->mCallback:Ljava/lang/ref/WeakReference;
 Landroid/graphics/drawable/Drawable;->parseTintMode(ILandroid/graphics/PorterDuff$Mode;)Landroid/graphics/PorterDuff$Mode;
-Landroid/graphics/drawable/GradientDrawable;->getOpticalInsets()Landroid/graphics/Insets;
+Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;->mConstantPadding:Landroid/graphics/Rect;
+Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;->mDrawables:[Landroid/graphics/drawable/Drawable;
+Landroid/graphics/drawable/DrawableContainer;->getOpticalInsets()Landroid/graphics/Insets;
+Landroid/graphics/drawable/DrawableContainer;->mDrawableContainerState:Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;
+Landroid/graphics/drawable/DrawableInflater;->mClassLoader:Ljava/lang/ClassLoader;
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mAngle:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mGradientColors:[I
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mGradient:I
+Landroid/graphics/drawable/GradientDrawable$GradientState;->mGradientColors:[I
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mHeight:I
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mInnerRadius:I
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mInnerRadiusRatio:F
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mOrientation:Landroid/graphics/drawable/GradientDrawable$Orientation;
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mPadding:Landroid/graphics/Rect;
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mPositions:[F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mRadiusArray:[F
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mRadius:F
+Landroid/graphics/drawable/GradientDrawable$GradientState;->mRadiusArray:[F
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mShape:I
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mSolidColors:Landroid/content/res/ColorStateList;
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mStrokeDashGap:F
@@ -852,6 +1046,7 @@
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mThickness:I
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mThicknessRatio:F
 Landroid/graphics/drawable/GradientDrawable$GradientState;->mWidth:I
+Landroid/graphics/drawable/GradientDrawable;->getOpticalInsets()Landroid/graphics/Insets;
 Landroid/graphics/drawable/GradientDrawable;->mGradientState:Landroid/graphics/drawable/GradientDrawable$GradientState;
 Landroid/graphics/drawable/GradientDrawable;->mPadding:Landroid/graphics/Rect;
 Landroid/graphics/drawable/Icon;->getBitmap()Landroid/graphics/Bitmap;
@@ -860,15 +1055,16 @@
 Landroid/graphics/drawable/Icon;->getDataOffset()I
 Landroid/graphics/drawable/Icon;->getResources()Landroid/content/res/Resources;
 Landroid/graphics/drawable/Icon;->hasTint()Z
+Landroid/graphics/drawable/Icon;->mString1:Ljava/lang/String;
 Landroid/graphics/drawable/Icon;->mType:I
 Landroid/graphics/drawable/InsetDrawable;->mState:Landroid/graphics/drawable/InsetDrawable$InsetState;
 Landroid/graphics/drawable/LayerDrawable$ChildDrawable;->mDrawable:Landroid/graphics/drawable/Drawable;
 Landroid/graphics/drawable/LayerDrawable$LayerState;->mChildren:[Landroid/graphics/drawable/LayerDrawable$ChildDrawable;
 Landroid/graphics/drawable/LayerDrawable;->mLayerState:Landroid/graphics/drawable/LayerDrawable$LayerState;
-Landroid/graphics/drawable/NinePatchDrawable;->mNinePatchState:Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;
 Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;->mNinePatch:Landroid/graphics/NinePatch;
-Landroid/graphics/drawable/RippleDrawable;->mState:Landroid/graphics/drawable/RippleDrawable$RippleState;
+Landroid/graphics/drawable/NinePatchDrawable;->mNinePatchState:Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;
 Landroid/graphics/drawable/RippleDrawable$RippleState;->mColor:Landroid/content/res/ColorStateList;
+Landroid/graphics/drawable/RippleDrawable;->mState:Landroid/graphics/drawable/RippleDrawable$RippleState;
 Landroid/graphics/drawable/StateListDrawable;->extractStateSet(Landroid/util/AttributeSet;)[I
 Landroid/graphics/drawable/StateListDrawable;->getStateCount()I
 Landroid/graphics/drawable/StateListDrawable;->getStateDrawable(I)Landroid/graphics/drawable/Drawable;
@@ -876,23 +1072,26 @@
 Landroid/graphics/drawable/StateListDrawable;->getStateSet(I)[I
 Landroid/graphics/drawable/StateListDrawable;->mStateListState:Landroid/graphics/drawable/StateListDrawable$StateListState;
 Landroid/graphics/drawable/StateListDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
-Landroid/graphics/drawable/VectorDrawable;->getTargetByName(Ljava/lang/String;)Ljava/lang/Object;
-Landroid/graphics/drawable/VectorDrawable;->setAllowCaching(Z)V
 Landroid/graphics/drawable/VectorDrawable$VGroup;->setRotation(F)V
+Landroid/graphics/drawable/VectorDrawable;->getTargetByName(Ljava/lang/String;)Ljava/lang/Object;
+Landroid/graphics/drawable/VectorDrawable;->mTintFilter:Landroid/graphics/PorterDuffColorFilter;
+Landroid/graphics/drawable/VectorDrawable;->setAllowCaching(Z)V
+Landroid/graphics/FontFamily;-><init>()V
 Landroid/graphics/FontFamily;->abortCreation()V
 Landroid/graphics/FontFamily;->addFontFromAssetManager(Landroid/content/res/AssetManager;Ljava/lang/String;IZIII[Landroid/graphics/fonts/FontVariationAxis;)Z
 Landroid/graphics/FontFamily;->addFontFromBuffer(Ljava/nio/ByteBuffer;I[Landroid/graphics/fonts/FontVariationAxis;II)Z
 Landroid/graphics/FontFamily;->freeze()Z
-Landroid/graphics/FontFamily;-><init>()V
 Landroid/graphics/fonts/FontVariationAxis;->mStyleValue:F
 Landroid/graphics/fonts/FontVariationAxis;->mTag:I
+Landroid/graphics/GraphicBuffer;-><init>(IIIIJ)V
 Landroid/graphics/GraphicBuffer;->createFromExisting(IIIIJ)Landroid/graphics/GraphicBuffer;
 Landroid/graphics/GraphicBuffer;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/graphics/GraphicBuffer;-><init>(IIIIJ)V
 Landroid/graphics/GraphicBuffer;->mNativeObject:J
 Landroid/graphics/ImageDecoder;->postProcessAndRelease(Landroid/graphics/Canvas;)I
+Landroid/graphics/Insets;->bottom:I
 Landroid/graphics/Insets;->left:I
 Landroid/graphics/Insets;->right:I
+Landroid/graphics/Insets;->top:I
 Landroid/graphics/LinearGradient;->mColors:[I
 Landroid/graphics/Matrix;->native_instance:J
 Landroid/graphics/Movie;-><init>(J)V
@@ -901,6 +1100,7 @@
 Landroid/graphics/NinePatch;->mBitmap:Landroid/graphics/Bitmap;
 Landroid/graphics/Picture;->mNativePicture:J
 Landroid/graphics/PixelXorXfermode;-><init>(I)V
+Landroid/graphics/PorterDuffColorFilter;->getColor()I
 Landroid/graphics/Rect;->scale(F)V
 Landroid/graphics/Region;-><init>(JI)V
 Landroid/graphics/Region;->mNativeRegion:J
@@ -915,15 +1115,15 @@
 Landroid/graphics/Typeface;->sDefaults:[Landroid/graphics/Typeface;
 Landroid/graphics/Typeface;->setDefault(Landroid/graphics/Typeface;)V
 Landroid/graphics/Typeface;->sSystemFontMap:Ljava/util/Map;
+Landroid/hardware/camera2/CameraCharacteristics$Key;-><init>(Ljava/lang/String;Landroid/hardware/camera2/utils/TypeReference;)V
+Landroid/hardware/camera2/CameraCharacteristics$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;)V
+Landroid/hardware/camera2/CameraCharacteristics$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
+Landroid/hardware/camera2/CameraCharacteristics$Key;->getNativeKey()Landroid/hardware/camera2/impl/CameraMetadataNative$Key;
 Landroid/hardware/camera2/CameraCharacteristics;->CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
 Landroid/hardware/camera2/CameraCharacteristics;->CONTROL_MAX_REGIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
 Landroid/hardware/camera2/CameraCharacteristics;->DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
 Landroid/hardware/camera2/CameraCharacteristics;->DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
 Landroid/hardware/camera2/CameraCharacteristics;->DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics$Key;->getNativeKey()Landroid/hardware/camera2/impl/CameraMetadataNative$Key;
-Landroid/hardware/camera2/CameraCharacteristics$Key;-><init>(Ljava/lang/String;Landroid/hardware/camera2/utils/TypeReference;)V
-Landroid/hardware/camera2/CameraCharacteristics$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
-Landroid/hardware/camera2/CameraCharacteristics$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;)V
 Landroid/hardware/camera2/CameraCharacteristics;->LED_AVAILABLE_LEDS:Landroid/hardware/camera2/CameraCharacteristics$Key;
 Landroid/hardware/camera2/CameraCharacteristics;->LENS_INFO_SHADING_MAP_SIZE:Landroid/hardware/camera2/CameraCharacteristics$Key;
 Landroid/hardware/camera2/CameraCharacteristics;->LOGICAL_MULTI_CAMERA_PHYSICAL_IDS:Landroid/hardware/camera2/CameraCharacteristics$Key;
@@ -943,24 +1143,24 @@
 Landroid/hardware/camera2/CameraCharacteristics;->SCALER_AVAILABLE_PROCESSED_SIZES:Landroid/hardware/camera2/CameraCharacteristics$Key;
 Landroid/hardware/camera2/CameraCharacteristics;->SCALER_AVAILABLE_STALL_DURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
 Landroid/hardware/camera2/CameraCharacteristics;->SCALER_AVAILABLE_STREAM_CONFIGURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
+Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Landroid/hardware/camera2/utils/TypeReference;)V
+Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
+Landroid/hardware/camera2/CaptureRequest$Key;->getNativeKey()Landroid/hardware/camera2/impl/CameraMetadataNative$Key;
 Landroid/hardware/camera2/CaptureRequest;->JPEG_GPS_COORDINATES:Landroid/hardware/camera2/CaptureRequest$Key;
 Landroid/hardware/camera2/CaptureRequest;->JPEG_GPS_PROCESSING_METHOD:Landroid/hardware/camera2/CaptureRequest$Key;
 Landroid/hardware/camera2/CaptureRequest;->JPEG_GPS_TIMESTAMP:Landroid/hardware/camera2/CaptureRequest$Key;
-Landroid/hardware/camera2/CaptureRequest$Key;->getNativeKey()Landroid/hardware/camera2/impl/CameraMetadataNative$Key;
-Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Landroid/hardware/camera2/utils/TypeReference;)V
-Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
 Landroid/hardware/camera2/CaptureRequest;->LED_TRANSMIT:Landroid/hardware/camera2/CaptureRequest$Key;
 Landroid/hardware/camera2/CaptureRequest;->REQUEST_ID:Landroid/hardware/camera2/CaptureRequest$Key;
 Landroid/hardware/camera2/CaptureRequest;->TONEMAP_CURVE_BLUE:Landroid/hardware/camera2/CaptureRequest$Key;
 Landroid/hardware/camera2/CaptureRequest;->TONEMAP_CURVE_GREEN:Landroid/hardware/camera2/CaptureRequest$Key;
 Landroid/hardware/camera2/CaptureRequest;->TONEMAP_CURVE_RED:Landroid/hardware/camera2/CaptureRequest$Key;
+Landroid/hardware/camera2/CaptureResult$Key;-><init>(Ljava/lang/String;Landroid/hardware/camera2/utils/TypeReference;)V
+Landroid/hardware/camera2/CaptureResult$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;)V
+Landroid/hardware/camera2/CaptureResult$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
+Landroid/hardware/camera2/CaptureResult$Key;->getNativeKey()Landroid/hardware/camera2/impl/CameraMetadataNative$Key;
 Landroid/hardware/camera2/CaptureResult;->JPEG_GPS_COORDINATES:Landroid/hardware/camera2/CaptureResult$Key;
 Landroid/hardware/camera2/CaptureResult;->JPEG_GPS_PROCESSING_METHOD:Landroid/hardware/camera2/CaptureResult$Key;
 Landroid/hardware/camera2/CaptureResult;->JPEG_GPS_TIMESTAMP:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult$Key;->getNativeKey()Landroid/hardware/camera2/impl/CameraMetadataNative$Key;
-Landroid/hardware/camera2/CaptureResult$Key;-><init>(Ljava/lang/String;Landroid/hardware/camera2/utils/TypeReference;)V
-Landroid/hardware/camera2/CaptureResult$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
-Landroid/hardware/camera2/CaptureResult$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;)V
 Landroid/hardware/camera2/CaptureResult;->LED_TRANSMIT:Landroid/hardware/camera2/CaptureResult$Key;
 Landroid/hardware/camera2/CaptureResult;->QUIRKS_PARTIAL_RESULT:Landroid/hardware/camera2/CaptureResult$Key;
 Landroid/hardware/camera2/CaptureResult;->REQUEST_FRAME_COUNT:Landroid/hardware/camera2/CaptureResult$Key;
@@ -984,8 +1184,12 @@
 Landroid/hardware/camera2/utils/TypeReference;->createSpecializedTypeReference(Ljava/lang/reflect/Type;)Landroid/hardware/camera2/utils/TypeReference;
 Landroid/hardware/Camera;->addCallbackBuffer([BI)V
 Landroid/hardware/Camera;->mNativeContext:J
+Landroid/hardware/Camera;->native_setup(Ljava/lang/Object;IILjava/lang/String;)I
 Landroid/hardware/Camera;->openLegacy(II)Landroid/hardware/Camera;
 Landroid/hardware/Camera;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
+Landroid/hardware/display/DisplayManagerGlobal;->mDm:Landroid/hardware/display/IDisplayManager;
+Landroid/hardware/display/DisplayManagerGlobal;->sInstance:Landroid/hardware/display/DisplayManagerGlobal;
+Landroid/hardware/display/IDisplayManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/display/IDisplayManager;
 Landroid/hardware/display/WifiDisplayStatus;->mActiveDisplay:Landroid/hardware/display/WifiDisplay;
 Landroid/hardware/display/WifiDisplayStatus;->mDisplays:[Landroid/hardware/display/WifiDisplay;
 Landroid/hardware/fingerprint/Fingerprint;->getFingerId()I
@@ -993,44 +1197,47 @@
 Landroid/hardware/fingerprint/IFingerprintService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/hardware/HardwareBuffer;-><init>(J)V
 Landroid/hardware/HardwareBuffer;->mNativeObject:J
-Landroid/hardware/input/IInputManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/input/IInputManager;
+Landroid/hardware/ICameraService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/ICameraService;
 Landroid/hardware/input/IInputManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/hardware/input/IInputManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/input/IInputManager;
 Landroid/hardware/input/InputManager;->getInstance()Landroid/hardware/input/InputManager;
 Landroid/hardware/input/InputManager;->injectInputEvent(Landroid/view/InputEvent;I)Z
 Landroid/hardware/input/InputManager;->INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH:I
 Landroid/hardware/input/InputManager;->mIm:Landroid/hardware/input/IInputManager;
 Landroid/hardware/location/IActivityRecognitionHardwareClient$Stub;-><init>()V
+Landroid/hardware/location/IContextHubService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/location/IContextHubService;
 Landroid/hardware/SerialPort;->mNativeContext:I
-Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;->confidenceLevel:I
 Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;-><init>(II)V
+Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;->confidenceLevel:I
 Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;->userId:I
 Landroid/hardware/soundtrigger/SoundTrigger$GenericRecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B)V
 Landroid/hardware/soundtrigger/SoundTrigger$GenericSoundModel;-><init>(Ljava/util/UUID;Ljava/util/UUID;[B)V
 Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->id:I
 Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->locale:Ljava/lang/String;
+Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->recognitionModes:I
+Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->text:Ljava/lang/String;
+Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->users:[I
 Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;)V
+Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;-><init>(III[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;)V
 Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;->coarseConfidenceLevel:I
 Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;->confidenceLevels:[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;
 Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;->id:I
-Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;-><init>(III[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;)V
 Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;->recognitionModes:I
-Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->recognitionModes:I
 Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel;->keyphrases:[Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;
-Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->text:Ljava/lang/String;
-Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->users:[I
+Landroid/hardware/soundtrigger/SoundTrigger$ModuleProperties;-><init>(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIZIZIZ)V
+Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;-><init>(ZZ[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;[B)V
+Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->captureRequested:Z
+Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->data:[B
+Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->keyphrases:[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;
+Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B)V
+Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;->data:[B
+Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->data:[B
+Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->uuid:Ljava/util/UUID;
+Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->vendorUuid:Ljava/util/UUID;
+Landroid/hardware/soundtrigger/SoundTrigger$SoundModelEvent;-><init>(II[B)V
 Landroid/hardware/soundtrigger/SoundTriggerModule;->mId:I
 Landroid/hardware/soundtrigger/SoundTriggerModule;->mNativeContext:J
 Landroid/hardware/soundtrigger/SoundTriggerModule;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
-Landroid/hardware/soundtrigger/SoundTrigger$ModuleProperties;-><init>(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIZIZIZ)V
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->captureRequested:Z
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->data:[B
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;-><init>(ZZ[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;[B)V
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->keyphrases:[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B)V
-Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->data:[B
-Landroid/hardware/soundtrigger/SoundTrigger$SoundModelEvent;-><init>(II[B)V
-Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->uuid:Ljava/util/UUID;
-Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->vendorUuid:Ljava/util/UUID;
 Landroid/hardware/SystemSensorManager$BaseEventQueue;->dispatchAdditionalInfoEvent(III[F[I)V
 Landroid/hardware/SystemSensorManager$BaseEventQueue;->dispatchFlushCompleteEvent(I)V
 Landroid/hardware/SystemSensorManager$BaseEventQueue;->dispatchSensorEvent(I[FIJ)V
@@ -1059,29 +1266,38 @@
 Landroid/icu/text/DateTimePatternGenerator$DistanceInfo;-><init>()V
 Landroid/icu/text/DecimalFormatSymbols;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
 Landroid/icu/text/RuleBasedCollator;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/text/SpoofChecker$ScriptSet;->and(I)V
 Landroid/icu/text/SpoofChecker$ScriptSet;-><init>()V
+Landroid/icu/text/SpoofChecker$ScriptSet;->and(I)V
 Landroid/icu/text/SpoofChecker$ScriptSet;->isFull()Z
 Landroid/icu/text/SpoofChecker$ScriptSet;->setAll()V
 Landroid/icu/text/TimeZoneNames$DefaultTimeZoneNames$FactoryImpl;-><init>()V
 Landroid/icu/text/Transliterator;->createFromRules(Ljava/lang/String;Ljava/lang/String;I)Landroid/icu/text/Transliterator;
+Landroid/icu/text/Transliterator;->getInstance(Ljava/lang/String;)Landroid/icu/text/Transliterator;
 Landroid/icu/text/Transliterator;->transliterate(Ljava/lang/String;)Ljava/lang/String;
 Landroid/icu/text/UFormat;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
 Landroid/icu/util/Calendar;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
+Landroid/inputmethodservice/InputMethodService$SettingsObserver;->shouldShowImeWithHardKeyboard()Z
 Landroid/inputmethodservice/InputMethodService;->mExtractEditText:Landroid/inputmethodservice/ExtractEditText;
 Landroid/inputmethodservice/InputMethodService;->mRootView:Landroid/view/View;
 Landroid/inputmethodservice/InputMethodService;->mSettingsObserver:Landroid/inputmethodservice/InputMethodService$SettingsObserver;
-Landroid/inputmethodservice/InputMethodService$SettingsObserver;->shouldShowImeWithHardKeyboard()Z
-Landroid/location/CountryDetector;->detectCountry()Landroid/location/Country;
 Landroid/location/Country;->getCountryIso()Ljava/lang/String;
 Landroid/location/Country;->getSource()I
+Landroid/location/CountryDetector;->detectCountry()Landroid/location/Country;
 Landroid/location/GeocoderParams;->getClientPackage()Ljava/lang/String;
 Landroid/location/GeocoderParams;->getLocale()Ljava/util/Locale;
 Landroid/location/IGeocodeProvider$Stub;-><init>()V
 Landroid/location/IGeofenceProvider$Stub;-><init>()V
-Landroid/location/ILocationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ILocationManager;
+Landroid/location/ILocationListener$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/location/ILocationListener$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/location/ILocationListener;->onLocationChanged(Landroid/location/Location;)V
 Landroid/location/ILocationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/location/ILocationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ILocationManager;
+Landroid/location/Location;->mElapsedRealtimeNanos:J
 Landroid/location/LocationManager;->mService:Landroid/location/ILocationManager;
+Landroid/location/LocationRequest;->mHideFromAppOps:Z
+Landroid/location/LocationRequest;->mInterval:J
+Landroid/location/LocationRequest;->mProvider:Ljava/lang/String;
+Landroid/location/LocationRequest;->mWorkSource:Landroid/os/WorkSource;
 Landroid/media/AudioAttributes$Builder;->addTag(Ljava/lang/String;)Landroid/media/AudioAttributes$Builder;
 Landroid/media/AudioAttributes;->mContentType:I
 Landroid/media/AudioAttributes;->mFlags:I
@@ -1089,30 +1305,30 @@
 Landroid/media/AudioAttributes;->mSource:I
 Landroid/media/AudioAttributes;->mUsage:I
 Landroid/media/AudioAttributes;->toLegacyStreamType(Landroid/media/AudioAttributes;)I
-Landroid/media/AudioDevicePortConfig;-><init>(Landroid/media/AudioDevicePort;IIILandroid/media/AudioGainConfig;)V
 Landroid/media/AudioDevicePort;-><init>(Landroid/media/AudioHandle;Ljava/lang/String;[I[I[I[I[Landroid/media/AudioGain;ILjava/lang/String;)V
+Landroid/media/AudioDevicePortConfig;-><init>(Landroid/media/AudioDevicePort;IIILandroid/media/AudioGainConfig;)V
 Landroid/media/AudioFormat;-><init>(IIII)V
 Landroid/media/AudioFormat;->mChannelMask:I
 Landroid/media/AudioFormat;->mEncoding:I
 Landroid/media/AudioFormat;->mSampleRate:I
+Landroid/media/audiofx/AudioEffect;-><init>(Ljava/util/UUID;Ljava/util/UUID;II)V
 Landroid/media/audiofx/AudioEffect;->command(I[B[B)I
 Landroid/media/audiofx/AudioEffect;->getParameter([I[B)I
 Landroid/media/audiofx/AudioEffect;->getParameter([I[I)I
-Landroid/media/audiofx/AudioEffect;-><init>(Ljava/util/UUID;Ljava/util/UUID;II)V
 Landroid/media/audiofx/AudioEffect;->setParameter([I[S)I
+Landroid/media/AudioGain;-><init>(IIIIIIIII)V
 Landroid/media/AudioGainConfig;-><init>(ILandroid/media/AudioGain;II[II)V
 Landroid/media/AudioGainConfig;->mChannelMask:I
 Landroid/media/AudioGainConfig;->mIndex:I
 Landroid/media/AudioGainConfig;->mMode:I
 Landroid/media/AudioGainConfig;->mRampDurationMs:I
 Landroid/media/AudioGainConfig;->mValues:[I
-Landroid/media/AudioGain;-><init>(IIIIIIIII)V
 Landroid/media/AudioHandle;-><init>(I)V
 Landroid/media/AudioHandle;->mId:I
+Landroid/media/AudioManager;-><init>(Landroid/content/Context;)V
 Landroid/media/AudioManager;->forceVolumeControlStream(I)V
 Landroid/media/AudioManager;->getOutputLatency(I)I
 Landroid/media/AudioManager;->getService()Landroid/media/IAudioService;
-Landroid/media/AudioManager;-><init>(Landroid/content/Context;)V
 Landroid/media/AudioManager;->mAudioFocusIdListenerMap:Ljava/util/concurrent/ConcurrentHashMap;
 Landroid/media/AudioManager;->setMasterMute(ZI)V
 Landroid/media/AudioManager;->setRingerModeInternal(I)V
@@ -1120,14 +1336,10 @@
 Landroid/media/AudioManager;->STREAM_BLUETOOTH_SCO:I
 Landroid/media/AudioManager;->STREAM_SYSTEM_ENFORCED:I
 Landroid/media/AudioManager;->STREAM_TTS:I
-Landroid/media/AudioMixPortConfig;-><init>(Landroid/media/AudioMixPort;IIILandroid/media/AudioGainConfig;)V
 Landroid/media/AudioMixPort;-><init>(Landroid/media/AudioHandle;IILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V
+Landroid/media/AudioMixPortConfig;-><init>(Landroid/media/AudioMixPort;IIILandroid/media/AudioGainConfig;)V
 Landroid/media/AudioPatch;-><init>(Landroid/media/AudioHandle;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)V
 Landroid/media/AudioPatch;->mHandle:Landroid/media/AudioHandle;
-Landroid/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion;->mAttr:Landroid/media/AudioAttributes;
-Landroid/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion;->mIntProp:I
-Landroid/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion;->mRule:I
-Landroid/media/audiopolicy/AudioMixingRule;->mCriteria:Ljava/util/ArrayList;
 Landroid/media/audiopolicy/AudioMix;->mCallbackFlags:I
 Landroid/media/audiopolicy/AudioMix;->mDeviceAddress:Ljava/lang/String;
 Landroid/media/audiopolicy/AudioMix;->mDeviceSystemType:I
@@ -1135,6 +1347,15 @@
 Landroid/media/audiopolicy/AudioMix;->mMixType:I
 Landroid/media/audiopolicy/AudioMix;->mRouteFlags:I
 Landroid/media/audiopolicy/AudioMix;->mRule:Landroid/media/audiopolicy/AudioMixingRule;
+Landroid/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion;->mAttr:Landroid/media/AudioAttributes;
+Landroid/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion;->mIntProp:I
+Landroid/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion;->mRule:I
+Landroid/media/audiopolicy/AudioMixingRule;->mCriteria:Ljava/util/ArrayList;
+Landroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V
+Landroid/media/AudioPort;->mActiveConfig:Landroid/media/AudioPortConfig;
+Landroid/media/AudioPort;->mGains:[Landroid/media/AudioGain;
+Landroid/media/AudioPort;->mHandle:Landroid/media/AudioHandle;
+Landroid/media/AudioPort;->mRole:I
 Landroid/media/AudioPortConfig;-><init>(Landroid/media/AudioPort;IIILandroid/media/AudioGainConfig;)V
 Landroid/media/AudioPortConfig;->mChannelMask:I
 Landroid/media/AudioPortConfig;->mConfigMask:I
@@ -1144,18 +1365,13 @@
 Landroid/media/AudioPortConfig;->mSamplingRate:I
 Landroid/media/AudioPortEventHandler;->mJniCallback:J
 Landroid/media/AudioPortEventHandler;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
-Landroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V
-Landroid/media/AudioPort;->mActiveConfig:Landroid/media/AudioPortConfig;
-Landroid/media/AudioPort;->mGains:[Landroid/media/AudioGain;
-Landroid/media/AudioPort;->mHandle:Landroid/media/AudioHandle;
-Landroid/media/AudioPort;->mRole:I
-Landroid/media/AudioRecordingConfiguration;->getClientPackageName()Ljava/lang/String;
-Landroid/media/AudioRecordingConfiguration;->getClientUid()I
 Landroid/media/AudioRecord;->mNativeCallbackCookie:J
 Landroid/media/AudioRecord;->mNativeDeviceCallback:J
 Landroid/media/AudioRecord;->mNativeRecorderInJavaObj:J
 Landroid/media/AudioRecord;->native_release()V
 Landroid/media/AudioRecord;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
+Landroid/media/AudioRecordingConfiguration;->getClientPackageName()Ljava/lang/String;
+Landroid/media/AudioRecordingConfiguration;->getClientUid()I
 Landroid/media/AudioSystem;->dynamicPolicyCallbackFromNative(ILjava/lang/String;I)V
 Landroid/media/AudioSystem;->errorCallbackFromNative(I)V
 Landroid/media/AudioSystem;->getPrimaryOutputFrameCount()I
@@ -1173,14 +1389,15 @@
 Landroid/media/AudioTrack;->native_release()V
 Landroid/media/AudioTrack;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
 Landroid/media/ExifInterface;->getDateTime()J
+Landroid/media/IAudioService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/media/IAudioService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IAudioService;
 Landroid/media/IAudioService;->getStreamMaxVolume(I)I
 Landroid/media/IAudioService;->getStreamVolume(I)I
 Landroid/media/IAudioService;->setStreamVolume(IIILjava/lang/String;)V
-Landroid/media/IAudioService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IAudioService;
-Landroid/media/IAudioService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/media/Image;-><init>()V
-Landroid/media/IMediaScannerService;->scanFile(Ljava/lang/String;Ljava/lang/String;)V
+Landroid/media/IMediaRouterService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IMediaRouterService;
 Landroid/media/IMediaScannerService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IMediaScannerService;
+Landroid/media/IMediaScannerService;->scanFile(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/media/IRemoteDisplayCallback;->onStateChanged(Landroid/media/RemoteDisplayState;)V
 Landroid/media/IVolumeController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IVolumeController;
 Landroid/media/JetPlayer;->mNativePlayerInJavaObj:J
@@ -1188,18 +1405,18 @@
 Landroid/media/MediaCodec$CodecException;-><init>(IILjava/lang/String;)V
 Landroid/media/MediaCodec;->getBuffers(Z)[Ljava/nio/ByteBuffer;
 Landroid/media/MediaCodec;->releaseOutputBuffer(IZZJ)V
-Landroid/media/MediaFile;->FIRST_AUDIO_FILE_TYPE:I
-Landroid/media/MediaFile;->getFileTypeForMimeType(Ljava/lang/String;)I
-Landroid/media/MediaFile;->getFileType(Ljava/lang/String;)Landroid/media/MediaFile$MediaFileType;
-Landroid/media/MediaFile;->getMimeTypeForFile(Ljava/lang/String;)Ljava/lang/String;
+Landroid/media/MediaFile$MediaFileType;->fileType:I
+Landroid/media/MediaFile$MediaFileType;->mimeType:Ljava/lang/String;
 Landroid/media/MediaFile;-><init>()V
+Landroid/media/MediaFile;->FIRST_AUDIO_FILE_TYPE:I
+Landroid/media/MediaFile;->getFileType(Ljava/lang/String;)Landroid/media/MediaFile$MediaFileType;
+Landroid/media/MediaFile;->getFileTypeForMimeType(Ljava/lang/String;)I
+Landroid/media/MediaFile;->getMimeTypeForFile(Ljava/lang/String;)Ljava/lang/String;
 Landroid/media/MediaFile;->isAudioFileType(I)Z
 Landroid/media/MediaFile;->isImageFileType(I)Z
 Landroid/media/MediaFile;->isPlayListFileType(I)Z
 Landroid/media/MediaFile;->isVideoFileType(I)Z
 Landroid/media/MediaFile;->LAST_AUDIO_FILE_TYPE:I
-Landroid/media/MediaFile$MediaFileType;->fileType:I
-Landroid/media/MediaFile$MediaFileType;->mimeType:Ljava/lang/String;
 Landroid/media/MediaFile;->sFileTypeMap:Ljava/util/HashMap;
 Landroid/media/MediaFormat;->getMap()Ljava/util/Map;
 Landroid/media/MediaHTTPService;->createHttpServiceBinderIfNecessary(Ljava/lang/String;)Landroid/os/IBinder;
@@ -1208,9 +1425,9 @@
 Landroid/media/MediaPlayer;->invoke(Landroid/os/Parcel;Landroid/os/Parcel;)V
 Landroid/media/MediaPlayer;->mEventHandler:Landroid/media/MediaPlayer$EventHandler;
 Landroid/media/MediaPlayer;->newRequest()Landroid/os/Parcel;
-Landroid/media/MediaPlayer;->setDataSource(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;Ljava/util/List;)V
-Landroid/media/MediaPlayer;->setDataSource(Ljava/lang/String;Ljava/util/Map;Ljava/util/List;)V
 Landroid/media/MediaPlayer;->setDataSource(Ljava/lang/String;Ljava/util/Map;)V
+Landroid/media/MediaPlayer;->setDataSource(Ljava/lang/String;Ljava/util/Map;Ljava/util/List;)V
+Landroid/media/MediaPlayer;->setDataSource(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;Ljava/util/List;)V
 Landroid/media/MediaPlayer;->setRetransmitEndpoint(Ljava/net/InetSocketAddress;)V
 Landroid/media/MediaRecorder;->setParameter(Ljava/lang/String;)V
 Landroid/media/MediaRouter$RouteInfo;->getStatusCode()I
@@ -1238,15 +1455,17 @@
 Landroid/media/RemoteDisplay;->notifyDisplayConnected(Landroid/view/Surface;IIII)V
 Landroid/media/RemoteDisplay;->notifyDisplayDisconnected()V
 Landroid/media/RemoteDisplay;->notifyDisplayError(I)V
-Landroid/media/RemoteDisplayState;->displays:Ljava/util/ArrayList;
 Landroid/media/RemoteDisplayState;-><init>()V
+Landroid/media/RemoteDisplayState;->displays:Ljava/util/ArrayList;
 Landroid/media/RingtoneManager;->getRingtone(Landroid/content/Context;Landroid/net/Uri;I)Landroid/media/Ringtone;
-Landroid/media/session/MediaSessionLegacyHelper;->getHelper(Landroid/content/Context;)Landroid/media/session/MediaSessionLegacyHelper;
+Landroid/media/session/ISessionManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/session/ISessionManager;
+Landroid/media/session/MediaSession;->getCallingPackage()Ljava/lang/String;
 Landroid/media/session/MediaSession;->mCallback:Landroid/media/session/MediaSession$CallbackMessageHandler;
+Landroid/media/session/MediaSessionLegacyHelper;->getHelper(Landroid/content/Context;)Landroid/media/session/MediaSessionLegacyHelper;
 Landroid/media/soundtrigger/SoundTriggerDetector$EventPayload;->getCaptureSession()Ljava/lang/Integer;
 Landroid/media/soundtrigger/SoundTriggerDetector$EventPayload;->getData()[B
+Landroid/media/soundtrigger/SoundTriggerManager;->isRecognitionActive(Ljava/util/UUID;)Z
 Landroid/media/soundtrigger/SoundTriggerManager;->loadSoundModel(Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;)I
-Landroid/media/soundtrigger/SoundTriggerManager;->startRecognition(Ljava/util/UUID;Landroid/app/PendingIntent;Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;)I
 Landroid/media/soundtrigger/SoundTriggerManager;->startRecognition(Ljava/util/UUID;Landroid/os/Bundle;Landroid/content/ComponentName;Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;)I
 Landroid/media/soundtrigger/SoundTriggerManager;->stopRecognition(Ljava/util/UUID;)I
 Landroid/media/soundtrigger/SoundTriggerManager;->unloadSoundModel(Ljava/util/UUID;)I
@@ -1285,8 +1504,8 @@
 Landroid/net/ConnectivityManager;->isNetworkTypeMobile(I)Z
 Landroid/net/ConnectivityManager;->mService:Landroid/net/IConnectivityManager;
 Landroid/net/ConnectivityManager;->registerNetworkFactory(Landroid/os/Messenger;Ljava/lang/String;)V
-Landroid/net/ConnectivityManager;->requestRouteToHostAddress(ILjava/net/InetAddress;)Z
 Landroid/net/ConnectivityManager;->requestRouteToHost(II)Z
+Landroid/net/ConnectivityManager;->requestRouteToHostAddress(ILjava/net/InetAddress;)Z
 Landroid/net/ConnectivityManager;->setBackgroundDataSetting(Z)V
 Landroid/net/ConnectivityManager;->TYPE_MOBILE_CBS:I
 Landroid/net/ConnectivityManager;->TYPE_MOBILE_EMERGENCY:I
@@ -1297,11 +1516,7 @@
 Landroid/net/ConnectivityManager;->TYPE_PROXY:I
 Landroid/net/ConnectivityManager;->TYPE_WIFI_P2P:I
 Landroid/net/http/SslError;->mCertificate:Landroid/net/http/SslCertificate;
-Landroid/net/IConnectivityManager;->getActiveLinkProperties()Landroid/net/LinkProperties;
-Landroid/net/IConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
-Landroid/net/IConnectivityManager;->getAllNetworkInfo()[Landroid/net/NetworkInfo;
-Landroid/net/IConnectivityManager;->getTetheredIfaces()[Ljava/lang/String;
-Landroid/net/IConnectivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/IConnectivityManager;
+Landroid/net/IConnectivityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/net/IConnectivityManager$Stub$Proxy;->getActiveLinkProperties()Landroid/net/LinkProperties;
 Landroid/net/IConnectivityManager$Stub$Proxy;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
 Landroid/net/IConnectivityManager$Stub$Proxy;->getAllNetworkInfo()[Landroid/net/NetworkInfo;
@@ -1309,9 +1524,16 @@
 Landroid/net/IConnectivityManager$Stub$Proxy;->getTetherableIfaces()[Ljava/lang/String;
 Landroid/net/IConnectivityManager$Stub$Proxy;->getTetherableUsbRegexs()[Ljava/lang/String;
 Landroid/net/IConnectivityManager$Stub$Proxy;->getTetheredIfaces()[Ljava/lang/String;
-Landroid/net/IConnectivityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/net/INetworkStatsService$Stub$Proxy;->getMobileIfaces()[Ljava/lang/String;
+Landroid/net/IConnectivityManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/net/IConnectivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/IConnectivityManager;
+Landroid/net/IConnectivityManager;->getActiveLinkProperties()Landroid/net/LinkProperties;
+Landroid/net/IConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
+Landroid/net/IConnectivityManager;->getAllNetworkInfo()[Landroid/net/NetworkInfo;
+Landroid/net/IConnectivityManager;->getTetheredIfaces()[Ljava/lang/String;
+Landroid/net/INetworkPolicyManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkPolicyManager;
+Landroid/net/INetworkScoreService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkScoreService;
 Landroid/net/INetworkStatsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/net/INetworkStatsService$Stub$Proxy;->getMobileIfaces()[Ljava/lang/String;
 Landroid/net/IpConfiguration;->httpProxy:Landroid/net/ProxyInfo;
 Landroid/net/LinkProperties;->setHttpProxy(Landroid/net/ProxyInfo;)V
 Landroid/net/LocalSocketImpl;->inboundFileDescriptors:[Ljava/io/FileDescriptor;
@@ -1321,7 +1543,6 @@
 Landroid/net/NetworkPolicyManager;->mService:Landroid/net/INetworkPolicyManager;
 Landroid/net/NetworkStats;->capacity:I
 Landroid/net/NetworkStats;->defaultNetwork:[I
-Landroid/net/NetworkStatsHistory$Entry;->rxBytes:J
 Landroid/net/NetworkStats;->iface:[Ljava/lang/String;
 Landroid/net/NetworkStats;->metered:[I
 Landroid/net/NetworkStats;->operations:[J
@@ -1334,15 +1555,16 @@
 Landroid/net/NetworkStats;->txBytes:[J
 Landroid/net/NetworkStats;->txPackets:[J
 Landroid/net/NetworkStats;->uid:[I
+Landroid/net/NetworkStatsHistory$Entry;->rxBytes:J
 Landroid/net/NetworkTemplate;->buildTemplateWifi()Landroid/net/NetworkTemplate;
 Landroid/net/Proxy;->getProxy(Landroid/content/Context;Ljava/lang/String;)Ljava/net/Proxy;
 Landroid/net/ProxyInfo;-><init>(Ljava/lang/String;ILjava/lang/String;)V
 Landroid/net/SntpClient;-><init>()V
+Landroid/net/SSLCertificateSocketFactory;-><init>(ILandroid/net/SSLSessionCache;Z)V
 Landroid/net/SSLCertificateSocketFactory;->castToOpenSSLSocket(Ljava/net/Socket;)Lcom/android/org/conscrypt/OpenSSLSocketImpl;
 Landroid/net/SSLCertificateSocketFactory;->getAlpnSelectedProtocol(Ljava/net/Socket;)[B
 Landroid/net/SSLCertificateSocketFactory;->getDelegate()Ljavax/net/ssl/SSLSocketFactory;
 Landroid/net/SSLCertificateSocketFactory;->getHttpSocketFactory(ILandroid/net/SSLSessionCache;)Lorg/apache/http/conn/ssl/SSLSocketFactory;
-Landroid/net/SSLCertificateSocketFactory;-><init>(ILandroid/net/SSLSessionCache;Z)V
 Landroid/net/SSLCertificateSocketFactory;->INSECURE_TRUST_MANAGER:[Ljavax/net/ssl/TrustManager;
 Landroid/net/SSLCertificateSocketFactory;->isSslCheckRelaxed()Z
 Landroid/net/SSLCertificateSocketFactory;->makeSocketFactory([Ljavax/net/ssl/KeyManager;[Ljavax/net/ssl/TrustManager;)Ljavax/net/ssl/SSLSocketFactory;
@@ -1352,8 +1574,8 @@
 Landroid/net/SSLCertificateSocketFactory;->mInsecureFactory:Ljavax/net/ssl/SSLSocketFactory;
 Landroid/net/SSLCertificateSocketFactory;->mKeyManagers:[Ljavax/net/ssl/KeyManager;
 Landroid/net/SSLCertificateSocketFactory;->mNpnProtocols:[B
-Landroid/net/SSLCertificateSocketFactory;->mSecureFactory:Ljavax/net/ssl/SSLSocketFactory;
 Landroid/net/SSLCertificateSocketFactory;->mSecure:Z
+Landroid/net/SSLCertificateSocketFactory;->mSecureFactory:Ljavax/net/ssl/SSLSocketFactory;
 Landroid/net/SSLCertificateSocketFactory;->mSessionCache:Lcom/android/org/conscrypt/SSLClientSessionCache;
 Landroid/net/SSLCertificateSocketFactory;->mTrustManagers:[Ljavax/net/ssl/TrustManager;
 Landroid/net/SSLCertificateSocketFactory;->setAlpnProtocols([[B)V
@@ -1362,19 +1584,23 @@
 Landroid/net/SSLCertificateSocketFactory;->TAG:Ljava/lang/String;
 Landroid/net/SSLCertificateSocketFactory;->verifyHostname(Ljava/net/Socket;Ljava/lang/String;)V
 Landroid/net/SSLSessionCache;->mSessionCache:Lcom/android/org/conscrypt/SSLClientSessionCache;
-Landroid/net/StaticIpConfiguration;->gateway:Ljava/net/InetAddress;
 Landroid/net/StaticIpConfiguration;-><init>()V
+Landroid/net/StaticIpConfiguration;->gateway:Ljava/net/InetAddress;
 Landroid/net/StaticIpConfiguration;->ipAddress:Landroid/net/LinkAddress;
 Landroid/net/TrafficStats;->getMobileIfaces()[Ljava/lang/String;
 Landroid/net/TrafficStats;->getRxBytes(Ljava/lang/String;)J
 Landroid/net/TrafficStats;->getStatsService()Landroid/net/INetworkStatsService;
 Landroid/net/TrafficStats;->getTxBytes(Ljava/lang/String;)J
 Landroid/net/Uri;-><init>()V
-Landroid/net/wifi/IWifiManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiManager;
 Landroid/net/wifi/IWifiManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/net/wifi/IWifiManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiManager;
+Landroid/net/wifi/IWifiScanner$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/net/wifi/IWifiScanner$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/net/wifi/IWifiScanner$Stub;-><init>()V
+Landroid/net/wifi/IWifiScanner$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiScanner;
 Landroid/net/wifi/p2p/WifiP2pGroup;->getNetworkId()I
-Landroid/net/wifi/p2p/WifiP2pGroupList;->getGroupList()Ljava/util/Collection;
 Landroid/net/wifi/p2p/WifiP2pGroup;->TEMPORARY_NET_ID:I
+Landroid/net/wifi/p2p/WifiP2pGroupList;->getGroupList()Ljava/util/Collection;
 Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mAsyncChannel:Lcom/android/internal/util/AsyncChannel;
 Landroid/net/wifi/p2p/WifiP2pManager$Channel;->putListener(Ljava/lang/Object;)I
 Landroid/net/wifi/p2p/WifiP2pManager;->CREATE_GROUP:I
@@ -1382,12 +1608,6 @@
 Landroid/net/wifi/p2p/WifiP2pManager;->requestPersistentGroupInfo(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Landroid/net/wifi/p2p/WifiP2pManager$PersistentGroupInfoListener;)V
 Landroid/net/wifi/p2p/WifiP2pManager;->setDeviceName(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Ljava/lang/String;Landroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V
 Landroid/net/wifi/p2p/WifiP2pManager;->setWifiP2pChannels(Landroid/net/wifi/p2p/WifiP2pManager$Channel;IILandroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V
-Landroid/net/wifi/ScanResult;->anqpDomainId:I
-Landroid/net/wifi/ScanResult;->anqpLines:Ljava/util/List;
-Landroid/net/wifi/ScanResult;->distanceCm:I
-Landroid/net/wifi/ScanResult;->distanceSdCm:I
-Landroid/net/wifi/ScanResult;->flags:J
-Landroid/net/wifi/ScanResult;->hessid:J
 Landroid/net/wifi/ScanResult$InformationElement;->bytes:[B
 Landroid/net/wifi/ScanResult$InformationElement;->EID_BSS_LOAD:I
 Landroid/net/wifi/ScanResult$InformationElement;->EID_ERP:I
@@ -1403,6 +1623,12 @@
 Landroid/net/wifi/ScanResult$InformationElement;->EID_VHT_OPERATION:I
 Landroid/net/wifi/ScanResult$InformationElement;->EID_VSA:I
 Landroid/net/wifi/ScanResult$InformationElement;->id:I
+Landroid/net/wifi/ScanResult;->anqpDomainId:I
+Landroid/net/wifi/ScanResult;->anqpLines:Ljava/util/List;
+Landroid/net/wifi/ScanResult;->distanceCm:I
+Landroid/net/wifi/ScanResult;->distanceSdCm:I
+Landroid/net/wifi/ScanResult;->flags:J
+Landroid/net/wifi/ScanResult;->hessid:J
 Landroid/net/wifi/ScanResult;->informationElements:[Landroid/net/wifi/ScanResult$InformationElement;
 Landroid/net/wifi/ScanResult;->numUsage:I
 Landroid/net/wifi/ScanResult;->seen:J
@@ -1446,12 +1672,24 @@
 Landroid/os/AsyncTask;->sDefaultExecutor:Ljava/util/concurrent/Executor;
 Landroid/os/AsyncTask;->setDefaultExecutor(Ljava/util/concurrent/Executor;)V
 Landroid/os/BatteryStats$Counter;->getCountLocked(I)I
-Landroid/os/BatteryStats;->getUidStats()Landroid/util/SparseArray;
 Landroid/os/BatteryStats$HistoryItem;->CMD_UPDATE:B
 Landroid/os/BatteryStats$HistoryItem;->states2:I
-Landroid/os/BatteryStats;->NUM_DATA_CONNECTION_TYPES:I
-Landroid/os/BatteryStats;->startIteratingHistoryLocked()Z
 Landroid/os/BatteryStats$Timer;->getTotalTimeLocked(JI)J
+Landroid/os/BatteryStats$Uid$Pkg$Serv;->getLaunches(I)I
+Landroid/os/BatteryStats$Uid$Pkg$Serv;->getStartTime(JI)J
+Landroid/os/BatteryStats$Uid$Pkg;->getServiceStats()Landroid/util/ArrayMap;
+Landroid/os/BatteryStats$Uid$Pkg;->getWakeupAlarmStats()Landroid/util/ArrayMap;
+Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->overTime:J
+Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->type:I
+Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->usedTime:J
+Landroid/os/BatteryStats$Uid$Proc;->countExcessivePowers()I
+Landroid/os/BatteryStats$Uid$Proc;->getExcessivePower(I)Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;
+Landroid/os/BatteryStats$Uid$Proc;->getForegroundTime(I)J
+Landroid/os/BatteryStats$Uid$Proc;->getStarts(I)I
+Landroid/os/BatteryStats$Uid$Proc;->getSystemTime(I)J
+Landroid/os/BatteryStats$Uid$Proc;->getUserTime(I)J
+Landroid/os/BatteryStats$Uid$Sensor;->getHandle()I
+Landroid/os/BatteryStats$Uid$Sensor;->getSensorTime()Landroid/os/BatteryStats$Timer;
 Landroid/os/BatteryStats$Uid;->getAudioTurnedOnTimer()Landroid/os/BatteryStats$Timer;
 Landroid/os/BatteryStats$Uid;->getFullWifiLockTime(JI)J
 Landroid/os/BatteryStats$Uid;->getPackageStats()Landroid/util/ArrayMap;
@@ -1461,31 +1699,17 @@
 Landroid/os/BatteryStats$Uid;->getVideoTurnedOnTimer()Landroid/os/BatteryStats$Timer;
 Landroid/os/BatteryStats$Uid;->getWifiMulticastTime(JI)J
 Landroid/os/BatteryStats$Uid;->getWifiScanTime(JI)J
-Landroid/os/BatteryStats$Uid$Pkg;->getServiceStats()Landroid/util/ArrayMap;
-Landroid/os/BatteryStats$Uid$Pkg;->getWakeupAlarmStats()Landroid/util/ArrayMap;
-Landroid/os/BatteryStats$Uid$Pkg$Serv;->getLaunches(I)I
-Landroid/os/BatteryStats$Uid$Pkg$Serv;->getStartTime(JI)J
-Landroid/os/BatteryStats$Uid$Proc;->countExcessivePowers()I
-Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->overTime:J
-Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->type:I
-Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->usedTime:J
-Landroid/os/BatteryStats$Uid$Proc;->getExcessivePower(I)Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;
-Landroid/os/BatteryStats$Uid$Proc;->getForegroundTime(I)J
-Landroid/os/BatteryStats$Uid$Proc;->getSystemTime(I)J
-Landroid/os/BatteryStats$Uid$Proc;->getUserTime(I)J
-Landroid/os/BatteryStats$Uid$Sensor;->getHandle()I
-Landroid/os/BatteryStats$Uid$Sensor;->getSensorTime()Landroid/os/BatteryStats$Timer;
+Landroid/os/BatteryStats;->getUidStats()Landroid/util/SparseArray;
+Landroid/os/BatteryStats;->NUM_DATA_CONNECTION_TYPES:I
+Landroid/os/BatteryStats;->startIteratingHistoryLocked()Z
 Landroid/os/Binder;->execTransact(IJJI)Z
 Landroid/os/Binder;->mObject:J
+Landroid/os/Build$VERSION;->ACTIVE_CODENAMES:[Ljava/lang/String;
 Landroid/os/Build;->getString(Ljava/lang/String;)Ljava/lang/String;
 Landroid/os/Build;->IS_DEBUGGABLE:Z
 Landroid/os/Build;->IS_EMULATOR:Z
-Landroid/os/Build$VERSION;->ACTIVE_CODENAMES:[Ljava/lang/String;
 Landroid/os/Bundle;->getIBinder(Ljava/lang/String;)Landroid/os/IBinder;
 Landroid/os/Bundle;->putIBinder(Ljava/lang/String;Landroid/os/IBinder;)V
-Landroid/os/Debug;->countInstancesOfClass(Ljava/lang/Class;)J
-Landroid/os/Debug;->dumpReferenceTables()V
-Landroid/os/Debug;-><init>()V
 Landroid/os/Debug$MemoryInfo;->dalvikPrivateClean:I
 Landroid/os/Debug$MemoryInfo;->dalvikRss:I
 Landroid/os/Debug$MemoryInfo;->dalvikSharedClean:I
@@ -1493,8 +1717,8 @@
 Landroid/os/Debug$MemoryInfo;->dalvikSwappedOut:I
 Landroid/os/Debug$MemoryInfo;->dalvikSwappedOutPss:I
 Landroid/os/Debug$MemoryInfo;->getOtherLabel(I)Ljava/lang/String;
-Landroid/os/Debug$MemoryInfo;->getOtherPrivateDirty(I)I
 Landroid/os/Debug$MemoryInfo;->getOtherPrivate(I)I
+Landroid/os/Debug$MemoryInfo;->getOtherPrivateDirty(I)I
 Landroid/os/Debug$MemoryInfo;->getOtherPss(I)I
 Landroid/os/Debug$MemoryInfo;->getOtherSharedDirty(I)I
 Landroid/os/Debug$MemoryInfo;->getTotalUss()I
@@ -1514,6 +1738,10 @@
 Landroid/os/Debug$MemoryInfo;->otherSwappablePss:I
 Landroid/os/Debug$MemoryInfo;->otherSwappedOut:I
 Landroid/os/Debug$MemoryInfo;->otherSwappedOutPss:I
+Landroid/os/Debug;-><init>()V
+Landroid/os/Debug;->countInstancesOfClass(Ljava/lang/Class;)J
+Landroid/os/Debug;->dumpReferenceTables()V
+Landroid/os/DropBoxManager;->mService:Lcom/android/internal/os/IDropBoxManagerService;
 Landroid/os/Environment;->buildExternalStorageAppDataDirs(Ljava/lang/String;)[Ljava/io/File;
 Landroid/os/Environment;->getStorageDirectory()Ljava/io/File;
 Landroid/os/Environment;->getVendorDirectory()Ljava/io/File;
@@ -1524,42 +1752,46 @@
 Landroid/os/FileUtils;->copyToFile(Ljava/io/InputStream;Ljava/io/File;)Z
 Landroid/os/FileUtils;->deleteOlderFiles(Ljava/io/File;IJ)Z
 Landroid/os/FileUtils;->readTextFile(Ljava/io/File;ILjava/lang/String;)Ljava/lang/String;
-Landroid/os/FileUtils;->setPermissions(Ljava/io/FileDescriptor;III)I
 Landroid/os/FileUtils;->setPermissions(Ljava/io/File;III)I
+Landroid/os/FileUtils;->setPermissions(Ljava/io/FileDescriptor;III)I
 Landroid/os/FileUtils;->setPermissions(Ljava/lang/String;III)I
 Landroid/os/FileUtils;->stringToFile(Ljava/io/File;Ljava/lang/String;)V
 Landroid/os/FileUtils;->stringToFile(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/os/FileUtils;->sync(Ljava/io/FileOutputStream;)Z
+Landroid/os/Handler;-><init>(Z)V
 Landroid/os/Handler;->getIMessenger()Landroid/os/IMessenger;
 Landroid/os/Handler;->hasCallbacks(Ljava/lang/Runnable;)Z
-Landroid/os/Handler;-><init>(Z)V
 Landroid/os/Handler;->mCallback:Landroid/os/Handler$Callback;
 Landroid/os/Handler;->mMessenger:Landroid/os/IMessenger;
 Landroid/os/health/HealthKeys$Constants;-><init>(Ljava/lang/Class;)V
 Landroid/os/health/HealthStats;-><init>(Landroid/os/Parcel;)V
-Landroid/os/health/HealthStatsParceler;->getHealthStats()Landroid/os/health/HealthStats;
 Landroid/os/health/HealthStatsParceler;-><init>(Landroid/os/health/HealthStatsWriter;)V
 Landroid/os/health/HealthStatsParceler;-><init>(Landroid/os/Parcel;)V
+Landroid/os/health/HealthStatsParceler;->getHealthStats()Landroid/os/health/HealthStats;
+Landroid/os/health/HealthStatsWriter;-><init>(Landroid/os/health/HealthKeys$Constants;)V
 Landroid/os/health/HealthStatsWriter;->addMeasurement(IJ)V
 Landroid/os/health/HealthStatsWriter;->addMeasurements(ILjava/lang/String;J)V
 Landroid/os/health/HealthStatsWriter;->addStats(ILjava/lang/String;Landroid/os/health/HealthStatsWriter;)V
 Landroid/os/health/HealthStatsWriter;->addTimer(IIJ)V
 Landroid/os/health/HealthStatsWriter;->addTimers(ILjava/lang/String;Landroid/os/health/TimerStat;)V
 Landroid/os/health/HealthStatsWriter;->flattenToParcel(Landroid/os/Parcel;)V
-Landroid/os/health/HealthStatsWriter;-><init>(Landroid/os/health/HealthKeys$Constants;)V
 Landroid/os/health/SystemHealthManager;->from(Landroid/content/Context;)Landroid/os/health/SystemHealthManager;
 Landroid/os/HwParcel;-><init>(Z)V
 Landroid/os/HwRemoteBinder;-><init>()V
 Landroid/os/IBatteryPropertiesRegistrar$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/os/IPermissionController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPermissionController;
 Landroid/os/IPermissionController$Stub$Proxy;->checkPermission(Ljava/lang/String;II)Z
-Landroid/os/IPowerManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPowerManager;
+Landroid/os/IPermissionController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPermissionController;
 Landroid/os/IPowerManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/os/IPowerManager$Stub$Proxy;->isLightDeviceIdleMode()Z
+Landroid/os/IPowerManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPowerManager;
+Landroid/os/IPowerManager;->releaseWakeLock(Landroid/os/IBinder;I)V
 Landroid/os/IPowerManager;->userActivity(JII)V
+Landroid/os/IRecoverySystem$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IRecoverySystem;
 Landroid/os/IServiceManager;->checkService(Ljava/lang/String;)Landroid/os/IBinder;
 Landroid/os/IServiceManager;->getService(Ljava/lang/String;)Landroid/os/IBinder;
 Landroid/os/IUserManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/os/IUserManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IUserManager;
+Landroid/os/IVibratorService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IVibratorService;
 Landroid/os/LocaleList;->setDefault(Landroid/os/LocaleList;I)V
 Landroid/os/Looper;->mQueue:Landroid/os/MessageQueue;
 Landroid/os/Looper;->setTraceTag(J)V
@@ -1569,6 +1801,9 @@
 Landroid/os/Message;->flags:I
 Landroid/os/Message;->markInUse()V
 Landroid/os/Message;->next:Landroid/os/Message;
+Landroid/os/Message;->recycleUnchecked()V
+Landroid/os/Message;->target:Landroid/os/Handler;
+Landroid/os/Message;->when:J
 Landroid/os/MessageQueue;->dispatchEvents(II)I
 Landroid/os/MessageQueue;->mIdleHandlers:Ljava/util/ArrayList;
 Landroid/os/MessageQueue;->mMessages:Landroid/os/Message;
@@ -1578,17 +1813,14 @@
 Landroid/os/MessageQueue;->next()Landroid/os/Message;
 Landroid/os/MessageQueue;->postSyncBarrier()I
 Landroid/os/MessageQueue;->removeSyncBarrier(I)V
-Landroid/os/Message;->recycleUnchecked()V
-Landroid/os/Message;->target:Landroid/os/Handler;
-Landroid/os/Message;->when:J
-Landroid/os/ParcelFileDescriptor;->fromData([BLjava/lang/String;)Landroid/os/ParcelFileDescriptor;
-Landroid/os/ParcelFileDescriptor;-><init>(Ljava/io/FileDescriptor;)V
+Landroid/os/Parcel$ReadWriteHelper;-><init>()V
 Landroid/os/Parcel;->mNativePtr:J
 Landroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;Ljava/lang/ClassLoader;)V
 Landroid/os/Parcel;->readParcelableList(Ljava/util/List;Ljava/lang/ClassLoader;)Ljava/util/List;
-Landroid/os/Parcel$ReadWriteHelper;-><init>()V
 Landroid/os/Parcel;->writeArrayMap(Landroid/util/ArrayMap;)V
 Landroid/os/Parcel;->writeParcelableList(Ljava/util/List;I)V
+Landroid/os/ParcelFileDescriptor;-><init>(Ljava/io/FileDescriptor;)V
+Landroid/os/ParcelFileDescriptor;->fromData([BLjava/lang/String;)Landroid/os/ParcelFileDescriptor;
 Landroid/os/PowerManager;->getDefaultScreenBrightnessSetting()I
 Landroid/os/PowerManager;->getMaximumScreenBrightnessSetting()I
 Landroid/os/PowerManager;->getMinimumScreenBrightnessSetting()I
@@ -1596,8 +1828,9 @@
 Landroid/os/PowerManager;->mService:Landroid/os/IPowerManager;
 Landroid/os/PowerManager;->userActivity(JZ)V
 Landroid/os/PowerManager;->validateWakeLockParameters(ILjava/lang/String;)V
-Landroid/os/PowerManager;->wakeUp(JLjava/lang/String;)V
 Landroid/os/PowerManager;->wakeUp(J)V
+Landroid/os/PowerManager;->wakeUp(JLjava/lang/String;)V
+Landroid/os/Process;->getFreeMemory()J
 Landroid/os/Process;->getParentPid(I)I
 Landroid/os/Process;->getPids(Ljava/lang/String;[I)[I
 Landroid/os/Process;->getTotalMemory()J
@@ -1606,24 +1839,26 @@
 Landroid/os/Process;->readProcFile(Ljava/lang/String;[I[Ljava/lang/String;[J[F)Z
 Landroid/os/Process;->readProcLines(Ljava/lang/String;[Ljava/lang/String;[J)V
 Landroid/os/Process;->setArgV0(Ljava/lang/String;)V
+Landroid/os/SELinux;->checkSELinuxAccess(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
 Landroid/os/SELinux;->getFileContext(Ljava/lang/String;)Ljava/lang/String;
+Landroid/os/SELinux;->getPidContext(I)Ljava/lang/String;
 Landroid/os/SELinux;->isSELinuxEnabled()Z
 Landroid/os/SELinux;->isSELinuxEnforced()Z
+Landroid/os/ServiceManager;-><init>()V
 Landroid/os/ServiceManager;->addService(Ljava/lang/String;Landroid/os/IBinder;)V
 Landroid/os/ServiceManager;->checkService(Ljava/lang/String;)Landroid/os/IBinder;
 Landroid/os/ServiceManager;->getIServiceManager()Landroid/os/IServiceManager;
 Landroid/os/ServiceManager;->getService(Ljava/lang/String;)Landroid/os/IBinder;
-Landroid/os/ServiceManager;-><init>()V
 Landroid/os/ServiceManager;->listServices()[Ljava/lang/String;
-Landroid/os/ServiceManagerNative;->asInterface(Landroid/os/IBinder;)Landroid/os/IServiceManager;
 Landroid/os/ServiceManager;->sCache:Ljava/util/HashMap;
 Landroid/os/ServiceManager;->sServiceManager:Landroid/os/IServiceManager;
+Landroid/os/ServiceManagerNative;->asInterface(Landroid/os/IBinder;)Landroid/os/IServiceManager;
 Landroid/os/SharedMemory;->getFd()I
 Landroid/os/storage/DiskInfo;->getDescription()Ljava/lang/String;
 Landroid/os/storage/DiskInfo;->isSd()Z
 Landroid/os/storage/DiskInfo;->isUsb()Z
-Landroid/os/storage/IStorageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IStorageManager;
 Landroid/os/storage/IStorageManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/os/storage/IStorageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IStorageManager;
 Landroid/os/storage/StorageManager;->findVolumeByUuid(Ljava/lang/String;)Landroid/os/storage/VolumeInfo;
 Landroid/os/storage/StorageManager;->getBestVolumeDescription(Landroid/os/storage/VolumeInfo;)Ljava/lang/String;
 Landroid/os/storage/StorageManager;->getDisks()Ljava/util/List;
@@ -1631,15 +1866,15 @@
 Landroid/os/storage/StorageManager;->getStorageBytesUntilLow(Ljava/io/File;)J
 Landroid/os/storage/StorageManager;->getStorageFullBytes(Ljava/io/File;)J
 Landroid/os/storage/StorageManager;->getStorageLowBytes(Ljava/io/File;)J
-Landroid/os/storage/StorageManager;->getVolumeList(II)[Landroid/os/storage/StorageVolume;
 Landroid/os/storage/StorageManager;->getVolumeList()[Landroid/os/storage/StorageVolume;
+Landroid/os/storage/StorageManager;->getVolumeList(II)[Landroid/os/storage/StorageVolume;
 Landroid/os/storage/StorageManager;->getVolumePaths()[Ljava/lang/String;
 Landroid/os/storage/StorageManager;->getVolumes()Ljava/util/List;
 Landroid/os/storage/StorageManager;->getVolumeState(Ljava/lang/String;)Ljava/lang/String;
 Landroid/os/storage/StorageVolume;->allowMassStorage()Z
 Landroid/os/storage/StorageVolume;->getMaxFileSize()J
-Landroid/os/storage/StorageVolume;->getPathFile()Ljava/io/File;
 Landroid/os/storage/StorageVolume;->getPath()Ljava/lang/String;
+Landroid/os/storage/StorageVolume;->getPathFile()Ljava/io/File;
 Landroid/os/storage/StorageVolume;->getUserLabel()Ljava/lang/String;
 Landroid/os/storage/StorageVolume;->mPath:Ljava/io/File;
 Landroid/os/storage/VolumeInfo;->buildStorageVolume(Landroid/content/Context;IZ)Landroid/os/storage/StorageVolume;
@@ -1653,16 +1888,16 @@
 Landroid/os/storage/VolumeInfo;->isVisible()Z
 Landroid/os/storage/VolumeInfo;->TYPE_EMULATED:I
 Landroid/os/storage/VolumeInfo;->TYPE_PUBLIC:I
+Landroid/os/StrictMode$Span;->finish()V
+Landroid/os/StrictMode$ThreadPolicy$Builder;->penaltyListener(Landroid/os/StrictMode$OnThreadViolationListener;Ljava/util/concurrent/Executor;)Landroid/os/StrictMode$ThreadPolicy$Builder;
 Landroid/os/StrictMode;->conditionallyCheckInstanceCounts()V
 Landroid/os/StrictMode;->disableDeathOnFileUriExposure()V
 Landroid/os/StrictMode;->enterCriticalSpan(Ljava/lang/String;)Landroid/os/StrictMode$Span;
 Landroid/os/StrictMode;->getThreadPolicyMask()I
 Landroid/os/StrictMode;->onBinderStrictModePolicyChange(I)V
-Landroid/os/StrictMode$Span;->finish()V
-Landroid/os/StrictMode$ThreadPolicy$Builder;->penaltyListener(Landroid/os/StrictMode$OnThreadViolationListener;Ljava/util/concurrent/Executor;)Landroid/os/StrictMode$ThreadPolicy$Builder;
 Landroid/os/StrictMode;->violationsBeingTimed:Ljava/lang/ThreadLocal;
-Landroid/os/SystemProperties;->addChangeCallback(Ljava/lang/Runnable;)V
 Landroid/os/SystemProperties;-><init>()V
+Landroid/os/SystemProperties;->addChangeCallback(Ljava/lang/Runnable;)V
 Landroid/os/SystemProperties;->native_get(Ljava/lang/String;)Ljava/lang/String;
 Landroid/os/SystemProperties;->PROP_NAME_MAX:I
 Landroid/os/SystemProperties;->set(Ljava/lang/String;Ljava/lang/String;)V
@@ -1681,6 +1916,7 @@
 Landroid/os/UpdateLock;->release()V
 Landroid/os/UpdateLock;->TIMESTAMP:Ljava/lang/String;
 Landroid/os/UpdateLock;->UPDATE_LOCK_CHANGED:Ljava/lang/String;
+Landroid/os/UserHandle;-><init>(I)V
 Landroid/os/UserHandle;->AID_APP_END:I
 Landroid/os/UserHandle;->AID_APP_START:I
 Landroid/os/UserHandle;->AID_CACHE_GID_START:I
@@ -1694,7 +1930,6 @@
 Landroid/os/UserHandle;->getCallingUserId()I
 Landroid/os/UserHandle;->getUid(II)I
 Landroid/os/UserHandle;->getUserId(I)I
-Landroid/os/UserHandle;-><init>(I)V
 Landroid/os/UserHandle;->MU_ENABLED:Z
 Landroid/os/UserHandle;->OWNER:Landroid/os/UserHandle;
 Landroid/os/UserHandle;->PER_USER_RANGE:I
@@ -1705,21 +1940,22 @@
 Landroid/os/UserHandle;->USER_OWNER:I
 Landroid/os/UserHandle;->USER_SERIAL_SYSTEM:I
 Landroid/os/UserHandle;->USER_SYSTEM:I
-Landroid/os/UserManager;->getBadgedLabelForUser(Ljava/lang/CharSequence;Landroid/os/UserHandle;)Ljava/lang/CharSequence;
 Landroid/os/UserManager;->get(Landroid/content/Context;)Landroid/os/UserManager;
+Landroid/os/UserManager;->getBadgedLabelForUser(Ljava/lang/CharSequence;Landroid/os/UserHandle;)Ljava/lang/CharSequence;
 Landroid/os/UserManager;->getMaxSupportedUsers()I
 Landroid/os/UserManager;->getProfiles(I)Ljava/util/List;
 Landroid/os/UserManager;->getUserHandle()I
 Landroid/os/UserManager;->getUserHandle(I)I
 Landroid/os/UserManager;->getUserIcon(I)Landroid/graphics/Bitmap;
 Landroid/os/UserManager;->getUserInfo(I)Landroid/content/pm/UserInfo;
-Landroid/os/UserManager;->getUserSerialNumber(I)I
 Landroid/os/UserManager;->getUsers()Ljava/util/List;
+Landroid/os/UserManager;->getUserSerialNumber(I)I
 Landroid/os/UserManager;->getUserStartRealtime()J
 Landroid/os/UserManager;->getUserUnlockRealtime()J
 Landroid/os/UserManager;->hasBaseUserRestriction(Ljava/lang/String;Landroid/os/UserHandle;)Z
 Landroid/os/UserManager;->isLinkedUser()Z
 Landroid/os/UserManager;->isUserUnlocked(I)Z
+Landroid/os/UserManager;->mService:Landroid/os/IUserManager;
 Landroid/os/VintfObject;->getHalNamesAndVersions()[Ljava/lang/String;
 Landroid/os/VintfObject;->getSepolicyVersion()Ljava/lang/String;
 Landroid/os/VintfObject;->getTargetFrameworkCompatibilityMatrixVersion()Ljava/lang/Long;
@@ -1732,12 +1968,12 @@
 Landroid/os/VintfRuntimeInfo;->getOsName()Ljava/lang/String;
 Landroid/os/VintfRuntimeInfo;->getOsRelease()Ljava/lang/String;
 Landroid/os/VintfRuntimeInfo;->getOsVersion()Ljava/lang/String;
-Landroid/os/WorkSource;->add(ILjava/lang/String;)Z
+Landroid/os/WorkSource;-><init>(I)V
 Landroid/os/WorkSource;->add(I)Z
+Landroid/os/WorkSource;->add(ILjava/lang/String;)Z
 Landroid/os/WorkSource;->addReturningNewbs(Landroid/os/WorkSource;)Landroid/os/WorkSource;
 Landroid/os/WorkSource;->get(I)I
 Landroid/os/WorkSource;->getName(I)Ljava/lang/String;
-Landroid/os/WorkSource;-><init>(I)V
 Landroid/os/WorkSource;->mNames:[Ljava/lang/String;
 Landroid/os/WorkSource;->mNum:I
 Landroid/os/WorkSource;->mUids:[I
@@ -1745,16 +1981,20 @@
 Landroid/os/WorkSource;->size()I
 Landroid/permissionpresenterservice/RuntimePermissionPresenterService;->onRevokeRuntimePermission(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/preference/DialogPreference;->mBuilder:Landroid/app/AlertDialog$Builder;
-Landroid/preference/DialogPreference;->mDialogIcon:Landroid/graphics/drawable/Drawable;
 Landroid/preference/DialogPreference;->mDialog:Landroid/app/Dialog;
+Landroid/preference/DialogPreference;->mDialogIcon:Landroid/graphics/drawable/Drawable;
 Landroid/preference/DialogPreference;->mDialogMessage:Ljava/lang/CharSequence;
 Landroid/preference/DialogPreference;->mDialogTitle:Ljava/lang/CharSequence;
 Landroid/preference/DialogPreference;->mNegativeButtonText:Ljava/lang/CharSequence;
 Landroid/preference/DialogPreference;->mPositiveButtonText:Ljava/lang/CharSequence;
 Landroid/preference/DialogPreference;->mWhichButtonClicked:I
 Landroid/preference/ListPreference;->mClickedDialogEntryIndex:I
+Landroid/preference/Preference;->onKey(Landroid/view/View;ILandroid/view/KeyEvent;)Z
+Landroid/preference/Preference;->performClick(Landroid/preference/PreferenceScreen;)V
 Landroid/preference/PreferenceActivity;->mPreferenceManager:Landroid/preference/PreferenceManager;
 Landroid/preference/PreferenceActivity;->mPrefsContainer:Landroid/view/ViewGroup;
+Landroid/preference/PreferenceManager;-><init>(Landroid/app/Activity;I)V
+Landroid/preference/PreferenceManager;-><init>(Landroid/content/Context;)V
 Landroid/preference/PreferenceManager;->dispatchActivityDestroy()V
 Landroid/preference/PreferenceManager;->dispatchActivityResult(IILandroid/content/Intent;)V
 Landroid/preference/PreferenceManager;->dispatchActivityStop()V
@@ -1762,8 +2002,6 @@
 Landroid/preference/PreferenceManager;->getPreferenceScreen()Landroid/preference/PreferenceScreen;
 Landroid/preference/PreferenceManager;->inflateFromIntent(Landroid/content/Intent;Landroid/preference/PreferenceScreen;)Landroid/preference/PreferenceScreen;
 Landroid/preference/PreferenceManager;->inflateFromResource(Landroid/content/Context;ILandroid/preference/PreferenceScreen;)Landroid/preference/PreferenceScreen;
-Landroid/preference/PreferenceManager;-><init>(Landroid/app/Activity;I)V
-Landroid/preference/PreferenceManager;-><init>(Landroid/content/Context;)V
 Landroid/preference/PreferenceManager;->mActivityDestroyListeners:Ljava/util/List;
 Landroid/preference/PreferenceManager;->mOnPreferenceTreeClickListener:Landroid/preference/PreferenceManager$OnPreferenceTreeClickListener;
 Landroid/preference/PreferenceManager;->mSharedPreferences:Landroid/content/SharedPreferences;
@@ -1774,8 +2012,6 @@
 Landroid/preference/PreferenceManager;->shouldCommit()Z
 Landroid/preference/PreferenceManager;->unregisterOnActivityDestroyListener(Landroid/preference/PreferenceManager$OnActivityDestroyListener;)V
 Landroid/preference/PreferenceManager;->unregisterOnActivityStopListener(Landroid/preference/PreferenceManager$OnActivityStopListener;)V
-Landroid/preference/Preference;->onKey(Landroid/view/View;ILandroid/view/KeyEvent;)Z
-Landroid/preference/Preference;->performClick(Landroid/preference/PreferenceScreen;)V
 Landroid/preference/PreferenceScreen;->mRootAdapter:Landroid/widget/ListAdapter;
 Landroid/print/PrinterId;->getServiceName()Landroid/content/ComponentName;
 Landroid/print/PrintJobInfo;->getAdvancedOptions()Landroid/os/Bundle;
@@ -1793,13 +2029,32 @@
 Landroid/provider/Browser;->updateVisitedHistory(Landroid/content/ContentResolver;Ljava/lang/String;Z)V
 Landroid/provider/CalendarContract$CalendarAlerts;->findNextAlarmTime(Landroid/content/ContentResolver;J)J
 Landroid/provider/CalendarContract$CalendarAlerts;->rescheduleMissedAlarms(Landroid/content/ContentResolver;Landroid/content/Context;Landroid/app/AlarmManager;)V
+Landroid/provider/Downloads$Impl$RequestHeaders;->INSERT_KEY_PREFIX:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_ALLOWED_NETWORK_TYPES:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_ALLOW_ROAMING:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_COOKIE_DATA:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_DELETED:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_DESCRIPTION:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_DESTINATION:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_FILE_NAME_HINT:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_IS_PUBLIC_API:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_MEDIA_SCANNED:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_MIME_TYPE:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_NOTIFICATION_CLASS:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_NOTIFICATION_EXTRAS:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_NOTIFICATION_PACKAGE:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_REFERER:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_TITLE:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_URI:Ljava/lang/String;
+Landroid/provider/Downloads$Impl;->COLUMN_VISIBILITY:Ljava/lang/String;
 Landroid/provider/Downloads$Impl;->CONTENT_URI:Landroid/net/Uri;
+Landroid/provider/Downloads$Impl;->DESTINATION_CACHE_PARTITION_PURGEABLE:I
+Landroid/provider/Downloads$Impl;->DESTINATION_FILE_URI:I
 Landroid/provider/Settings$ContentProviderHolder;->mContentProvider:Landroid/content/IContentProvider;
 Landroid/provider/Settings$Global;->ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED:Ljava/lang/String;
 Landroid/provider/Settings$Global;->PACKAGE_VERIFIER_ENABLE:Ljava/lang/String;
 Landroid/provider/Settings$Global;->sNameValueCache:Landroid/provider/Settings$NameValueCache;
-Landroid/provider/Settings;->isCallingPackageAllowedToDrawOverlays(Landroid/content/Context;ILjava/lang/String;Z)Z
-Landroid/provider/Settings;->isCallingPackageAllowedToWriteSettings(Landroid/content/Context;ILjava/lang/String;Z)Z
 Landroid/provider/Settings$NameValueCache;->mProviderHolder:Landroid/provider/Settings$ContentProviderHolder;
 Landroid/provider/Settings$Secure;->ACCESSIBILITY_AUTOCLICK_ENABLED:Ljava/lang/String;
 Landroid/provider/Settings$Secure;->ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED:Ljava/lang/String;
@@ -1818,28 +2073,26 @@
 Landroid/provider/Settings$System;->SCREEN_AUTO_BRIGHTNESS_ADJ:Ljava/lang/String;
 Landroid/provider/Settings$System;->sNameValueCache:Landroid/provider/Settings$NameValueCache;
 Landroid/provider/Settings$System;->VOLUME_SETTINGS:[Ljava/lang/String;
-Landroid/provider/Telephony$Sms;->addMessageToUri(ILandroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;ZZJ)Landroid/net/Uri;
-Landroid/provider/Telephony$Sms;->addMessageToUri(ILandroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;ZZ)Landroid/net/Uri;
-Landroid/provider/Telephony$Sms;->addMessageToUri(Landroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;ZZJ)Landroid/net/Uri;
-Landroid/provider/Telephony$Sms;->addMessageToUri(Landroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;ZZ)Landroid/net/Uri;
+Landroid/provider/Settings;->isCallingPackageAllowedToDrawOverlays(Landroid/content/Context;ILjava/lang/String;Z)Z
+Landroid/provider/Settings;->isCallingPackageAllowedToWriteSettings(Landroid/content/Context;ILjava/lang/String;Z)Z
 Landroid/provider/Telephony$Sms$Inbox;->addMessage(ILandroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Z)Landroid/net/Uri;
 Landroid/provider/Telephony$Sms$Inbox;->addMessage(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Z)Landroid/net/Uri;
 Landroid/provider/Telephony$Sms$Sent;->addMessage(ILandroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;)Landroid/net/Uri;
 Landroid/provider/Telephony$Sms$Sent;->addMessage(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;)Landroid/net/Uri;
-Landroid/renderscript/RenderScriptCacheDir;->mCacheDir:Ljava/io/File;
-Landroid/renderscript/RenderScript;->create(Landroid/content/Context;I)Landroid/renderscript/RenderScript;
-Landroid/renderscript/RenderScript;->create(Landroid/content/Context;ILandroid/renderscript/RenderScript$ContextType;I)Landroid/renderscript/RenderScript;
-Landroid/renderscript/RenderScript;->getMinorID()J
+Landroid/provider/Telephony$Sms;->addMessageToUri(ILandroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;ZZ)Landroid/net/Uri;
+Landroid/provider/Telephony$Sms;->addMessageToUri(ILandroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;ZZJ)Landroid/net/Uri;
+Landroid/provider/Telephony$Sms;->addMessageToUri(Landroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;ZZ)Landroid/net/Uri;
+Landroid/provider/Telephony$Sms;->addMessageToUri(Landroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;ZZJ)Landroid/net/Uri;
+Landroid/R$styleable;->ActionBar:[I
 Landroid/R$styleable;->ActionBar_background:I
 Landroid/R$styleable;->ActionBar_backgroundSplit:I
 Landroid/R$styleable;->ActionBar_backgroundStacked:I
 Landroid/R$styleable;->ActionBar_divider:I
-Landroid/R$styleable;->ActionBar:[I
 Landroid/R$styleable;->ActionBar_itemPadding:I
+Landroid/R$styleable;->CalendarView:[I
 Landroid/R$styleable;->CalendarView_dateTextAppearance:I
 Landroid/R$styleable;->CalendarView_firstDayOfWeek:I
 Landroid/R$styleable;->CalendarView_focusedMonthDateColor:I
-Landroid/R$styleable;->CalendarView:[I
 Landroid/R$styleable;->CalendarView_selectedDateVerticalBar:I
 Landroid/R$styleable;->CalendarView_selectedWeekBackgroundColor:I
 Landroid/R$styleable;->CalendarView_shownWeekCount:I
@@ -1848,26 +2101,27 @@
 Landroid/R$styleable;->CalendarView_weekDayTextAppearance:I
 Landroid/R$styleable;->CalendarView_weekNumberColor:I
 Landroid/R$styleable;->CalendarView_weekSeparatorLineColor:I
-Landroid/R$styleable;->CheckedTextView_checkMark:I
 Landroid/R$styleable;->CheckedTextView:[I
-Landroid/R$styleable;->CompoundButton_button:I
+Landroid/R$styleable;->CheckedTextView_checkMark:I
 Landroid/R$styleable;->CompoundButton:[I
+Landroid/R$styleable;->CompoundButton_button:I
+Landroid/R$styleable;->DrawableStates:[I
+Landroid/R$styleable;->ImageView:[I
 Landroid/R$styleable;->ImageView_adjustViewBounds:I
 Landroid/R$styleable;->ImageView_baselineAlignBottom:I
 Landroid/R$styleable;->ImageView_cropToPadding:I
-Landroid/R$styleable;->ImageView:[I
 Landroid/R$styleable;->ImageView_maxHeight:I
 Landroid/R$styleable;->ImageView_maxWidth:I
 Landroid/R$styleable;->ImageView_scaleType:I
 Landroid/R$styleable;->ImageView_src:I
 Landroid/R$styleable;->ImageView_tint:I
+Landroid/R$styleable;->LinearLayout:[I
 Landroid/R$styleable;->LinearLayout_divider:I
 Landroid/R$styleable;->LinearLayout_dividerPadding:I
-Landroid/R$styleable;->LinearLayout:[I
 Landroid/R$styleable;->LinearLayout_showDividers:I
-Landroid/R$styleable;->ListView_dividerHeight:I
-Landroid/R$styleable;->ListView_divider:I
 Landroid/R$styleable;->ListView:[I
+Landroid/R$styleable;->ListView_divider:I
+Landroid/R$styleable;->ListView_dividerHeight:I
 Landroid/R$styleable;->ProgressBar:[I
 Landroid/R$styleable;->ProgressBar_indeterminateDrawable:I
 Landroid/R$styleable;->ProgressBar_indeterminateDuration:I
@@ -1892,13 +2146,14 @@
 Landroid/R$styleable;->Switch_track:I
 Landroid/R$styleable;->TextAppearance:[I
 Landroid/R$styleable;->TextAppearance_textAllCaps:I
+Landroid/R$styleable;->TextAppearance_textColor:I
 Landroid/R$styleable;->TextAppearance_textColorHighlight:I
 Landroid/R$styleable;->TextAppearance_textColorHint:I
-Landroid/R$styleable;->TextAppearance_textColor:I
 Landroid/R$styleable;->TextAppearance_textColorLink:I
 Landroid/R$styleable;->TextAppearance_textSize:I
 Landroid/R$styleable;->TextAppearance_textStyle:I
 Landroid/R$styleable;->TextAppearance_typeface:I
+Landroid/R$styleable;->TextView:[I
 Landroid/R$styleable;->TextView_autoLink:I
 Landroid/R$styleable;->TextView_autoText:I
 Landroid/R$styleable;->TextView_bufferType:I
@@ -1920,7 +2175,6 @@
 Landroid/R$styleable;->TextView_gravity:I
 Landroid/R$styleable;->TextView_height:I
 Landroid/R$styleable;->TextView_hint:I
-Landroid/R$styleable;->TextView:[I
 Landroid/R$styleable;->TextView_imeActionId:I
 Landroid/R$styleable;->TextView_imeActionLabel:I
 Landroid/R$styleable;->TextView_imeOptions:I
@@ -1952,14 +2206,14 @@
 Landroid/R$styleable;->TextView_shadowDy:I
 Landroid/R$styleable;->TextView_shadowRadius:I
 Landroid/R$styleable;->TextView_singleLine:I
+Landroid/R$styleable;->TextView_text:I
 Landroid/R$styleable;->TextView_textAllCaps:I
 Landroid/R$styleable;->TextView_textAppearance:I
+Landroid/R$styleable;->TextView_textColor:I
 Landroid/R$styleable;->TextView_textColorHighlight:I
 Landroid/R$styleable;->TextView_textColorHint:I
-Landroid/R$styleable;->TextView_textColor:I
 Landroid/R$styleable;->TextView_textColorLink:I
 Landroid/R$styleable;->TextView_textCursorDrawable:I
-Landroid/R$styleable;->TextView_text:I
 Landroid/R$styleable;->TextView_textIsSelectable:I
 Landroid/R$styleable;->TextView_textScaleX:I
 Landroid/R$styleable;->TextView_textSelectHandle:I
@@ -1969,10 +2223,13 @@
 Landroid/R$styleable;->TextView_textStyle:I
 Landroid/R$styleable;->TextView_typeface:I
 Landroid/R$styleable;->TextView_width:I
+Landroid/R$styleable;->View:[I
+Landroid/R$styleable;->ViewDrawableStates:[I
+Landroid/R$styleable;->ViewGroup_Layout:[I
+Landroid/R$styleable;->ViewGroup_MarginLayout:[I
 Landroid/R$styleable;->View_background:I
 Landroid/R$styleable;->View_clickable:I
 Landroid/R$styleable;->View_contentDescription:I
-Landroid/R$styleable;->ViewDrawableStates:[I
 Landroid/R$styleable;->View_drawingCacheQuality:I
 Landroid/R$styleable;->View_duplicateParentState:I
 Landroid/R$styleable;->View_fadingEdge:I
@@ -1980,10 +2237,7 @@
 Landroid/R$styleable;->View_fitsSystemWindows:I
 Landroid/R$styleable;->View_focusable:I
 Landroid/R$styleable;->View_focusableInTouchMode:I
-Landroid/R$styleable;->ViewGroup_Layout:[I
-Landroid/R$styleable;->ViewGroup_MarginLayout:[I
 Landroid/R$styleable;->View_hapticFeedbackEnabled:I
-Landroid/R$styleable;->View:[I
 Landroid/R$styleable;->View_id:I
 Landroid/R$styleable;->View_isScrollContainer:I
 Landroid/R$styleable;->View_keepScreenOn:I
@@ -1996,9 +2250,9 @@
 Landroid/R$styleable;->View_nextFocusUp:I
 Landroid/R$styleable;->View_onClick:I
 Landroid/R$styleable;->View_overScrollMode:I
+Landroid/R$styleable;->View_padding:I
 Landroid/R$styleable;->View_paddingBottom:I
 Landroid/R$styleable;->View_paddingEnd:I
-Landroid/R$styleable;->View_padding:I
 Landroid/R$styleable;->View_paddingLeft:I
 Landroid/R$styleable;->View_paddingRight:I
 Landroid/R$styleable;->View_paddingStart:I
@@ -2021,26 +2275,37 @@
 Landroid/R$styleable;->Window:[I
 Landroid/R$styleable;->Window_windowBackground:I
 Landroid/R$styleable;->Window_windowFrame:I
+Landroid/renderscript/RenderScript;->create(Landroid/content/Context;I)Landroid/renderscript/RenderScript;
+Landroid/renderscript/RenderScript;->create(Landroid/content/Context;ILandroid/renderscript/RenderScript$ContextType;I)Landroid/renderscript/RenderScript;
+Landroid/renderscript/RenderScript;->getMinorID()J
+Landroid/renderscript/RenderScriptCacheDir;->mCacheDir:Ljava/io/File;
+Landroid/renderscript/RenderScriptCacheDir;->setupDiskCache(Ljava/io/File;)V
 Landroid/security/keystore/AndroidKeyStoreProvider;->getKeyStoreOperationHandle(Ljava/lang/Object;)J
-Landroid/security/KeyStore;->getInstance()Landroid/security/KeyStore;
+Landroid/security/keystore/recovery/RecoveryController;->getRecoveryStatus(Ljava/lang/String;Ljava/lang/String;)I
 Landroid/security/keystore/recovery/RecoveryController;->initRecoveryService(Ljava/lang/String;[B)V
+Landroid/security/KeyStore;->getInstance()Landroid/security/KeyStore;
 Landroid/security/net/config/RootTrustManager;->checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List;
-Landroid/service/media/IMediaBrowserServiceCallbacks;->onConnectFailed()V
+Landroid/service/media/IMediaBrowserServiceCallbacks$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/media/IMediaBrowserServiceCallbacks;
 Landroid/service/media/IMediaBrowserServiceCallbacks;->onConnect(Ljava/lang/String;Landroid/media/session/MediaSession$Token;Landroid/os/Bundle;)V
+Landroid/service/media/IMediaBrowserServiceCallbacks;->onConnectFailed()V
 Landroid/service/media/IMediaBrowserServiceCallbacks;->onLoadChildren(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;)V
 Landroid/service/media/IMediaBrowserServiceCallbacks;->onLoadChildrenWithOptions(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;Landroid/os/Bundle;)V
-Landroid/service/media/IMediaBrowserServiceCallbacks$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/media/IMediaBrowserServiceCallbacks;
-Landroid/service/media/MediaBrowserService;->KEY_MEDIA_ITEM:Ljava/lang/String;
 Landroid/service/media/MediaBrowserService$Result;->mFlags:I
+Landroid/service/media/MediaBrowserService;->KEY_MEDIA_ITEM:Ljava/lang/String;
+Landroid/service/notification/NotificationListenerService;->isBound()Z
+Landroid/service/notification/NotificationListenerService;->mHandler:Landroid/os/Handler;
 Landroid/service/notification/NotificationListenerService;->registerAsSystemService(Landroid/content/Context;Landroid/content/ComponentName;I)V
 Landroid/service/notification/NotificationListenerService;->unregisterAsSystemService()V
+Landroid/service/notification/StatusBarNotification;->getInitialPid()I
 Landroid/service/notification/StatusBarNotification;->getUid()I
+Landroid/service/persistentdata/IPersistentDataBlockService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/persistentdata/IPersistentDataBlockService;
 Landroid/service/voice/AlwaysOnHotwordDetector$EventPayload;->getCaptureSession()Ljava/lang/Integer;
 Landroid/service/voice/VoiceInteractionService;->isKeyphraseAndLocaleSupportedForHotword(Ljava/lang/String;Ljava/util/Locale;)Z
 Landroid/service/vr/IVrManager;->getVr2dDisplayId()I
 Landroid/service/wallpaper/WallpaperService$Engine;->setFixedSizeAllowed(Z)V
 Landroid/speech/tts/TextToSpeech;->getCurrentEngine()Ljava/lang/String;
 Landroid/system/Int32Ref;->value:I
+Landroid/system/OsConstants;-><init>()V
 Landroid/system/OsConstants;->AF_NETLINK:I
 Landroid/system/OsConstants;->AF_PACKET:I
 Landroid/system/OsConstants;->ARPHRD_ETHER:I
@@ -2058,10 +2323,8 @@
 Landroid/system/OsConstants;->ICMP_ECHO:I
 Landroid/system/OsConstants;->ICMP_ECHOREPLY:I
 Landroid/system/OsConstants;->initConstants()V
-Landroid/system/OsConstants;-><init>()V
 Landroid/system/OsConstants;->IP_MULTICAST_ALL:I
 Landroid/system/OsConstants;->IP_RECVTOS:I
-Landroid/system/OsConstants;->_LINUX_CAPABILITY_VERSION_3:I
 Landroid/system/OsConstants;->MAP_POPULATE:I
 Landroid/system/OsConstants;->NETLINK_NETFILTER:I
 Landroid/system/OsConstants;->NETLINK_ROUTE:I
@@ -2089,12 +2352,13 @@
 Landroid/system/OsConstants;->SPLICE_F_MOVE:I
 Landroid/system/OsConstants;->SPLICE_F_NONBLOCK:I
 Landroid/system/OsConstants;->TIOCOUTQ:I
+Landroid/system/OsConstants;->UDP_ENCAP:I
 Landroid/system/OsConstants;->UDP_ENCAP_ESPINUDP:I
 Landroid/system/OsConstants;->UDP_ENCAP_ESPINUDP_NON_IKE:I
-Landroid/system/OsConstants;->UDP_ENCAP:I
 Landroid/system/OsConstants;->UNIX_PATH_MAX:I
 Landroid/system/OsConstants;->XATTR_CREATE:I
 Landroid/system/OsConstants;->XATTR_REPLACE:I
+Landroid/system/OsConstants;->_LINUX_CAPABILITY_VERSION_3:I
 Landroid/system/StructTimeval;->fromMillis(J)Landroid/system/StructTimeval;
 Landroid/telecom/AudioState;->isMuted:Z
 Landroid/telecom/TelecomManager;->EXTRA_IS_HANDOVER:Ljava/lang/String;
@@ -2105,20 +2369,23 @@
 Landroid/telephony/CellSignalStrengthLte;->mRsrq:I
 Landroid/telephony/CellSignalStrengthLte;->mRssnr:I
 Landroid/telephony/CellSignalStrengthLte;->mSignalStrength:I
+Landroid/telephony/CellSignalStrengthLte;->mTimingAdvance:I
 Landroid/telephony/CellSignalStrengthWcdma;->mBitErrorRate:I
 Landroid/telephony/CellSignalStrengthWcdma;->mSignalStrength:I
 Landroid/telephony/PhoneNumberUtils;->isLocalEmergencyNumber(Landroid/content/Context;ILjava/lang/String;)Z
 Landroid/telephony/PhoneStateListener;->mSubId:Ljava/lang/Integer;
 Landroid/telephony/ServiceState;->newFromBundle(Landroid/os/Bundle;)Landroid/telephony/ServiceState;
+Landroid/telephony/SignalStrength;-><init>()V
 Landroid/telephony/SignalStrength;->getAsuLevel()I
 Landroid/telephony/SignalStrength;->getCdmaLevel()I
 Landroid/telephony/SignalStrength;->getDbm()I
+Landroid/telephony/SignalStrength;->getGsmDbm()I
+Landroid/telephony/SignalStrength;->getLteCqi()I
 Landroid/telephony/SignalStrength;->getLteDbm()I
 Landroid/telephony/SignalStrength;->getLteRsrp()I
 Landroid/telephony/SignalStrength;->getLteRsrq()I
 Landroid/telephony/SignalStrength;->getLteRssnr()I
 Landroid/telephony/SignalStrength;->getLteSignalStrength()I
-Landroid/telephony/SignalStrength;-><init>()V
 Landroid/telephony/SignalStrength;->mGsmBitErrorRate:I
 Landroid/telephony/SignalStrength;->mGsmSignalStrength:I
 Landroid/telephony/SignalStrength;->mLteCqi:I
@@ -2147,6 +2414,8 @@
 Landroid/telephony/SubscriptionManager;->getSubId(I)[I
 Landroid/telephony/SubscriptionManager;->setDefaultDataSubId(I)V
 Landroid/telephony/SubscriptionManager;->setDefaultSmsSubId(I)V
+Landroid/telephony/TelephonyManager;-><init>()V
+Landroid/telephony/TelephonyManager;-><init>(Landroid/content/Context;)V
 Landroid/telephony/TelephonyManager;->from(Landroid/content/Context;)Landroid/telephony/TelephonyManager;
 Landroid/telephony/TelephonyManager;->getCallState(I)I
 Landroid/telephony/TelephonyManager;->getDataNetworkType(I)I
@@ -2157,27 +2426,26 @@
 Landroid/telephony/TelephonyManager;->getMultiSimConfiguration()Landroid/telephony/TelephonyManager$MultiSimVariants;
 Landroid/telephony/TelephonyManager;->getNetworkClass(I)I
 Landroid/telephony/TelephonyManager;->getNetworkCountryIso(I)Ljava/lang/String;
-Landroid/telephony/TelephonyManager;->getNetworkOperatorForPhone(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getNetworkOperator(I)Ljava/lang/String;
+Landroid/telephony/TelephonyManager;->getNetworkOperatorForPhone(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getNetworkOperatorName(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getNetworkType(I)I
 Landroid/telephony/TelephonyManager;->getNetworkTypeName(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getPhoneType(I)I
 Landroid/telephony/TelephonyManager;->getSimCount()I
 Landroid/telephony/TelephonyManager;->getSimOperator(I)Ljava/lang/String;
-Landroid/telephony/TelephonyManager;->getSimOperatorNameForPhone(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getSimOperatorName(I)Ljava/lang/String;
-Landroid/telephony/TelephonyManager;->getSimOperatorNumericForPhone(I)Ljava/lang/String;
+Landroid/telephony/TelephonyManager;->getSimOperatorNameForPhone(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getSimOperatorNumeric(I)Ljava/lang/String;
+Landroid/telephony/TelephonyManager;->getSimOperatorNumericForPhone(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getSimSerialNumber(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getSubIdForPhoneAccount(Landroid/telecom/PhoneAccount;)I
 Landroid/telephony/TelephonyManager;->getSubscriberId(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getSubscriberInfo()Lcom/android/internal/telephony/IPhoneSubInfo;
 Landroid/telephony/TelephonyManager;->hasIccCard(I)Z
-Landroid/telephony/TelephonyManager;-><init>(Landroid/content/Context;)V
-Landroid/telephony/TelephonyManager;-><init>()V
 Landroid/telephony/TelephonyManager;->isMultiSimEnabled()Z
 Landroid/telephony/TelephonyManager;->isNetworkRoaming(I)Z
+Landroid/telephony/TelephonyManager;->isVideoTelephonyAvailable()Z
 Landroid/telephony/TelephonyManager;->isVolteAvailable()Z
 Landroid/telephony/TelephonyManager;->isWifiCallingAvailable()Z
 Landroid/telephony/TelephonyManager;->mSubscriptionManager:Landroid/telephony/SubscriptionManager;
@@ -2198,6 +2466,7 @@
 Landroid/text/SpannableStringBuilder;->mSpanFlags:[I
 Landroid/text/SpannableStringBuilder;->mSpans:[Ljava/lang/Object;
 Landroid/text/SpannableStringBuilder;->mSpanStarts:[I
+Landroid/text/SpannableStringInternal;-><init>(Ljava/lang/CharSequence;II)V
 Landroid/text/SpannableStringInternal;->charAt(I)C
 Landroid/text/SpannableStringInternal;->checkRange(Ljava/lang/String;II)V
 Landroid/text/SpannableStringInternal;->COLUMNS:I
@@ -2211,7 +2480,6 @@
 Landroid/text/SpannableStringInternal;->getSpanFlags(Ljava/lang/Object;)I
 Landroid/text/SpannableStringInternal;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;
 Landroid/text/SpannableStringInternal;->getSpanStart(Ljava/lang/Object;)I
-Landroid/text/SpannableStringInternal;-><init>(Ljava/lang/CharSequence;II)V
 Landroid/text/SpannableStringInternal;->isIndexFollowsNextLine(I)Z
 Landroid/text/SpannableStringInternal;->isOutOfCopyRange(IIII)Z
 Landroid/text/SpannableStringInternal;->length()I
@@ -2229,13 +2497,13 @@
 Landroid/text/SpannableStringInternal;->setSpan(Ljava/lang/Object;IIIZ)V
 Landroid/text/SpannableStringInternal;->START:I
 Landroid/text/SpanSet;->spans:[Ljava/lang/Object;
-Landroid/text/StaticLayout;->getHeight(Z)I
-Landroid/text/StaticLayout;-><init>(Ljava/lang/CharSequence;IILandroid/text/TextPaint;ILandroid/text/Layout$Alignment;Landroid/text/TextDirectionHeuristic;FFZLandroid/text/TextUtils$TruncateAt;II)V
 Landroid/text/StaticLayout$LineBreaks;->ascents:[F
 Landroid/text/StaticLayout$LineBreaks;->breaks:[I
 Landroid/text/StaticLayout$LineBreaks;->descents:[F
 Landroid/text/StaticLayout$LineBreaks;->flags:[I
 Landroid/text/StaticLayout$LineBreaks;->widths:[F
+Landroid/text/StaticLayout;-><init>(Ljava/lang/CharSequence;IILandroid/text/TextPaint;ILandroid/text/Layout$Alignment;Landroid/text/TextDirectionHeuristic;FFZLandroid/text/TextUtils$TruncateAt;II)V
+Landroid/text/StaticLayout;->getHeight(Z)I
 Landroid/text/StaticLayout;->mColumns:I
 Landroid/text/StaticLayout;->mLineCount:I
 Landroid/text/StaticLayout;->mLines:[I
@@ -2259,6 +2527,7 @@
 Landroid/util/ArrayMap;->mBaseCacheSize:I
 Landroid/util/ArrayMap;->mTwiceBaseCacheSize:I
 Landroid/util/ArraySet;-><init>(Ljava/util/Collection;)V
+Landroid/util/DisplayMetrics;->DENSITY_DEVICE:I
 Landroid/util/DisplayMetrics;->noncompatHeightPixels:I
 Landroid/util/DisplayMetrics;->noncompatWidthPixels:I
 Landroid/util/EventLog$Event;-><init>([B)V
@@ -2274,13 +2543,13 @@
 Landroid/util/NtpTrustedTime;->hasCache()Z
 Landroid/util/PathParser;->createPathFromPathData(Ljava/lang/String;)Landroid/graphics/Path;
 Landroid/util/Pools$SimplePool;->mPool:[Ljava/lang/Object;
-Landroid/util/Pools$SynchronizedPool;->acquire()Ljava/lang/Object;
 Landroid/util/Pools$SynchronizedPool;-><init>(I)V
+Landroid/util/Pools$SynchronizedPool;->acquire()Ljava/lang/Object;
 Landroid/util/Pools$SynchronizedPool;->release(Ljava/lang/Object;)Z
 Landroid/util/Rational;->mDenominator:I
 Landroid/util/Rational;->mNumerator:I
-Landroid/util/Singleton;->get()Ljava/lang/Object;
 Landroid/util/Singleton;-><init>()V
+Landroid/util/Singleton;->get()Ljava/lang/Object;
 Landroid/util/Singleton;->mInstance:Ljava/lang/Object;
 Landroid/util/Slog;->d(Ljava/lang/String;Ljava/lang/String;)I
 Landroid/util/Slog;->w(Ljava/lang/String;Ljava/lang/String;)I
@@ -2302,9 +2571,9 @@
 Landroid/view/accessibility/AccessibilityNodeInfo;->refresh(Landroid/os/Bundle;Z)Z
 Landroid/view/accessibility/AccessibilityNodeInfo;->setSealed(Z)V
 Landroid/view/accessibility/AccessibilityRecord;->getSourceNodeId()J
-Landroid/view/accessibility/IAccessibilityManager;->getEnabledAccessibilityServiceList(II)Ljava/util/List;
-Landroid/view/accessibility/IAccessibilityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/accessibility/IAccessibilityManager;
 Landroid/view/accessibility/IAccessibilityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/view/accessibility/IAccessibilityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/accessibility/IAccessibilityManager;
+Landroid/view/accessibility/IAccessibilityManager;->getEnabledAccessibilityServiceList(II)Ljava/util/List;
 Landroid/view/animation/Animation;->detach()V
 Landroid/view/animation/Animation;->initializeInvalidateRegion(IIII)V
 Landroid/view/animation/Animation;->mListener:Landroid/view/animation/Animation$AnimationListener;
@@ -2324,9 +2593,12 @@
 Landroid/view/ContextThemeWrapper;->mResources:Landroid/content/res/Resources;
 Landroid/view/ContextThemeWrapper;->mTheme:Landroid/content/res/Resources$Theme;
 Landroid/view/ContextThemeWrapper;->mThemeResource:I
+Landroid/view/Display$HdrCapabilities;-><init>([IFFF)V
+Landroid/view/Display;->getDisplayAdjustments()Landroid/view/DisplayAdjustments;
+Landroid/view/DisplayAdjustments;->getConfiguration()Landroid/content/res/Configuration;
+Landroid/view/DisplayAdjustments;->setCompatibilityInfo(Landroid/content/res/CompatibilityInfo;)V
 Landroid/view/DisplayEventReceiver;->dispatchHotplug(JIZ)V
 Landroid/view/DisplayEventReceiver;->dispatchVsync(JII)V
-Landroid/view/Display$HdrCapabilities;-><init>([IFFF)V
 Landroid/view/DisplayListCanvas;->callDrawGLFunction2(J)V
 Landroid/view/DisplayListCanvas;->drawGLFunctor2(JLjava/lang/Runnable;)V
 Landroid/view/FrameMetrics;->mTimingData:[J
@@ -2338,10 +2610,11 @@
 Landroid/view/GhostView;->addGhost(Landroid/view/View;Landroid/view/ViewGroup;Landroid/graphics/Matrix;)Landroid/view/GhostView;
 Landroid/view/GhostView;->removeGhost(Landroid/view/View;)V
 Landroid/view/IGraphicsStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/view/IGraphicsStats$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IGraphicsStats;
 Landroid/view/InputChannel;-><init>()V
 Landroid/view/InputChannel;->mPtr:J
-Landroid/view/InputDevice;->addMotionRange(IIFFFFF)V
 Landroid/view/InputDevice;-><init>(IIILjava/lang/String;IILjava/lang/String;ZIILandroid/view/KeyCharacterMap;ZZZ)V
+Landroid/view/InputDevice;->addMotionRange(IIFFFFF)V
 Landroid/view/InputDevice;->isExternal()Z
 Landroid/view/InputEvent;->getSequenceNumber()I
 Landroid/view/InputEventReceiver;->dispatchBatchedInputEventPending()V
@@ -2351,6 +2624,7 @@
 Landroid/view/inputmethod/InputMethodManager;->finishInputLocked()V
 Landroid/view/inputmethod/InputMethodManager;->focusIn(Landroid/view/View;)V
 Landroid/view/inputmethod/InputMethodManager;->focusOut(Landroid/view/View;)V
+Landroid/view/inputmethod/InputMethodManager;->getClient()Lcom/android/internal/view/IInputMethodClient;
 Landroid/view/inputmethod/InputMethodManager;->getInputMethodWindowVisibleHeight()I
 Landroid/view/inputmethod/InputMethodManager;->getInstance()Landroid/view/inputmethod/InputMethodManager;
 Landroid/view/inputmethod/InputMethodManager;->mCurId:Ljava/lang/String;
@@ -2368,17 +2642,17 @@
 Landroid/view/inputmethod/InputMethodSubtypeArray;-><init>(Ljava/util/List;)V
 Landroid/view/InputQueue;->finishInputEvent(JZ)V
 Landroid/view/IRecentsAnimationController;->setAnimationTargetsBehindSystemBars(Z)V
+Landroid/view/IWindowManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/view/IWindowManager$Stub$Proxy;->getBaseDisplayDensity(I)I
+Landroid/view/IWindowManager$Stub$Proxy;->getDockedStackSide()I
+Landroid/view/IWindowManager$Stub$Proxy;->getInitialDisplayDensity(I)I
+Landroid/view/IWindowManager$Stub$Proxy;->hasNavigationBar()Z
+Landroid/view/IWindowManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IWindowManager;
 Landroid/view/IWindowManager;->getAnimationScale(I)F
 Landroid/view/IWindowManager;->hasNavigationBar()Z
 Landroid/view/IWindowManager;->setAnimationScale(IF)V
 Landroid/view/IWindowManager;->setShelfHeight(ZI)V
 Landroid/view/IWindowManager;->setStrictModeVisualIndicatorPreference(Ljava/lang/String;)V
-Landroid/view/IWindowManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IWindowManager;
-Landroid/view/IWindowManager$Stub$Proxy;->getBaseDisplayDensity(I)I
-Landroid/view/IWindowManager$Stub$Proxy;->getDockedStackSide()I
-Landroid/view/IWindowManager$Stub$Proxy;->getInitialDisplayDensity(I)I
-Landroid/view/IWindowManager$Stub$Proxy;->hasNavigationBar()Z
-Landroid/view/IWindowManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/view/IWindowSession$Stub$Proxy;->relayout(Landroid/view/IWindow;ILandroid/view/WindowManager$LayoutParams;IIIIJLandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/util/MergedConfiguration;Landroid/view/Surface;)I
 Landroid/view/KeyCharacterMap$FallbackAction;->keyCode:I
 Landroid/view/KeyCharacterMap$FallbackAction;->metaState:I
@@ -2407,18 +2681,18 @@
 Landroid/view/LayoutInflater;->mPrivateFactory:Landroid/view/LayoutInflater$Factory2;
 Landroid/view/LayoutInflater;->sConstructorMap:Ljava/util/HashMap;
 Landroid/view/LayoutInflater;->setPrivateFactory(Landroid/view/LayoutInflater$Factory2;)V
+Landroid/view/MotionEvent$PointerCoords;->mPackedAxisBits:J
+Landroid/view/MotionEvent$PointerCoords;->mPackedAxisValues:[F
 Landroid/view/MotionEvent;->getPointerIdBits()I
 Landroid/view/MotionEvent;->HISTORY_CURRENT:I
 Landroid/view/MotionEvent;->mNativePtr:J
 Landroid/view/MotionEvent;->nativeGetRawAxisValue(JIII)F
 Landroid/view/MotionEvent;->obtain()Landroid/view/MotionEvent;
-Landroid/view/MotionEvent$PointerCoords;->mPackedAxisBits:J
-Landroid/view/MotionEvent$PointerCoords;->mPackedAxisValues:[F
 Landroid/view/MotionEvent;->scale(F)V
 Landroid/view/MotionEvent;->split(I)Landroid/view/MotionEvent;
 Landroid/view/PointerIcon;->load(Landroid/content/Context;)Landroid/view/PointerIcon;
-Landroid/view/PointerIcon;->mBitmapFrames:[Landroid/graphics/Bitmap;
 Landroid/view/PointerIcon;->mBitmap:Landroid/graphics/Bitmap;
+Landroid/view/PointerIcon;->mBitmapFrames:[Landroid/graphics/Bitmap;
 Landroid/view/PointerIcon;->mDurationPerFrame:I
 Landroid/view/PointerIcon;->mHotSpotX:F
 Landroid/view/PointerIcon;->mHotSpotY:F
@@ -2435,29 +2709,29 @@
 Landroid/view/RemoteAnimationTarget;->sourceContainerBounds:Landroid/graphics/Rect;
 Landroid/view/RemoteAnimationTarget;->taskId:I
 Landroid/view/RemoteAnimationTarget;->windowConfiguration:Landroid/app/WindowConfiguration;
-Landroid/view/RenderNodeAnimator;->callOnFinished(Landroid/view/RenderNodeAnimator;)V
-Landroid/view/RenderNodeAnimator;-><init>(IF)V
-Landroid/view/RenderNodeAnimator;->mapViewPropertyToRenderProperty(I)I
-Landroid/view/RenderNodeAnimator;->setTarget(Landroid/view/View;)V
 Landroid/view/RenderNode;->discardDisplayList()V
 Landroid/view/RenderNode;->output()V
+Landroid/view/RenderNodeAnimator;-><init>(IF)V
+Landroid/view/RenderNodeAnimator;->callOnFinished(Landroid/view/RenderNodeAnimator;)V
+Landroid/view/RenderNodeAnimator;->mapViewPropertyToRenderProperty(I)I
+Landroid/view/RenderNodeAnimator;->setTarget(Landroid/view/View;)V
 Landroid/view/ScaleGestureDetector;->mListener:Landroid/view/ScaleGestureDetector$OnScaleGestureListener;
 Landroid/view/ScaleGestureDetector;->mMinSpan:I
+Landroid/view/Surface;-><init>(J)V
+Landroid/view/Surface;->mLock:Ljava/lang/Object;
+Landroid/view/Surface;->mNativeObject:J
+Landroid/view/Surface;->transferFrom(Landroid/view/Surface;)V
+Landroid/view/SurfaceControl$PhysicalDisplayInfo;-><init>()V
 Landroid/view/SurfaceControl$PhysicalDisplayInfo;->appVsyncOffsetNanos:J
 Landroid/view/SurfaceControl$PhysicalDisplayInfo;->density:F
 Landroid/view/SurfaceControl$PhysicalDisplayInfo;->height:I
-Landroid/view/SurfaceControl$PhysicalDisplayInfo;-><init>()V
 Landroid/view/SurfaceControl$PhysicalDisplayInfo;->presentationDeadlineNanos:J
 Landroid/view/SurfaceControl$PhysicalDisplayInfo;->refreshRate:F
 Landroid/view/SurfaceControl$PhysicalDisplayInfo;->secure:Z
 Landroid/view/SurfaceControl$PhysicalDisplayInfo;->width:I
 Landroid/view/SurfaceControl$PhysicalDisplayInfo;->xDpi:F
 Landroid/view/SurfaceControl$PhysicalDisplayInfo;->yDpi:F
-Landroid/view/Surface;-><init>(J)V
-Landroid/view/Surface;->mLock:Ljava/lang/Object;
-Landroid/view/Surface;->mNativeObject:J
 Landroid/view/SurfaceSession;->mNativeClient:J
-Landroid/view/Surface;->transferFrom(Landroid/view/Surface;)V
 Landroid/view/SurfaceView;->isFixedSize()Z
 Landroid/view/SurfaceView;->mCallbacks:Ljava/util/ArrayList;
 Landroid/view/SurfaceView;->mFormat:I
@@ -2466,14 +2740,14 @@
 Landroid/view/SurfaceView;->setFrame(IIII)Z
 Landroid/view/SurfaceView;->surfacePositionLost_uiRtSync(J)V
 Landroid/view/SurfaceView;->updateSurfacePosition_renderWorker(JIIII)V
-Landroid/view/textclassifier/logging/SmartSelectionEventTracker;-><init>(Landroid/content/Context;I)V
-Landroid/view/textclassifier/logging/SmartSelectionEventTracker;->logEvent(Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;)V
 Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionAction(III)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;
 Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionAction(IIILandroid/view/textclassifier/TextClassification;)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;
 Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionModified(II)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;
 Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionModified(IILandroid/view/textclassifier/TextClassification;)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;
 Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionModified(IILandroid/view/textclassifier/TextSelection;)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;
 Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionStarted(I)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;
+Landroid/view/textclassifier/logging/SmartSelectionEventTracker;-><init>(Landroid/content/Context;I)V
+Landroid/view/textclassifier/logging/SmartSelectionEventTracker;->logEvent(Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;)V
 Landroid/view/textclassifier/TextClassificationManager;->getTextClassifier(I)Landroid/view/textclassifier/TextClassifier;
 Landroid/view/textclassifier/TextClassifier;->classifyText(Ljava/lang/CharSequence;IILandroid/view/textclassifier/TextClassification$Options;)Landroid/view/textclassifier/TextClassification;
 Landroid/view/textclassifier/TextClassifier;->generateLinks(Ljava/lang/CharSequence;Landroid/view/textclassifier/TextLinks$Options;)Landroid/view/textclassifier/TextLinks;
@@ -2486,28 +2760,28 @@
 Landroid/view/TextureView;->mNativeWindow:J
 Landroid/view/TextureView;->mSurface:Landroid/graphics/SurfaceTexture;
 Landroid/view/TextureView;->mUpdateListener:Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;
+Landroid/view/ThreadedRenderer;->setupDiskCache(Ljava/io/File;)V
 Landroid/view/TouchDelegate;->mDelegateTargeted:Z
 Landroid/view/VelocityTracker$Estimator;->confidence:F
 Landroid/view/VelocityTracker$Estimator;->degree:I
 Landroid/view/VelocityTracker$Estimator;->xCoeff:[F
 Landroid/view/VelocityTracker$Estimator;->yCoeff:[F
 Landroid/view/VelocityTracker;->obtain(Ljava/lang/String;)Landroid/view/VelocityTracker;
-Landroid/view/View;->applyDrawableToTransparentRegion(Landroid/graphics/drawable/Drawable;Landroid/graphics/Region;)V
 Landroid/view/View$AttachInfo;->mContentInsets:Landroid/graphics/Rect;
 Landroid/view/View$AttachInfo;->mDrawingTime:J
 Landroid/view/View$AttachInfo;->mStableInsets:Landroid/graphics/Rect;
+Landroid/view/View$ListenerInfo;-><init>()V
+Landroid/view/View$ListenerInfo;->mOnClickListener:Landroid/view/View$OnClickListener;
+Landroid/view/View$ListenerInfo;->mOnDragListener:Landroid/view/View$OnDragListener;
+Landroid/view/View$ListenerInfo;->mOnFocusChangeListener:Landroid/view/View$OnFocusChangeListener;
+Landroid/view/View$ListenerInfo;->mOnLongClickListener:Landroid/view/View$OnLongClickListener;
+Landroid/view/View$ListenerInfo;->mOnTouchListener:Landroid/view/View$OnTouchListener;
+Landroid/view/View$ScrollabilityCache;->scrollBar:Landroid/widget/ScrollBarDrawable;
+Landroid/view/View;->applyDrawableToTransparentRegion(Landroid/graphics/drawable/Drawable;Landroid/graphics/Region;)V
 Landroid/view/View;->clearAccessibilityFocus()V
 Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z
 Landroid/view/View;->computeOpaqueFlags()V
-Landroid/view/ViewConfiguration;->getDeviceGlobalActionKeyTimeout()J
-Landroid/view/ViewConfiguration;->getDoubleTapMinTime()I
-Landroid/view/ViewConfiguration;->getScaledScrollFactor()I
-Landroid/view/ViewConfiguration;->mFadingMarqueeEnabled:Z
-Landroid/view/ViewConfiguration;->sHasPermanentMenuKeySet:Z
-Landroid/view/ViewConfiguration;->sHasPermanentMenuKey:Z
 Landroid/view/View;->createSnapshot(Landroid/view/ViewDebug$CanvasProvider;Z)Landroid/graphics/Bitmap;
-Landroid/view/ViewDebug;->dispatchCommand(Landroid/view/View;Ljava/lang/String;Ljava/lang/String;Ljava/io/OutputStream;)V
-Landroid/view/ViewDebug;->dump(Landroid/view/View;ZZLjava/io/OutputStream;)V
 Landroid/view/View;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V
 Landroid/view/View;->dispatchDetachedFromWindow()V
 Landroid/view/View;->fitsSystemWindows()Z
@@ -2524,40 +2798,14 @@
 Landroid/view/View;->getVerticalScrollFactor()F
 Landroid/view/View;->getViewRootImpl()Landroid/view/ViewRootImpl;
 Landroid/view/View;->getWindowDisplayFrame(Landroid/graphics/Rect;)V
-Landroid/view/ViewGroup;->dispatchViewAdded(Landroid/view/View;)V
-Landroid/view/ViewGroup;->dispatchViewRemoved(Landroid/view/View;)V
-Landroid/view/ViewGroup;->FLAG_SUPPORT_STATIC_TRANSFORMATIONS:I
-Landroid/view/ViewGroup;->FLAG_USE_CHILD_DRAWING_ORDER:I
-Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V
-Landroid/view/ViewGroup$MarginLayoutParams;->endMargin:I
-Landroid/view/ViewGroup$MarginLayoutParams;->startMargin:I
-Landroid/view/ViewGroup;->mChildrenCount:I
-Landroid/view/ViewGroup;->mChildren:[Landroid/view/View;
-Landroid/view/ViewGroup;->mFirstTouchTarget:Landroid/view/ViewGroup$TouchTarget;
-Landroid/view/ViewGroup;->mGroupFlags:I
-Landroid/view/ViewGroup;->mOnHierarchyChangeListener:Landroid/view/ViewGroup$OnHierarchyChangeListener;
-Landroid/view/ViewGroup;->mPersistentDrawingCache:I
-Landroid/view/ViewGroup;->offsetChildrenTopAndBottom(I)V
-Landroid/view/ViewGroup;->onChildVisibilityChanged(Landroid/view/View;II)V
-Landroid/view/ViewGroup;->resetResolvedDrawables()V
-Landroid/view/ViewGroup;->resetResolvedLayoutDirection()V
-Landroid/view/ViewGroup;->resetResolvedPadding()V
-Landroid/view/ViewGroup;->resetResolvedTextAlignment()V
-Landroid/view/ViewGroup;->resetResolvedTextDirection()V
-Landroid/view/ViewGroup;->suppressLayout(Z)V
 Landroid/view/View;->includeForAccessibility()Z
 Landroid/view/View;->initializeScrollbars(Landroid/content/res/TypedArray;)V
 Landroid/view/View;->internalSetPadding(IIII)V
+Landroid/view/View;->invalidateParentIfNeeded()V
 Landroid/view/View;->isPaddingResolved()Z
 Landroid/view/View;->isRootNamespace()Z
-Landroid/view/View;->isVisibleToUser(Landroid/graphics/Rect;)Z
 Landroid/view/View;->isVisibleToUser()Z
-Landroid/view/View$ListenerInfo;-><init>()V
-Landroid/view/View$ListenerInfo;->mOnClickListener:Landroid/view/View$OnClickListener;
-Landroid/view/View$ListenerInfo;->mOnDragListener:Landroid/view/View$OnDragListener;
-Landroid/view/View$ListenerInfo;->mOnFocusChangeListener:Landroid/view/View$OnFocusChangeListener;
-Landroid/view/View$ListenerInfo;->mOnLongClickListener:Landroid/view/View$OnLongClickListener;
-Landroid/view/View$ListenerInfo;->mOnTouchListener:Landroid/view/View$OnTouchListener;
+Landroid/view/View;->isVisibleToUser(Landroid/graphics/Rect;)Z
 Landroid/view/View;->mAccessibilityDelegate:Landroid/view/View$AccessibilityDelegate;
 Landroid/view/View;->mAttachInfo:Landroid/view/View$AttachInfo;
 Landroid/view/View;->mBackground:Landroid/graphics/drawable/Drawable;
@@ -2601,16 +2849,6 @@
 Landroid/view/View;->resetResolvedTextAlignment()V
 Landroid/view/View;->resetResolvedTextDirection()V
 Landroid/view/View;->resetRtlProperties()V
-Landroid/view/ViewRootImpl;->detachFunctor(J)V
-Landroid/view/ViewRootImpl;->dispatchInputEvent(Landroid/view/InputEvent;Landroid/view/InputEventReceiver;)V
-Landroid/view/ViewRootImpl;->dispatchInputEvent(Landroid/view/InputEvent;)V
-Landroid/view/ViewRootImpl;->enqueueInputEvent(Landroid/view/InputEvent;)V
-Landroid/view/ViewRootImpl;->getWindowFlags()I
-Landroid/view/ViewRootImpl;->invokeFunctor(JZ)V
-Landroid/view/ViewRootImpl;->mStopped:Z
-Landroid/view/ViewRootImpl;->mSurface:Landroid/view/Surface;
-Landroid/view/ViewRootImpl;->mView:Landroid/view/View;
-Landroid/view/View$ScrollabilityCache;->scrollBar:Landroid/widget/ScrollBarDrawable;
 Landroid/view/View;->setAlphaNoInvalidation(F)Z
 Landroid/view/View;->setAnimationMatrix(Landroid/graphics/Matrix;)V
 Landroid/view/View;->setAssistBlocked(Z)V
@@ -2627,13 +2865,63 @@
 Landroid/view/View;->toLocalMotionEvent(Landroid/view/MotionEvent;)Z
 Landroid/view/View;->transformMatrixToGlobal(Landroid/graphics/Matrix;)V
 Landroid/view/View;->transformMatrixToLocal(Landroid/graphics/Matrix;)V
-Landroid/view/ViewTreeObserver;->addOnComputeInternalInsetsListener(Landroid/view/ViewTreeObserver$OnComputeInternalInsetsListener;)V
+Landroid/view/ViewConfiguration;->getDeviceGlobalActionKeyTimeout()J
+Landroid/view/ViewConfiguration;->getDoubleTapMinTime()I
+Landroid/view/ViewConfiguration;->getScaledScrollFactor()I
+Landroid/view/ViewConfiguration;->mFadingMarqueeEnabled:Z
+Landroid/view/ViewConfiguration;->sHasPermanentMenuKey:Z
+Landroid/view/ViewConfiguration;->sHasPermanentMenuKeySet:Z
+Landroid/view/ViewDebug;->dispatchCommand(Landroid/view/View;Ljava/lang/String;Ljava/lang/String;Ljava/io/OutputStream;)V
+Landroid/view/ViewDebug;->dump(Landroid/view/View;ZZLjava/io/OutputStream;)V
+Landroid/view/ViewGroup$MarginLayoutParams;->endMargin:I
+Landroid/view/ViewGroup$MarginLayoutParams;->startMargin:I
+Landroid/view/ViewGroup;->dispatchViewAdded(Landroid/view/View;)V
+Landroid/view/ViewGroup;->dispatchViewRemoved(Landroid/view/View;)V
+Landroid/view/ViewGroup;->FLAG_SUPPORT_STATIC_TRANSFORMATIONS:I
+Landroid/view/ViewGroup;->FLAG_USE_CHILD_DRAWING_ORDER:I
+Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V
+Landroid/view/ViewGroup;->mChildren:[Landroid/view/View;
+Landroid/view/ViewGroup;->mChildrenCount:I
+Landroid/view/ViewGroup;->mFirstTouchTarget:Landroid/view/ViewGroup$TouchTarget;
+Landroid/view/ViewGroup;->mGroupFlags:I
+Landroid/view/ViewGroup;->mOnHierarchyChangeListener:Landroid/view/ViewGroup$OnHierarchyChangeListener;
+Landroid/view/ViewGroup;->mPersistentDrawingCache:I
+Landroid/view/ViewGroup;->offsetChildrenTopAndBottom(I)V
+Landroid/view/ViewGroup;->onChildVisibilityChanged(Landroid/view/View;II)V
+Landroid/view/ViewGroup;->resetResolvedDrawables()V
+Landroid/view/ViewGroup;->resetResolvedLayoutDirection()V
+Landroid/view/ViewGroup;->resetResolvedPadding()V
+Landroid/view/ViewGroup;->resetResolvedTextAlignment()V
+Landroid/view/ViewGroup;->resetResolvedTextDirection()V
+Landroid/view/ViewGroup;->suppressLayout(Z)V
+Landroid/view/ViewRootImpl;->detachFunctor(J)V
+Landroid/view/ViewRootImpl;->dispatchInputEvent(Landroid/view/InputEvent;)V
+Landroid/view/ViewRootImpl;->dispatchInputEvent(Landroid/view/InputEvent;Landroid/view/InputEventReceiver;)V
+Landroid/view/ViewRootImpl;->enqueueInputEvent(Landroid/view/InputEvent;)V
+Landroid/view/ViewRootImpl;->getWindowFlags()I
+Landroid/view/ViewRootImpl;->invokeFunctor(JZ)V
+Landroid/view/ViewRootImpl;->mStopped:Z
+Landroid/view/ViewRootImpl;->mSurface:Landroid/view/Surface;
+Landroid/view/ViewRootImpl;->mView:Landroid/view/View;
 Landroid/view/ViewTreeObserver$InternalInsetsInfo;->setTouchableInsets(I)V
-Landroid/view/ViewTreeObserver$InternalInsetsInfo;->TOUCHABLE_INSETS_REGION:I
 Landroid/view/ViewTreeObserver$InternalInsetsInfo;->touchableRegion:Landroid/graphics/Region;
+Landroid/view/ViewTreeObserver$InternalInsetsInfo;->TOUCHABLE_INSETS_REGION:I
+Landroid/view/ViewTreeObserver;->addOnComputeInternalInsetsListener(Landroid/view/ViewTreeObserver$OnComputeInternalInsetsListener;)V
 Landroid/view/ViewTreeObserver;->removeOnComputeInternalInsetsListener(Landroid/view/ViewTreeObserver$OnComputeInternalInsetsListener;)V
+Landroid/view/Window;->mAppName:Ljava/lang/String;
+Landroid/view/Window;->mAppToken:Landroid/os/IBinder;
+Landroid/view/Window;->mCallback:Landroid/view/Window$Callback;
+Landroid/view/Window;->mContext:Landroid/content/Context;
+Landroid/view/Window;->mHardwareAccelerated:Z
+Landroid/view/Window;->mWindowStyle:Landroid/content/res/TypedArray;
+Landroid/view/Window;->setNeedsMenuKey(I)V
 Landroid/view/WindowAnimationFrameStats;->init(J[J)V
 Landroid/view/WindowContentFrameStats;->init(J[J[J[J)V
+Landroid/view/WindowManager$LayoutParams;->hideTimeoutMilliseconds:J
+Landroid/view/WindowManager$LayoutParams;->needsMenuKey:I
+Landroid/view/WindowManager$LayoutParams;->NEEDS_MENU_SET_FALSE:I
+Landroid/view/WindowManager$LayoutParams;->NEEDS_MENU_SET_TRUE:I
+Landroid/view/WindowManager$LayoutParams;->userActivityTimeout:J
 Landroid/view/WindowManagerGlobal;->getInstance()Landroid/view/WindowManagerGlobal;
 Landroid/view/WindowManagerGlobal;->getRootView(Ljava/lang/String;)Landroid/view/View;
 Landroid/view/WindowManagerGlobal;->getViewRootNames()[Ljava/lang/String;
@@ -2648,17 +2936,7 @@
 Landroid/view/WindowManagerGlobal;->sWindowSession:Landroid/view/IWindowSession;
 Landroid/view/WindowManagerGlobal;->trimMemory(I)V
 Landroid/view/WindowManagerImpl;->mGlobal:Landroid/view/WindowManagerGlobal;
-Landroid/view/WindowManager$LayoutParams;->hideTimeoutMilliseconds:J
-Landroid/view/WindowManager$LayoutParams;->needsMenuKey:I
-Landroid/view/WindowManager$LayoutParams;->NEEDS_MENU_SET_TRUE:I
-Landroid/view/WindowManager$LayoutParams;->userActivityTimeout:J
-Landroid/view/Window;->mAppName:Ljava/lang/String;
-Landroid/view/Window;->mAppToken:Landroid/os/IBinder;
-Landroid/view/Window;->mCallback:Landroid/view/Window$Callback;
-Landroid/view/Window;->mContext:Landroid/content/Context;
-Landroid/view/Window;->mHardwareAccelerated:Z
-Landroid/view/Window;->mWindowStyle:Landroid/content/res/TypedArray;
-Landroid/webkit/CacheManager;->cacheDisabled()Z
+Landroid/webkit/CacheManager$CacheResult;-><init>()V
 Landroid/webkit/CacheManager$CacheResult;->getContentDisposition()Ljava/lang/String;
 Landroid/webkit/CacheManager$CacheResult;->getContentLength()J
 Landroid/webkit/CacheManager$CacheResult;->getEncoding()Ljava/lang/String;
@@ -2672,43 +2950,51 @@
 Landroid/webkit/CacheManager$CacheResult;->getLocation()Ljava/lang/String;
 Landroid/webkit/CacheManager$CacheResult;->getMimeType()Ljava/lang/String;
 Landroid/webkit/CacheManager$CacheResult;->getOutputStream()Ljava/io/OutputStream;
-Landroid/webkit/CacheManager$CacheResult;-><init>()V
 Landroid/webkit/CacheManager$CacheResult;->setEncoding(Ljava/lang/String;)V
 Landroid/webkit/CacheManager$CacheResult;->setInputStream(Ljava/io/InputStream;)V
+Landroid/webkit/CacheManager;->cacheDisabled()Z
 Landroid/webkit/CacheManager;->endCacheTransaction()Z
-Landroid/webkit/CacheManager;->getCacheFileBaseDir()Ljava/io/File;
 Landroid/webkit/CacheManager;->getCacheFile(Ljava/lang/String;Ljava/util/Map;)Landroid/webkit/CacheManager$CacheResult;
+Landroid/webkit/CacheManager;->getCacheFileBaseDir()Ljava/io/File;
 Landroid/webkit/CacheManager;->saveCacheFile(Ljava/lang/String;Landroid/webkit/CacheManager$CacheResult;)V
 Landroid/webkit/CacheManager;->startCacheTransaction()Z
 Landroid/webkit/IWebViewUpdateService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/webkit/WebResourceResponse;->mImmutable:Z
 Landroid/webkit/WebSettings$TextSize;->value:I
 Landroid/webkit/WebSyncManager;->mHandler:Landroid/os/Handler;
-Landroid/webkit/WebViewClient;->onUnhandledInputEvent(Landroid/webkit/WebView;Landroid/view/InputEvent;)V
 Landroid/webkit/WebView;->debugDump()V
 Landroid/webkit/WebView;->disablePlatformNotifications()V
 Landroid/webkit/WebView;->emulateShiftHeld()V
 Landroid/webkit/WebView;->enablePlatformNotifications()V
-Landroid/webkit/WebViewFactory;->getProvider()Landroid/webkit/WebViewFactoryProvider;
-Landroid/webkit/WebViewFactory;->getWebViewContextAndSetProvider()Landroid/content/Context;
-Landroid/webkit/WebViewFactory;->sPackageInfo:Landroid/content/pm/PackageInfo;
-Landroid/webkit/WebViewFactory;->sProviderInstance:Landroid/webkit/WebViewFactoryProvider;
 Landroid/webkit/WebView;->getContentWidth()I
 Landroid/webkit/WebView;->getTouchIconUrl()Ljava/lang/String;
 Landroid/webkit/WebView;->getVisibleTitleHeight()I
 Landroid/webkit/WebView;->isPaused()Z
 Landroid/webkit/WebView;->mProvider:Landroid/webkit/WebViewProvider;
+Landroid/webkit/WebView;->mWebViewThread:Landroid/os/Looper;
 Landroid/webkit/WebView;->notifyFindDialogDismissed()V
 Landroid/webkit/WebView;->onDrawVerticalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V
 Landroid/webkit/WebView;->restorePicture(Landroid/os/Bundle;Ljava/io/File;)Z
 Landroid/webkit/WebView;->savePicture(Landroid/os/Bundle;Ljava/io/File;)Z
 Landroid/webkit/WebView;->sEnforceThreadChecking:Z
+Landroid/webkit/WebViewClient;->onUnhandledInputEvent(Landroid/webkit/WebView;Landroid/view/InputEvent;)V
+Landroid/webkit/WebViewDelegate;-><init>()V
+Landroid/webkit/WebViewFactory;->getProvider()Landroid/webkit/WebViewFactoryProvider;
+Landroid/webkit/WebViewFactory;->getUpdateService()Landroid/webkit/IWebViewUpdateService;
+Landroid/webkit/WebViewFactory;->getWebViewContextAndSetProvider()Landroid/content/Context;
+Landroid/webkit/WebViewFactory;->sPackageInfo:Landroid/content/pm/PackageInfo;
+Landroid/webkit/WebViewFactory;->sProviderInstance:Landroid/webkit/WebViewFactoryProvider;
 Landroid/widget/AbsListView$FlingRunnable;->endFling()V
 Landroid/widget/AbsListView$FlingRunnable;->mScroller:Landroid/widget/OverScroller;
 Landroid/widget/AbsListView$FlingRunnable;->start(I)V
+Landroid/widget/AbsListView$RecycleBin;->clear()V
+Landroid/widget/AbsListView$RecycleBin;->mRecyclerListener:Landroid/widget/AbsListView$RecyclerListener;
+Landroid/widget/AbsListView$SavedState;->firstId:J
+Landroid/widget/AbsListView$SavedState;->viewTop:I
 Landroid/widget/AbsListView;->invokeOnItemScrollListener()V
 Landroid/widget/AbsListView;->isVerticalScrollBarHidden()Z
 Landroid/widget/AbsListView;->mAdapter:Landroid/widget/ListAdapter;
+Landroid/widget/AbsListView;->mDataSetObserver:Landroid/widget/AbsListView$AdapterDataSetObserver;
 Landroid/widget/AbsListView;->mEdgeGlowBottom:Landroid/widget/EdgeEffect;
 Landroid/widget/AbsListView;->mEdgeGlowTop:Landroid/widget/EdgeEffect;
 Landroid/widget/AbsListView;->mFastScroll:Landroid/widget/FastScroller;
@@ -2727,13 +3013,9 @@
 Landroid/widget/AbsListView;->mTouchMode:I
 Landroid/widget/AbsListView;->mTouchSlop:I
 Landroid/widget/AbsListView;->mVelocityTracker:Landroid/view/VelocityTracker;
-Landroid/widget/AbsListView;->performLongPress(Landroid/view/View;IJFF)Z
 Landroid/widget/AbsListView;->performLongPress(Landroid/view/View;IJ)Z
-Landroid/widget/AbsListView$RecycleBin;->clear()V
-Landroid/widget/AbsListView$RecycleBin;->mRecyclerListener:Landroid/widget/AbsListView$RecyclerListener;
+Landroid/widget/AbsListView;->performLongPress(Landroid/view/View;IJFF)Z
 Landroid/widget/AbsListView;->reportScrollStateChange(I)V
-Landroid/widget/AbsListView$SavedState;->firstId:J
-Landroid/widget/AbsListView$SavedState;->viewTop:I
 Landroid/widget/AbsListView;->smoothScrollBy(IIZZ)V
 Landroid/widget/AbsListView;->trackMotionScroll(II)Z
 Landroid/widget/AbsSeekBar;->mIsDragging:Z
@@ -2756,6 +3038,7 @@
 Landroid/widget/AutoCompleteTextView;->setDropDownAlwaysVisible(Z)V
 Landroid/widget/AutoCompleteTextView;->setForceIgnoreOutsideTouch(Z)V
 Landroid/widget/BaseAdapter;->mDataSetObservable:Landroid/database/DataSetObservable;
+Landroid/widget/CompoundButton;->mBroadcasting:Z
 Landroid/widget/CompoundButton;->mButtonDrawable:Landroid/graphics/drawable/Drawable;
 Landroid/widget/CompoundButton;->mOnCheckedChangeListener:Landroid/widget/CompoundButton$OnCheckedChangeListener;
 Landroid/widget/CursorAdapter;->mChangeObserver:Landroid/widget/CursorAdapter$ChangeObserver;
@@ -2765,6 +3048,7 @@
 Landroid/widget/DatePicker;->mDelegate:Landroid/widget/DatePicker$DatePickerDelegate;
 Landroid/widget/EdgeEffect;->mPaint:Landroid/graphics/Paint;
 Landroid/widget/Editor;->invalidateTextDisplayList()V
+Landroid/widget/Editor;->mSelectHandleLeft:Landroid/graphics/drawable/Drawable;
 Landroid/widget/Editor;->mShowCursor:J
 Landroid/widget/Editor;->mShowSoftInputOnFocus:Z
 Landroid/widget/ExpandableListView;->mChildDivider:Landroid/graphics/drawable/Drawable;
@@ -2777,9 +3061,9 @@
 Landroid/widget/FastScroller;->mThumbImage:Landroid/widget/ImageView;
 Landroid/widget/FastScroller;->mTrackDrawable:Landroid/graphics/drawable/Drawable;
 Landroid/widget/FastScroller;->mTrackImage:Landroid/widget/ImageView;
+Landroid/widget/Gallery$FlingRunnable;->startUsingVelocity(I)V
 Landroid/widget/Gallery;->fillToGalleryLeft()V
 Landroid/widget/Gallery;->fillToGalleryRight()V
-Landroid/widget/Gallery$FlingRunnable;->startUsingVelocity(I)V
 Landroid/widget/Gallery;->makeAndAddView(IIIZ)Landroid/view/View;
 Landroid/widget/Gallery;->mDownTouchPosition:I
 Landroid/widget/Gallery;->mDownTouchView:Landroid/view/View;
@@ -2803,6 +3087,7 @@
 Landroid/widget/ImageView;->mDrawMatrix:Landroid/graphics/Matrix;
 Landroid/widget/ImageView;->mMaxHeight:I
 Landroid/widget/ImageView;->mMaxWidth:I
+Landroid/widget/ImageView;->mRecycleableBitmapDrawable:Landroid/graphics/drawable/BitmapDrawable;
 Landroid/widget/ImageView;->mResource:I
 Landroid/widget/ImageView;->mUri:Landroid/net/Uri;
 Landroid/widget/ImageView;->updateDrawable(Landroid/graphics/drawable/Drawable;)V
@@ -2816,6 +3101,8 @@
 Landroid/widget/ListView;->findViewTraversal(I)Landroid/view/View;
 Landroid/widget/ListView;->findViewWithTagTraversal(Ljava/lang/Object;)Landroid/view/View;
 Landroid/widget/ListView;->mAreAllItemsSelectable:Z
+Landroid/widget/ListView;->mFooterViewInfos:Ljava/util/ArrayList;
+Landroid/widget/ListView;->mHeaderViewInfos:Ljava/util/ArrayList;
 Landroid/widget/ListView;->setSelectionInt(I)V
 Landroid/widget/MediaController;->mAnchor:Landroid/view/View;
 Landroid/widget/MediaController;->mDecor:Landroid/view/View;
@@ -2824,9 +3111,9 @@
 Landroid/widget/NumberPicker;->mInputText:Landroid/widget/EditText;
 Landroid/widget/NumberPicker;->mSelectionDivider:Landroid/graphics/drawable/Drawable;
 Landroid/widget/NumberPicker;->mSelectorWheelPaint:Landroid/graphics/Paint;
+Landroid/widget/OverScroller$SplineOverScroller;->mCurrVelocity:F
 Landroid/widget/OverScroller;->isScrollingInDirection(FF)Z
 Landroid/widget/OverScroller;->mScrollerY:Landroid/widget/OverScroller$SplineOverScroller;
-Landroid/widget/OverScroller$SplineOverScroller;->mCurrVelocity:F
 Landroid/widget/PopupMenu;->mPopup:Lcom/android/internal/view/menu/MenuPopupHelper;
 Landroid/widget/PopupWindow;->computeAnimationResource()I
 Landroid/widget/PopupWindow;->createPopupLayoutParams(Landroid/os/IBinder;)Landroid/view/WindowManager$LayoutParams;
@@ -2867,20 +3154,23 @@
 Landroid/widget/RelativeLayout;->mGravity:I
 Landroid/widget/RemoteViews$Action;->mergeBehavior()I
 Landroid/widget/RemoteViews$Action;->viewId:I
-Landroid/widget/RemoteViewsAdapter;->mCache:Landroid/widget/RemoteViewsAdapter$FixedSizeRemoteViewsCache;
-Landroid/widget/RemoteViewsAdapter;->mWorkerThread:Landroid/os/HandlerThread;
 Landroid/widget/RemoteViews$BitmapCache;->mBitmaps:Ljava/util/ArrayList;
 Landroid/widget/RemoteViews$BitmapReflectionAction;->bitmap:Landroid/graphics/Bitmap;
 Landroid/widget/RemoteViews$BitmapReflectionAction;->methodName:Ljava/lang/String;
+Landroid/widget/RemoteViews$ReflectionAction;->methodName:Ljava/lang/String;
+Landroid/widget/RemoteViews$ReflectionAction;->value:Ljava/lang/Object;
+Landroid/widget/RemoteViews$SetOnClickPendingIntent;->pendingIntent:Landroid/app/PendingIntent;
+Landroid/widget/RemoteViews$SetPendingIntentTemplate;->pendingIntentTemplate:Landroid/app/PendingIntent;
+Landroid/widget/RemoteViews$ViewGroupActionAdd;->mNestedViews:Landroid/widget/RemoteViews;
 Landroid/widget/RemoteViews;->estimateMemoryUsage()I
 Landroid/widget/RemoteViews;->mActions:Ljava/util/ArrayList;
 Landroid/widget/RemoteViews;->mApplication:Landroid/content/pm/ApplicationInfo;
 Landroid/widget/RemoteViews;->mBitmapCache:Landroid/widget/RemoteViews$BitmapCache;
 Landroid/widget/RemoteViews;->mergeRemoteViews(Landroid/widget/RemoteViews;)V
+Landroid/widget/RemoteViews;->mLayoutId:I
 Landroid/widget/RemoteViews;->mPortrait:Landroid/widget/RemoteViews;
-Landroid/widget/RemoteViews$ReflectionAction;->methodName:Ljava/lang/String;
-Landroid/widget/RemoteViews$ReflectionAction;->value:Ljava/lang/Object;
-Landroid/widget/RemoteViews$SetOnClickPendingIntent;->pendingIntent:Landroid/app/PendingIntent;
+Landroid/widget/RemoteViewsAdapter;->mCache:Landroid/widget/RemoteViewsAdapter$FixedSizeRemoteViewsCache;
+Landroid/widget/RemoteViewsAdapter;->mWorkerThread:Landroid/os/HandlerThread;
 Landroid/widget/ScrollBarDrawable;->mVerticalThumb:Landroid/graphics/drawable/Drawable;
 Landroid/widget/ScrollBarDrawable;->setHorizontalThumbDrawable(Landroid/graphics/drawable/Drawable;)V
 Landroid/widget/ScrollBarDrawable;->setVerticalThumbDrawable(Landroid/graphics/drawable/Drawable;)V
@@ -2893,6 +3183,7 @@
 Landroid/widget/ScrollView;->mOverflingDistance:I
 Landroid/widget/ScrollView;->mOverscrollDistance:I
 Landroid/widget/ScrollView;->mScroller:Landroid/widget/OverScroller;
+Landroid/widget/SearchView$SearchAutoComplete;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 Landroid/widget/SearchView;->mCloseButton:Landroid/widget/ImageView;
 Landroid/widget/SearchView;->mSearchButton:Landroid/widget/ImageView;
 Landroid/widget/SearchView;->mSearchPlate:Landroid/view/View;
@@ -2905,9 +3196,9 @@
 Landroid/widget/Switch;->mTrackDrawable:Landroid/graphics/drawable/Drawable;
 Landroid/widget/TabHost$IntentContentStrategy;->getContentView()Landroid/view/View;
 Landroid/widget/TabHost$IntentContentStrategy;->tabClosed()V
-Landroid/widget/TabHost;->mTabSpecs:Ljava/util/List;
 Landroid/widget/TabHost$TabSpec;->mContentStrategy:Landroid/widget/TabHost$ContentStrategy;
 Landroid/widget/TabHost$TabSpec;->mIndicatorStrategy:Landroid/widget/TabHost$IndicatorStrategy;
+Landroid/widget/TabHost;->mTabSpecs:Ljava/util/List;
 Landroid/widget/TabWidget;->mDrawBottomStrips:Z
 Landroid/widget/TabWidget;->mSelectedTab:I
 Landroid/widget/TabWidget;->setTabSelectionListener(Landroid/widget/TabWidget$OnTabSelectionChanged;)V
@@ -2925,17 +3216,19 @@
 Landroid/widget/TextView;->mMaximum:I
 Landroid/widget/TextView;->mMaxMode:I
 Landroid/widget/TextView;->mSingleLine:Z
+Landroid/widget/TextView;->mText:Ljava/lang/CharSequence;
 Landroid/widget/TextView;->mTextPaint:Landroid/text/TextPaint;
 Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;ZI)V
+Landroid/widget/Toast$TN;->mNextView:Landroid/view/View;
+Landroid/widget/Toast$TN;->mParams:Landroid/view/WindowManager$LayoutParams;
+Landroid/widget/Toast$TN;->mView:Landroid/view/View;
 Landroid/widget/Toast;->getService()Landroid/app/INotificationManager;
 Landroid/widget/Toast;->getWindowParams()Landroid/view/WindowManager$LayoutParams;
 Landroid/widget/Toast;->mDuration:I
 Landroid/widget/Toast;->mTN:Landroid/widget/Toast$TN;
 Landroid/widget/Toast;->sService:Landroid/app/INotificationManager;
-Landroid/widget/Toast$TN;->mNextView:Landroid/view/View;
-Landroid/widget/Toast$TN;->mParams:Landroid/view/WindowManager$LayoutParams;
-Landroid/widget/VideoView2;->getMediaController()Landroid/media/session/MediaController;
 Landroid/widget/VideoView2$OnViewTypeChangedListener;->onViewTypeChanged(Landroid/view/View;I)V
+Landroid/widget/VideoView2;->getMediaController()Landroid/media/session/MediaController;
 Landroid/widget/VideoView2;->setOnViewTypeChangedListener(Landroid/widget/VideoView2$OnViewTypeChangedListener;)V
 Landroid/widget/VideoView2;->setVideoPath(Ljava/lang/String;)V
 Landroid/widget/VideoView;->mCurrentBufferPercentage:I
@@ -2944,6 +3237,8 @@
 Landroid/widget/VideoView;->mUri:Landroid/net/Uri;
 Landroid/widget/VideoView;->mVideoHeight:I
 Landroid/widget/VideoView;->mVideoWidth:I
+Landroid/widget/ViewAnimator;->mFirstTime:Z
+Landroid/widget/ViewAnimator;->mWhichChild:I
 Lcom/android/ims/internal/uce/common/CapInfo;-><init>()V
 Lcom/android/ims/internal/uce/common/CapInfo;->setCapTimestamp(J)V
 Lcom/android/ims/internal/uce/common/CapInfo;->setCdViaPresenceSupported(Z)V
@@ -3012,39 +3307,57 @@
 Lcom/android/ims/internal/uce/presence/PresTupleInfo;->setFeatureTag(Ljava/lang/String;)V
 Lcom/android/ims/internal/uce/presence/PresTupleInfo;->setTimestamp(Ljava/lang/String;)V
 Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V
+Lcom/android/internal/app/AlertController$RecycleListView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 Lcom/android/internal/app/AlertController;->mCustomTitleView:Landroid/view/View;
 Lcom/android/internal/app/AlertController;->mForceInverseBackground:Z
 Lcom/android/internal/app/AlertController;->mTitle:Ljava/lang/CharSequence;
 Lcom/android/internal/app/AlertController;->mView:Landroid/view/View;
-Lcom/android/internal/app/AlertController$RecycleListView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
-Lcom/android/internal/app/IAppOpsService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IAppOpsService;
-Lcom/android/internal/app/IAppOpsService$Stub$Proxy;->checkOperation(IILjava/lang/String;)I
 Lcom/android/internal/app/IAppOpsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Lcom/android/internal/app/IAppOpsService$Stub$Proxy;->checkOperation(IILjava/lang/String;)I
 Lcom/android/internal/app/IAppOpsService$Stub$Proxy;->setMode(IILjava/lang/String;I)V
-Lcom/android/internal/app/IBatteryStats;->getStatistics()[B
-Lcom/android/internal/app/IBatteryStats$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IBatteryStats;
+Lcom/android/internal/app/IAppOpsService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IAppOpsService;
 Lcom/android/internal/app/IBatteryStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Lcom/android/internal/app/IVoiceInteractionManagerService;->getKeyphraseSoundModel(ILjava/lang/String;)Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel;
-Lcom/android/internal/app/IVoiceInteractionManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IVoiceInteractionManagerService;
+Lcom/android/internal/app/IBatteryStats$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IBatteryStats;
+Lcom/android/internal/app/IBatteryStats;->getStatistics()[B
 Lcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->showSessionFromSession(Landroid/os/IBinder;Landroid/os/Bundle;I)Z
+Lcom/android/internal/app/IVoiceInteractionManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IVoiceInteractionManagerService;
+Lcom/android/internal/app/IVoiceInteractionManagerService;->getKeyphraseSoundModel(ILjava/lang/String;)Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel;
+Lcom/android/internal/appwidget/IAppWidgetService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/appwidget/IAppWidgetService;
+Lcom/android/internal/content/ReferrerIntent;-><init>(Landroid/content/Intent;Ljava/lang/String;)V
+Lcom/android/internal/content/ReferrerIntent;->mReferrer:Ljava/lang/String;
 Lcom/android/internal/location/ILocationProvider$Stub;-><init>()V
+Lcom/android/internal/os/BatterySipper;-><init>(Lcom/android/internal/os/BatterySipper$DrainType;Landroid/os/BatteryStats$Uid;D)V
 Lcom/android/internal/os/BatterySipper;->add(Lcom/android/internal/os/BatterySipper;)V
 Lcom/android/internal/os/BatterySipper;->drainType:Lcom/android/internal/os/BatterySipper$DrainType;
 Lcom/android/internal/os/BatterySipper;->getUid()I
-Lcom/android/internal/os/BatterySipper;-><init>(Lcom/android/internal/os/BatterySipper$DrainType;Landroid/os/BatteryStats$Uid;D)V
 Lcom/android/internal/os/BatterySipper;->mPackages:[Ljava/lang/String;
 Lcom/android/internal/os/BatterySipper;->packageWithHighestDrain:Ljava/lang/String;
 Lcom/android/internal/os/BatterySipper;->totalPowerMah:D
 Lcom/android/internal/os/BatterySipper;->uidObj:Landroid/os/BatteryStats$Uid;
+Lcom/android/internal/os/BatteryStatsHelper;-><init>(Landroid/content/Context;ZZ)V
 Lcom/android/internal/os/BatteryStatsHelper;->getMaxPower()D
 Lcom/android/internal/os/BatteryStatsHelper;->getStats()Landroid/os/BatteryStats;
 Lcom/android/internal/os/BatteryStatsHelper;->getTotalPower()D
-Lcom/android/internal/os/BatteryStatsHelper;-><init>(Landroid/content/Context;ZZ)V
 Lcom/android/internal/os/BatteryStatsHelper;->load()V
 Lcom/android/internal/os/BatteryStatsHelper;->mBatteryInfo:Lcom/android/internal/app/IBatteryStats;
 Lcom/android/internal/os/BatteryStatsHelper;->mPowerProfile:Lcom/android/internal/os/PowerProfile;
 Lcom/android/internal/os/BatteryStatsHelper;->mUsageList:Ljava/util/List;
 Lcom/android/internal/os/BatteryStatsHelper;->refreshStats(II)V
+Lcom/android/internal/os/BatteryStatsImpl$Timer;->getCountLocked(I)I
+Lcom/android/internal/os/BatteryStatsImpl$Timer;->getTotalTimeLocked(JI)J
+Lcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->getForegroundTime(I)J
+Lcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->getStarts(I)I
+Lcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->getSystemTime(I)J
+Lcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->getUserTime(I)J
+Lcom/android/internal/os/BatteryStatsImpl$Uid$Sensor;->getHandle()I
+Lcom/android/internal/os/BatteryStatsImpl$Uid$Sensor;->getSensorTime()Lcom/android/internal/os/BatteryStatsImpl$Timer;
+Lcom/android/internal/os/BatteryStatsImpl$Uid$Wakelock;->getWakeTime(I)Lcom/android/internal/os/BatteryStatsImpl$Timer;
+Lcom/android/internal/os/BatteryStatsImpl$Uid;->getProcessStats()Landroid/util/ArrayMap;
+Lcom/android/internal/os/BatteryStatsImpl$Uid;->getSensorStats()Landroid/util/SparseArray;
+Lcom/android/internal/os/BatteryStatsImpl$Uid;->getUid()I
+Lcom/android/internal/os/BatteryStatsImpl$Uid;->getWakelockStats()Landroid/util/ArrayMap;
+Lcom/android/internal/os/BatteryStatsImpl$Uid;->getWifiRunningTime(JI)J
+Lcom/android/internal/os/BatteryStatsImpl$Uid;->getWifiScanTime(JI)J
 Lcom/android/internal/os/BatteryStatsImpl;->computeBatteryRealtime(JI)J
 Lcom/android/internal/os/BatteryStatsImpl;->computeBatteryUptime(JI)J
 Lcom/android/internal/os/BatteryStatsImpl;->CREATOR:Landroid/os/Parcelable$Creator;
@@ -3054,27 +3367,14 @@
 Lcom/android/internal/os/BatteryStatsImpl;->getScreenOnTime(JI)J
 Lcom/android/internal/os/BatteryStatsImpl;->getUidStats()Landroid/util/SparseArray;
 Lcom/android/internal/os/BatteryStatsImpl;->getUidStatsLocked(I)Lcom/android/internal/os/BatteryStatsImpl$Uid;
-Lcom/android/internal/os/BatteryStatsImpl$Timer;->getCountLocked(I)I
-Lcom/android/internal/os/BatteryStatsImpl$Timer;->getTotalTimeLocked(JI)J
-Lcom/android/internal/os/BatteryStatsImpl$Uid;->getProcessStats()Landroid/util/ArrayMap;
-Lcom/android/internal/os/BatteryStatsImpl$Uid;->getSensorStats()Landroid/util/SparseArray;
-Lcom/android/internal/os/BatteryStatsImpl$Uid;->getUid()I
-Lcom/android/internal/os/BatteryStatsImpl$Uid;->getWakelockStats()Landroid/util/ArrayMap;
-Lcom/android/internal/os/BatteryStatsImpl$Uid;->getWifiRunningTime(JI)J
-Lcom/android/internal/os/BatteryStatsImpl$Uid;->getWifiScanTime(JI)J
-Lcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->getForegroundTime(I)J
-Lcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->getStarts(I)I
-Lcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->getSystemTime(I)J
-Lcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->getUserTime(I)J
-Lcom/android/internal/os/BatteryStatsImpl$Uid$Sensor;->getHandle()I
-Lcom/android/internal/os/BatteryStatsImpl$Uid$Sensor;->getSensorTime()Lcom/android/internal/os/BatteryStatsImpl$Timer;
-Lcom/android/internal/os/BatteryStatsImpl$Uid$Wakelock;->getWakeTime(I)Lcom/android/internal/os/BatteryStatsImpl$Timer;
 Lcom/android/internal/os/FuseAppLoop;->onCommand(IJJJI[B)V
 Lcom/android/internal/os/FuseAppLoop;->onOpen(JJ)[B
+Lcom/android/internal/os/IDropBoxManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/os/IDropBoxManagerService;
+Lcom/android/internal/os/PowerProfile;-><init>(Landroid/content/Context;)V
 Lcom/android/internal/os/PowerProfile;->getAveragePower(Ljava/lang/String;)D
 Lcom/android/internal/os/PowerProfile;->getAveragePower(Ljava/lang/String;I)D
 Lcom/android/internal/os/PowerProfile;->getBatteryCapacity()D
-Lcom/android/internal/os/PowerProfile;-><init>(Landroid/content/Context;)V
+Lcom/android/internal/os/SomeArgs;->arg1:Ljava/lang/Object;
 Lcom/android/internal/R$array;->config_mobile_hotspot_provision_app:I
 Lcom/android/internal/R$array;->config_tether_wifi_regexs:I
 Lcom/android/internal/R$array;->maps_starting_lat_lng:I
@@ -3110,8 +3410,8 @@
 Lcom/android/internal/R$id;->text:I
 Lcom/android/internal/R$id;->time:I
 Lcom/android/internal/R$id;->timePicker:I
-Lcom/android/internal/R$id;->title_container:I
 Lcom/android/internal/R$id;->title:I
+Lcom/android/internal/R$id;->title_container:I
 Lcom/android/internal/R$integer;->config_screenBrightnessDim:I
 Lcom/android/internal/R$integer;->config_toastDefaultGravity:I
 Lcom/android/internal/R$layout;->screen_title:I
@@ -3121,25 +3421,28 @@
 Lcom/android/internal/R$string;->megabyteShort:I
 Lcom/android/internal/R$string;->petabyteShort:I
 Lcom/android/internal/R$string;->terabyteShort:I
+Lcom/android/internal/R$style;->Theme:I
+Lcom/android/internal/R$styleable;->AbsListView:[I
 Lcom/android/internal/R$styleable;->AbsListView_cacheColorHint:I
 Lcom/android/internal/R$styleable;->AbsListView_choiceMode:I
 Lcom/android/internal/R$styleable;->AbsListView_drawSelectorOnTop:I
 Lcom/android/internal/R$styleable;->AbsListView_fastScrollAlwaysVisible:I
 Lcom/android/internal/R$styleable;->AbsListView_fastScrollEnabled:I
-Lcom/android/internal/R$styleable;->AbsListView:[I
 Lcom/android/internal/R$styleable;->AbsListView_listSelector:I
 Lcom/android/internal/R$styleable;->AbsListView_scrollingCache:I
 Lcom/android/internal/R$styleable;->AbsListView_smoothScrollbar:I
 Lcom/android/internal/R$styleable;->AbsListView_stackFromBottom:I
 Lcom/android/internal/R$styleable;->AbsListView_textFilterEnabled:I
 Lcom/android/internal/R$styleable;->AbsListView_transcriptMode:I
+Lcom/android/internal/R$styleable;->AccountAuthenticator:[I
 Lcom/android/internal/R$styleable;->AccountAuthenticator_accountPreferences:I
 Lcom/android/internal/R$styleable;->AccountAuthenticator_accountType:I
 Lcom/android/internal/R$styleable;->AccountAuthenticator_customTokens:I
-Lcom/android/internal/R$styleable;->AccountAuthenticator:[I
 Lcom/android/internal/R$styleable;->AccountAuthenticator_icon:I
 Lcom/android/internal/R$styleable;->AccountAuthenticator_label:I
 Lcom/android/internal/R$styleable;->AccountAuthenticator_smallIcon:I
+Lcom/android/internal/R$styleable;->AndroidManifest:[I
+Lcom/android/internal/R$styleable;->AndroidManifestActivity:[I
 Lcom/android/internal/R$styleable;->AndroidManifestActivity_allowTaskReparenting:I
 Lcom/android/internal/R$styleable;->AndroidManifestActivity_configChanges:I
 Lcom/android/internal/R$styleable;->AndroidManifestActivity_description:I
@@ -3147,7 +3450,6 @@
 Lcom/android/internal/R$styleable;->AndroidManifestActivity_excludeFromRecents:I
 Lcom/android/internal/R$styleable;->AndroidManifestActivity_exported:I
 Lcom/android/internal/R$styleable;->AndroidManifestActivity_hardwareAccelerated:I
-Lcom/android/internal/R$styleable;->AndroidManifestActivity:[I
 Lcom/android/internal/R$styleable;->AndroidManifestActivity_icon:I
 Lcom/android/internal/R$styleable;->AndroidManifestActivity_immersive:I
 Lcom/android/internal/R$styleable;->AndroidManifestActivity_label:I
@@ -3162,9 +3464,9 @@
 Lcom/android/internal/R$styleable;->AndroidManifestActivity_theme:I
 Lcom/android/internal/R$styleable;->AndroidManifestActivity_uiOptions:I
 Lcom/android/internal/R$styleable;->AndroidManifestActivity_windowSoftInputMode:I
+Lcom/android/internal/R$styleable;->AndroidManifestApplication:[I
 Lcom/android/internal/R$styleable;->AndroidManifestApplication_enabled:I
 Lcom/android/internal/R$styleable;->AndroidManifestApplication_hardwareAccelerated:I
-Lcom/android/internal/R$styleable;->AndroidManifestApplication:[I
 Lcom/android/internal/R$styleable;->AndroidManifestApplication_label:I
 Lcom/android/internal/R$styleable;->AndroidManifestApplication_largeHeap:I
 Lcom/android/internal/R$styleable;->AndroidManifestApplication_name:I
@@ -3174,62 +3476,61 @@
 Lcom/android/internal/R$styleable;->AndroidManifestApplication_theme:I
 Lcom/android/internal/R$styleable;->AndroidManifestApplication_uiOptions:I
 Lcom/android/internal/R$styleable;->AndroidManifestData:[I
-Lcom/android/internal/R$styleable;->AndroidManifest:[I
-Lcom/android/internal/R$styleable;->AndroidManifest_installLocation:I
 Lcom/android/internal/R$styleable;->AndroidManifestIntentFilter:[I
 Lcom/android/internal/R$styleable;->AndroidManifestIntentFilter_priority:I
 Lcom/android/internal/R$styleable;->AndroidManifestMetaData:[I
 Lcom/android/internal/R$styleable;->AndroidManifestMetaData_name:I
 Lcom/android/internal/R$styleable;->AndroidManifestMetaData_resource:I
 Lcom/android/internal/R$styleable;->AndroidManifestMetaData_value:I
+Lcom/android/internal/R$styleable;->AndroidManifestService:[I
 Lcom/android/internal/R$styleable;->AndroidManifestService_enabled:I
 Lcom/android/internal/R$styleable;->AndroidManifestService_exported:I
-Lcom/android/internal/R$styleable;->AndroidManifestService:[I
 Lcom/android/internal/R$styleable;->AndroidManifestService_name:I
 Lcom/android/internal/R$styleable;->AndroidManifestService_permission:I
 Lcom/android/internal/R$styleable;->AndroidManifestService_process:I
-Lcom/android/internal/R$styleable;->AndroidManifest_sharedUserId:I
 Lcom/android/internal/R$styleable;->AndroidManifestUsesPermission:[I
 Lcom/android/internal/R$styleable;->AndroidManifestUsesPermission_name:I
 Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk:[I
 Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk_minSdkVersion:I
 Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk_targetSdkVersion:I
+Lcom/android/internal/R$styleable;->AndroidManifest_installLocation:I
+Lcom/android/internal/R$styleable;->AndroidManifest_sharedUserId:I
 Lcom/android/internal/R$styleable;->AndroidManifest_versionCode:I
 Lcom/android/internal/R$styleable;->AndroidManifest_versionName:I
-Lcom/android/internal/R$styleable;->CheckBoxPreference_disableDependentsState:I
 Lcom/android/internal/R$styleable;->CheckBoxPreference:[I
+Lcom/android/internal/R$styleable;->CheckBoxPreference_disableDependentsState:I
 Lcom/android/internal/R$styleable;->CheckBoxPreference_summaryOff:I
 Lcom/android/internal/R$styleable;->CheckBoxPreference_summaryOn:I
+Lcom/android/internal/R$styleable;->CompoundButton:[I
 Lcom/android/internal/R$styleable;->CompoundButton_button:I
 Lcom/android/internal/R$styleable;->CompoundButton_checked:I
-Lcom/android/internal/R$styleable;->CompoundButton:[I
-Lcom/android/internal/R$styleable;->DialogPreference_dialogTitle:I
 Lcom/android/internal/R$styleable;->DialogPreference:[I
-Lcom/android/internal/R$styleable;->EdgeEffect_colorEdgeEffect:I
+Lcom/android/internal/R$styleable;->DialogPreference_dialogTitle:I
 Lcom/android/internal/R$styleable;->EdgeEffect:[I
+Lcom/android/internal/R$styleable;->EdgeEffect_colorEdgeEffect:I
 Lcom/android/internal/R$styleable;->GridView:[I
 Lcom/android/internal/R$styleable;->IconMenuView:[I
 Lcom/android/internal/R$styleable;->ImageView:[I
 Lcom/android/internal/R$styleable;->ImageView_scaleType:I
 Lcom/android/internal/R$styleable;->ImageView_src:I
-Lcom/android/internal/R$styleable;->ListPreference_entries:I
 Lcom/android/internal/R$styleable;->ListPreference:[I
-Lcom/android/internal/R$styleable;->ListView_dividerHeight:I
+Lcom/android/internal/R$styleable;->ListPreference_entries:I
+Lcom/android/internal/R$styleable;->ListView:[I
 Lcom/android/internal/R$styleable;->ListView_divider:I
+Lcom/android/internal/R$styleable;->ListView_dividerHeight:I
 Lcom/android/internal/R$styleable;->ListView_entries:I
 Lcom/android/internal/R$styleable;->ListView_footerDividersEnabled:I
 Lcom/android/internal/R$styleable;->ListView_headerDividersEnabled:I
-Lcom/android/internal/R$styleable;->ListView:[I
 Lcom/android/internal/R$styleable;->ListView_overScrollFooter:I
 Lcom/android/internal/R$styleable;->ListView_overScrollHeader:I
 Lcom/android/internal/R$styleable;->PopupWindow:[I
+Lcom/android/internal/R$styleable;->Preference:[I
+Lcom/android/internal/R$styleable;->PreferenceGroup:[I
+Lcom/android/internal/R$styleable;->PreferenceGroup_orderingFromXml:I
 Lcom/android/internal/R$styleable;->Preference_defaultValue:I
 Lcom/android/internal/R$styleable;->Preference_dependency:I
 Lcom/android/internal/R$styleable;->Preference_enabled:I
 Lcom/android/internal/R$styleable;->Preference_fragment:I
-Lcom/android/internal/R$styleable;->PreferenceGroup:[I
-Lcom/android/internal/R$styleable;->PreferenceGroup_orderingFromXml:I
-Lcom/android/internal/R$styleable;->Preference:[I
 Lcom/android/internal/R$styleable;->Preference_icon:I
 Lcom/android/internal/R$styleable;->Preference_key:I
 Lcom/android/internal/R$styleable;->Preference_layout:I
@@ -3240,73 +3541,76 @@
 Lcom/android/internal/R$styleable;->Preference_summary:I
 Lcom/android/internal/R$styleable;->Preference_title:I
 Lcom/android/internal/R$styleable;->Preference_widgetLayout:I
-Lcom/android/internal/R$styleable;->ScrollView_fillViewport:I
 Lcom/android/internal/R$styleable;->ScrollView:[I
+Lcom/android/internal/R$styleable;->ScrollView_fillViewport:I
+Lcom/android/internal/R$styleable;->SyncAdapter:[I
 Lcom/android/internal/R$styleable;->SyncAdapter_accountType:I
 Lcom/android/internal/R$styleable;->SyncAdapter_allowParallelSyncs:I
 Lcom/android/internal/R$styleable;->SyncAdapter_contentAuthority:I
-Lcom/android/internal/R$styleable;->SyncAdapter:[I
 Lcom/android/internal/R$styleable;->SyncAdapter_isAlwaysSyncable:I
 Lcom/android/internal/R$styleable;->SyncAdapter_settingsActivity:I
 Lcom/android/internal/R$styleable;->SyncAdapter_supportsUploading:I
 Lcom/android/internal/R$styleable;->SyncAdapter_userVisible:I
 Lcom/android/internal/R$styleable;->TabWidget:[I
 Lcom/android/internal/R$styleable;->TextAppearance:[I
+Lcom/android/internal/R$styleable;->TextView:[I
 Lcom/android/internal/R$styleable;->TextViewAppearance:[I
 Lcom/android/internal/R$styleable;->TextView_drawableBottom:I
 Lcom/android/internal/R$styleable;->TextView_drawableLeft:I
 Lcom/android/internal/R$styleable;->TextView_drawableRight:I
 Lcom/android/internal/R$styleable;->TextView_drawableTop:I
-Lcom/android/internal/R$styleable;->TextView:[I
 Lcom/android/internal/R$styleable;->TextView_maxLines:I
-Lcom/android/internal/R$styleable;->TextView_textColorHint:I
 Lcom/android/internal/R$styleable;->TextView_textColor:I
-Lcom/android/internal/R$styleable;->View_background:I
+Lcom/android/internal/R$styleable;->TextView_textColorHint:I
+Lcom/android/internal/R$styleable;->View:[I
 Lcom/android/internal/R$styleable;->ViewGroup_Layout:[I
 Lcom/android/internal/R$styleable;->ViewGroup_Layout_layout_height:I
 Lcom/android/internal/R$styleable;->ViewGroup_Layout_layout_width:I
-Lcom/android/internal/R$styleable;->View:[I
-Lcom/android/internal/R$styleable;->View_id:I
 Lcom/android/internal/R$styleable;->ViewStub:[I
 Lcom/android/internal/R$styleable;->ViewStub_inflatedId:I
 Lcom/android/internal/R$styleable;->ViewStub_layout:I
+Lcom/android/internal/R$styleable;->View_background:I
+Lcom/android/internal/R$styleable;->View_id:I
 Lcom/android/internal/R$styleable;->Window:[I
 Lcom/android/internal/R$styleable;->Window_windowActionBarFullscreenDecorLayout:I
 Lcom/android/internal/R$styleable;->Window_windowIsFloating:I
 Lcom/android/internal/R$styleable;->Window_windowIsTranslucent:I
 Lcom/android/internal/R$styleable;->Window_windowShowWallpaper:I
-Lcom/android/internal/R$style;->Theme:I
 Lcom/android/internal/R$xml;->power_profile:I
-Lcom/android/internal/telephony/IPhoneSubInfo$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IPhoneSubInfo;
+Lcom/android/internal/telephony/IMms$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IMms;
 Lcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Lcom/android/internal/telephony/IPhoneSubInfo$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IPhoneSubInfo;
 Lcom/android/internal/telephony/ISms$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ISms;
 Lcom/android/internal/telephony/ISub$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Lcom/android/internal/telephony/ITelephony$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->endCall()Z
+Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Lcom/android/internal/telephony/ITelephony$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephony;
+Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_call:I
+Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_endCall:I
+Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_getDeviceId:I
 Lcom/android/internal/telephony/ITelephony;->answerRingingCall()V
 Lcom/android/internal/telephony/ITelephony;->call(Ljava/lang/String;Ljava/lang/String;)V
 Lcom/android/internal/telephony/ITelephony;->dial(Ljava/lang/String;)V
 Lcom/android/internal/telephony/ITelephony;->disableDataConnectivity()Z
 Lcom/android/internal/telephony/ITelephony;->enableDataConnectivity()Z
 Lcom/android/internal/telephony/ITelephony;->endCall()Z
+Lcom/android/internal/telephony/ITelephony;->endCallForSubscriber(I)Z
 Lcom/android/internal/telephony/ITelephony;->getCallState()I
 Lcom/android/internal/telephony/ITelephony;->getDataState()I
 Lcom/android/internal/telephony/ITelephony;->isIdle(Ljava/lang/String;)Z
-Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCallState(ILjava/lang/String;)V
-Lcom/android/internal/telephony/ITelephonyRegistry$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephonyRegistry;
 Lcom/android/internal/telephony/ITelephony;->setRadio(Z)Z
 Lcom/android/internal/telephony/ITelephony;->silenceRinger()V
-Lcom/android/internal/telephony/ITelephony$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephony;
-Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->endCall()Z
-Lcom/android/internal/telephony/ITelephony$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_call:I
-Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_endCall:I
-Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_getDeviceId:I
-Lcom/android/internal/telephony/SmsHeader;->concatRef:Lcom/android/internal/telephony/SmsHeader$ConcatRef;
+Lcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Lcom/android/internal/telephony/ITelephonyRegistry$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephonyRegistry;
+Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCallState(ILjava/lang/String;)V
 Lcom/android/internal/telephony/SmsHeader$ConcatRef;->msgCount:I
 Lcom/android/internal/telephony/SmsHeader$ConcatRef;->refNumber:I
 Lcom/android/internal/telephony/SmsHeader$ConcatRef;->seqNumber:I
+Lcom/android/internal/telephony/SmsHeader;->concatRef:Lcom/android/internal/telephony/SmsHeader$ConcatRef;
 Lcom/android/internal/telephony/SmsMessageBase;->mUserDataHeader:Lcom/android/internal/telephony/SmsHeader;
-Lcom/android/internal/telephony/SmsRawData;->CREATOR:Landroid/os/Parcelable$Creator;
 Lcom/android/internal/telephony/SmsRawData;-><init>([B)V
+Lcom/android/internal/telephony/SmsRawData;->CREATOR:Landroid/os/Parcelable$Creator;
 Lcom/android/internal/textservice/ITextServicesManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Lcom/android/internal/util/AsyncChannel;->sendMessage(III)V
 Lcom/android/internal/util/FastPrintWriter;-><init>(Ljava/io/OutputStream;)V
@@ -3315,9 +3619,9 @@
 Lcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Ljava/io/OutputStream;)V
 Lcom/android/internal/view/IInputConnectionWrapper;->mInputConnection:Landroid/view/inputmethod/InputConnection;
 Lcom/android/internal/view/IInputConnectionWrapper;->mLock:Ljava/lang/Object;
-Lcom/android/internal/view/IInputMethodManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodManager;
-Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;->getEnabledInputMethodList()Ljava/util/List;
 Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;->getEnabledInputMethodList()Ljava/util/List;
+Lcom/android/internal/view/IInputMethodManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodManager;
 Lcom/android/internal/view/InputBindResult;->CREATOR:Landroid/os/Parcelable$Creator;
 Lcom/android/internal/view/menu/MenuBuilder;-><init>(Landroid/content/Context;)V
 Lcom/android/internal/view/menu/MenuBuilder;->mContext:Landroid/content/Context;
@@ -3334,8 +3638,8 @@
 Lcom/android/okhttp/HttpUrl;->encodedPath()Ljava/lang/String;
 Lcom/android/okhttp/HttpUrl;->query()Ljava/lang/String;
 Lcom/android/okhttp/internal/http/HttpEngine;->httpStream:Lcom/android/okhttp/internal/http/HttpStream;
-Lcom/android/okhttp/internal/http/HttpEngine;->networkRequest:Lcom/android/okhttp/Request;
 Lcom/android/okhttp/internal/http/HttpEngine;->networkRequest(Lcom/android/okhttp/Request;)Lcom/android/okhttp/Request;
+Lcom/android/okhttp/internal/http/HttpEngine;->networkRequest:Lcom/android/okhttp/Request;
 Lcom/android/okhttp/internal/http/HttpEngine;->priorResponse:Lcom/android/okhttp/Response;
 Lcom/android/okhttp/internal/http/HttpEngine;->userResponse:Lcom/android/okhttp/Response;
 Lcom/android/okhttp/OkHttpClient;->connectionPool:Lcom/android/okhttp/ConnectionPool;
@@ -3397,9 +3701,9 @@
 Ldalvik/system/BaseDexClassLoader;->addDexPath(Ljava/lang/String;)V
 Ldalvik/system/BaseDexClassLoader;->getLdLibraryPath()Ljava/lang/String;
 Ldalvik/system/BaseDexClassLoader;->pathList:Ldalvik/system/DexPathList;
-Ldalvik/system/BlockGuard;->getThreadPolicy()Ldalvik/system/BlockGuard$Policy;
 Ldalvik/system/BlockGuard$Policy;->onNetwork()V
 Ldalvik/system/BlockGuard$Policy;->onReadFromDisk()V
+Ldalvik/system/BlockGuard;->getThreadPolicy()Ldalvik/system/BlockGuard$Policy;
 Ldalvik/system/CloseGuard;->close()V
 Ldalvik/system/CloseGuard;->get()Ldalvik/system/CloseGuard;
 Ldalvik/system/CloseGuard;->open(Ljava/lang/String;)V
@@ -3412,32 +3716,35 @@
 Ldalvik/system/DexFile;->mFileName:Ljava/lang/String;
 Ldalvik/system/DexFile;->mInternalCookie:Ljava/lang/Object;
 Ldalvik/system/DexFile;->openDexFile(Ljava/lang/String;Ljava/lang/String;ILjava/lang/ClassLoader;[Ldalvik/system/DexPathList$Element;)Ljava/lang/Object;
+Ldalvik/system/DexPathList$Element;-><init>(Ldalvik/system/DexFile;Ljava/io/File;)V
+Ldalvik/system/DexPathList$Element;-><init>(Ljava/io/File;ZLjava/io/File;Ldalvik/system/DexFile;)V
+Ldalvik/system/DexPathList$Element;->dexFile:Ldalvik/system/DexFile;
+Ldalvik/system/DexPathList$NativeLibraryElement;-><init>(Ljava/io/File;)V
+Ldalvik/system/DexPathList$NativeLibraryElement;->path:Ljava/io/File;
+Ldalvik/system/DexPathList;-><init>(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;Ljava/io/File;)V
 Ldalvik/system/DexPathList;->addDexPath(Ljava/lang/String;Ljava/io/File;)V
 Ldalvik/system/DexPathList;->definingContext:Ljava/lang/ClassLoader;
 Ldalvik/system/DexPathList;->dexElements:[Ldalvik/system/DexPathList$Element;
-Ldalvik/system/DexPathList$Element;->dexFile:Ldalvik/system/DexFile;
-Ldalvik/system/DexPathList$Element;-><init>(Ldalvik/system/DexFile;Ljava/io/File;)V
-Ldalvik/system/DexPathList$Element;-><init>(Ljava/io/File;ZLjava/io/File;Ldalvik/system/DexFile;)V
-Ldalvik/system/DexPathList;-><init>(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;Ljava/io/File;)V
 Ldalvik/system/DexPathList;->loadDexFile(Ljava/io/File;Ljava/io/File;Ljava/lang/ClassLoader;[Ldalvik/system/DexPathList$Element;)Ldalvik/system/DexFile;
 Ldalvik/system/DexPathList;->makeDexElements(Ljava/util/List;Ljava/io/File;Ljava/util/List;Ljava/lang/ClassLoader;)[Ldalvik/system/DexPathList$Element;
 Ldalvik/system/DexPathList;->makeInMemoryDexElements([Ljava/nio/ByteBuffer;Ljava/util/List;)[Ldalvik/system/DexPathList$Element;
 Ldalvik/system/DexPathList;->makePathElements(Ljava/util/List;)[Ldalvik/system/DexPathList$NativeLibraryElement;
 Ldalvik/system/DexPathList;->makePathElements(Ljava/util/List;Ljava/io/File;Ljava/util/List;)[Ldalvik/system/DexPathList$Element;
 Ldalvik/system/DexPathList;->nativeLibraryDirectories:Ljava/util/List;
-Ldalvik/system/DexPathList$NativeLibraryElement;-><init>(Ljava/io/File;)V
-Ldalvik/system/DexPathList$NativeLibraryElement;->path:Ljava/io/File;
 Ldalvik/system/DexPathList;->nativeLibraryPathElements:[Ldalvik/system/DexPathList$NativeLibraryElement;
 Ldalvik/system/DexPathList;->splitPaths(Ljava/lang/String;Z)Ljava/util/List;
 Ldalvik/system/DexPathList;->systemNativeLibraryDirectories:Ljava/util/List;
 Ldalvik/system/VMDebug;->dumpReferenceTables()V
+Ldalvik/system/VMDebug;->isDebuggerConnected()Z
 Ldalvik/system/VMRuntime;->addressOf(Ljava/lang/Object;)J
 Ldalvik/system/VMRuntime;->clearGrowthLimit()V
+Ldalvik/system/VMRuntime;->gcSoftReferences()V
 Ldalvik/system/VMRuntime;->getCurrentInstructionSet()Ljava/lang/String;
+Ldalvik/system/VMRuntime;->getExternalBytesAllocated()J
 Ldalvik/system/VMRuntime;->getInstructionSet(Ljava/lang/String;)Ljava/lang/String;
 Ldalvik/system/VMRuntime;->getRuntime()Ldalvik/system/VMRuntime;
-Ldalvik/system/VMRuntime;->is64BitAbi(Ljava/lang/String;)Z
 Ldalvik/system/VMRuntime;->is64Bit()Z
+Ldalvik/system/VMRuntime;->is64BitAbi(Ljava/lang/String;)Z
 Ldalvik/system/VMRuntime;->newNonMovableArray(Ljava/lang/Class;I)Ljava/lang/Object;
 Ldalvik/system/VMRuntime;->registerNativeAllocation(I)V
 Ldalvik/system/VMRuntime;->registerNativeFree(I)V
@@ -3451,20 +3758,20 @@
 Ldalvik/system/VMRuntime;->vmLibrary()Ljava/lang/String;
 Ldalvik/system/VMStack;->getCallingClassLoader()Ljava/lang/ClassLoader;
 Ldalvik/system/VMStack;->getStackClass2()Ljava/lang/Class;
+Ljava/io/File;->filePath:Ljava/nio/file/Path;
+Ljava/io/File;->fs:Ljava/io/FileSystem;
+Ljava/io/File;->path:Ljava/lang/String;
+Ljava/io/File;->prefixLength:I
+Ljava/io/File;->status:Ljava/io/File$PathStatus;
 Ljava/io/FileDescriptor;->descriptor:I
 Ljava/io/FileDescriptor;->getInt$()I
 Ljava/io/FileDescriptor;->isSocket$()Z
 Ljava/io/FileDescriptor;->setInt$(I)V
-Ljava/io/File;->filePath:Ljava/nio/file/Path;
-Ljava/io/File;->fs:Ljava/io/FileSystem;
 Ljava/io/FileInputStream;->fd:Ljava/io/FileDescriptor;
 Ljava/io/FileOutputStream;->fd:Ljava/io/FileDescriptor;
-Ljava/io/File;->path:Ljava/lang/String;
-Ljava/io/File;->prefixLength:I
-Ljava/io/File;->status:Ljava/io/File$PathStatus;
 Ljava/io/ObjectStreamClass;->getConstructorId(Ljava/lang/Class;)J
-Ljava/io/ObjectStreamClass;->newInstance(Ljava/lang/Class;J)Ljava/lang/Object;
 Ljava/io/ObjectStreamClass;->newInstance()Ljava/lang/Object;
+Ljava/io/ObjectStreamClass;->newInstance(Ljava/lang/Class;J)Ljava/lang/Object;
 Ljava/lang/AbstractStringBuilder;->value:[C
 Ljava/lang/Boolean;->value:Z
 Ljava/lang/Byte;->value:B
@@ -3481,8 +3788,8 @@
 Ljava/lang/Daemons$FinalizerDaemon;->finalizingObject:Ljava/lang/Object;
 Ljava/lang/Daemons$FinalizerDaemon;->INSTANCE:Ljava/lang/Daemons$FinalizerDaemon;
 Ljava/lang/Daemons$FinalizerWatchdogDaemon;->INSTANCE:Ljava/lang/Daemons$FinalizerWatchdogDaemon;
-Ljava/lang/Daemons;->MAX_FINALIZE_NANOS:J
 Ljava/lang/Daemons$ReferenceQueueDaemon;->INSTANCE:Ljava/lang/Daemons$ReferenceQueueDaemon;
+Ljava/lang/Daemons;->MAX_FINALIZE_NANOS:J
 Ljava/lang/Daemons;->requestHeapTrim()V
 Ljava/lang/Daemons;->start()V
 Ljava/lang/Daemons;->stop()V
@@ -3496,42 +3803,43 @@
 Ljava/lang/ref/FinalizerReference;->next:Ljava/lang/ref/FinalizerReference;
 Ljava/lang/ref/FinalizerReference;->queue:Ljava/lang/ref/ReferenceQueue;
 Ljava/lang/ref/FinalizerReference;->remove(Ljava/lang/ref/FinalizerReference;)V
+Ljava/lang/ref/Reference;->getReferent()Ljava/lang/Object;
+Ljava/lang/ref/Reference;->referent:Ljava/lang/Object;
+Ljava/lang/ref/ReferenceQueue;->add(Ljava/lang/ref/Reference;)V
 Ljava/lang/reflect/Executable;->artMethod:J
+Ljava/lang/reflect/Field;->accessFlags:I
 Ljava/lang/reflect/Parameter;-><init>(Ljava/lang/String;ILjava/lang/reflect/Executable;I)V
 Ljava/lang/reflect/Proxy;->invoke(Ljava/lang/reflect/Proxy;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/ref/Reference;->getReferent()Ljava/lang/Object;
-Ljava/lang/ref/ReferenceQueue;->add(Ljava/lang/ref/Reference;)V
-Ljava/lang/ref/Reference;->referent:Ljava/lang/Object;
-Ljava/lang/Runtime;->loadLibrary(Ljava/lang/String;Ljava/lang/ClassLoader;)V
 Ljava/lang/Runtime;->load(Ljava/lang/String;Ljava/lang/ClassLoader;)V
+Ljava/lang/Runtime;->loadLibrary(Ljava/lang/String;Ljava/lang/ClassLoader;)V
 Ljava/lang/Runtime;->mLibPaths:[Ljava/lang/String;
 Ljava/lang/Runtime;->nativeLoad(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/String;
 Ljava/lang/Short;->value:S
-Ljava/lang/String;->getCharsNoCheck(II[CI)V
 Ljava/lang/String;-><init>(II[C)V
+Ljava/lang/String;->getCharsNoCheck(II[CI)V
+Ljava/lang/System;-><init>()V
 Ljava/lang/System;->arraycopy([CI[CII)V
 Ljava/lang/System;->arraycopy([II[III)V
-Ljava/lang/System;-><init>()V
+Ljava/lang/Thread;-><init>(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V
 Ljava/lang/Thread;->contextClassLoader:Ljava/lang/ClassLoader;
 Ljava/lang/Thread;->daemon:Z
 Ljava/lang/Thread;->dispatchUncaughtException(Ljava/lang/Throwable;)V
-Ljava/lang/ThreadGroup;->add(Ljava/lang/Thread;)V
-Ljava/lang/ThreadGroup;->groups:[Ljava/lang/ThreadGroup;
 Ljava/lang/Thread;->group:Ljava/lang/ThreadGroup;
-Ljava/lang/ThreadGroup;->mainThreadGroup:Ljava/lang/ThreadGroup;
-Ljava/lang/ThreadGroup;->name:Ljava/lang/String;
-Ljava/lang/ThreadGroup;->ngroups:I
-Ljava/lang/ThreadGroup;->parent:Ljava/lang/ThreadGroup;
-Ljava/lang/ThreadGroup;->systemThreadGroup:Ljava/lang/ThreadGroup;
-Ljava/lang/ThreadGroup;->threadTerminated(Ljava/lang/Thread;)V
 Ljava/lang/Thread;->inheritableThreadLocals:Ljava/lang/ThreadLocal$ThreadLocalMap;
-Ljava/lang/Thread;-><init>(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V
 Ljava/lang/Thread;->lock:Ljava/lang/Object;
 Ljava/lang/Thread;->name:Ljava/lang/String;
 Ljava/lang/Thread;->nativePeer:J
 Ljava/lang/Thread;->parkBlocker:Ljava/lang/Object;
 Ljava/lang/Thread;->priority:I
 Ljava/lang/Thread;->threadLocals:Ljava/lang/ThreadLocal$ThreadLocalMap;
+Ljava/lang/ThreadGroup;->add(Ljava/lang/Thread;)V
+Ljava/lang/ThreadGroup;->groups:[Ljava/lang/ThreadGroup;
+Ljava/lang/ThreadGroup;->mainThreadGroup:Ljava/lang/ThreadGroup;
+Ljava/lang/ThreadGroup;->name:Ljava/lang/String;
+Ljava/lang/ThreadGroup;->ngroups:I
+Ljava/lang/ThreadGroup;->parent:Ljava/lang/ThreadGroup;
+Ljava/lang/ThreadGroup;->systemThreadGroup:Ljava/lang/ThreadGroup;
+Ljava/lang/ThreadGroup;->threadTerminated(Ljava/lang/Thread;)V
 Ljava/lang/Throwable;->backtrace:Ljava/lang/Object;
 Ljava/lang/Throwable;->cause:Ljava/lang/Throwable;
 Ljava/lang/Throwable;->detailMessage:Ljava/lang/String;
@@ -3558,19 +3866,19 @@
 Ljava/net/HttpCookie;->version:I
 Ljava/net/HttpCookie;->whenCreated:J
 Ljava/net/Inet4Address;-><init>()V
-Ljava/net/Inet6Address;->holder6:Ljava/net/Inet6Address$Inet6AddressHolder;
 Ljava/net/Inet6Address$Inet6AddressHolder;->ipaddress:[B
 Ljava/net/Inet6Address$Inet6AddressHolder;->scope_id:I
 Ljava/net/Inet6Address$Inet6AddressHolder;->scope_id_set:Z
 Ljava/net/Inet6Address$Inet6AddressHolder;->scope_ifname:Ljava/net/NetworkInterface;
 Ljava/net/Inet6Address;-><init>()V
-Ljava/net/InetAddress;->clearDnsCache()V
-Ljava/net/InetAddress;->holder:Ljava/net/InetAddress$InetAddressHolder;
-Ljava/net/InetAddress;->holder()Ljava/net/InetAddress$InetAddressHolder;
+Ljava/net/Inet6Address;->holder6:Ljava/net/Inet6Address$Inet6AddressHolder;
 Ljava/net/InetAddress$InetAddressHolder;->address:I
 Ljava/net/InetAddress$InetAddressHolder;->family:I
 Ljava/net/InetAddress$InetAddressHolder;->hostName:Ljava/lang/String;
 Ljava/net/InetAddress$InetAddressHolder;->originalHostName:Ljava/lang/String;
+Ljava/net/InetAddress;->clearDnsCache()V
+Ljava/net/InetAddress;->holder()Ljava/net/InetAddress$InetAddressHolder;
+Ljava/net/InetAddress;->holder:Ljava/net/InetAddress$InetAddressHolder;
 Ljava/net/InetAddress;->isNumeric(Ljava/lang/String;)Z
 Ljava/net/InetAddress;->parseNumericAddress(Ljava/lang/String;)Ljava/net/InetAddress;
 Ljava/net/Socket;->getFileDescriptor$()Ljava/io/FileDescriptor;
@@ -3585,9 +3893,9 @@
 Ljava/net/URL;->handlers:Ljava/util/Hashtable;
 Ljava/nio/Buffer;->address:J
 Ljava/nio/Buffer;->capacity:I
-Ljava/nio/Buffer;->_elementSizeShift:I
 Ljava/nio/Buffer;->limit:I
 Ljava/nio/Buffer;->position:I
+Ljava/nio/Buffer;->_elementSizeShift:I
 Ljava/nio/ByteBuffer;->hb:[B
 Ljava/nio/ByteBuffer;->isReadOnly:Z
 Ljava/nio/ByteBuffer;->offset:I
@@ -3604,11 +3912,11 @@
 Ljava/util/ArrayDeque;->elements:[Ljava/lang/Object;
 Ljava/util/ArrayDeque;->head:I
 Ljava/util/ArrayDeque;->tail:I
-Ljava/util/ArrayList;->elementData:[Ljava/lang/Object;
-Ljava/util/ArrayList;->size:I
 Ljava/util/ArrayList$SubList;->parent:Ljava/util/AbstractList;
 Ljava/util/ArrayList$SubList;->parentOffset:I
 Ljava/util/ArrayList$SubList;->size:I
+Ljava/util/ArrayList;->elementData:[Ljava/lang/Object;
+Ljava/util/ArrayList;->size:I
 Ljava/util/Arrays$ArrayList;->a:[Ljava/lang/Object;
 Ljava/util/Calendar;->zone:Ljava/util/TimeZone;
 Ljava/util/Collections$EmptyList;-><init>()V
@@ -3634,12 +3942,13 @@
 Ljava/util/EnumMap;->keyType:Ljava/lang/Class;
 Ljava/util/EnumSet;->elementType:Ljava/lang/Class;
 Ljava/util/HashMap$HashIterator;->hasNext()Z
+Ljava/util/HashMap$HashIterator;->remove()V
 Ljava/util/HashMap;->modCount:I
 Ljava/util/HashMap;->table:[Ljava/util/HashMap$Node;
 Ljava/util/HashSet;->map:Ljava/util/HashMap;
 Ljava/util/jar/JarFile;->manifest:Ljava/util/jar/Manifest;
-Ljava/util/LinkedHashMap;->eldest()Ljava/util/Map$Entry;
 Ljava/util/LinkedHashMap$LinkedHashIterator;->hasNext()Z
+Ljava/util/LinkedHashMap;->eldest()Ljava/util/Map$Entry;
 Ljava/util/LinkedList;->size:I
 Ljava/util/Locale;->createConstant(Ljava/lang/String;Ljava/lang/String;)Ljava/util/Locale;
 Ljava/util/PriorityQueue;->modCount:I
@@ -3650,8 +3959,8 @@
 Ljava/util/UUID;->mostSigBits:J
 Ljava/util/Vector;->elementData(I)Ljava/lang/Object;
 Ljava/util/zip/Deflater;->buf:[B
-Ljava/util/zip/Deflater;->finished:Z
 Ljava/util/zip/Deflater;->finish:Z
+Ljava/util/zip/Deflater;->finished:Z
 Ljava/util/zip/Deflater;->len:I
 Ljava/util/zip/Deflater;->level:I
 Ljava/util/zip/Deflater;->off:I
@@ -3668,8 +3977,8 @@
 Ljavax/net/ssl/SSLSocketFactory;->defaultSocketFactory:Ljavax/net/ssl/SSLSocketFactory;
 Llibcore/util/BasicLruCache;->map:Ljava/util/LinkedHashMap;
 Llibcore/util/ZoneInfo;->mTransitions:[J
-Lorg/apache/http/conn/ssl/SSLSocketFactory;-><init>(Ljavax/net/ssl/SSLSocketFactory;)V
 Lorg/apache/http/conn/ssl/SSLSocketFactory;-><init>()V
+Lorg/apache/http/conn/ssl/SSLSocketFactory;-><init>(Ljavax/net/ssl/SSLSocketFactory;)V
 Lorg/ccil/cowan/tagsoup/AttributesImpl;->data:[Ljava/lang/String;
 Lorg/ccil/cowan/tagsoup/AttributesImpl;->length:I
 Lorg/json/JSONArray;->values:Ljava/util/List;
diff --git a/config/hiddenapi-vendor-list.txt b/config/hiddenapi-vendor-list.txt
index 88f8794..b5cce56 100644
--- a/config/hiddenapi-vendor-list.txt
+++ b/config/hiddenapi-vendor-list.txt
@@ -1,24 +1,24 @@
 Landroid/accounts/AccountManager;-><init>(Landroid/content/Context;Landroid/accounts/IAccountManager;Landroid/os/Handler;)V
 Landroid/app/Activity;->managedQuery(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
-Landroid/app/ActivityManagerNative;->broadcastStickyIntent(Landroid/content/Intent;Ljava/lang/String;I)V
+Landroid/app/Activity;->registerRemoteAnimations(Landroid/view/RemoteAnimationDefinition;)V
 Landroid/app/ActivityManager$RecentTaskInfo;->configuration:Landroid/content/res/Configuration;
 Landroid/app/ActivityManager$TaskDescription;->loadTaskDescriptionIcon(Ljava/lang/String;I)Landroid/graphics/Bitmap;
 Landroid/app/ActivityManager$TaskSnapshot;->getSnapshot()Landroid/graphics/GraphicBuffer;
+Landroid/app/ActivityManagerNative;->broadcastStickyIntent(Landroid/content/Intent;Ljava/lang/String;I)V
 Landroid/app/ActivityOptions;->makeRemoteAnimation(Landroid/view/RemoteAnimationAdapter;)Landroid/app/ActivityOptions;
 Landroid/app/ActivityOptions;->setSplitScreenCreateMode(I)V
-Landroid/app/Activity;->registerRemoteAnimations(Landroid/view/RemoteAnimationDefinition;)V
 Landroid/app/ActivityView;-><init>(Landroid/content/Context;)V
 Landroid/app/ActivityView;->release()V
 Landroid/app/ActivityView;->startActivity(Landroid/app/PendingIntent;)V
 Landroid/app/ActivityView;->startActivity(Landroid/content/Intent;)V
-Landroid/app/AppOpsManager;->getPackagesForOps([I)Ljava/util/List;
-Landroid/app/AppOpsManager;->getToken(Lcom/android/internal/app/IAppOpsService;)Landroid/os/IBinder;
 Landroid/app/AppOpsManager$OpEntry;->getOp()I
 Landroid/app/AppOpsManager$OpEntry;->getTime()J
 Landroid/app/AppOpsManager$OpEntry;->isRunning()Z
 Landroid/app/AppOpsManager$PackageOps;->getOps()Ljava/util/List;
 Landroid/app/AppOpsManager$PackageOps;->getPackageName()Ljava/lang/String;
 Landroid/app/AppOpsManager$PackageOps;->getUid()I
+Landroid/app/AppOpsManager;->getPackagesForOps([I)Ljava/util/List;
+Landroid/app/AppOpsManager;->getToken(Lcom/android/internal/app/IAppOpsService;)Landroid/os/IBinder;
 Landroid/app/IActivityController$Stub;-><init>()V
 Landroid/app/IActivityManager;->cancelRecentsAnimation(Z)V
 Landroid/app/IActivityManager;->cancelTaskWindowTransition(I)V
@@ -32,15 +32,14 @@
 Landroid/app/IActivityManager;->getTaskSnapshot(IZ)Landroid/app/ActivityManager$TaskSnapshot;
 Landroid/app/IActivityManager;->registerTaskStackListener(Landroid/app/ITaskStackListener;)V
 Landroid/app/IActivityManager;->removeTask(I)Z
+Landroid/app/IActivityManager;->startActivity(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;)I
 Landroid/app/IActivityManager;->startActivityAsUser(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;I)I
 Landroid/app/IActivityManager;->startActivityFromRecents(ILandroid/os/Bundle;)I
-Landroid/app/IActivityManager;->startActivity(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;)I
 Landroid/app/IActivityManager;->startRecentsActivity(Landroid/content/Intent;Landroid/app/IAssistDataReceiver;Landroid/view/IRecentsAnimationRunner;)V
 Landroid/app/IAlarmManager;->setTime(J)Z
-Landroid/app/IAlarmManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IAlarmManager;
+Landroid/app/IAssistDataReceiver$Stub;-><init>()V
 Landroid/app/IAssistDataReceiver;->onHandleAssistData(Landroid/os/Bundle;)V
 Landroid/app/IAssistDataReceiver;->onHandleAssistScreenshot(Landroid/graphics/Bitmap;)V
-Landroid/app/IAssistDataReceiver$Stub;-><init>()V
 Landroid/app/KeyguardManager;->isDeviceLocked(I)Z
 Landroid/app/NotificationManager;->cancelAsUser(Ljava/lang/String;ILandroid/os/UserHandle;)V
 Landroid/app/StatusBarManager;->removeIcon(Ljava/lang/String;)V
@@ -73,17 +72,16 @@
 Landroid/companion/BluetoothLeDeviceFilter;->getScanFilter()Landroid/bluetooth/le/ScanFilter;
 Landroid/companion/DeviceFilter;->getDeviceDisplayName(Landroid/os/Parcelable;)Ljava/lang/String;
 Landroid/companion/DeviceFilter;->matches(Landroid/os/Parcelable;)Z
+Landroid/companion/ICompanionDeviceDiscoveryService$Stub;-><init>()V
 Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelected(Ljava/lang/String;ILjava/lang/String;)V
 Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelectionCancel()V
-Landroid/companion/ICompanionDeviceDiscoveryService$Stub;-><init>()V
 Landroid/companion/IFindDeviceCallback;->onSuccess(Landroid/app/PendingIntent;)V
+Landroid/content/ContentProvider;-><init>(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;[Landroid/content/pm/PathPermission;)V
 Landroid/content/ContentProvider;->attachInfoForTesting(Landroid/content/Context;Landroid/content/pm/ProviderInfo;)V
 Landroid/content/ContentProvider;->getIContentProvider()Landroid/content/IContentProvider;
-Landroid/content/ContentProvider;-><init>(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;[Landroid/content/pm/PathPermission;)V
 Landroid/content/ContentResolver;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/ContentObserver;I)V
 Landroid/content/ContentValues;->getStringArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
 Landroid/content/ContentValues;->putStringArrayList(Ljava/lang/String;Ljava/util/ArrayList;)V
-Landroid/content/Context;->getOpPackageName()Ljava/lang/String;
 Landroid/content/Context;->registerReceiverAsUser(Landroid/content/BroadcastReceiver;Landroid/os/UserHandle;Landroid/content/IntentFilter;Ljava/lang/String;Landroid/os/Handler;)Landroid/content/Intent;
 Landroid/content/Context;->startActivityAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V
 Landroid/content/Context;->startServiceAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)Landroid/content/ComponentName;
@@ -91,10 +89,9 @@
 Landroid/content/Intent;->getExtra(Ljava/lang/String;)Ljava/lang/Object;
 Landroid/content/Intent;->getIBinderExtra(Ljava/lang/String;)Landroid/os/IBinder;
 Landroid/content/Intent;->resolveSystemService(Landroid/content/pm/PackageManager;I)Landroid/content/ComponentName;
-Landroid/content/pm/IPackageDataObserver;->onRemoveCompleted(Ljava/lang/String;Z)V
 Landroid/content/pm/IPackageDataObserver$Stub;-><init>()V
-Landroid/content/pm/IPackageDeleteObserver;->packageDeleted(Ljava/lang/String;I)V
 Landroid/content/pm/IPackageDeleteObserver$Stub;-><init>()V
+Landroid/content/pm/IPackageDeleteObserver;->packageDeleted(Ljava/lang/String;I)V
 Landroid/content/pm/IPackageManager;->getActivityInfo(Landroid/content/ComponentName;II)Landroid/content/pm/ActivityInfo;
 Landroid/content/pm/IPackageManager;->getApplicationInfo(Ljava/lang/String;II)Landroid/content/pm/ApplicationInfo;
 Landroid/content/pm/IPackageManager;->getHomeActivities(Ljava/util/List;)Landroid/content/ComponentName;
@@ -105,8 +102,8 @@
 Landroid/graphics/AvoidXfermode;-><init>(IILandroid/graphics/AvoidXfermode$Mode;)V
 Landroid/graphics/Bitmap;->createGraphicBufferHandle()Landroid/graphics/GraphicBuffer;
 Landroid/graphics/Bitmap;->createHardwareBitmap(Landroid/graphics/GraphicBuffer;)Landroid/graphics/Bitmap;
-Landroid/graphics/Canvas;->clipRegion(Landroid/graphics/Region;Landroid/graphics/Region$Op;)Z
 Landroid/graphics/Canvas;->clipRegion(Landroid/graphics/Region;)Z
+Landroid/graphics/Canvas;->clipRegion(Landroid/graphics/Region;Landroid/graphics/Region$Op;)Z
 Landroid/graphics/drawable/Drawable;->isProjected()Z
 Landroid/graphics/drawable/Drawable;->updateTintFilter(Landroid/graphics/PorterDuffColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/PorterDuff$Mode;)Landroid/graphics/PorterDuffColorFilter;
 Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;)V
@@ -119,8 +116,8 @@
 Landroid/location/IGeofenceProvider;->setGeofenceHardware(Landroid/hardware/location/IGeofenceHardware;)V
 Landroid/location/ILocationManager;->getNetworkProviderPackage()Ljava/lang/String;
 Landroid/location/ILocationManager;->reportLocation(Landroid/location/Location;Z)V
-Landroid/location/INetInitiatedListener;->sendNiResponse(II)Z
 Landroid/location/INetInitiatedListener$Stub;-><init>()V
+Landroid/location/INetInitiatedListener;->sendNiResponse(II)Z
 Landroid/location/Location;->setExtraLocation(Ljava/lang/String;Landroid/location/Location;)V
 Landroid/media/AudioManager;->registerAudioPortUpdateListener(Landroid/media/AudioManager$OnAudioPortUpdateListener;)V
 Landroid/media/AudioManager;->unregisterAudioPortUpdateListener(Landroid/media/AudioManager$OnAudioPortUpdateListener;)V
@@ -146,32 +143,31 @@
 Landroid/media/tv/ITvRemoteServiceInput;->sendPointerSync(Landroid/os/IBinder;)V
 Landroid/media/tv/ITvRemoteServiceInput;->sendPointerUp(Landroid/os/IBinder;I)V
 Landroid/media/tv/ITvRemoteServiceInput;->sendTimestamp(Landroid/os/IBinder;J)V
-Landroid/net/ConnectivityManager;->getActiveNetworkQuotaInfo()Landroid/net/NetworkQuotaInfo;
+Landroid/net/ConnectivityManager$PacketKeepalive;->stop()V
 Landroid/net/ConnectivityManager$PacketKeepaliveCallback;-><init>()V
 Landroid/net/ConnectivityManager$PacketKeepaliveCallback;->onError(I)V
 Landroid/net/ConnectivityManager$PacketKeepaliveCallback;->onStarted()V
 Landroid/net/ConnectivityManager$PacketKeepaliveCallback;->onStopped()V
-Landroid/net/ConnectivityManager$PacketKeepalive;->stop()V
+Landroid/net/ConnectivityManager;->getActiveNetworkQuotaInfo()Landroid/net/NetworkQuotaInfo;
 Landroid/net/ConnectivityManager;->setAirplaneMode(Z)V
 Landroid/net/ConnectivityManager;->startNattKeepalive(Landroid/net/Network;ILandroid/net/ConnectivityManager$PacketKeepaliveCallback;Ljava/net/InetAddress;ILjava/net/InetAddress;)Landroid/net/ConnectivityManager$PacketKeepalive;
 Landroid/net/ConnectivityManager;->startUsingNetworkFeature(ILjava/lang/String;)I
 Landroid/net/ConnectivityManager;->stopUsingNetworkFeature(ILjava/lang/String;)I
 Landroid/net/ConnectivityManager;->tether(Ljava/lang/String;)I
 Landroid/net/ConnectivityManager;->untether(Ljava/lang/String;)I
+Landroid/net/DhcpResults;-><init>()V
 Landroid/net/DhcpResults;-><init>(Landroid/net/DhcpResults;)V
 Landroid/net/DhcpResults;-><init>(Landroid/net/StaticIpConfiguration;)V
-Landroid/net/DhcpResults;-><init>()V
 Landroid/net/DhcpResults;->leaseDuration:I
 Landroid/net/DhcpResults;->mtu:I
 Landroid/net/DhcpResults;->serverAddress:Ljava/net/Inet4Address;
 Landroid/net/DhcpResults;->vendorInfo:Ljava/lang/String;
 Landroid/net/IConnectivityManager;->getAllNetworkState()[Landroid/net/NetworkState;
-Landroid/net/INetd;->interfaceAddAddress(Ljava/lang/String;Ljava/lang/String;I)V
 Landroid/net/INetd$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetd;
+Landroid/net/INetd;->interfaceAddAddress(Ljava/lang/String;Ljava/lang/String;I)V
 Landroid/net/INetworkPolicyManager;->getNetworkQuotaInfo(Landroid/net/NetworkState;)Landroid/net/NetworkQuotaInfo;
-Landroid/net/INetworkPolicyManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkPolicyManager;
-Landroid/net/INetworkStatsService;->openSession()Landroid/net/INetworkStatsSession;
 Landroid/net/INetworkStatsService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkStatsService;
+Landroid/net/INetworkStatsService;->openSession()Landroid/net/INetworkStatsSession;
 Landroid/net/INetworkStatsSession;->getHistoryForNetwork(Landroid/net/NetworkTemplate;I)Landroid/net/NetworkStatsHistory;
 Landroid/net/INetworkStatsSession;->getHistoryForUid(Landroid/net/NetworkTemplate;IIII)Landroid/net/NetworkStatsHistory;
 Landroid/net/InterfaceConfiguration;-><init>()V
@@ -180,6 +176,13 @@
 Landroid/net/LinkAddress;-><init>(Ljava/net/InetAddress;I)V
 Landroid/net/LinkAddress;->isIPv6()Z
 Landroid/net/LinkAddress;->isSameAddressAs(Landroid/net/LinkAddress;)Z
+Landroid/net/LinkProperties$ProvisioningChange;->GAINED_PROVISIONING:Landroid/net/LinkProperties$ProvisioningChange;
+Landroid/net/LinkProperties$ProvisioningChange;->LOST_PROVISIONING:Landroid/net/LinkProperties$ProvisioningChange;
+Landroid/net/LinkProperties$ProvisioningChange;->STILL_NOT_PROVISIONED:Landroid/net/LinkProperties$ProvisioningChange;
+Landroid/net/LinkProperties$ProvisioningChange;->STILL_PROVISIONED:Landroid/net/LinkProperties$ProvisioningChange;
+Landroid/net/LinkProperties$ProvisioningChange;->values()[Landroid/net/LinkProperties$ProvisioningChange;
+Landroid/net/LinkProperties;-><init>()V
+Landroid/net/LinkProperties;-><init>(Landroid/net/LinkProperties;)V
 Landroid/net/LinkProperties;->addDnsServer(Ljava/net/InetAddress;)Z
 Landroid/net/LinkProperties;->addRoute(Landroid/net/RouteInfo;)Z
 Landroid/net/LinkProperties;->addStackedLink(Landroid/net/LinkProperties;)Z
@@ -195,8 +198,6 @@
 Landroid/net/LinkProperties;->hasIPv4DnsServer()Z
 Landroid/net/LinkProperties;->hasIPv6DefaultRoute()Z
 Landroid/net/LinkProperties;->hasIPv6DnsServer()Z
-Landroid/net/LinkProperties;-><init>(Landroid/net/LinkProperties;)V
-Landroid/net/LinkProperties;-><init>()V
 Landroid/net/LinkProperties;->isIdenticalAddresses(Landroid/net/LinkProperties;)Z
 Landroid/net/LinkProperties;->isIdenticalDnses(Landroid/net/LinkProperties;)Z
 Landroid/net/LinkProperties;->isIdenticalRoutes(Landroid/net/LinkProperties;)Z
@@ -204,11 +205,6 @@
 Landroid/net/LinkProperties;->isIPv6Provisioned()Z
 Landroid/net/LinkProperties;->isProvisioned()Z
 Landroid/net/LinkProperties;->isReachable(Ljava/net/InetAddress;)Z
-Landroid/net/LinkProperties$ProvisioningChange;->GAINED_PROVISIONING:Landroid/net/LinkProperties$ProvisioningChange;
-Landroid/net/LinkProperties$ProvisioningChange;->LOST_PROVISIONING:Landroid/net/LinkProperties$ProvisioningChange;
-Landroid/net/LinkProperties$ProvisioningChange;->STILL_NOT_PROVISIONED:Landroid/net/LinkProperties$ProvisioningChange;
-Landroid/net/LinkProperties$ProvisioningChange;->STILL_PROVISIONED:Landroid/net/LinkProperties$ProvisioningChange;
-Landroid/net/LinkProperties$ProvisioningChange;->values()[Landroid/net/LinkProperties$ProvisioningChange;
 Landroid/net/LinkProperties;->removeDnsServer(Ljava/net/InetAddress;)Z
 Landroid/net/LinkProperties;->removeRoute(Landroid/net/RouteInfo;)Z
 Landroid/net/LinkProperties;->setDnsServers(Ljava/util/Collection;)V
@@ -218,26 +214,27 @@
 Landroid/net/LinkProperties;->setMtu(I)V
 Landroid/net/LinkProperties;->setTcpBufferSizes(Ljava/lang/String;)V
 Landroid/net/MacAddress;->ALL_ZEROS_ADDRESS:Landroid/net/MacAddress;
+Landroid/net/metrics/ApfProgramEvent;-><init>()V
 Landroid/net/metrics/ApfProgramEvent;->actualLifetime:J
 Landroid/net/metrics/ApfProgramEvent;->currentRas:I
 Landroid/net/metrics/ApfProgramEvent;->filteredRas:I
-Landroid/net/metrics/ApfProgramEvent;->flagsFor(ZZ)I
 Landroid/net/metrics/ApfProgramEvent;->flags:I
-Landroid/net/metrics/ApfProgramEvent;-><init>()V
+Landroid/net/metrics/ApfProgramEvent;->flagsFor(ZZ)I
 Landroid/net/metrics/ApfProgramEvent;->lifetime:J
 Landroid/net/metrics/ApfProgramEvent;->programLength:I
+Landroid/net/metrics/ApfStats;-><init>()V
 Landroid/net/metrics/ApfStats;->droppedRas:I
 Landroid/net/metrics/ApfStats;->durationMs:J
-Landroid/net/metrics/ApfStats;-><init>()V
 Landroid/net/metrics/ApfStats;->matchingRas:I
 Landroid/net/metrics/ApfStats;->maxProgramSize:I
 Landroid/net/metrics/ApfStats;->parseErrors:I
+Landroid/net/metrics/ApfStats;->programUpdates:I
 Landroid/net/metrics/ApfStats;->programUpdatesAll:I
 Landroid/net/metrics/ApfStats;->programUpdatesAllowingMulticast:I
-Landroid/net/metrics/ApfStats;->programUpdates:I
 Landroid/net/metrics/ApfStats;->receivedRas:I
 Landroid/net/metrics/ApfStats;->zeroLifetimeRas:I
 Landroid/net/metrics/DhcpClientEvent;-><init>(Ljava/lang/String;I)V
+Landroid/net/metrics/DhcpErrorEvent;-><init>(I)V
 Landroid/net/metrics/DhcpErrorEvent;->BOOTP_TOO_SHORT:I
 Landroid/net/metrics/DhcpErrorEvent;->BUFFER_UNDERFLOW:I
 Landroid/net/metrics/DhcpErrorEvent;->DHCP_BAD_MAGIC_COOKIE:I
@@ -246,7 +243,6 @@
 Landroid/net/metrics/DhcpErrorEvent;->DHCP_NO_MSG_TYPE:I
 Landroid/net/metrics/DhcpErrorEvent;->DHCP_UNKNOWN_MSG_TYPE:I
 Landroid/net/metrics/DhcpErrorEvent;->errorCodeWithOption(II)I
-Landroid/net/metrics/DhcpErrorEvent;-><init>(I)V
 Landroid/net/metrics/DhcpErrorEvent;->L2_TOO_SHORT:I
 Landroid/net/metrics/DhcpErrorEvent;->L2_WRONG_ETH_TYPE:I
 Landroid/net/metrics/DhcpErrorEvent;->L3_INVALID_IP:I
@@ -262,29 +258,28 @@
 Landroid/net/metrics/IpManagerEvent;-><init>(IJ)V
 Landroid/net/metrics/IpReachabilityEvent;-><init>(I)V
 Landroid/net/metrics/IpReachabilityEvent;->nudFailureEventType(ZZ)I
-Landroid/net/metrics/RaEvent$Builder;->build()Landroid/net/metrics/RaEvent;
 Landroid/net/metrics/RaEvent$Builder;-><init>()V
+Landroid/net/metrics/RaEvent$Builder;->build()Landroid/net/metrics/RaEvent;
 Landroid/net/metrics/RaEvent$Builder;->updateDnsslLifetime(J)Landroid/net/metrics/RaEvent$Builder;
 Landroid/net/metrics/RaEvent$Builder;->updatePrefixPreferredLifetime(J)Landroid/net/metrics/RaEvent$Builder;
 Landroid/net/metrics/RaEvent$Builder;->updatePrefixValidLifetime(J)Landroid/net/metrics/RaEvent$Builder;
 Landroid/net/metrics/RaEvent$Builder;->updateRdnssLifetime(J)Landroid/net/metrics/RaEvent$Builder;
 Landroid/net/metrics/RaEvent$Builder;->updateRouteInfoLifetime(J)Landroid/net/metrics/RaEvent$Builder;
 Landroid/net/metrics/RaEvent$Builder;->updateRouterLifetime(J)Landroid/net/metrics/RaEvent$Builder;
+Landroid/net/Network;-><init>(I)V
+Landroid/net/Network;->netId:I
 Landroid/net/NetworkCapabilities;->getNetworkSpecifier()Landroid/net/NetworkSpecifier;
 Landroid/net/NetworkCapabilities;->getSignalStrength()I
 Landroid/net/NetworkCapabilities;->hasSignalStrength()Z
 Landroid/net/NetworkCapabilities;->transportNamesOf([I)Ljava/lang/String;
-Landroid/net/Network;-><init>(I)V
-Landroid/net/Network;->netId:I
 Landroid/net/NetworkQuotaInfo;->getEstimatedBytes()J
 Landroid/net/NetworkQuotaInfo;->getHardLimitBytes()J
 Landroid/net/NetworkQuotaInfo;->getSoftLimitBytes()J
 Landroid/net/NetworkRequest$Builder;->setSignalStrength(I)Landroid/net/NetworkRequest$Builder;
 Landroid/net/NetworkRequest;->networkCapabilities:Landroid/net/NetworkCapabilities;
 Landroid/net/NetworkState;->network:Landroid/net/Network;
-Landroid/net/NetworkStats;->combineValues(Landroid/net/NetworkStats$Entry;)Landroid/net/NetworkStats;
-Landroid/net/NetworkStats$Entry;->iface:Ljava/lang/String;
 Landroid/net/NetworkStats$Entry;-><init>()V
+Landroid/net/NetworkStats$Entry;->iface:Ljava/lang/String;
 Landroid/net/NetworkStats$Entry;->rxBytes:J
 Landroid/net/NetworkStats$Entry;->rxPackets:J
 Landroid/net/NetworkStats$Entry;->set:I
@@ -292,10 +287,11 @@
 Landroid/net/NetworkStats$Entry;->txBytes:J
 Landroid/net/NetworkStats$Entry;->txPackets:J
 Landroid/net/NetworkStats$Entry;->uid:I
+Landroid/net/NetworkStats;-><init>(JI)V
+Landroid/net/NetworkStats;->combineValues(Landroid/net/NetworkStats$Entry;)Landroid/net/NetworkStats;
 Landroid/net/NetworkStatsHistory$Entry;->txBytes:J
 Landroid/net/NetworkStatsHistory;->getStart()J
 Landroid/net/NetworkStatsHistory;->getValues(JJLandroid/net/NetworkStatsHistory$Entry;)Landroid/net/NetworkStatsHistory$Entry;
-Landroid/net/NetworkStats;-><init>(JI)V
 Landroid/net/NetworkTemplate;->buildTemplateMobileAll(Ljava/lang/String;)Landroid/net/NetworkTemplate;
 Landroid/net/NetworkUtils;->attachControlPacketFilter(Ljava/io/FileDescriptor;I)V
 Landroid/net/NetworkUtils;->attachDhcpFilter(Ljava/io/FileDescriptor;)V
@@ -303,8 +299,8 @@
 Landroid/net/NetworkUtils;->getImplicitNetmask(Ljava/net/Inet4Address;)I
 Landroid/net/NetworkUtils;->netmaskToPrefixLength(Ljava/net/Inet4Address;)I
 Landroid/net/NetworkUtils;->protectFromVpn(Ljava/io/FileDescriptor;)Z
-Landroid/net/RouteInfo;->hasGateway()Z
 Landroid/net/RouteInfo;-><init>(Landroid/net/IpPrefix;Ljava/net/InetAddress;Ljava/lang/String;)V
+Landroid/net/RouteInfo;->hasGateway()Z
 Landroid/net/RouteInfo;->selectBestRoute(Ljava/util/Collection;Ljava/net/InetAddress;)Landroid/net/RouteInfo;
 Landroid/net/SntpClient;->getNtpTime()J
 Landroid/net/SntpClient;->getNtpTimeReference()J
@@ -318,29 +314,30 @@
 Landroid/net/TrafficStats;->getMobileTcpTxPackets()J
 Landroid/net/wifi/WifiInfo;->is5GHz()Z
 Landroid/net/wifi/WifiInfo;->score:I
+Landroid/os/AsyncResult;-><init>(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Throwable;)V
 Landroid/os/AsyncResult;->exception:Ljava/lang/Throwable;
 Landroid/os/AsyncResult;->forMessage(Landroid/os/Message;Ljava/lang/Object;Ljava/lang/Throwable;)Landroid/os/AsyncResult;
-Landroid/os/AsyncResult;-><init>(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Throwable;)V
 Landroid/os/AsyncResult;->result:Ljava/lang/Object;
 Landroid/os/AsyncResult;->userObj:Ljava/lang/Object;
-Landroid/os/BatteryStats;->getNextHistoryLocked(Landroid/os/BatteryStats$HistoryItem;)Z
+Landroid/os/BatteryStats$HistoryItem;-><init>()V
 Landroid/os/BatteryStats$HistoryItem;->batteryLevel:B
 Landroid/os/BatteryStats$HistoryItem;->cmd:B
-Landroid/os/BatteryStats$HistoryItem;-><init>()V
 Landroid/os/BatteryStats$HistoryItem;->states:I
 Landroid/os/BatteryStats$HistoryItem;->time:J
 Landroid/os/BatteryStats$Timer;->getCountLocked(I)I
-Landroid/os/BatteryStats$Uid;->getWifiRunningTime(JI)J
-Landroid/os/BatteryStats$Uid;-><init>()V
 Landroid/os/BatteryStats$Uid$Wakelock;->getWakeTime(I)Landroid/os/BatteryStats$Timer;
+Landroid/os/BatteryStats$Uid;-><init>()V
+Landroid/os/BatteryStats$Uid;->getWifiRunningTime(JI)J
+Landroid/os/BatteryStats;->getNextHistoryLocked(Landroid/os/BatteryStats$HistoryItem;)Z
+Landroid/os/Broadcaster;-><init>()V
 Landroid/os/Broadcaster;->broadcast(Landroid/os/Message;)V
 Landroid/os/Broadcaster;->cancelRequest(ILandroid/os/Handler;I)V
-Landroid/os/Broadcaster;-><init>()V
 Landroid/os/Broadcaster;->request(ILandroid/os/Handler;I)V
 Landroid/os/Environment;->getLegacyExternalStorageDirectory()Ljava/io/File;
-Landroid/os/Handler;->getMain()Landroid/os/Handler;
 Landroid/os/Handler;-><init>(Landroid/os/Looper;Landroid/os/Handler$Callback;Z)V
+Landroid/os/Handler;->getMain()Landroid/os/Handler;
 Landroid/os/HwBinder;->reportSyspropChanged()V
+Landroid/os/INetworkManagementService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/INetworkManagementService;
 Landroid/os/INetworkManagementService;->clearInterfaceAddresses(Ljava/lang/String;)V
 Landroid/os/INetworkManagementService;->disableIpv6(Ljava/lang/String;)V
 Landroid/os/INetworkManagementService;->enableIpv6(Ljava/lang/String;)V
@@ -349,7 +346,6 @@
 Landroid/os/INetworkManagementService;->setInterfaceConfig(Ljava/lang/String;Landroid/net/InterfaceConfiguration;)V
 Landroid/os/INetworkManagementService;->setInterfaceIpv6PrivacyExtensions(Ljava/lang/String;Z)V
 Landroid/os/INetworkManagementService;->setIPv6AddrGenMode(Ljava/lang/String;I)V
-Landroid/os/INetworkManagementService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/INetworkManagementService;
 Landroid/os/INetworkManagementService;->unregisterObserver(Landroid/net/INetworkManagementEventObserver;)V
 Landroid/os/IPowerManager;->goToSleep(JII)V
 Landroid/os/IPowerManager;->reboot(ZLjava/lang/String;Z)V
@@ -360,17 +356,17 @@
 Landroid/os/Parcel;->writeBlob([B)V
 Landroid/os/PowerManager;->goToSleep(J)V
 Landroid/os/PowerManager;->isScreenBrightnessBoosted()Z
-Landroid/os/Registrant;->clear()V
 Landroid/os/Registrant;-><init>(Landroid/os/Handler;ILjava/lang/Object;)V
+Landroid/os/Registrant;->clear()V
+Landroid/os/Registrant;->notifyRegistrant()V
+Landroid/os/Registrant;->notifyRegistrant(Landroid/os/AsyncResult;)V
+Landroid/os/RegistrantList;-><init>()V
 Landroid/os/RegistrantList;->add(Landroid/os/Registrant;)V
 Landroid/os/RegistrantList;->addUnique(Landroid/os/Handler;ILjava/lang/Object;)V
-Landroid/os/RegistrantList;-><init>()V
-Landroid/os/RegistrantList;->notifyRegistrants(Landroid/os/AsyncResult;)V
 Landroid/os/RegistrantList;->notifyRegistrants()V
-Landroid/os/RegistrantList;->removeCleared()V
+Landroid/os/RegistrantList;->notifyRegistrants(Landroid/os/AsyncResult;)V
 Landroid/os/RegistrantList;->remove(Landroid/os/Handler;)V
-Landroid/os/Registrant;->notifyRegistrant(Landroid/os/AsyncResult;)V
-Landroid/os/Registrant;->notifyRegistrant()V
+Landroid/os/RegistrantList;->removeCleared()V
 Landroid/os/RemoteException;->rethrowFromSystemServer()Ljava/lang/RuntimeException;
 Landroid/os/ServiceSpecificException;->errorCode:I
 Landroid/os/storage/DiskInfo;->getId()Ljava/lang/String;
@@ -430,8 +426,8 @@
 Landroid/telephony/ims/compat/ImsService;-><init>()V
 Landroid/telephony/ims/compat/ImsService;->mImsServiceController:Landroid/os/IBinder;
 Landroid/telephony/ims/compat/stub/ImsCallSessionImplBase;-><init>()V
-Landroid/telephony/ims/compat/stub/ImsConfigImplBase;->getIImsConfig()Lcom/android/ims/internal/IImsConfig;
 Landroid/telephony/ims/compat/stub/ImsConfigImplBase;-><init>(Landroid/content/Context;)V
+Landroid/telephony/ims/compat/stub/ImsConfigImplBase;->getIImsConfig()Lcom/android/ims/internal/IImsConfig;
 Landroid/telephony/ims/compat/stub/ImsUtListenerImplBase;-><init>()V
 Landroid/telephony/ims/ImsCallForwardInfo;-><init>()V
 Landroid/telephony/ims/ImsCallForwardInfo;->mCondition:I
@@ -459,21 +455,21 @@
 Landroid/telephony/ims/ImsVideoCallProvider;->getInterface()Lcom/android/ims/internal/IImsVideoCallProvider;
 Landroid/telephony/mbms/IMbmsStreamingSessionCallback$Stub;-><init>()V
 Landroid/telephony/mbms/IStreamingServiceCallback$Stub;-><init>()V
+Landroid/telephony/mbms/vendor/IMbmsStreamingService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/telephony/mbms/vendor/IMbmsStreamingService;
 Landroid/telephony/mbms/vendor/IMbmsStreamingService;->getPlaybackUri(ILjava/lang/String;)Landroid/net/Uri;
 Landroid/telephony/mbms/vendor/IMbmsStreamingService;->initialize(Landroid/telephony/mbms/IMbmsStreamingSessionCallback;I)I
 Landroid/telephony/mbms/vendor/IMbmsStreamingService;->requestUpdateStreamingServices(ILjava/util/List;)I
 Landroid/telephony/mbms/vendor/IMbmsStreamingService;->startStreaming(ILjava/lang/String;Landroid/telephony/mbms/IStreamingServiceCallback;)I
-Landroid/telephony/mbms/vendor/IMbmsStreamingService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/telephony/mbms/vendor/IMbmsStreamingService;
 Landroid/telephony/PhoneNumberUtils;->formatNumber(Ljava/lang/String;I)Ljava/lang/String;
 Landroid/telephony/PhoneNumberUtils;->isEmergencyNumber(ILjava/lang/String;)Z
 Landroid/telephony/PhoneNumberUtils;->isPotentialEmergencyNumber(ILjava/lang/String;)Z
 Landroid/telephony/PhoneNumberUtils;->isPotentialLocalEmergencyNumber(Landroid/content/Context;ILjava/lang/String;)Z
-Landroid/telephony/PhoneStateListener;-><init>(Ljava/lang/Integer;Landroid/os/Looper;)V
 Landroid/telephony/PhoneStateListener;-><init>(Ljava/lang/Integer;)V
+Landroid/telephony/PhoneStateListener;-><init>(Ljava/lang/Integer;Landroid/os/Looper;)V
 Landroid/telephony/PreciseCallState;->getBackgroundCallState()I
 Landroid/telephony/PreciseCallState;->getForegroundCallState()I
-Landroid/telephony/RadioAccessFamily;->getRafFromNetworkType(I)I
 Landroid/telephony/RadioAccessFamily;-><init>(II)V
+Landroid/telephony/RadioAccessFamily;->getRafFromNetworkType(I)I
 Landroid/telephony/Rlog;->d(Ljava/lang/String;Ljava/lang/String;)I
 Landroid/telephony/Rlog;->e(Ljava/lang/String;Ljava/lang/String;)I
 Landroid/telephony/Rlog;->e(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I
@@ -499,10 +495,12 @@
 Landroid/telephony/SubscriptionManager;->isValidPhoneId(I)Z
 Landroid/telephony/SubscriptionManager;->isValidSlotIndex(I)Z
 Landroid/telephony/SubscriptionManager;->isValidSubscriptionId(I)Z
-Landroid/telephony/SubscriptionManager;->putPhoneIdAndSubIdExtra(Landroid/content/Intent;II)V
 Landroid/telephony/SubscriptionManager;->putPhoneIdAndSubIdExtra(Landroid/content/Intent;I)V
+Landroid/telephony/SubscriptionManager;->putPhoneIdAndSubIdExtra(Landroid/content/Intent;II)V
 Landroid/telephony/SubscriptionManager;->setDisplayName(Ljava/lang/String;IJ)I
 Landroid/telephony/SubscriptionManager;->setIconTint(II)I
+Landroid/telephony/TelephonyManager$MultiSimVariants;->DSDA:Landroid/telephony/TelephonyManager$MultiSimVariants;
+Landroid/telephony/TelephonyManager$MultiSimVariants;->DSDS:Landroid/telephony/TelephonyManager$MultiSimVariants;
 Landroid/telephony/TelephonyManager;->getIntAtIndex(Landroid/content/ContentResolver;Ljava/lang/String;I)I
 Landroid/telephony/TelephonyManager;->getIsimDomain()Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getNetworkTypeName()Ljava/lang/String;
@@ -511,8 +509,6 @@
 Landroid/telephony/TelephonyManager;->getVoiceMessageCount()I
 Landroid/telephony/TelephonyManager;->getVoiceNetworkType(I)I
 Landroid/telephony/TelephonyManager;->isImsRegistered()Z
-Landroid/telephony/TelephonyManager$MultiSimVariants;->DSDA:Landroid/telephony/TelephonyManager$MultiSimVariants;
-Landroid/telephony/TelephonyManager$MultiSimVariants;->DSDS:Landroid/telephony/TelephonyManager$MultiSimVariants;
 Landroid/telephony/TelephonyManager;->nvResetConfig(I)Z
 Landroid/telephony/TelephonyManager;->putIntAtIndex(Landroid/content/ContentResolver;Ljava/lang/String;II)Z
 Landroid/telephony/TelephonyManager;->setPreferredNetworkType(II)Z
@@ -525,13 +521,13 @@
 Landroid/util/FloatMath;->sqrt(F)F
 Landroid/util/IconDrawableFactory;->getBadgedIcon(Landroid/content/pm/PackageItemInfo;Landroid/content/pm/ApplicationInfo;I)Landroid/graphics/drawable/Drawable;
 Landroid/util/IconDrawableFactory;->newInstance(Landroid/content/Context;)Landroid/util/IconDrawableFactory;
+Landroid/util/LocalLog$ReadOnlyLocalLog;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
 Landroid/util/LocalLog;-><init>(I)V
 Landroid/util/LocalLog;->log(Ljava/lang/String;)V
-Landroid/util/LocalLog$ReadOnlyLocalLog;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
 Landroid/util/LocalLog;->readOnlyLocalLog()Landroid/util/LocalLog$ReadOnlyLocalLog;
+Landroid/util/LongArray;-><init>()V
 Landroid/util/LongArray;->add(IJ)V
 Landroid/util/LongArray;->get(I)J
-Landroid/util/LongArray;-><init>()V
 Landroid/util/LongArray;->size()I
 Landroid/util/RecurrenceRule;->buildRecurringMonthly(ILjava/time/ZoneId;)Landroid/util/RecurrenceRule;
 Landroid/util/RecurrenceRule;->start:Ljava/time/ZonedDateTime;
@@ -548,14 +544,14 @@
 Landroid/view/IRecentsAnimationController;->finish(Z)V
 Landroid/view/IRecentsAnimationController;->screenshotTask(I)Landroid/app/ActivityManager$TaskSnapshot;
 Landroid/view/IRecentsAnimationController;->setInputConsumerEnabled(Z)V
+Landroid/view/IRecentsAnimationRunner$Stub;-><init>()V
 Landroid/view/IRecentsAnimationRunner;->onAnimationCanceled()V
 Landroid/view/IRecentsAnimationRunner;->onAnimationStart(Landroid/view/IRecentsAnimationController;[Landroid/view/RemoteAnimationTarget;)V
 Landroid/view/IRecentsAnimationRunner;->onAnimationStart_New(Landroid/view/IRecentsAnimationController;[Landroid/view/RemoteAnimationTarget;Landroid/graphics/Rect;Landroid/graphics/Rect;)V
-Landroid/view/IRecentsAnimationRunner$Stub;-><init>()V
 Landroid/view/IRemoteAnimationFinishedCallback;->onAnimationFinished()V
+Landroid/view/IRemoteAnimationRunner$Stub;-><init>()V
 Landroid/view/IRemoteAnimationRunner;->onAnimationCancelled()V
 Landroid/view/IRemoteAnimationRunner;->onAnimationStart([Landroid/view/RemoteAnimationTarget;Landroid/view/IRemoteAnimationFinishedCallback;)V
-Landroid/view/IRemoteAnimationRunner$Stub;-><init>()V
 Landroid/view/IWindowManager;->createInputConsumer(Landroid/os/IBinder;Ljava/lang/String;Landroid/view/InputChannel;)V
 Landroid/view/IWindowManager;->destroyInputConsumer(Ljava/lang/String;)Z
 Landroid/view/IWindowManager;->endProlongedAnimations()V
@@ -564,19 +560,20 @@
 Landroid/view/IWindowManager;->overridePendingAppTransitionRemote(Landroid/view/RemoteAnimationAdapter;)V
 Landroid/view/IWindowManager;->setNavBarVirtualKeyHapticFeedbackEnabled(Z)V
 Landroid/view/RemoteAnimationAdapter;-><init>(Landroid/view/IRemoteAnimationRunner;JJ)V
-Landroid/view/RemoteAnimationDefinition;->addRemoteAnimation(ILandroid/view/RemoteAnimationAdapter;)V
 Landroid/view/RemoteAnimationDefinition;-><init>()V
+Landroid/view/RemoteAnimationDefinition;->addRemoteAnimation(ILandroid/view/RemoteAnimationAdapter;)V
 Landroid/view/RenderNode;->create(Ljava/lang/String;Landroid/view/View;)Landroid/view/RenderNode;
 Landroid/view/RenderNode;->end(Landroid/view/DisplayListCanvas;)V
 Landroid/view/RenderNode;->isValid()Z
 Landroid/view/RenderNode;->setClipToBounds(Z)Z
 Landroid/view/RenderNode;->setLeftTopRightBottom(IIII)Z
 Landroid/view/RenderNode;->start(II)Landroid/view/DisplayListCanvas;
+Landroid/view/Surface;->getNextFrameNumber()J
+Landroid/view/SurfaceControl$Transaction;-><init>()V
 Landroid/view/SurfaceControl$Transaction;->apply()V
 Landroid/view/SurfaceControl$Transaction;->deferTransactionUntil(Landroid/view/SurfaceControl;Landroid/os/IBinder;J)Landroid/view/SurfaceControl$Transaction;
 Landroid/view/SurfaceControl$Transaction;->deferTransactionUntilSurface(Landroid/view/SurfaceControl;Landroid/view/Surface;J)Landroid/view/SurfaceControl$Transaction;
 Landroid/view/SurfaceControl$Transaction;->hide(Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Transaction;
-Landroid/view/SurfaceControl$Transaction;-><init>()V
 Landroid/view/SurfaceControl$Transaction;->setAlpha(Landroid/view/SurfaceControl;F)Landroid/view/SurfaceControl$Transaction;
 Landroid/view/SurfaceControl$Transaction;->setColor(Landroid/view/SurfaceControl;[F)Landroid/view/SurfaceControl$Transaction;
 Landroid/view/SurfaceControl$Transaction;->setFinalCrop(Landroid/view/SurfaceControl;Landroid/graphics/Rect;)Landroid/view/SurfaceControl$Transaction;
@@ -587,7 +584,6 @@
 Landroid/view/SurfaceControl$Transaction;->setSize(Landroid/view/SurfaceControl;II)Landroid/view/SurfaceControl$Transaction;
 Landroid/view/SurfaceControl$Transaction;->setWindowCrop(Landroid/view/SurfaceControl;Landroid/graphics/Rect;)Landroid/view/SurfaceControl$Transaction;
 Landroid/view/SurfaceControl$Transaction;->show(Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Transaction;
-Landroid/view/Surface;->getNextFrameNumber()J
 Landroid/view/ThreadedRenderer;->createHardwareBitmap(Landroid/view/RenderNode;II)Landroid/graphics/Bitmap;
 Landroid/view/View;->hideTooltip()V
 Landroid/view/View;->setTooltip(Ljava/lang/CharSequence;)V
@@ -601,8 +597,8 @@
 Landroid/widget/ListView;->lookForSelectablePosition(IZ)I
 Lcom/android/ims/ImsConfigListener;->onSetFeatureResponse(IIII)V
 Lcom/android/ims/internal/IImsCallSessionListener;->callSessionConferenceStateUpdated(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsConferenceState;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHandoverFailed(Lcom/android/ims/internal/IImsCallSession;IILandroid/telephony/ims/ImsReasonInfo;)V
 Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHandover(Lcom/android/ims/internal/IImsCallSession;IILandroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHandoverFailed(Lcom/android/ims/internal/IImsCallSession;IILandroid/telephony/ims/ImsReasonInfo;)V
 Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHeld(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
 Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHoldFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
 Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHoldReceived(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
@@ -658,8 +654,8 @@
 Lcom/android/ims/internal/uce/common/CapInfo;->isVsDuringCSSupported()Z
 Lcom/android/ims/internal/uce/common/CapInfo;->isVsSupported()Z
 Lcom/android/ims/internal/uce/common/StatusCode;->getStatusCode()I
-Lcom/android/ims/internal/uce/common/UceLong;->getClientId()I
 Lcom/android/ims/internal/uce/common/UceLong;-><init>()V
+Lcom/android/ims/internal/uce/common/UceLong;->getClientId()I
 Lcom/android/ims/internal/uce/common/UceLong;->setClientId(I)V
 Lcom/android/ims/internal/uce/options/IOptionsListener;->cmdStatus(Lcom/android/ims/internal/uce/options/OptionsCmdStatus;)V
 Lcom/android/ims/internal/uce/options/IOptionsListener;->getVersionCb(Ljava/lang/String;)V
@@ -667,6 +663,7 @@
 Lcom/android/ims/internal/uce/options/IOptionsListener;->serviceAvailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
 Lcom/android/ims/internal/uce/options/IOptionsListener;->serviceUnavailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
 Lcom/android/ims/internal/uce/options/IOptionsListener;->sipResponseReceived(Ljava/lang/String;Lcom/android/ims/internal/uce/options/OptionsSipResponse;Lcom/android/ims/internal/uce/options/OptionsCapInfo;)V
+Lcom/android/ims/internal/uce/options/IOptionsService$Stub;-><init>()V
 Lcom/android/ims/internal/uce/options/IOptionsService;->addListener(ILcom/android/ims/internal/uce/options/IOptionsListener;Lcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
 Lcom/android/ims/internal/uce/options/IOptionsService;->getContactCap(ILjava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
 Lcom/android/ims/internal/uce/options/IOptionsService;->getContactListCap(I[Ljava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
@@ -675,10 +672,9 @@
 Lcom/android/ims/internal/uce/options/IOptionsService;->removeListener(ILcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
 Lcom/android/ims/internal/uce/options/IOptionsService;->responseIncomingOptions(IIILjava/lang/String;Lcom/android/ims/internal/uce/options/OptionsCapInfo;Z)Lcom/android/ims/internal/uce/common/StatusCode;
 Lcom/android/ims/internal/uce/options/IOptionsService;->setMyInfo(ILcom/android/ims/internal/uce/common/CapInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService$Stub;-><init>()V
+Lcom/android/ims/internal/uce/options/OptionsCapInfo;-><init>()V
 Lcom/android/ims/internal/uce/options/OptionsCapInfo;->getCapInfo()Lcom/android/ims/internal/uce/common/CapInfo;
 Lcom/android/ims/internal/uce/options/OptionsCapInfo;->getSdp()Ljava/lang/String;
-Lcom/android/ims/internal/uce/options/OptionsCapInfo;-><init>()V
 Lcom/android/ims/internal/uce/options/OptionsCapInfo;->setCapInfo(Lcom/android/ims/internal/uce/common/CapInfo;)V
 Lcom/android/ims/internal/uce/options/OptionsCapInfo;->setSdp(Ljava/lang/String;)V
 Lcom/android/ims/internal/uce/options/OptionsCmdId;-><init>()V
@@ -703,6 +699,7 @@
 Lcom/android/ims/internal/uce/presence/IPresenceListener;->serviceUnAvailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
 Lcom/android/ims/internal/uce/presence/IPresenceListener;->sipResponseReceived(Lcom/android/ims/internal/uce/presence/PresSipResponse;)V
 Lcom/android/ims/internal/uce/presence/IPresenceListener;->unpublishMessageSent()V
+Lcom/android/ims/internal/uce/presence/IPresenceService$Stub;-><init>()V
 Lcom/android/ims/internal/uce/presence/IPresenceService;->addListener(ILcom/android/ims/internal/uce/presence/IPresenceListener;Lcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
 Lcom/android/ims/internal/uce/presence/IPresenceService;->getContactCap(ILjava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
 Lcom/android/ims/internal/uce/presence/IPresenceService;->getContactListCap(I[Ljava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
@@ -711,7 +708,6 @@
 Lcom/android/ims/internal/uce/presence/IPresenceService;->reenableService(II)Lcom/android/ims/internal/uce/common/StatusCode;
 Lcom/android/ims/internal/uce/presence/IPresenceService;->removeListener(ILcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
 Lcom/android/ims/internal/uce/presence/IPresenceService;->setNewFeatureTag(ILjava/lang/String;Lcom/android/ims/internal/uce/presence/PresServiceInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService$Stub;-><init>()V
 Lcom/android/ims/internal/uce/presence/PresCapInfo;->getCapInfo()Lcom/android/ims/internal/uce/common/CapInfo;
 Lcom/android/ims/internal/uce/presence/PresCapInfo;->getContactUri()Ljava/lang/String;
 Lcom/android/ims/internal/uce/presence/PresCapInfo;->mContactUri:Ljava/lang/String;
@@ -725,6 +721,7 @@
 Lcom/android/ims/internal/uce/presence/PresSipResponse;->getRetryAfter()I
 Lcom/android/ims/internal/uce/presence/PresSipResponse;->getSipResponseCode()I
 Lcom/android/ims/internal/uce/uceservice/IUceListener;->setStatus(I)V
+Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V
 Lcom/android/ims/internal/uce/uceservice/IUceService;->createOptionsService(Lcom/android/ims/internal/uce/options/IOptionsListener;Lcom/android/ims/internal/uce/common/UceLong;)I
 Lcom/android/ims/internal/uce/uceservice/IUceService;->createPresenceService(Lcom/android/ims/internal/uce/presence/IPresenceListener;Lcom/android/ims/internal/uce/common/UceLong;)I
 Lcom/android/ims/internal/uce/uceservice/IUceService;->destroyOptionsService(I)V
@@ -735,7 +732,6 @@
 Lcom/android/ims/internal/uce/uceservice/IUceService;->isServiceStarted()Z
 Lcom/android/ims/internal/uce/uceservice/IUceService;->startService(Lcom/android/ims/internal/uce/uceservice/IUceListener;)Z
 Lcom/android/ims/internal/uce/uceservice/IUceService;->stopService()Z
-Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V
 Lcom/android/internal/app/AlertController$AlertParams;->mIconId:I
 Lcom/android/internal/app/AlertController$AlertParams;->mMessage:Ljava/lang/CharSequence;
 Lcom/android/internal/app/AlertController$AlertParams;->mNegativeButtonListener:Landroid/content/DialogInterface$OnClickListener;
@@ -749,6 +745,7 @@
 Lcom/android/internal/content/PackageMonitor;-><init>()V
 Lcom/android/internal/content/PackageMonitor;->register(Landroid/content/Context;Landroid/os/Looper;Landroid/os/UserHandle;Z)V
 Lcom/android/internal/content/PackageMonitor;->unregister()V
+Lcom/android/internal/location/ILocationProvider$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/location/ILocationProvider;
 Lcom/android/internal/location/ILocationProvider;->disable()V
 Lcom/android/internal/location/ILocationProvider;->enable()V
 Lcom/android/internal/location/ILocationProvider;->getProperties()Lcom/android/internal/location/ProviderProperties;
@@ -756,7 +753,6 @@
 Lcom/android/internal/location/ILocationProvider;->getStatusUpdateTime()J
 Lcom/android/internal/location/ILocationProvider;->sendExtraCommand(Ljava/lang/String;Landroid/os/Bundle;)Z
 Lcom/android/internal/location/ILocationProvider;->setRequest(Lcom/android/internal/location/ProviderRequest;Landroid/os/WorkSource;)V
-Lcom/android/internal/location/ILocationProvider$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/location/ILocationProvider;
 Lcom/android/internal/location/ProviderRequest;-><init>()V
 Lcom/android/internal/location/ProviderRequest;->interval:J
 Lcom/android/internal/location/ProviderRequest;->locationRequests:Ljava/util/List;
@@ -768,7 +764,6 @@
 Lcom/android/internal/os/BatteryStatsImpl;->getPhoneSignalStrengthTime(IJI)J
 Lcom/android/internal/os/BatteryStatsImpl;->getScreenBrightnessTime(IJI)J
 Lcom/android/internal/os/BatteryStatsImpl;->getWifiOnTime(JI)J
-Lcom/android/internal/os/SomeArgs;->arg1:Ljava/lang/Object;
 Lcom/android/internal/os/SomeArgs;->arg2:Ljava/lang/Object;
 Lcom/android/internal/os/SomeArgs;->arg3:Ljava/lang/Object;
 Lcom/android/internal/os/SomeArgs;->obtain()Lcom/android/internal/os/SomeArgs;
@@ -778,20 +773,20 @@
 Lcom/android/internal/telephony/GsmAlphabet;->gsm7BitPackedToString([BII)Ljava/lang/String;
 Lcom/android/internal/telephony/GsmAlphabet;->stringToGsm7BitPacked(Ljava/lang/String;)[B
 Lcom/android/internal/telephony/ITelephony;->getDataEnabled(I)Z
+Lcom/android/internal/telephony/OperatorInfo$State;->CURRENT:Lcom/android/internal/telephony/OperatorInfo$State;
+Lcom/android/internal/telephony/OperatorInfo$State;->FORBIDDEN:Lcom/android/internal/telephony/OperatorInfo$State;
+Lcom/android/internal/telephony/OperatorInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 Lcom/android/internal/telephony/OperatorInfo;->CREATOR:Landroid/os/Parcelable$Creator;
 Lcom/android/internal/telephony/OperatorInfo;->getOperatorAlphaLong()Ljava/lang/String;
 Lcom/android/internal/telephony/OperatorInfo;->getOperatorAlphaShort()Ljava/lang/String;
 Lcom/android/internal/telephony/OperatorInfo;->getOperatorNumeric()Ljava/lang/String;
 Lcom/android/internal/telephony/OperatorInfo;->getState()Lcom/android/internal/telephony/OperatorInfo$State;
-Lcom/android/internal/telephony/OperatorInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
-Lcom/android/internal/telephony/OperatorInfo$State;->CURRENT:Lcom/android/internal/telephony/OperatorInfo$State;
-Lcom/android/internal/telephony/OperatorInfo$State;->FORBIDDEN:Lcom/android/internal/telephony/OperatorInfo$State;
-Lcom/android/internal/util/AsyncChannel;->connect(Landroid/content/Context;Landroid/os/Handler;Landroid/os/Messenger;)V
 Lcom/android/internal/util/AsyncChannel;-><init>()V
+Lcom/android/internal/util/AsyncChannel;->connect(Landroid/content/Context;Landroid/os/Handler;Landroid/os/Messenger;)V
 Lcom/android/internal/util/AsyncChannel;->sendMessage(Landroid/os/Message;)V
+Lcom/android/internal/util/IndentingPrintWriter;-><init>(Ljava/io/Writer;Ljava/lang/String;)V
 Lcom/android/internal/util/IndentingPrintWriter;->decreaseIndent()Lcom/android/internal/util/IndentingPrintWriter;
 Lcom/android/internal/util/IndentingPrintWriter;->increaseIndent()Lcom/android/internal/util/IndentingPrintWriter;
-Lcom/android/internal/util/IndentingPrintWriter;-><init>(Ljava/io/Writer;Ljava/lang/String;)V
 Lcom/android/internal/util/XmlUtils;->beginDocument(Lorg/xmlpull/v1/XmlPullParser;Ljava/lang/String;)V
 Lcom/android/internal/util/XmlUtils;->nextElement(Lorg/xmlpull/v1/XmlPullParser;)V
 Ljava/lang/System;->arraycopy([BI[BII)V
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 452225c..ed684d7 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -302,7 +302,16 @@
 
     /**
      * This flag requests that all fingerprint gestures be sent to the accessibility service.
-     * It is handled in {@link FingerprintGestureController}
+     * <p>
+     * Services that want to set this flag have to declare the capability
+     * to retrieve window content in their meta-data by setting the attribute
+     * {@link android.R.attr#canRequestFingerprintGestures} to
+     * true, otherwise this flag will be ignored. For how to declare the meta-data
+     * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}.
+     * </p>
+     *
+     * @see android.R.styleable#AccessibilityService_canRequestFingerprintGestures
+     * @see AccessibilityService#getFingerprintGestureController()
      */
     public static final int FLAG_REQUEST_FINGERPRINT_GESTURES = 0x00000200;
 
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 97c9fa5..7338bfe 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -236,6 +236,17 @@
             int userId, Intent[] intents, Bundle bOptions);
 
     /**
+     * Start activity {@code intent} without calling user-id check.
+     *
+     * - DO NOT call it with the calling UID cleared.
+     * - The caller must do the calling user ID check.
+     *
+     * @return error codes used by {@link IActivityManager#startActivity} and its siblings.
+     */
+    public abstract int startActivityAsUser(IApplicationThread caller, String callingPackage,
+            Intent intent, @Nullable Bundle options, int userId);
+
+    /**
      * Get the procstate for the UID.  The return value will be between
      * {@link ActivityManager#MIN_PROCESS_STATE} and {@link ActivityManager#MAX_PROCESS_STATE}.
      * Note if the UID doesn't exist, it'll return {@link ActivityManager#PROCESS_STATE_NONEXISTENT}
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index a44bd03..07b4b9c 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -16,8 +16,6 @@
 
 package android.app;
 
-import com.android.internal.app.AlertController;
-
 import android.annotation.ArrayRes;
 import android.annotation.AttrRes;
 import android.annotation.DrawableRes;
@@ -30,17 +28,19 @@
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.Message;
+import android.text.Layout;
+import android.text.method.MovementMethod;
 import android.util.TypedValue;
 import android.view.ContextThemeWrapper;
 import android.view.KeyEvent;
 import android.view.View;
-import android.view.WindowManager;
 import android.widget.AdapterView;
 import android.widget.Button;
 import android.widget.ListAdapter;
 import android.widget.ListView;
 
 import com.android.internal.R;
+import com.android.internal.app.AlertController;
 
 /**
  * A subclass of Dialog that can display one, two or three buttons. If you only want to
@@ -54,7 +54,7 @@
  * </pre>
  *
  * <p>The AlertDialog class takes care of automatically setting
- * {@link WindowManager.LayoutParams#FLAG_ALT_FOCUSABLE_IM
+ * {@link android.view.WindowManager.LayoutParams#FLAG_ALT_FOCUSABLE_IM
  * WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM} for you based on whether
  * any views in the dialog return true from {@link View#onCheckIsTextEditor()
  * View.onCheckIsTextEditor()}.  Generally you want this set for a Dialog
@@ -266,6 +266,17 @@
         mAlert.setMessage(message);
     }
 
+    /** @hide */
+    public void setMessageMovementMethod(MovementMethod movementMethod) {
+        mAlert.setMessageMovementMethod(movementMethod);
+    }
+
+    /** @hide */
+    public void setMessageHyphenationFrequency(
+            @Layout.HyphenationFrequency int hyphenationFrequency) {
+        mAlert.setMessageHyphenationFrequency(hyphenationFrequency);
+    }
+
     /**
      * Set the view to display in that dialog.
      */
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index ca69118..2e788aa 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -109,6 +109,48 @@
      */
     public static final int MODE_DEFAULT = 3;
 
+    /**
+     * Metrics about an op when its uid is persistent.
+     * @hide
+     */
+    public static final int UID_STATE_PERSISTENT = 0;
+
+    /**
+     * Metrics about an op when its uid is at the top.
+     * @hide
+     */
+    public static final int UID_STATE_TOP = 1;
+
+    /**
+     * Metrics about an op when its uid is running a foreground service.
+     * @hide
+     */
+    public static final int UID_STATE_FOREGROUND_SERVICE = 2;
+
+    /**
+     * Metrics about an op when its uid is in the foreground for any other reasons.
+     * @hide
+     */
+    public static final int UID_STATE_FOREGROUND = 3;
+
+    /**
+     * Metrics about an op when its uid is in the background for any reason.
+     * @hide
+     */
+    public static final int UID_STATE_BACKGROUND = 4;
+
+    /**
+     * Metrics about an op when its uid is cached.
+     * @hide
+     */
+    public static final int UID_STATE_CACHED = 5;
+
+    /**
+     * Number of uid states we track.
+     * @hide
+     */
+    public static final int _NUM_UID_STATE = 6;
+
     // when adding one of these:
     //  - increment _NUM_OP
     //  - define an OPSTR_* constant (marked as @SystemApi)
@@ -275,6 +317,7 @@
     /** @hide Any app start foreground service. */
     public static final int OP_START_FOREGROUND = 76;
     /** @hide */
+    @TestApi
     public static final int _NUM_OP = 77;
 
     /** Access to coarse location information. */
@@ -1334,6 +1377,7 @@
      * Retrieve the permission associated with an operation, or null if there is not one.
      * @hide
      */
+    @TestApi
     public static String opToPermission(int op) {
         return sOpPerms[op];
     }
@@ -1352,6 +1396,7 @@
      * to the corresponding app op.
      * @hide
      */
+    @TestApi
     public static int permissionToOpCode(String permission) {
         Integer boxedOpCode = sPermToOp.get(permission);
         return boxedOpCode != null ? boxedOpCode : OP_NONE;
@@ -1471,8 +1516,8 @@
     public static class OpEntry implements Parcelable {
         private final int mOp;
         private final int mMode;
-        private final long mTime;
-        private final long mRejectTime;
+        private final long[] mTimes;
+        private final long[] mRejectTimes;
         private final int mDuration;
         private final int mProxyUid;
         private final String mProxyPackageName;
@@ -1481,8 +1526,23 @@
                 int proxyUid, String proxyPackage) {
             mOp = op;
             mMode = mode;
-            mTime = time;
-            mRejectTime = rejectTime;
+            mTimes = new long[_NUM_UID_STATE];
+            mRejectTimes = new long[_NUM_UID_STATE];
+            mTimes[0] = time;
+            mRejectTimes[0] = rejectTime;
+            mDuration = duration;
+            mProxyUid = proxyUid;
+            mProxyPackageName = proxyPackage;
+        }
+
+        public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration,
+                int proxyUid, String proxyPackage) {
+            mOp = op;
+            mMode = mode;
+            mTimes = new long[_NUM_UID_STATE];
+            mRejectTimes = new long[_NUM_UID_STATE];
+            System.arraycopy(times, 0, mTimes, 0, _NUM_UID_STATE);
+            System.arraycopy(rejectTimes, 0, mRejectTimes, 0, _NUM_UID_STATE);
             mDuration = duration;
             mProxyUid = proxyUid;
             mProxyPackageName = proxyPackage;
@@ -1497,11 +1557,31 @@
         }
 
         public long getTime() {
-            return mTime;
+            long time = 0;
+            for (int i = 0; i < _NUM_UID_STATE; i++) {
+                if (mTimes[i] > time) {
+                    time = mTimes[i];
+                }
+            }
+            return time;
+        }
+
+        public long getTimeFor(int uidState) {
+            return mTimes[uidState];
         }
 
         public long getRejectTime() {
-            return mRejectTime;
+            long time = 0;
+            for (int i = 0; i < _NUM_UID_STATE; i++) {
+                if (mRejectTimes[i] > time) {
+                    time = mRejectTimes[i];
+                }
+            }
+            return time;
+        }
+
+        public long getRejectTimeFor(int uidState) {
+            return mRejectTimes[uidState];
         }
 
         public boolean isRunning() {
@@ -1509,7 +1589,7 @@
         }
 
         public int getDuration() {
-            return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
+            return mDuration;
         }
 
         public int getProxyUid() {
@@ -1529,8 +1609,8 @@
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(mOp);
             dest.writeInt(mMode);
-            dest.writeLong(mTime);
-            dest.writeLong(mRejectTime);
+            dest.writeLongArray(mTimes);
+            dest.writeLongArray(mRejectTimes);
             dest.writeInt(mDuration);
             dest.writeInt(mProxyUid);
             dest.writeString(mProxyPackageName);
@@ -1539,8 +1619,8 @@
         OpEntry(Parcel source) {
             mOp = source.readInt();
             mMode = source.readInt();
-            mTime = source.readLong();
-            mRejectTime = source.readLong();
+            mTimes = source.createLongArray();
+            mRejectTimes = source.createLongArray();
             mDuration = source.readInt();
             mProxyUid = source.readInt();
             mProxyPackageName = source.readString();
@@ -1916,6 +1996,7 @@
     /**
      * {@hide}
      */
+    @TestApi
     public static int strOpToOp(String op) {
         Integer val = sOpStrToOp.get(op);
         if (val == null) {
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 2830ea7..badb2f6 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -972,6 +972,18 @@
     public static final String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
 
     /**
+     * {@link #extras} key: boolean as supplied to
+     * {@link Builder#setShowRemoteInputSpinner(boolean)}.
+     *
+     * If set to true, then the view displaying the remote input history from
+     * {@link Builder#setRemoteInputHistory(CharSequence[])} will have a progress spinner.
+     *
+     * @see Builder#setShowRemoteInputSpinner(boolean)
+     * @hide
+     */
+    public static final String EXTRA_SHOW_REMOTE_INPUT_SPINNER = "android.remoteInputSpinner";
+
+    /**
      * {@link #extras} key: this is a small piece of additional text as supplied to
      * {@link Builder#setContentInfo(CharSequence)}.
      */
@@ -1098,11 +1110,11 @@
     public static final String EXTRA_ALLOW_DURING_SETUP = "android.allowDuringSetup";
 
     /**
-     * {@link #extras} key: A
-     * {@link android.content.ContentUris content URI} pointing to an image that can be displayed
-     * in the background when the notification is selected. Used on television platforms.
-     * The URI must point to an image stream suitable for passing into
-     * {@link android.graphics.BitmapFactory#decodeStream(java.io.InputStream)
+     * {@link #extras} key:
+     * flat {@link String} representation of a {@link android.content.ContentUris content URI}
+     * pointing to an image that can be displayed in the background when the notification is
+     * selected. Used on television platforms. The URI must point to an image stream suitable for
+     * passing into {@link android.graphics.BitmapFactory#decodeStream(java.io.InputStream)
      * BitmapFactory.decodeStream}; all other content types will be ignored.
      */
     public static final String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
@@ -2323,7 +2335,9 @@
 
         if (extras != null) {
             visitor.accept(extras.getParcelable(EXTRA_AUDIO_CONTENTS_URI));
-            visitor.accept(extras.getParcelable(EXTRA_BACKGROUND_IMAGE_URI));
+            if (extras.containsKey(EXTRA_BACKGROUND_IMAGE_URI)) {
+                visitor.accept(Uri.parse(extras.getString(EXTRA_BACKGROUND_IMAGE_URI)));
+            }
         }
 
         if (MessagingStyle.class.equals(getNotificationStyle()) && extras != null) {
@@ -2710,7 +2724,40 @@
      * @hide
      */
     public static boolean areRemoteViewsChanged(Builder first, Builder second) {
-        return !first.usesStandardHeader() || !second.usesStandardHeader();
+        if (!Objects.equals(first.usesStandardHeader(), second.usesStandardHeader())) {
+            return true;
+        }
+
+        if (areRemoteViewsChanged(first.mN.contentView, second.mN.contentView)) {
+            return true;
+        }
+        if (areRemoteViewsChanged(first.mN.bigContentView, second.mN.bigContentView)) {
+            return true;
+        }
+        if (areRemoteViewsChanged(first.mN.headsUpContentView, second.mN.headsUpContentView)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private static boolean areRemoteViewsChanged(RemoteViews first, RemoteViews second) {
+        if (first == null && second == null) {
+            return false;
+        }
+        if (first == null && second != null || first != null && second == null) {
+            return true;
+        }
+
+        if (!Objects.equals(first.getLayoutId(), second.getLayoutId())) {
+            return true;
+        }
+
+        if (!Objects.equals(first.getSequenceNumber(), second.getSequenceNumber())) {
+            return true;
+        }
+
+        return false;
     }
 
     /**
@@ -3142,10 +3189,14 @@
         private int mCachedContrastColor = COLOR_INVALID;
         private int mCachedContrastColorIsFor = COLOR_INVALID;
         /**
-         * Caches a ambient version of {@link #mCachedContrastColorIsFor}.
+         * Caches a ambient version of {@link #mCachedAmbientColorIsFor}.
          */
         private int mCachedAmbientColor = COLOR_INVALID;
         private int mCachedAmbientColorIsFor = COLOR_INVALID;
+        /**
+         * A neutral color color that can be used for icons.
+         */
+        private int mNeutralColor = COLOR_INVALID;
 
         /**
          * Caches an instance of StandardTemplateParams. Note that this may have been used before,
@@ -3537,6 +3588,15 @@
         }
 
         /**
+         * Sets whether remote history entries view should have a spinner.
+         * @hide
+         */
+        public Builder setShowRemoteInputSpinner(boolean showSpinner) {
+            mN.extras.putBoolean(EXTRA_SHOW_REMOTE_INPUT_SPINNER, showSpinner);
+            return this;
+        }
+
+        /**
          * Sets the number of items this notification represents. May be displayed as a badge count
          * for Launchers that support badging.
          */
@@ -4278,7 +4338,6 @@
 
         private void resetStandardTemplate(RemoteViews contentView) {
             resetNotificationHeader(contentView);
-            resetContentMargins(contentView);
             contentView.setViewVisibility(R.id.right_icon, View.GONE);
             contentView.setViewVisibility(R.id.title, View.GONE);
             contentView.setTextViewText(R.id.title, null);
@@ -4310,24 +4369,23 @@
             mN.mUsesStandardHeader = false;
         }
 
-        private void resetContentMargins(RemoteViews contentView) {
-            contentView.setViewLayoutMarginEndDimen(R.id.line1, 0);
-            contentView.setViewLayoutMarginEndDimen(R.id.text, 0);
-        }
-
-        private RemoteViews applyStandardTemplate(int resId) {
-            return applyStandardTemplate(resId, mParams.reset().fillTextsFrom(this));
+        private RemoteViews applyStandardTemplate(int resId, TemplateBindResult result) {
+            return applyStandardTemplate(resId, mParams.reset().fillTextsFrom(this),
+                    result);
         }
 
         /**
          * @param hasProgress whether the progress bar should be shown and set
+         * @param result
          */
-        private RemoteViews applyStandardTemplate(int resId, boolean hasProgress) {
+        private RemoteViews applyStandardTemplate(int resId, boolean hasProgress,
+                TemplateBindResult result) {
             return applyStandardTemplate(resId, mParams.reset().hasProgress(hasProgress)
-                    .fillTextsFrom(this));
+                    .fillTextsFrom(this), result);
         }
 
-        private RemoteViews applyStandardTemplate(int resId, StandardTemplateParams p) {
+        private RemoteViews applyStandardTemplate(int resId, StandardTemplateParams p,
+                TemplateBindResult result) {
             RemoteViews contentView = new BuilderRemoteViews(mContext.getApplicationInfo(), resId);
 
             resetStandardTemplate(contentView);
@@ -4335,7 +4393,7 @@
             final Bundle ex = mN.extras;
             updateBackgroundColor(contentView);
             bindNotificationHeader(contentView, p.ambient, p.headerTextSecondary);
-            bindLargeIcon(contentView, p.hideLargeIcon || p.ambient, p.alwaysShowReply);
+            bindLargeIconAndReply(contentView, p, result);
             boolean showProgress = handleProgressBar(p.hasProgress, contentView, ex);
             if (p.title != null) {
                 contentView.setViewVisibility(R.id.title, View.VISIBLE);
@@ -4531,8 +4589,58 @@
             }
         }
 
-        private void bindLargeIcon(RemoteViews contentView, boolean hideLargeIcon,
-                boolean alwaysShowReply) {
+        private void bindLargeIconAndReply(RemoteViews contentView, StandardTemplateParams p,
+                TemplateBindResult result) {
+            boolean largeIconShown = bindLargeIcon(contentView, p.hideLargeIcon || p.ambient);
+            boolean replyIconShown = bindReplyIcon(contentView, p.hideReplyIcon || p.ambient);
+            contentView.setViewVisibility(R.id.right_icon_container,
+                    largeIconShown || replyIconShown ? View.VISIBLE : View.GONE);
+            int marginEnd = calculateMarginEnd(largeIconShown, replyIconShown);
+            contentView.setViewLayoutMarginEnd(R.id.line1, marginEnd);
+            contentView.setViewLayoutMarginEnd(R.id.text, marginEnd);
+            contentView.setViewLayoutMarginEnd(R.id.progress, marginEnd);
+            if (result != null) {
+                result.setIconMarginEnd(marginEnd);
+            }
+        }
+
+        private int calculateMarginEnd(boolean largeIconShown, boolean replyIconShown) {
+            int marginEnd = 0;
+            int contentMargin = mContext.getResources().getDimensionPixelSize(
+                    R.dimen.notification_content_margin_end);
+            int iconSize = mContext.getResources().getDimensionPixelSize(
+                    R.dimen.notification_right_icon_size);
+            if (replyIconShown) {
+                // The size of the reply icon
+                marginEnd += iconSize;
+
+                int replyInset = mContext.getResources().getDimensionPixelSize(
+                        R.dimen.notification_reply_inset);
+                // We're subtracting the inset of the reply icon to make sure it's
+                // aligned nicely on the right, and remove it from the following padding
+                marginEnd -= replyInset * 2;
+            }
+            if (largeIconShown) {
+                // adding size of the right icon
+                marginEnd += iconSize;
+
+                if (replyIconShown) {
+                    // We also add some padding to the reply icon if it's around
+                    marginEnd += contentMargin;
+                }
+            }
+            if (replyIconShown || largeIconShown) {
+                // The padding to the content
+                marginEnd += contentMargin;
+            }
+            return marginEnd;
+        }
+
+        /**
+         * Bind the large icon.
+         * @return if the largeIcon is visible
+         */
+        private boolean bindLargeIcon(RemoteViews contentView, boolean hideLargeIcon) {
             if (mN.mLargeIcon == null && mN.largeIcon != null) {
                 mN.mLargeIcon = Icon.createWithBitmap(mN.largeIcon);
             }
@@ -4541,51 +4649,35 @@
                 contentView.setViewVisibility(R.id.right_icon, View.VISIBLE);
                 contentView.setImageViewIcon(R.id.right_icon, mN.mLargeIcon);
                 processLargeLegacyIcon(mN.mLargeIcon, contentView);
-                int endMargin = R.dimen.notification_content_picture_margin;
-                contentView.setViewLayoutMarginEndDimen(R.id.line1, endMargin);
-                contentView.setViewLayoutMarginEndDimen(R.id.text, endMargin);
-                contentView.setViewLayoutMarginEndDimen(R.id.progress, endMargin);
             }
-            // Bind the reply action
-            Action action = findReplyAction();
+            return showLargeIcon;
+        }
 
-            boolean actionVisible = action != null && (showLargeIcon || alwaysShowReply);
-            int replyId = showLargeIcon ? R.id.reply_icon_action : R.id.right_icon;
+        /**
+         * Bind the reply icon.
+         * @return if the reply icon is visible
+         */
+        private boolean bindReplyIcon(RemoteViews contentView, boolean hideReplyIcon) {
+            boolean actionVisible = !hideReplyIcon;
+            Action action = null;
             if (actionVisible) {
-                // We're only showing the icon as big if we're hiding the large icon
-                int contrastColor = resolveContrastColor();
-                int iconColor;
-                if (showLargeIcon) {
-                    contentView.setDrawableTint(R.id.reply_icon_action,
-                            true /* targetBackground */,
-                            contrastColor, PorterDuff.Mode.SRC_ATOP);
-                    contentView.setOnClickPendingIntent(R.id.right_icon,
-                            action.actionIntent);
-                    contentView.setRemoteInputs(R.id.right_icon, action.mRemoteInputs);
-                    iconColor = NotificationColorUtil.isColorLight(contrastColor)
-                            ? Color.BLACK : Color.WHITE;
-                } else {
-                    contentView.setImageViewResource(R.id.right_icon,
-                            R.drawable.ic_reply_notification_large);
-                    contentView.setViewVisibility(R.id.right_icon, View.VISIBLE);
-                    iconColor = contrastColor;
-                }
-                contentView.setDrawableTint(replyId,
-                        false /* targetBackground */,
-                        iconColor,
-                        PorterDuff.Mode.SRC_ATOP);
-                contentView.setOnClickPendingIntent(replyId,
-                        action.actionIntent);
-                contentView.setRemoteInputs(replyId, action.mRemoteInputs);
-            } else {
-                contentView.setRemoteInputs(R.id.right_icon, null);
+                action = findReplyAction();
+                actionVisible = action != null;
             }
-            contentView.setViewVisibility(R.id.reply_icon_action, actionVisible && showLargeIcon
-                    ? View.VISIBLE
-                    : View.GONE);
-            contentView.setViewVisibility(R.id.right_icon_container, actionVisible || showLargeIcon
-                    ? View.VISIBLE
-                    : View.GONE);
+            if (actionVisible) {
+                contentView.setViewVisibility(R.id.reply_icon_action, View.VISIBLE);
+                contentView.setDrawableTint(R.id.reply_icon_action,
+                        false /* targetBackground */,
+                        getNeutralColor(),
+                        PorterDuff.Mode.SRC_ATOP);
+                contentView.setOnClickPendingIntent(R.id.reply_icon_action, action.actionIntent);
+                contentView.setRemoteInputs(R.id.reply_icon_action, action.mRemoteInputs);
+            } else {
+                contentView.setRemoteInputs(R.id.reply_icon_action, null);
+            }
+            contentView.setViewVisibility(R.id.reply_icon_action,
+                    actionVisible ? View.VISIBLE : View.GONE);
+            return actionVisible;
         }
 
         private Action findReplyAction() {
@@ -4620,8 +4712,7 @@
         }
 
         private void bindActivePermissions(RemoteViews contentView, boolean ambient) {
-            int color = ambient ? resolveAmbientColor()
-                    : isColorized() ? getPrimaryTextColor() : resolveContrastColor();
+            int color = ambient ? resolveAmbientColor() : getNeutralColor();
             contentView.setDrawableTint(R.id.camera, false, color, PorterDuff.Mode.SRC_ATOP);
             contentView.setDrawableTint(R.id.mic, false, color, PorterDuff.Mode.SRC_ATOP);
             contentView.setDrawableTint(R.id.overlay, false, color, PorterDuff.Mode.SRC_ATOP);
@@ -4760,6 +4851,8 @@
 
             big.setViewVisibility(R.id.notification_material_reply_container, View.GONE);
             big.setTextViewText(R.id.notification_material_reply_text_1, null);
+            big.setViewVisibility(R.id.notification_material_reply_text_1_container, View.GONE);
+            big.setViewVisibility(R.id.notification_material_reply_progress, View.GONE);
 
             big.setViewVisibility(R.id.notification_material_reply_text_2, View.GONE);
             big.setTextViewText(R.id.notification_material_reply_text_2, null);
@@ -4770,13 +4863,15 @@
                     R.dimen.notification_content_margin);
         }
 
-        private RemoteViews applyStandardTemplateWithActions(int layoutId) {
-            return applyStandardTemplateWithActions(layoutId, mParams.reset().fillTextsFrom(this));
+        private RemoteViews applyStandardTemplateWithActions(int layoutId,
+                TemplateBindResult result) {
+            return applyStandardTemplateWithActions(layoutId, mParams.reset().fillTextsFrom(this),
+                    result);
         }
 
         private RemoteViews applyStandardTemplateWithActions(int layoutId,
-            StandardTemplateParams p) {
-            RemoteViews big = applyStandardTemplate(layoutId, p);
+                StandardTemplateParams p, TemplateBindResult result) {
+            RemoteViews big = applyStandardTemplate(layoutId, p, result);
 
             resetStandardTemplateWithActions(big);
 
@@ -4810,10 +4905,19 @@
             CharSequence[] replyText = mN.extras.getCharSequenceArray(EXTRA_REMOTE_INPUT_HISTORY);
             if (!p.ambient && validRemoteInput && replyText != null
                     && replyText.length > 0 && !TextUtils.isEmpty(replyText[0])) {
+                boolean showSpinner = mN.extras.getBoolean(EXTRA_SHOW_REMOTE_INPUT_SPINNER);
                 big.setViewVisibility(R.id.notification_material_reply_container, View.VISIBLE);
+                big.setViewVisibility(R.id.notification_material_reply_text_1_container,
+                        View.VISIBLE);
                 big.setTextViewText(R.id.notification_material_reply_text_1,
                         processTextSpans(replyText[0]));
                 setTextViewColorSecondary(big, R.id.notification_material_reply_text_1);
+                big.setViewVisibility(R.id.notification_material_reply_progress,
+                        showSpinner ? View.VISIBLE : View.GONE);
+                big.setProgressIndeterminateTintList(
+                        R.id.notification_material_reply_progress,
+                        ColorStateList.valueOf(
+                                isColorized() ? getPrimaryTextColor() : resolveContrastColor()));
 
                 if (replyText.length > 1 && !TextUtils.isEmpty(replyText[1])) {
                     big.setViewVisibility(R.id.notification_material_reply_text_2, View.VISIBLE);
@@ -4883,7 +4987,7 @@
                     return styleView;
                 }
             }
-            return applyStandardTemplate(getBaseLayoutResource());
+            return applyStandardTemplate(getBaseLayoutResource(), null /* result */);
         }
 
         private boolean useExistingRemoteView() {
@@ -4902,7 +5006,8 @@
                 result = mStyle.makeBigContentView();
                 hideLine1Text(result);
             } else if (mActions.size() != 0) {
-                result = applyStandardTemplateWithActions(getBigBaseLayoutResource());
+                result = applyStandardTemplateWithActions(getBigBaseLayoutResource(),
+                        null /* result */);
             }
             makeHeaderExpanded(result);
             return result;
@@ -4939,7 +5044,8 @@
         public RemoteViews makeAmbientNotification() {
             RemoteViews ambient = applyStandardTemplateWithActions(
                     R.layout.notification_template_material_ambient,
-                    mParams.reset().ambient(true).fillTextsFrom(this).hasProgress(false));
+                    mParams.reset().ambient(true).fillTextsFrom(this).hasProgress(false),
+                    null /* result */);
             return ambient;
         }
 
@@ -4982,7 +5088,7 @@
                 return null;
             }
 
-            return applyStandardTemplateWithActions(getBigBaseLayoutResource());
+            return applyStandardTemplateWithActions(getBigBaseLayoutResource(), null /* result */);
         }
 
         /**
@@ -5031,6 +5137,10 @@
                     savedBundle.getBoolean(EXTRA_SHOW_CHRONOMETER));
             publicExtras.putBoolean(EXTRA_CHRONOMETER_COUNT_DOWN,
                     savedBundle.getBoolean(EXTRA_CHRONOMETER_COUNT_DOWN));
+            String appName = savedBundle.getString(EXTRA_SUBSTITUTE_APP_NAME);
+            if (appName != null) {
+                publicExtras.putString(EXTRA_SUBSTITUTE_APP_NAME, appName);
+            }
             mN.extras = publicExtras;
             RemoteViews view;
             if (ambient) {
@@ -5330,6 +5440,20 @@
             return mCachedContrastColor = color;
         }
 
+        int resolveNeutralColor() {
+            if (mNeutralColor != COLOR_INVALID) {
+                return mNeutralColor;
+            }
+            int background = mContext.getColor(
+                    com.android.internal.R.color.notification_material_background_color);
+            mNeutralColor = NotificationColorUtil.resolveDefaultColor(mContext, background);
+            if (Color.alpha(mNeutralColor) < 255) {
+                // alpha doesn't go well for color filters, so let's blend it manually
+                mNeutralColor = NotificationColorUtil.compositeColors(mNeutralColor, background);
+            }
+            return mNeutralColor;
+        }
+
         int resolveAmbientColor() {
             if (mCachedAmbientColorIsFor == mN.color && mCachedAmbientColorIsFor != COLOR_INVALID) {
                 return mCachedAmbientColor;
@@ -5567,6 +5691,17 @@
         }
 
         /**
+         * Gets a neutral color that can be used for icons or similar that should not stand out.
+         */
+        private int getNeutralColor() {
+            if (isColorized()) {
+                return getSecondaryTextColor();
+            } else {
+                return resolveNeutralColor();
+            }
+        }
+
+        /**
          * Same as getBackgroundColor but also resolved the default color to the background.
          */
         private int resolveBackgroundColor() {
@@ -5868,6 +6003,18 @@
         }
 
         protected RemoteViews getStandardView(int layoutId) {
+            return getStandardView(layoutId, null);
+        }
+
+        /**
+         * Get the standard view for this style.
+         *
+         * @param layoutId The layout id to use
+         * @param result The result where template bind information is saved.
+         * @return A remoteView for this style.
+         * @hide
+         */
+        protected RemoteViews getStandardView(int layoutId, TemplateBindResult result) {
             checkBuilder();
 
             // Nasty.
@@ -5877,7 +6024,7 @@
                 mBuilder.setContentTitle(mBigContentTitle);
             }
 
-            RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(layoutId);
+            RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(layoutId, result);
 
             mBuilder.getAllExtras().putCharSequence(EXTRA_TITLE, oldBuilderContentTitle);
 
@@ -6174,7 +6321,8 @@
                 mBuilder.mN.largeIcon = null;
             }
 
-            RemoteViews contentView = getStandardView(mBuilder.getBigPictureLayoutResource());
+            RemoteViews contentView = getStandardView(mBuilder.getBigPictureLayoutResource(),
+                    null /* result */);
             if (mSummaryTextSet) {
                 contentView.setTextViewText(R.id.text, mBuilder.processTextSpans(
                         mBuilder.processLegacyText(mSummaryText)));
@@ -6361,7 +6509,9 @@
             CharSequence text = mBuilder.getAllExtras().getCharSequence(EXTRA_TEXT);
             mBuilder.getAllExtras().putCharSequence(EXTRA_TEXT, null);
 
-            RemoteViews contentView = getStandardView(mBuilder.getBigTextLayoutResource());
+            TemplateBindResult result = new TemplateBindResult();
+            RemoteViews contentView = getStandardView(mBuilder.getBigTextLayoutResource(), result);
+            contentView.setInt(R.id.big_text, "setImageEndMargin", result.getIconMarginEnd());
 
             mBuilder.getAllExtras().putCharSequence(EXTRA_TEXT, text);
 
@@ -6744,7 +6894,7 @@
             mBuilder.mOriginalActions = mBuilder.mActions;
             mBuilder.mActions = new ArrayList<>();
             RemoteViews remoteViews = makeMessagingView(true /* displayImagesAtEnd */,
-                    true /* showReplyIcon */);
+                    false /* hideLargeIcon */);
             mBuilder.mActions = mBuilder.mOriginalActions;
             mBuilder.mOriginalActions = null;
             return remoteViews;
@@ -6831,7 +6981,7 @@
          */
         @Override
         public RemoteViews makeBigContentView() {
-            return makeMessagingView(false /* displayImagesAtEnd */, false /* showReplyIcon */);
+            return makeMessagingView(false /* displayImagesAtEnd */, true /* hideLargeIcon */);
         }
 
         /**
@@ -6839,11 +6989,11 @@
          *
          * @param displayImagesAtEnd should images be displayed at the end of the content instead
          *                           of inline.
-         * @param showReplyIcon Should the reply affordance be shown at the end of the notification
+         * @param hideRightIcons Should the reply affordance be shown at the end of the notification
          * @return the created remoteView.
          */
         @NonNull
-        private RemoteViews makeMessagingView(boolean displayImagesAtEnd, boolean showReplyIcon) {
+        private RemoteViews makeMessagingView(boolean displayImagesAtEnd, boolean hideRightIcons) {
             CharSequence conversationTitle = !TextUtils.isEmpty(super.mBigContentTitle)
                     ? super.mBigContentTitle
                     : mConversationTitle;
@@ -6854,20 +7004,18 @@
                 nameReplacement = conversationTitle;
                 conversationTitle = null;
             }
-            boolean hideLargeIcon = !showReplyIcon || isOneToOne;
+            TemplateBindResult bindResult = new TemplateBindResult();
             RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(
                     mBuilder.getMessagingLayoutResource(),
                     mBuilder.mParams.reset().hasProgress(false).title(conversationTitle).text(null)
-                            .hideLargeIcon(hideLargeIcon)
-                            .headerTextSecondary(conversationTitle)
-                            .alwaysShowReply(showReplyIcon));
+                            .hideLargeIcon(hideRightIcons || isOneToOne)
+                            .hideReplyIcon(hideRightIcons)
+                            .headerTextSecondary(conversationTitle),
+                    bindResult);
             addExtras(mBuilder.mN.extras);
             // also update the end margin if there is an image
-            int endMargin = R.dimen.notification_content_margin_end;
-            if (showReplyIcon) {
-                endMargin = R.dimen.notification_content_plus_picture_margin_end;
-            }
-            contentView.setViewLayoutMarginEndDimen(R.id.notification_main_column, endMargin);
+            contentView.setViewLayoutMarginEnd(R.id.notification_messaging,
+                    bindResult.getIconMarginEnd());
             contentView.setInt(R.id.status_bar_latest_event_content, "setLayoutColor",
                     mBuilder.resolveContrastColor());
             contentView.setBoolean(R.id.status_bar_latest_event_content, "setDisplayImagesAtEnd",
@@ -6939,7 +7087,7 @@
         @Override
         public RemoteViews makeHeadsUpContentView(boolean increasedHeight) {
             RemoteViews remoteViews = makeMessagingView(true /* displayImagesAtEnd */,
-                    false /* showReplyIcon */);
+                    true /* hideLargeIcon */);
             remoteViews.setInt(R.id.notification_messaging, "setMaxDisplayedLines", 1);
             return remoteViews;
         }
@@ -6958,11 +7106,16 @@
             static final String KEY_DATA_MIME_TYPE = "type";
             static final String KEY_DATA_URI= "uri";
             static final String KEY_EXTRAS_BUNDLE = "extras";
+            static final String KEY_REMOTE_INPUT_HISTORY = "remote_input_history";
 
             private final CharSequence mText;
             private final long mTimestamp;
             @Nullable
             private final Person mSender;
+            /** True if this message was generated from the extra
+             *  {@link Notification#EXTRA_REMOTE_INPUT_HISTORY}
+             */
+            private final boolean mRemoteInputHistory;
 
             private Bundle mExtras = new Bundle();
             private String mDataMimeType;
@@ -7001,9 +7154,33 @@
              * </p>
              */
             public Message(@NonNull CharSequence text, long timestamp, @Nullable Person sender) {
+                this(text, timestamp, sender, false /* remoteHistory */);
+            }
+
+            /**
+             * Constructor
+             * @param text A {@link CharSequence} to be displayed as the message content
+             * @param timestamp Time at which the message arrived
+             * @param sender The {@link Person} who sent the message.
+             * Should be <code>null</code> for messages by the current user, in which case
+             * the platform will insert the user set in {@code MessagingStyle(Person)}.
+             * @param remoteInputHistory True if the messages was generated from the extra
+             * {@link Notification#EXTRA_REMOTE_INPUT_HISTORY}.
+             * <p>
+             * The person provided should contain an Icon, set with
+             * {@link Person.Builder#setIcon(Icon)} and also have a name provided
+             * with {@link Person.Builder#setName(CharSequence)}. If multiple users have the same
+             * name, consider providing a key with {@link Person.Builder#setKey(String)} in order
+             * to differentiate between the different users.
+             * </p>
+             * @hide
+             */
+            public Message(@NonNull CharSequence text, long timestamp, @Nullable Person sender,
+                    boolean remoteInputHistory) {
                 mText = text;
                 mTimestamp = timestamp;
                 mSender = sender;
+                mRemoteInputHistory = remoteInputHistory;
             }
 
             /**
@@ -7093,6 +7270,15 @@
                 return mDataUri;
             }
 
+            /**
+             * @return True if the message was generated from
+             * {@link Notification#EXTRA_REMOTE_INPUT_HISTORY}.
+             * @hide
+             */
+            public boolean isRemoteInputHistory() {
+                return mRemoteInputHistory;
+            }
+
             private Bundle toBundle() {
                 Bundle bundle = new Bundle();
                 if (mText != null) {
@@ -7113,6 +7299,9 @@
                 if (mExtras != null) {
                     bundle.putBundle(KEY_EXTRAS_BUNDLE, mExtras);
                 }
+                if (mRemoteInputHistory) {
+                    bundle.putBoolean(KEY_REMOTE_INPUT_HISTORY, mRemoteInputHistory);
+                }
                 return bundle;
             }
 
@@ -7164,7 +7353,8 @@
                         }
                         Message message = new Message(bundle.getCharSequence(KEY_TEXT),
                                 bundle.getLong(KEY_TIMESTAMP),
-                                senderPerson);
+                                senderPerson,
+                                bundle.getBoolean(KEY_REMOTE_INPUT_HISTORY, false));
                         if (bundle.containsKey(KEY_DATA_MIME_TYPE) &&
                                 bundle.containsKey(KEY_DATA_URI)) {
                             message.setData(bundle.getString(KEY_DATA_MIME_TYPE),
@@ -7280,7 +7470,8 @@
             CharSequence oldBuilderContentText = mBuilder.mN.extras.getCharSequence(EXTRA_TEXT);
             mBuilder.getAllExtras().putCharSequence(EXTRA_TEXT, null);
 
-            RemoteViews contentView = getStandardView(mBuilder.getInboxLayoutResource());
+            TemplateBindResult result = new TemplateBindResult();
+            RemoteViews contentView = getStandardView(mBuilder.getInboxLayoutResource(), result);
 
             mBuilder.getAllExtras().putCharSequence(EXTRA_TEXT, oldBuilderContentText);
 
@@ -7309,7 +7500,8 @@
                             mBuilder.processTextSpans(mBuilder.processLegacyText(str)));
                     mBuilder.setTextViewColorSecondary(contentView, rowIds[i]);
                     contentView.setViewPadding(rowIds[i], 0, topPadding, 0, 0);
-                    handleInboxImageMargin(contentView, rowIds[i], first);
+                    handleInboxImageMargin(contentView, rowIds[i], first,
+                            result.getIconMarginEnd());
                     if (first) {
                         onlyViewId = rowIds[i];
                     } else {
@@ -7341,17 +7533,18 @@
             return !Objects.equals(getLines(), newS.getLines());
         }
 
-        private void handleInboxImageMargin(RemoteViews contentView, int id, boolean first) {
+        private void handleInboxImageMargin(RemoteViews contentView, int id, boolean first,
+                int marginEndValue) {
             int endMargin = 0;
             if (first) {
                 final int max = mBuilder.mN.extras.getInt(EXTRA_PROGRESS_MAX, 0);
                 final boolean ind = mBuilder.mN.extras.getBoolean(EXTRA_PROGRESS_INDETERMINATE);
                 boolean hasProgress = max != 0 || ind;
-                if (mBuilder.mN.hasLargeIcon() && !hasProgress) {
-                    endMargin = R.dimen.notification_content_picture_margin;
+                if (!hasProgress) {
+                    endMargin = marginEndValue;
                 }
             }
-            contentView.setViewLayoutMarginEndDimen(id, endMargin);
+            contentView.setViewLayoutMarginEnd(id, endMargin);
         }
     }
 
@@ -7540,7 +7733,8 @@
 
         private RemoteViews makeMediaContentView() {
             RemoteViews view = mBuilder.applyStandardTemplate(
-                    R.layout.notification_template_material_media, false /* hasProgress */);
+                    R.layout.notification_template_material_media, false, /* hasProgress */
+                    null /* result */);
 
             final int numActions = mBuilder.mActions.size();
             final int N = mActionsToShowInCompact == null
@@ -7564,7 +7758,7 @@
             // handle the content margin
             int endMargin = R.dimen.notification_content_margin_end;
             if (mBuilder.mN.hasLargeIcon()) {
-                endMargin = R.dimen.notification_content_plus_picture_margin_end;
+                endMargin = R.dimen.notification_media_image_margin_end;
             }
             view.setViewLayoutMarginEndDimen(R.id.notification_main_column, endMargin);
             return view;
@@ -7585,8 +7779,7 @@
                 return null;
             }
             RemoteViews big = mBuilder.applyStandardTemplate(
-                    R.layout.notification_template_material_big_media,
-                    false);
+                    R.layout.notification_template_material_big_media, false, null /* result */);
 
             if (actionCount > 0) {
                 big.removeAllViews(com.android.internal.R.id.media_actions);
@@ -7682,16 +7875,18 @@
             if (mBuilder.mActions.size() == 0) {
                return makeStandardTemplateWithCustomContent(headsUpContentView);
             }
+            TemplateBindResult result = new TemplateBindResult();
             RemoteViews remoteViews = mBuilder.applyStandardTemplateWithActions(
-                        mBuilder.getBigBaseLayoutResource());
-            buildIntoRemoteViewContent(remoteViews, headsUpContentView);
+                        mBuilder.getBigBaseLayoutResource(), result);
+            buildIntoRemoteViewContent(remoteViews, headsUpContentView, result);
             return remoteViews;
         }
 
         private RemoteViews makeStandardTemplateWithCustomContent(RemoteViews customContent) {
+            TemplateBindResult result = new TemplateBindResult();
             RemoteViews remoteViews = mBuilder.applyStandardTemplate(
-                    mBuilder.getBaseLayoutResource());
-            buildIntoRemoteViewContent(remoteViews, customContent);
+                    mBuilder.getBaseLayoutResource(), result);
+            buildIntoRemoteViewContent(remoteViews, customContent, result);
             return remoteViews;
         }
 
@@ -7702,14 +7897,15 @@
             if (mBuilder.mActions.size() == 0) {
                 return makeStandardTemplateWithCustomContent(bigContentView);
             }
+            TemplateBindResult result = new TemplateBindResult();
             RemoteViews remoteViews = mBuilder.applyStandardTemplateWithActions(
-                    mBuilder.getBigBaseLayoutResource());
-            buildIntoRemoteViewContent(remoteViews, bigContentView);
+                    mBuilder.getBigBaseLayoutResource(), result);
+            buildIntoRemoteViewContent(remoteViews, bigContentView, result);
             return remoteViews;
         }
 
         private void buildIntoRemoteViewContent(RemoteViews remoteViews,
-                RemoteViews customContent) {
+                RemoteViews customContent, TemplateBindResult result) {
             if (customContent != null) {
                 // Need to clone customContent before adding, because otherwise it can no longer be
                 // parceled independently of remoteViews.
@@ -7719,11 +7915,10 @@
                 remoteViews.setReapplyDisallowed();
             }
             // also update the end margin if there is an image
-            int endMargin = R.dimen.notification_content_margin_end;
-            if (mBuilder.mN.hasLargeIcon()) {
-                endMargin = R.dimen.notification_content_plus_picture_margin_end;
-            }
-            remoteViews.setViewLayoutMarginEndDimen(R.id.notification_main_column, endMargin);
+            Resources resources = mBuilder.mContext.getResources();
+            int endMargin = resources.getDimensionPixelSize(
+                    R.dimen.notification_content_margin_end) + result.getIconMarginEnd();
+            remoteViews.setViewLayoutMarginEnd(R.id.notification_main_column, endMargin);
         }
 
         /**
@@ -9327,6 +9522,25 @@
         }
     }
 
+    /**
+     * A result object where information about the template that was created is saved.
+     */
+    private static class TemplateBindResult {
+        int mIconMarginEnd;
+
+        /**
+         * Get the margin end that needs to be added to any fields that may overlap
+         * with the right actions.
+         */
+        public int getIconMarginEnd() {
+            return mIconMarginEnd;
+        }
+
+        public void setIconMarginEnd(int iconMarginEnd) {
+            this.mIconMarginEnd = iconMarginEnd;
+        }
+    }
+
     private static class StandardTemplateParams {
         boolean hasProgress = true;
         boolean ambient = false;
@@ -9334,7 +9548,7 @@
         CharSequence text;
         CharSequence headerTextSecondary;
         boolean hideLargeIcon;
-        public boolean alwaysShowReply;
+        boolean hideReplyIcon;
 
         final StandardTemplateParams reset() {
             hasProgress = true;
@@ -9365,13 +9579,13 @@
             return this;
         }
 
-        final StandardTemplateParams alwaysShowReply(boolean alwaysShowReply) {
-            this.alwaysShowReply = alwaysShowReply;
+        final StandardTemplateParams hideLargeIcon(boolean hideLargeIcon) {
+            this.hideLargeIcon = hideLargeIcon;
             return this;
         }
 
-        final StandardTemplateParams hideLargeIcon(boolean hideLargeIcon) {
-            this.hideLargeIcon = hideLargeIcon;
+        final StandardTemplateParams hideReplyIcon(boolean hideReplyIcon) {
+            this.hideReplyIcon = hideReplyIcon;
             return this;
         }
 
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 315259b..bdaf80e 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -33,8 +33,11 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.AndroidException;
+import android.util.ArraySet;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.os.IResultReceiver;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -93,7 +96,9 @@
  */
 public final class PendingIntent implements Parcelable {
     private final IIntentSender mTarget;
+    private IResultReceiver mCancelReceiver;
     private IBinder mWhitelistToken;
+    private ArraySet<CancelListener> mCancelListeners;
 
     /** @hide */
     @IntDef(flag = true,
@@ -964,6 +969,74 @@
     }
 
     /**
+     * Register a listener to when this pendingIntent is cancelled. There are no guarantees on which
+     * thread a listener will be called and it's up to the caller to synchronize. This may
+     * trigger a synchronous binder call so should therefore usually be called on a background
+     * thread.
+     *
+     * @hide
+     */
+    public void registerCancelListener(CancelListener cancelListener) {
+        synchronized (this) {
+            if (mCancelReceiver == null) {
+                mCancelReceiver = new IResultReceiver.Stub() {
+                    @Override
+                    public void send(int resultCode, Bundle resultData) throws RemoteException {
+                        notifyCancelListeners();
+                    }
+                };
+            }
+            if (mCancelListeners == null) {
+                mCancelListeners = new ArraySet<>();
+            }
+            boolean wasEmpty = mCancelListeners.isEmpty();
+            mCancelListeners.add(cancelListener);
+            if (wasEmpty) {
+                try {
+                    ActivityManager.getService().registerIntentSenderCancelListener(mTarget,
+                            mCancelReceiver);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
+            }
+        }
+    }
+
+    private void notifyCancelListeners() {
+        ArraySet<CancelListener> cancelListeners;
+        synchronized (this) {
+            cancelListeners = new ArraySet<>(mCancelListeners);
+        }
+        int size = cancelListeners.size();
+        for (int i = 0; i < size; i++) {
+            cancelListeners.valueAt(i).onCancelled(this);
+        }
+    }
+
+    /**
+     * Un-register a listener to when this pendingIntent is cancelled.
+     *
+     * @hide
+     */
+    public void unregisterCancelListener(CancelListener cancelListener) {
+        synchronized (this) {
+            if (mCancelListeners == null) {
+                return;
+            }
+            boolean wasEmpty = mCancelListeners.isEmpty();
+            mCancelListeners.remove(cancelListener);
+            if (mCancelListeners.isEmpty() && !wasEmpty) {
+                try {
+                    ActivityManager.getService().unregisterIntentSenderCancelListener(mTarget,
+                            mCancelReceiver);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
+            }
+        }
+    }
+
+    /**
      * Return the user handle of the application that created this
      * PendingIntent, that is the user under which you will actually be
      * sending the Intent.  The returned UserHandle is supplied by the system, so
@@ -1184,4 +1257,18 @@
     public IBinder getWhitelistToken() {
         return mWhitelistToken;
     }
+
+    /**
+     * A listener to when a pending intent is cancelled
+     *
+     * @hide
+     */
+    public interface CancelListener {
+        /**
+         * Called when a Pending Intent is cancelled.
+         *
+         * @param intent The intent that was cancelled.
+         */
+        void onCancelled(PendingIntent intent);
+    }
 }
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index 46566e7..21d6762 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -495,7 +495,15 @@
      * @hide
      */
     public boolean tasksAreFloating() {
-        return mWindowingMode == WINDOWING_MODE_FREEFORM || mWindowingMode == WINDOWING_MODE_PINNED;
+        return isFloating(mWindowingMode);
+    }
+
+    /**
+     * Returns true if the windowingMode represents a floating window.
+     * @hide
+     */
+    public static boolean isFloating(int windowingMode) {
+        return windowingMode == WINDOWING_MODE_FREEFORM || windowingMode == WINDOWING_MODE_PINNED;
     }
 
     /**
diff --git a/core/java/android/app/admin/SystemUpdatePolicy.java b/core/java/android/app/admin/SystemUpdatePolicy.java
index 20eef6c..2a451ff 100644
--- a/core/java/android/app/admin/SystemUpdatePolicy.java
+++ b/core/java/android/app/admin/SystemUpdatePolicy.java
@@ -48,7 +48,37 @@
 import java.util.stream.Collectors;
 
 /**
- * A class that represents a local system update policy set by the device owner.
+ * Determines when over-the-air system updates are installed on a device. Only a device policy
+ * controller (DPC) running in device owner mode can set an update policy for the device—by calling
+ * the {@code DevicePolicyManager} method
+ * {@link DevicePolicyManager#setSystemUpdatePolicy setSystemUpdatePolicy()}. An update
+ * policy affects the pending system update (if there is one) and any future updates for the device.
+ *
+ * <p>If a policy is set on a device, the system doesn't notify the user about updates.</p>
+ * <h3>Example</h3>
+ *
+ * <p>The example below shows how a DPC might set a maintenance window for system updates:</p>
+ * <pre><code>
+ * private final MAINTENANCE_WINDOW_START = 1380; // 11pm
+ * private final MAINTENANCE_WINDOW_END = 120; // 2am
+ *
+ * // ...
+ *
+ * // Create the system update policy
+ * SystemUpdatePolicy policy = SystemUpdatePolicy.createWindowedInstallPolicy(
+ *     MAINTENANCE_WINDOW_START, MAINTENANCE_WINDOW_END);
+ *
+ * // Get a DevicePolicyManager instance to set the policy on the device
+ * DevicePolicyManager dpm =
+ *     (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ * ComponentName adminComponent = getComponentName(context);
+ * dpm.setSystemUpdatePolicy(adminComponent, policy);
+ * </code></pre>
+ *
+ * <h3>Developer guide</h3>
+ * To learn more about managing system updates, read
+ * <a href="{@docRoot}/work/dpc/security.html#control_remote_software_updates">Control remote
+ * software updates</a>.
  *
  * @see DevicePolicyManager#setSystemUpdatePolicy
  * @see DevicePolicyManager#getSystemUpdatePolicy
@@ -71,44 +101,37 @@
     private static final int TYPE_UNKNOWN = -1;
 
     /**
-     * Install system update automatically as soon as one is available.
+     * Installs system updates (without user interaction) as soon as they become available. Setting
+     * this policy type immediately installs any pending updates that might be postponed or waiting
+     * for a maintenance window.
      */
     public static final int TYPE_INSTALL_AUTOMATIC = 1;
 
     /**
-     * Install system update automatically within a daily maintenance window. An update can be
-     * delayed for a maximum of 30 days, after which the policy will no longer be effective and the
-     * system will revert back to its normal behavior as if no policy were set.
+     * Installs system updates (without user interaction) during a daily maintenance window. Set the
+     * start and end of the daily maintenance window, as minutes of the day, when creating a new
+     * {@code TYPE_INSTALL_WINDOWED} policy. See
+     * {@link #createWindowedInstallPolicy createWindowedInstallPolicy()}.
      *
-     * <p>After this policy expires, resetting it to any policy other than
-     * {@link #TYPE_INSTALL_AUTOMATIC} will produce no effect, as the 30-day maximum delay has
-     * already been used up.
-     * The {@link #TYPE_INSTALL_AUTOMATIC} policy will still take effect to install the delayed
-     * system update immediately.
-     *
-     * <p>Re-applying this policy or changing it to {@link #TYPE_POSTPONE} within the 30-day period
-     * will <i>not</i> extend policy expiration.
-     * However, the expiration will be recalculated when a new system update is made available.
+     * <p>No connectivity, not enough disk space, or a low battery are typical reasons Android might
+     * not install a system update in the daily maintenance window. After 30 days trying to install
+     * an update in the maintenance window (regardless of policy changes in this period), the system
+     * prompts the device user to install the update.
      */
     public static final int TYPE_INSTALL_WINDOWED = 2;
 
     /**
-     * Incoming system updates (except for security updates) will be blocked for a maximum of 30
-     * days, after which the policy will no longer be effective and the system will revert back to
-     * its normal behavior as if no policy were set.
+     * Postpones the installation of system updates for 30 days. After the 30-day period has ended,
+     * the system prompts the device user to install the update.
      *
-     * <p><b>Note:</b> security updates (e.g. monthly security patches) may <i>not</i> be affected
-     * by this policy, depending on the policy set by the device manufacturer and carrier.
+     * <p>The system limits each update to one 30-day postponement. The period begins when the
+     * system first postpones the update and setting new {@code TYPE_POSTPONE} policies won’t extend
+     * the period. If, after 30 days the update isn’t installed (through policy changes), the system
+     * prompts the user to install the update.
      *
-     * <p>After this policy expires, resetting it to any policy other than
-     * {@link #TYPE_INSTALL_AUTOMATIC} will produce no effect, as the 30-day maximum delay has
-     * already been used up.
-     * The {@link #TYPE_INSTALL_AUTOMATIC} policy will still take effect to install the delayed
-     * system update immediately.
-     *
-     * <p>Re-applying this policy or changing it to {@link #TYPE_INSTALL_WINDOWED} within the 30-day
-     * period will <i>not</i> extend policy expiration.
-     * However, the expiration will be recalculated when a new system update is made available.
+     * <p><strong>Note</strong>: Device manufacturers or carriers might choose to exempt important
+     * security updates from a postponement policy. Exempted updates notify the device user when
+     * they become available.
      */
     public static final int TYPE_POSTPONE = 3;
 
@@ -303,16 +326,20 @@
      * Create a policy object and set it to: new system update will only be installed automatically
      * when the system clock is inside a daily maintenance window. If the start and end times are
      * the same, the window is considered to include the <i>whole 24 hours</i>. That is, updates can
-     * install at any time. If the given window in invalid, an {@link IllegalArgumentException}
-     * will be thrown. If start time is later than end time, the window is considered spanning
+     * install at any time. If start time is later than end time, the window is considered spanning
      * midnight (i.e. the end time denotes a time on the next day). The maintenance window will last
-     * for 30 days, after which the system will revert back to its normal behavior as if no policy
-     * were set.
+     * for 30 days for any given update, after which the window will no longer be effective and
+     * the pending update will be made available for manual installation as if no system update
+     * policy were set on the device. See {@link #TYPE_INSTALL_WINDOWED} for the details of this
+     * policy's behavior.
      *
      * @param startTime the start of the maintenance window, measured as the number of minutes from
      *            midnight in the device's local time. Must be in the range of [0, 1440).
      * @param endTime the end of the maintenance window, measured as the number of minutes from
      *            midnight in the device's local time. Must be in the range of [0, 1440).
+     * @throws IllegalArgumentException If the {@code startTime} or {@code endTime} isn't in the
+     *            accepted range.
+     * @return The configured policy.
      * @see #TYPE_INSTALL_WINDOWED
      */
     public static SystemUpdatePolicy createWindowedInstallPolicy(int startTime, int endTime) {
@@ -329,8 +356,7 @@
 
     /**
      * Create a policy object and set it to block installation for a maximum period of 30 days.
-     * After expiration the system will revert back to its normal behavior as if no policy were
-     * set.
+     * To learn more about this policy's behavior, see {@link #TYPE_POSTPONE}.
      *
      * <p><b>Note: </b> security updates (e.g. monthly security patches) will <i>not</i> be affected
      * by this policy.
@@ -344,10 +370,9 @@
     }
 
     /**
-     * Returns the type of system update policy.
+     * Returns the type of system update policy, or -1 if no policy has been set.
      *
-     * @return an integer, either one of {@link #TYPE_INSTALL_AUTOMATIC},
-     * {@link #TYPE_INSTALL_WINDOWED} and {@link #TYPE_POSTPONE}, or -1 if no policy has been set.
+     @return The policy type or -1 if the type isn't set.
      */
     @SystemUpdatePolicyType
     public int getPolicyType() {
@@ -423,24 +448,16 @@
      * be blocked and cannot be installed. When the device is outside the freeze periods, the normal
      * policy behavior will apply.
      * <p>
-     * Each freeze period is defined by a starting and finishing date (both inclusive). Since the
-     * freeze period repeats annually, both of these dates are simply represented by integers
-     * counting the number of days since year start, similar to {@link LocalDate#getDayOfYear()}. We
-     * do not consider leap year when handling freeze period so the valid range of the integer is
-     * always [1,365] (see last section for more details on leap year). If the finishing date is
-     * smaller than the starting date, the freeze period is considered to be spanning across
-     * year-end.
-     * <p>
      * Each individual freeze period is allowed to be at most 90 days long, and adjacent freeze
      * periods need to be at least 60 days apart. Also, the list of freeze periods should not
      * contain duplicates or overlap with each other. If any of these conditions is not met, a
      * {@link ValidationFailedException} will be thrown.
      * <p>
-     * Handling of leap year: we do not consider leap year when handling freeze period, in
-     * particular,
+     * Handling of leap year: we ignore leap years in freeze period calculations, in particular,
      * <ul>
-     * <li>When a freeze period is defined by the day of year, February 29th does not count as one
-     * day, so day 59 is February 28th while day 60 is March 1st.</li>
+     * <li>When a freeze period is defined, February 29th is disregarded so even though a freeze
+     * period can be specified to start or end on February 29th, it will be treated as if the period
+     * started or ended on February 28th.</li>
      * <li>When applying freeze period behavior to the device, a system clock of February 29th is
      * treated as if it were February 28th</li>
      * <li>When calculating the number of days of a freeze period or separation between two freeze
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index debc32b..30f340c 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -387,7 +387,7 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.BACKUP)
     public boolean isBackupServiceActive(UserHandle user) {
-        mContext.enforceCallingPermission(android.Manifest.permission.BACKUP,
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "isBackupServiceActive");
         checkServiceBinder();
         if (sService != null) {
diff --git a/core/java/android/app/slice/SliceMetrics.java b/core/java/android/app/slice/SliceMetrics.java
index 20c1390..746beaf 100644
--- a/core/java/android/app/slice/SliceMetrics.java
+++ b/core/java/android/app/slice/SliceMetrics.java
@@ -18,9 +18,11 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.metrics.LogMaker;
 import android.net.Uri;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 
 /**
  * Metrics interface for slices.
@@ -34,24 +36,38 @@
 
     private static final String TAG = "SliceMetrics";
     private MetricsLogger mMetricsLogger;
+    private LogMaker mLogMaker;
 
     /**
      * An object to be used throughout the life of a slice to register events.
      */
     public SliceMetrics(@NonNull Context context, @NonNull Uri uri) {
         mMetricsLogger = new MetricsLogger();
+        mLogMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN);
+        mLogMaker.addTaggedData(MetricsEvent.FIELD_SLICE_AUTHORITY, uri.getAuthority());
+        mLogMaker.addTaggedData(MetricsEvent.FIELD_SLICE_PATH, uri.getPath());
     }
 
     /**
      * To be called whenever the slice becomes visible to the user.
      */
     public void logVisible() {
+        synchronized (mLogMaker)  {
+            mLogMaker.setCategory(MetricsEvent.SLICE)
+                    .setType(MetricsEvent.TYPE_OPEN);
+            mMetricsLogger.write(mLogMaker);
+        }
     }
 
     /**
      * To be called whenever the slice becomes invisible to the user.
      */
     public void logHidden() {
+        synchronized (mLogMaker)  {
+            mLogMaker.setCategory(MetricsEvent.SLICE)
+                    .setType(MetricsEvent.TYPE_CLOSE);
+            mMetricsLogger.write(mLogMaker);
+        }
     }
 
     /**
@@ -68,5 +84,12 @@
      * @param subSlice The URI of the sub-slice that is the subject of the interaction.
      */
     public void logTouch(int actionType, @NonNull Uri subSlice) {
+        synchronized (mLogMaker)  {
+            mLogMaker.setCategory(MetricsEvent.SLICE)
+                    .setType(MetricsEvent.TYPE_ACTION)
+                    .addTaggedData(MetricsEvent.FIELD_SUBSLICE_AUTHORITY, subSlice.getAuthority())
+                    .addTaggedData(MetricsEvent.FIELD_SUBSLICE_PATH, subSlice.getPath());
+            mMetricsLogger.write(mLogMaker);
+        }
     }
 }
diff --git a/core/java/android/app/usage/EventList.java b/core/java/android/app/usage/EventList.java
new file mode 100644
index 0000000..aaae57e5
--- /dev/null
+++ b/core/java/android/app/usage/EventList.java
@@ -0,0 +1,106 @@
+/*
+ * 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 android.app.usage;
+
+import java.util.ArrayList;
+
+/**
+ * A container to keep {@link UsageEvents.Event usage events} in non-descending order of their
+ * {@link UsageEvents.Event#mTimeStamp timestamps}.
+ *
+ * @hide
+ */
+public class EventList {
+
+    private final ArrayList<UsageEvents.Event> mEvents;
+
+    /**
+     * Create a new event list with default capacity
+     */
+    public EventList() {
+        mEvents = new ArrayList<>();
+    }
+
+    /**
+     * Returns the size of the list
+     * @return the number of events in the list
+     */
+    public int size() {
+        return mEvents.size();
+    }
+
+    /**
+     * Removes all events from the list
+     */
+    public void clear() {
+        mEvents.clear();
+    }
+
+    /**
+     * Returns the {@link UsageEvents.Event event} at the specified position in this list.
+     * @param index the index of the event to return, such that {@code 0 <= index < size()}
+     * @return The {@link UsageEvents.Event event} at position {@code index}
+     */
+    public UsageEvents.Event get(int index) {
+        return mEvents.get(index);
+    }
+
+    /**
+     * Inserts the given {@link UsageEvents.Event event} into the list while keeping the list sorted
+     * based on the event {@link UsageEvents.Event#mTimeStamp timestamps}.
+     *
+     * @param event The event to insert
+     */
+    public void insert(UsageEvents.Event event) {
+        final int size = mEvents.size();
+        // fast case: just append if this is the latest event
+        if (size == 0 || event.mTimeStamp >= mEvents.get(size - 1).mTimeStamp) {
+            mEvents.add(event);
+            return;
+        }
+        // To minimize number of elements being shifted, insert at the first occurrence of the next
+        // greatest timestamp in the list.
+        final int insertIndex = firstIndexOnOrAfter(event.mTimeStamp + 1);
+        mEvents.add(insertIndex, event);
+    }
+
+    /**
+     * Finds the index of the first event whose timestamp is greater than or equal to the given
+     * timestamp.
+     *
+     * @param timeStamp The timestamp for which to search the list.
+     * @return The smallest {@code index} for which {@code (get(index).mTimeStamp >= timeStamp)} is
+     * {@code true}, or {@link #size() size} if no such {@code index} exists.
+     */
+    public int firstIndexOnOrAfter(long timeStamp) {
+        final int size = mEvents.size();
+        int result = size;
+        int lo = 0;
+        int hi = size - 1;
+        while (lo <= hi) {
+            final int mid = (lo + hi) >>> 1;
+            final long midTimeStamp = mEvents.get(mid).mTimeStamp;
+            if (midTimeStamp >= timeStamp) {
+                hi = mid - 1;
+                result = mid;
+            } else {
+                lo = mid + 1;
+            }
+        }
+        return result;
+    }
+}
diff --git a/core/java/android/app/usage/TimeSparseArray.java b/core/java/android/app/usage/TimeSparseArray.java
index 4ec0e9e..2bd6b24 100644
--- a/core/java/android/app/usage/TimeSparseArray.java
+++ b/core/java/android/app/usage/TimeSparseArray.java
@@ -27,14 +27,12 @@
 public class TimeSparseArray<E> extends LongSparseArray<E> {
     private static final String TAG = TimeSparseArray.class.getSimpleName();
 
+    private boolean mWtfReported;
+
     public TimeSparseArray() {
         super();
     }
 
-    public TimeSparseArray(int initialCapacity) {
-        super(initialCapacity);
-    }
-
     /**
      * Finds the index of the first element whose timestamp is greater or equal to
      * the given time.
@@ -75,22 +73,16 @@
     /**
      * {@inheritDoc}
      *
-     * Overridden to ensure no collisions. The key (time in milliseconds) is incremented till an
-     * empty place is found.
+     * <p> As this container is being used only to keep {@link android.util.AtomicFile files},
+     * there should not be any collisions. Reporting a {@link Slog#wtf(String, String)} in case that
+     * happens, as that will lead to one whole file being dropped.
      */
     @Override
     public void put(long key, E value) {
-        final long origKey = key;
-        int keyIndex = indexOfKey(key);
-        if (keyIndex >= 0) {
-            final long sz = size();
-            while (keyIndex < sz && keyAt(keyIndex) == key) {
-                key++;
-                keyIndex++;
-            }
-            if (key >= origKey + 100) {
-                Slog.w(TAG, "Value " + value + " supposed to be inserted at " + origKey
-                        + " displaced to " + key);
+        if (indexOfKey(key) >= 0) {
+            if (!mWtfReported) {
+                Slog.wtf(TAG, "Overwriting value " + get(key) + " by " + value);
+                mWtfReported = true;
             }
         }
         super.put(key, value);
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 1b6b5a0..1b9e27c 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -394,6 +394,58 @@
     public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23;
 
     /**
+     * Device only has a display.
+     *
+     * @hide
+     */
+    public static final int IO_CAPABILITY_OUT = 0;
+
+    /**
+     * Device has a display and the ability to input Yes/No.
+     *
+     * @hide
+     */
+    public static final int IO_CAPABILITY_IO = 1;
+
+    /**
+     * Device only has a keyboard for entry but no display.
+     *
+     * @hide
+     */
+    public static final int IO_CAPABILITY_IN = 2;
+
+    /**
+     * Device has no Input or Output capability.
+     *
+     * @hide
+     */
+    public static final int IO_CAPABILITY_NONE = 3;
+
+    /**
+     * Device has a display and a full keyboard.
+     *
+     * @hide
+     */
+    public static final int IO_CAPABILITY_KBDISP = 4;
+
+    /**
+     * Maximum range value for Input/Output capabilities.
+     *
+     * <p>This should be updated when adding a new Input/Output capability. Other code
+     * like validation depends on this being accurate.
+     *
+     * @hide
+     */
+    public static final int IO_CAPABILITY_MAX = 5;
+
+    /**
+     * The Input/Output capability of the device is unknown.
+     *
+     * @hide
+     */
+    public static final int IO_CAPABILITY_UNKNOWN = 255;
+
+    /**
      * Broadcast Action: The local Bluetooth adapter has started the remote
      * device discovery process.
      * <p>This usually involves an inquiry scan of about 12 seconds, followed
@@ -1225,6 +1277,106 @@
     }
 
     /**
+     * Returns the Input/Output capability of the device for classic Bluetooth.
+     *
+     * @return Input/Output capability of the device. One of {@link #IO_CAPABILITY_OUT},
+     *         {@link #IO_CAPABILITY_IO}, {@link #IO_CAPABILITY_IN}, {@link #IO_CAPABILITY_NONE},
+     *         {@link #IO_CAPABILITY_KBDISP} or {@link #IO_CAPABILITY_UNKNOWN}.
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    public int getIoCapability() {
+        if (getState() != STATE_ON) return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
+        try {
+            mServiceLock.readLock().lock();
+            if (mService != null) return mService.getIoCapability();
+        } catch (RemoteException e) {
+            Log.e(TAG, e.getMessage(), e);
+        } finally {
+            mServiceLock.readLock().unlock();
+        }
+        return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
+    }
+
+    /**
+     * Sets the Input/Output capability of the device for classic Bluetooth.
+     *
+     * <p>Changing the Input/Output capability of a device only takes effect on restarting the
+     * Bluetooth stack. You would need to restart the stack using {@link BluetoothAdapter#disable()}
+     * and {@link BluetoothAdapter#enable()} to see the changes.
+     *
+     * @param capability Input/Output capability of the device. One of {@link #IO_CAPABILITY_OUT},
+     *                   {@link #IO_CAPABILITY_IO}, {@link #IO_CAPABILITY_IN},
+     *                   {@link #IO_CAPABILITY_NONE} or {@link #IO_CAPABILITY_KBDISP}.
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    public boolean setIoCapability(int capability) {
+        if (getState() != STATE_ON) return false;
+        try {
+            mServiceLock.readLock().lock();
+            if (mService != null) return mService.setIoCapability(capability);
+        } catch (RemoteException e) {
+            Log.e(TAG, e.getMessage(), e);
+        } finally {
+            mServiceLock.readLock().unlock();
+        }
+        return false;
+    }
+
+    /**
+     * Returns the Input/Output capability of the device for BLE operations.
+     *
+     * @return Input/Output capability of the device. One of {@link #IO_CAPABILITY_OUT},
+     *         {@link #IO_CAPABILITY_IO}, {@link #IO_CAPABILITY_IN}, {@link #IO_CAPABILITY_NONE},
+     *         {@link #IO_CAPABILITY_KBDISP} or {@link #IO_CAPABILITY_UNKNOWN}.
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    public int getLeIoCapability() {
+        if (getState() != STATE_ON) return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
+        try {
+            mServiceLock.readLock().lock();
+            if (mService != null) return mService.getLeIoCapability();
+        } catch (RemoteException e) {
+            Log.e(TAG, e.getMessage(), e);
+        } finally {
+            mServiceLock.readLock().unlock();
+        }
+        return BluetoothAdapter.IO_CAPABILITY_UNKNOWN;
+    }
+
+    /**
+     * Sets the Input/Output capability of the device for BLE operations.
+     *
+     * <p>Changing the Input/Output capability of a device only takes effect on restarting the
+     * Bluetooth stack. You would need to restart the stack using {@link BluetoothAdapter#disable()}
+     * and {@link BluetoothAdapter#enable()} to see the changes.
+     *
+     * @param capability Input/Output capability of the device. One of {@link #IO_CAPABILITY_OUT},
+     *                   {@link #IO_CAPABILITY_IO}, {@link #IO_CAPABILITY_IN},
+     *                   {@link #IO_CAPABILITY_NONE} or {@link #IO_CAPABILITY_KBDISP}.
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+    public boolean setLeIoCapability(int capability) {
+        if (getState() != STATE_ON) return false;
+        try {
+            mServiceLock.readLock().lock();
+            if (mService != null) return mService.setLeIoCapability(capability);
+        } catch (RemoteException e) {
+            Log.e(TAG, e.getMessage(), e);
+        } finally {
+            mServiceLock.readLock().unlock();
+        }
+        return false;
+    }
+
+    /**
      * Get the current Bluetooth scan mode of the local Bluetooth adapter.
      * <p>The Bluetooth scan mode determines if the local adapter is
      * connectable and/or discoverable from remote Bluetooth devices.
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index ac21395..7a6b72e 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -848,7 +848,11 @@
             return null;
         }
         try {
-            return service.getRemoteName(this);
+            String name = service.getRemoteName(this);
+            if (name != null) {
+                return name.replaceAll("[\\t\\n\\r]+", " ");
+            }
+            return null;
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
         }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index ede7ee4..64998a3 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -729,6 +729,7 @@
      * cases where system components are loaded into other app processes, in which
      * case this will be the name of the primary package in that process (so that app
      * ops uid verification will work with the name). */
+    @TestApi
     public abstract String getOpPackageName();
 
     /** Return the full application info for this context's package. */
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 206ed71..dec2cd4 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3659,6 +3659,10 @@
      * <p class="note">This is a protected intent that can only be sent by the system.
      * @hide
      * @removed
+     * @deprecated Use {@link android.provider.Telephony.ServiceStateTable} and the helper
+     * functions {@code ServiceStateTable.getUriForSubscriptionIdAndField} and
+     * {@code ServiceStateTable.getUriForSubscriptionId} to subscribe to changes to the ServiceState
+     * for a given subscription id and field with a ContentObserver or using JobScheduler.
      */
     @Deprecated
     @SystemApi
@@ -3674,6 +3678,7 @@
      * @see android.telephony.ServiceState#STATE_POWER_OFF
      * @hide
      * @removed
+     * @deprecated Use {@link android.provider.Telephony.ServiceStateTable#VOICE_REG_STATE}.
      */
     @Deprecated
     @SystemApi
@@ -3687,6 +3692,7 @@
      * @see android.telephony.ServiceState#STATE_POWER_OFF
      * @hide
      * @removed
+     * @deprecated Use {@link android.provider.Telephony.ServiceStateTable#DATA_REG_STATE}.
      */
     @Deprecated
     @SystemApi
@@ -3697,6 +3703,7 @@
      * type.
      * @hide
      * @removed
+     * @deprecated Use {@link android.provider.Telephony.ServiceStateTable#VOICE_ROAMING_TYPE}.
      */
     @Deprecated
     @SystemApi
@@ -3707,6 +3714,7 @@
      * type.
      * @hide
      * @removed
+     * @deprecated Use {@link android.provider.Telephony.ServiceStateTable#DATA_ROAMING_TYPE}.
      */
     @Deprecated
     @SystemApi
@@ -3718,6 +3726,8 @@
      * {@code null} if the operator name is not known or unregistered.
      * @hide
      * @removed
+     * @deprecated Use
+     * {@link android.provider.Telephony.ServiceStateTable#VOICE_OPERATOR_ALPHA_LONG}.
      */
     @Deprecated
     @SystemApi
@@ -3729,6 +3739,8 @@
      * {@code null} if the operator name is not known or unregistered.
      * @hide
      * @removed
+     * @deprecated Use
+     * {@link android.provider.Telephony.ServiceStateTable#VOICE_OPERATOR_ALPHA_SHORT}.
      */
     @Deprecated
     @SystemApi
@@ -3740,6 +3752,7 @@
      * network.
      * @hide
      * @removed
+     * @deprecated Use {@link android.provider.Telephony.ServiceStateTable#VOICE_OPERATOR_NUMERIC}.
      */
     @Deprecated
     @SystemApi
@@ -3751,6 +3764,8 @@
      * {@code null} if the operator name is not known or unregistered.
      * @hide
      * @removed
+     * @deprecated Use
+     * {@link android.provider.Telephony.ServiceStateTable#DATA_OPERATOR_ALPHA_LONG}.
      */
     @Deprecated
     @SystemApi
@@ -3762,6 +3777,8 @@
      * {@code null} if the operator name is not known or unregistered.
      * @hide
      * @removed
+     * @deprecated Use
+     * {@link android.provider.Telephony.ServiceStateTable#DATA_OPERATOR_ALPHA_SHORT}.
      */
     @Deprecated
     @SystemApi
@@ -3773,6 +3790,7 @@
      * data operator.
      * @hide
      * @removed
+     * @deprecated Use {@link android.provider.Telephony.ServiceStateTable#DATA_OPERATOR_NUMERIC}.
      */
     @Deprecated
     @SystemApi
@@ -3784,6 +3802,8 @@
      * Will be {@code true} if manual mode, {@code false} if automatic mode.
      * @hide
      * @removed
+     * @deprecated Use
+     * {@link android.provider.Telephony.ServiceStateTable#IS_MANUAL_NETWORK_SELECTION}.
      */
     @Deprecated
     @SystemApi
@@ -3794,6 +3814,8 @@
      * radio technology.
      * @hide
      * @removed
+     * @deprecated Use
+     * {@link android.provider.Telephony.ServiceStateTable#RIL_VOICE_RADIO_TECHNOLOGY}.
      */
     @Deprecated
     @SystemApi
@@ -3804,6 +3826,8 @@
      * radio technology.
      * @hide
      * @removed
+     * @deprecated Use
+     * {@link android.provider.Telephony.ServiceStateTable#RIL_DATA_RADIO_TECHNOLOGY}.
      */
     @Deprecated
     @SystemApi
@@ -3815,6 +3839,7 @@
      * Will be {@code true} if support, {@code false} otherwise.
      * @hide
      * @removed
+     * @deprecated Use {@link android.provider.Telephony.ServiceStateTable#CSS_INDICATOR}.
      */
     @Deprecated
     @SystemApi
@@ -3825,6 +3850,7 @@
      * id. {@code Integer.MAX_VALUE} if unknown.
      * @hide
      * @removed
+     * @deprecated Use {@link android.provider.Telephony.ServiceStateTable#NETWORK_ID}.
      */
     @Deprecated
     @SystemApi
@@ -3835,6 +3861,7 @@
      * {@code Integer.MAX_VALUE} if unknown.
      * @hide
      * @removed
+     * @deprecated Use {@link android.provider.Telephony.ServiceStateTable#SYSTEM_ID}.
      */
     @Deprecated
     @SystemApi
@@ -3845,6 +3872,7 @@
      * indicator if registered on a CDMA or EVDO system or {@code -1} if not.
      * @hide
      * @removed
+     * @deprecated Use {@link android.provider.Telephony.ServiceStateTable#CDMA_ROAMING_INDICATOR}.
      */
     @Deprecated
     @SystemApi
@@ -3855,6 +3883,8 @@
      * indicator from the PRL if registered on a CDMA or EVDO system {@code -1} if not.
      * @hide
      * @removed
+     * @deprecated Use
+     * {@link android.provider.Telephony.ServiceStateTable#CDMA_DEFAULT_ROAMING_INDICATOR}.
      */
     @Deprecated
     @SystemApi
@@ -3866,6 +3896,7 @@
      * {@code true} if in emergency only mode, {@code false} otherwise.
      * @hide
      * @removed
+     * @deprecated Use {@link android.provider.Telephony.ServiceStateTable#IS_EMERGENCY_ONLY}.
      */
     @Deprecated
     @SystemApi
@@ -3877,6 +3908,8 @@
      * {@code true} if registration indicates roaming, {@code false} otherwise
      * @hide
      * @removed
+     * @deprecated Use
+     * {@link android.provider.Telephony.ServiceStateTable#IS_DATA_ROAMING_FROM_REGISTRATION}.
      */
     @Deprecated
     @SystemApi
@@ -3889,6 +3922,8 @@
      * {@code true} if carrier aggregation is in use, {@code false} otherwise.
      * @hide
      * @removed
+     * @deprecated Use
+     * {@link android.provider.Telephony.ServiceStateTable#IS_USING_CARRIER_AGGREGATION}.
      */
     @Deprecated
     @SystemApi
diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl
index ae1c207..ba7710b 100644
--- a/core/java/android/content/pm/ILauncherApps.aidl
+++ b/core/java/android/content/pm/ILauncherApps.aidl
@@ -16,6 +16,7 @@
 
 package android.content.pm;
 
+import android.app.IApplicationThread;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentSender;
@@ -42,10 +43,10 @@
             String callingPackage, String packageName, in UserHandle user);
     ActivityInfo resolveActivity(
             String callingPackage, in ComponentName component, in UserHandle user);
-    void startActivityAsUser(String callingPackage,
+    void startActivityAsUser(in IApplicationThread caller, String callingPackage,
             in ComponentName component, in Rect sourceBounds,
             in Bundle opts, in UserHandle user);
-    void showAppDetailsAsUser(
+    void showAppDetailsAsUser(in IApplicationThread caller,
             String callingPackage, in ComponentName component, in Rect sourceBounds,
             in Bundle opts, in UserHandle user);
     boolean isPackageEnabled(String callingPackage, String packageName, in UserHandle user);
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 8717601..fa423e2 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -548,7 +548,8 @@
             Log.i(TAG, "StartMainActivity " + component + " " + user.getIdentifier());
         }
         try {
-            mService.startActivityAsUser(mContext.getPackageName(),
+            mService.startActivityAsUser(mContext.getIApplicationThread(),
+                    mContext.getPackageName(),
                     component, sourceBounds, opts, user);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
@@ -568,7 +569,8 @@
             Rect sourceBounds, Bundle opts) {
         logErrorForInvalidProfileAccess(user);
         try {
-            mService.showAppDetailsAsUser(mContext.getPackageName(),
+            mService.showAppDetailsAsUser(mContext.getIApplicationThread(),
+                    mContext.getPackageName(),
                     component, sourceBounds, opts, user);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
index a05a8ec..83a0228 100644
--- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
+++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
@@ -529,14 +529,32 @@
     private boolean swapBuffers(EGLSurface surface)
             throws LegacyExceptionUtils.BufferQueueAbandonedException {
         boolean result = EGL14.eglSwapBuffers(mEGLDisplay, surface);
+
         int error = EGL14.eglGetError();
-        if (error == EGL14.EGL_BAD_SURFACE) {
-            throw new LegacyExceptionUtils.BufferQueueAbandonedException();
-        } else if (error != EGL14.EGL_SUCCESS) {
-            throw new IllegalStateException("swapBuffers: EGL error: 0x" +
-                    Integer.toHexString(error));
+        switch (error) {
+            case EGL14.EGL_SUCCESS:
+                return result;
+
+            // Check for an abandoned buffer queue, or other error conditions out
+            // of the user's control.
+            //
+            // From the EGL 1.4 spec (2013-12-04), Section 3.9.4 Posting Errors:
+            //
+            //   If eglSwapBuffers is called and the native window associated with
+            //   surface is no longer valid, an EGL_BAD_NATIVE_WINDOW error is
+            //   generated.
+            //
+            // We also interpret EGL_BAD_SURFACE as indicating an abandoned
+            // surface, even though the EGL spec does not document it as such, for
+            // backwards compatibility with older versions of this file.
+            case EGL14.EGL_BAD_NATIVE_WINDOW:
+            case EGL14.EGL_BAD_SURFACE:
+                throw new LegacyExceptionUtils.BufferQueueAbandonedException();
+
+            default:
+                throw new IllegalStateException(
+                        "swapBuffers: EGL error: 0x" + Integer.toHexString(error));
         }
-        return result;
     }
 
     private void checkEglError(String msg) {
diff --git a/core/java/android/hardware/radio/RadioMetadata.java b/core/java/android/hardware/radio/RadioMetadata.java
index 6e51060..baa7a50 100644
--- a/core/java/android/hardware/radio/RadioMetadata.java
+++ b/core/java/android/hardware/radio/RadioMetadata.java
@@ -269,6 +269,29 @@
         mBundle = in.readBundle();
     }
 
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("RadioMetadata[");
+
+        final String removePrefix = "android.hardware.radio.metadata";
+
+        boolean first = true;
+        for (String key : mBundle.keySet()) {
+            if (first) first = false;
+            else sb.append(", ");
+
+            String keyDisp = key;
+            if (key.startsWith(removePrefix)) keyDisp = key.substring(removePrefix.length());
+
+            sb.append(keyDisp);
+            sb.append('=');
+            sb.append(mBundle.get(key));
+        }
+
+        sb.append("]");
+        return sb.toString();
+    }
+
     /**
      * Returns {@code true} if the given key is contained in the meta data
      *
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
index 8732375..1145d5b 100644
--- a/core/java/android/net/IpSecManager.java
+++ b/core/java/android/net/IpSecManager.java
@@ -27,6 +27,9 @@
 import android.os.Binder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.system.ErrnoException;
+import android.system.OsConstants;
 import android.util.AndroidException;
 import android.util.Log;
 
@@ -173,11 +176,16 @@
         public void close() {
             try {
                 mService.releaseSecurityParameterIndex(mResourceId);
-                mResourceId = INVALID_RESOURCE_ID;
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
+            } catch (Exception e) {
+                // On close we swallow all random exceptions since failure to close is not
+                // actionable by the user.
+                Log.e(TAG, "Failed to close " + this + ", Exception=" + e);
+            } finally {
+                mResourceId = INVALID_RESOURCE_ID;
+                mCloseGuard.close();
             }
-            mCloseGuard.close();
         }
 
         /** Check that the SPI was closed properly. */
@@ -228,7 +236,6 @@
                     throw new RuntimeException(
                             "Invalid Resource ID returned by IpSecService: " + status);
                 }
-
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -240,6 +247,17 @@
         public int getResourceId() {
             return mResourceId;
         }
+
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                .append("SecurityParameterIndex{spi=")
+                .append(mSpi)
+                .append(",resourceId=")
+                .append(mResourceId)
+                .append("}")
+                .toString();
+        }
     }
 
     /**
@@ -262,7 +280,11 @@
                     mService,
                     destinationAddress,
                     IpSecManager.INVALID_SECURITY_PARAMETER_INDEX);
+        } catch (ServiceSpecificException e) {
+            throw rethrowUncheckedExceptionFromServiceSpecificException(e);
         } catch (SpiUnavailableException unlikely) {
+            // Because this function allocates a totally random SPI, it really shouldn't ever
+            // fail to allocate an SPI; we simply need this because the exception is checked.
             throw new ResourceUnavailableException("No SPIs available");
         }
     }
@@ -275,8 +297,8 @@
      *
      * @param destinationAddress the destination address for traffic bearing the requested SPI.
      *     For inbound traffic, the destination should be an address currently assigned on-device.
-     * @param requestedSpi the requested SPI, or '0' to allocate a random SPI. The range 1-255 is
-     *     reserved and may not be used. See RFC 4303 Section 2.1.
+     * @param requestedSpi the requested SPI. The range 1-255 is reserved and may not be used. See
+     *     RFC 4303 Section 2.1.
      * @return the reserved SecurityParameterIndex
      * @throws {@link #ResourceUnavailableException} indicating that too many SPIs are
      *     currently allocated for this user
@@ -290,7 +312,11 @@
         if (requestedSpi == IpSecManager.INVALID_SECURITY_PARAMETER_INDEX) {
             throw new IllegalArgumentException("Requested SPI must be a valid (non-zero) SPI");
         }
-        return new SecurityParameterIndex(mService, destinationAddress, requestedSpi);
+        try {
+            return new SecurityParameterIndex(mService, destinationAddress, requestedSpi);
+        } catch (ServiceSpecificException e) {
+            throw rethrowUncheckedExceptionFromServiceSpecificException(e);
+        }
     }
 
     /**
@@ -425,6 +451,8 @@
         // constructor takes control and closes the user's FD when we exit the method.
         try (ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(socket)) {
             mService.applyTransportModeTransform(pfd, direction, transform.getResourceId());
+        } catch (ServiceSpecificException e) {
+            throw rethrowCheckedExceptionFromServiceSpecificException(e);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -483,6 +511,8 @@
     public void removeTransportModeTransforms(@NonNull FileDescriptor socket) throws IOException {
         try (ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(socket)) {
             mService.removeTransportModeTransforms(pfd);
+        } catch (ServiceSpecificException e) {
+            throw rethrowCheckedExceptionFromServiceSpecificException(e);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -576,6 +606,13 @@
                 mResourceId = INVALID_RESOURCE_ID;
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
+            } catch (Exception e) {
+                // On close we swallow all random exceptions since failure to close is not
+                // actionable by the user.
+                Log.e(TAG, "Failed to close " + this + ", Exception=" + e);
+            } finally {
+                mResourceId = INVALID_RESOURCE_ID;
+                mCloseGuard.close();
             }
 
             try {
@@ -584,7 +621,6 @@
                 Log.e(TAG, "Failed to close UDP Encapsulation Socket with Port= " + mPort);
                 throw e;
             }
-            mCloseGuard.close();
         }
 
         /** Check that the socket was closed properly. */
@@ -601,6 +637,17 @@
         public int getResourceId() {
             return mResourceId;
         }
+
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                .append("UdpEncapsulationSocket{port=")
+                .append(mPort)
+                .append(",resourceId=")
+                .append(mResourceId)
+                .append("}")
+                .toString();
+        }
     };
 
     /**
@@ -628,7 +675,11 @@
         if (port == 0) {
             throw new IllegalArgumentException("Specified port must be a valid port number!");
         }
-        return new UdpEncapsulationSocket(mService, port);
+        try {
+            return new UdpEncapsulationSocket(mService, port);
+        } catch (ServiceSpecificException e) {
+            throw rethrowCheckedExceptionFromServiceSpecificException(e);
+        }
     }
 
     /**
@@ -651,7 +702,11 @@
     @NonNull
     public UdpEncapsulationSocket openUdpEncapsulationSocket()
             throws IOException, ResourceUnavailableException {
-        return new UdpEncapsulationSocket(mService, 0);
+        try {
+            return new UdpEncapsulationSocket(mService, 0);
+        } catch (ServiceSpecificException e) {
+            throw rethrowCheckedExceptionFromServiceSpecificException(e);
+        }
     }
 
     /**
@@ -699,6 +754,8 @@
             try {
                 mService.addAddressToTunnelInterface(
                         mResourceId, new LinkAddress(address, prefixLen), mOpPackageName);
+            } catch (ServiceSpecificException e) {
+                throw rethrowCheckedExceptionFromServiceSpecificException(e);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -719,6 +776,8 @@
             try {
                 mService.removeAddressFromTunnelInterface(
                         mResourceId, new LinkAddress(address, prefixLen), mOpPackageName);
+            } catch (ServiceSpecificException e) {
+                throw rethrowCheckedExceptionFromServiceSpecificException(e);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -771,11 +830,16 @@
         public void close() {
             try {
                 mService.deleteTunnelInterface(mResourceId, mOpPackageName);
-                mResourceId = INVALID_RESOURCE_ID;
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
+            } catch (Exception e) {
+                // On close we swallow all random exceptions since failure to close is not
+                // actionable by the user.
+                Log.e(TAG, "Failed to close " + this + ", Exception=" + e);
+            } finally {
+                mResourceId = INVALID_RESOURCE_ID;
+                mCloseGuard.close();
             }
-            mCloseGuard.close();
         }
 
         /** Check that the Interface was closed properly. */
@@ -792,6 +856,17 @@
         public int getResourceId() {
             return mResourceId;
         }
+
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                .append("IpSecTunnelInterface{ifname=")
+                .append(mInterfaceName)
+                .append(",resourceId=")
+                .append(mResourceId)
+                .append("}")
+                .toString();
+        }
     }
 
     /**
@@ -815,8 +890,12 @@
     public IpSecTunnelInterface createIpSecTunnelInterface(@NonNull InetAddress localAddress,
             @NonNull InetAddress remoteAddress, @NonNull Network underlyingNetwork)
             throws ResourceUnavailableException, IOException {
-        return new IpSecTunnelInterface(
-                mContext, mService, localAddress, remoteAddress, underlyingNetwork);
+        try {
+            return new IpSecTunnelInterface(
+                    mContext, mService, localAddress, remoteAddress, underlyingNetwork);
+        } catch (ServiceSpecificException e) {
+            throw rethrowCheckedExceptionFromServiceSpecificException(e);
+        }
     }
 
     /**
@@ -844,6 +923,8 @@
             mService.applyTunnelModeTransform(
                     tunnel.getResourceId(), direction,
                     transform.getResourceId(), mContext.getOpPackageName());
+        } catch (ServiceSpecificException e) {
+            throw rethrowCheckedExceptionFromServiceSpecificException(e);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -859,4 +940,44 @@
         mContext = ctx;
         mService = checkNotNull(service, "missing service");
     }
+
+    private static void maybeHandleServiceSpecificException(ServiceSpecificException sse) {
+        // OsConstants are late binding, so switch statements can't be used.
+        if (sse.errorCode == OsConstants.EINVAL) {
+            throw new IllegalArgumentException(sse);
+        } else if (sse.errorCode == OsConstants.EAGAIN) {
+            throw new IllegalStateException(sse);
+        } else if (sse.errorCode == OsConstants.EOPNOTSUPP) {
+            throw new UnsupportedOperationException(sse);
+        }
+    }
+
+    /**
+     * Convert an Errno SSE to the correct Unchecked exception type.
+     *
+     * This method never actually returns.
+     */
+    // package
+    static RuntimeException
+            rethrowUncheckedExceptionFromServiceSpecificException(ServiceSpecificException sse) {
+        maybeHandleServiceSpecificException(sse);
+        throw new RuntimeException(sse);
+    }
+
+    /**
+     * Convert an Errno SSE to the correct Checked or Unchecked exception type.
+     *
+     * This method may throw IOException, or it may throw an unchecked exception; it will never
+     * actually return.
+     */
+    // package
+    static IOException rethrowCheckedExceptionFromServiceSpecificException(
+            ServiceSpecificException sse) throws IOException {
+        // First see if this is an unchecked exception of a type we know.
+        // If so, then we prefer the unchecked (specific) type of exception.
+        maybeHandleServiceSpecificException(sse);
+        // If not, then all we can do is provide the SSE in the form of an IOException.
+        throw new ErrnoException(
+                "IpSec encountered errno=" + sse.errorCode, sse.errorCode).rethrowAsIOException();
+    }
 }
diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java
index fb5f46c..23c8aa3 100644
--- a/core/java/android/net/IpSecTransform.java
+++ b/core/java/android/net/IpSecTransform.java
@@ -29,6 +29,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -137,6 +138,8 @@
                 mResourceId = result.resourceId;
                 Log.d(TAG, "Added Transform with Id " + mResourceId);
                 mCloseGuard.open("build");
+            } catch (ServiceSpecificException e) {
+                throw IpSecManager.rethrowUncheckedExceptionFromServiceSpecificException(e);
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
             }
@@ -181,6 +184,10 @@
             stopNattKeepalive();
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
+        } catch (Exception e) {
+            // On close we swallow all random exceptions since failure to close is not
+            // actionable by the user.
+            Log.e(TAG, "Failed to close " + this + ", Exception=" + e);
         } finally {
             mResourceId = INVALID_RESOURCE_ID;
             mCloseGuard.close();
@@ -507,4 +514,13 @@
             mConfig = new IpSecConfig();
         }
     }
+
+    @Override
+    public String toString() {
+        return new StringBuilder()
+            .append("IpSecTransform{resourceId=")
+            .append(mResourceId)
+            .append("}")
+            .toString();
+    }
 }
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index bd4a27c..227a4cb 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -228,7 +228,7 @@
          * @param capability The capability to add to unwanted capability list.
          * @return The builder to facilitate chaining.
          *
-         * @removed
+         * @hide
          */
         public Builder addUnwantedCapability(@NetworkCapabilities.NetCapability int capability) {
             mNetworkCapabilities.addUnwantedCapability(capability);
@@ -436,7 +436,7 @@
     /**
      * @see Builder#addUnwantedCapability(int)
      *
-     * @removed
+     * @hide
      */
     public boolean hasUnwantedCapability(@NetCapability int capability) {
         return networkCapabilities.hasUnwantedCapability(capability);
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index f5a7433..0fef78d 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -40,8 +40,9 @@
     private static final String TAG = "Bundle";
     static final boolean DEBUG = false;
 
-    // Keep in sync with frameworks/native/libs/binder/PersistableBundle.cpp.
-    static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L'
+    // Keep them in sync with frameworks/native/libs/binder/PersistableBundle.cpp.
+    private static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L'
+    private static final int BUNDLE_MAGIC_NATIVE = 0x4C444E44; // 'B' 'N' 'D' 'N'
 
     /**
      * Flag indicating that this Bundle is okay to "defuse." That is, it's okay
@@ -91,6 +92,11 @@
     Parcel mParcelledData = null;
 
     /**
+     * Whether {@link #mParcelledData} was generated by native coed or not.
+     */
+    private boolean mParcelledByNative;
+
+    /**
      * The ClassLoader used when unparcelling data from mParcelledData.
      */
     private ClassLoader mClassLoader;
@@ -223,7 +229,7 @@
         synchronized (this) {
             final Parcel source = mParcelledData;
             if (source != null) {
-                initializeFromParcelLocked(source, /*recycleParcel=*/ true);
+                initializeFromParcelLocked(source, /*recycleParcel=*/ true, mParcelledByNative);
             } else {
                 if (DEBUG) {
                     Log.d(TAG, "unparcel "
@@ -234,7 +240,8 @@
         }
     }
 
-    private void initializeFromParcelLocked(@NonNull Parcel parcelledData, boolean recycleParcel) {
+    private void initializeFromParcelLocked(@NonNull Parcel parcelledData, boolean recycleParcel,
+            boolean parcelledByNative) {
         if (LOG_DEFUSABLE && sShouldDefuse && (mFlags & FLAG_DEFUSABLE) == 0) {
             Slog.wtf(TAG, "Attempting to unparcel a Bundle while in transit; this may "
                     + "clobber all data inside!", new Throwable());
@@ -251,6 +258,7 @@
                 mMap.erase();
             }
             mParcelledData = null;
+            mParcelledByNative = false;
             return;
         }
 
@@ -270,7 +278,15 @@
             map.ensureCapacity(count);
         }
         try {
-            parcelledData.readArrayMapInternal(map, count, mClassLoader);
+            if (parcelledByNative) {
+                // If it was parcelled by native code, then the array map keys aren't sorted
+                // by their hash codes, so use the safe (slow) one.
+                parcelledData.readArrayMapSafelyInternal(map, count, mClassLoader);
+            } else {
+                // If parcelled by Java, we know the contents are sorted properly,
+                // so we can use ArrayMap.append().
+                parcelledData.readArrayMapInternal(map, count, mClassLoader);
+            }
         } catch (BadParcelableException e) {
             if (sShouldDefuse) {
                 Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e);
@@ -284,6 +300,7 @@
                 recycleParcel(parcelledData);
             }
             mParcelledData = null;
+            mParcelledByNative = false;
         }
         if (DEBUG) {
             Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
@@ -403,14 +420,17 @@
             if (from.mParcelledData != null) {
                 if (from.isEmptyParcel()) {
                     mParcelledData = NoImagePreloadHolder.EMPTY_PARCEL;
+                    mParcelledByNative = false;
                 } else {
                     mParcelledData = Parcel.obtain();
                     mParcelledData.appendFrom(from.mParcelledData, 0,
                             from.mParcelledData.dataSize());
                     mParcelledData.setDataPosition(0);
+                    mParcelledByNative = from.mParcelledByNative;
                 }
             } else {
                 mParcelledData = null;
+                mParcelledByNative = false;
             }
 
             if (from.mMap != null) {
@@ -1538,7 +1558,7 @@
                 } else {
                     int length = mParcelledData.dataSize();
                     parcel.writeInt(length);
-                    parcel.writeInt(BUNDLE_MAGIC);
+                    parcel.writeInt(mParcelledByNative ? BUNDLE_MAGIC_NATIVE : BUNDLE_MAGIC);
                     parcel.appendFrom(mParcelledData, 0, length);
                 }
                 return;
@@ -1585,11 +1605,14 @@
         } else if (length == 0) {
             // Empty Bundle or end of data.
             mParcelledData = NoImagePreloadHolder.EMPTY_PARCEL;
+            mParcelledByNative = false;
             return;
         }
 
         final int magic = parcel.readInt();
-        if (magic != BUNDLE_MAGIC) {
+        final boolean isJavaBundle = magic == BUNDLE_MAGIC;
+        final boolean isNativeBundle = magic == BUNDLE_MAGIC_NATIVE;
+        if (!isJavaBundle && !isNativeBundle) {
             throw new IllegalStateException("Bad magic number for Bundle: 0x"
                     + Integer.toHexString(magic));
         }
@@ -1598,7 +1621,7 @@
             // If the parcel has a read-write helper, then we can't lazily-unparcel it, so just
             // unparcel right away.
             synchronized (this) {
-                initializeFromParcelLocked(parcel, /*recycleParcel=*/ false);
+                initializeFromParcelLocked(parcel, /*recycleParcel=*/ false, isNativeBundle);
             }
             return;
         }
@@ -1616,6 +1639,7 @@
         p.setDataPosition(0);
 
         mParcelledData = p;
+        mParcelledByNative = isNativeBundle;
     }
 
     /** {@hide} */
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index 848c596..f17e0f0 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -77,10 +77,18 @@
     private Printer mLogging;
     private long mTraceTag;
 
-    /* If set, the looper will show a warning log if a message dispatch takes longer than time. */
+    /**
+     * If set, the looper will show a warning log if a message dispatch takes longer than this.
+     */
     private long mSlowDispatchThresholdMs;
 
-     /** Initialize the current thread as a looper.
+    /**
+     * If set, the looper will show a warning log if a message delivery (actual delivery time -
+     * post time) takes longer than this.
+     */
+    private long mSlowDeliveryThresholdMs;
+
+    /** Initialize the current thread as a looper.
       * This gives you a chance to create handlers that then reference
       * this looper, before actually starting the loop. Be sure to call
       * {@link #loop()} after calling this method, and end it by calling
@@ -138,6 +146,16 @@
         Binder.clearCallingIdentity();
         final long ident = Binder.clearCallingIdentity();
 
+        // Allow overriding a threshold with a system prop. e.g.
+        // adb shell 'setprop log.looper.1000.main.slow 1 && stop && start'
+        final int thresholdOverride =
+                SystemProperties.getInt("log.looper."
+                        + Process.myUid() + "."
+                        + Thread.currentThread().getName()
+                        + ".slow", 0);
+
+        boolean slowDeliveryDetected = false;
+
         for (;;) {
             Message msg = queue.next(); // might block
             if (msg == null) {
@@ -152,30 +170,50 @@
                         msg.callback + ": " + msg.what);
             }
 
-            final long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;
-
             final long traceTag = me.mTraceTag;
+            long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;
+            long slowDeliveryThresholdMs = me.mSlowDeliveryThresholdMs;
+            if (thresholdOverride > 0) {
+                slowDispatchThresholdMs = thresholdOverride;
+                slowDeliveryThresholdMs = thresholdOverride;
+            }
+            final boolean logSlowDelivery = (slowDeliveryThresholdMs > 0) && (msg.when > 0);
+            final boolean logSlowDispatch = (slowDispatchThresholdMs > 0);
+
+            final boolean needStartTime = logSlowDelivery || logSlowDispatch;
+            final boolean needEndTime = logSlowDispatch;
+
             if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
                 Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
             }
-            final long start = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
-            final long end;
+
+            final long dispatchStart = needStartTime ? SystemClock.uptimeMillis() : 0;
+            final long dispatchEnd;
             try {
                 msg.target.dispatchMessage(msg);
-                end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
+                dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
             } finally {
                 if (traceTag != 0) {
                     Trace.traceEnd(traceTag);
                 }
             }
-            if (slowDispatchThresholdMs > 0) {
-                final long time = end - start;
-                if (time > slowDispatchThresholdMs) {
-                    Slog.w(TAG, "Dispatch took " + time + "ms on "
-                            + Thread.currentThread().getName() + ", h=" +
-                            msg.target + " cb=" + msg.callback + " msg=" + msg.what);
+            if (logSlowDelivery) {
+                if (slowDeliveryDetected) {
+                    if ((dispatchStart - msg.when) <= 10) {
+                        Slog.w(TAG, "Drained");
+                        slowDeliveryDetected = false;
+                    }
+                } else {
+                    if (showSlowLog(slowDeliveryThresholdMs, msg.when, dispatchStart, "delivery",
+                            msg)) {
+                        // Once we write a slow delivery log, suppress until the queue drains.
+                        slowDeliveryDetected = true;
+                    }
                 }
             }
+            if (logSlowDispatch) {
+                showSlowLog(slowDispatchThresholdMs, dispatchStart, dispatchEnd, "dispatch", msg);
+            }
 
             if (logging != null) {
                 logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
@@ -196,6 +234,19 @@
         }
     }
 
+    private static boolean showSlowLog(long threshold, long measureStart, long measureEnd,
+            String what, Message msg) {
+        final long actualTime = measureEnd - measureStart;
+        if (actualTime < threshold) {
+            return false;
+        }
+        // For slow delivery, the current message isn't really important, but log it anyway.
+        Slog.w(TAG, "Slow " + what + " took " + actualTime + "ms "
+                + Thread.currentThread().getName() + " h="
+                + msg.target.getClass().getName() + " c=" + msg.callback + " m=" + msg.what);
+        return true;
+    }
+
     /**
      * Return the Looper object associated with the current thread.  Returns
      * null if the calling thread is not associated with a Looper.
@@ -243,9 +294,13 @@
         mTraceTag = traceTag;
     }
 
-    /** {@hide} */
-    public void setSlowDispatchThresholdMs(long slowDispatchThresholdMs) {
+    /**
+     * Set a thresholds for slow dispatch/delivery log.
+     * {@hide}
+     */
+    public void setSlowLogThresholdMs(long slowDispatchThresholdMs, long slowDeliveryThresholdMs) {
         mSlowDispatchThresholdMs = slowDispatchThresholdMs;
+        mSlowDeliveryThresholdMs = slowDeliveryThresholdMs;
     }
 
     /**
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 5142928..6d76c0b 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -715,7 +715,13 @@
         nativeWriteString(mNativePtr, val);
     }
 
-    /** @hide */
+    /**
+     * Write a boolean value into the parcel at the current dataPosition(),
+     * growing dataCapacity() if needed.
+     *
+     * <p>Note: This method currently delegates to writeInt with a value of 1 or 0
+     * for true or false, respectively, but may change in the future.
+     */
     public final void writeBoolean(boolean val) {
         writeInt(val ? 1 : 0);
     }
@@ -805,6 +811,9 @@
     /**
      * Write a byte value into the parcel at the current dataPosition(),
      * growing dataCapacity() if needed.
+     *
+     * <p>Note: This method currently delegates to writeInt but may change in
+     * the future.
      */
     public final void writeByte(byte val) {
         writeInt(val);
@@ -2007,7 +2016,9 @@
         return nativeReadString(mNativePtr);
     }
 
-    /** @hide */
+    /**
+     * Read a boolean value from the parcel at the current dataPosition().
+     */
     public final boolean readBoolean() {
         return readInt() != 0;
     }
diff --git a/core/java/android/os/ShellCommand.java b/core/java/android/os/ShellCommand.java
index fa05a5e..5228d6d 100644
--- a/core/java/android/os/ShellCommand.java
+++ b/core/java/android/os/ShellCommand.java
@@ -247,7 +247,11 @@
         }
         if (DEBUG) Slog.d(TAG, "Error: Unable to open file: " + path);
         getErrPrintWriter().println("Error: Unable to open file: " + path);
-        getErrPrintWriter().println("Consider using a file under /data/local/tmp/");
+
+        String suggestedPath = "/data/local/tmp/";
+        if (path == null || !path.startsWith(suggestedPath)) {
+            getErrPrintWriter().println("Consider using a file under " + suggestedPath);
+        }
         return null;
     }
 
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index 30451c2..583f060 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -93,6 +93,8 @@
     public static final long TRACE_TAG_VIBRATOR = 1L << 23;
     /** @hide */
     public static final long TRACE_TAG_AIDL = 1L << 24;
+    /** @hide */
+    public static final long TRACE_TAG_NNAPI = 1L << 25;
 
     private static final long TRACE_TAG_NOT_READY = 1L << 63;
     private static final int MAX_SECTION_NAME_LEN = 127;
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 4d4f31d..66ebbdb 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -145,6 +145,7 @@
      * "it's system", because of isolated UIDs. Use {@link #isCore} for that.
      * @hide
      */
+    @TestApi
     public static boolean isApp(int uid) {
         if (uid > 0) {
             final int appId = getAppId(uid);
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 3a2e485..62359ec 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -359,6 +359,26 @@
             return new OneShot(mDuration, newAmplitude);
         }
 
+        /**
+         * Resolve default values into integer amplitude numbers.
+         *
+         * @param defaultAmplitude the default amplitude to apply, must be between 0 and
+         *         MAX_AMPLITUDE
+         * @return A {@link OneShot} effect with same physical meaning but explicitly set amplitude
+         *
+         * @hide
+         */
+        public OneShot resolve(int defaultAmplitude) {
+            if (defaultAmplitude > MAX_AMPLITUDE || defaultAmplitude < 0) {
+                throw new IllegalArgumentException(
+                        "Amplitude is negative or greater than MAX_AMPLITUDE");
+            }
+            if (mAmplitude == DEFAULT_AMPLITUDE) {
+                return new OneShot(mDuration, defaultAmplitude);
+            }
+            return this;
+        }
+
         @Override
         public void validate() {
             if (mAmplitude < -1 || mAmplitude == 0 || mAmplitude > 255) {
@@ -487,6 +507,30 @@
             return new Waveform(mTimings, scaledAmplitudes, mRepeat);
         }
 
+        /**
+         * Resolve default values into integer amplitude numbers.
+         *
+         * @param defaultAmplitude the default amplitude to apply, must be between 0 and
+         *         MAX_AMPLITUDE
+         * @return A {@link Waveform} effect with same physical meaning but explicitly set
+         *         amplitude
+         *
+         * @hide
+         */
+        public Waveform resolve(int defaultAmplitude) {
+            if (defaultAmplitude > MAX_AMPLITUDE || defaultAmplitude < 0) {
+                throw new IllegalArgumentException(
+                        "Amplitude is negative or greater than MAX_AMPLITUDE");
+            }
+            int[] resolvedAmplitudes = Arrays.copyOf(mAmplitudes, mAmplitudes.length);
+            for (int i = 0; i < resolvedAmplitudes.length; i++) {
+                if (resolvedAmplitudes[i] == DEFAULT_AMPLITUDE) {
+                    resolvedAmplitudes[i] = defaultAmplitude;
+                }
+            }
+            return new Waveform(mTimings, resolvedAmplitudes, mRepeat);
+        }
+
         @Override
         public void validate() {
             if (mTimings.length != mAmplitudes.length) {
diff --git a/core/java/android/printservice/recommendation/RecommendationService.java b/core/java/android/printservice/recommendation/RecommendationService.java
index 733629a..968a625 100644
--- a/core/java/android/printservice/recommendation/RecommendationService.java
+++ b/core/java/android/printservice/recommendation/RecommendationService.java
@@ -119,14 +119,16 @@
                     mCallbacks = null;
                     break;
                 case MSG_UPDATE:
-                    // Note that there might be a connection change in progress. In this case the
-                    // message is handled as before the change. This is acceptable as the caller of
-                    // the connection change has not guarantee when the connection change binder
-                    // transaction is actually processed.
-                    try {
-                        mCallbacks.onRecommendationsUpdated((List<RecommendationInfo>) msg.obj);
-                    } catch (RemoteException | NullPointerException e) {
-                        Log.e(LOG_TAG, "Could not update recommended services", e);
+                    if (mCallbacks != null) {
+                        // Note that there might be a connection change in progress. In this case
+                        // the message is handled as before the change. This is acceptable as the
+                        // caller of the connection change has not guarantee when the connection
+                        // change binder transaction is actually processed.
+                        try {
+                            mCallbacks.onRecommendationsUpdated((List<RecommendationInfo>) msg.obj);
+                        } catch (RemoteException | NullPointerException e) {
+                            Log.e(LOG_TAG, "Could not update recommended services", e);
+                        }
                     }
                     break;
             }
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index c94da9a..f7409d0 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -20,6 +20,7 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.app.Activity;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -5050,6 +5051,7 @@
         *
         * @hide
         */
+        @TestApi
         public static final Uri CORP_CONTENT_URI =
                 Uri.withAppendedPath(AUTHORITY_URI, "raw_contact_entities_corp");
 
@@ -6057,6 +6059,7 @@
             *
             * @hide
             */
+            @TestApi
             public static final Uri ENTERPRISE_CONTENT_URI =
                     Uri.withAppendedPath(Data.ENTERPRISE_CONTENT_URI, "phones");
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 9751b7f..f1dcaf9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -86,6 +86,7 @@
 import android.view.textservice.TextServicesManager;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.app.ColorDisplayController;
 import com.android.internal.widget.ILockSettings;
 
 import java.io.IOException;
@@ -1784,6 +1785,12 @@
     public static final int USER_SETUP_PERSONALIZATION_STARTED = 1;
 
     /**
+     * User has snoozed personalization and will complete it later.
+     * @hide
+     */
+    public static final int USER_SETUP_PERSONALIZATION_PAUSED = 2;
+
+    /**
      * User has completed setup personalization.
      * @hide
      */
@@ -1794,6 +1801,7 @@
     @IntDef({
             USER_SETUP_PERSONALIZATION_NOT_STARTED,
             USER_SETUP_PERSONALIZATION_STARTED,
+            USER_SETUP_PERSONALIZATION_PAUSED,
             USER_SETUP_PERSONALIZATION_COMPLETE
     })
     public @interface UserSetupPersonalization {}
@@ -3147,7 +3155,9 @@
         public static final String DISPLAY_COLOR_MODE = "display_color_mode";
 
         private static final Validator DISPLAY_COLOR_MODE_VALIDATOR =
-                new SettingsValidators.InclusiveIntegerRangeValidator(0, 2);
+                new SettingsValidators.InclusiveIntegerRangeValidator(
+                        ColorDisplayController.COLOR_MODE_NATURAL,
+                        ColorDisplayController.COLOR_MODE_AUTOMATIC);
 
         /**
          * The amount of time in milliseconds before the device goes to sleep or begins
@@ -10784,6 +10794,7 @@
          * read_binary_cpu_time          (boolean)
          * proc_state_cpu_times_read_delay_ms (long)
          * external_stats_collection_rate_limit_ms (long)
+         * battery_level_collection_delay_ms (long)
          * </pre>
          *
          * <p>
@@ -10804,16 +10815,29 @@
         public static final String SYNC_MANAGER_CONSTANTS = "sync_manager_constants";
 
         /**
-         * Whether or not App Standby feature is enabled. This controls throttling of apps
-         * based on usage patterns and predictions.
+         * Whether or not App Standby feature is enabled by system. This controls throttling of apps
+         * based on usage patterns and predictions. Platform will turn on this feature if both this
+         * flag and {@link #ADAPTIVE_BATTERY_MANAGEMENT_ENABLED} is on.
          * Type: int (0 for false, 1 for true)
          * Default: 1
          * @hide
+         * @see #ADAPTIVE_BATTERY_MANAGEMENT_ENABLED
          */
         @SystemApi
         public static final String APP_STANDBY_ENABLED = "app_standby_enabled";
 
         /**
+         * Whether or not adaptive battery feature is enabled by user. Platform will turn on this
+         * feature if both this flag and {@link #APP_STANDBY_ENABLED} is on.
+         * Type: int (0 for false, 1 for true)
+         * Default: 1
+         * @hide
+         * @see #APP_STANDBY_ENABLED
+         */
+        public static final String ADAPTIVE_BATTERY_MANAGEMENT_ENABLED =
+                "adaptive_battery_management_enabled";
+
+        /**
          * Whether or not app auto restriction is enabled. When it is enabled, settings app will
          * auto restrict the app if it has bad behavior(e.g. hold wakelock for long time).
          *
diff --git a/core/java/android/security/net/config/WfaCertificateSource.java b/core/java/android/security/net/config/WfaCertificateSource.java
new file mode 100644
index 0000000..f212ef8
--- /dev/null
+++ b/core/java/android/security/net/config/WfaCertificateSource.java
@@ -0,0 +1,42 @@
+/*
+ * 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 android.security.net.config;
+
+import java.io.File;
+
+/**
+ * {@link CertificateSource} based on the system WFA CA store.
+ * @hide
+ */
+public final class WfaCertificateSource extends DirectoryCertificateSource {
+    private static class NoPreloadHolder {
+        private static final WfaCertificateSource INSTANCE = new WfaCertificateSource();
+    }
+
+    private WfaCertificateSource() {
+        super(new File(System.getenv("ANDROID_ROOT") + "/etc/security/cacerts_wfa"));
+    }
+
+    public static WfaCertificateSource getInstance() {
+        return NoPreloadHolder.INSTANCE;
+    }
+
+    @Override
+    protected boolean isCertMarkedAsRemoved(String caFile) {
+        return false;
+    }
+}
diff --git a/core/java/android/security/net/config/XmlConfigSource.java b/core/java/android/security/net/config/XmlConfigSource.java
index 02be403..311a8d2 100644
--- a/core/java/android/security/net/config/XmlConfigSource.java
+++ b/core/java/android/security/net/config/XmlConfigSource.java
@@ -189,6 +189,8 @@
             source = SystemCertificateSource.getInstance();
         } else if ("user".equals(sourceString)) {
             source = UserCertificateSource.getInstance();
+        } else if ("wfa".equals(sourceString)) {
+            source = WfaCertificateSource.getInstance();
         } else {
             throw new ParserException(parser, "Unknown certificates src. "
                     + "Should be one of system|user|@resourceVal");
diff --git a/core/java/android/service/autofill/BatchUpdates.java b/core/java/android/service/autofill/BatchUpdates.java
index 90acc88..2ba0376 100644
--- a/core/java/android/service/autofill/BatchUpdates.java
+++ b/core/java/android/service/autofill/BatchUpdates.java
@@ -82,6 +82,9 @@
          * {@link #transformChild(int, Transformation) transformations} are applied to the children
          * views.
          *
+         * <p>Theme does not work with RemoteViews layout. Avoid hardcoded text color
+         * or background color: Autofill on different platforms may have different themes.
+         *
          * @param updates a {@link RemoteViews} with the updated actions to be applied in the
          * underlying presentation template.
          *
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index ccec483..5211767 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -336,6 +336,9 @@
          * higher, datasets that require authentication can be also be filtered by passing a
          * {@link AutofillValue#forText(CharSequence) text value} as the  {@code value} parameter.
          *
+         * <p>Theme does not work with RemoteViews layout. Avoid hardcoded text color
+         * or background color: Autofill on different platforms may have different themes.
+         *
          * @param id id returned by {@link
          *         android.app.assist.AssistStructure.ViewNode#getAutofillId()}.
          * @param value the value to be autofilled. Pass {@code null} if you do not have the value
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 2bc4b8f..7bf1f83 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -241,6 +241,9 @@
          * immutable by using {@link android.app.PendingIntent#FLAG_IMMUTABLE} as the
          * platform needs to fill in the authentication arguments.
          *
+         * <p>Theme does not work with RemoteViews layout. Avoid hardcoded text color
+         * or background color: Autofill on different platforms may have different themes.
+         *
          * @param authentication Intent to an activity with your authentication flow.
          * @param presentation The presentation to visualize the response.
          * @param ids id of Views that when focused will display the authentication UI.
@@ -449,6 +452,9 @@
          * authentication (as the header could have been set directly in the main presentation in
          * these cases).
          *
+         * <p>Theme does not work with RemoteViews layout. Avoid hardcoded text color
+         * or background color: Autofill on different platforms may have different themes.
+         *
          * @param header a presentation to represent the header. This presentation is not clickable
          * &mdash;calling
          * {@link RemoteViews#setOnClickPendingIntent(int, android.app.PendingIntent)} on it would
@@ -477,6 +483,9 @@
          * authentication (as the footer could have been set directly in the main presentation in
          * these cases).
          *
+         * <p>Theme does not work with RemoteViews layout. Avoid hardcoded text color
+         * or background color: Autofill on different platforms may have different themes.
+         *
          * @param footer a presentation to represent the footer. This presentation is not clickable
          * &mdash;calling
          * {@link RemoteViews#setOnClickPendingIntent(int, android.app.PendingIntent)} on it would
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 309fa4a..510626b 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -16,6 +16,10 @@
 
 package android.service.notification;
 
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
+
 import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.app.NotificationManager;
@@ -68,6 +72,7 @@
     public static final int SOURCE_STAR = 2;
     public static final int MAX_SOURCE = SOURCE_STAR;
     private static final int DEFAULT_SOURCE = SOURCE_CONTACT;
+    private static final int DEFAULT_CALLS_SOURCE = SOURCE_STAR;
 
     public static final String EVENTS_DEFAULT_RULE_ID = "EVENTS_DEFAULT_RULE";
     public static final String EVERY_NIGHT_DEFAULT_RULE_ID = "EVERY_NIGHT_DEFAULT_RULE";
@@ -93,13 +98,10 @@
     private static final boolean DEFAULT_ALLOW_REMINDERS = false;
     private static final boolean DEFAULT_ALLOW_EVENTS = false;
     private static final boolean DEFAULT_ALLOW_REPEAT_CALLERS = false;
-    private static final boolean DEFAULT_ALLOW_SCREEN_OFF = false;
-    private static final boolean DEFAULT_ALLOW_SCREEN_ON = false;
     private static final boolean DEFAULT_CHANNELS_BYPASSING_DND = false;
-    private static final int DEFAULT_SUPPRESSED_VISUAL_EFFECTS =
-            Policy.getAllSuppressedVisualEffects();
+    private static final int DEFAULT_SUPPRESSED_VISUAL_EFFECTS = 0;
 
-    public static final int XML_VERSION = 7;
+    public static final int XML_VERSION = 8;
     public static final String ZEN_TAG = "zen";
     private static final String ZEN_ATT_VERSION = "version";
     private static final String ZEN_ATT_USER = "user";
@@ -151,12 +153,10 @@
     public boolean allowMessages = DEFAULT_ALLOW_MESSAGES;
     public boolean allowReminders = DEFAULT_ALLOW_REMINDERS;
     public boolean allowEvents = DEFAULT_ALLOW_EVENTS;
-    public int allowCallsFrom = DEFAULT_SOURCE;
+    public int allowCallsFrom = DEFAULT_CALLS_SOURCE;
     public int allowMessagesFrom = DEFAULT_SOURCE;
     public int user = UserHandle.USER_SYSTEM;
     public int suppressedVisualEffects = DEFAULT_SUPPRESSED_VISUAL_EFFECTS;
-    public boolean allowWhenScreenOff = DEFAULT_ALLOW_SCREEN_OFF;
-    public boolean allowWhenScreenOn = DEFAULT_ALLOW_SCREEN_ON;
     public boolean areChannelsBypassingDnd = DEFAULT_CHANNELS_BYPASSING_DND;
     public int version;
 
@@ -185,8 +185,6 @@
                 automaticRules.put(ids[i], rules[i]);
             }
         }
-        allowWhenScreenOff = source.readInt() == 1;
-        allowWhenScreenOn = source.readInt() == 1;
         allowAlarms = source.readInt() == 1;
         allowMedia = source.readInt() == 1;
         allowSystem = source.readInt() == 1;
@@ -219,8 +217,6 @@
         } else {
             dest.writeInt(0);
         }
-        dest.writeInt(allowWhenScreenOff ? 1 : 0);
-        dest.writeInt(allowWhenScreenOn ? 1 : 0);
         dest.writeInt(allowAlarms ? 1 : 0);
         dest.writeInt(allowMedia ? 1 : 0);
         dest.writeInt(allowSystem ? 1 : 0);
@@ -242,8 +238,6 @@
                 .append(",allowMessages=").append(allowMessages)
                 .append(",allowCallsFrom=").append(sourceToString(allowCallsFrom))
                 .append(",allowMessagesFrom=").append(sourceToString(allowMessagesFrom))
-                .append(",allowWhenScreenOff=").append(allowWhenScreenOff)
-                .append(",allowWhenScreenOn=").append(allowWhenScreenOn)
                 .append(",suppressedVisualEffects=").append(suppressedVisualEffects)
                 .append(",areChannelsBypassingDnd=").append(areChannelsBypassingDnd)
                 .append(",automaticRules=").append(automaticRules)
@@ -289,12 +283,6 @@
         if (allowMessagesFrom != to.allowMessagesFrom) {
             d.addLine("allowMessagesFrom", allowMessagesFrom, to.allowMessagesFrom);
         }
-        if (allowWhenScreenOff != to.allowWhenScreenOff) {
-            d.addLine("allowWhenScreenOff", allowWhenScreenOff, to.allowWhenScreenOff);
-        }
-        if (allowWhenScreenOn != to.allowWhenScreenOn) {
-            d.addLine("allowWhenScreenOn", allowWhenScreenOn, to.allowWhenScreenOn);
-        }
         if (suppressedVisualEffects != to.suppressedVisualEffects) {
             d.addLine("suppressedVisualEffects", suppressedVisualEffects,
                     to.suppressedVisualEffects);
@@ -404,8 +392,6 @@
                 && other.allowMessagesFrom == allowMessagesFrom
                 && other.allowReminders == allowReminders
                 && other.allowEvents == allowEvents
-                && other.allowWhenScreenOff == allowWhenScreenOff
-                && other.allowWhenScreenOn == allowWhenScreenOn
                 && other.user == user
                 && Objects.equals(other.automaticRules, automaticRules)
                 && Objects.equals(other.manualRule, manualRule)
@@ -418,7 +404,7 @@
         return Objects.hash(allowAlarms, allowMedia, allowSystem, allowCalls,
                 allowRepeatCallers, allowMessages,
                 allowCallsFrom, allowMessagesFrom, allowReminders, allowEvents,
-                allowWhenScreenOff, allowWhenScreenOn, user, automaticRules, manualRule,
+                user, automaticRules, manualRule,
                 suppressedVisualEffects, areChannelsBypassingDnd);
     }
 
@@ -472,6 +458,7 @@
         final ZenModeConfig rt = new ZenModeConfig();
         rt.version = safeInt(parser, ZEN_ATT_VERSION, XML_VERSION);
         rt.user = safeInt(parser, ZEN_ATT_USER, rt.user);
+        boolean readSuppressedEffects = false;
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
             tag = parser.getName();
             if (type == XmlPullParser.END_TAG && ZEN_TAG.equals(tag)) {
@@ -502,17 +489,33 @@
                         rt.allowCallsFrom = DEFAULT_SOURCE;
                         rt.allowMessagesFrom = DEFAULT_SOURCE;
                     }
-                    // continue to read even though we now have suppressedVisualEffects, in case
-                    // we need to revert to users' previous settings
-                    rt.allowWhenScreenOff =
-                            safeBoolean(parser, ALLOW_ATT_SCREEN_OFF, DEFAULT_ALLOW_SCREEN_OFF);
-                    rt.allowWhenScreenOn =
-                            safeBoolean(parser, ALLOW_ATT_SCREEN_ON, DEFAULT_ALLOW_SCREEN_ON);
                     rt.allowAlarms = safeBoolean(parser, ALLOW_ATT_ALARMS, DEFAULT_ALLOW_ALARMS);
                     rt.allowMedia = safeBoolean(parser, ALLOW_ATT_MEDIA,
                             DEFAULT_ALLOW_MEDIA);
                     rt.allowSystem = safeBoolean(parser, ALLOW_ATT_SYSTEM, DEFAULT_ALLOW_SYSTEM);
-                } else if (DISALLOW_TAG.equals(tag)) {
+
+                    // migrate old suppressed visual effects fields, if they still exist in the xml
+                    Boolean allowWhenScreenOff = unsafeBoolean(parser, ALLOW_ATT_SCREEN_OFF);
+                    if (allowWhenScreenOff != null) {
+                        readSuppressedEffects = true;
+                        if (allowWhenScreenOff) {
+                            rt.suppressedVisualEffects |= SUPPRESSED_EFFECT_LIGHTS
+                                    | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
+                        }
+                    }
+                    Boolean allowWhenScreenOn = unsafeBoolean(parser, ALLOW_ATT_SCREEN_ON);
+                    if (allowWhenScreenOn != null) {
+                        readSuppressedEffects = true;
+                        if (allowWhenScreenOn) {
+                            rt.suppressedVisualEffects |= SUPPRESSED_EFFECT_PEEK;
+                        }
+                    }
+                    if (readSuppressedEffects) {
+                        Slog.d(TAG, "Migrated visual effects to " + rt.suppressedVisualEffects);
+                    }
+                } else if (DISALLOW_TAG.equals(tag) && !readSuppressedEffects) {
+                    // only read from suppressed visual effects field if we haven't just migrated
+                    // the values from allowOn/allowOff, lest we wipe out those settings
                     rt.suppressedVisualEffects = safeInt(parser, DISALLOW_ATT_VISUAL_EFFECTS,
                             DEFAULT_SUPPRESSED_VISUAL_EFFECTS);
                 } else if (MANUAL_TAG.equals(tag)) {
@@ -552,8 +555,6 @@
         out.attribute(null, ALLOW_ATT_EVENTS, Boolean.toString(allowEvents));
         out.attribute(null, ALLOW_ATT_CALLS_FROM, Integer.toString(allowCallsFrom));
         out.attribute(null, ALLOW_ATT_MESSAGES_FROM, Integer.toString(allowMessagesFrom));
-        out.attribute(null, ALLOW_ATT_SCREEN_OFF, Boolean.toString(allowWhenScreenOff));
-        out.attribute(null, ALLOW_ATT_SCREEN_ON, Boolean.toString(allowWhenScreenOn));
         out.attribute(null, ALLOW_ATT_ALARMS, Boolean.toString(allowAlarms));
         out.attribute(null, ALLOW_ATT_MEDIA, Boolean.toString(allowMedia));
         out.attribute(null, ALLOW_ATT_SYSTEM, Boolean.toString(allowSystem));
@@ -673,6 +674,12 @@
         return source >= SOURCE_ANYONE && source <= MAX_SOURCE;
     }
 
+    private static Boolean unsafeBoolean(XmlPullParser parser, String att) {
+        final String val = parser.getAttributeValue(null, att);
+        if (TextUtils.isEmpty(val)) return null;
+        return Boolean.parseBoolean(val);
+    }
+
     private static boolean safeBoolean(XmlPullParser parser, String att, boolean defValue) {
         final String val = parser.getAttributeValue(null, att);
         return safeBoolean(val, defValue);
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index af0eebf..ba7288d 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -498,7 +498,7 @@
 
     /** {@hide} */
     public static int length(@Nullable String s) {
-        return isEmpty(s) ? 0 : s.length();
+        return s != null ? s.length() : 0;
     }
 
     /**
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index dec0ecc..378bb1a 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.method.MetaKeyKeyListener;
@@ -2857,6 +2858,7 @@
      * @return The symbolic name of the specified action.
      * @hide
      */
+    @TestApi
     public static String actionToString(int action) {
         switch (action) {
             case ACTION_DOWN:
diff --git a/core/java/android/view/RecordingCanvas.java b/core/java/android/view/RecordingCanvas.java
index f7a41ff..18cc10f 100644
--- a/core/java/android/view/RecordingCanvas.java
+++ b/core/java/android/view/RecordingCanvas.java
@@ -34,6 +34,7 @@
 import android.graphics.RectF;
 import android.graphics.TemporaryBuffer;
 import android.text.GraphicsOperations;
+import android.text.MeasuredParagraph;
 import android.text.PrecomputedText;
 import android.text.SpannableString;
 import android.text.SpannedString;
@@ -500,21 +501,31 @@
             ((GraphicsOperations) text).drawTextRun(this, start, end,
                     contextStart, contextEnd, x, y, isRtl, paint);
         } else {
+            if (text instanceof PrecomputedText) {
+                final PrecomputedText pt = (PrecomputedText) text;
+                final int paraIndex = pt.findParaIndex(start);
+                if (end <= pt.getParagraphEnd(paraIndex)) {
+                    final int paraStart = pt.getParagraphStart(paraIndex);
+                    final MeasuredParagraph mp = pt.getMeasuredParagraph(paraIndex);
+                    // Only support if the target is in the same paragraph.
+                    nDrawTextRun(mNativeCanvasWrapper,
+                            mp.getChars(),
+                            start - paraStart,
+                            end - start,
+                            contextStart - paraStart,
+                            contextEnd - contextStart,
+                            x, y, isRtl, paint.getNativeInstance(),
+                            mp.getNativePtr());
+                    return;
+                }
+            }
             int contextLen = contextEnd - contextStart;
             int len = end - start;
             char[] buf = TemporaryBuffer.obtain(contextLen);
             TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
-            long measuredTextPtr = 0;
-            if (text instanceof PrecomputedText) {
-                PrecomputedText mt = (PrecomputedText) text;
-                int paraIndex = mt.findParaIndex(start);
-                if (end <= mt.getParagraphEnd(paraIndex)) {
-                    // Only support if the target is in the same paragraph.
-                    measuredTextPtr = mt.getMeasuredParagraph(paraIndex).getNativePtr();
-                }
-            }
             nDrawTextRun(mNativeCanvasWrapper, buf, start - contextStart, len,
-                    0, contextLen, x, y, isRtl, paint.getNativeInstance(), measuredTextPtr);
+                    0, contextLen, x, y, isRtl, paint.getNativeInstance(),
+                    0 /* measured paragraph pointer */);
             TemporaryBuffer.recycle(buf);
         }
     }
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 7e54647..db34856 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -700,15 +700,9 @@
                     mIsCreating = false;
                     if (mSurfaceControl != null && !mSurfaceCreated) {
                         mSurface.release();
-                        // If we are not in the stopped state, then the destruction of the Surface
-                        // represents a visual change we need to display, and we should go ahead
-                        // and destroy the SurfaceControl. However if we are in the stopped state,
-                        // we can just leave the Surface around so it can be a part of animations,
-                        // and we let the life-time be tied to the parent surface.
-                        if (!mWindowStopped) {
-                            mSurfaceControl.destroy();
-                            mSurfaceControl = null;
-                        }
+
+                        mSurfaceControl.destroy();
+                        mSurfaceControl = null;
                     }
                 }
             } catch (Exception ex) {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index fd3461f..78e4204 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1657,7 +1657,7 @@
      *
      * @return Returns the top-level window decor view.
      */
-    public abstract View getDecorView();
+    public abstract @NonNull View getDecorView();
 
     /**
      * Retrieve the current decor view, but only if it has already been created;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 03f1c12..6bacdfe 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -901,7 +901,7 @@
      * Refreshes this info with the latest state of the view it represents, and request new
      * data be added by the View.
      *
-     * @param extraDataKey A bitmask of the extra data requested. Data that must be requested
+     * @param extraDataKey The extra data requested. Data that must be requested
      *                     with this mechanism is generally expensive to retrieve, so should only be
      *                     requested when needed. See
      *                     {@link #EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY} and
@@ -2413,11 +2413,16 @@
 
     /**
      * Returns whether node represents a heading.
+     * <p><strong>Note:</strong> Returns {@code true} if either {@link #setHeading(boolean)}
+     * marks this node as a heading or if the node has a {@link CollectionItemInfo} that marks
+     * it as such, to accomodate apps that use the now-deprecated API.</p>
      *
      * @return {@code true} if the node is a heading, {@code false} otherwise.
      */
     public boolean isHeading() {
-        return getBooleanProperty(BOOLEAN_PROPERTY_IS_HEADING);
+        if (getBooleanProperty(BOOLEAN_PROPERTY_IS_HEADING)) return true;
+        CollectionItemInfo itemInfo = getCollectionItemInfo();
+        return ((itemInfo != null) && itemInfo.mHeading);
     }
 
     /**
@@ -3437,6 +3442,7 @@
         mPackageName = other.mPackageName;
         mClassName = other.mClassName;
         mText = other.mText;
+        mOriginalText = other.mOriginalText;
         mHintText = other.mHintText;
         mError = other.mError;
         mContentDescription = other.mContentDescription;
diff --git a/core/java/android/view/autofill/AutofillPopupWindow.java b/core/java/android/view/autofill/AutofillPopupWindow.java
index a6495d1..8266207 100644
--- a/core/java/android/view/autofill/AutofillPopupWindow.java
+++ b/core/java/android/view/autofill/AutofillPopupWindow.java
@@ -19,6 +19,7 @@
 import static android.view.autofill.Helper.sVerbose;
 
 import android.annotation.NonNull;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.IBinder;
@@ -79,11 +80,6 @@
     public AutofillPopupWindow(@NonNull IAutofillWindowPresenter presenter) {
         mWindowPresenter = new WindowPresenter(presenter);
 
-        // We want to show the window as system controlled one so it covers app windows, but it has
-        // to be an application type (so it's contained inside the application area).
-        // Hence, we set it to the application type with the highest z-order, which currently
-        // is TYPE_APPLICATION_ABOVE_SUB_PANEL.
-        setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL);
         setTouchModal(false);
         setOutsideTouchable(true);
         setInputMethodMode(INPUT_METHOD_NOT_NEEDED);
@@ -110,7 +106,16 @@
      */
     public void update(View anchor, int offsetX, int offsetY, int width, int height,
             Rect virtualBounds) {
-        mFullScreen = width == LayoutParams.MATCH_PARENT && height == LayoutParams.MATCH_PARENT;
+        mFullScreen = width == LayoutParams.MATCH_PARENT;
+        // For no fullscreen autofill window, we want to show the window as system controlled one
+        // so it covers app windows, but it has to be an application type (so it's contained inside
+        // the application area). Hence, we set it to the application type with the highest z-order,
+        // which currently is TYPE_APPLICATION_ABOVE_SUB_PANEL.
+        // For fullscreen mode, autofill window is at the bottom of screen, it should not be
+        // clipped by app activity window. Fullscreen autofill window does not need to follow app
+        // anchor view position.
+        setWindowLayoutType(mFullScreen ? WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
+                : WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL);
         // If we are showing the popup for a virtual view we use a fake view which
         // delegates to the anchor but present itself with the same bounds as the
         // virtual view. This ensures that the location logic in popup works
@@ -119,6 +124,15 @@
         if (mFullScreen) {
             offsetX = 0;
             offsetY = 0;
+            // If it is not fullscreen height, put window at bottom. Computes absolute position.
+            // Note that we cannot easily change default gravity from Gravity.TOP to
+            // Gravity.BOTTOM because PopupWindow base class does not expose computeGravity().
+            final Point outPoint = new Point();
+            anchor.getContext().getDisplay().getSize(outPoint);
+            width = outPoint.x;
+            if (height != LayoutParams.MATCH_PARENT) {
+                offsetY = outPoint.y - height;
+            }
             actualAnchor = anchor;
         } else if (virtualBounds != null) {
             final int[] mLocationOnScreen = new int[] {virtualBounds.left, virtualBounds.top};
@@ -202,6 +216,16 @@
             actualAnchor = anchor;
         }
 
+        if (!mFullScreen) {
+            // No fullscreen window animation is controlled by PopupWindow.
+            setAnimationStyle(-1);
+        } else if (height == LayoutParams.MATCH_PARENT) {
+            // Complete fullscreen autofill window has no animation.
+            setAnimationStyle(0);
+        } else {
+            // Slide half screen height autofill window from bottom.
+            setAnimationStyle(com.android.internal.R.style.AutofillHalfScreenAnimation);
+        }
         if (!isShowing()) {
             setWidth(width);
             setHeight(height);
@@ -223,7 +247,12 @@
     protected boolean findDropDownPosition(View anchor, LayoutParams outParams,
             int xOffset, int yOffset, int width, int height, int gravity, boolean allowScroll) {
         if (mFullScreen) {
-            // Do not patch LayoutParams if force full screen
+            // In fullscreen mode, don't need consider the anchor view.
+            outParams.x = xOffset;
+            outParams.y = yOffset;
+            outParams.width = width;
+            outParams.height = height;
+            outParams.gravity = gravity;
             return false;
         }
         return super.findDropDownPosition(anchor, outParams, xOffset, yOffset,
@@ -316,11 +345,6 @@
     }
 
     @Override
-    public void setAnimationStyle(int animationStyle) {
-        throw new IllegalStateException("You can't call this!");
-    }
-
-    @Override
     public void setBackgroundDrawable(Drawable background) {
         throw new IllegalStateException("You can't call this!");
     }
diff --git a/core/java/android/view/textclassifier/SystemTextClassifier.java b/core/java/android/view/textclassifier/SystemTextClassifier.java
index 490c389..da86b55 100644
--- a/core/java/android/view/textclassifier/SystemTextClassifier.java
+++ b/core/java/android/view/textclassifier/SystemTextClassifier.java
@@ -55,7 +55,8 @@
         mManagerService = ITextClassifierService.Stub.asInterface(
                 ServiceManager.getServiceOrThrow(Context.TEXT_CLASSIFICATION_SERVICE));
         mSettings = Preconditions.checkNotNull(settings);
-        mFallback = new TextClassifierImpl(context, settings);
+        mFallback = context.getSystemService(TextClassificationManager.class)
+                .getTextClassifier(TextClassifier.LOCAL);
         mPackageName = Preconditions.checkNotNull(context.getPackageName());
     }
 
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index 262d9b8..1737861 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -191,10 +191,11 @@
         synchronized (mLock) {
             if (mLocalTextClassifier == null) {
                 if (mSettings.isLocalTextClassifierEnabled()) {
-                    mLocalTextClassifier = new TextClassifierImpl(mContext, mSettings);
+                    mLocalTextClassifier =
+                            new TextClassifierImpl(mContext, mSettings, TextClassifier.NO_OP);
                 } else {
                     Log.d(LOG_TAG, "Local TextClassifier disabled");
-                    mLocalTextClassifier = TextClassifierImpl.NO_OP;
+                    mLocalTextClassifier = TextClassifier.NO_OP;
                 }
             }
             return mLocalTextClassifier;
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 910fcaa..2cf265d 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -21,6 +21,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.WorkerThread;
+import android.app.PendingIntent;
 import android.app.RemoteAction;
 import android.app.SearchManager;
 import android.content.ComponentName;
@@ -98,13 +99,18 @@
 
     private final TextClassificationConstants mSettings;
 
-    public TextClassifierImpl(Context context, TextClassificationConstants settings) {
+    public TextClassifierImpl(
+            Context context, TextClassificationConstants settings, TextClassifier fallback) {
         mContext = Preconditions.checkNotNull(context);
-        mFallback = TextClassifier.NO_OP;
+        mFallback = Preconditions.checkNotNull(fallback);
         mSettings = Preconditions.checkNotNull(settings);
         mGenerateLinksLogger = new GenerateLinksLogger(mSettings.getGenerateLinksLogSampleRate());
     }
 
+    public TextClassifierImpl(Context context, TextClassificationConstants settings) {
+        this(context, settings, TextClassifier.NO_OP);
+    }
+
     /** @inheritDoc */
     @Override
     @WorkerThread
@@ -413,6 +419,9 @@
         for (LabeledIntent labeledIntent : IntentFactory.create(
                 mContext, referenceTime, highestScoringResult, classifiedText)) {
             final RemoteAction action = labeledIntent.asRemoteAction(mContext);
+            if (action == null) {
+                continue;
+            }
             if (isPrimaryAction) {
                 // For O backwards compatibility, the first RemoteAction is also written to the
                 // legacy API fields.
@@ -601,6 +610,7 @@
             return mRequestCode;
         }
 
+        @Nullable
         RemoteAction asRemoteAction(Context context) {
             final PackageManager pm = context.getPackageManager();
             final ResolveInfo resolveInfo = pm.resolveActivity(mIntent, 0);
@@ -622,8 +632,12 @@
                 icon = Icon.createWithResource("android",
                         com.android.internal.R.drawable.ic_more_items);
             }
-            final RemoteAction action = new RemoteAction(icon, mTitle, mDescription,
-                    TextClassification.createPendingIntent(context, mIntent, mRequestCode));
+            final PendingIntent pendingIntent =
+                    TextClassification.createPendingIntent(context, mIntent, mRequestCode);
+            if (pendingIntent == null) {
+                return null;
+            }
+            final RemoteAction action = new RemoteAction(icon, mTitle, mDescription, pendingIntent);
             action.setShouldShowIcon(shouldShowIcon);
             return action;
         }
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index f6ac1cc..10de449 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -123,6 +123,7 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 import com.android.internal.util.Preconditions;
+import com.android.internal.view.FloatingActionMode;
 import com.android.internal.widget.EditableInputConnection;
 
 import java.lang.annotation.Retention;
@@ -2215,6 +2216,15 @@
         ActionMode.Callback actionModeCallback = new TextActionModeCallback(actionMode);
         mTextActionMode = mTextView.startActionMode(actionModeCallback, ActionMode.TYPE_FLOATING);
 
+        final boolean selectableText = mTextView.isTextEditable() || mTextView.isTextSelectable();
+        if (actionMode == TextActionMode.TEXT_LINK && !selectableText
+                && mTextActionMode instanceof FloatingActionMode) {
+            // Make the toolbar outside-touchable so that it can be dismissed when the user clicks
+            // outside of it.
+            ((FloatingActionMode) mTextActionMode).setOutsideTouchable(true,
+                    () -> stopTextActionMode());
+        }
+
         final boolean selectionStarted = mTextActionMode != null;
         if (selectionStarted
                 && mTextView.isTextEditable() && !mTextView.isTextSelectable()
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index cb362e6..f1a1457 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -170,7 +170,7 @@
             if (mWindow == null) {
                 synchronized (mLock) {
                     mWindow = new InternalPopupWindow(mView.getContext(), mView.getDisplay(),
-                            getValidViewSurface(),
+                            getValidParentSurfaceForMagnifier(),
                             mWindowWidth, mWindowHeight, mWindowElevation, mWindowCornerRadius,
                             Handler.getMain() /* draw the magnifier on the UI thread */, mLock,
                             mCallback);
@@ -245,18 +245,20 @@
     }
 
     @Nullable
-    private Surface getValidViewSurface() {
-        // TODO: deduplicate this against the first part of #performPixelCopy
-        final Surface surface;
-        if (mView instanceof SurfaceView) {
-            surface = ((SurfaceView) mView).getHolder().getSurface();
-        } else if (mView.getViewRootImpl() != null) {
-            surface = mView.getViewRootImpl().mSurface;
-        } else {
-            surface = null;
+    private Surface getValidParentSurfaceForMagnifier() {
+        if (mView.getViewRootImpl() != null) {
+            final Surface mainWindowSurface = mView.getViewRootImpl().mSurface;
+            if (mainWindowSurface != null && mainWindowSurface.isValid()) {
+                return mainWindowSurface;
+            }
         }
-
-        return (surface != null && surface.isValid()) ? surface : null;
+        if (mView instanceof SurfaceView) {
+            final Surface surfaceViewSurface = ((SurfaceView) mView).getHolder().getSurface();
+            if (surfaceViewSurface != null && surfaceViewSurface.isValid()) {
+                return surfaceViewSurface;
+            }
+        }
+        return null;
     }
 
     private void configureCoordinates(final float xPosInView, final float yPosInView) {
@@ -264,12 +266,12 @@
         // magnifier. These are relative to the surface the content is copied from.
         final float posX;
         final float posY;
+        mView.getLocationInSurface(mViewCoordinatesInSurface);
         if (mView instanceof SurfaceView) {
             // No offset required if the backing Surface matches the size of the SurfaceView.
             posX = xPosInView;
             posY = yPosInView;
         } else {
-            mView.getLocationInSurface(mViewCoordinatesInSurface);
             posX = xPosInView + mViewCoordinatesInSurface[0];
             posY = yPosInView + mViewCoordinatesInSurface[1];
         }
@@ -282,6 +284,14 @@
                 R.dimen.magnifier_offset);
         mWindowCoords.x = mCenterZoomCoords.x - mWindowWidth / 2;
         mWindowCoords.y = mCenterZoomCoords.y - mWindowHeight / 2 - verticalOffset;
+        if (mView instanceof SurfaceView && mView.getViewRootImpl() != null) {
+            // TODO: deduplicate against the first part of #getValidParentSurfaceForMagnifier()
+            final Surface mainWindowSurface = mView.getViewRootImpl().mSurface;
+            if (mainWindowSurface != null && mainWindowSurface.isValid()) {
+                mWindowCoords.x += mViewCoordinatesInSurface[0];
+                mWindowCoords.y += mViewCoordinatesInSurface[1];
+            }
+        }
     }
 
     private void performPixelCopy(final int startXInSurface, final int startYInSurface,
@@ -361,6 +371,9 @@
         // The alpha set on the magnifier's content, which defines how
         // prominent the white background is.
         private static final int CONTENT_BITMAP_ALPHA = 242;
+        // The z of the magnifier surface, defining its z order in the list of
+        // siblings having the same parent surface (usually the main app surface).
+        private static final int SURFACE_Z = 5;
 
         // Display associated to the view the magnifier is attached to.
         private final Display mDisplay;
@@ -602,6 +615,7 @@
                                     mSurfaceControl.setPosition(pendingX, pendingY);
                                 }
                                 if (firstDraw) {
+                                    mSurfaceControl.setLayer(SURFACE_Z);
                                     mSurfaceControl.show();
                                 }
                                 SurfaceControl.closeTransaction();
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index b6bd14e..4865dab 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -21,6 +21,7 @@
 import android.annotation.ColorInt;
 import android.annotation.DimenRes;
 import android.annotation.NonNull;
+import android.annotation.StyleRes;
 import android.app.ActivityOptions;
 import android.app.ActivityThread;
 import android.app.Application;
@@ -56,6 +57,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.LayoutInflater.Filter;
 import android.view.RemotableViewMethod;
@@ -182,6 +184,12 @@
     private boolean mIsRoot = true;
 
     /**
+     * Optional theme resource id applied in inflateView(). When 0, Theme.DeviceDefault will be
+     * used.
+     */
+    private int mApplyThemeResId;
+
+    /**
      * Whether reapply is disallowed on this remoteview. This maybe be true if some actions modify
      * the layout in a way that isn't recoverable, since views are being removed.
      */
@@ -946,6 +954,7 @@
                     }
                 };
             }
+            target.setTagInternal(R.id.pending_intent_tag, pendingIntent);
             target.setOnClickListener(listener);
         }
 
@@ -1999,6 +2008,7 @@
         /** Set width */
         public static final int LAYOUT_WIDTH = 2;
         public static final int LAYOUT_MARGIN_BOTTOM_DIMEN = 3;
+        public static final int LAYOUT_MARGIN_END = 4;
 
         final int mProperty;
         final int mValue;
@@ -2036,11 +2046,14 @@
             if (layoutParams == null) {
                 return;
             }
+            int value = mValue;
             switch (mProperty) {
                 case LAYOUT_MARGIN_END_DIMEN:
+                    value = resolveDimenPixelOffset(target, mValue);
+                    // fall-through
+                case LAYOUT_MARGIN_END:
                     if (layoutParams instanceof ViewGroup.MarginLayoutParams) {
-                        int resolved = resolveDimenPixelOffset(target, mValue);
-                        ((ViewGroup.MarginLayoutParams) layoutParams).setMarginEnd(resolved);
+                        ((ViewGroup.MarginLayoutParams) layoutParams).setMarginEnd(value);
                         target.setLayoutParams(layoutParams);
                     }
                     break;
@@ -2980,6 +2993,20 @@
     }
 
     /**
+     * Equivalent to calling {@link android.view.ViewGroup.MarginLayoutParams#setMarginEnd(int)}.
+     * Only works if the {@link View#getLayoutParams()} supports margins.
+     * Hidden for now since we don't want to support this for all different layout margins yet.
+     *
+     * @param viewId The id of the view to change
+     * @param endMargin a value in pixels for the end margin.
+     * @hide
+     */
+    public void setViewLayoutMarginEnd(int viewId, @DimenRes int endMargin) {
+        addAction(new LayoutParamAction(viewId, LayoutParamAction.LAYOUT_MARGIN_END,
+                endMargin));
+    }
+
+    /**
      * Equivalent to setting {@link android.view.ViewGroup.MarginLayoutParams#bottomMargin}.
      *
      * @param bottomMarginDimen a dimen resource to read the margin from or 0 to clear the margin.
@@ -3248,6 +3275,14 @@
     }
 
     /**
+     * Set the theme used in apply() and applyASync().
+     * @hide
+     */
+    public void setApplyTheme(@StyleRes int themeResId) {
+        mApplyThemeResId = themeResId;
+    }
+
+    /**
      * Inflates the view hierarchy represented by this object and applies
      * all of the actions.
      *
@@ -3282,6 +3317,10 @@
         final Context contextForResources = getContextForResources(context);
         Context inflationContext = new RemoteViewsContextWrapper(context, contextForResources);
 
+        // If mApplyThemeResId is not given, Theme.DeviceDefault will be used.
+        if (mApplyThemeResId != 0) {
+            inflationContext = new ContextThemeWrapper(inflationContext, mApplyThemeResId);
+        }
         LayoutInflater inflater = (LayoutInflater)
                 context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 1b9055c..6cc86b9 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -28,7 +28,6 @@
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.graphics.RectF;
-import android.graphics.Region;
 import android.graphics.TableMaskFilter;
 import android.os.Bundle;
 import android.util.AttributeSet;
@@ -550,8 +549,8 @@
 
         // We only expand the clip bounds if necessary.
         if (expandClipRegion) {
-            canvas.save(Canvas.CLIP_SAVE_FLAG);
-            canvas.clipRect(stackInvalidateRect, Region.Op.UNION);
+            canvas.save();
+            canvas.clipRectUnion(stackInvalidateRect);
             super.dispatchDraw(canvas);
             canvas.restore();
         } else {
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 46cb546..7321721 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -30,7 +30,10 @@
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.Message;
+import android.text.Layout;
 import android.text.TextUtils;
+import android.text.method.LinkMovementMethod;
+import android.text.method.MovementMethod;
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.view.Gravity;
@@ -101,6 +104,9 @@
     private ImageView mIconView;
     private TextView mTitleView;
     protected TextView mMessageView;
+    private MovementMethod mMessageMovementMethod;
+    @Layout.HyphenationFrequency
+    private Integer mMessageHyphenationFrequency;
     private View mCustomTitleView;
 
     private boolean mForceInverseBackground;
@@ -290,6 +296,21 @@
         }
     }
 
+    public void setMessageMovementMethod(MovementMethod movementMethod) {
+        mMessageMovementMethod = movementMethod;
+        if (mMessageView != null) {
+            mMessageView.setMovementMethod(movementMethod);
+        }
+    }
+
+    public void setMessageHyphenationFrequency(
+            @Layout.HyphenationFrequency int hyphenationFrequency) {
+        mMessageHyphenationFrequency = hyphenationFrequency;
+        if (mMessageView != null) {
+            mMessageView.setHyphenationFrequency(hyphenationFrequency);
+        }
+    }
+
     /**
      * Set the view resource to display in the dialog.
      */
@@ -676,6 +697,12 @@
 
         if (mMessage != null) {
             mMessageView.setText(mMessage);
+            if (mMessageMovementMethod != null) {
+                mMessageView.setMovementMethod(mMessageMovementMethod);
+            }
+            if (mMessageHyphenationFrequency != null) {
+                mMessageView.setHyphenationFrequency(mMessageHyphenationFrequency);
+            }
         } else {
             mMessageView.setVisibility(View.GONE);
             mScrollView.removeView(mMessageView);
diff --git a/core/java/com/android/internal/app/ColorDisplayController.java b/core/java/com/android/internal/app/ColorDisplayController.java
index f1539ee..6cc964b 100644
--- a/core/java/com/android/internal/app/ColorDisplayController.java
+++ b/core/java/com/android/internal/app/ColorDisplayController.java
@@ -82,7 +82,7 @@
     public static final int AUTO_MODE_TWILIGHT = 2;
 
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({ COLOR_MODE_NATURAL, COLOR_MODE_BOOSTED, COLOR_MODE_SATURATED })
+    @IntDef({ COLOR_MODE_NATURAL, COLOR_MODE_BOOSTED, COLOR_MODE_SATURATED, COLOR_MODE_AUTOMATIC })
     public @interface ColorMode {}
 
     /**
@@ -103,12 +103,12 @@
      * @see #setColorMode(int)
      */
     public static final int COLOR_MODE_SATURATED = 2;
-
     /**
-     * See com.android.server.display.DisplayTransformManager.
+     * Color mode with automatic colors.
+     *
+     * @see #setColorMode(int)
      */
-    private static final String PERSISTENT_PROPERTY_SATURATION = "persist.sys.sf.color_saturation";
-    private static final String PERSISTENT_PROPERTY_NATIVE_MODE = "persist.sys.sf.native_mode";
+    public static final int COLOR_MODE_AUTOMATIC = 3;
 
     private final Context mContext;
     private final int mUserId;
@@ -362,6 +362,41 @@
     }
 
     /**
+     * Get the current color mode from system properties, or return -1.
+     *
+     * See com.android.server.display.DisplayTransformManager.
+     */
+    private @ColorMode int getCurrentColorModeFromSystemProperties() {
+        int displayColorSetting = SystemProperties.getInt("persist.sys.sf.native_mode", 0);
+        if (displayColorSetting == 0) {
+            return "1.0".equals(SystemProperties.get("persist.sys.sf.color_saturation"))
+                ? COLOR_MODE_NATURAL : COLOR_MODE_BOOSTED;
+        } else if (displayColorSetting == 1) {
+            return COLOR_MODE_SATURATED;
+        } else if (displayColorSetting == 2) {
+            return COLOR_MODE_AUTOMATIC;
+        } else {
+            return -1;
+        }
+    }
+
+    private boolean isColorModeAvailable(@ColorMode int colorMode) {
+        // SATURATED is always allowed
+        if (colorMode == COLOR_MODE_SATURATED) {
+            return true;
+        }
+
+        final int[] availableColorModes = mContext.getResources().getIntArray(
+                R.array.config_availableColorModes);
+        for (int mode : availableColorModes) {
+            if (mode == colorMode) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
      * Get the current color mode.
      */
     public int getColorMode() {
@@ -369,17 +404,27 @@
             return COLOR_MODE_SATURATED;
         }
 
-        final int colorMode = System.getIntForUser(mContext.getContentResolver(),
+        int colorMode = System.getIntForUser(mContext.getContentResolver(),
             System.DISPLAY_COLOR_MODE, -1, mUserId);
-        if (colorMode < COLOR_MODE_NATURAL || colorMode > COLOR_MODE_SATURATED) {
+        if (colorMode == -1) {
             // There still might be a legacy system property controlling color mode that we need to
             // respect.
-            if ("1".equals(SystemProperties.get(PERSISTENT_PROPERTY_NATIVE_MODE))) {
-                return COLOR_MODE_SATURATED;
-            }
-            return "1.0".equals(SystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
-                    ? COLOR_MODE_NATURAL : COLOR_MODE_BOOSTED;
+            colorMode = getCurrentColorModeFromSystemProperties();
         }
+
+        // This happens when a color mode is no longer available (e.g., after system update or B&R)
+        // or the device does not support any color mode.
+        if (!isColorModeAvailable(colorMode)) {
+            if (colorMode == COLOR_MODE_BOOSTED && isColorModeAvailable(COLOR_MODE_NATURAL)) {
+                colorMode = COLOR_MODE_NATURAL;
+            } else if (colorMode == COLOR_MODE_SATURATED
+                && isColorModeAvailable(COLOR_MODE_AUTOMATIC)) {
+                colorMode = COLOR_MODE_AUTOMATIC;
+            } else {
+                colorMode = COLOR_MODE_SATURATED;
+            }
+        }
+
         return colorMode;
     }
 
@@ -389,7 +434,7 @@
      * @param colorMode the color mode
      */
     public void setColorMode(@ColorMode int colorMode) {
-        if (colorMode < COLOR_MODE_NATURAL || colorMode > COLOR_MODE_SATURATED) {
+        if (!isColorModeAvailable(colorMode)) {
             throw new IllegalArgumentException("Invalid colorMode: " + colorMode);
         }
         System.putIntForUser(mContext.getContentResolver(), System.DISPLAY_COLOR_MODE, colorMode,
diff --git a/core/java/com/android/internal/app/ISoundTriggerService.aidl b/core/java/com/android/internal/app/ISoundTriggerService.aidl
index 93730df..b8a2dff 100644
--- a/core/java/com/android/internal/app/ISoundTriggerService.aidl
+++ b/core/java/com/android/internal/app/ISoundTriggerService.aidl
@@ -43,15 +43,10 @@
     int loadGenericSoundModel(in SoundTrigger.GenericSoundModel soundModel);
     int loadKeyphraseSoundModel(in SoundTrigger.KeyphraseSoundModel soundModel);
 
-    int startRecognitionForIntent(in ParcelUuid soundModelId, in PendingIntent callbackIntent,
-         in SoundTrigger.RecognitionConfig config);
-
-
     int startRecognitionForService(in ParcelUuid soundModelId, in Bundle params,
          in ComponentName callbackIntent,in SoundTrigger.RecognitionConfig config);
 
-    /** For both ...Intent and ...Service based usage */
-    int stopRecognitionForIntent(in ParcelUuid soundModelId);
+    int stopRecognitionForService(in ParcelUuid soundModelId);
 
     int unloadSoundModel(in ParcelUuid soundModelId);
 
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 7f289d0..1e5b5c8 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -67,7 +67,6 @@
     private static final String NOT_A_SUBTYPE_ID_STR = String.valueOf(NOT_A_SUBTYPE_ID);
     private static final String TAG_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE =
             "EnabledWhenDefaultIsNotAsciiCapable";
-    private static final String TAG_ASCII_CAPABLE = "AsciiCapable";
 
     // The string for enabled input method is saved as follows:
     // example: ("ime0;subtype0;subtype1;subtype2:ime1:ime2;subtype0")
@@ -539,7 +538,7 @@
             final int numApplicationSubtypes = applicableSubtypes.size();
             for (int i = 0; i < numApplicationSubtypes; ++i) {
                 final InputMethodSubtype subtype = applicableSubtypes.get(i);
-                if (subtype.containsExtraValueKey(TAG_ASCII_CAPABLE)) {
+                if (subtype.isAsciiCapable()) {
                     hasAsciiCapableKeyboard = true;
                     break;
                 }
diff --git a/core/java/com/android/internal/os/BackgroundThread.java b/core/java/com/android/internal/os/BackgroundThread.java
index 7558f8c..eada142 100644
--- a/core/java/com/android/internal/os/BackgroundThread.java
+++ b/core/java/com/android/internal/os/BackgroundThread.java
@@ -18,12 +18,15 @@
 
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.os.Looper;
 import android.os.Trace;
 
 /**
  * Shared singleton background thread for each process.
  */
 public final class BackgroundThread extends HandlerThread {
+    private static final long SLOW_DISPATCH_THRESHOLD_MS = 10_000;
+    private static final long SLOW_DELIVERY_THRESHOLD_MS = 30_000;
     private static BackgroundThread sInstance;
     private static Handler sHandler;
 
@@ -35,7 +38,10 @@
         if (sInstance == null) {
             sInstance = new BackgroundThread();
             sInstance.start();
-            sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
+            final Looper looper = sInstance.getLooper();
+            looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
+            looper.setSlowLogThresholdMs(
+                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
             sHandler = new Handler(sInstance.getLooper());
         }
     }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index a4680ca..7703052 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -585,6 +585,7 @@
                 boolean onBatteryScreenOff);
         Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis);
         void cancelCpuSyncDueToWakelockChange();
+        Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis);
     }
 
     public Handler mHandler;
@@ -4083,7 +4084,8 @@
 
     boolean ensureStartClockTime(final long currentTime) {
         final long ABOUT_ONE_YEAR = 365*24*60*60*1000L;
-        if (currentTime > ABOUT_ONE_YEAR && mStartClockTime < (currentTime-ABOUT_ONE_YEAR)) {
+        if ((currentTime > ABOUT_ONE_YEAR && mStartClockTime < (currentTime-ABOUT_ONE_YEAR))
+                || (mStartClockTime > currentTime)) {
             // If the start clock time has changed by more than a year, then presumably
             // the previous time was completely bogus.  So we are going to figure out a
             // new time based on how much time has elapsed since we started counting.
@@ -12614,7 +12616,8 @@
 
                 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record
                 // which will pull external stats.
-                scheduleSyncExternalStatsLocked("battery-level", ExternalStatsSync.UPDATE_ALL);
+                mExternalSync.scheduleSyncDueToBatteryLevelChange(
+                        mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS);
             }
             if (mHistoryCur.batteryStatus != status) {
                 mHistoryCur.batteryStatus = (byte)status;
@@ -13270,6 +13273,8 @@
                 = "uid_remove_delay_ms";
         public static final String KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS
                 = "external_stats_collection_rate_limit_ms";
+        public static final String KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS
+                = "battery_level_collection_delay_ms";
 
         private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = true;
         private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true;
@@ -13277,6 +13282,7 @@
         private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 10_000;
         private static final long DEFAULT_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L;
         private static final long DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = 600_000;
+        private static final long DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS = 300_000;
 
         public boolean TRACK_CPU_TIMES_BY_PROC_STATE = DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE;
         public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME;
@@ -13285,6 +13291,8 @@
         public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS;
         public long EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS
                 = DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS;
+        public long BATTERY_LEVEL_COLLECTION_DELAY_MS
+                = DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS;
 
         private ContentResolver mResolver;
         private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -13333,6 +13341,9 @@
                 EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = mParser.getLong(
                         KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS,
                         DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS);
+                BATTERY_LEVEL_COLLECTION_DELAY_MS = mParser.getLong(
+                        KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS,
+                        DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS);
             }
         }
 
@@ -13384,6 +13395,8 @@
             pw.println(KERNEL_UID_READERS_THROTTLE_TIME);
             pw.print(KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print("=");
             pw.println(EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS);
+            pw.print(KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS); pw.print("=");
+            pw.println(BATTERY_LEVEL_COLLECTION_DELAY_MS);
         }
     }
 
diff --git a/core/java/com/android/internal/policy/DecorContext.java b/core/java/com/android/internal/policy/DecorContext.java
index eac9f64..cd80d53 100644
--- a/core/java/com/android/internal/policy/DecorContext.java
+++ b/core/java/com/android/internal/policy/DecorContext.java
@@ -23,6 +23,8 @@
 import android.view.WindowManager;
 import android.view.WindowManagerImpl;
 
+import java.lang.ref.WeakReference;
+
 /**
  * Context for decor views which can be seeded with pure application context and not depend on the
  * activity, but still provide some of the facilities that Activity has,
@@ -35,9 +37,12 @@
     private WindowManager mWindowManager;
     private Resources mActivityResources;
 
-    public DecorContext(Context context, Resources activityResources) {
+    private WeakReference<Context> mActivityContext;
+
+    public DecorContext(Context context, Context activityContext) {
         super(context, null);
-        mActivityResources = activityResources;
+        mActivityContext = new WeakReference<>(activityContext);
+        mActivityResources = activityContext.getResources();
     }
 
     void setPhoneWindow(PhoneWindow phoneWindow) {
@@ -60,6 +65,13 @@
 
     @Override
     public Resources getResources() {
+        Context activityContext = mActivityContext.get();
+        // Attempt to update the local cached Resources from the activity context. If the activity
+        // is no longer around, return the old cached values.
+        if (activityContext != null) {
+            mActivityResources = activityContext.getResources();
+        }
+
         return mActivityResources;
     }
 
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index eadefc9..a186f1a 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.policy;
 
+import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.app.WindowConfiguration;
 import android.graphics.Outline;
 import android.graphics.drawable.InsetDrawable;
@@ -41,7 +43,6 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
-import android.app.ActivityManager;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -55,7 +56,6 @@
 import android.graphics.Shader;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.os.RemoteException;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.TypedValue;
@@ -281,11 +281,16 @@
         initResizingPaints();
     }
 
-    void setBackgroundFallback(int resId) {
-        mBackgroundFallback.setDrawable(resId != 0 ? getContext().getDrawable(resId) : null);
+    void setBackgroundFallback(@Nullable Drawable fallbackDrawable) {
+        mBackgroundFallback.setDrawable(fallbackDrawable);
         setWillNotDraw(getBackground() == null && !mBackgroundFallback.hasFallback());
     }
 
+    @TestApi
+    public @Nullable Drawable getBackgroundFallback() {
+        return mBackgroundFallback.getDrawable();
+    }
+
     @Override
     public boolean gatherTransparentRegion(Region region) {
         boolean statusOpaque = gatherTransparentRegion(mStatusColorViewState, region);
@@ -946,7 +951,7 @@
                         mWindow.isTranslucent() || mWindow.isShowingWallpaper());
             } else {
                 mResizingBackgroundDrawable = getResizingBackgroundDrawable(
-                        getContext(), 0, mWindow.mBackgroundFallbackResource,
+                        mWindow.mBackgroundDrawable, mWindow.mBackgroundFallbackDrawable,
                         mWindow.isTranslucent() || mWindow.isShowingWallpaper());
             }
             if (mResizingBackgroundDrawable != null) {
@@ -1844,6 +1849,13 @@
     }
 
     @Override
+    public Resources getResources() {
+        // Make sure the Resources object is propogated from the Context since it can be updated in
+        // the Context object.
+        return getContext().getResources();
+    }
+
+    @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
 
@@ -1901,9 +1913,9 @@
 
     private void loadBackgroundDrawablesIfNeeded() {
         if (mResizingBackgroundDrawable == null) {
-            mResizingBackgroundDrawable = getResizingBackgroundDrawable(getContext(),
-                    mWindow.mBackgroundResource, mWindow.mBackgroundFallbackResource,
-                    mWindow.isTranslucent() || mWindow.isShowingWallpaper());
+            mResizingBackgroundDrawable = getResizingBackgroundDrawable(mWindow.mBackgroundDrawable,
+                    mWindow.mBackgroundFallbackDrawable, mWindow.isTranslucent()
+                    || mWindow.isShowingWallpaper());
             if (mResizingBackgroundDrawable == null) {
                 // We shouldn't really get here as the background fallback should be always
                 // available since it is defaulted by the system.
@@ -2011,20 +2023,14 @@
      * Returns the color used to fill areas the app has not rendered content to yet when the
      * user is resizing the window of an activity in multi-window mode.
      */
-    public static Drawable getResizingBackgroundDrawable(Context context, int backgroundRes,
-            int backgroundFallbackRes, boolean windowTranslucent) {
-        if (backgroundRes != 0) {
-            final Drawable drawable = context.getDrawable(backgroundRes);
-            if (drawable != null) {
-                return enforceNonTranslucentBackground(drawable, windowTranslucent);
-            }
+    public static Drawable getResizingBackgroundDrawable(@Nullable Drawable backgroundDrawable,
+            @Nullable Drawable fallbackDrawable, boolean windowTranslucent) {
+        if (backgroundDrawable != null) {
+            return enforceNonTranslucentBackground(backgroundDrawable, windowTranslucent);
         }
 
-        if (backgroundFallbackRes != 0) {
-            final Drawable fallbackDrawable = context.getDrawable(backgroundFallbackRes);
-            if (fallbackDrawable != null) {
-                return enforceNonTranslucentBackground(fallbackDrawable, windowTranslucent);
-            }
+        if (fallbackDrawable != null) {
+            return enforceNonTranslucentBackground(fallbackDrawable, windowTranslucent);
         }
         return new ColorDrawable(Color.BLACK);
     }
diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index 3af3e2a..a3c7a9e 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -344,7 +344,7 @@
             if (dockedSide == DOCKED_LEFT) {
                 position += mInsets.left;
             } else if (dockedSide == DOCKED_RIGHT) {
-                position = mDisplayWidth - position - mInsets.right;
+                position = mDisplayWidth - position - mInsets.right - mDividerSize;
             }
         }
         mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE));
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 528888f..64a8f9f 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -21,6 +21,7 @@
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 import static android.view.WindowManager.LayoutParams.*;
 
+import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.SearchManager;
 import android.os.UserHandle;
@@ -217,10 +218,8 @@
 
     private ProgressBar mHorizontalProgressBar;
 
-    int mBackgroundResource = 0;
-    int mBackgroundFallbackResource = 0;
-
-    private Drawable mBackgroundDrawable;
+    Drawable mBackgroundDrawable = null;
+    Drawable mBackgroundFallbackDrawable = null;
 
     private boolean mLoadElevation = true;
     private float mElevation;
@@ -1470,14 +1469,14 @@
 
     @Override
     public final void setBackgroundDrawable(Drawable drawable) {
-        if (drawable != mBackgroundDrawable || mBackgroundResource != 0) {
-            mBackgroundResource = 0;
+        if (drawable != mBackgroundDrawable) {
             mBackgroundDrawable = drawable;
             if (mDecor != null) {
                 mDecor.setWindowBackground(drawable);
-            }
-            if (mBackgroundFallbackResource != 0) {
-                mDecor.setBackgroundFallback(drawable != null ? 0 : mBackgroundFallbackResource);
+                if (mBackgroundFallbackDrawable != null) {
+                    mDecor.setBackgroundFallback(drawable != null ? null :
+                            mBackgroundFallbackDrawable);
+                }
             }
         }
     }
@@ -2066,7 +2065,7 @@
     }
 
     @Override
-    public final View getDecorView() {
+    public final @NonNull View getDecorView() {
         if (mDecor == null || mForceDecorInstall) {
             installDecor();
         }
@@ -2299,7 +2298,7 @@
             if (applicationContext == null) {
                 context = getContext();
             } else {
-                context = new DecorContext(applicationContext, getContext().getResources());
+                context = new DecorContext(applicationContext, getContext());
                 if (mTheme != -1) {
                     context.setTheme(mTheme);
                 }
@@ -2510,19 +2509,18 @@
         // the values are inherited from our container.
         if (getContainer() == null) {
             if (mBackgroundDrawable == null) {
-                if (mBackgroundResource == 0) {
-                    mBackgroundResource = a.getResourceId(
-                            R.styleable.Window_windowBackground, 0);
-                }
+
                 if (mFrameResource == 0) {
                     mFrameResource = a.getResourceId(R.styleable.Window_windowFrame, 0);
                 }
-                mBackgroundFallbackResource = a.getResourceId(
-                        R.styleable.Window_windowBackgroundFallback, 0);
-                if (false) {
-                    System.out.println("Background: "
-                            + Integer.toHexString(mBackgroundResource) + " Frame: "
-                            + Integer.toHexString(mFrameResource));
+
+                if (a.hasValue(R.styleable.Window_windowBackground)) {
+                    mBackgroundDrawable = a.getDrawable(R.styleable.Window_windowBackground);
+                }
+
+                if (a.hasValue(R.styleable.Window_windowBackgroundFallback)) {
+                    mBackgroundFallbackDrawable =
+                            a.getDrawable(R.styleable.Window_windowBackgroundFallback);
                 }
             }
             if (mLoadElevation) {
@@ -2617,13 +2615,7 @@
         // Remaining setup -- of background and title -- that only applies
         // to top-level windows.
         if (getContainer() == null) {
-            final Drawable background;
-            if (mBackgroundResource != 0) {
-                background = getContext().getDrawable(mBackgroundResource);
-            } else {
-                background = mBackgroundDrawable;
-            }
-            mDecor.setWindowBackground(background);
+            mDecor.setWindowBackground(mBackgroundDrawable);
 
             final Drawable frame;
             if (mFrameResource != 0) {
@@ -2733,8 +2725,8 @@
                 }
             }
 
-            if (mDecor.getBackground() == null && mBackgroundFallbackResource != 0) {
-                mDecor.setBackgroundFallback(mBackgroundFallbackResource);
+            if (mDecor.getBackground() == null && mBackgroundFallbackDrawable != null) {
+                mDecor.setBackgroundFallback(mBackgroundFallbackDrawable);
             }
 
             // Only inflate or create a new TransitionManager if the caller hasn't
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 497e7b0..54dede6 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -17,6 +17,7 @@
 package com.android.internal.view;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -30,6 +31,7 @@
 import android.view.ViewParent;
 import android.view.WindowManager;
 
+import android.widget.PopupWindow;
 import com.android.internal.R;
 import com.android.internal.util.Preconditions;
 import com.android.internal.view.menu.MenuBuilder;
@@ -241,6 +243,23 @@
         }
     }
 
+    /**
+     * If this is set to true, the action mode view will dismiss itself on touch events outside of
+     * its window. This only makes sense if the action mode view is a PopupWindow that is touchable
+     * but not focusable, which means touches outside of the window will be delivered to the window
+     * behind. The default is false.
+     *
+     * This is for internal use only and the approach to this may change.
+     * @hide
+     *
+     * @param outsideTouchable whether or not this action mode is "outside touchable"
+     * @param onDismiss optional. Sets a callback for when this action mode popup dismisses itself
+     */
+    public void setOutsideTouchable(
+            boolean outsideTouchable, @Nullable PopupWindow.OnDismissListener onDismiss) {
+        mFloatingToolbar.setOutsideTouchable(outsideTouchable, onDismiss);
+    }
+
     @Override
     public void onWindowFocusChanged(boolean hasWindowFocus) {
         mFloatingToolbarVisibilityHelper.setWindowFocused(hasWindowFocus);
diff --git a/core/java/com/android/internal/widget/BackgroundFallback.java b/core/java/com/android/internal/widget/BackgroundFallback.java
index 309f80c..f69aa4d 100644
--- a/core/java/com/android/internal/widget/BackgroundFallback.java
+++ b/core/java/com/android/internal/widget/BackgroundFallback.java
@@ -17,6 +17,7 @@
 
 package com.android.internal.widget;
 
+import android.annotation.Nullable;
 import android.graphics.Canvas;
 import android.graphics.PixelFormat;
 import android.graphics.drawable.Drawable;
@@ -35,6 +36,10 @@
         mBackgroundFallback = d;
     }
 
+    public @Nullable Drawable getDrawable() {
+        return mBackgroundFallback;
+    }
+
     public boolean hasFallback() {
         return mBackgroundFallback != null;
     }
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 63c2e96..42fb1f5 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -21,6 +21,7 @@
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Color;
@@ -259,6 +260,22 @@
         return mPopup.isHidden();
     }
 
+    /**
+     * If this is set to true, the action mode view will dismiss itself on touch events outside of
+     * its window. If the toolbar is already showing, it will be re-shown so that this setting takes
+     * effect immediately.
+     *
+     * @param outsideTouchable whether or not this action mode is "outside touchable"
+     * @param onDismiss optional. Sets a callback for when this action mode popup dismisses itself
+     */
+    public void setOutsideTouchable(
+            boolean outsideTouchable, @Nullable PopupWindow.OnDismissListener onDismiss) {
+        if (mPopup.setOutsideTouchable(outsideTouchable, onDismiss) && isShowing()) {
+            dismiss();
+            doShow();
+        }
+    }
+
     private void doShow() {
         List<MenuItem> menuItems = getVisibleAndEnabledMenuItems(mMenu);
         menuItems.sort(mMenuItemComparator);
@@ -452,7 +469,7 @@
             mLineHeight = context.getResources()
                     .getDimensionPixelSize(R.dimen.floating_toolbar_height);
             mIconTextSpacing = context.getResources()
-                    .getDimensionPixelSize(R.dimen.floating_toolbar_menu_button_side_padding);
+                    .getDimensionPixelSize(R.dimen.floating_toolbar_icon_text_spacing);
 
             // Interpolators
             mLogAccelerateInterpolator = new LogAccelerateInterpolator();
@@ -481,7 +498,7 @@
             mOverflowButton = createOverflowButton();
             mOverflowButtonSize = measure(mOverflowButton);
             mMainPanel = createMainPanel();
-            mOverflowPanelViewHelper = new OverflowPanelViewHelper(mContext);
+            mOverflowPanelViewHelper = new OverflowPanelViewHelper(mContext, mIconTextSpacing);
             mOverflowPanel = createOverflowPanel();
 
             // Animation. Need views.
@@ -513,6 +530,32 @@
         }
 
         /**
+         * Makes this toolbar "outside touchable" and sets the onDismissListener.
+         * This will take effect the next time the toolbar is re-shown.
+         *
+         * @param outsideTouchable if true, the popup will be made "outside touchable" and
+         *      "non focusable". The reverse will happen if false.
+         * @param onDismiss
+         *
+         * @return true if the "outsideTouchable" setting was modified. Otherwise returns false
+         *
+         * @see PopupWindow#setOutsideTouchable(boolean)
+         * @see PopupWindow#setFocusable(boolean)
+         * @see PopupWindow.OnDismissListener
+         */
+        public boolean setOutsideTouchable(
+                boolean outsideTouchable, @Nullable PopupWindow.OnDismissListener onDismiss) {
+            boolean ret = false;
+            if (mPopupWindow.isOutsideTouchable() ^ outsideTouchable) {
+                mPopupWindow.setOutsideTouchable(outsideTouchable);
+                mPopupWindow.setFocusable(!outsideTouchable);
+                ret = true;
+            }
+            mPopupWindow.setOnDismissListener(onDismiss);
+            return ret;
+        }
+
+        /**
          * Lays out buttons for the specified menu items.
          * Requires a subsequent call to {@link #show()} to show the items.
          */
@@ -1573,10 +1616,9 @@
 
             private final Context mContext;
 
-            public OverflowPanelViewHelper(Context context) {
+            public OverflowPanelViewHelper(Context context, int iconTextSpacing) {
                 mContext = Preconditions.checkNotNull(context);
-                mIconTextSpacing = context.getResources()
-                        .getDimensionPixelSize(R.dimen.floating_toolbar_menu_button_side_padding);
+                mIconTextSpacing = iconTextSpacing;
                 mSidePadding = context.getResources()
                         .getDimensionPixelSize(R.dimen.floating_toolbar_overflow_side_padding);
                 mCalculator = createMenuButton(null);
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index 7e63adc..591f15f 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -45,6 +45,7 @@
     boolean checkVoldPassword(int userId);
     boolean havePattern(int userId);
     boolean havePassword(int userId);
+    byte[] getHashFactor(String currentCredential, int userId);
     void setSeparateProfileChallengeEnabled(int userId, boolean enabled, String managedUserPassword);
     boolean getSeparateProfileChallengeEnabled(int userId);
     void registerStrongAuthTracker(in IStrongAuthTracker tracker);
diff --git a/core/java/com/android/internal/widget/ImageFloatingTextView.java b/core/java/com/android/internal/widget/ImageFloatingTextView.java
index 09f7282..1e7c11e 100644
--- a/core/java/com/android/internal/widget/ImageFloatingTextView.java
+++ b/core/java/com/android/internal/widget/ImageFloatingTextView.java
@@ -47,6 +47,7 @@
     private boolean mFirstMeasure = true;
     private int mLayoutMaxLines = -1;
     private boolean mBlockLayouts;
+    private int mImageEndMargin;
 
     public ImageFloatingTextView(Context context) {
         this(context, null);
@@ -98,13 +99,11 @@
         }
 
         // we set the endmargin on the requested number of lines.
-        int endMargin = getContext().getResources().getDimensionPixelSize(
-                R.dimen.notification_content_picture_margin);
         int[] margins = null;
         if (mIndentLines > 0) {
             margins = new int[mIndentLines + 1];
             for (int i = 0; i < mIndentLines; i++) {
-                margins[i] = endMargin;
+                margins[i] = mImageEndMargin;
             }
         }
         if (mResolvedDirection == LAYOUT_DIRECTION_RTL) {
@@ -116,6 +115,11 @@
         return builder.build();
     }
 
+    @RemotableViewMethod
+    public void setImageEndMargin(int imageEndMargin) {
+        mImageEndMargin = imageEndMargin;
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         int height = MeasureSpec.getSize(heightMeasureSpec);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index d4ab426..7c339fb 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -66,8 +66,10 @@
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
+import java.util.StringJoiner;
 /**
  * Utilities for the lock pattern and its settings.
  */
@@ -165,6 +167,7 @@
 
     public static final String SYNTHETIC_PASSWORD_HANDLE_KEY = "sp-handle";
     public static final String SYNTHETIC_PASSWORD_ENABLED_KEY = "enable-sp";
+    private static final String HISTORY_DELIMITER = ",";
 
     private final Context mContext;
     private final ContentResolver mContentResolver;
@@ -507,31 +510,50 @@
     }
 
     /**
+     * Returns the password history hash factor, needed to check new password against password
+     * history with {@link #checkPasswordHistory(String, byte[], int)}
+     */
+    public byte[] getPasswordHistoryHashFactor(String currentPassword, int userId) {
+        try {
+            return getLockSettings().getHashFactor(currentPassword, userId);
+        } catch (RemoteException e) {
+            Log.e(TAG, "failed to get hash factor", e);
+            return null;
+        }
+    }
+
+    /**
      * Check to see if a password matches any of the passwords stored in the
      * password history.
      *
-     * @param password The password to check.
+     * @param passwordToCheck The password to check.
+     * @param hashFactor Hash factor of the current user returned from
+     *        {@link ILockSettings#getHashFactor}
      * @return Whether the password matches any in the history.
      */
-    public boolean checkPasswordHistory(String password, int userId) {
-        String passwordHashString = new String(
-                passwordToHash(password, userId), StandardCharsets.UTF_8);
-        String passwordHistory = getString(PASSWORD_HISTORY_KEY, userId);
-        if (passwordHistory == null) {
+    public boolean checkPasswordHistory(String passwordToCheck, byte[] hashFactor, int userId) {
+        if (TextUtils.isEmpty(passwordToCheck)) {
+            Log.e(TAG, "checkPasswordHistory: empty password");
             return false;
         }
-        // Password History may be too long...
-        int passwordHashLength = passwordHashString.length();
+        String passwordHistory = getString(PASSWORD_HISTORY_KEY, userId);
+        if (TextUtils.isEmpty(passwordHistory)) {
+            return false;
+        }
         int passwordHistoryLength = getRequestedPasswordHistoryLength(userId);
         if(passwordHistoryLength == 0) {
             return false;
         }
-        int neededPasswordHistoryLength = passwordHashLength * passwordHistoryLength
-                + passwordHistoryLength - 1;
-        if (passwordHistory.length() > neededPasswordHistoryLength) {
-            passwordHistory = passwordHistory.substring(0, neededPasswordHistoryLength);
+        String legacyHash = legacyPasswordToHash(passwordToCheck, userId);
+        String passwordHash = passwordToHistoryHash(passwordToCheck, hashFactor, userId);
+        String[] history = passwordHistory.split(HISTORY_DELIMITER);
+        // Password History may be too long...
+        for (int i = 0; i < Math.min(passwordHistoryLength, history.length); i++) {
+            if (history[i].equals(legacyHash) || history[i].equals(passwordHash)) {
+                return true;
+            }
         }
-        return passwordHistory.contains(passwordHashString);
+        return false;
     }
 
     /**
@@ -830,6 +852,7 @@
         updateEncryptionPasswordIfNeeded(password,
                 PasswordMetrics.computeForPassword(password).quality, userHandle);
         updatePasswordHistory(password, userHandle);
+        onAfterChangingPassword(userHandle);
     }
 
     /**
@@ -852,8 +875,15 @@
         }
     }
 
+    /**
+     * Store the hash of the *current* password in the password history list, if device policy
+     * enforces password history requirement.
+     */
     private void updatePasswordHistory(String password, int userHandle) {
-
+        if (TextUtils.isEmpty(password)) {
+            Log.e(TAG, "checkPasswordHistory: empty password");
+            return;
+        }
         // Add the password to the password history. We assume all
         // password hashes have the same length for simplicity of implementation.
         String passwordHistory = getString(PASSWORD_HISTORY_KEY, userHandle);
@@ -864,16 +894,25 @@
         if (passwordHistoryLength == 0) {
             passwordHistory = "";
         } else {
-            byte[] hash = passwordToHash(password, userHandle);
-            passwordHistory = new String(hash, StandardCharsets.UTF_8) + "," + passwordHistory;
-            // Cut it to contain passwordHistoryLength hashes
-            // and passwordHistoryLength -1 commas.
-            passwordHistory = passwordHistory.substring(0, Math.min(hash.length
-                    * passwordHistoryLength + passwordHistoryLength - 1, passwordHistory
-                    .length()));
+            final byte[] hashFactor = getPasswordHistoryHashFactor(password, userHandle);
+            String hash = passwordToHistoryHash(password, hashFactor, userHandle);
+            if (hash == null) {
+                Log.e(TAG, "Compute new style password hash failed, fallback to legacy style");
+                hash = legacyPasswordToHash(password, userHandle);
+            }
+            if (TextUtils.isEmpty(passwordHistory)) {
+                passwordHistory = hash;
+            } else {
+                String[] history = passwordHistory.split(HISTORY_DELIMITER);
+                StringJoiner joiner = new StringJoiner(HISTORY_DELIMITER);
+                joiner.add(hash);
+                for (int i = 0; i < passwordHistoryLength - 1 && i < history.length; i++) {
+                    joiner.add(history[i]);
+                }
+                passwordHistory = joiner.toString();
+            }
         }
         setString(PASSWORD_HISTORY_KEY, passwordHistory, userHandle);
-        onAfterChangingPassword(userHandle);
     }
 
     /**
@@ -1098,7 +1137,7 @@
         return Long.toHexString(salt);
     }
 
-    /*
+    /**
      * Generate a hash for the given password. To avoid brute force attacks, we use a salted hash.
      * Not the most secure, but it is at least a second level of protection. First level is that
      * the file is in a location only readable by the system process.
@@ -1107,7 +1146,7 @@
      *
      * @return the hash of the pattern in a byte array.
      */
-    public byte[] passwordToHash(String password, int userId) {
+    public String legacyPasswordToHash(String password, int userId) {
         if (password == null) {
             return null;
         }
@@ -1122,7 +1161,24 @@
             System.arraycopy(md5, 0, combined, sha1.length, md5.length);
 
             final char[] hexEncoded = HexEncoding.encode(combined);
-            return new String(hexEncoded).getBytes(StandardCharsets.UTF_8);
+            return new String(hexEncoded);
+        } catch (NoSuchAlgorithmException e) {
+            throw new AssertionError("Missing digest algorithm: ", e);
+        }
+    }
+
+    /**
+     * Hash the password for password history check purpose.
+     */
+    private String passwordToHistoryHash(String passwordToHash, byte[] hashFactor, int userId) {
+        if (TextUtils.isEmpty(passwordToHash) || hashFactor == null) {
+            return null;
+        }
+        try {
+            MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
+            sha256.update(hashFactor);
+            sha256.update((passwordToHash + getSalt(userId)).getBytes());
+            return new String(HexEncoding.encode(sha256.digest()));
         } catch (NoSuchAlgorithmException e) {
             throw new AssertionError("Missing digest algorithm: ", e);
         }
@@ -1571,6 +1627,7 @@
 
             updateEncryptionPasswordIfNeeded(credential, quality, userId);
             updatePasswordHistory(credential, userId);
+            onAfterChangingPassword(userId);
         } else {
             if (!TextUtils.isEmpty(credential)) {
                 throw new IllegalArgumentException("password must be emtpy for NONE type");
diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java
index 07d78fe..3f73237 100644
--- a/core/java/com/android/internal/widget/MessagingGroup.java
+++ b/core/java/com/android/internal/widget/MessagingGroup.java
@@ -22,6 +22,8 @@
 import android.annotation.StyleRes;
 import android.app.Person;
 import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Icon;
@@ -29,6 +31,7 @@
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.Pools;
+import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -36,6 +39,7 @@
 import android.view.ViewTreeObserver;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
+import android.widget.ProgressBar;
 import android.widget.RemoteViews;
 
 import com.android.internal.R;
@@ -58,6 +62,7 @@
     private CharSequence mAvatarName = "";
     private Icon mAvatarIcon;
     private int mTextColor;
+    private int mSendingTextColor;
     private List<MessagingMessage> mMessages;
     private ArrayList<MessagingMessage> mAddedMessages = new ArrayList<>();
     private boolean mFirstLayout;
@@ -69,6 +74,8 @@
     private MessagingImageMessage mIsolatedMessage;
     private boolean mTransformingImages;
     private Point mDisplaySize = new Point();
+    private ProgressBar mSendingSpinner;
+    private View mSendingSpinnerContainer;
 
     public MessagingGroup(@NonNull Context context) {
         super(context);
@@ -96,6 +103,8 @@
         mSenderName.addOnLayoutChangeListener(MessagingLayout.MESSAGING_PROPERTY_ANIMATOR);
         mAvatarView = findViewById(R.id.message_icon);
         mImageContainer = findViewById(R.id.messaging_group_icon_container);
+        mSendingSpinner = findViewById(R.id.messaging_group_sending_progress);
+        mSendingSpinnerContainer = findViewById(R.id.messaging_group_sending_progress_container);
         DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
         mDisplaySize.x = displayMetrics.widthPixels;
         mDisplaySize.y = displayMetrics.heightPixels;
@@ -139,17 +148,37 @@
         mAvatarView.setVisibility(VISIBLE);
         mSenderName.setVisibility(VISIBLE);
         mTextColor = getNormalTextColor();
+        mSendingTextColor = calculateSendingTextColor();
+    }
+
+    public void setSending(boolean sending) {
+        int visibility = sending ? View.VISIBLE : View.GONE;
+        if (mSendingSpinnerContainer.getVisibility() != visibility) {
+            mSendingSpinnerContainer.setVisibility(visibility);
+            updateMessageColor();
+        }
     }
 
     private int getNormalTextColor() {
         return mContext.getColor(R.color.notification_secondary_text_color_light);
     }
 
+    private int calculateSendingTextColor() {
+        TypedValue alphaValue = new TypedValue();
+        mContext.getResources().getValue(
+                R.dimen.notification_secondary_text_disabled_alpha, alphaValue, true);
+        float alpha = alphaValue.getFloat();
+        return Color.valueOf(
+                Color.red(mTextColor),
+                Color.green(mTextColor),
+                Color.blue(mTextColor),
+                alpha).toArgb();
+    }
+
     public void setAvatar(Icon icon) {
         mAvatarIcon = icon;
         mAvatarView.setImageIcon(icon);
         mAvatarSymbol = "";
-        mLayoutColor = 0;
         mAvatarName = "";
     }
 
@@ -321,13 +350,26 @@
                 || layoutColor != mLayoutColor) {
             setAvatar(cachedIcon);
             mAvatarSymbol = avatarSymbol;
-            mLayoutColor = layoutColor;
+            setLayoutColor(layoutColor);
             mAvatarName = avatarName;
         }
     }
 
     public void setLayoutColor(int layoutColor) {
-        mLayoutColor = layoutColor;
+        if (layoutColor != mLayoutColor){
+            mLayoutColor = layoutColor;
+            mSendingSpinner.setIndeterminateTintList(ColorStateList.valueOf(mLayoutColor));
+        }
+    }
+
+    private void updateMessageColor() {
+        if (mMessages != null) {
+            int color = mSendingSpinnerContainer.getVisibility() == View.VISIBLE
+                    ? mSendingTextColor : mTextColor;
+            for (MessagingMessage message : mMessages) {
+                message.setColor(message.getMessage().isRemoteInputHistory() ? color : mTextColor);
+            }
+        }
     }
 
     public void setMessages(List<MessagingMessage> group) {
@@ -336,7 +378,6 @@
         MessagingImageMessage isolatedMessage = null;
         for (int messageIndex = 0; messageIndex < group.size(); messageIndex++) {
             MessagingMessage message = group.get(messageIndex);
-            message.setColor(mTextColor);
             if (message.getGroup() != this) {
                 message.setMessagingGroup(this);
                 mAddedMessages.add(message);
@@ -375,7 +416,14 @@
             mImageContainer.removeAllViews();
         }
         mIsolatedMessage = isolatedMessage;
+        updateImageContainerVisibility();
         mMessages = group;
+        updateMessageColor();
+    }
+
+    private void updateImageContainerVisibility() {
+        mImageContainer.setVisibility(mIsolatedMessage != null && mImagesAtEnd
+                ? View.VISIBLE : View.GONE);
     }
 
     /**
@@ -477,7 +525,7 @@
     public void setDisplayImagesAtEnd(boolean atEnd) {
         if (mImagesAtEnd != atEnd) {
             mImagesAtEnd = atEnd;
-            mImageContainer.setVisibility(atEnd ? View.VISIBLE : View.GONE);
+            updateImageContainerVisibility();
         }
     }
 
diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java
index f8236c7..df20e63 100644
--- a/core/java/com/android/internal/widget/MessagingLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLayout.java
@@ -149,7 +149,9 @@
         }
         addRemoteInputHistoryToMessages(newMessages,
                 extras.getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY));
-        bind(newMessages, newHistoricMessages);
+        boolean showSpinner =
+                extras.getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false);
+        bind(newMessages, newHistoricMessages, showSpinner);
     }
 
     private void addRemoteInputHistoryToMessages(
@@ -161,17 +163,18 @@
         for (int i = remoteInputHistory.length - 1; i >= 0; i--) {
             CharSequence message = remoteInputHistory[i];
             newMessages.add(new Notification.MessagingStyle.Message(
-                    message, 0, (Person) null));
+                    message, 0, (Person) null, true /* remoteHistory */));
         }
     }
 
     private void bind(List<Notification.MessagingStyle.Message> newMessages,
-            List<Notification.MessagingStyle.Message> newHistoricMessages) {
+            List<Notification.MessagingStyle.Message> newHistoricMessages,
+            boolean showSpinner) {
 
         List<MessagingMessage> historicMessages = createMessages(newHistoricMessages,
                 true /* isHistoric */);
         List<MessagingMessage> messages = createMessages(newMessages, false /* isHistoric */);
-        addMessagesToGroups(historicMessages, messages);
+        addMessagesToGroups(historicMessages, messages, showSpinner);
 
         // Let's remove the remaining messages
         mMessages.forEach(REMOVE_MESSAGE);
@@ -308,7 +311,7 @@
     }
 
     private void addMessagesToGroups(List<MessagingMessage> historicMessages,
-            List<MessagingMessage> messages) {
+            List<MessagingMessage> messages, boolean showSpinner) {
         // Let's first find our groups!
         List<List<MessagingMessage>> groups = new ArrayList<>();
         List<Person> senders = new ArrayList<>();
@@ -317,11 +320,11 @@
         findGroups(historicMessages, messages, groups, senders);
 
         // Let's now create the views and reorder them accordingly
-        createGroupViews(groups, senders);
+        createGroupViews(groups, senders, showSpinner);
     }
 
     private void createGroupViews(List<List<MessagingMessage>> groups,
-            List<Person> senders) {
+            List<Person> senders, boolean showSpinner) {
         mGroups.clear();
         for (int groupIndex = 0; groupIndex < groups.size(); groupIndex++) {
             List<MessagingMessage> group = groups.get(groupIndex);
@@ -346,6 +349,7 @@
                 nameOverride = mNameReplacement;
             }
             newGroup.setSender(sender, nameOverride);
+            newGroup.setSending(groupIndex == (groups.size() - 1) && showSpinner);
             mGroups.add(newGroup);
 
             if (mMessagingLinearLayout.indexOfChild(newGroup) != groupIndex) {
diff --git a/core/java/com/android/internal/widget/MessagingMessage.java b/core/java/com/android/internal/widget/MessagingMessage.java
index a2cc7cf..f0b6068 100644
--- a/core/java/com/android/internal/widget/MessagingMessage.java
+++ b/core/java/com/android/internal/widget/MessagingMessage.java
@@ -82,6 +82,9 @@
         if (!Objects.equals(message.getDataUri(), ownMessage.getDataUri())) {
             return false;
         }
+        if (message.isRemoteInputHistory() != ownMessage.isRemoteInputHistory()) {
+            return false;
+        }
         return true;
     }
 
diff --git a/core/java/com/android/internal/widget/NotificationActionListLayout.java b/core/java/com/android/internal/widget/NotificationActionListLayout.java
index 5729b53..9048f87 100644
--- a/core/java/com/android/internal/widget/NotificationActionListLayout.java
+++ b/core/java/com/android/internal/widget/NotificationActionListLayout.java
@@ -77,7 +77,6 @@
         int otherViews = 0;
         int notGoneChildren = 0;
 
-        View lastNotGoneChild = null;
         for (int i = 0; i < N; i++) {
             View c = getChildAt(i);
             if (c instanceof TextView) {
@@ -87,7 +86,6 @@
             }
             if (c.getVisibility() != GONE) {
                 notGoneChildren++;
-                lastNotGoneChild = c;
             }
         }
 
@@ -107,11 +105,8 @@
                 }
             }
         }
-        boolean centerAligned = (mGravity & Gravity.CENTER_HORIZONTAL) != 0;
-        boolean singleChildCentered = notGoneChildren == 1 && centerAligned;
-        boolean needsRegularMeasurement = notGoneChildren > 1 || singleChildCentered;
 
-        if (needsRegularMeasurement && needRebuild) {
+        if (needRebuild) {
             rebuildMeasureOrder(textViews, otherViews);
         }
 
@@ -123,7 +118,7 @@
         int usedWidth = 0;
 
         int measuredChildren = 0;
-        for (int i = 0; i < N && needsRegularMeasurement; i++) {
+        for (int i = 0; i < N; i++) {
             // Measure shortest children first. To avoid measuring twice, we approximate by looking
             // at the text length.
             View c;
@@ -156,25 +151,6 @@
             measuredChildren++;
         }
 
-        // Make sure to measure the last child full-width if we didn't use up the entire width,
-        // or we didn't measure yet because there's just one child.
-        if (lastNotGoneChild != null && !centerAligned && (constrained && usedWidth < innerWidth
-                || notGoneChildren == 1)) {
-            MarginLayoutParams lp = (MarginLayoutParams) lastNotGoneChild.getLayoutParams();
-            if (notGoneChildren > 1) {
-                // Need to make room, since we already measured this once.
-                usedWidth -= lastNotGoneChild.getMeasuredWidth() + lp.rightMargin + lp.leftMargin;
-            }
-
-            int originalWidth = lp.width;
-            lp.width = LayoutParams.MATCH_PARENT;
-            measureChildWithMargins(lastNotGoneChild, widthMeasureSpec, usedWidth,
-                    heightMeasureSpec, 0 /* usedHeight */);
-            lp.width = originalWidth;
-
-            usedWidth += lastNotGoneChild.getMeasuredWidth() + lp.rightMargin + lp.leftMargin;
-        }
-
         mTotalWidth = usedWidth + mPaddingRight + mPaddingLeft;
         setMeasuredDimension(resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                 resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec));
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index da494d4..21c769e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -726,7 +726,7 @@
         android:description="@string/permdesc_receiveMms"
         android:protectionLevel="dangerous" />
 
-    <!-- Allows an application to read previously received cell broadcast
+    <!-- @TestApi Allows an application to read previously received cell broadcast
          messages and to register a content observer to get notifications when
          a cell broadcast has been received and added to the database. For
          emergency alerts, the database is updated immediately after the
@@ -1424,6 +1424,13 @@
     <permission android:name="android.permission.NETWORK_SETTINGS"
         android:protectionLevel="signature" />
 
+    <!-- Allows SetupWizard to call methods in Networking services
+         <p>Not for use by any other third-party or privileged applications.
+         @hide This should only be used by SetupWizard.
+    -->
+    <permission android:name="android.permission.NETWORK_SETUP_WIZARD"
+        android:protectionLevel="signature|setup" />
+
     <!-- #SystemApi @hide Allows applications to access information about LoWPAN interfaces.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.ACCESS_LOWPAN_STATE"
@@ -3324,7 +3331,7 @@
     <permission android:name="android.permission.OBSERVE_APP_USAGE"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @hide @SystemApi Allows an application to change the app idle state of an app.
+    <!-- @hide @TestApi @SystemApi Allows an application to change the app idle state of an app.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CHANGE_APP_IDLE_STATE"
         android:protectionLevel="signature|privileged" />
@@ -3550,7 +3557,7 @@
     <permission android:name="android.permission.UPDATE_LOCK"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows an application to read the current set of notifications, including
+    <!-- @SystemApi @TestApi Allows an application to read the current set of notifications, including
          any metadata and intents attached.
          @hide -->
     <permission android:name="android.permission.ACCESS_NOTIFICATIONS"
diff --git a/core/res/res/anim-ldrtl/task_close_enter.xml b/core/res/res/anim-ldrtl/task_close_enter.xml
new file mode 100644
index 0000000..7abada3
--- /dev/null
+++ b/core/res/res/anim-ldrtl/task_close_enter.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ 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
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false"
+    android:zAdjustment="top"
+    android:showWallpaper="true">
+
+    <alpha
+        android:fromAlpha="1"
+        android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="67"
+        android:duration="217"/>
+
+    <translate
+        android:fromXDelta="105%"
+        android:toXDelta="0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/aggressive_ease"
+        android:startOffset="50"
+        android:duration="383"/>
+
+    <scale
+        android:fromXScale="1.0526"
+        android:toXScale="1"
+        android:fromYScale="1.0526"
+        android:toYScale="1"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="283"/>
+
+    <scale
+        android:fromXScale="0.95"
+        android:toXScale="1"
+        android:fromYScale="0.95"
+        android:toYScale="1"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:startOffset="283"
+        android:duration="317"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim-ldrtl/task_close_exit.xml b/core/res/res/anim-ldrtl/task_close_exit.xml
new file mode 100644
index 0000000..a017820
--- /dev/null
+++ b/core/res/res/anim-ldrtl/task_close_exit.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ 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
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false"
+    android:showWallpaper="true">
+
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="1"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="67"
+        android:duration="283"/>
+
+    <translate
+        android:fromXDelta="0"
+        android:toXDelta="-105%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/aggressive_ease"
+        android:startOffset="50"
+        android:duration="383"/>
+
+    <scale
+        android:fromXScale="1.0"
+        android:toXScale="0.95"
+        android:fromYScale="1.0"
+        android:toYScale="0.95"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="283"/>
+
+    <!-- This is needed to keep the animation running while task_open_enter completes -->
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="1.0"
+        android:duration="600"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim-ldrtl/task_open_enter.xml b/core/res/res/anim-ldrtl/task_open_enter.xml
new file mode 100644
index 0000000..0433664
--- /dev/null
+++ b/core/res/res/anim-ldrtl/task_open_enter.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ 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
+  -->
+<!-- This should in sync with task_open_enter_cross_profile_apps.xml -->
+<!-- This should in sync with cross_profile_apps_thumbnail_enter.xml -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false"
+    android:zAdjustment="top"
+    android:showWallpaper="true">
+
+    <alpha
+        android:fromAlpha="1"
+        android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="67"
+        android:duration="217"/>
+
+    <translate
+        android:fromXDelta="-105%"
+        android:toXDelta="0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/aggressive_ease"
+        android:startOffset="50"
+        android:duration="383"/>
+
+    <scale
+        android:fromXScale="1.0526"
+        android:toXScale="1"
+        android:fromYScale="1.0526"
+        android:toYScale="1"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="283"/>
+
+    <scale
+        android:fromXScale="0.95"
+        android:toXScale="1"
+        android:fromYScale="0.95"
+        android:toYScale="1"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:startOffset="283"
+        android:duration="317"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim-ldrtl/task_open_enter_cross_profile_apps.xml b/core/res/res/anim-ldrtl/task_open_enter_cross_profile_apps.xml
new file mode 100644
index 0000000..45ca80e
--- /dev/null
+++ b/core/res/res/anim-ldrtl/task_open_enter_cross_profile_apps.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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
+  -->
+<!-- This should in sync with task_open_enter.xml -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false"
+    android:zAdjustment="top"
+    android:showWallpaper="true">
+
+    <alpha
+        android:fromAlpha="1"
+        android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="67"
+        android:duration="217"/>
+
+    <translate
+        android:fromXDelta="-105%"
+        android:toXDelta="0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/aggressive_ease"
+        android:startOffset="50"
+        android:duration="383"/>
+
+    <scale
+        android:fromXScale="1.0526"
+        android:toXScale="1"
+        android:fromYScale="1.0526"
+        android:toYScale="1"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="283"/>
+
+    <scale
+        android:fromXScale="0.95"
+        android:toXScale="1"
+        android:fromYScale="0.95"
+        android:toYScale="1"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:startOffset="283"
+        android:duration="317"/>
+
+    <!-- To keep the transition around longer for the thumbnail, should be kept in sync with
+         cross_profile_apps_thumbmail.xml -->
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="1.0"
+        android:startOffset="717"
+        android:duration="200"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim-ldrtl/task_open_exit.xml b/core/res/res/anim-ldrtl/task_open_exit.xml
new file mode 100644
index 0000000..f50494d
--- /dev/null
+++ b/core/res/res/anim-ldrtl/task_open_exit.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ 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
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false"
+    android:showWallpaper="true">
+
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="1"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="67"
+        android:duration="283"/>
+
+    <translate
+        android:fromXDelta="0"
+        android:toXDelta="105%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/aggressive_ease"
+        android:startOffset="50"
+        android:duration="383"/>
+
+    <scale
+        android:fromXScale="1.0"
+        android:toXScale="0.95"
+        android:fromYScale="1.0"
+        android:toYScale="0.95"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="283"/>
+
+    <!-- This is needed to keep the animation running while task_open_enter completes -->
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="1.0"
+        android:duration="600"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml
index c298b80..b059aa9 100644
--- a/core/res/res/anim/task_close_enter.xml
+++ b/core/res/res/anim/task_close_enter.xml
@@ -31,7 +31,7 @@
         android:duration="217"/>
 
     <translate
-        android:fromXDelta="105%"
+        android:fromXDelta="-105%"
         android:toXDelta="0"
         android:fillEnabled="true"
         android:fillBefore="true"
diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml
index 9394c57..c9ade22 100644
--- a/core/res/res/anim/task_close_exit.xml
+++ b/core/res/res/anim/task_close_exit.xml
@@ -32,7 +32,7 @@
 
     <translate
         android:fromXDelta="0"
-        android:toXDelta="-105%"
+        android:toXDelta="105%"
         android:fillEnabled="true"
         android:fillBefore="true"
         android:fillAfter="true"
diff --git a/core/res/res/anim/task_open_enter.xml b/core/res/res/anim/task_open_enter.xml
index e23201f..5c61859 100644
--- a/core/res/res/anim/task_open_enter.xml
+++ b/core/res/res/anim/task_open_enter.xml
@@ -33,7 +33,7 @@
         android:duration="217"/>
 
     <translate
-        android:fromXDelta="-105%"
+        android:fromXDelta="105%"
         android:toXDelta="0"
         android:fillEnabled="true"
         android:fillBefore="true"
diff --git a/core/res/res/anim/task_open_enter_cross_profile_apps.xml b/core/res/res/anim/task_open_enter_cross_profile_apps.xml
index defea08..6441047 100644
--- a/core/res/res/anim/task_open_enter_cross_profile_apps.xml
+++ b/core/res/res/anim/task_open_enter_cross_profile_apps.xml
@@ -33,7 +33,7 @@
         android:duration="217"/>
 
     <translate
-        android:fromXDelta="-105%"
+        android:fromXDelta="105%"
         android:toXDelta="0"
         android:fillEnabled="true"
         android:fillBefore="true"
diff --git a/core/res/res/anim/task_open_exit.xml b/core/res/res/anim/task_open_exit.xml
index c9ade22..9394c57 100644
--- a/core/res/res/anim/task_open_exit.xml
+++ b/core/res/res/anim/task_open_exit.xml
@@ -32,7 +32,7 @@
 
     <translate
         android:fromXDelta="0"
-        android:toXDelta="105%"
+        android:toXDelta="-105%"
         android:fillEnabled="true"
         android:fillBefore="true"
         android:fillAfter="true"
diff --git a/core/res/res/drawable/ic_dnd_block_notifications.xml b/core/res/res/drawable/ic_dnd_block_notifications.xml
new file mode 100644
index 0000000..4983614
--- /dev/null
+++ b/core/res/res/drawable/ic_dnd_block_notifications.xml
@@ -0,0 +1,30 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="40dp"
+        android:height="40dp"
+        android:viewportWidth="40.0"
+        android:viewportHeight="40.0">
+    <path
+        android:pathData="M34,20H2c-1.1,0 -2,-0.9 -2,-2V6c0,-1.1 0.9,-2 2,-2h32c1.1,0 2,0.9 2,2v12C36,19.1 35.1,20 34,20z"
+        android:fillColor="#FBBC04"/>
+    <path
+        android:pathData="M4.63,10L4.63,10c-0.83,0 -1.5,-0.67 -1.5,-1.5v0C3.12,7.67 3.8,7 4.62,7h0c0.82,0 1.5,0.67 1.5,1.5v0C6.12,9.33 5.45,10 4.63,10z"
+        android:fillColor="#FFFFFF"/>
+    <path
+        android:pathData="M8.62,7.5h9.5v2h-9.5z"
+        android:fillColor="#FFFFFF"/>
+    <path
+        android:pathData="M3.12,15h24v2h-24z"
+        android:fillColor="#FFFFFF"/>
+    <path
+        android:pathData="M3.12,12h17.5v2h-17.5z"
+        android:fillColor="#FFFFFF"/>
+    <path
+        android:pathData="M33.59,6.41m-5.78,0a5.78,5.78 0,1 1,11.56 0a5.78,5.78 0,1 1,-11.56 0"
+        android:fillColor="#FFFFFF"/>
+    <path
+        android:pathData="M33.5,0C29.91,0 27,2.91 27,6.5s2.91,6.5 6.5,6.5S40,10.09 40,6.5S37.09,0 33.5,0zM33.5,11.7c-2.87,0 -5.2,-2.33 -5.2,-5.2s2.33,-5.2 5.2,-5.2s5.2,2.33 5.2,5.2S36.37,11.7 33.5,11.7z"
+        android:fillColor="#4285F4"/>
+    <path
+        android:pathData="M30.25,5.85h6.5v1.3h-6.5z"
+        android:fillColor="#4285F4"/>
+</vector>
diff --git a/core/res/res/drawable/ic_reply_notification.xml b/core/res/res/drawable/ic_reply_notification.xml
index 88b8c5b..a9864b0 100644
--- a/core/res/res/drawable/ic_reply_notification.xml
+++ b/core/res/res/drawable/ic_reply_notification.xml
@@ -13,15 +13,20 @@
   ~ 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="10dp"
-        android:height="10dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M10.0,9.0L10.0,5.0l-7.0,7.0 7.0,7.0l0.0,-4.1c5.0,0.0 8.5,1.6 11.0,5.1 -1.0,-5.0 -4.0,-10.0 -11.0,-11.0z"/>
-    <path
-        android:pathData="M0 0h24v24H0z"
-        android:fillColor="#00000000"/>
-</vector>
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+       android:inset="@dimen/notification_reply_inset">
+    <vector android:width="24dp"
+            android:height="24dp"
+            android:viewportWidth="24"
+            android:viewportHeight="24">
+
+        <path
+            android:fillColor="#000000"
+            android:strokeWidth="1"
+            android:pathData="M16,10 L6.83,10 L9,7.83 L10.41,6.42 L9,5 L3,11 L9,17 L10.41,15.59 L9,14.17 L6.83,12 L16,12 C17.65,12 19,13.35 19,15 L19,19 L21,19 L21,15 C21,12.24 18.76,10 16,10 Z" />
+        <path
+            android:fillColor="#000000"
+            android:strokeWidth="1"
+            android:pathData="M16,10 L6.83,10 L9,7.83 L10.41,6.42 L9,5 L3,11 L9,17 L10.41,15.59 L9,14.17 L6.83,12 L16,12 C17.65,12 19,13.35 19,15 L19,19 L21,19 L21,15 C21,12.24 18.76,10 16,10 Z" />
+    </vector>
+</inset>
diff --git a/core/res/res/drawable/ic_reply_notification_large.xml b/core/res/res/drawable/ic_reply_notification_large.xml
deleted file mode 100644
index e75afdd..0000000
--- a/core/res/res/drawable/ic_reply_notification_large.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<!--
-  ~ Copyright (C) 2017 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
-  -->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
-       android:inset="8dp">
-    <vector android:width="24dp"
-            android:height="24dp"
-            android:viewportHeight="24.0"
-            android:viewportWidth="24.0">
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M10.0,9.0L10.0,5.0l-7.0,7.0 7.0,7.0l0.0,-4.1c5.0,0.0 8.5,1.6 11.0,5.1 -1.0,-5.0 -4.0,-10.0 -11.0,-11.0z"/>
-        <path
-            android:fillColor="#00000000"
-            android:pathData="M0 0h24v24H0z"/>
-    </vector>
-</inset>
diff --git a/core/res/res/layout-television/autofill_save.xml b/core/res/res/layout-television/autofill_save.xml
new file mode 100644
index 0000000..ebd2dec
--- /dev/null
+++ b/core/res/res/layout-television/autofill_save.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- NOTE: outer layout is required to provide proper shadow. -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:id="@+id/autofill_save"
+        android:background="?android:attr/colorBackground"
+        android:layout_marginTop="32dp"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingStart="40dp"
+        android:paddingEnd="40dp"
+        android:paddingTop="40dp"
+        android:paddingBottom="40dp">
+
+        <LinearLayout
+            android:orientation="vertical"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_marginEnd="32dp">
+
+            <LinearLayout
+                android:orientation="horizontal"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginBottom="6dp">
+
+                <ImageView
+                    android:id="@+id/autofill_save_icon"
+                    android:scaleType="fitStart"
+                    android:layout_marginEnd="10dp"
+                    android:layout_gravity="center_vertical"
+                    android:layout_width="48dp"
+                    android:layout_height="48dp"/>
+                <TextView
+                    android:id="@+id/autofill_save_title"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/autofill_save_title"
+                    android:layout_gravity="center_vertical"
+                    android:textSize="24sp" />
+            </LinearLayout>
+
+            <com.android.server.autofill.ui.CustomScrollView
+                android:id="@+id/autofill_save_custom_subtitle"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="4dp"
+                android:visibility="gone"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="304dp"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <Button
+                android:id="@+id/autofill_save_no"
+                style="?attr/borderlessButtonStyle"
+                android:textAlignment="viewStart"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/autofill_save_no">
+            </Button>
+
+            <Button
+                android:id="@+id/autofill_save_yes"
+                style="?attr/borderlessButtonStyle"
+                android:textAlignment="viewStart"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/autofill_save_yes">
+            </Button>
+        </LinearLayout>
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/core/res/res/layout/autofill_dataset_picker.xml b/core/res/res/layout/autofill_dataset_picker.xml
index ef19f87..a88836e 100644
--- a/core/res/res/layout/autofill_dataset_picker.xml
+++ b/core/res/res/layout/autofill_dataset_picker.xml
@@ -14,8 +14,7 @@
      limitations under the License.
 -->
 
-<view  xmlns:android="http://schemas.android.com/apk/res/android"
-    class="com.android.server.autofill.ui.FillUi$AutofillFrameLayout"
+<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/autofill_dataset_picker"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
@@ -31,4 +30,4 @@
         android:visibility="gone">
     </ListView>
 
-</view>
+</FrameLayout>
diff --git a/core/res/res/layout/autofill_dataset_picker_fullscreen.xml b/core/res/res/layout/autofill_dataset_picker_fullscreen.xml
index 07298c1..1d2b5e5 100644
--- a/core/res/res/layout/autofill_dataset_picker_fullscreen.xml
+++ b/core/res/res/layout/autofill_dataset_picker_fullscreen.xml
@@ -14,35 +14,73 @@
      limitations under the License.
 -->
 
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/autofill_dataset_picker"
-    style="@style/AutofillDatasetPicker"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:background="?android:attr/windowBackground"
+    android:paddingStart="40dp"
+    android:paddingEnd="40dp"
+    android:paddingTop="40dp"
+    android:paddingBottom="40dp">
 
-    <TextView
-        android:layout_width="wrap_content"
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:text="@string/autofill_window_title"
-        android:layout_above="@+id/autofill_dataset_container"
-        android:layout_alignStart="@+id/autofill_dataset_container"
-        android:textSize="16sp"/>
+        android:layout_weight="1"
+        android:layout_marginEnd="32dp">
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="6dp"
+            >
+            <ImageView
+                android:id="@+id/autofill_dataset_icon"
+                android:scaleType="fitStart"
+                android:layout_marginEnd="10dp"
+                android:layout_gravity="center_vertical"
+                android:layout_width="48dp"
+                android:layout_height="48dp"/>
+            <TextView
+                android:id="@+id/autofill_dataset_title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:textSize="24sp" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/autofill_dataset_header"
+            android:visibility="gone"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"/>
+
+    </LinearLayout>
 
     <!-- autofill_container is the common parent for inserting authentication item or
-         autofill_dataset_list-->
-    <FrameLayout
-        android:id="@+id/autofill_dataset_container"
-        android:layout_width="wrap_content"
+         autofill_dataset_list, autofill_dataset_foolter-->
+    <LinearLayout
+        android:layout_width="304dp"
         android:layout_height="wrap_content"
-        android:layout_centerInParent="true">
+        android:id="@+id/autofill_dataset_picker"
+        android:orientation="vertical">
         <ListView
             android:id="@+id/autofill_dataset_list"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:clickable="true"
             android:divider="@null"
             android:drawSelectorOnTop="true"
             android:visibility="gone"/>
-    </FrameLayout>
+        <LinearLayout
+            android:id="@+id/autofill_dataset_footer"
+            android:visibility="gone"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"/>
+    </LinearLayout>
 
-</RelativeLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/autofill_dataset_picker_header_footer.xml b/core/res/res/layout/autofill_dataset_picker_header_footer.xml
index 048494a..093f035 100644
--- a/core/res/res/layout/autofill_dataset_picker_header_footer.xml
+++ b/core/res/res/layout/autofill_dataset_picker_header_footer.xml
@@ -14,8 +14,7 @@
      limitations under the License.
 -->
 
-<view  xmlns:android="http://schemas.android.com/apk/res/android"
-    class="com.android.server.autofill.ui.FillUi$AutofillFrameLayout"
+<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/autofill_dataset_picker"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
@@ -54,4 +53,4 @@
 
     </LinearLayout>
 
-</view>
+</FrameLayout>
diff --git a/core/res/res/layout/autofill_dataset_picker_header_footer_fullscreen.xml b/core/res/res/layout/autofill_dataset_picker_header_footer_fullscreen.xml
deleted file mode 100644
index 24b14a0..0000000
--- a/core/res/res/layout/autofill_dataset_picker_header_footer_fullscreen.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/autofill_dataset_picker"
-    style="@style/AutofillDatasetPicker"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="@string/autofill_window_title"
-        android:layout_above="@+id/autofill_dataset_container"
-        android:layout_alignStart="@+id/autofill_dataset_container"
-        android:textSize="16sp"/>
-
-    <!-- autofill_container is the common parent for inserting authentication item or
-         autofill_dataset_list-->
-    <FrameLayout
-        android:id="@+id/autofill_dataset_container"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerInParent="true">
-
-        <LinearLayout
-            xmlns:android="http://schemas.android.com/apk/res/android"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-
-            <LinearLayout
-                android:id="@+id/autofill_dataset_header"
-                android:visibility="gone"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:orientation="vertical"/>
-
-            <ListView
-                android:id="@+id/autofill_dataset_list"
-                android:layout_weight="1"
-                android:layout_width="fill_parent"
-                android:layout_height="0dp"
-                android:clickable="true"
-                android:divider="@null"
-                android:drawSelectorOnTop="true"
-                android:visibility="gone"/>
-
-            <LinearLayout
-                android:id="@+id/autofill_dataset_footer"
-                android:visibility="gone"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:orientation="vertical"/>
-
-        </LinearLayout>
-
-    </FrameLayout>
-
-</RelativeLayout>
diff --git a/core/res/res/layout/notification_material_action_tombstone.xml b/core/res/res/layout/notification_material_action_tombstone.xml
index 817f298..9fa7c6a 100644
--- a/core/res/res/layout/notification_material_action_tombstone.xml
+++ b/core/res/res/layout/notification_material_action_tombstone.xml
@@ -27,7 +27,7 @@
     android:singleLine="true"
     android:ellipsize="end"
     android:textAlignment="viewStart"
-    android:alpha="0.5"
+    android:alpha="@dimen/notification_action_disabled_alpha"
     android:enabled="false"
     android:background="@drawable/notification_material_action_background"
     />
diff --git a/core/res/res/layout/notification_material_reply_text.xml b/core/res/res/layout/notification_material_reply_text.xml
index 84603b0..dbf2dd0 100644
--- a/core/res/res/layout/notification_material_reply_text.xml
+++ b/core/res/res/layout/notification_material_reply_text.xml
@@ -30,6 +30,7 @@
             android:id="@+id/action_divider"
             android:layout_marginTop="@dimen/notification_content_margin"
             android:layout_marginBottom="@dimen/notification_content_margin"
+            android:layout_marginEnd="@dimen/notification_content_margin_end"
             android:background="@drawable/notification_template_divider" />
 
     <TextView
@@ -50,12 +51,31 @@
             android:textAppearance="@style/TextAppearance.Material.Notification.Reply"
             android:singleLine="true" />
 
-    <TextView
-            android:id="@+id/notification_material_reply_text_1"
+    <LinearLayout
+            android:id="@+id/notification_material_reply_text_1_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:layout_marginStart="@dimen/notification_content_margin_start"
+            android:layout_marginEnd="@dimen/notification_content_margin_end">
+        <TextView
+                android:id="@+id/notification_material_reply_text_1"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:layout_marginEnd="@dimen/notification_content_margin_end"
+                android:layout_gravity="center"
+                android:textAppearance="@style/TextAppearance.Material.Notification.Reply"
+                android:singleLine="true" />
+        <ProgressBar
+            android:id="@+id/notification_material_reply_progress"
+            android:layout_height="@dimen/messaging_group_sending_progress_size"
+            android:layout_width="@dimen/messaging_group_sending_progress_size"
+            android:layout_marginStart="@dimen/notification_content_margin_start"
             android:layout_marginEnd="@dimen/notification_content_margin_end"
-            android:textAppearance="@style/TextAppearance.Material.Notification.Reply"
-            android:singleLine="true" />
+            android:layout_gravity="center"
+            android:indeterminate="true"
+            style="?android:attr/progressBarStyleSmall" />
+    </LinearLayout>
 
 </LinearLayout>
diff --git a/core/res/res/layout/notification_template_material_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml
index 3a6f573..d1861d9 100644
--- a/core/res/res/layout/notification_template_material_big_text.xml
+++ b/core/res/res/layout/notification_template_material_big_text.xml
@@ -53,10 +53,10 @@
                 android:layout_marginTop="@dimen/notification_progress_margin_top"
                 android:layout_marginBottom="6dp"/>
             <com.android.internal.widget.ImageFloatingTextView android:id="@+id/big_text"
+                style="@style/Widget.Material.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="@dimen/notification_text_margin_top"
-                android:textAppearance="@style/TextAppearance.Material.Notification"
                 android:singleLine="false"
                 android:gravity="top"
                 android:visibility="gone"
diff --git a/core/res/res/layout/notification_template_material_inbox.xml b/core/res/res/layout/notification_template_material_inbox.xml
index 23d8799..d6f0e1d 100644
--- a/core/res/res/layout/notification_template_material_inbox.xml
+++ b/core/res/res/layout/notification_template_material_inbox.xml
@@ -53,7 +53,7 @@
                 android:layout_marginTop="@dimen/notification_progress_margin_top"
                 android:layout_marginBottom="2dp"/>
             <TextView android:id="@+id/inbox_text0"
-                android:textAppearance="@style/TextAppearance.Material.Notification"
+                style="@style/Widget.Material.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:singleLine="true"
@@ -62,7 +62,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text1"
-                android:textAppearance="@style/TextAppearance.Material.Notification"
+                style="@style/Widget.Material.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:singleLine="true"
@@ -71,7 +71,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text2"
-                android:textAppearance="@style/TextAppearance.Material.Notification"
+                style="@style/Widget.Material.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:singleLine="true"
@@ -80,7 +80,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text3"
-                android:textAppearance="@style/TextAppearance.Material.Notification"
+                style="@style/Widget.Material.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:singleLine="true"
@@ -89,7 +89,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text4"
-                android:textAppearance="@style/TextAppearance.Material.Notification"
+                style="@style/Widget.Material.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:singleLine="true"
@@ -98,7 +98,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text5"
-                android:textAppearance="@style/TextAppearance.Material.Notification"
+                style="@style/Widget.Material.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:singleLine="true"
@@ -107,7 +107,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text6"
-                android:textAppearance="@style/TextAppearance.Material.Notification"
+                style="@style/Widget.Material.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:singleLine="true"
diff --git a/core/res/res/layout/notification_template_material_messaging.xml b/core/res/res/layout/notification_template_material_messaging.xml
index 53514a3..10c7509 100644
--- a/core/res/res/layout/notification_template_material_messaging.xml
+++ b/core/res/res/layout/notification_template_material_messaging.xml
@@ -52,7 +52,9 @@
         <include layout="@layout/notification_template_smart_reply_container"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/notification_content_margin" />
+                android:layout_marginTop="@dimen/notification_content_margin"
+                android:layout_marginStart="@dimen/notification_content_margin_start"
+                android:layout_marginEnd="@dimen/notification_content_margin_end" />
         <include layout="@layout/notification_material_action_list" />
     </com.android.internal.widget.RemeasuringLinearLayout>
     <include layout="@layout/notification_template_right_icon"/>
diff --git a/core/res/res/layout/notification_template_messaging_group.xml b/core/res/res/layout/notification_template_messaging_group.xml
index bd1030e..9bdc495 100644
--- a/core/res/res/layout/notification_template_messaging_group.xml
+++ b/core/res/res/layout/notification_template_messaging_group.xml
@@ -41,6 +41,7 @@
             android:id="@+id/group_message_container"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_marginTop="@dimen/notification_text_margin_top"
             android:spacing="2dp"
             android:layout_weight="1"/>
     </com.android.internal.widget.RemeasuringLinearLayout>
@@ -50,4 +51,19 @@
         android:layout_height="@dimen/messaging_avatar_size"
         android:layout_marginStart="12dp"
         android:visibility="gone"/>
+    <FrameLayout
+        android:id="@+id/messaging_group_sending_progress_container"
+        android:layout_width="@dimen/messaging_group_sending_progress_size"
+        android:layout_height="@dimen/messaging_avatar_size"
+        android:layout_marginStart="12dp"
+        android:layout_gravity="top"
+        android:visibility="gone">
+        <ProgressBar
+            android:id="@+id/messaging_group_sending_progress"
+            android:layout_height="@dimen/messaging_group_sending_progress_size"
+            android:layout_width="@dimen/messaging_group_sending_progress_size"
+            android:layout_gravity="center"
+            android:indeterminate="true"
+            style="?android:attr/progressBarStyleSmall" />
+    </FrameLayout>
 </com.android.internal.widget.MessagingGroup>
diff --git a/core/res/res/layout/notification_template_part_line1.xml b/core/res/res/layout/notification_template_part_line1.xml
index ca35de3..6459bb8 100644
--- a/core/res/res/layout/notification_template_part_line1.xml
+++ b/core/res/res/layout/notification_template_part_line1.xml
@@ -31,7 +31,7 @@
         android:textAlignment="viewStart"
         />
     <TextView android:id="@+id/text_line_1"
-        android:textAppearance="@style/TextAppearance.Material.Notification"
+        style="@style/Widget.Material.Notification.Text"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:gravity="end|bottom"
diff --git a/core/res/res/layout/notification_template_right_icon.xml b/core/res/res/layout/notification_template_right_icon.xml
index 0b97e45..ee416ad 100644
--- a/core/res/res/layout/notification_template_right_icon.xml
+++ b/core/res/res/layout/notification_template_right_icon.xml
@@ -14,30 +14,29 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<!-- The view only has 8dp padding at the end instead of notification_content_margin_end,
+     since the reply icon has an inset of 8dp and we want it to visually start at the start of the
+     icon. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/right_icon_container"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_marginTop="@dimen/notification_content_margin_top"
+             android:layout_marginEnd="8dp"
              android:layout_gravity="top|end">
     <ImageView android:id="@+id/right_icon"
                android:layout_width="@dimen/notification_right_icon_size"
                android:layout_height="@dimen/notification_right_icon_size"
                android:layout_gravity="top|end"
-               android:layout_marginEnd="@dimen/notification_content_margin_end"
+               android:layout_marginEnd="8dp"
                android:scaleType="centerCrop"
                android:importantForAccessibility="no" />
-    <ImageButton android:id="@+id/reply_icon_action"
-               android:layout_width="16dp"
-               android:layout_height="16dp"
-               android:layout_gravity="top|end"
-               android:layout_marginTop="27dp"
-               android:layout_marginEnd="16dp"
-               android:background="@drawable/notification_reply_background"
-               android:src="@drawable/ic_reply_notification"
-               android:scaleType="center"
-               android:contentDescription="@string/notification_reply_button_accessibility"
-               visiblity="gone"/>
-</FrameLayout>
+    <ImageView android:id="@+id/reply_icon_action"
+                 android:layout_width="@dimen/notification_right_icon_size"
+                 android:layout_height="@dimen/notification_right_icon_size"
+                 android:layout_gravity="top|end"
+                 android:contentDescription="@string/notification_reply_button_accessibility"
+                 android:scaleType="centerCrop"
+                 android:src="@drawable/ic_reply_notification"/>
+</LinearLayout>
 
diff --git a/core/res/res/layout/notification_template_text.xml b/core/res/res/layout/notification_template_text.xml
index 68f34c8..3b27666 100644
--- a/core/res/res/layout/notification_template_text.xml
+++ b/core/res/res/layout/notification_template_text.xml
@@ -15,6 +15,7 @@
   ~ limitations under the License
   -->
 <com.android.internal.widget.ImageFloatingTextView xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/Widget.Material.Notification.Text"
     android:id="@+id/text"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
@@ -25,5 +26,4 @@
     android:gravity="top"
     android:singleLine="true"
     android:textAlignment="viewStart"
-    android:textAppearance="@style/TextAppearance.Material.Notification"
     />
diff --git a/core/res/res/values-television/dimens.xml b/core/res/res/values-television/dimens.xml
index aa56251..4c25225 100644
--- a/core/res/res/values-television/dimens.xml
+++ b/core/res/res/values-television/dimens.xml
@@ -20,8 +20,4 @@
      <item type="dimen" format="float" name="ambient_shadow_alpha">0.15</item>
      <item type="dimen" format="float" name="spot_shadow_alpha">0.3</item>
 
-     <!-- Max width/height of the autofill data set picker as a fraction of the screen width/height -->
-     <dimen name="autofill_dataset_picker_max_width">60%</dimen>
-     <dimen name="autofill_dataset_picker_max_height">70%</dimen>
-
 </resources>
diff --git a/core/res/res/values-television/themes_device_defaults.xml b/core/res/res/values-television/themes_device_defaults.xml
index e01caa3..e380a7b 100644
--- a/core/res/res/values-television/themes_device_defaults.xml
+++ b/core/res/res/values-television/themes_device_defaults.xml
@@ -16,4 +16,6 @@
 <resources>
     <style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
     <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
+    <style name="Theme.DeviceDefault.Autofill" parent="Theme.Material.Autofill" />
+    <style name="Theme.DeviceDefault.Autofill.Save" parent="Theme.Material.Autofill.Save" />
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 21c10ce..a83878b 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -339,13 +339,13 @@
                   then in code manually set your window's background to
                   null so it will not be drawn.
              </ul> -->
-        <attr name="windowBackground" format="reference" />
+        <attr name="windowBackground" format="reference|color" />
         <!-- Drawable to draw selectively within the inset areas when the windowBackground
              has been set to null. This protects against seeing visual garbage in the
              surface when the app has not drawn any content into this area. One example is
              when the user is resizing a window of an activity that has
              {@link android.R.attr#resizeableActivity} set for multi-window mode. -->
-        <attr name="windowBackgroundFallback" format="reference" />
+        <attr name="windowBackgroundFallback" format="reference|color" />
         <!-- Drawable to use as a frame around the window. -->
         <attr name="windowFrame" format="reference" />
         <!-- Flag indicating whether there should be no title on this window. -->
@@ -3419,10 +3419,16 @@
              constructor or 0. Arrays.hashCode(new Object[] {locale, mode, extraValue,
              isAuxiliary, overridesImplicitlyEnabledSubtype}) will be used instead. -->
         <attr name="subtypeId" format="integer"/>
-        <!-- Set to true if this subtype is ASCII capable. If the subtype is ASCII
+        <!-- Set to {@code true} if this subtype is ASCII capable. If the subtype is ASCII
              capable, it should guarantee that the user can input ASCII characters with
              this subtype. This is important because many password fields only allow
-             ASCII-characters. -->
+             ASCII-characters.
+
+             <p>Note: In order to avoid some known system issues on
+             {@link android.os.Build.VERSION_CODES#P} and prior OSes, you may want to include
+             {@code "AsciiCapable"} in
+             {@link android.R.styleable#InputMethod_Subtype_imeSubtypeExtraValue} when you specify
+             {@code true} to this attribute.-->
         <attr name="isAsciiCapable" format="boolean" />
         <!-- The BCP-47 Language Tag of the subtype.  This replaces
         {@link android.R.styleable#InputMethod_Subtype_imeSubtypeLocale}.  -->
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index da9fed0..095a632 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -137,6 +137,7 @@
     <color name="notification_primary_text_color_light">@color/primary_text_default_material_light</color>
     <color name="notification_primary_text_color_dark">@color/primary_text_default_material_dark</color>
     <color name="notification_secondary_text_color_light">@color/primary_text_default_material_light</color>
+    <item name="notification_secondary_text_disabled_alpha" format="float" type="dimen">0.30</item>
     <color name="notification_secondary_text_color_dark">@color/primary_text_default_material_dark</color>
     <color name="notification_default_color_dark">@color/primary_text_default_material_light</color>
     <color name="notification_default_color_light">#a3202124</color>
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index 3609fb8..2966aff 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -145,4 +145,8 @@
     <color name="datepicker_default_view_animator_color_material_light">#fff2f2f2</color>
     <color name="datepicker_default_view_animator_color_material_dark">#ff303030</color>
 
+    <!-- Autofill colors -->
+    <color name="autofill_background_material_dark">@color/material_blue_grey_900</color>
+    <color name="autofill_background_material_light">@color/material_grey_50</color>
+
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 50bbe26..5c80d4d2 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -647,6 +647,9 @@
     <!-- Boolean indicating associated network selection is allowed -->
     <bool translatable="false" name="config_wifi_framework_enable_associated_network_selection">true</bool>
 
+    <!-- Boolean indicating whether single radio chain scan results are to be used for network selection -->
+    <bool translatable="false" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection">false</bool>
+
     <!-- Boolean indicating that wifi only link configuratios that have exact same credentials (i.e PSK) -->
     <bool translatable="false" name="config_wifi_only_link_same_credential_configurations">true</bool>
 
@@ -945,6 +948,16 @@
         <!-- B y-intercept --> <item>-0.198650895</item>
     </string-array>
 
+
+    <!-- Indicate available ColorDisplayController.COLOR_MODE_xxx. -->
+    <integer-array name="config_availableColorModes">
+        <!-- Example:
+        <item>0</item>
+        <item>1</item>
+        <item>2</item>
+        -->
+    </integer-array>
+
     <!-- Indicate whether to allow the device to suspend when the screen is off
          due to the proximity sensor.  This resource should only be set to true
          if the sensor HAL correctly handles the proximity sensor as a wake-up source.
@@ -2850,6 +2863,9 @@
     <!-- For performance and storage reasons, limit the number of fingerprints per user -->
     <integer name="config_fingerprintMaxTemplatesPerUser">5</integer>
 
+    <!-- Specify if the fingerprint hardware support gestures-->
+    <bool name="config_fingerprintSupportsGestures">false</bool>
+
     <!-- This config is used to force VoiceInteractionService to start on certain low ram devices.
          It declares the package name of VoiceInteractionService that should be started. -->
     <string translatable="false" name="config_forceVoiceInteractionServicePackage"></string>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index a135b28..c7b65ef 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -162,19 +162,14 @@
     <!-- The margin on the start of the content view -->
     <dimen name="notification_content_margin_start">16dp</dimen>
 
-    <!-- The margin on the end of the content view
-        Keep in sync with notification_content_plus_picture_margin! -->
+    <!-- The margin on the end of the content view. -->
     <dimen name="notification_content_margin_end">16dp</dimen>
 
-    <!-- The margin on the end of the content view with a picture.
-        Keep in sync with notification_content_plus_picture_margin! -->
-    <dimen name="notification_content_picture_margin">56dp</dimen>
+    <!-- The inset of the reply icon. -->
+    <dimen name="notification_reply_inset">8dp</dimen>
 
-    <!-- The margin on the end of the content view with a picture, plus the standard
-        content end margin.
-        Keep equal to (notification_content_picture_margin + notification_content_margin_end)!
-    -->
-    <dimen name="notification_content_plus_picture_margin_end">72dp</dimen>
+    <!-- The margin for text at the end of the image view for media notifications -->
+    <dimen name="notification_media_image_margin_end">72dp</dimen>
 
     <!-- The additional margin on the sides of the ambient view. -->
     <dimen name="notification_extra_margin_ambient">16dp</dimen>
@@ -212,6 +207,9 @@
     <!-- The bottom padding for the notification header -->
     <dimen name="notification_header_padding_bottom">16dp</dimen>
 
+    <!-- The margin at the top of the notification header when dozing. -->
+    <dimen name="notification_header_margin_top_ambient">3dp</dimen>
+
     <!-- The margin at the bottom of the notification header. -->
     <dimen name="notification_header_margin_bottom">0dp</dimen>
 
@@ -536,7 +534,7 @@
     <dimen name="floating_toolbar_menu_image_width">24dp</dimen>
     <dimen name="floating_toolbar_menu_image_button_width">56dp</dimen>
     <dimen name="floating_toolbar_menu_image_button_vertical_padding">12dp</dimen>
-    <dimen name="floating_toolbar_menu_button_side_padding">8dp</dimen>
+    <dimen name="floating_toolbar_menu_button_side_padding">11dp</dimen>
     <dimen name="floating_toolbar_overflow_image_button_width">60dp</dimen>
     <dimen name="floating_toolbar_overflow_side_padding">18dp</dimen>
     <dimen name="floating_toolbar_text_size">14sp</dimen>
@@ -547,6 +545,7 @@
     <dimen name="floating_toolbar_horizontal_margin">16dp</dimen>
     <dimen name="floating_toolbar_vertical_margin">8dp</dimen>
     <dimen name="content_rect_bottom_clip_allowance">20dp</dimen>
+    <dimen name="floating_toolbar_icon_text_spacing">8dp</dimen>
 
     <!-- Magnifier dimensions -->
     <dimen name="magnifier_width">100dp</dimen>
@@ -616,7 +615,9 @@
     <!-- The maximum width of a image in a media notification. The images will be reduced to that width in case they are bigger.-->
     <dimen name="notification_media_image_max_width">280dp</dimen>
     <!-- The size of the right icon -->
-    <dimen name="notification_right_icon_size">38dp</dimen>
+    <dimen name="notification_right_icon_size">36dp</dimen>
+    <!-- The alpha of a disabled notification button -->
+    <item type="dimen" format="float" name="notification_action_disabled_alpha">0.5</item>
 
     <!-- The maximum height of any image in a remote view. This is applied to all images in custom remoteviews. -->
     <dimen name="notification_custom_view_max_image_height_low_ram">208dp</dimen>
@@ -631,10 +632,12 @@
     <!-- The maximum width of a image in a media notification. The images will be reduced to that width in case they are bigger.-->
     <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">40dp</dimen>
+    <dimen name="notification_right_icon_size_low_ram">@dimen/notification_right_icon_size</dimen>
 
     <dimen name="messaging_avatar_size">@dimen/notification_right_icon_size</dimen>
 
+    <dimen name="messaging_group_sending_progress_size">24dp</dimen>
+
     <!-- Max width/height of the autofill data set picker as a fraction of the screen width/height -->
     <dimen name="autofill_dataset_picker_max_width">90%</dimen>
     <dimen name="autofill_dataset_picker_max_height">90%</dimen>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index c90a0df..47d04ed 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -128,6 +128,7 @@
   <item type="id" name="accessibilityActionContextClick" />
 
   <item type="id" name="remote_input_tag" />
+  <item type="id" name="pending_intent_tag" />
 
   <item type="id" name="cross_task_transition" />
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 395b269..b92052b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2196,8 +2196,8 @@
     <!-- Text to show in the auto complete drop down list on a text view when the WebView can auto fill the entire form but the user has not configured an AutoFill profile [CHAR-LIMIT=19] -->
     <string name="setup_autofill">Set up Autofill</string>
 
-    <!-- Title of fullscreen autofill window [CHAR-LIMIT=80] -->
-    <string name="autofill_window_title">Autofill</string>
+    <!-- Title of fullscreen autofill window, including the name of which autofill service it is using [CHAR-LIMIT=NONE] -->
+    <string name="autofill_window_title">Autofill with <xliff:g id="serviceName" example="MyPass">%1$s</xliff:g></string>
 
     <!-- String used to separate FirstName and LastName when writing out a local name
          e.g. John<separator>Smith [CHAR-LIMIT=NONE]-->
@@ -4514,7 +4514,10 @@
     <!-- Notification shown when device owner silently deletes a package [CHAR LIMIT=NONE] -->
     <string name="package_deleted_device_owner">Deleted by your admin</string>
 
-    <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description -->
+    <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, with a "learn more" link. -->
+    <string name="battery_saver_description_with_learn_more">To extend your battery life, Battery Saver turns off some device features and restricts apps. <annotation id="url">Learn More</annotation></string>
+
+    <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, without a "learn more" link. -->
     <string name="battery_saver_description">To extend your battery life, Battery Saver turns off some device features and restricts apps.</string>
 
     <!-- [CHAR_LIMIT=NONE] Data saver: Feature description -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 984461b..50a6ff3 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1487,13 +1487,19 @@
         <item name="successColor">@color/lock_pattern_view_success_color</item>
     </style>
 
-    <!-- @hide -->
+    <!-- @hide Autofill background for popup window (not for fullscreen) -->
     <style name="AutofillDatasetPicker">
         <item name="elevation">4dp</item>
         <item name="background">@drawable/autofill_dataset_picker_background</item>
     </style>
 
     <!-- @hide -->
+    <style name="AutofillHalfScreenAnimation">
+        <item name="android:windowEnterAnimation">@anim/slide_in_up</item>
+        <item name="android:windowExitAnimation">@anim/slide_out_down</item>
+    </style>
+
+    <!-- @hide -->
     <style name="AutofillSaveAnimation">
         <item name="android:windowEnterAnimation">@anim/slide_in_up</item>
         <item name="android:windowExitAnimation">@anim/slide_out_down</item>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index b8a046f..67b3c92 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -500,11 +500,15 @@
 
     <style name="Widget.Material.Notification.ProgressBar" parent="Widget.Material.Light.ProgressBar.Horizontal" />
 
-    <style name="Widget.Material.Notification.MessagingText" parent="Widget.Material.Light.TextView">
+    <style name="Widget.Material.Notification.Text" parent="Widget.Material.Light.TextView">
+        <item name="lineHeight">20sp</item>
+        <item name="textAppearance">@style/TextAppearance.Material.Notification</item>
+    </style>
+
+    <style name="Widget.Material.Notification.MessagingText" parent="Widget.Material.Notification.Text">
         <item name="layout_width">wrap_content</item>
         <item name="layout_height">wrap_content</item>
-        <item name="ellipsize">end</item>
-        <item name="textAppearance">@style/TextAppearance.Material.Notification</item>
+        <item name="ellipsize">end</item>z
     </style>
 
     <style name="Widget.Material.Notification.MessagingName" parent="Widget.Material.Light.TextView">
@@ -1305,6 +1309,7 @@
     </style>
 
     <style name="Notification.Header.Ambient">
+        <item name="layout_marginTop">@dimen/notification_header_margin_top_ambient</item>
         <item name="gravity">top|center_horizontal</item>
     </style>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b349932..c3ab1a6 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -334,6 +334,7 @@
   <java-symbol type="bool" name="config_windowShowCircularMask" />
   <java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" />
   <java-symbol type="bool" name="config_wifi_framework_enable_associated_network_selection" />
+  <java-symbol type="bool" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection" />
   <java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" />
   <java-symbol type="bool" name="config_wifi_framework_enable_voice_call_sar_tx_power_limit" />
   <java-symbol type="bool" name="config_wifi_enable_disconnection_debounce" />
@@ -662,6 +663,7 @@
   <java-symbol type="string" name="autofill_state_re" />
   <java-symbol type="string" name="autofill_this_form" />
   <java-symbol type="string" name="autofill_username_re" />
+  <java-symbol type="string" name="autofill_window_title" />
   <java-symbol type="string" name="autofill_zip_4_re" />
   <java-symbol type="string" name="autofill_zip_code" />
   <java-symbol type="string" name="autofill_zip_code_re" />
@@ -2406,6 +2408,7 @@
 
   <!-- Fingerprint config -->
   <java-symbol type="integer" name="config_fingerprintMaxTemplatesPerUser"/>
+  <java-symbol type="bool" name="config_fingerprintSupportsGestures"/>
 
   <!-- From various Material changes -->
   <java-symbol type="attr" name="titleTextAppearance" />
@@ -2552,6 +2555,7 @@
   <java-symbol type="drawable" name="ic_storage_48dp" />
   <java-symbol type="drawable" name="ic_usb_48dp" />
   <java-symbol type="drawable" name="ic_zen_24dp" />
+  <java-symbol type="drawable" name="ic_dnd_block_notifications" />
 
   <!-- Floating toolbar -->
   <java-symbol type="id" name="floating_toolbar_menu_item_image" />
@@ -2574,6 +2578,7 @@
   <java-symbol type="dimen" name="floating_toolbar_maximum_overflow_height" />
   <java-symbol type="dimen" name="floating_toolbar_horizontal_margin" />
   <java-symbol type="dimen" name="floating_toolbar_vertical_margin" />
+  <java-symbol type="dimen" name="floating_toolbar_icon_text_spacing" />
   <java-symbol type="dimen" name="content_rect_bottom_clip_allowance" />
   <java-symbol type="drawable" name="ft_avd_tooverflow" />
   <java-symbol type="drawable" name="ft_avd_toarrow" />
@@ -2615,6 +2620,7 @@
   <java-symbol type="id" name="actions_container" />
   <java-symbol type="id" name="smart_reply_container" />
   <java-symbol type="id" name="remote_input_tag" />
+  <java-symbol type="id" name="pending_intent_tag" />
 
   <java-symbol type="attr" name="seekBarDialogPreferenceStyle" />
   <java-symbol type="string" name="ext_media_status_removed" />
@@ -2668,8 +2674,10 @@
 
   <java-symbol type="id" name="notification_material_reply_container" />
   <java-symbol type="id" name="notification_material_reply_text_1" />
+  <java-symbol type="id" name="notification_material_reply_text_1_container" />
   <java-symbol type="id" name="notification_material_reply_text_2" />
   <java-symbol type="id" name="notification_material_reply_text_3" />
+  <java-symbol type="id" name="notification_material_reply_progress" />
 
   <java-symbol type="string" name="notification_hidden_text" />
   <java-symbol type="id" name="app_name_text" />
@@ -2689,7 +2697,7 @@
   <java-symbol type="dimen" name="notification_header_shrink_min_width" />
   <java-symbol type="dimen" name="notification_content_margin_start" />
   <java-symbol type="dimen" name="notification_content_margin_end" />
-  <java-symbol type="dimen" name="notification_content_picture_margin" />
+  <java-symbol type="dimen" name="notification_reply_inset" />
   <java-symbol type="dimen" name="notification_content_margin_top" />
   <java-symbol type="dimen" name="notification_content_margin" />
   <java-symbol type="dimen" name="notification_header_background_height" />
@@ -2873,8 +2881,9 @@
 
   <java-symbol type="bool" name="config_supportPreRebootSecurityLogs" />
 
-  <java-symbol type="dimen" name="notification_content_plus_picture_margin_end" />
+  <java-symbol type="dimen" name="notification_media_image_margin_end" />
   <java-symbol type="id" name="notification_action_list_margin_target" />
+  <java-symbol type="dimen" name="notification_action_disabled_alpha" />
 
   <!-- Pinner Service -->
   <java-symbol type="array" name="config_defaultPinnerServiceFiles" />
@@ -2956,6 +2965,7 @@
   <java-symbol type="integer" name="config_nightDisplayColorTemperatureMax" />
   <java-symbol type="array" name="config_nightDisplayColorTemperatureCoefficients" />
   <java-symbol type="array" name="config_nightDisplayColorTemperatureCoefficientsNative" />
+  <java-symbol type="array" name="config_availableColorModes" />
 
   <!-- Default first user restrictions -->
   <java-symbol type="array" name="config_defaultFirstUserRestrictions" />
@@ -3001,6 +3011,7 @@
   <java-symbol type="color" name="notification_secondary_text_color_dark" />
   <java-symbol type="color" name="notification_default_color_light" />
   <java-symbol type="color" name="notification_default_color_dark" />
+  <java-symbol type="dimen" name="notification_secondary_text_disabled_alpha" />
 
   <java-symbol type="string" name="app_category_game" />
   <java-symbol type="string" name="app_category_audio" />
@@ -3047,13 +3058,13 @@
   <java-symbol type="layout" name="autofill_dataset_picker"/>
   <java-symbol type="layout" name="autofill_dataset_picker_fullscreen"/>
   <java-symbol type="layout" name="autofill_dataset_picker_header_footer"/>
-  <java-symbol type="layout" name="autofill_dataset_picker_header_footer_fullscreen"/>
   <java-symbol type="id" name="autofill" />
-  <java-symbol type="id" name="autofill_dataset_container"/>
   <java-symbol type="id" name="autofill_dataset_footer"/>
   <java-symbol type="id" name="autofill_dataset_header"/>
+  <java-symbol type="id" name="autofill_dataset_icon" />
   <java-symbol type="id" name="autofill_dataset_list"/>
   <java-symbol type="id" name="autofill_dataset_picker"/>
+  <java-symbol type="id" name="autofill_dataset_title" />
   <java-symbol type="id" name="autofill_save_custom_subtitle" />
   <java-symbol type="id" name="autofill_save_icon" />
   <java-symbol type="id" name="autofill_save_no" />
@@ -3078,6 +3089,7 @@
   <java-symbol type="string" name="autofill_save_type_email_address" />
   <java-symbol type="drawable" name="autofill_dataset_picker_background" />
   <java-symbol type="style" name="AutofillDatasetPicker" />
+  <java-symbol type="style" name="AutofillHalfScreenAnimation" />
   <java-symbol type="style" name="AutofillSaveAnimation" />
   <java-symbol type="dimen" name="autofill_dataset_picker_max_width"/>
   <java-symbol type="dimen" name="autofill_dataset_picker_max_height"/>
@@ -3085,6 +3097,9 @@
   <java-symbol type="dimen" name="autofill_save_icon_max_size"/>
   <java-symbol type="integer" name="autofill_max_visible_datasets" />
 
+  <java-symbol type="style" name="Theme.DeviceDefault.Autofill" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Autofill.Save" />
+
   <java-symbol type="dimen" name="notification_big_picture_max_height"/>
   <java-symbol type="dimen" name="notification_big_picture_max_width"/>
   <java-symbol type="dimen" name="notification_media_image_max_width"/>
@@ -3254,13 +3269,15 @@
   <java-symbol type="id" name="clip_children_set_tag" />
   <java-symbol type="id" name="clip_to_padding_tag" />
   <java-symbol type="id" name="clip_children_tag" />
-  <java-symbol type="drawable" name="ic_reply_notification_large" />
   <java-symbol type="dimen" name="messaging_avatar_size" />
+  <java-symbol type="dimen" name="messaging_group_sending_progress_size" />
   <java-symbol type="dimen" name="messaging_image_rounding" />
   <java-symbol type="dimen" name="messaging_image_min_size" />
   <java-symbol type="dimen" name="messaging_image_max_height" />
   <java-symbol type="dimen" name="messaging_image_extra_spacing" />
   <java-symbol type="id" name="messaging_group_icon_container" />
+  <java-symbol type="id" name="messaging_group_sending_progress" />
+  <java-symbol type="id" name="messaging_group_sending_progress_container" />
 
   <java-symbol type="integer" name="config_stableDeviceDisplayWidth" />
   <java-symbol type="integer" name="config_stableDeviceDisplayHeight" />
@@ -3363,4 +3380,5 @@
   <java-symbol type="id" name="user_loading_avatar" />
   <java-symbol type="id" name="user_loading" />
 
+  <java-symbol type="string" name="battery_saver_description_with_learn_more" />
 </resources>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 92b2f33..14e5082 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -1673,6 +1673,15 @@
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
+
+    <!-- @hide DeviceDefault theme for the autofill FillUi -->
+    <style name="Theme.DeviceDefault.Autofill" parent="Theme.Material.Autofill.Light">
+    </style>
+
+    <!-- @hide DeviceDefault theme for the autofill SaveUi -->
+    <style name="Theme.DeviceDefault.Autofill.Save" parent="Theme.Material.Autofill.Save.Light">
+    </style>
+
     <!-- DeviceDefault theme for the default system theme.  -->
     <style name="Theme.DeviceDefault.System" parent="Theme.DeviceDefault.Light.DarkActionBar" />
 
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 9b633fc..b3e33d5 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -1417,4 +1417,25 @@
         <item name="colorPrimaryDark">@color/primary_dark_material_settings</item>
         <item name="colorSecondary">@color/secondary_material_settings</item>
     </style>
+
+    <!-- @hide -->
+    <style name="Theme.Material.Autofill" parent="Theme.Material">
+        <item name="colorBackground">@color/autofill_background_material_dark</item>
+    </style>
+
+    <!-- @hide -->
+    <style name="Theme.Material.Autofill.Light" parent="Theme.Material.Light">
+        <item name="colorBackground">@color/autofill_background_material_light</item>
+    </style>
+
+    <!-- @hide -->
+    <style name="Theme.Material.Autofill.Save" parent="Theme.Material.Panel">
+        <item name="colorBackground">@color/autofill_background_material_dark</item>
+    </style>
+
+    <!-- @hide -->
+    <style name="Theme.Material.Autofill.Save.Light" parent="Theme.Material.Light.Panel">
+        <item name="colorBackground">@color/autofill_background_material_light</item>
+    </style>
+
 </resources>
diff --git a/core/res/res/xml/default_zen_mode_config.xml b/core/res/res/xml/default_zen_mode_config.xml
index 3a71851..ba8173e 100644
--- a/core/res/res/xml/default_zen_mode_config.xml
+++ b/core/res/res/xml/default_zen_mode_config.xml
@@ -19,7 +19,7 @@
 
 <!-- Default configuration for zen mode.  See android.service.notification.ZenModeConfig. -->
 <zen version="7">
-    <allow alarms="true" media="true" system="false" calls="false" messages="false"
+    <allow alarms="true" media="true" system="false" calls="false" callsFrom="2" messages="false"
            reminders="false" events="false" />
 
     <!-- all visual effects that exist as of P -->
diff --git a/core/tests/coretests/res/layout/activity_text_view.xml b/core/tests/coretests/res/layout/activity_text_view.xml
index d5be87d..0568683 100644
--- a/core/tests/coretests/res/layout/activity_text_view.xml
+++ b/core/tests/coretests/res/layout/activity_text_view.xml
@@ -31,6 +31,8 @@
     <TextView
         android:id="@+id/nonselectable_textview"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content" />
+        android:layout_height="wrap_content"
+        android:focusable="false"
+        android:focusableInTouchMode="false" />
 
 </LinearLayout>
diff --git a/core/tests/coretests/res/values/styles.xml b/core/tests/coretests/res/values/styles.xml
index bcde4c1..dbc4626 100644
--- a/core/tests/coretests/res/values/styles.xml
+++ b/core/tests/coretests/res/values/styles.xml
@@ -31,4 +31,12 @@
     <style name="LayoutInDisplayCutoutModeNever">
         <item name="android:windowLayoutInDisplayCutoutMode">never</item>
     </style>
+    <style name="WindowBackgroundColorLiteral">
+        <item name="android:windowBackground">#00FF00</item>
+    </style>
+    <style name="WindowBackgroundFallbackColorLiteral">
+        <item name="android:windowBackground">@null</item>
+        <item name="android:colorBackground">@null</item>
+        <item name="android:windowBackgroundFallback">#0000FF</item>
+    </style>
 </resources>
diff --git a/core/tests/coretests/src/android/app/usage/EventListTest.java b/core/tests/coretests/src/android/app/usage/EventListTest.java
new file mode 100644
index 0000000..9dc0d43
--- /dev/null
+++ b/core/tests/coretests/src/android/app/usage/EventListTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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 android.app.usage;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Random;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class EventListTest {
+    private static final String TAG = EventListTest.class.getSimpleName();
+
+    private UsageEvents.Event getUsageEvent(long timeStamp) {
+        final UsageEvents.Event event = new UsageEvents.Event();
+        event.mTimeStamp = timeStamp;
+        return event;
+    }
+
+    private static String getListTimeStamps(EventList list) {
+        final StringBuilder builder = new StringBuilder("[");
+        for (int i = 0; i < list.size() - 1; i++) {
+            builder.append(list.get(i).mTimeStamp);
+            builder.append(", ");
+        }
+        builder.append(list.get(list.size() - 1).mTimeStamp);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    private static void assertSorted(EventList eventList) {
+        for (int i = 1; i < eventList.size(); i++) {
+            final long lastTimeStamp = eventList.get(i - 1).mTimeStamp;
+            if (eventList.get(i).mTimeStamp < lastTimeStamp) {
+                Log.e(TAG, "Unsorted timestamps in list: " + getListTimeStamps(eventList));
+                fail("Timestamp " + eventList.get(i).mTimeStamp + " at " + i
+                        + " follows larger timestamp " + lastTimeStamp);
+            }
+        }
+    }
+
+    @Test
+    public void testInsertsSortedRandom() {
+        final Random random = new Random(128);
+        final EventList listUnderTest = new EventList();
+        for (int i = 0; i < 100; i++) {
+            listUnderTest.insert(getUsageEvent(random.nextLong()));
+        }
+        assertSorted(listUnderTest);
+    }
+
+    @Test
+    public void testInsertsSortedWithDuplicates() {
+        final Random random = new Random(256);
+        final EventList listUnderTest = new EventList();
+        for (int i = 0; i < 10; i++) {
+            final long randomTimeStamp = random.nextLong();
+            for (int j = 0; j < 10; j++) {
+                listUnderTest.insert(getUsageEvent(randomTimeStamp));
+            }
+        }
+        assertSorted(listUnderTest);
+    }
+
+    @Test
+    public void testFirstIndexOnOrAfter() {
+        final EventList listUnderTest = new EventList();
+        listUnderTest.insert(getUsageEvent(2));
+        listUnderTest.insert(getUsageEvent(5));
+        listUnderTest.insert(getUsageEvent(5));
+        listUnderTest.insert(getUsageEvent(5));
+        listUnderTest.insert(getUsageEvent(8));
+        assertTrue(listUnderTest.firstIndexOnOrAfter(1) == 0);
+        assertTrue(listUnderTest.firstIndexOnOrAfter(2) == 0);
+        assertTrue(listUnderTest.firstIndexOnOrAfter(3) == 1);
+        assertTrue(listUnderTest.firstIndexOnOrAfter(4) == 1);
+        assertTrue(listUnderTest.firstIndexOnOrAfter(5) == 1);
+        assertTrue(listUnderTest.firstIndexOnOrAfter(6) == 4);
+        assertTrue(listUnderTest.firstIndexOnOrAfter(7) == 4);
+        assertTrue(listUnderTest.firstIndexOnOrAfter(8) == 4);
+        assertTrue(listUnderTest.firstIndexOnOrAfter(9) == listUnderTest.size());
+        assertTrue(listUnderTest.firstIndexOnOrAfter(100) == listUnderTest.size());
+
+        listUnderTest.clear();
+        assertTrue(listUnderTest.firstIndexOnOrAfter(5) == 0);
+        assertTrue(listUnderTest.firstIndexOnOrAfter(100) == 0);
+    }
+
+    @Test
+    public void testClear() {
+        final EventList listUnderTest = new EventList();
+        for (int i = 1; i <= 100; i++) {
+            listUnderTest.insert(getUsageEvent(i));
+        }
+        listUnderTest.clear();
+        assertEquals(0, listUnderTest.size());
+    }
+
+    @Test
+    public void testSize() {
+        final EventList listUnderTest = new EventList();
+        for (int i = 1; i <= 100; i++) {
+            listUnderTest.insert(getUsageEvent(i));
+        }
+        assertEquals(100, listUnderTest.size());
+    }
+}
diff --git a/core/tests/coretests/src/android/app/usage/TimeSparseArrayTest.java b/core/tests/coretests/src/android/app/usage/TimeSparseArrayTest.java
deleted file mode 100644
index db46740..0000000
--- a/core/tests/coretests/src/android/app/usage/TimeSparseArrayTest.java
+++ /dev/null
@@ -1,47 +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 android.app.usage;
-
-import static org.junit.Assert.assertTrue;
-
-import android.os.SystemClock;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class TimeSparseArrayTest {
-    @Test
-    public void testDuplicateKeysNotDropped() {
-        final TimeSparseArray<Integer> testTimeSparseArray = new TimeSparseArray<>();
-        final long key = SystemClock.elapsedRealtime();
-        for (int i = 0; i < 5; i++) {
-            testTimeSparseArray.put(key, i);
-        }
-        for (int i = 0; i < 5; i++) {
-            final int valueIndex = testTimeSparseArray.indexOfValue(i);
-            assertTrue("Value " + i + " not found; intended key: " + key , valueIndex >= 0);
-            final long keyForValue = testTimeSparseArray.keyAt(valueIndex);
-            assertTrue("Value " + i + " stored too far (at " + keyForValue + ") from intended key "
-                    + key, Math.abs(keyForValue - key) < 100);
-        }
-    }
-}
diff --git a/core/tests/coretests/src/android/os/VibrationEffectTest.java b/core/tests/coretests/src/android/os/VibrationEffectTest.java
index 9f50eea..ea778fd 100644
--- a/core/tests/coretests/src/android/os/VibrationEffectTest.java
+++ b/core/tests/coretests/src/android/os/VibrationEffectTest.java
@@ -50,6 +50,8 @@
 
     private static final VibrationEffect TEST_ONE_SHOT =
             VibrationEffect.createOneShot(TEST_TIMING, TEST_AMPLITUDE);
+    private static final VibrationEffect DEFAULT_ONE_SHOT =
+            VibrationEffect.createOneShot(TEST_TIMING, VibrationEffect.DEFAULT_AMPLITUDE);
     private static final VibrationEffect TEST_WAVEFORM =
             VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, -1);
 
@@ -104,6 +106,22 @@
     }
 
     @Test
+    public void testResolveOneShot() {
+        VibrationEffect.OneShot initial = (VibrationEffect.OneShot) DEFAULT_ONE_SHOT;
+        VibrationEffect.OneShot resolved = initial.resolve(239);
+        assertEquals(239, resolved.getAmplitude());
+    }
+
+    @Test
+    public void testResolveOneShotFailsWhenMaxAmplitudeAboveThreshold() {
+        try {
+            ((VibrationEffect.OneShot) TEST_ONE_SHOT).resolve(1000);
+            fail("Max amplitude above threshold, should throw IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
     public void testScaleWaveform() {
         VibrationEffect.Waveform scaled =
                 ((VibrationEffect.Waveform) TEST_WAVEFORM).scale(1.1f, 200);
@@ -120,6 +138,24 @@
         }
     }
 
+    @Test
+    public void testResolveWaveform() {
+        VibrationEffect.Waveform resolved =
+                ((VibrationEffect.Waveform) TEST_WAVEFORM).resolve(239);
+        assertEquals(255, resolved.getAmplitudes()[0]);
+        assertEquals(0, resolved.getAmplitudes()[1]);
+        assertEquals(239, resolved.getAmplitudes()[2]);
+    }
+
+    @Test
+    public void testResolveWaveformFailsWhenMaxAmplitudeAboveThreshold() {
+        try {
+            ((VibrationEffect.Waveform) TEST_WAVEFORM).resolve(1000);
+            fail("Max amplitude above threshold, should throw IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
 
     private Resources mockRingtoneResources() {
         return mockRingtoneResources(new String[] {
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 542266f..cfc7f9f 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -99,6 +99,7 @@
     private static final Set<String> BACKUP_BLACKLISTED_GLOBAL_SETTINGS =
             newHashSet(
                     Settings.Global.ACTIVITY_MANAGER_CONSTANTS,
+                    Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED,
                     Settings.Global.ADB_ENABLED,
                     Settings.Global.ADD_USERS_WHEN_LOCKED,
                     Settings.Global.AIRPLANE_MODE_ON,
diff --git a/core/tests/coretests/src/android/text/TextUtilsTest.java b/core/tests/coretests/src/android/text/TextUtilsTest.java
index e70b841..870d6b2 100644
--- a/core/tests/coretests/src/android/text/TextUtilsTest.java
+++ b/core/tests/coretests/src/android/text/TextUtilsTest.java
@@ -777,4 +777,12 @@
     public void testTrimToSizeThrowsExceptionForZeroSize() {
         TextUtils.trimToSize("abc", 0);
     }
+
+    @Test
+    public void length() {
+        assertEquals(0, TextUtils.length(null));
+        assertEquals(0, TextUtils.length(""));
+        assertEquals(2, TextUtils.length("  "));
+        assertEquals(6, TextUtils.length("Hello!"));
+    }
 }
diff --git a/core/tests/coretests/src/android/view/inputmethod/CursorAnchorInfoTest.java b/core/tests/coretests/src/android/view/inputmethod/CursorAnchorInfoTest.java
index ff3452c..0fd0136 100644
--- a/core/tests/coretests/src/android/view/inputmethod/CursorAnchorInfoTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/CursorAnchorInfoTest.java
@@ -28,7 +28,6 @@
 import android.graphics.Matrix;
 import android.graphics.RectF;
 import android.os.Parcel;
-import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.text.TextUtils;
@@ -40,7 +39,6 @@
 import java.util.Objects;
 
 @SmallTest
-@Presubmit
 @RunWith(AndroidJUnit4.class)
 public class CursorAnchorInfoTest {
     private static final float EPSILON = 0.0000001f;
diff --git a/core/tests/coretests/src/android/view/inputmethod/InputMethodInfoTest.java b/core/tests/coretests/src/android/view/inputmethod/InputMethodInfoTest.java
index 52df338..9edbf3e 100644
--- a/core/tests/coretests/src/android/view/inputmethod/InputMethodInfoTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/InputMethodInfoTest.java
@@ -26,7 +26,6 @@
 import android.content.pm.ServiceInfo;
 import android.os.Bundle;
 import android.os.Parcel;
-import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.LargeTest;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
@@ -37,7 +36,6 @@
 import org.junit.runner.RunWith;
 
 @LargeTest
-@Presubmit
 @RunWith(AndroidJUnit4.class)
 public class InputMethodInfoTest {
 
diff --git a/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeArrayTest.java b/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeArrayTest.java
index ff71c00..8df1848 100644
--- a/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeArrayTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeArrayTest.java
@@ -19,7 +19,6 @@
 import static org.junit.Assert.assertEquals;
 
 import android.os.Parcel;
-import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
@@ -30,7 +29,6 @@
 import java.util.ArrayList;
 
 @SmallTest
-@Presubmit
 @RunWith(AndroidJUnit4.class)
 public class InputMethodSubtypeArrayTest {
 
diff --git a/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java b/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java
index 2c85ce7..c76359e 100644
--- a/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/InputMethodSubtypeTest.java
@@ -23,7 +23,6 @@
 import static org.junit.Assert.assertTrue;
 
 import android.os.Parcel;
-import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
@@ -35,7 +34,6 @@
 import java.util.Objects;
 
 @SmallTest
-@Presubmit
 @RunWith(AndroidJUnit4.class)
 public class InputMethodSubtypeTest {
 
diff --git a/core/tests/coretests/src/android/view/inputmethod/SparseRectFArrayTest.java b/core/tests/coretests/src/android/view/inputmethod/SparseRectFArrayTest.java
index c7b5933..8c96b58 100644
--- a/core/tests/coretests/src/android/view/inputmethod/SparseRectFArrayTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/SparseRectFArrayTest.java
@@ -23,7 +23,6 @@
 
 import android.graphics.RectF;
 import android.os.Parcel;
-import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.inputmethod.SparseRectFArray.SparseRectFArrayBuilder;
@@ -34,7 +33,6 @@
 import java.util.Objects;
 
 @SmallTest
-@Presubmit
 @RunWith(AndroidJUnit4.class)
 public class SparseRectFArrayTest {
     // A test data for {@link SparseRectFArray}. null represents the gap of indices.
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
index b0593d2..e891fc9 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
@@ -18,11 +18,22 @@
 
 import static org.hamcrest.CoreMatchers.not;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
 import android.os.LocaleList;
 import android.service.textclassifier.TextClassifierService;
 import android.support.test.InstrumentationRegistry;
@@ -35,6 +46,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
 
 import java.util.Arrays;
 import java.util.Collections;
@@ -305,7 +317,6 @@
     public void testGetLocalTextClassifier() {
         assertTrue(mTcm.getTextClassifier(TextClassifier.LOCAL) instanceof TextClassifierImpl);
     }
-
     @Test
     public void testGetSystemTextClassifier() {
         assertTrue(
@@ -313,6 +324,48 @@
                 || mTcm.getTextClassifier(TextClassifier.SYSTEM) instanceof SystemTextClassifier);
     }
 
+    @Test
+    public void testCannotResolveIntent() {
+        final PackageManager fakePackageMgr = mock(PackageManager.class);
+
+        ResolveInfo validInfo = mContext.getPackageManager().resolveActivity(
+                new Intent(Intent.ACTION_DIAL).setData(Uri.parse("tel:+12122537077")), 0);
+        // Make packageManager fail when it gets the following intent:
+        ArgumentMatcher<Intent> toFailIntent =
+                intent -> intent.getAction().equals(Intent.ACTION_INSERT_OR_EDIT);
+
+        when(fakePackageMgr.resolveActivity(any(Intent.class), anyInt())).thenReturn(validInfo);
+        when(fakePackageMgr.resolveActivity(argThat(toFailIntent), anyInt())).thenReturn(null);
+
+        ContextWrapper fakeContext = new ContextWrapper(mContext) {
+            @Override
+            public PackageManager getPackageManager() {
+                return fakePackageMgr;
+            }
+        };
+
+        TextClassifier fallback = TextClassifier.NO_OP;
+        TextClassifier classifier = new TextClassifierImpl(
+                fakeContext, TextClassificationConstants.loadFromString(null), fallback);
+
+        String text = "Contact me at +12122537077";
+        String classifiedText = "+12122537077";
+        int startIndex = text.indexOf(classifiedText);
+        int endIndex = startIndex + classifiedText.length();
+        TextClassification.Request request = new TextClassification.Request.Builder(
+                text, startIndex, endIndex)
+                .setDefaultLocales(LOCALES)
+                .build();
+
+        TextClassification result = classifier.classifyText(request);
+        TextClassification fallbackResult = fallback.classifyText(request);
+
+        // classifier should not totally fail in which case it returns a fallback result.
+        // It should skip the failing intent and return a result for non-failing intents.
+        assertFalse(result.getActions().isEmpty());
+        assertNotSame(result, fallbackResult);
+    }
+
     private boolean isTextClassifierDisabled() {
         return mClassifier == TextClassifier.NO_OP;
     }
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index 320a7ac..bcb7cf3 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -318,40 +318,52 @@
         onView(withId(R.id.textview)).perform(clickOnTextAtIndex(position));
         sleepForFloatingToolbarPopup();
         assertFloatingToolbarIsDisplayed();
-
     }
 
     @Test
     public void testToolbarAppearsAfterLinkClickedNonselectable() throws Throwable {
-        TextLinks.TextLink textLink = addLinkifiedTextToTextView(R.id.nonselectable_textview);
-        int position = (textLink.getStart() + textLink.getEnd()) / 2;
+        final TextView textView = mActivity.findViewById(R.id.nonselectable_textview);
+        final TextLinks.TextLink textLink = addLinkifiedTextToTextView(R.id.nonselectable_textview);
+        final int position = (textLink.getStart() + textLink.getEnd()) / 2;
+
         onView(withId(R.id.nonselectable_textview)).perform(clickOnTextAtIndex(position));
         sleepForFloatingToolbarPopup();
         assertFloatingToolbarIsDisplayed();
+        assertTrue(textView.hasSelection());
+
+        // toggle
+        onView(withId(R.id.nonselectable_textview)).perform(clickOnTextAtIndex(position));
+        sleepForFloatingToolbarPopup();
+        assertFalse(textView.hasSelection());
+
+        onView(withId(R.id.nonselectable_textview)).perform(clickOnTextAtIndex(position));
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarIsDisplayed();
+        assertTrue(textView.hasSelection());
+
+        // click outside
+        onView(withId(R.id.nonselectable_textview)).perform(clickOnTextAtIndex(0));
+        sleepForFloatingToolbarPopup();
+        assertFalse(textView.hasSelection());
     }
 
     @Test
     public void testSelectionRemovedWhenNonselectableTextLosesFocus() throws Throwable {
-        // Add a link to both selectable and nonselectable TextViews:
-        TextLinks.TextLink textLink = addLinkifiedTextToTextView(R.id.textview);
-        int selectablePosition = (textLink.getStart() + textLink.getEnd()) / 2;
-        textLink = addLinkifiedTextToTextView(R.id.nonselectable_textview);
-        int nonselectablePosition = (textLink.getStart() + textLink.getEnd()) / 2;
-        TextView selectableTextView = mActivity.findViewById(R.id.textview);
-        TextView nonselectableTextView = mActivity.findViewById(R.id.nonselectable_textview);
+        final TextLinks.TextLink textLink = addLinkifiedTextToTextView(R.id.nonselectable_textview);
+        final int position = (textLink.getStart() + textLink.getEnd()) / 2;
+        final TextView textView = mActivity.findViewById(R.id.nonselectable_textview);
+        mActivityRule.runOnUiThread(() -> textView.setFocusableInTouchMode(true));
 
-        onView(withId(R.id.nonselectable_textview))
-                .perform(clickOnTextAtIndex(nonselectablePosition));
+        onView(withId(R.id.nonselectable_textview)).perform(clickOnTextAtIndex(position));
         sleepForFloatingToolbarPopup();
         assertFloatingToolbarIsDisplayed();
-        assertTrue(nonselectableTextView.hasSelection());
+        assertTrue(textView.hasSelection());
 
-        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(selectablePosition));
+        mActivityRule.runOnUiThread(() -> textView.clearFocus());
+        mInstrumentation.waitForIdleSync();
         sleepForFloatingToolbarPopup();
-        assertFloatingToolbarIsDisplayed();
 
-        assertTrue(selectableTextView.hasSelection());
-        assertFalse(nonselectableTextView.hasSelection());
+        assertFalse(textView.hasSelection());
     }
 
     @Test
diff --git a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodSubtypeSwitchingControllerTest.java b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
index 0429d99..13d6749 100644
--- a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
@@ -23,7 +23,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
-import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.inputmethod.InputMethodInfo;
@@ -41,7 +40,6 @@
 import java.util.List;
 
 @SmallTest
-@Presubmit
 @RunWith(AndroidJUnit4.class)
 public class InputMethodSubtypeSwitchingControllerTest {
     private static final String DUMMY_PACKAGE_NAME = "dummy package name";
diff --git a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
index 863cf05..3064afa 100644
--- a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
@@ -37,7 +37,6 @@
 import android.os.Build;
 import android.os.LocaleList;
 import android.os.Parcel;
-import android.platform.test.annotations.Presubmit;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -54,7 +53,6 @@
 import java.util.Objects;
 
 @SmallTest
-@Presubmit
 @RunWith(AndroidJUnit4.class)
 public class InputMethodUtilsTest {
     private static final boolean IS_AUX = true;
@@ -87,7 +85,6 @@
     private static final String SUBTYPE_MODE_HANDWRITING = "handwriting";
     private static final String SUBTYPE_MODE_ANY = null;
     private static final String EXTRA_VALUE_PAIR_SEPARATOR = ",";
-    private static final String EXTRA_VALUE_ASCII_CAPABLE = "AsciiCapable";
     private static final String EXTRA_VALUE_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE =
             "EnabledWhenDefaultIsNotAsciiCapable";
 
@@ -910,13 +907,6 @@
             subtypeExtraValue.append(EXTRA_VALUE_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
         }
 
-        // TODO: Remove following code. InputMethodSubtype#isAsciiCapable() has been publicly
-        // available since API level 19 (KitKat). We no longer need to rely on extra value.
-        if (isAsciiCapable) {
-            subtypeExtraValue.append(EXTRA_VALUE_PAIR_SEPARATOR);
-            subtypeExtraValue.append(EXTRA_VALUE_ASCII_CAPABLE);
-        }
-
         return new InputMethodSubtypeBuilder()
                 .setSubtypeNameResId(0)
                 .setSubtypeIconResId(0)
diff --git a/core/tests/coretests/src/com/android/internal/inputmethod/LocaleUtilsTest.java b/core/tests/coretests/src/com/android/internal/inputmethod/LocaleUtilsTest.java
index 1269ffd..549511a 100644
--- a/core/tests/coretests/src/com/android/internal/inputmethod/LocaleUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/inputmethod/LocaleUtilsTest.java
@@ -19,7 +19,6 @@
 import static org.junit.Assert.assertEquals;
 
 import android.os.LocaleList;
-import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
@@ -30,7 +29,6 @@
 import java.util.Locale;
 
 @SmallTest
-@Presubmit
 @RunWith(AndroidJUnit4.class)
 public class LocaleUtilsTest {
 
diff --git a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java
index 36e54ad..b68f6b1 100644
--- a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java
+++ b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java
@@ -190,6 +190,11 @@
         @Override
         public void cancelCpuSyncDueToWakelockChange() {
         }
+
+        @Override
+        public Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis) {
+            return null;
+        }
     }
 }
 
diff --git a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java
index 518cadd..85b210b 100644
--- a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java
+++ b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowTest.java
@@ -24,6 +24,9 @@
 import static org.junit.Assert.assertThat;
 
 import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
@@ -89,6 +92,32 @@
                 is(LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER));
     }
 
+    @Test
+    public void testWindowBackground_colorLiteral() {
+        createPhoneWindowWithTheme(R.style.WindowBackgroundColorLiteral);
+        installDecor();
+
+        Drawable backgroundDrawable = mPhoneWindow.getDecorView().getBackground();
+        assertThat(backgroundDrawable instanceof ColorDrawable, is(true));
+
+        ColorDrawable colorDrawable = (ColorDrawable) backgroundDrawable;
+        assertThat(colorDrawable.getColor(), is(Color.GREEN));
+    }
+
+    @Test
+    public void testWindowBackgroundFallback_colorLiteral() {
+        createPhoneWindowWithTheme(R.style.WindowBackgroundFallbackColorLiteral);
+        installDecor();
+
+        DecorView decorView = (DecorView) mPhoneWindow.getDecorView();
+        Drawable fallbackDrawable = decorView.getBackgroundFallback();
+
+        assertThat(fallbackDrawable instanceof ColorDrawable, is(true));
+
+        ColorDrawable colorDrawable = (ColorDrawable) fallbackDrawable;
+        assertThat(colorDrawable.getColor(), is(Color.BLUE));
+    }
+
     private void createPhoneWindowWithTheme(int theme) {
         mPhoneWindow = new PhoneWindow(new ContextThemeWrapper(mContext, theme));
     }
diff --git a/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java b/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
index bf91a16..6d5276f 100644
--- a/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
+++ b/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
@@ -118,7 +118,7 @@
 
     @Test
     public void installPlatformSignedFrameworkOverlayAndUpdate() throws Exception {
-        assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS, "expectAppResource"));
+        assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS, "expectFrameworkResource"));
 
         installPackage("OverlayHostTests_FrameworkOverlayV1.apk");
         setOverlayEnabled(FRAMEWORK_OVERLAY_PACKAGE_NAME, true);
@@ -138,6 +138,27 @@
                 "expectFrameworkOverlayV2Resource"));
     }
 
+    @Test
+    public void enabledFrameworkOverlayMustAffectNewlyInstalledPackage() throws Exception {
+        try {
+            setPackageEnabled(DEVICE_TEST_PKG, false);
+
+            installPackage("OverlayHostTests_FrameworkOverlayV1.apk");
+            setOverlayEnabled(FRAMEWORK_OVERLAY_PACKAGE_NAME, true);
+            assertTrue(overlayManagerContainsPackage(FRAMEWORK_OVERLAY_PACKAGE_NAME));
+
+            setPackageEnabled(DEVICE_TEST_PKG, true);
+            assertTrue(runDeviceTests(DEVICE_TEST_PKG, DEVICE_TEST_CLS,
+                    "expectFrameworkOverlayV1Resource"));
+        } finally {
+            setPackageEnabled(DEVICE_TEST_PKG, true);
+        }
+    }
+
+    private void setPackageEnabled(String pkg, boolean enabled) throws Exception {
+        getDevice().executeShellCommand("cmd package " + (enabled ? "enable " : "disable ") + pkg);
+    }
+
     private void setOverlayEnabled(String pkg, boolean enabled) throws Exception {
         getDevice().executeShellCommand("cmd overlay " + (enabled ? "enable " : "disable ") + pkg);
     }
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/src/com/android/server/om/hosttest/update_overlay_test/UpdateOverlayTest.java b/core/tests/overlaytests/host/test-apps/UpdateOverlay/src/com/android/server/om/hosttest/update_overlay_test/UpdateOverlayTest.java
index d46bb37..a174d77 100644
--- a/core/tests/overlaytests/host/test-apps/UpdateOverlay/src/com/android/server/om/hosttest/update_overlay_test/UpdateOverlayTest.java
+++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/src/com/android/server/om/hosttest/update_overlay_test/UpdateOverlayTest.java
@@ -61,7 +61,7 @@
     }
 
     @Test
-    public void expectFrameworkOverlayResource() throws Exception {
+    public void expectFrameworkResource() throws Exception {
         assertEquals("OK", mResources.getString(android.R.string.ok));
     }
 
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index 71ee6c2..97130f1 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -22,6 +22,7 @@
 import android.annotation.Size;
 import android.graphics.Canvas.VertexMode;
 import android.text.GraphicsOperations;
+import android.text.MeasuredParagraph;
 import android.text.PrecomputedText;
 import android.text.SpannableString;
 import android.text.SpannedString;
@@ -486,21 +487,31 @@
             ((GraphicsOperations) text).drawTextRun(this, start, end,
                     contextStart, contextEnd, x, y, isRtl, paint);
         } else {
+            if (text instanceof PrecomputedText) {
+                final PrecomputedText pt = (PrecomputedText) text;
+                final int paraIndex = pt.findParaIndex(start);
+                if (end <= pt.getParagraphEnd(paraIndex)) {
+                    final int paraStart = pt.getParagraphStart(paraIndex);
+                    final MeasuredParagraph mp = pt.getMeasuredParagraph(paraIndex);
+                    // Only support the text in the same paragraph.
+                    nDrawTextRun(mNativeCanvasWrapper,
+                            mp.getChars(),
+                            start - paraStart,
+                            end - start,
+                            contextStart - paraStart,
+                            contextEnd - contextStart,
+                            x, y, isRtl, paint.getNativeInstance(),
+                            mp.getNativePtr());
+                    return;
+                }
+            }
             int contextLen = contextEnd - contextStart;
             int len = end - start;
             char[] buf = TemporaryBuffer.obtain(contextLen);
             TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
-            long measuredTextPtr = 0;
-            if (text instanceof PrecomputedText) {
-                PrecomputedText mt = (PrecomputedText) text;
-                int paraIndex = mt.findParaIndex(start);
-                if (end <= mt.getParagraphEnd(paraIndex)) {
-                    // Only suppor the text in the same paragraph.
-                    measuredTextPtr = mt.getMeasuredParagraph(paraIndex).getNativePtr();
-                }
-            }
             nDrawTextRun(mNativeCanvasWrapper, buf, start - contextStart, len,
-                    0, contextLen, x, y, isRtl, paint.getNativeInstance(), measuredTextPtr);
+                    0, contextLen, x, y, isRtl, paint.getNativeInstance(),
+                    0 /* measured paragraph pointer */);
             TemporaryBuffer.recycle(buf);
         }
     }
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 3cc92bc..a465eea 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -829,6 +829,17 @@
     }
 
     /**
+     * DON'T USE THIS METHOD.  It exists only to support a particular legacy behavior in
+     * the view system and will be removed as soon as that code is refactored to no longer
+     * depend on this behavior.
+     * @hide
+     */
+    public boolean clipRectUnion(@NonNull Rect rect) {
+        return nClipRect(mNativeCanvasWrapper, rect.left, rect.top, rect.right, rect.bottom,
+                Region.Op.UNION.nativeInt);
+    }
+
+    /**
      * Intersect the current clip with the specified rectangle, which is
      * expressed in local coordinates.
      *
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 9ae747d..a601d6d 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -21,12 +21,18 @@
 import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.content.pm.ActivityInfo.Config;
-import android.graphics.*;
-import android.graphics.PorterDuff.Mode;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Outline;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Xfermode;
 import android.util.AttributeSet;
 import android.view.ViewDebug;
 
@@ -180,6 +186,17 @@
         mPaint.setColorFilter(colorFilter);
     }
 
+    /**
+     * Returns the color filter applied to this color configured by
+     * {@link #setColorFilter(ColorFilter)}
+     *
+     * @see android.graphics.drawable.Drawable#getColorFilter()
+     */
+    @Override
+    public @Nullable ColorFilter getColorFilter() {
+        return mPaint.getColorFilter();
+    }
+
     @Override
     public void setTintList(ColorStateList tint) {
         mColorState.mTint = tint;
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 66f2a31..5ff49ab 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -692,13 +692,13 @@
                 mPadding = new Rect();
             }
             mPadding.left = Drawable.scaleFromDensity(
-                    sourcePadding.left, sourceDensity, targetDensity, false);
+                    sourcePadding.left, sourceDensity, targetDensity, true);
             mPadding.top = Drawable.scaleFromDensity(
-                    sourcePadding.top, sourceDensity, targetDensity, false);
+                    sourcePadding.top, sourceDensity, targetDensity, true);
             mPadding.right = Drawable.scaleFromDensity(
-                    sourcePadding.right, sourceDensity, targetDensity, false);
+                    sourcePadding.right, sourceDensity, targetDensity, true);
             mPadding.bottom = Drawable.scaleFromDensity(
-                    sourcePadding.bottom, sourceDensity, targetDensity, false);
+                    sourcePadding.bottom, sourceDensity, targetDensity, true);
         } else {
             mPadding = null;
         }
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 46a7fa8..066e17c 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -371,9 +371,9 @@
      *     a private key; used only to call startActivity(); must not
      *     be null.
      * @param response Callback to invoke when the request completes;
-     *     must not be null
+     *     must not be null.
      * @param keyTypes The acceptable types of asymmetric keys such as
-     *     "RSA" or "DSA", or a null array.
+     *     "RSA" or "DSA", or null.
      * @param issuers The acceptable certificate issuers for the
      *     certificate matching the private key, or null.
      * @param host The host name of the server requesting the
@@ -385,7 +385,8 @@
      */
     public static void choosePrivateKeyAlias(@NonNull Activity activity,
             @NonNull KeyChainAliasCallback response,
-            @KeyProperties.KeyAlgorithmEnum String[] keyTypes, Principal[] issuers,
+            @Nullable @KeyProperties.KeyAlgorithmEnum String[] keyTypes,
+            @Nullable Principal[] issuers,
             @Nullable String host, int port, @Nullable String alias) {
         Uri uri = null;
         if (host != null) {
@@ -421,9 +422,9 @@
      *     a private key; used only to call startActivity(); must not
      *     be null.
      * @param response Callback to invoke when the request completes;
-     *     must not be null
+     *     must not be null.
      * @param keyTypes The acceptable types of asymmetric keys such as
-     *     "EC" or "RSA", or a null array.
+     *     "EC" or "RSA", or null.
      * @param issuers The acceptable certificate issuers for the
      *     certificate matching the private key, or null.
      * @param uri The full URI the server is requesting the certificate
@@ -433,7 +434,8 @@
      */
     public static void choosePrivateKeyAlias(@NonNull Activity activity,
             @NonNull KeyChainAliasCallback response,
-            @KeyProperties.KeyAlgorithmEnum String[] keyTypes, Principal[] issuers,
+            @Nullable @KeyProperties.KeyAlgorithmEnum String[] keyTypes,
+            @Nullable Principal[] issuers,
             @Nullable Uri uri, @Nullable String alias) {
         /*
          * TODO currently keyTypes, issuers are unused. They are meant
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 7d4e6f8..b3a3f45 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -3504,13 +3504,14 @@
 {
     PackageGroup(
             ResTable* _owner, const String16& _name, uint32_t _id,
-            bool appAsLib, bool _isSystemAsset)
+            bool appAsLib, bool _isSystemAsset, bool _isDynamic)
         : owner(_owner)
         , name(_name)
         , id(_id)
         , largestTypeId(0)
         , dynamicRefTable(static_cast<uint8_t>(_id), appAsLib)
         , isSystemAsset(_isSystemAsset)
+        , isDynamic(_isDynamic)
     { }
 
     ~PackageGroup() {
@@ -3614,6 +3615,7 @@
     // If the package group comes from a system asset. Used in
     // determining non-system locales.
     const bool                      isSystemAsset;
+    const bool isDynamic;
 };
 
 ResTable::Theme::Theme(const ResTable& table)
@@ -3982,6 +3984,11 @@
     return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1;
 }
 
+inline ssize_t ResTable::getResourcePackageIndexFromPackage(uint8_t packageID) const
+{
+    return ((ssize_t)mPackageMap[packageID])-1;
+}
+
 status_t ResTable::add(const void* data, size_t size, const int32_t cookie, bool copyData) {
     return addInternal(data, size, NULL, 0, false, cookie, copyData);
 }
@@ -4037,7 +4044,7 @@
     for (size_t i=0; i < src->mPackageGroups.size(); i++) {
         PackageGroup* srcPg = src->mPackageGroups[i];
         PackageGroup* pg = new PackageGroup(this, srcPg->name, srcPg->id,
-                false /* appAsLib */, isSystemAsset || srcPg->isSystemAsset);
+                false /* appAsLib */, isSystemAsset || srcPg->isSystemAsset, srcPg->isDynamic);
         for (size_t j=0; j<srcPg->packages.size(); j++) {
             pg->packages.add(srcPg->packages[j]);
         }
@@ -6277,6 +6284,68 @@
     return true;
 }
 
+bool ResTable::isPackageDynamic(uint8_t packageID) const {
+  if (mError != NO_ERROR) {
+      return false;
+  }
+  if (packageID == 0) {
+      ALOGW("Invalid package number 0x%08x", packageID);
+      return false;
+  }
+
+  const ssize_t p = getResourcePackageIndexFromPackage(packageID);
+
+  if (p < 0) {
+      ALOGW("Unknown package number 0x%08x", packageID);
+      return false;
+  }
+
+  const PackageGroup* const grp = mPackageGroups[p];
+  if (grp == NULL) {
+      ALOGW("Bad identifier for package number 0x%08x", packageID);
+      return false;
+  }
+
+  return grp->isDynamic;
+}
+
+bool ResTable::isResourceDynamic(uint32_t resID) const {
+    if (mError != NO_ERROR) {
+        return false;
+    }
+
+    const ssize_t p = getResourcePackageIndex(resID);
+    const int t = Res_GETTYPE(resID);
+    const int e = Res_GETENTRY(resID);
+
+    if (p < 0) {
+        if (Res_GETPACKAGE(resID)+1 == 0) {
+            ALOGW("No package identifier for resource number 0x%08x", resID);
+        } else {
+            ALOGW("No known package for resource number 0x%08x", resID);
+        }
+        return false;
+    }
+    if (t < 0) {
+        ALOGW("No type identifier for resource number 0x%08x", resID);
+        return false;
+    }
+
+    const PackageGroup* const grp = mPackageGroups[p];
+    if (grp == NULL) {
+        ALOGW("Bad identifier for resource number 0x%08x", resID);
+        return false;
+    }
+
+    Entry entry;
+    status_t err = getEntry(grp, t, e, NULL, &entry);
+    if (err != NO_ERROR) {
+        return false;
+    }
+
+    return grp->isDynamic;
+}
+
 static bool keyCompare(const ResTable_sparseTypeEntry& entry , uint16_t entryIdx) {
   return dtohs(entry.idx) < entryIdx;
 }
@@ -6520,12 +6589,14 @@
         id = targetPackageId;
     }
 
+    bool isDynamic = false;
     if (id >= 256) {
         LOG_ALWAYS_FATAL("Package id out of range");
         return NO_ERROR;
     } else if (id == 0 || (id == 0x7f && appAsLib) || isSystemAsset) {
         // This is a library or a system asset, so assign an ID
         id = mNextPackageId++;
+        isDynamic = true;
     }
 
     PackageGroup* group = NULL;
@@ -6553,10 +6624,9 @@
     size_t idx = mPackageMap[id];
     if (idx == 0) {
         idx = mPackageGroups.size() + 1;
-
         char16_t tmpName[sizeof(pkg->name)/sizeof(pkg->name[0])];
         strcpy16_dtoh(tmpName, pkg->name, sizeof(pkg->name)/sizeof(pkg->name[0]));
-        group = new PackageGroup(this, String16(tmpName), id, appAsLib, isSystemAsset);
+        group = new PackageGroup(this, String16(tmpName), id, appAsLib, isSystemAsset, isDynamic);
         if (group == NULL) {
             delete package;
             return (mError=NO_MEMORY);
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index bc0a07a..63b9e3a 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -1716,6 +1716,18 @@
     bool getResourceFlags(uint32_t resID, uint32_t* outFlags) const;
 
     /**
+     * Returns whether or not the package for the given resource has been dynamically assigned.
+     * If the resource can't be found, returns 'false'.
+     */
+    bool isResourceDynamic(uint32_t resID) const;
+
+    /**
+     * Returns whether or not the given package has been dynamically assigned.
+     * If the package can't be found, returns 'false'.
+     */
+    bool isPackageDynamic(uint8_t packageID) const;
+
+    /**
      * Retrieve the value of a resource.  If the resource is found, returns a
      * value >= 0 indicating the table it is in (for use with
      * getTableStringBlock() and getTableCookie()) and fills in 'outValue'.  If
@@ -2024,6 +2036,7 @@
             bool appAsLib, const int32_t cookie, bool copyData, bool isSystemAsset=false);
 
     ssize_t getResourcePackageIndex(uint32_t resID) const;
+    ssize_t getResourcePackageIndexFromPackage(uint8_t packageID) const;
 
     status_t getEntry(
         const PackageGroup* packageGroup, int typeIndex, int entryIndex,
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index be7d663..569de76 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -40,7 +40,6 @@
 }
 
 DeferredLayerUpdater::~DeferredLayerUpdater() {
-    SkSafeUnref(mColorFilter);
     setTransform(nullptr);
     mRenderState.unregisterDeferredLayerUpdater(this);
     destroyLayer();
@@ -67,8 +66,11 @@
 void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
     mAlpha = PaintUtils::getAlphaDirect(paint);
     mMode = PaintUtils::getBlendModeDirect(paint);
-    SkColorFilter* colorFilter = (paint) ? paint->getColorFilter() : nullptr;
-    SkRefCnt_SafeAssign(mColorFilter, colorFilter);
+    if (paint) {
+        mColorFilter = paint->refColorFilter();
+    } else {
+        mColorFilter.reset();
+    }
 }
 
 void DeferredLayerUpdater::apply() {
@@ -143,7 +145,7 @@
 #endif
         mSurfaceTexture->getTransformMatrix(transform);
 
-        updateLayer(forceFilter, transform);
+        updateLayer(forceFilter, transform, mSurfaceTexture->getCurrentDataSpace());
     }
 }
 
@@ -153,17 +155,19 @@
                         Layer::Api::OpenGL, Layer::Api::Vulkan);
 
     static const mat4 identityMatrix;
-    updateLayer(false, identityMatrix.data);
+    updateLayer(false, identityMatrix.data, HAL_DATASPACE_UNKNOWN);
 
     VkLayer* vkLayer = static_cast<VkLayer*>(mLayer);
     vkLayer->updateTexture();
 }
 
-void DeferredLayerUpdater::updateLayer(bool forceFilter, const float* textureTransform) {
+void DeferredLayerUpdater::updateLayer(bool forceFilter, const float* textureTransform,
+                                       android_dataspace dataspace) {
     mLayer->setBlend(mBlend);
     mLayer->setForceFilter(forceFilter);
     mLayer->setSize(mWidth, mHeight);
     mLayer->getTexTransform().load(textureTransform);
+    mLayer->setDataSpace(dataspace);
 }
 
 void DeferredLayerUpdater::detachSurfaceTexture() {
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 9dc029f..fe3ee7a 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -20,6 +20,7 @@
 #include <SkMatrix.h>
 #include <cutils/compiler.h>
 #include <gui/GLConsumer.h>
+#include <system/graphics.h>
 #include <utils/StrongPointer.h>
 
 #include <GLES2/gl2.h>
@@ -41,7 +42,7 @@
     // Note that DeferredLayerUpdater assumes it is taking ownership of the layer
     // and will not call incrementRef on it as a result.
     typedef std::function<Layer*(RenderState& renderState, uint32_t layerWidth,
-                                 uint32_t layerHeight, SkColorFilter* colorFilter, int alpha,
+                                 uint32_t layerHeight, sk_sp<SkColorFilter> colorFilter, int alpha,
                                  SkBlendMode mode, bool blend)>
             CreateLayerFn;
     ANDROID_API explicit DeferredLayerUpdater(RenderState& renderState, CreateLayerFn createLayerFn,
@@ -96,7 +97,7 @@
 
     void detachSurfaceTexture();
 
-    void updateLayer(bool forceFilter, const float* textureTransform);
+    void updateLayer(bool forceFilter, const float* textureTransform, android_dataspace dataspace);
 
     void destroyLayer();
 
@@ -109,7 +110,7 @@
     int mWidth = 0;
     int mHeight = 0;
     bool mBlend = false;
-    SkColorFilter* mColorFilter = nullptr;
+    sk_sp<SkColorFilter> mColorFilter;
     int mAlpha = 255;
     SkBlendMode mMode = SkBlendMode::kSrcOver;
     sp<GLConsumer> mSurfaceTexture;
diff --git a/libs/hwui/EglReadback.cpp b/libs/hwui/EglReadback.cpp
index a836afe..2d5367b 100644
--- a/libs/hwui/EglReadback.cpp
+++ b/libs/hwui/EglReadback.cpp
@@ -58,7 +58,7 @@
 CopyResult EglReadback::copyGraphicBufferInto(GraphicBuffer* graphicBuffer,
                                                  Matrix4& texTransform, const Rect& srcRect,
                                                  SkBitmap* bitmap) {
-    mRenderThread.eglManager().initialize();
+    mRenderThread.requireGlContext();
     // TODO: Can't use Image helper since it forces GL_TEXTURE_2D usage via
     // GL_OES_EGL_image, which doesn't work since we need samplerExternalOES
     // to be able to properly sample from the buffer.
diff --git a/libs/hwui/GlLayer.cpp b/libs/hwui/GlLayer.cpp
index 32a3014..42ae29d 100644
--- a/libs/hwui/GlLayer.cpp
+++ b/libs/hwui/GlLayer.cpp
@@ -32,7 +32,7 @@
 namespace uirenderer {
 
 GlLayer::GlLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight,
-                 SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend)
+                 sk_sp<SkColorFilter> colorFilter, int alpha, SkBlendMode mode, bool blend)
         : Layer(renderState, Api::OpenGL, colorFilter, alpha, mode)
         , caches(Caches::getInstance())
         , texture(caches) {
diff --git a/libs/hwui/GlLayer.h b/libs/hwui/GlLayer.h
index 1b09191..28749a0 100644
--- a/libs/hwui/GlLayer.h
+++ b/libs/hwui/GlLayer.h
@@ -32,7 +32,7 @@
 class GlLayer : public Layer {
 public:
     GlLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight,
-            SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend);
+            sk_sp<SkColorFilter> colorFilter, int alpha, SkBlendMode mode, bool blend);
     virtual ~GlLayer();
 
     uint32_t getWidth() const override { return texture.mWidth; }
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 86950d5..fb8f033 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -18,34 +18,58 @@
 
 #include "renderstate/RenderState.h"
 
-#include <SkColorFilter.h>
+#include <SkToSRGBColorFilter.h>
 
 namespace android {
 namespace uirenderer {
 
-Layer::Layer(RenderState& renderState, Api api, SkColorFilter* colorFilter, int alpha,
+Layer::Layer(RenderState& renderState, Api api, sk_sp<SkColorFilter> colorFilter, int alpha,
              SkBlendMode mode)
         : GpuMemoryTracker(GpuObjectType::Layer)
         , mRenderState(renderState)
         , mApi(api)
-        , colorFilter(nullptr)
+        , mColorFilter(colorFilter)
         , alpha(alpha)
         , mode(mode) {
     // TODO: This is a violation of Android's typical ref counting, but it
     // preserves the old inc/dec ref locations. This should be changed...
     incStrong(nullptr);
-
+    buildColorSpaceWithFilter();
     renderState.registerLayer(this);
 }
 
 Layer::~Layer() {
-    SkSafeUnref(colorFilter);
-
     mRenderState.unregisterLayer(this);
 }
 
-void Layer::setColorFilter(SkColorFilter* filter) {
-    SkRefCnt_SafeAssign(colorFilter, filter);
+void Layer::setColorFilter(sk_sp<SkColorFilter> filter) {
+    if (filter != mColorFilter) {
+        mColorFilter = filter;
+        buildColorSpaceWithFilter();
+    }
+}
+
+void Layer::setDataSpace(android_dataspace dataspace) {
+    if (dataspace != mCurrentDataspace) {
+        mCurrentDataspace = dataspace;
+        buildColorSpaceWithFilter();
+    }
+}
+
+void Layer::buildColorSpaceWithFilter() {
+    sk_sp<SkColorFilter> colorSpaceFilter;
+    sk_sp<SkColorSpace> colorSpace = DataSpaceToColorSpace(mCurrentDataspace);
+    if (colorSpace && !colorSpace->isSRGB()) {
+        colorSpaceFilter = SkToSRGBColorFilter::Make(colorSpace);
+    }
+
+    if (mColorFilter && colorSpaceFilter) {
+        mColorSpaceWithFilter = mColorFilter->makeComposed(colorSpaceFilter);
+    } else if (colorSpaceFilter) {
+        mColorSpaceWithFilter = colorSpaceFilter;
+    } else {
+        mColorSpaceWithFilter = mColorFilter;
+    }
 }
 
 void Layer::postDecStrong() {
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 6921381..89bcddc 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -19,6 +19,8 @@
 #include <GpuMemoryTracker.h>
 #include <utils/RefBase.h>
 
+#include <SkColorFilter.h>
+#include <SkColorSpace.h>
 #include <SkBlendMode.h>
 #include <SkPaint.h>
 
@@ -72,9 +74,15 @@
 
     inline SkBlendMode getMode() const { return mode; }
 
-    inline SkColorFilter* getColorFilter() const { return colorFilter; }
+    inline SkColorFilter* getColorFilter() const { return mColorFilter.get(); }
 
-    void setColorFilter(SkColorFilter* filter);
+    void setColorFilter(sk_sp<SkColorFilter> filter);
+
+    void setDataSpace(android_dataspace dataspace);
+
+    void setColorSpace(sk_sp<SkColorSpace> colorSpace);
+
+    inline sk_sp<SkColorFilter> getColorSpaceWithFilter() const { return mColorSpaceWithFilter; }
 
     inline mat4& getTexTransform() { return texTransform; }
 
@@ -87,18 +95,30 @@
     void postDecStrong();
 
 protected:
-    Layer(RenderState& renderState, Api api, SkColorFilter* colorFilter, int alpha,
+    Layer(RenderState& renderState, Api api, sk_sp<SkColorFilter>, int alpha,
           SkBlendMode mode);
 
     RenderState& mRenderState;
 
 private:
+    void buildColorSpaceWithFilter();
+
     Api mApi;
 
     /**
      * Color filter used to draw this layer. Optional.
      */
-    SkColorFilter* colorFilter;
+    sk_sp<SkColorFilter> mColorFilter;
+
+    /**
+     * Colorspace of the contents of the layer. Optional.
+     */
+    android_dataspace mCurrentDataspace = HAL_DATASPACE_UNKNOWN;
+
+    /**
+     * A color filter that is the combination of the mColorFilter and mColorSpace. Optional.
+     */
+    sk_sp<SkColorFilter> mColorSpaceWithFilter;
 
     /**
      * Indicates raster data backing the layer is scaled, requiring filtration.
diff --git a/libs/hwui/VkLayer.h b/libs/hwui/VkLayer.h
index f23f472..e9664d0 100644
--- a/libs/hwui/VkLayer.h
+++ b/libs/hwui/VkLayer.h
@@ -28,7 +28,7 @@
 class VkLayer : public Layer {
 public:
     VkLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight,
-            SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend)
+            sk_sp<SkColorFilter> colorFilter, int alpha, SkBlendMode mode, bool blend)
             : Layer(renderState, Api::Vulkan, colorFilter, alpha, mode)
             , mWidth(layerWidth)
             , mHeight(layerHeight)
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index beb4a9e1..e3b5b8c 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -290,6 +290,11 @@
                                                      info().colorType(), info().alphaType(),
                                                      nullptr));
         uirenderer::renderthread::RenderProxy::copyGraphicBufferInto(graphicBuffer(), outBitmap);
+        if (mInfo.colorSpace()) {
+            sk_sp<SkPixelRef> pixelRef = sk_ref_sp(outBitmap->pixelRef());
+            outBitmap->setInfo(mInfo);
+            outBitmap->setPixelRef(std::move(pixelRef), 0, 0);
+        }
         return;
     }
     outBitmap->setInfo(mInfo, rowBytes());
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index 896c01c..00ba7130 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -50,9 +50,13 @@
         GlLayer* glLayer = static_cast<GlLayer*>(layer);
         GrGLTextureInfo externalTexture;
         externalTexture.fTarget = glLayer->getRenderTarget();
-        SkASSERT(GL_RGBA == glLayer->getTexture().internalFormat());
-        externalTexture.fFormat = GL_RGBA8;
         externalTexture.fID = glLayer->getTextureId();
+        // The format may not be GL_RGBA8, but given the DeferredLayerUpdater and GLConsumer don't
+        // expose that info we use it as our default.  Further, given that we only use this texture
+        // as a source this will not impact how Skia uses the texture.  The only potential affect
+        // this is anticipated to have is that for some format types if we are not bound as an OES
+        // texture we may get invalid results for SKP capture if we read back the texture.
+        externalTexture.fFormat = GL_RGBA8;
         GrBackendTexture backendTexture(layerWidth, layerHeight, GrMipMapped::kNo, externalTexture);
         layerImage = SkImage::MakeFromTexture(context, backendTexture, kTopLeft_GrSurfaceOrigin,
                                               kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
@@ -83,7 +87,7 @@
         SkPaint paint;
         paint.setAlpha(layer->getAlpha());
         paint.setBlendMode(layer->getMode());
-        paint.setColorFilter(sk_ref_sp(layer->getColorFilter()));
+        paint.setColorFilter(layer->getColorSpaceWithFilter());
 
         const bool nonIdentityMatrix = !matrix.isIdentity();
         if (nonIdentityMatrix) {
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index b7aa78b..cfcfd2b 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -158,7 +158,7 @@
 }
 
 static Layer* createLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight,
-                          SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend) {
+                          sk_sp<SkColorFilter> colorFilter, int alpha, SkBlendMode mode, bool blend) {
     GlLayer* layer =
             new GlLayer(renderState, layerWidth, layerHeight, colorFilter, alpha, mode, blend);
     layer->generateTexture();
@@ -166,7 +166,7 @@
 }
 
 DeferredLayerUpdater* SkiaOpenGLPipeline::createTextureLayer() {
-    mEglManager.initialize();
+    mRenderThread.requireGlContext();
     return new DeferredLayerUpdater(mRenderThread.renderState(), createLayer, Layer::Api::OpenGL);
 }
 
@@ -184,6 +184,7 @@
     }
 
     if (surface) {
+        mRenderThread.requireGlContext();
         const bool wideColorGamut = colorMode == ColorMode::WideColorGamut;
         mEglSurface = mEglManager.createSurface(surface, wideColorGamut);
     }
@@ -221,24 +222,6 @@
 
 #define FENCE_TIMEOUT 2000000000
 
-class AutoEglFence {
-public:
-    AutoEglFence(EGLDisplay display) : mDisplay(display) {
-        fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
-    }
-
-    ~AutoEglFence() {
-        if (fence != EGL_NO_SYNC_KHR) {
-            eglDestroySyncKHR(mDisplay, fence);
-        }
-    }
-
-    EGLSyncKHR fence = EGL_NO_SYNC_KHR;
-
-private:
-    EGLDisplay mDisplay = EGL_NO_DISPLAY;
-};
-
 class AutoEglImage {
 public:
     AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer) : mDisplay(display) {
@@ -272,73 +255,102 @@
     GLuint mTexture = 0;
 };
 
-sk_sp<Bitmap> SkiaOpenGLPipeline::allocateHardwareBitmap(renderthread::RenderThread& renderThread,
-                                                         SkBitmap& skBitmap) {
-    renderThread.eglManager().initialize();
+struct FormatInfo {
 
-    sk_sp<GrContext> grContext = sk_ref_sp(renderThread.getGrContext());
-    const SkImageInfo& info = skBitmap.info();
     PixelFormat pixelFormat;
     GLint format, type;
     bool isSupported = false;
+    bool valid = true;
+};
 
+static bool gpuSupportsHalfFloatTextures(renderthread::RenderThread& renderThread) {
+    static bool isSupported = renderThread.queue().runSync([&renderThread]() -> bool {
+        renderThread.requireGlContext();
+        sk_sp<GrContext> grContext = sk_ref_sp(renderThread.getGrContext());
+        return grContext->colorTypeSupportedAsImage(kRGBA_F16_SkColorType);
+    });
+    return isSupported;
+}
+
+static FormatInfo determineFormat(renderthread::RenderThread& renderThread,
+                                  const SkBitmap& skBitmap) {
+    FormatInfo formatInfo;
     // TODO: add support for linear blending (when ANDROID_ENABLE_LINEAR_BLENDING is defined)
-    switch (info.colorType()) {
+    switch (skBitmap.info().colorType()) {
         case kRGBA_8888_SkColorType:
-            isSupported = true;
+            formatInfo.isSupported = true;
         // ARGB_4444 is upconverted to RGBA_8888
         case kARGB_4444_SkColorType:
-            pixelFormat = PIXEL_FORMAT_RGBA_8888;
-            format = GL_RGBA;
-            type = GL_UNSIGNED_BYTE;
+            formatInfo.pixelFormat = PIXEL_FORMAT_RGBA_8888;
+            formatInfo.format = GL_RGBA;
+            formatInfo.type = GL_UNSIGNED_BYTE;
             break;
         case kRGBA_F16_SkColorType:
-            isSupported = grContext->colorTypeSupportedAsImage(kRGBA_F16_SkColorType);
-            if (isSupported) {
-                type = GL_HALF_FLOAT;
-                pixelFormat = PIXEL_FORMAT_RGBA_FP16;
+            formatInfo.isSupported = gpuSupportsHalfFloatTextures(renderThread);
+            if (formatInfo.isSupported) {
+                formatInfo.type = GL_HALF_FLOAT;
+                formatInfo.pixelFormat = PIXEL_FORMAT_RGBA_FP16;
             } else {
-                type = GL_UNSIGNED_BYTE;
-                pixelFormat = PIXEL_FORMAT_RGBA_8888;
+                formatInfo.type = GL_UNSIGNED_BYTE;
+                formatInfo.pixelFormat = PIXEL_FORMAT_RGBA_8888;
             }
-            format = GL_RGBA;
+            formatInfo.format = GL_RGBA;
             break;
         case kRGB_565_SkColorType:
-            isSupported = true;
-            pixelFormat = PIXEL_FORMAT_RGB_565;
-            format = GL_RGB;
-            type = GL_UNSIGNED_SHORT_5_6_5;
+            formatInfo.isSupported = true;
+            formatInfo.pixelFormat = PIXEL_FORMAT_RGB_565;
+            formatInfo.format = GL_RGB;
+            formatInfo.type = GL_UNSIGNED_SHORT_5_6_5;
             break;
         case kGray_8_SkColorType:
-            isSupported = true;
-            pixelFormat = PIXEL_FORMAT_RGBA_8888;
-            format = GL_LUMINANCE;
-            type = GL_UNSIGNED_BYTE;
+            formatInfo.isSupported = true;
+            formatInfo.pixelFormat = PIXEL_FORMAT_RGBA_8888;
+            formatInfo.format = GL_LUMINANCE;
+            formatInfo.type = GL_UNSIGNED_BYTE;
             break;
         default:
-            ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType());
-            return nullptr;
+            ALOGW("unable to create hardware bitmap of colortype: %d", skBitmap.info().colorType());
+            formatInfo.valid = false;
     }
+    return formatInfo;
+}
 
-    SkBitmap bitmap;
-    if (isSupported) {
-        bitmap = skBitmap;
+static SkBitmap makeHwCompatible(const FormatInfo& format, const SkBitmap& source) {
+    if (format.isSupported) {
+        return source;
     } else {
+        SkBitmap bitmap;
+        const SkImageInfo& info = source.info();
         bitmap.allocPixels(
                 SkImageInfo::MakeN32(info.width(), info.height(), info.alphaType(), nullptr));
         bitmap.eraseColor(0);
         if (info.colorType() == kRGBA_F16_SkColorType) {
             // Drawing RGBA_F16 onto ARGB_8888 is not supported
-            skBitmap.readPixels(bitmap.info().makeColorSpace(SkColorSpace::MakeSRGB()),
-                                bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
+            source.readPixels(bitmap.info().makeColorSpace(SkColorSpace::MakeSRGB()),
+                              bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
         } else {
             SkCanvas canvas(bitmap);
-            canvas.drawBitmap(skBitmap, 0.0f, 0.0f, nullptr);
+            canvas.drawBitmap(source, 0.0f, 0.0f, nullptr);
         }
+        return bitmap;
+    }
+}
+
+sk_sp<Bitmap> SkiaOpenGLPipeline::allocateHardwareBitmap(renderthread::RenderThread& thread,
+                                                         const SkBitmap& sourceBitmap) {
+    ATRACE_CALL();
+
+    LOG_ALWAYS_FATAL_IF(thread.isCurrent(), "Must not be called on RenderThread");
+
+    FormatInfo format = determineFormat(thread, sourceBitmap);
+    if (!format.valid) {
+        return nullptr;
     }
 
+    SkBitmap bitmap = makeHwCompatible(format, sourceBitmap);
     sp<GraphicBuffer> buffer = new GraphicBuffer(
-            info.width(), info.height(), pixelFormat,
+            static_cast<uint32_t>(bitmap.width()), static_cast<uint32_t>(bitmap.height()),
+            format.pixelFormat,
             GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_NEVER |
                     GraphicBuffer::USAGE_SW_READ_NEVER,
             std::string("Bitmap::allocateSkiaHardwareBitmap pid [") + std::to_string(getpid()) +
@@ -350,8 +362,11 @@
         return nullptr;
     }
 
-    // upload the bitmap into a texture
-    EGLDisplay display = eglGetCurrentDisplay();
+    EGLDisplay display = thread.queue().runSync([&]() -> EGLDisplay {
+        thread.requireGlContext();
+        return eglGetCurrentDisplay();
+    });
+
     LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY, "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
                         uirenderer::renderthread::EglManager::eglErrorString());
     // We use an EGLImage to access the content of the GraphicBuffer
@@ -363,35 +378,40 @@
               uirenderer::renderthread::EglManager::eglErrorString());
         return nullptr;
     }
-    AutoSkiaGlTexture glTexture;
-    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
-    GL_CHECKPOINT(MODERATE);
 
-    // glTexSubImage2D is synchronous in sense that it memcpy() from pointer that we provide.
-    // But asynchronous in sense that driver may upload texture onto hardware buffer when we first
-    // use it in drawing
-    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, info.width(), info.height(), format, type,
-                    bitmap.getPixels());
-    GL_CHECKPOINT(MODERATE);
+    {
+        ATRACE_FORMAT("CPU -> gralloc transfer (%dx%d)", bitmap.width(), bitmap.height());
+        EGLSyncKHR fence = thread.queue().runSync([&]() -> EGLSyncKHR {
+            thread.requireGlContext();
+            sk_sp<GrContext> grContext = sk_ref_sp(thread.getGrContext());
+            AutoSkiaGlTexture glTexture;
+            glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
+            GL_CHECKPOINT(MODERATE);
 
-    // The fence is used to wait for the texture upload to finish
-    // properly. We cannot rely on glFlush() and glFinish() as
-    // some drivers completely ignore these API calls
-    AutoEglFence autoFence(display);
-    if (autoFence.fence == EGL_NO_SYNC_KHR) {
-        LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError());
-        return nullptr;
+            // glTexSubImage2D is synchronous in sense that it memcpy() from pointer that we
+            // provide.
+            // But asynchronous in sense that driver may upload texture onto hardware buffer when we
+            // first
+            // use it in drawing
+            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(), format.format,
+                            format.type, bitmap.getPixels());
+            GL_CHECKPOINT(MODERATE);
+
+            EGLSyncKHR uploadFence =
+                    eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_FENCE_KHR, NULL);
+            LOG_ALWAYS_FATAL_IF(uploadFence == EGL_NO_SYNC_KHR, "Could not create sync fence %#x",
+                                eglGetError());
+            glFlush();
+            grContext->resetContext(kTextureBinding_GrGLBackendState);
+            return uploadFence;
+        });
+
+        EGLint waitStatus = eglClientWaitSyncKHR(display, fence, 0, FENCE_TIMEOUT);
+        LOG_ALWAYS_FATAL_IF(waitStatus != EGL_CONDITION_SATISFIED_KHR,
+                            "Failed to wait for the fence %#x", eglGetError());
+
+        eglDestroySyncKHR(display, fence);
     }
-    // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
-    // pipeline flush (similar to what a glFlush() would do.)
-    EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence,
-                                             EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
-    if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
-        LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError());
-        return nullptr;
-    }
-
-    grContext->resetContext(kTextureBinding_GrGLBackendState);
 
     return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info()));
 }
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
index 5e013b6..ef5d934 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
@@ -49,8 +49,10 @@
     bool isContextReady() override;
 
     static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor);
+
+    // May be called by any thread except RenderThread.
     static sk_sp<Bitmap> allocateHardwareBitmap(renderthread::RenderThread& thread,
-                                                SkBitmap& skBitmap);
+                                                const SkBitmap& skBitmap);
 
 private:
     renderthread::EglManager& mEglManager;
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 9e73046..d66cba1 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -147,6 +147,7 @@
             GrContext* currentContext = layerNode->getLayerSurface()->getCanvas()->getGrContext();
             if (cachedContext.get() != currentContext) {
                 if (cachedContext.get()) {
+                    ATRACE_NAME("flush layers (context changed)");
                     cachedContext->flush();
                 }
                 cachedContext.reset(SkSafeRef(currentContext));
@@ -155,6 +156,7 @@
     }
 
     if (cachedContext.get()) {
+        ATRACE_NAME("flush layers");
         cachedContext->flush();
     }
 }
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index 6530074..5825060 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -115,7 +115,8 @@
 }
 
 static Layer* createLayer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight,
-                          SkColorFilter* colorFilter, int alpha, SkBlendMode mode, bool blend) {
+                          sk_sp<SkColorFilter> colorFilter, int alpha, SkBlendMode mode,
+                          bool blend) {
     return new VkLayer(renderState, layerWidth, layerHeight, colorFilter, alpha, mode, blend);
 }
 
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 95ca8d9..a36dae4 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -552,7 +552,7 @@
     ATRACE_CALL();
     if (level >= TRIM_MEMORY_COMPLETE) {
         thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
-        thread.eglManager().destroy();
+        thread.destroyGlContext();
         thread.vulkanManager().destroy();
     } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
         thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::UiHidden);
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 6e239e3..cd21822 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -16,27 +16,19 @@
 
 #include "EglManager.h"
 
-#include <string>
-
 #include <cutils/properties.h>
 #include <log/log.h>
+#include <utils/Trace.h>
 #include "utils/StringUtils.h"
 
-#include "Caches.h"
 #include "DeviceInfo.h"
 #include "Frame.h"
 #include "Properties.h"
-#include "RenderThread.h"
-#include "Texture.h"
-#include "renderstate/RenderState.h"
 
 #include <EGL/eglext.h>
-#include <GrContextOptions.h>
-#include <gl/GrGLInterface.h>
 
-#ifdef HWUI_GLES_WRAP_ENABLED
-#include "debug/GlesDriver.h"
-#endif
+#include <string>
+#include <vector>
 
 #define GLES_VERSION 2
 
@@ -83,17 +75,21 @@
     bool glColorSpace = false;
     bool scRGB = false;
     bool contextPriority = false;
+    bool surfacelessContext = false;
 } EglExtensions;
 
-EglManager::EglManager(RenderThread& thread)
-        : mRenderThread(thread)
-        , mEglDisplay(EGL_NO_DISPLAY)
+EglManager::EglManager()
+        : mEglDisplay(EGL_NO_DISPLAY)
         , mEglConfig(nullptr)
         , mEglConfigWideGamut(nullptr)
         , mEglContext(EGL_NO_CONTEXT)
         , mPBufferSurface(EGL_NO_SURFACE)
         , mCurrentSurface(EGL_NO_SURFACE) {}
 
+EglManager::~EglManager() {
+    destroy();
+}
+
 void EglManager::initialize() {
     if (hasEglContext()) return;
 
@@ -126,26 +122,8 @@
     loadConfigs();
     createContext();
     createPBufferSurface();
-    makeCurrent(mPBufferSurface);
+    makeCurrent(mPBufferSurface, nullptr, /* force */ true);
     DeviceInfo::initialize();
-    mRenderThread.renderState().onGLContextCreated();
-
-    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
-#ifdef HWUI_GLES_WRAP_ENABLED
-        debug::GlesDriver* driver = debug::GlesDriver::get();
-        sk_sp<const GrGLInterface> glInterface(driver->getSkiaInterface());
-#else
-        sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
-#endif
-        LOG_ALWAYS_FATAL_IF(!glInterface.get());
-
-        GrContextOptions options;
-        options.fDisableDistanceFieldPaths = true;
-        mRenderThread.cacheManager().configureContext(&options);
-        sk_sp<GrContext> grContext(GrContext::MakeGL(std::move(glInterface), options));
-        LOG_ALWAYS_FATAL_IF(!grContext.get());
-        mRenderThread.setGrContext(grContext);
-    }
 }
 
 void EglManager::initExtensions() {
@@ -170,6 +148,7 @@
     EglExtensions.scRGB = extensions.has("EGL_EXT_gl_colorspace_scrgb");
 #endif
     EglExtensions.contextPriority = extensions.has("EGL_IMG_context_priority");
+    EglExtensions.surfacelessContext = extensions.has("EGL_KHR_surfaceless_context");
 }
 
 bool EglManager::hasEglContext() {
@@ -195,7 +174,7 @@
                         EGL_CONFIG_CAVEAT,
                         EGL_NONE,
                         EGL_STENCIL_SIZE,
-                        Stencil::getStencilSize(),
+                        STENCIL_BUFFER_SIZE,
                         EGL_SURFACE_TYPE,
                         EGL_WINDOW_BIT | swapBehavior,
                         EGL_NONE};
@@ -232,7 +211,7 @@
                                EGL_DEPTH_SIZE,
                                0,
                                EGL_STENCIL_SIZE,
-                               Stencil::getStencilSize(),
+                               STENCIL_BUFFER_SIZE,
                                EGL_SURFACE_TYPE,
                                EGL_WINDOW_BIT | swapBehavior,
                                EGL_NONE};
@@ -269,14 +248,14 @@
     LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY,
                         "usePBufferSurface() called on uninitialized GlobalContext!");
 
-    if (mPBufferSurface == EGL_NO_SURFACE) {
+    if (mPBufferSurface == EGL_NO_SURFACE && !EglExtensions.surfacelessContext) {
         EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
         mPBufferSurface = eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs);
     }
 }
 
 EGLSurface EglManager::createSurface(EGLNativeWindowType window, bool wideColorGamut) {
-    initialize();
+    LOG_ALWAYS_FATAL_IF(!hasEglContext(), "Not initialized");
 
     wideColorGamut = wideColorGamut && EglExtensions.glColorSpace && EglExtensions.scRGB &&
                      EglExtensions.pixelFormatFloat && EglExtensions.noConfigContext;
@@ -350,10 +329,10 @@
 void EglManager::destroy() {
     if (mEglDisplay == EGL_NO_DISPLAY) return;
 
-    mRenderThread.setGrContext(nullptr);
-    mRenderThread.renderState().onGLContextDestroyed();
     eglDestroyContext(mEglDisplay, mEglContext);
-    eglDestroySurface(mEglDisplay, mPBufferSurface);
+    if (mPBufferSurface != EGL_NO_SURFACE) {
+        eglDestroySurface(mEglDisplay, mPBufferSurface);
+    }
     eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     eglTerminate(mEglDisplay);
     eglReleaseThread();
@@ -364,8 +343,8 @@
     mCurrentSurface = EGL_NO_SURFACE;
 }
 
-bool EglManager::makeCurrent(EGLSurface surface, EGLint* errOut) {
-    if (isCurrent(surface)) return false;
+bool EglManager::makeCurrent(EGLSurface surface, EGLint* errOut, bool force) {
+    if (!force && isCurrent(surface)) return false;
 
     if (surface == EGL_NO_SURFACE) {
         // Ensure we always have a valid surface & context
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index ef9effb..ca6d1b8 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -33,8 +33,12 @@
 // and EGLConfig, which are re-used by CanvasContext
 class EglManager {
 public:
+    explicit EglManager();
+
+    ~EglManager();
+
     static const char* eglErrorString();
-    // Returns true on success, false on failure
+
     void initialize();
 
     bool hasEglContext();
@@ -46,7 +50,7 @@
 
     bool isCurrent(EGLSurface surface) { return mCurrentSurface == surface; }
     // Returns true if the current surface changed, false if it was already current
-    bool makeCurrent(EGLSurface surface, EGLint* errOut = nullptr);
+    bool makeCurrent(EGLSurface surface, EGLint* errOut = nullptr, bool force = false);
     Frame beginFrame(EGLSurface surface);
     void damageFrame(const Frame& frame, const SkRect& dirty);
     // If this returns true it is mandatory that swapBuffers is called
@@ -61,10 +65,6 @@
     void fence();
 
 private:
-    friend class RenderThread;
-    explicit EglManager(RenderThread& thread);
-    // EglContext is never destroyed, method is purposely not implemented
-    ~EglManager();
 
     void initExtensions();
     void createPBufferSurface();
@@ -72,8 +72,6 @@
     void createContext();
     EGLint queryBufferAge(EGLSurface surface);
 
-    RenderThread& mRenderThread;
-
     EGLDisplay mEglDisplay;
     EGLConfig mEglConfig;
     EGLConfig mEglConfigWideGamut;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 4b948f8..0caf59b 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -21,6 +21,7 @@
 #include "Properties.h"
 #include "Readback.h"
 #include "Rect.h"
+#include "pipeline/skia/SkiaOpenGLPipeline.h"
 #include "pipeline/skia/VectorDrawableAtlas.h"
 #include "renderstate/RenderState.h"
 #include "renderthread/CanvasContext.h"
@@ -323,7 +324,13 @@
 
 sk_sp<Bitmap> RenderProxy::allocateHardwareBitmap(SkBitmap& bitmap) {
     auto& thread = RenderThread::getInstance();
-    return thread.queue().runSync([&]() -> auto { return thread.allocateHardwareBitmap(bitmap); });
+    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
+        return skiapipeline::SkiaOpenGLPipeline::allocateHardwareBitmap(thread, bitmap);
+    } else {
+        return thread.queue().runSync([&]() -> auto {
+            return thread.allocateHardwareBitmap(bitmap);
+        });
+    }
 }
 
 int RenderProxy::copyGraphicBufferInto(GraphicBuffer* buffer, SkBitmap* bitmap) {
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 5e067da..3eaf43b 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -24,12 +24,19 @@
 #include "hwui/Bitmap.h"
 #include "pipeline/skia/SkiaOpenGLPipeline.h"
 #include "pipeline/skia/SkiaOpenGLReadback.h"
-#include "pipeline/skia/SkiaVulkanReadback.h"
 #include "pipeline/skia/SkiaVulkanPipeline.h"
+#include "pipeline/skia/SkiaVulkanReadback.h"
 #include "renderstate/RenderState.h"
 #include "utils/FatVector.h"
 #include "utils/TimeUtils.h"
 
+#ifdef HWUI_GLES_WRAP_ENABLED
+#include "debug/GlesDriver.h"
+#endif
+
+#include <GrContextOptions.h>
+#include <gl/GrGLInterface.h>
+
 #include <gui/DisplayEventReceiver.h>
 #include <sys/resource.h>
 #include <utils/Condition.h>
@@ -91,14 +98,11 @@
     DummyVsyncSource(RenderThread* renderThread) : mRenderThread(renderThread) {}
 
     virtual void requestNextVsync() override {
-        mRenderThread->queue().postDelayed(16_ms, [this]() {
-            mRenderThread->drainDisplayEventQueue();
-        });
+        mRenderThread->queue().postDelayed(16_ms,
+                                           [this]() { mRenderThread->drainDisplayEventQueue(); });
     }
 
-    virtual nsecs_t latestVsyncEvent() override {
-        return systemTime(CLOCK_MONOTONIC);
-    }
+    virtual nsecs_t latestVsyncEvent() override { return systemTime(CLOCK_MONOTONIC); }
 
 private:
     RenderThread* mRenderThread;
@@ -145,13 +149,13 @@
         auto receiver = std::make_unique<DisplayEventReceiver>();
         status_t status = receiver->initCheck();
         LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
-                "Initialization of DisplayEventReceiver "
-                        "failed with status: %d",
-                status);
+                            "Initialization of DisplayEventReceiver "
+                            "failed with status: %d",
+                            status);
 
         // Register the FD
         mLooper->addFd(receiver->getFd(), 0, Looper::EVENT_INPUT,
-                RenderThread::displayEventReceiverCallback, this);
+                       RenderThread::displayEventReceiverCallback, this);
         mVsyncSource = new DisplayEventReceiverWrapper(std::move(receiver));
     } else {
         mVsyncSource = new DummyVsyncSource(this);
@@ -163,12 +167,43 @@
     nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1000000000 / mDisplayInfo.fps);
     mTimeLord.setFrameInterval(frameIntervalNanos);
     initializeDisplayEventReceiver();
-    mEglManager = new EglManager(*this);
+    mEglManager = new EglManager();
     mRenderState = new RenderState(*this);
     mVkManager = new VulkanManager(*this);
     mCacheManager = new CacheManager(mDisplayInfo);
 }
 
+void RenderThread::requireGlContext() {
+    if (mEglManager->hasEglContext()) {
+        return;
+    }
+    mEglManager->initialize();
+    renderState().onGLContextCreated();
+
+#ifdef HWUI_GLES_WRAP_ENABLED
+    debug::GlesDriver* driver = debug::GlesDriver::get();
+    sk_sp<const GrGLInterface> glInterface(driver->getSkiaInterface());
+#else
+    sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
+#endif
+    LOG_ALWAYS_FATAL_IF(!glInterface.get());
+
+    GrContextOptions options;
+    options.fDisableDistanceFieldPaths = true;
+    cacheManager().configureContext(&options);
+    sk_sp<GrContext> grContext(GrContext::MakeGL(std::move(glInterface), options));
+    LOG_ALWAYS_FATAL_IF(!grContext.get());
+    setGrContext(grContext);
+}
+
+void RenderThread::destroyGlContext() {
+    if (mEglManager->hasEglContext()) {
+        setGrContext(nullptr);
+        renderState().onGLContextDestroyed();
+        mEglManager->destroy();
+    }
+}
+
 void RenderThread::dumpGraphicsMemory(int fd) {
     globalProfileData()->dump(fd);
 
@@ -332,8 +367,6 @@
 sk_sp<Bitmap> RenderThread::allocateHardwareBitmap(SkBitmap& skBitmap) {
     auto renderType = Properties::getRenderPipelineType();
     switch (renderType) {
-        case RenderPipelineType::SkiaGL:
-            return skiapipeline::SkiaOpenGLPipeline::allocateHardwareBitmap(*this, skBitmap);
         case RenderPipelineType::SkiaVulkan:
             return skiapipeline::SkiaVulkanPipeline::allocateHardwareBitmap(*this, skBitmap);
         default:
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 689f518..4a1fd9e 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -103,6 +103,9 @@
     sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& skBitmap);
     void dumpGraphicsMemory(int fd);
 
+    void requireGlContext();
+    void destroyGlContext();
+
     /**
      * isCurrent provides a way to query, if the caller is running on
      * the render thread.
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 16c5afd..a7ac930 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -72,7 +72,7 @@
     layerUpdater->setTransform(&transform);
 
     // updateLayer so it's ready to draw
-    layerUpdater->updateLayer(true, Matrix4::identity().data);
+    layerUpdater->updateLayer(true, Matrix4::identity().data, HAL_DATASPACE_UNKNOWN);
     if (layerUpdater->backingLayer()->getApi() == Layer::Api::OpenGL) {
         static_cast<GlLayer*>(layerUpdater->backingLayer())
                 ->setRenderTarget(GL_TEXTURE_EXTERNAL_OES);
@@ -140,7 +140,7 @@
     if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
         renderThread.vulkanManager().initialize();
     } else {
-        renderThread.eglManager().initialize();
+        renderThread.requireGlContext();
     }
 
     rtCallback(renderThread);
@@ -149,7 +149,7 @@
         renderThread.vulkanManager().destroy();
     } else {
         renderThread.renderState().flush(Caches::FlushMode::Full);
-        renderThread.eglManager().destroy();
+        renderThread.destroyGlContext();
     }
 }
 
diff --git a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
index b8b5050..f29830f 100644
--- a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
+++ b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp
@@ -44,7 +44,7 @@
     // push the deferred updates to the layer
     Matrix4 scaledMatrix;
     scaledMatrix.loadScale(0.5, 0.5, 0.0);
-    layerUpdater->updateLayer(true, scaledMatrix.data);
+    layerUpdater->updateLayer(true, scaledMatrix.data, HAL_DATASPACE_UNKNOWN);
     if (layerUpdater->backingLayer()->getApi() == Layer::Api::OpenGL) {
         GlLayer* glLayer = static_cast<GlLayer*>(layerUpdater->backingLayer());
         glLayer->setRenderTarget(GL_TEXTURE_EXTERNAL_OES);
diff --git a/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp b/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp
index 9bfb082..08b9679 100644
--- a/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp
+++ b/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp
@@ -39,7 +39,7 @@
 // current thread can spoof being a GPU thread
 static void destroyEglContext() {
     if (TestUtils::isRenderThreadRunning()) {
-        TestUtils::runOnRenderThread([](RenderThread& thread) { thread.eglManager().destroy(); });
+        TestUtils::runOnRenderThread([](RenderThread& thread) { thread.destroyGlContext(); });
     }
 }
 
diff --git a/libs/hwui/utils/Color.cpp b/libs/hwui/utils/Color.cpp
index c2af867..75740e8 100644
--- a/libs/hwui/utils/Color.cpp
+++ b/libs/hwui/utils/Color.cpp
@@ -16,6 +16,8 @@
 
 #include "Color.h"
 
+
+#include <utils/Log.h>
 #include <cmath>
 
 namespace android {
@@ -53,5 +55,57 @@
     return false;
 }
 
+sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace) {
+
+    SkColorSpace::Gamut gamut;
+    switch (dataspace & HAL_DATASPACE_STANDARD_MASK) {
+        case HAL_DATASPACE_STANDARD_BT709:
+            gamut = SkColorSpace::kSRGB_Gamut;
+            break;
+        case HAL_DATASPACE_STANDARD_BT2020:
+            gamut = SkColorSpace::kRec2020_Gamut;
+            break;
+        case HAL_DATASPACE_STANDARD_DCI_P3:
+            gamut = SkColorSpace::kDCIP3_D65_Gamut;
+            break;
+        case HAL_DATASPACE_STANDARD_ADOBE_RGB:
+            gamut = SkColorSpace::kAdobeRGB_Gamut;
+            break;
+        case HAL_DATASPACE_STANDARD_UNSPECIFIED:
+            return nullptr;
+        case HAL_DATASPACE_STANDARD_BT601_625:
+        case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
+        case HAL_DATASPACE_STANDARD_BT601_525:
+        case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
+        case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
+        case HAL_DATASPACE_STANDARD_BT470M:
+        case HAL_DATASPACE_STANDARD_FILM:
+        default:
+            ALOGW("Unsupported Gamut: %d", dataspace);
+            return nullptr;
+    }
+
+    switch (dataspace & HAL_DATASPACE_TRANSFER_MASK) {
+        case HAL_DATASPACE_TRANSFER_LINEAR:
+            return SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma, gamut);
+        case HAL_DATASPACE_TRANSFER_SRGB:
+            return SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma, gamut);
+        case HAL_DATASPACE_TRANSFER_GAMMA2_2:
+            return SkColorSpace::MakeRGB({2.2f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut);
+        case HAL_DATASPACE_TRANSFER_GAMMA2_6:
+            return SkColorSpace::MakeRGB({2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut);
+        case HAL_DATASPACE_TRANSFER_GAMMA2_8:
+            return SkColorSpace::MakeRGB({2.8f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut);
+        case HAL_DATASPACE_TRANSFER_UNSPECIFIED:
+            return nullptr;
+        case HAL_DATASPACE_TRANSFER_SMPTE_170M:
+        case HAL_DATASPACE_TRANSFER_ST2084:
+        case HAL_DATASPACE_TRANSFER_HLG:
+        default:
+            ALOGW("Unsupported Gamma: %d", dataspace);
+            return nullptr;
+    }
+}
+
 };  // namespace uirenderer
 };  // namespace android
diff --git a/libs/hwui/utils/Color.h b/libs/hwui/utils/Color.h
index 7ac0d96..2bec1f5 100644
--- a/libs/hwui/utils/Color.h
+++ b/libs/hwui/utils/Color.h
@@ -17,6 +17,7 @@
 #define COLOR_H
 
 #include <math.h>
+#include <system/graphics.h>
 
 #include <SkColor.h>
 #include <SkColorSpace.h>
@@ -111,6 +112,8 @@
 // approximated with the native sRGB transfer function. This method
 // returns true for sRGB, gamma 2.2 and Display P3 for instance
 bool transferFunctionCloseToSRGB(const SkColorSpace* colorSpace);
+
+sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace);
 } /* namespace uirenderer */
 } /* namespace android */
 
diff --git a/libs/protoutil/Android.bp b/libs/protoutil/Android.bp
index 7ad83ca..44bc97a 100644
--- a/libs/protoutil/Android.bp
+++ b/libs/protoutil/Android.bp
@@ -12,9 +12,8 @@
 // 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.
-
-cc_library {
-    name: "libprotoutil",
+cc_defaults {
+    name: "libprotoutil_defaults",
 
     cflags: [
         "-Wall",
@@ -30,27 +29,39 @@
         "src/protobuf.cpp",
     ],
 
-    export_include_dirs: ["include"],
-
     shared_libs: [
+        "libbase",
         "libcutils",
         "liblog",
     ],
 }
 
+cc_library {
+    name: "libprotoutil",
+
+    defaults: ["libprotoutil_defaults"],
+
+    export_include_dirs: ["include"],
+}
+
 cc_test {
     name: "libprotoutil_test",
 
-    srcs: [
-        "tests/EncodedBuffer_test.cpp",
-    ],
+    defaults: ["libprotoutil_defaults"],
+
+    local_include_dirs: ["include"],
+
+    srcs: ["tests/*"],
 
     shared_libs: [
-        "libcutils",
-        "libprotoutil",
+        "libprotobuf-cpp-full",
     ],
 
     static_libs: [
         "libgmock",
     ],
+
+    proto: {
+        type: "full",
+    }
 }
diff --git a/libs/protoutil/include/android/util/ProtoOutputStream.h b/libs/protoutil/include/android/util/ProtoOutputStream.h
index e17f48b..ad76559 100644
--- a/libs/protoutil/include/android/util/ProtoOutputStream.h
+++ b/libs/protoutil/include/android/util/ProtoOutputStream.h
@@ -17,10 +17,11 @@
 #ifndef ANDROID_UTIL_PROTOOUTPUT_STREAM_H
 #define ANDROID_UTIL_PROTOOUTPUT_STREAM_H
 
-#include <android/util/EncodedBuffer.h>
-
+#include <cstdint>
 #include <string>
 
+#include <android/util/EncodedBuffer.h>
+
 namespace android {
 namespace util {
 
@@ -104,7 +105,7 @@
     /**
      * Starts a sub-message write session.
      * Returns a token of this write session.
-     * Must call end(token) when finish write this sub-message.
+     * Must call end(token) exactly once when finish write this sub-message.
      */
     uint64_t start(uint64_t fieldId);
     void end(uint64_t token);
@@ -143,16 +144,16 @@
 
     inline void writeDoubleImpl(uint32_t id, double val);
     inline void writeFloatImpl(uint32_t id, float val);
-    inline void writeInt64Impl(uint32_t id, long long val);
-    inline void writeInt32Impl(uint32_t id, int val);
+    inline void writeInt64Impl(uint32_t id, int64_t val);
+    inline void writeInt32Impl(uint32_t id, int32_t val);
     inline void writeUint64Impl(uint32_t id, uint64_t val);
     inline void writeUint32Impl(uint32_t id, uint32_t val);
     inline void writeFixed64Impl(uint32_t id, uint64_t val);
     inline void writeFixed32Impl(uint32_t id, uint32_t val);
-    inline void writeSFixed64Impl(uint32_t id, long long val);
-    inline void writeSFixed32Impl(uint32_t id, int val);
-    inline void writeZigzagInt64Impl(uint32_t id, long long val);
-    inline void writeZigzagInt32Impl(uint32_t id, int val);
+    inline void writeSFixed64Impl(uint32_t id, int64_t val);
+    inline void writeSFixed32Impl(uint32_t id, int32_t val);
+    inline void writeZigzagInt64Impl(uint32_t id, int64_t val);
+    inline void writeZigzagInt32Impl(uint32_t id, int32_t val);
     inline void writeEnumImpl(uint32_t id, int val);
     inline void writeBoolImpl(uint32_t id, bool val);
     inline void writeUtf8StringImpl(uint32_t id, const char* val, size_t size);
@@ -161,6 +162,9 @@
     bool compact();
     size_t editEncodedSize(size_t rawSize);
     bool compactSize(size_t rawSize);
+
+    template<typename T>
+    bool internalWrite(uint64_t fieldId, T val, const char* typeName);
 };
 
 }
diff --git a/libs/protoutil/src/ProtoOutputStream.cpp b/libs/protoutil/src/ProtoOutputStream.cpp
index 22b9709..ff3fad6 100644
--- a/libs/protoutil/src/ProtoOutputStream.cpp
+++ b/libs/protoutil/src/ProtoOutputStream.cpp
@@ -15,8 +15,10 @@
  */
 #define LOG_TAG "libprotoutil"
 
-#include <inttypes.h>
+#include <cinttypes>
+#include <type_traits>
 
+#include <android-base/file.h>
 #include <android/util/protobuf.h>
 #include <android/util/ProtoOutputStream.h>
 #include <cutils/log.h>
@@ -50,112 +52,73 @@
     mExpectedObjectToken = UINT64_C(-1);
 }
 
+template<typename T>
 bool
-ProtoOutputStream::write(uint64_t fieldId, double val)
+ProtoOutputStream::internalWrite(uint64_t fieldId, T val, const char* typeName)
 {
     if (mCompact) return false;
     const uint32_t id = (uint32_t)fieldId;
     switch (fieldId & FIELD_TYPE_MASK) {
         case FIELD_TYPE_DOUBLE:   writeDoubleImpl(id, (double)val);           break;
         case FIELD_TYPE_FLOAT:    writeFloatImpl(id, (float)val);             break;
-        case FIELD_TYPE_INT64:    writeInt64Impl(id, (long long)val);         break;
+        case FIELD_TYPE_INT64:    writeInt64Impl(id, (int64_t)val);           break;
         case FIELD_TYPE_UINT64:   writeUint64Impl(id, (uint64_t)val);         break;
-        case FIELD_TYPE_INT32:    writeInt32Impl(id, (int)val);               break;
+        case FIELD_TYPE_INT32:    writeInt32Impl(id, (int32_t)val);           break;
         case FIELD_TYPE_FIXED64:  writeFixed64Impl(id, (uint64_t)val);        break;
         case FIELD_TYPE_FIXED32:  writeFixed32Impl(id, (uint32_t)val);        break;
         case FIELD_TYPE_UINT32:   writeUint32Impl(id, (uint32_t)val);         break;
-        case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val);            break;
-        case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val);      break;
-        case FIELD_TYPE_SINT32:   writeZigzagInt32Impl(id, (int)val);         break;
-        case FIELD_TYPE_SINT64:   writeZigzagInt64Impl(id, (long long)val);   break;
+        case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int32_t)val);        break;
+        case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (int64_t)val);        break;
+        case FIELD_TYPE_SINT32:   writeZigzagInt32Impl(id, (int32_t)val);     break;
+        case FIELD_TYPE_SINT64:   writeZigzagInt64Impl(id, (int64_t)val);     break;
+        case FIELD_TYPE_ENUM:
+            if (std::is_integral<T>::value) {
+                writeEnumImpl(id, (int)val);
+            } else {
+                goto unsupported;
+            }
+            break;
+        case FIELD_TYPE_BOOL:
+            if (std::is_integral<T>::value) {
+                writeBoolImpl(id, val != 0);
+            } else {
+                goto unsupported;
+            }
+            break;
         default:
-            ALOGW("Field type %d is not supported when writing double val.",
-                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
-            return false;
+            goto unsupported;
     }
     return true;
+
+unsupported:
+    ALOGW("Field type %" PRIu64 " is not supported when writing %s val.",
+            (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT, typeName);
+    return false;
 }
 
 bool
+ProtoOutputStream::write(uint64_t fieldId, double val)
+{
+    return internalWrite(fieldId, val, "double");
+}
+
+
+bool
 ProtoOutputStream::write(uint64_t fieldId, float val)
 {
-    if (mCompact) return false;
-    const uint32_t id = (uint32_t)fieldId;
-    switch (fieldId & FIELD_TYPE_MASK) {
-        case FIELD_TYPE_DOUBLE:   writeDoubleImpl(id, (double)val);           break;
-        case FIELD_TYPE_FLOAT:    writeFloatImpl(id, (float)val);             break;
-        case FIELD_TYPE_INT64:    writeInt64Impl(id, (long long)val);         break;
-        case FIELD_TYPE_UINT64:   writeUint64Impl(id, (uint64_t)val);         break;
-        case FIELD_TYPE_INT32:    writeInt32Impl(id, (int)val);               break;
-        case FIELD_TYPE_FIXED64:  writeFixed64Impl(id, (uint64_t)val);        break;
-        case FIELD_TYPE_FIXED32:  writeFixed32Impl(id, (uint32_t)val);        break;
-        case FIELD_TYPE_UINT32:   writeUint32Impl(id, (uint32_t)val);         break;
-        case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val);            break;
-        case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val);      break;
-        case FIELD_TYPE_SINT32:   writeZigzagInt32Impl(id, (int)val);         break;
-        case FIELD_TYPE_SINT64:   writeZigzagInt64Impl(id, (long long)val);   break;
-        default:
-            ALOGW("Field type %d is not supported when writing float val.",
-                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
-            return false;
-    }
-    return true;
+    return internalWrite(fieldId, val, "float");
 }
 
 bool
 ProtoOutputStream::write(uint64_t fieldId, int val)
 {
-    if (mCompact) return false;
-    const uint32_t id = (uint32_t)fieldId;
-    switch (fieldId & FIELD_TYPE_MASK) {
-        case FIELD_TYPE_DOUBLE:   writeDoubleImpl(id, (double)val);           break;
-        case FIELD_TYPE_FLOAT:    writeFloatImpl(id, (float)val);             break;
-        case FIELD_TYPE_INT64:    writeInt64Impl(id, (long long)val);         break;
-        case FIELD_TYPE_UINT64:   writeUint64Impl(id, (uint64_t)val);         break;
-        case FIELD_TYPE_INT32:    writeInt32Impl(id, (int)val);               break;
-        case FIELD_TYPE_FIXED64:  writeFixed64Impl(id, (uint64_t)val);        break;
-        case FIELD_TYPE_FIXED32:  writeFixed32Impl(id, (uint32_t)val);        break;
-        case FIELD_TYPE_UINT32:   writeUint32Impl(id, (uint32_t)val);         break;
-        case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val);            break;
-        case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val);      break;
-        case FIELD_TYPE_SINT32:   writeZigzagInt32Impl(id, (int)val);         break;
-        case FIELD_TYPE_SINT64:   writeZigzagInt64Impl(id, (long long)val);   break;
-        case FIELD_TYPE_ENUM:     writeEnumImpl(id, (int)val);                break;
-        case FIELD_TYPE_BOOL:     writeBoolImpl(id, val != 0);                break;
-        default:
-            ALOGW("Field type %d is not supported when writing int val.",
-                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
-            return false;
-    }
-    return true;
+    return internalWrite(fieldId, val, "int");
 }
 
 bool
 ProtoOutputStream::write(uint64_t fieldId, long long val)
 {
-    if (mCompact) return false;
-    const uint32_t id = (uint32_t)fieldId;
-    switch (fieldId & FIELD_TYPE_MASK) {
-        case FIELD_TYPE_DOUBLE:   writeDoubleImpl(id, (double)val);           break;
-        case FIELD_TYPE_FLOAT:    writeFloatImpl(id, (float)val);             break;
-        case FIELD_TYPE_INT64:    writeInt64Impl(id, (long long)val);         break;
-        case FIELD_TYPE_UINT64:   writeUint64Impl(id, (uint64_t)val);         break;
-        case FIELD_TYPE_INT32:    writeInt32Impl(id, (int)val);               break;
-        case FIELD_TYPE_FIXED64:  writeFixed64Impl(id, (uint64_t)val);        break;
-        case FIELD_TYPE_FIXED32:  writeFixed32Impl(id, (uint32_t)val);        break;
-        case FIELD_TYPE_UINT32:   writeUint32Impl(id, (uint32_t)val);         break;
-        case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val);            break;
-        case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val);      break;
-        case FIELD_TYPE_SINT32:   writeZigzagInt32Impl(id, (int)val);         break;
-        case FIELD_TYPE_SINT64:   writeZigzagInt64Impl(id, (long long)val);   break;
-        case FIELD_TYPE_ENUM:     writeEnumImpl(id, (int)val);                break;
-        case FIELD_TYPE_BOOL:     writeBoolImpl(id, val != 0);                break;
-        default:
-            ALOGW("Field type %d is not supported when writing long long val.",
-                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
-            return false;
-    }
-    return true;
+    return internalWrite(fieldId, val, "long long");
 }
 
 bool
@@ -168,8 +131,8 @@
             writeBoolImpl(id, val);
             return true;
         default:
-            ALOGW("Field type %d is not supported when writing bool val.",
-                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
+            ALOGW("Field type %" PRIu64 " is not supported when writing bool val.",
+                    (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT);
             return false;
     }
 }
@@ -184,8 +147,8 @@
             writeUtf8StringImpl(id, val.c_str(), val.size());
             return true;
         default:
-            ALOGW("Field type %d is not supported when writing string val.",
-                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
+            ALOGW("Field type %" PRIu64 " is not supported when writing string val.",
+                    (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT);
             return false;
     }
 }
@@ -205,8 +168,8 @@
             writeMessageBytesImpl(id, val, size);
             return true;
         default:
-            ALOGW("Field type %d is not supported when writing char[] val.",
-                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
+            ALOGW("Field type %" PRIu64 " is not supported when writing char[] val.",
+                    (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT);
             return false;
     }
 }
@@ -281,12 +244,14 @@
 {
     if (token != mExpectedObjectToken) {
         ALOGE("Unexpected token: 0x%" PRIx64 ", should be 0x%" PRIx64, token, mExpectedObjectToken);
+        mDepth = UINT32_C(-1); // make depth invalid
         return;
     }
 
     uint32_t depth = getDepthFromToken(token);
     if (depth != (mDepth & 0x01ff)) {
         ALOGE("Unexpected depth: %" PRIu32 ", should be %" PRIu32, depth, mDepth);
+        mDepth = UINT32_C(-1); // make depth invalid
         return;
     }
     mDepth--;
@@ -319,7 +284,7 @@
 ProtoOutputStream::compact() {
     if (mCompact) return true;
     if (mDepth != 0) {
-        ALOGE("Can't compact when depth(%" PRIu32 ") is not zero. Missing calls to end.", mDepth);
+        ALOGE("Can't compact when depth(%" PRIu32 ") is not zero. Missing or extra calls to end.", mDepth);
         return false;
     }
     // record the size of the original buffer.
@@ -462,24 +427,11 @@
 {
     if (!compact()) {
         ALOGE("compact failed, the ProtoOutputStream data is corrupted!");
-        // TODO: handle this error
+        return 0;
     }
     return mBuffer.size();
 }
 
-static bool write_all(int fd, uint8_t const* buf, size_t size)
-{
-    while (size > 0) {
-        ssize_t amt = ::write(fd, buf, size);
-        if (amt < 0) {
-            return false;
-        }
-        size -= amt;
-        buf += amt;
-    }
-    return true;
-}
-
 bool
 ProtoOutputStream::flush(int fd)
 {
@@ -488,7 +440,7 @@
 
     EncodedBuffer::iterator it = mBuffer.begin();
     while (it.readBuffer() != NULL) {
-        if (!write_all(fd, it.readBuffer(), it.currentToRead())) return false;
+        if (!android::base::WriteFully(fd, it.readBuffer(), it.currentToRead())) return false;
         it.rp()->move(it.currentToRead());
     }
     return true;
@@ -499,7 +451,7 @@
 {
     if (!compact()) {
         ALOGE("compact failed, the ProtoOutputStream data is corrupted!");
-        // TODO: handle this error
+        mBuffer.clear();
     }
     return mBuffer.begin();
 }
@@ -554,17 +506,17 @@
 }
 
 inline void
-ProtoOutputStream::writeInt64Impl(uint32_t id, long long val)
+ProtoOutputStream::writeInt64Impl(uint32_t id, int64_t val)
 {
     mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
-    mBuffer.writeRawVarint64((uint64_t)val);
+    mBuffer.writeRawVarint64(val);
 }
 
 inline void
-ProtoOutputStream::writeInt32Impl(uint32_t id, int val)
+ProtoOutputStream::writeInt32Impl(uint32_t id, int32_t val)
 {
     mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
-    mBuffer.writeRawVarint32((uint32_t)val);
+    mBuffer.writeRawVarint32(val);
 }
 
 inline void
@@ -596,28 +548,28 @@
 }
 
 inline void
-ProtoOutputStream::writeSFixed64Impl(uint32_t id, long long val)
+ProtoOutputStream::writeSFixed64Impl(uint32_t id, int64_t val)
 {
     mBuffer.writeHeader(id, WIRE_TYPE_FIXED64);
-    mBuffer.writeRawFixed64((uint64_t)val);
+    mBuffer.writeRawFixed64(val);
 }
 
 inline void
-ProtoOutputStream::writeSFixed32Impl(uint32_t id, int val)
+ProtoOutputStream::writeSFixed32Impl(uint32_t id, int32_t val)
 {
     mBuffer.writeHeader(id, WIRE_TYPE_FIXED32);
-    mBuffer.writeRawFixed32((uint32_t)val);
+    mBuffer.writeRawFixed32(val);
 }
 
 inline void
-ProtoOutputStream::writeZigzagInt64Impl(uint32_t id, long long val)
+ProtoOutputStream::writeZigzagInt64Impl(uint32_t id, int64_t val)
 {
     mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
     mBuffer.writeRawVarint64((val << 1) ^ (val >> 63));
 }
 
 inline void
-ProtoOutputStream::writeZigzagInt32Impl(uint32_t id, int val)
+ProtoOutputStream::writeZigzagInt32Impl(uint32_t id, int32_t val)
 {
     mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
     mBuffer.writeRawVarint32((val << 1) ^ (val >> 31));
diff --git a/libs/protoutil/tests/EncodedBuffer_test.cpp b/libs/protoutil/tests/EncodedBuffer_test.cpp
index 615ab4a..964fc8e 100644
--- a/libs/protoutil/tests/EncodedBuffer_test.cpp
+++ b/libs/protoutil/tests/EncodedBuffer_test.cpp
@@ -17,9 +17,138 @@
 
 using namespace android::util;
 
+constexpr size_t TEST_CHUNK_SIZE = 16UL;
+constexpr size_t TEST_CHUNK_HALF_SIZE = TEST_CHUNK_SIZE / 2;
+constexpr size_t TEST_CHUNK_3X_SIZE = 3 * TEST_CHUNK_SIZE;
+
+static void expectPointer(EncodedBuffer::Pointer* p, size_t pos) {
+    EXPECT_EQ(p->pos(), pos);
+    EXPECT_EQ(p->index(), pos / TEST_CHUNK_SIZE);
+    EXPECT_EQ(p->offset(), pos % TEST_CHUNK_SIZE);
+}
+
+TEST(EncodedBufferTest, WriteSimple) {
+    EncodedBuffer buffer(TEST_CHUNK_SIZE);
+    EXPECT_EQ(buffer.size(), 0UL);
+    expectPointer(buffer.wp(), 0);
+    EXPECT_EQ(buffer.currentToWrite(), TEST_CHUNK_SIZE);
+    for (size_t i = 0; i < TEST_CHUNK_HALF_SIZE; i++) {
+        buffer.writeRawByte(50 + i);
+    }
+    EXPECT_EQ(buffer.size(), TEST_CHUNK_HALF_SIZE);
+    expectPointer(buffer.wp(), TEST_CHUNK_HALF_SIZE);
+    EXPECT_EQ(buffer.currentToWrite(), TEST_CHUNK_HALF_SIZE);
+    for (size_t i = 0; i < TEST_CHUNK_SIZE; i++) {
+        buffer.writeRawByte(80 + i);
+    }
+    EXPECT_EQ(buffer.size(), TEST_CHUNK_SIZE + TEST_CHUNK_HALF_SIZE);
+    expectPointer(buffer.wp(), TEST_CHUNK_SIZE + TEST_CHUNK_HALF_SIZE);
+    EXPECT_EQ(buffer.currentToWrite(), TEST_CHUNK_HALF_SIZE);
+
+    // verifies the buffer's data
+    expectPointer(buffer.ep(), 0);
+    for (size_t i = 0; i < TEST_CHUNK_HALF_SIZE; i++) {
+        EXPECT_EQ(buffer.readRawByte(), 50 + i);
+    }
+    for (size_t i = 0; i < TEST_CHUNK_SIZE; i++) {
+        EXPECT_EQ(buffer.readRawByte(), 80 + i);
+    }
+
+    // clears the buffer
+    buffer.clear();
+    EXPECT_EQ(buffer.size(), 0UL);
+    expectPointer(buffer.wp(), 0);
+}
+
+TEST(EncodedBufferTest, WriteVarint) {
+    EncodedBuffer buffer(TEST_CHUNK_SIZE);
+    size_t expected_buffer_size = 0;
+    EXPECT_EQ(buffer.writeRawVarint32(13), 1);
+    expected_buffer_size += 1;
+    EXPECT_EQ(buffer.size(), expected_buffer_size);
+    EXPECT_EQ(buffer.writeRawVarint32(UINT32_C(-1)), 5);
+    expected_buffer_size += 5;
+    EXPECT_EQ(buffer.size(), expected_buffer_size);
+
+    EXPECT_EQ(buffer.writeRawVarint64(200), 2);
+    expected_buffer_size += 2;
+    EXPECT_EQ(buffer.size(), expected_buffer_size);
+    EXPECT_EQ(buffer.writeRawVarint64(UINT64_C(-1)), 10);
+    expected_buffer_size += 10;
+    EXPECT_EQ(buffer.size(), expected_buffer_size);
+
+    buffer.writeRawFixed32(UINT32_C(-1));
+    expected_buffer_size += 4;
+    EXPECT_EQ(buffer.size(), expected_buffer_size);
+    buffer.writeRawFixed64(UINT64_C(-1));
+    expected_buffer_size += 8;
+    EXPECT_EQ(buffer.size(), expected_buffer_size);
+
+    EXPECT_EQ(buffer.writeHeader(32, 2), 2);
+    expected_buffer_size += 2;
+    EXPECT_EQ(buffer.size(), expected_buffer_size);
+
+    // verify data are correctly written to the buffer.
+    expectPointer(buffer.ep(), 0);
+    EXPECT_EQ(buffer.readRawVarint(), UINT32_C(13));
+    EXPECT_EQ(buffer.readRawVarint(), UINT32_C(-1));
+    EXPECT_EQ(buffer.readRawVarint(), UINT64_C(200));
+    EXPECT_EQ(buffer.readRawVarint(), UINT64_C(-1));
+    EXPECT_EQ(buffer.readRawFixed32(), UINT32_C(-1));
+    EXPECT_EQ(buffer.readRawFixed64(), UINT64_C(-1));
+    EXPECT_EQ(buffer.readRawVarint(), UINT64_C((32 << 3) + 2));
+    expectPointer(buffer.ep(), expected_buffer_size);
+}
+
+TEST(EncodedBufferTest, Edit) {
+    EncodedBuffer buffer(TEST_CHUNK_SIZE);
+    buffer.writeRawFixed64(0xdeadbeefdeadbeef);
+    EXPECT_EQ(buffer.readRawFixed64(), UINT64_C(0xdeadbeefdeadbeef));
+
+    buffer.editRawFixed32(4, 0x12345678);
+    // fixed 64 is little endian order.
+    buffer.ep()->rewind(); // rewind ep for readRawFixed64 from 0
+    EXPECT_EQ(buffer.readRawFixed64(), UINT64_C(0x12345678deadbeef));
+
+    buffer.wp()->rewind();
+    expectPointer(buffer.wp(), 0);
+    buffer.copy(4, 3);
+    buffer.ep()->rewind(); // rewind ep for readRawFixed64 from 0
+    EXPECT_EQ(buffer.readRawFixed64(), UINT64_C(0x12345678de345678));
+}
+
+TEST(EncodedBufferTest, ReadSimple) {
+    EncodedBuffer buffer(TEST_CHUNK_SIZE);
+    for (size_t i = 0; i < TEST_CHUNK_3X_SIZE; i++) {
+        buffer.writeRawByte(i);
+    }
+    auto iter = buffer.begin();
+    EXPECT_EQ(iter.size(), TEST_CHUNK_3X_SIZE);
+    EXPECT_EQ(iter.bytesRead(), 0);
+
+    expectPointer(iter.rp(), 0);
+    while (iter.readBuffer() != NULL) {
+        iter.rp()->move(iter.currentToRead());
+    }
+    EXPECT_EQ(iter.bytesRead(), TEST_CHUNK_3X_SIZE);
+    expectPointer(iter.rp(), TEST_CHUNK_3X_SIZE);
+
+    iter.rp()->rewind();
+    expectPointer(iter.rp(), 0);
+    uint8_t val = 0;
+    while (iter.hasNext()) {
+        EXPECT_EQ(iter.next(), val);
+        val++;
+    }
+    EXPECT_EQ(iter.bytesRead(), TEST_CHUNK_3X_SIZE);
+    expectPointer(iter.rp(), TEST_CHUNK_3X_SIZE);
+}
+
 TEST(EncodedBufferTest, ReadVarint) {
     EncodedBuffer buffer;
     uint64_t val = UINT64_C(1522865904593);
-    buffer.writeRawVarint64(val);
-    EXPECT_EQ(val, buffer.begin().readRawVarint());
+    size_t len = buffer.writeRawVarint64(val);
+    auto iter = buffer.begin();
+    EXPECT_EQ(iter.size(), len);
+    EXPECT_EQ(iter.readRawVarint(), val);
 }
diff --git a/libs/protoutil/tests/ProtoOutputStream_test.cpp b/libs/protoutil/tests/ProtoOutputStream_test.cpp
new file mode 100644
index 0000000..27ee13d
--- /dev/null
+++ b/libs/protoutil/tests/ProtoOutputStream_test.cpp
@@ -0,0 +1,228 @@
+// 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.
+
+#include <android-base/file.h>
+#include <android-base/test_utils.h>
+#include <android/util/protobuf.h>
+#include <android/util/ProtoOutputStream.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "frameworks/base/libs/protoutil/tests/test.pb.h"
+
+using namespace android::base;
+using namespace android::util;
+using ::testing::StrEq;
+
+static std::string flushToString(ProtoOutputStream* proto) {
+    TemporaryFile tf;
+    std::string content;
+
+    EXPECT_NE(tf.fd, -1);
+    EXPECT_TRUE(proto->flush(tf.fd));
+    EXPECT_TRUE(ReadFileToString(tf.path, &content));
+    return content;
+}
+
+static std::string iterateToString(ProtoOutputStream* proto) {
+    std::string content;
+    content.reserve(proto->size());
+    auto iter = proto->data();
+    while (iter.hasNext()) {
+        content.push_back(iter.next());
+    }
+    return content;
+}
+
+TEST(ProtoOutputStreamTest, Primitives) {
+    std::string s = "hello";
+    const char b[5] = { 'a', 'p', 'p', 'l', 'e' };
+
+    ProtoOutputStream proto;
+    EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | PrimitiveProto::kValInt32FieldNumber, 123));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_INT64 | PrimitiveProto::kValInt64FieldNumber, -1LL));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_FLOAT | PrimitiveProto::kValFloatFieldNumber, -23.5f));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_DOUBLE | PrimitiveProto::kValDoubleFieldNumber, 324.5));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_UINT32 | PrimitiveProto::kValUint32FieldNumber, 3424));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_UINT64 | PrimitiveProto::kValUint64FieldNumber, 57LL));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_FIXED32 | PrimitiveProto::kValFixed32FieldNumber, -20));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_FIXED64 | PrimitiveProto::kValFixed64FieldNumber, -37LL));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_BOOL | PrimitiveProto::kValBoolFieldNumber, true));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_STRING | PrimitiveProto::kValStringFieldNumber, s));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_BYTES | PrimitiveProto::kValBytesFieldNumber, b, 5));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_SFIXED32 | PrimitiveProto::kValSfixed32FieldNumber, 63));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_SFIXED64 | PrimitiveProto::kValSfixed64FieldNumber, -54));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_SINT32 | PrimitiveProto::kValSint32FieldNumber, -533));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_SINT64 | PrimitiveProto::kValSint64FieldNumber, -61224762453LL));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_ENUM | PrimitiveProto::kValEnumFieldNumber, 2));
+
+    PrimitiveProto primitives;
+    ASSERT_TRUE(primitives.ParseFromString(flushToString(&proto)));
+    EXPECT_EQ(primitives.val_int32(), 123);
+    EXPECT_EQ(primitives.val_int64(), -1);
+    EXPECT_EQ(primitives.val_float(), -23.5f);
+    EXPECT_EQ(primitives.val_double(), 324.5f);
+    EXPECT_EQ(primitives.val_uint32(), 3424);
+    EXPECT_EQ(primitives.val_uint64(), 57);
+    EXPECT_EQ(primitives.val_fixed32(), -20);
+    EXPECT_EQ(primitives.val_fixed64(), -37);
+    EXPECT_EQ(primitives.val_bool(), true);
+    EXPECT_THAT(primitives.val_string(), StrEq(s.c_str()));
+    EXPECT_THAT(primitives.val_bytes(), StrEq("apple"));
+    EXPECT_EQ(primitives.val_sfixed32(), 63);
+    EXPECT_EQ(primitives.val_sfixed64(), -54);
+    EXPECT_EQ(primitives.val_sint32(), -533);
+    EXPECT_EQ(primitives.val_sint64(), -61224762453LL);
+    EXPECT_EQ(primitives.val_enum(), PrimitiveProto_Count_TWO);
+}
+
+TEST(ProtoOutputStreamTest, Complex) {
+    std::string name1 = "cat";
+    std::string name2 = "dog";
+    const char data1[6] = { 'f', 'u', 'n', 'n', 'y', '!' };
+    const char data2[4] = { 'f', 'o', 'o', 'd' };
+
+    ProtoOutputStream proto;
+    EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 23));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 101));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, -72));
+    uint64_t token1 = proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
+    EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 12));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_STRING | ComplexProto::Log::kNameFieldNumber, name1));
+    // specify the length to test the write(id, bytes, length) function.
+    EXPECT_TRUE(proto.write(FIELD_TYPE_BYTES | ComplexProto::Log::kDataFieldNumber, data1, 5));
+    proto.end(token1);
+    uint64_t token2 = proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
+    EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 98));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_STRING | ComplexProto::Log::kNameFieldNumber, name2));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_BYTES | ComplexProto::Log::kDataFieldNumber, data2, 4));
+    proto.end(token2);
+
+    ComplexProto complex;
+    ASSERT_TRUE(complex.ParseFromString(iterateToString(&proto)));
+    EXPECT_EQ(complex.ints_size(), 3);
+    EXPECT_EQ(complex.ints(0), 23);
+    EXPECT_EQ(complex.ints(1), 101);
+    EXPECT_EQ(complex.ints(2), -72);
+    EXPECT_EQ(complex.logs_size(), 2);
+    ComplexProto::Log log1 = complex.logs(0);
+    EXPECT_EQ(log1.id(), 12);
+    EXPECT_THAT(log1.name(), StrEq(name1.c_str()));
+    EXPECT_THAT(log1.data(), StrEq("funny")); // should not contain '!'
+    ComplexProto::Log log2 = complex.logs(1);
+    EXPECT_EQ(log2.id(), 98);
+    EXPECT_THAT(log2.name(), StrEq(name2.c_str()));
+    EXPECT_THAT(log2.data(), StrEq("food"));
+}
+
+TEST(ProtoOutputStreamTest, Reusability) {
+    ProtoOutputStream proto;
+    EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 32));
+    EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 15));
+    EXPECT_EQ(proto.bytesWritten(), 4);
+    EXPECT_EQ(proto.size(), 4);
+    // Can't write to proto after compact
+    EXPECT_FALSE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 94));
+
+    ComplexProto beforeClear;
+    ASSERT_TRUE(beforeClear.ParseFromString(flushToString(&proto)));
+    EXPECT_EQ(beforeClear.ints_size(), 2);
+    EXPECT_EQ(beforeClear.ints(0), 32);
+    EXPECT_EQ(beforeClear.ints(1), 15);
+
+    proto.clear();
+    EXPECT_EQ(proto.bytesWritten(), 0);
+    EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 1076));
+
+    ComplexProto afterClear;
+    ASSERT_TRUE(afterClear.ParseFromString(flushToString(&proto)));
+    EXPECT_EQ(afterClear.ints_size(), 1);
+    EXPECT_EQ(afterClear.ints(0), 1076);
+}
+
+TEST(ProtoOutputStreamTest, AdvancedEncoding) {
+    ProtoOutputStream proto;
+    proto.writeRawVarint((ComplexProto::kIntsFieldNumber << FIELD_ID_SHIFT) + WIRE_TYPE_VARINT);
+    proto.writeRawVarint(UINT64_C(-123809234));
+    proto.writeLengthDelimitedHeader(ComplexProto::kLogsFieldNumber, 8);
+    proto.writeRawByte((ComplexProto::Log::kDataFieldNumber << FIELD_ID_SHIFT) + WIRE_TYPE_LENGTH_DELIMITED);
+    proto.writeRawByte(6);
+    proto.writeRawByte('b');
+    proto.writeRawByte('a');
+    proto.writeRawByte('n');
+    proto.writeRawByte('a');
+    proto.writeRawByte('n');
+    proto.writeRawByte('a');
+    uint64_t token = proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
+    proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 14);
+    proto.end(token);
+
+    ComplexProto complex;
+    ASSERT_TRUE(complex.ParseFromString(flushToString(&proto)));
+    EXPECT_EQ(complex.ints_size(), 1);
+    EXPECT_EQ(complex.ints(0), UINT64_C(-123809234));
+    EXPECT_EQ(complex.logs_size(), 2);
+    ComplexProto::Log log1 = complex.logs(0);
+    EXPECT_FALSE(log1.has_id());
+    EXPECT_FALSE(log1.has_name());
+    EXPECT_THAT(log1.data(), StrEq("banana"));
+    ComplexProto::Log log2 = complex.logs(1);
+    EXPECT_EQ(log2.id(), 14);
+    EXPECT_FALSE(log2.has_name());
+    EXPECT_FALSE(log2.has_data());
+}
+
+TEST(ProtoOutputStreamTest, InvalidTypes) {
+    ProtoOutputStream proto;
+    EXPECT_FALSE(proto.write(FIELD_TYPE_UNKNOWN | PrimitiveProto::kValInt32FieldNumber, 790));
+    EXPECT_FALSE(proto.write(FIELD_TYPE_ENUM | PrimitiveProto::kValEnumFieldNumber, 234.34));
+    EXPECT_FALSE(proto.write(FIELD_TYPE_BOOL | PrimitiveProto::kValBoolFieldNumber, 18.73f));
+    EXPECT_EQ(proto.size(), 0);
+}
+
+TEST(ProtoOutputStreamTest, NoEndCalled) {
+    ProtoOutputStream proto;
+    proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
+    proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 53);
+    // no proto.end called
+    EXPECT_NE(proto.bytesWritten(), 0);
+    EXPECT_EQ(proto.size(), 0);
+    EXPECT_EQ(proto.data().size(), 0);
+    EXPECT_FALSE(proto.flush(STDOUT_FILENO));
+}
+
+
+TEST(ProtoOutputStreamTest, TwoEndCalled) {
+    ProtoOutputStream proto;
+    uint64_t token = proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
+    proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 53);
+    proto.end(token);
+    proto.end(token);
+    EXPECT_NE(proto.bytesWritten(), 0);
+    EXPECT_EQ(proto.size(), 0);
+    EXPECT_EQ(proto.data().size(), 0);
+    EXPECT_FALSE(proto.flush(STDOUT_FILENO));
+}
+
+TEST(ProtoOutputStreamTest, NoStartCalled) {
+    ProtoOutputStream proto;
+    uint64_t wrongToken = UINT64_C(324536345);
+    // no proto.start called
+    proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 53);
+    proto.end(wrongToken);
+    EXPECT_NE(proto.bytesWritten(), 0);
+    EXPECT_EQ(proto.size(), 0);
+    EXPECT_EQ(proto.data().size(), 0);
+    EXPECT_FALSE(proto.flush(STDOUT_FILENO));
+}
diff --git a/libs/protoutil/tests/protobuf_test.cpp b/libs/protoutil/tests/protobuf_test.cpp
new file mode 100644
index 0000000..5ca3e64
--- /dev/null
+++ b/libs/protoutil/tests/protobuf_test.cpp
@@ -0,0 +1,51 @@
+// 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.
+#include <android/util/protobuf.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using namespace android::util;
+
+TEST(ProtobufTest, All) {
+    EXPECT_EQ(read_wire_type(UINT32_C(17)), 1);
+    EXPECT_EQ(read_field_id(UINT32_C(17)), 2);
+    EXPECT_EQ(get_varint_size(UINT64_C(234134)), 3);
+    EXPECT_EQ(get_varint_size(UINT64_C(-1)), 10);
+
+    constexpr uint8_t UNSET_BYTE = 0xAB;
+
+    uint8_t buf[11];
+    memset(buf, UNSET_BYTE, sizeof(buf));
+    EXPECT_EQ(write_raw_varint(buf, UINT64_C(150)) - buf, 2);
+    EXPECT_EQ(buf[0], 0x96);
+    EXPECT_EQ(buf[1], 0x01);
+    EXPECT_EQ(buf[2], UNSET_BYTE);
+
+    memset(buf, UNSET_BYTE, sizeof(buf));
+    EXPECT_EQ(write_raw_varint(buf, UINT64_C(-2)) - buf, 10);
+    EXPECT_EQ(buf[0], 0xfe);
+    for (int i = 1; i < 9; i++) {
+        EXPECT_EQ(buf[i], 0xff);
+    }
+    EXPECT_EQ(buf[9], 0x01);
+    EXPECT_EQ(buf[10], UNSET_BYTE);
+
+    uint8_t header[20];
+    memset(header, UNSET_BYTE, sizeof(header));
+    EXPECT_EQ(write_length_delimited_tag_header(header, 3, 150) - header, 3);
+    EXPECT_EQ(header[0], 26);
+    EXPECT_EQ(header[1], 0x96);
+    EXPECT_EQ(header[2], 0x01);
+    EXPECT_EQ(header[3], UNSET_BYTE);
+}
\ No newline at end of file
diff --git a/libs/protoutil/tests/test.proto b/libs/protoutil/tests/test.proto
new file mode 100644
index 0000000..52c55f3
--- /dev/null
+++ b/libs/protoutil/tests/test.proto
@@ -0,0 +1,42 @@
+// This proto file is only used for testing purpose.
+syntax = "proto2";
+
+package android.util;
+
+message PrimitiveProto {
+
+    optional int32 val_int32 = 1;
+    optional int64 val_int64 = 2;
+    optional float val_float = 3;
+    optional double val_double = 4;
+    optional uint32 val_uint32 = 5;
+    optional uint64 val_uint64 = 6;
+    optional fixed32 val_fixed32 = 7;
+    optional fixed64 val_fixed64 = 8;
+    optional bool val_bool = 9;
+    optional string val_string = 10;
+    optional bytes val_bytes = 11;
+    optional sfixed32 val_sfixed32 = 12;
+    optional sfixed64 val_sfixed64 = 13;
+    optional sint32 val_sint32 = 14;
+    optional sint64 val_sint64 = 15;
+
+    enum Count {
+        ZERO = 0;
+        ONE = 1;
+        TWO = 2;
+    };
+    optional Count val_enum = 16;
+}
+
+message ComplexProto {
+
+    repeated int32 ints = 1;
+
+    message Log {
+        optional int32 id = 1;
+        optional string name = 2;
+        optional bytes data = 3;
+    }
+    repeated Log logs = 2;
+}
diff --git a/location/java/android/location/GnssMeasurementsEvent.java b/location/java/android/location/GnssMeasurementsEvent.java
index 072a7fe..34c7354 100644
--- a/location/java/android/location/GnssMeasurementsEvent.java
+++ b/location/java/android/location/GnssMeasurementsEvent.java
@@ -74,6 +74,13 @@
         /**
          * The client is not allowed to register for GNSS Measurements in general or in the
          * requested mode.
+         *
+         * <p>Such a status is returned when a client tries to request a functionality from the GNSS
+         * chipset while another client has an ongoing request that does not allow such
+         * functionality to be performed.
+         *
+         * <p>If such a status is received, one would try again at a later time point where no
+         * other client is having a conflicting request.
          */
         public static final int STATUS_NOT_ALLOWED = 3;
 
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index c9d2f7f..703f2dc 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -17,6 +17,7 @@
 package android.location;
 
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -999,6 +1000,7 @@
      * @see #isComplete
      * @hide
      */
+    @TestApi
     @SystemApi
     public void makeComplete() {
         if (mProvider == null) mProvider = "?";
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 7ac1529..3a0a58e 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -86,7 +86,7 @@
  * <p>
  * Once the app has a sessionId, it can construct a MediaCrypto object from the UUID and
  * sessionId.  The MediaCrypto object is registered with the MediaCodec in the
- * {@link MediaCodec.#configure} method to enable the codec to decrypt content.
+ * {@link MediaCodec#configure} method to enable the codec to decrypt content.
  * <p>
  * When the app has constructed {@link android.media.MediaExtractor},
  * {@link android.media.MediaCodec} and {@link android.media.MediaCrypto} objects,
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index f476a6c..8a757b8 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -488,6 +488,7 @@
         private int mCompilation;
         private boolean mIsDrm;
         private boolean mNoMedia;   // flag to suppress file from appearing in media tables
+        private boolean mScanSuccess;
         private int mWidth;
         private int mHeight;
 
@@ -502,6 +503,7 @@
             mFileType = 0;
             mFileSize = fileSize;
             mIsDrm = false;
+            mScanSuccess = true;
 
             if (!isDirectory) {
                 if (!noMedia && isNoMediaFile(path)) {
@@ -623,14 +625,6 @@
                     if (noMedia) {
                         result = endFile(entry, false, false, false, false, false);
                     } else {
-                        String lowpath = path.toLowerCase(Locale.ROOT);
-                        boolean ringtones = (lowpath.indexOf(RINGTONES_DIR) > 0);
-                        boolean notifications = (lowpath.indexOf(NOTIFICATIONS_DIR) > 0);
-                        boolean alarms = (lowpath.indexOf(ALARMS_DIR) > 0);
-                        boolean podcasts = (lowpath.indexOf(PODCAST_DIR) > 0);
-                        boolean music = (lowpath.indexOf(MUSIC_DIR) > 0) ||
-                            (!ringtones && !notifications && !alarms && !podcasts);
-
                         boolean isaudio = MediaFile.isAudioFileType(mFileType);
                         boolean isvideo = MediaFile.isVideoFileType(mFileType);
                         boolean isimage = MediaFile.isImageFileType(mFileType);
@@ -642,13 +636,22 @@
 
                         // we only extract metadata for audio and video files
                         if (isaudio || isvideo) {
-                            processFile(path, mimeType, this);
+                            mScanSuccess = processFile(path, mimeType, this);
                         }
 
                         if (isimage) {
-                            processImageFile(path);
+                            mScanSuccess = processImageFile(path);
                         }
 
+                        String lowpath = path.toLowerCase(Locale.ROOT);
+                        boolean ringtones = mScanSuccess && (lowpath.indexOf(RINGTONES_DIR) > 0);
+                        boolean notifications = mScanSuccess &&
+                                (lowpath.indexOf(NOTIFICATIONS_DIR) > 0);
+                        boolean alarms = mScanSuccess && (lowpath.indexOf(ALARMS_DIR) > 0);
+                        boolean podcasts = mScanSuccess && (lowpath.indexOf(PODCAST_DIR) > 0);
+                        boolean music = mScanSuccess && ((lowpath.indexOf(MUSIC_DIR) > 0) ||
+                            (!ringtones && !notifications && !alarms && !podcasts));
+
                         result = endFile(entry, ringtones, notifications, alarms, music, podcasts);
                     }
                 }
@@ -816,16 +819,18 @@
             return genreTagValue;
         }
 
-        private void processImageFile(String path) {
+        private boolean processImageFile(String path) {
             try {
                 mBitmapOptions.outWidth = 0;
                 mBitmapOptions.outHeight = 0;
                 BitmapFactory.decodeFile(path, mBitmapOptions);
                 mWidth = mBitmapOptions.outWidth;
                 mHeight = mBitmapOptions.outHeight;
+                return mWidth > 0 && mHeight > 0;
             } catch (Throwable th) {
                 // ignore;
             }
+            return false;
         }
 
         public void setMimeType(String mimeType) {
@@ -878,7 +883,7 @@
                     }
                 } else if (MediaFile.isImageFileType(mFileType)) {
                     // FIXME - add DESCRIPTION
-                } else if (MediaFile.isAudioFileType(mFileType)) {
+                } else if (mScanSuccess && MediaFile.isAudioFileType(mFileType)) {
                     map.put(Audio.Media.ARTIST, (mArtist != null && mArtist.length() > 0) ?
                             mArtist : MediaStore.UNKNOWN_STRING);
                     map.put(Audio.Media.ALBUM_ARTIST, (mAlbumArtist != null &&
@@ -894,6 +899,10 @@
                     map.put(Audio.Media.DURATION, mDuration);
                     map.put(Audio.Media.COMPILATION, mCompilation);
                 }
+                if (!mScanSuccess) {
+                    // force mediaprovider to not determine the media type from the mime type
+                    map.put(Files.FileColumns.MEDIA_TYPE, 0);
+                }
             }
             return map;
         }
@@ -1001,7 +1010,7 @@
 
             Uri tableUri = mFilesUri;
             MediaInserter inserter = mMediaInserter;
-            if (!mNoMedia) {
+            if (mScanSuccess && !mNoMedia) {
                 if (MediaFile.isVideoFileType(mFileType)) {
                     tableUri = mVideoUri;
                 } else if (MediaFile.isImageFileType(mFileType)) {
@@ -1071,7 +1080,7 @@
                 values.remove(MediaStore.MediaColumns.DATA);
 
                 int mediaType = 0;
-                if (!MediaScanner.isNoMediaPath(entry.mPath)) {
+                if (mScanSuccess && !MediaScanner.isNoMediaPath(entry.mPath)) {
                     int fileType = MediaFile.getFileTypeForMimeType(mMimeType);
                     if (MediaFile.isAudioFileType(fileType)) {
                         mediaType = FileColumns.MEDIA_TYPE_AUDIO;
@@ -1890,7 +1899,7 @@
     }
 
     private native void processDirectory(String path, MediaScannerClient client);
-    private native void processFile(String path, String mimeType, MediaScannerClient client);
+    private native boolean processFile(String path, String mimeType, MediaScannerClient client);
     private native void setLocale(String locale);
 
     public native byte[] extractAlbumArt(FileDescriptor fd);
diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java
index c9ec752..107ce8e 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerManager.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerManager.java
@@ -262,25 +262,6 @@
     }
 
     /**
-     * Starts recognition on the given model id. All events from the model will be sent to the
-     * PendingIntent.
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
-    public int startRecognition(UUID soundModelId, PendingIntent callbackIntent,
-            RecognitionConfig config) {
-        if (soundModelId == null || callbackIntent == null || config == null) {
-            return STATUS_ERROR;
-        }
-        try {
-            return mSoundTriggerService.startRecognitionForIntent(new ParcelUuid(soundModelId),
-                    callbackIntent, config);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Starts recognition for the given model id. All events from the model will be sent to the
      * service.
      *
@@ -324,7 +305,7 @@
             return STATUS_ERROR;
         }
         try {
-            return mSoundTriggerService.stopRecognitionForIntent(new ParcelUuid(soundModelId));
+            return mSoundTriggerService.stopRecognitionForService(new ParcelUuid(soundModelId));
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index 3b475b2..c0ceb01 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -264,7 +264,7 @@
     env->ReleaseStringUTFChars(path, pathStr);
 }
 
-static void
+static jboolean
 android_media_MediaScanner_processFile(
         JNIEnv *env, jobject thiz, jstring path,
         jstring mimeType, jobject client)
@@ -275,17 +275,17 @@
     MediaScanner *mp = getNativeScanner_l(env, thiz);
     if (mp == NULL) {
         jniThrowException(env, kRunTimeException, "No scanner available");
-        return;
+        return false;
     }
 
     if (path == NULL) {
         jniThrowException(env, kIllegalArgumentException, NULL);
-        return;
+        return false;
     }
 
     const char *pathStr = env->GetStringUTFChars(path, NULL);
     if (pathStr == NULL) {  // Out of memory
-        return;
+        return false;
     }
 
     const char *mimeTypeStr =
@@ -293,7 +293,7 @@
     if (mimeType && mimeTypeStr == NULL) {  // Out of memory
         // ReleaseStringUTFChars can be called with an exception pending.
         env->ReleaseStringUTFChars(path, pathStr);
-        return;
+        return false;
     }
 
     MyMediaScannerClient myClient(env, client);
@@ -305,6 +305,7 @@
     if (mimeType) {
         env->ReleaseStringUTFChars(mimeType, mimeTypeStr);
     }
+    return result != MEDIA_SCAN_RESULT_ERROR;
 }
 
 static void
@@ -421,7 +422,7 @@
 
     {
         "processFile",
-        "(Ljava/lang/String;Ljava/lang/String;Landroid/media/MediaScannerClient;)V",
+        "(Ljava/lang/String;Ljava/lang/String;Landroid/media/MediaScannerClient;)Z",
         (void *)android_media_MediaScanner_processFile
     },
 
diff --git a/nfc-extras/Android.bp b/nfc-extras/Android.bp
new file mode 100644
index 0000000..cbacd48
--- /dev/null
+++ b/nfc-extras/Android.bp
@@ -0,0 +1,21 @@
+//
+// 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.
+//
+
+java_sdk_library {
+    name: "com.android.nfc_extras",
+    srcs: ["java/**/*.java"],
+    api_packages: ["com.android.nfc_extras"],
+}
diff --git a/nfc-extras/Android.mk b/nfc-extras/Android.mk
deleted file mode 100644
index 03de00c..0000000
--- a/nfc-extras/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := com.android.nfc_extras
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := $(call all-java-files-under,java)
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := com.android.nfc_extras-stubs-gen
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_SRC_FILES := $(call all-java-files-under,java)
-# This is to reference SdkConstant annotation; not part of this lib.
-LOCAL_DROIDDOC_SOURCE_PATH := frameworks/base/core/java/android/annotation
-LOCAL_DROIDDOC_STUB_OUT_DIR := $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/com.android.nfc_extras.stubs_intermediates/src
-LOCAL_DROIDDOC_OPTIONS:= \
-    -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 \
-    -stubpackages com.android.nfc_extras \
-    -nodocs
-LOCAL_UNINSTALLABLE_MODULE := true
-include $(BUILD_DROIDDOC)
-com_android_nfc_extras_gen_stamp := $(full_target)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := com.android.nfc_extras.stubs
-# This is to reference SdkConstant annotation; not part of this lib.
-LOCAL_SRC_FILES := ../core/java/android/annotation/SdkConstant.java
-LOCAL_SDK_VERSION := current
-LOCAL_ADDITIONAL_DEPENDENCIES := $(com_android_nfc_extras_gen_stamp)
-com_android_nfc_extras_gen_stamp :=
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/nfc-extras/com.android.nfc_extras.xml b/nfc-extras/com.android.nfc_extras.xml
deleted file mode 100644
index 370145d..0000000
--- a/nfc-extras/com.android.nfc_extras.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<permissions>
-    <library name="com.android.nfc_extras"
-            file="/system/framework/com.android.nfc_extras.jar" />
-</permissions>
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index 491f71e..db776c6 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -321,6 +321,7 @@
         // TODO: reuse NetworkMonitor facilities for consistent captive portal detection.
         new Thread(new Runnable() {
             public void run() {
+                final Network network = ResolvUtil.makeNetworkWithPrivateDnsBypass(mNetwork);
                 // Give time for captive portal to open.
                 try {
                     Thread.sleep(1000);
@@ -329,7 +330,7 @@
                 HttpURLConnection urlConnection = null;
                 int httpResponseCode = 500;
                 try {
-                    urlConnection = (HttpURLConnection) mNetwork.openConnection(mUrl);
+                    urlConnection = (HttpURLConnection) network.openConnection(mUrl);
                     urlConnection.setInstanceFollowRedirects(false);
                     urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
                     urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index 7479d9a..b1933373 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -111,13 +111,11 @@
         mWebView.setWebViewClient(mWebViewClient);
         mWebView.setWebChromeClient(new MyWebChromeClient());
 
-        mNetwork = getNetworkForCaptivePortal();
-        if (mNetwork == null) {
+        final Network network = getNetworkForCaptivePortal();
+        if (network == null) {
             requestNetworkForCaptivePortal();
         } else {
-            mCm.bindProcessToNetwork(mNetwork);
-            mCm.setProcessDefaultNetworkForHostResolution(
-                    ResolvUtil.getNetworkWithUseLocalNameserversFlag(mNetwork));
+            setNetwork(network);
             // Start initial page load so WebView finishes loading proxy settings.
             // Actual load of mUrl is initiated by MyWebViewClient.
             mWebView.loadData("", "text/html", null);
@@ -159,6 +157,15 @@
         super.onDestroy();
     }
 
+    private void setNetwork(Network network) {
+        if (network != null) {
+            mCm.bindProcessToNetwork(network);
+            mCm.setProcessDefaultNetworkForHostResolution(
+                    ResolvUtil.getNetworkWithUseLocalNameserversFlag(network));
+        }
+        mNetwork = network;
+    }
+
     // Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties.
     private void setWebViewProxy() {
         LoadedApk loadedApk = getApplication().mLoadedApk;
@@ -235,6 +242,7 @@
     private void testForCaptivePortal() {
         mTestingThread = new Thread(new Runnable() {
             public void run() {
+                final Network network = ResolvUtil.makeNetworkWithPrivateDnsBypass(mNetwork);
                 // Give time for captive portal to open.
                 try {
                     Thread.sleep(1000);
@@ -245,7 +253,7 @@
                 int httpResponseCode = 500;
                 int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_PROBE);
                 try {
-                    urlConnection = (HttpURLConnection) mNetwork.openConnection(
+                    urlConnection = (HttpURLConnection) network.openConnection(
                             new URL(mCm.getCaptivePortalServerUrl()));
                     urlConnection.setInstanceFollowRedirects(false);
                     urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
@@ -292,8 +300,7 @@
             @Override
             public void onAvailable(Network network) {
                 if (DBG) logd("Network available: " + network);
-                mCm.bindProcessToNetwork(network);
-                mNetwork = network;
+                setNetwork(network);
                 runOnUiThreadIfNotFinishing(() -> {
                     if (mReload) {
                         mWebView.reload();
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/PrinterHashMap.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/PrinterHashMap.java
deleted file mode 100644
index 61956f6..0000000
--- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/PrinterHashMap.java
+++ /dev/null
@@ -1,33 +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.
- */
-
-package com.android.printservice.recommendation.plugin.hp;
-
-import android.net.nsd.NsdServiceInfo;
-
-import java.util.HashMap;
-
-final class PrinterHashMap extends HashMap<String, NsdServiceInfo> {
-    public static String getKey(NsdServiceInfo serviceInfo) {
-        return serviceInfo.getServiceName();
-    }
-    public NsdServiceInfo addPrinter(NsdServiceInfo device) {
-        return put(getKey(device), device);
-    }
-    public NsdServiceInfo removePrinter(NsdServiceInfo device) {
-        return remove(getKey(device));
-    }
-}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/ServiceListener.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/ServiceListener.java
index 600af1f..9535ef0 100644
--- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/ServiceListener.java
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/hp/ServiceListener.java
@@ -24,6 +24,7 @@
 
 import com.android.printservice.recommendation.R;
 import com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer;
+import com.android.printservice.recommendation.util.PrinterHashMap;
 
 import java.net.InetAddress;
 import java.util.ArrayList;
@@ -183,9 +184,7 @@
         ArrayList<InetAddress> printerAddressess = new ArrayList<>();
 
         for (PrinterHashMap oneVendorPrinters : mVendorHashMap.values()) {
-            for (NsdServiceInfo printer : oneVendorPrinters.values()) {
-                printerAddressess.add(printer.getHost());
-            }
+            printerAddressess.addAll(oneVendorPrinters.getPrinterAddresses());
         }
 
         return printerAddressess;
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/PrinterHashMap.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/PrinterHashMap.java
deleted file mode 100755
index b88c7c7..0000000
--- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/PrinterHashMap.java
+++ /dev/null
@@ -1,34 +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.
- */
-package com.android.printservice.recommendation.plugin.xerox;
-
-import android.net.nsd.NsdServiceInfo;
-
-import java.util.HashMap;
-
-final class PrinterHashMap extends HashMap<String, NsdServiceInfo> {
-    public static String getKey(NsdServiceInfo serviceInfo) {
-        return serviceInfo.getServiceName();
-    }
-
-    public NsdServiceInfo addPrinter(NsdServiceInfo device) {
-        return put(getKey(device), device);
-    }
-
-    public NsdServiceInfo removePrinter(NsdServiceInfo device) {
-        return remove(getKey(device));
-    }
-}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/ServiceResolver.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/ServiceResolver.java
index 4d0efd8..9ada969 100755
--- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/ServiceResolver.java
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/ServiceResolver.java
@@ -22,6 +22,7 @@
 
 import com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer;
 import com.android.printservice.recommendation.util.NsdResolveQueue;
+import com.android.printservice.recommendation.util.PrinterHashMap;
 
 import java.net.InetAddress;
 import java.util.ArrayList;
@@ -195,12 +196,7 @@
     }
 
     public ArrayList<InetAddress> getPrinters() {
-        ArrayList<InetAddress> printerAddresses = new ArrayList<>();
-        for (NsdServiceInfo printer : mPrinterHashMap.values()) {
-            printerAddresses.add(printer.getHost());
-        }
-
-        return printerAddresses;
+        return mPrinterHashMap.getPrinterAddresses();
     }
 
 }
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/MDNSFilteredDiscovery.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/MDNSFilteredDiscovery.java
index c08ca6e..65cef94 100644
--- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/MDNSFilteredDiscovery.java
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/MDNSFilteredDiscovery.java
@@ -18,6 +18,7 @@
 import android.content.Context;
 import android.net.nsd.NsdManager;
 import android.net.nsd.NsdServiceInfo;
+import android.text.TextUtils;
 import android.util.Log;
 
 import androidx.annotation.GuardedBy;
@@ -27,9 +28,8 @@
 
 import com.android.printservice.recommendation.PrintServicePlugin;
 
-import java.net.InetAddress;
-import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -55,9 +55,9 @@
         boolean matchesCriteria(NsdServiceInfo nsdServiceInfo);
     }
 
-    /** Printer identifiers of the mPrinters found. */
+    /** Printers found. */
     @GuardedBy("mLock")
-    private final @NonNull HashSet<InetAddress> mPrinters;
+    private final @NonNull PrinterHashMap mPrinters;
 
     /** Service types discovered by this plugin */
     private final @NonNull HashSet<String> mServiceTypes;
@@ -97,7 +97,7 @@
         mPrinterFilter = Preconditions.checkNotNull(printerFilter, "printerFilter");
 
         mResolveQueue = NsdResolveQueue.getInstance();
-        mPrinters = new HashSet<>();
+        mPrinters = new PrinterHashMap();
     }
 
     /**
@@ -107,6 +107,12 @@
         return (NsdManager) mContext.getSystemService(Context.NSD_SERVICE);
     }
 
+    private void onChanged() {
+        if (mCallback != null) {
+            mCallback.onChanged(mPrinters.getPrinterAddresses());
+        }
+    }
+
     /**
      * Start the discovery.
      *
@@ -114,7 +120,8 @@
      */
     public void start(@NonNull PrintServicePlugin.PrinterDiscoveryCallback callback) {
         mCallback = callback;
-        mCallback.onChanged(new ArrayList<>(mPrinters));
+
+        onChanged();
 
         for (String serviceType : mServiceTypes) {
             DiscoveryListenerMultiplexer.addListener(getNDSManager(), serviceType, this);
@@ -167,11 +174,12 @@
 
                     @Override
                     public void onServiceResolved(NsdServiceInfo serviceInfo) {
-                        if (mPrinterFilter.matchesCriteria(serviceInfo)) {
+                        if (!TextUtils.isEmpty(PrinterHashMap.getKey(serviceInfo))
+                                && mPrinterFilter.matchesCriteria(serviceInfo)) {
                             if (mCallback != null) {
-                                boolean added = mPrinters.add(serviceInfo.getHost());
-                                if (added) {
-                                    mCallback.onChanged(new ArrayList<>(mPrinters));
+                                NsdServiceInfo old = mPrinters.addPrinter(serviceInfo);
+                                if (!Objects.equals(old, serviceInfo)) {
+                                    onChanged();
                                 }
                             }
                         }
@@ -181,26 +189,9 @@
 
     @Override
     public void onServiceLost(NsdServiceInfo serviceInfo) {
-        mResolveQueue.resolve(getNDSManager(), serviceInfo,
-                new NsdManager.ResolveListener() {
-                    @Override
-                    public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
-                        Log.w(LOG_TAG, "Service lost: Could not resolve " + serviceInfo + ": "
-                                + errorCode);
-                    }
-
-                    @Override
-                    public void onServiceResolved(NsdServiceInfo serviceInfo) {
-                        if (mPrinterFilter.matchesCriteria(serviceInfo)) {
-                            if (mCallback != null) {
-                                boolean removed = mPrinters.remove(serviceInfo.getHost());
-
-                                if (removed) {
-                                    mCallback.onChanged(new ArrayList<>(mPrinters));
-                                }
-                            }
-                        }
-                    }
-                });
+        NsdServiceInfo oldAddress = mPrinters.removePrinter(serviceInfo);
+        if (oldAddress != null) {
+            onChanged();
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/PrinterHashMap.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/PrinterHashMap.java
new file mode 100644
index 0000000..ee35edb
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/util/PrinterHashMap.java
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+package com.android.printservice.recommendation.util;
+
+import android.net.nsd.NsdServiceInfo;
+import android.util.ArrayMap;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+
+/**
+ * Map to store {@link NsdServiceInfo} belonging to printers. If two infos have the same
+ * {@link PrinterHashMap#getKey(NsdServiceInfo) key} they are considered the same.
+ */
+public class PrinterHashMap {
+    private final ArrayMap<String, NsdServiceInfo> mPrinters = new ArrayMap<>();
+
+    /**
+     * Key uniquely identifying a printer.
+     *
+     * @param serviceInfo The service info describing the printer
+     *
+     * @return The key
+     */
+    public static String getKey(NsdServiceInfo serviceInfo) {
+        return serviceInfo.getServiceName();
+    }
+
+    /**
+     * Add a printer.
+     *
+     * @param device The service info of the printer
+     *
+     * @return The service info of the printer that was previously registered for the same key
+     */
+    public NsdServiceInfo addPrinter(NsdServiceInfo device) {
+        return mPrinters.put(getKey(device), device);
+    }
+
+    /**
+     * Remove a printer.
+     *
+     * @param device The service info of the printer
+     *
+     * @return The service info of the printer that was previously registered for the same key
+     */
+    public NsdServiceInfo removePrinter(NsdServiceInfo device) {
+        return mPrinters.remove(getKey(device));
+    }
+
+    /**
+     * @return the addresses of printers
+     */
+    public ArrayList<InetAddress> getPrinterAddresses() {
+        int numPrinters = mPrinters.size();
+        ArrayList<InetAddress> printerAddressess = new ArrayList<>(numPrinters);
+        for (int i = 0; i < numPrinters; i++) {
+            printerAddressess.add(mPrinters.valueAt(i).getHost());
+        }
+
+        return printerAddressess;
+    }
+
+    /**
+     * Remove all printers
+     */
+    public void clear() {
+        mPrinters.clear();
+    }
+
+    /**
+     * @return {@code} true iff the map is empty
+     */
+    public boolean isEmpty() {
+        return mPrinters.isEmpty();
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index b976dd6..7f518c1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -46,6 +46,7 @@
 import com.android.internal.widget.LockPatternUtils;
 
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Utility class to host methods usable in adding a restricted padlock icon and showing admin
@@ -90,29 +91,29 @@
             // Restriction is not enforced.
             return null;
         } else if (enforcingUsers.size() > 1) {
-            return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+            return EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(userRestriction);
         }
 
         final int restrictionSource = enforcingUsers.get(0).getUserRestrictionSource();
         final int adminUserId = enforcingUsers.get(0).getUserHandle().getIdentifier();
-
         if (restrictionSource == UserManager.RESTRICTION_SOURCE_PROFILE_OWNER) {
             // Check if it is a profile owner of the user under consideration.
             if (adminUserId == userId) {
-                return getProfileOwner(context, adminUserId);
+                return getProfileOwner(context, userRestriction, adminUserId);
             } else {
                 // Check if it is a profile owner of a managed profile of the current user.
                 // Otherwise it is in a separate user and we return a default EnforcedAdmin.
                 final UserInfo parentUser = um.getProfileParent(adminUserId);
                 return (parentUser != null && parentUser.id == userId)
-                        ? getProfileOwner(context, adminUserId)
-                        : EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+                        ? getProfileOwner(context, userRestriction, adminUserId)
+                        : EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(userRestriction);
             }
         } else if (restrictionSource == UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) {
             // When the restriction is enforced by device owner, return the device owner admin only
             // if the admin is for the {@param userId} otherwise return a default EnforcedAdmin.
             return adminUserId == userId
-                    ? getDeviceOwner(context) : EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+                    ? getDeviceOwner(context, userRestriction)
+                    : EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(userRestriction);
         }
 
         // If the restriction is enforced by system then return null.
@@ -406,7 +407,6 @@
      * or {@code null} if no quality requirements are set. If the requirements are set by
      * multiple device admins, then the admin component will be set to {@code null} and userId to
      * {@link UserHandle#USER_NULL}.
-     *
      */
     public static EnforcedAdmin checkIfPasswordQualityIsSet(Context context, int userId) {
         final LockSettingCheck check =
@@ -518,6 +518,11 @@
     }
 
     public static EnforcedAdmin getProfileOrDeviceOwner(Context context, int userId) {
+        return getProfileOrDeviceOwner(context, null, userId);
+    }
+
+    public static EnforcedAdmin getProfileOrDeviceOwner(
+            Context context, String enforcedRestriction, int userId) {
         if (userId == UserHandle.USER_NULL) {
             return null;
         }
@@ -528,18 +533,22 @@
         }
         ComponentName adminComponent = dpm.getProfileOwnerAsUser(userId);
         if (adminComponent != null) {
-            return new EnforcedAdmin(adminComponent, userId);
+            return new EnforcedAdmin(adminComponent, enforcedRestriction, userId);
         }
         if (dpm.getDeviceOwnerUserId() == userId) {
             adminComponent = dpm.getDeviceOwnerComponentOnAnyUser();
             if (adminComponent != null) {
-                return new EnforcedAdmin(adminComponent, userId);
+                return new EnforcedAdmin(adminComponent, enforcedRestriction, userId);
             }
         }
         return null;
     }
 
     public static EnforcedAdmin getDeviceOwner(Context context) {
+        return getDeviceOwner(context, null);
+    }
+
+    private static EnforcedAdmin getDeviceOwner(Context context, String enforcedRestriction) {
         final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
         if (dpm == null) {
@@ -547,12 +556,18 @@
         }
         ComponentName adminComponent = dpm.getDeviceOwnerComponentOnAnyUser();
         if (adminComponent != null) {
-            return new EnforcedAdmin(adminComponent, dpm.getDeviceOwnerUserId());
+            return new EnforcedAdmin(
+                    adminComponent, enforcedRestriction, dpm.getDeviceOwnerUserId());
         }
         return null;
     }
 
     private static EnforcedAdmin getProfileOwner(Context context, int userId) {
+        return getProfileOwner(context, null, userId);
+    }
+
+    private static EnforcedAdmin getProfileOwner(
+            Context context, String enforcedRestriction, int userId) {
         if (userId == UserHandle.USER_NULL) {
             return null;
         }
@@ -563,7 +578,7 @@
         }
         ComponentName adminComponent = dpm.getProfileOwnerAsUser(userId);
         if (adminComponent != null) {
-            return new EnforcedAdmin(adminComponent, userId);
+            return new EnforcedAdmin(adminComponent, enforcedRestriction, userId);
         }
         return null;
     }
@@ -626,6 +641,7 @@
                 && isCurrentUserOrProfile(context, admin.userId)) {
             targetUserId = admin.userId;
         }
+        intent.putExtra(DevicePolicyManager.EXTRA_RESTRICTION, admin.enforcedRestriction);
         context.startActivityAsUser(intent, new UserHandle(targetUserId));
     }
 
@@ -700,53 +716,71 @@
     }
 
     public static class EnforcedAdmin {
+        @Nullable
         public ComponentName component = null;
+        /**
+         * The restriction enforced by admin. It could be any user restriction or policy like
+         * {@link DevicePolicyManager#POLICY_DISABLE_CAMERA}.
+         */
+        @Nullable
+        public String enforcedRestriction = null;
         public int userId = UserHandle.USER_NULL;
 
         // We use this to represent the case where a policy is enforced by multiple admins.
         public final static EnforcedAdmin MULTIPLE_ENFORCED_ADMIN = new EnforcedAdmin();
 
+        public static EnforcedAdmin createDefaultEnforcedAdminWithRestriction(
+                String enforcedRestriction) {
+            EnforcedAdmin enforcedAdmin = new EnforcedAdmin();
+            enforcedAdmin.enforcedRestriction = enforcedRestriction;
+            return enforcedAdmin;
+        }
+
         public EnforcedAdmin(ComponentName component, int userId) {
             this.component = component;
             this.userId = userId;
         }
 
+        public EnforcedAdmin(ComponentName component, String enforcedRestriction, int userId) {
+            this.component = component;
+            this.enforcedRestriction = enforcedRestriction;
+            this.userId = userId;
+        }
+
         public EnforcedAdmin(EnforcedAdmin other) {
             if (other == null) {
                 throw new IllegalArgumentException();
             }
             this.component = other.component;
+            this.enforcedRestriction = other.enforcedRestriction;
             this.userId = other.userId;
         }
 
-        public EnforcedAdmin() {}
+        public EnforcedAdmin() {
+        }
 
         @Override
-        public boolean equals(Object object) {
-            if (object == this) return true;
-            if (!(object instanceof EnforcedAdmin)) return false;
-            EnforcedAdmin other = (EnforcedAdmin) object;
-            if (userId != other.userId) {
-                return false;
-            }
-            if ((component == null && other.component == null) ||
-                    (component != null && component.equals(other.component))) {
-                return true;
-            }
-            return false;
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            EnforcedAdmin that = (EnforcedAdmin) o;
+            return userId == that.userId &&
+                    Objects.equals(component, that.component) &&
+                    Objects.equals(enforcedRestriction, that.enforcedRestriction);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(component, enforcedRestriction, userId);
         }
 
         @Override
         public String toString() {
-            return "EnforcedAdmin{component=" + component + ",userId=" + userId + "}";
-        }
-
-        public void copyTo(EnforcedAdmin other) {
-            if (other == null) {
-                throw new IllegalArgumentException();
-            }
-            other.component = component;
-            other.userId = userId;
+            return "EnforcedAdmin{" +
+                    "component=" + component +
+                    ", enforcedRestriction='" + enforcedRestriction +
+                    ", userId=" + userId +
+                    '}';
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index c756fdb..b4b5b58 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -15,6 +15,7 @@
 import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.location.LocationManager;
+import android.media.AudioManager;
 import android.net.ConnectivityManager;
 import android.os.BatteryManager;
 import android.os.SystemProperties;
@@ -26,7 +27,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.UserIcons;
 import com.android.settingslib.drawable.UserIconDrawable;
-import com.android.settingslib.wrapper.LocationManagerWrapper;
+
 import java.text.NumberFormat;
 
 public class Utils {
@@ -68,8 +69,7 @@
                 intent, UserHandle.of(userId), android.Manifest.permission.WRITE_SECURE_SETTINGS);
         LocationManager locationManager =
                 (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
-        LocationManagerWrapper wrapper = new LocationManagerWrapper(locationManager);
-        wrapper.setLocationEnabledForUser(enabled, UserHandle.of(userId));
+        locationManager.setLocationEnabledForUser(enabled, UserHandle.of(userId));
     }
 
     public static boolean updateLocationMode(Context context, int oldMode, int newMode, int userId,
@@ -373,4 +373,15 @@
                 isDefaultOn ? 1 : 0)
                 != 0;
     }
+
+    /**
+     * get that {@link AudioManager#getMode()} is in ringing/call/communication(VoIP) status.
+     */
+    public static boolean isAudioModeOngoingCall(Context context) {
+        final AudioManager audioManager = context.getSystemService(AudioManager.class);
+        final int audioMode = audioManager.getMode();
+        return audioMode == AudioManager.MODE_RINGTONE
+                || audioMode == AudioManager.MODE_IN_CALL
+                || audioMode == AudioManager.MODE_IN_COMMUNICATION;
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java b/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java
index 246ca47..3102239 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java
@@ -29,7 +29,6 @@
 import android.util.IconDrawableFactory;
 
 import com.android.settingslib.widget.CandidateInfo;
-import com.android.settingslib.wrapper.PackageManagerWrapper;
 
 /**
  * Data model representing an app in DefaultAppPicker UI.
@@ -40,18 +39,18 @@
     public final ComponentName componentName;
     public final PackageItemInfo packageItemInfo;
     public final String summary;
-    protected final PackageManagerWrapper mPm;
+    protected final PackageManager mPm;
     private final Context mContext;
 
-    public DefaultAppInfo(Context context, PackageManagerWrapper pm, int uid, ComponentName cn) {
+    public DefaultAppInfo(Context context, PackageManager pm, int uid, ComponentName cn) {
         this(context, pm, uid, cn, null /* summary */, true /* enabled */);
     }
 
-    public DefaultAppInfo(Context context, PackageManagerWrapper pm, PackageItemInfo info) {
+    public DefaultAppInfo(Context context, PackageManager pm, PackageItemInfo info) {
         this(context, pm, info, null /* summary */, true /* enabled */);
     }
 
-    public DefaultAppInfo(Context context, PackageManagerWrapper pm, int uid, ComponentName cn,
+    public DefaultAppInfo(Context context, PackageManager pm, int uid, ComponentName cn,
                           String summary, boolean enabled) {
         super(enabled);
         mContext = context;
@@ -62,7 +61,7 @@
         this.summary = summary;
     }
 
-    public DefaultAppInfo(Context context, PackageManagerWrapper pm, PackageItemInfo info,
+    public DefaultAppInfo(Context context, PackageManager pm, PackageItemInfo info,
                           String summary, boolean enabled) {
         super(enabled);
         mContext = context;
@@ -79,17 +78,17 @@
             try {
                 final ComponentInfo componentInfo = getComponentInfo();
                 if (componentInfo != null) {
-                    return componentInfo.loadLabel(mPm.getPackageManager());
+                    return componentInfo.loadLabel(mPm);
                 } else {
                     final ApplicationInfo appInfo = mPm.getApplicationInfoAsUser(
                             componentName.getPackageName(), 0, userId);
-                    return appInfo.loadLabel(mPm.getPackageManager());
+                    return appInfo.loadLabel(mPm);
                 }
             } catch (PackageManager.NameNotFoundException e) {
                 return null;
             }
         } else if (packageItemInfo != null) {
-            return packageItemInfo.loadLabel(mPm.getPackageManager());
+            return packageItemInfo.loadLabel(mPm);
         } else {
             return null;
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java b/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java
index 3c3c70a..454d1dc 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java
@@ -32,8 +32,6 @@
 import android.provider.Settings;
 import android.util.Slog;
 
-import com.android.settingslib.wrapper.PackageManagerWrapper;
-
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -127,8 +125,7 @@
         mServices.clear();
         final int user = ActivityManager.getCurrentUser();
 
-        final PackageManagerWrapper pmWrapper =
-                new PackageManagerWrapper(mContext.getPackageManager());
+        final PackageManager pmWrapper = mContext.getPackageManager();
         List<ResolveInfo> installedServices = pmWrapper.queryIntentServicesAsUser(
                 new Intent(mIntentAction),
                 PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index 6b99024..6272954 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -20,7 +20,6 @@
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothCodecConfig;
-import android.bluetooth.BluetoothCodecStatus;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
 import android.bluetooth.BluetoothUuid;
@@ -28,9 +27,7 @@
 import android.os.ParcelUuid;
 import android.util.Log;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.R;
-import com.android.settingslib.wrapper.BluetoothA2dpWrapper;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -43,7 +40,6 @@
     private Context mContext;
 
     private BluetoothA2dp mService;
-    private BluetoothA2dpWrapper mServiceWrapper;
     private boolean mIsProfileReady;
 
     private final LocalBluetoothAdapter mLocalAdapter;
@@ -67,7 +63,6 @@
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
             if (V) Log.d(TAG,"Bluetooth service connected");
             mService = (BluetoothA2dp) proxy;
-            mServiceWrapper = new BluetoothA2dpWrapper(mService);
             // We just bound to the service, so refresh the UI for any connected A2DP devices.
             List<BluetoothDevice> deviceList = mService.getConnectedDevices();
             while (!deviceList.isEmpty()) {
@@ -105,11 +100,6 @@
                 BluetoothProfile.A2DP);
     }
 
-    @VisibleForTesting
-    void setBluetoothA2dpWrapper(BluetoothA2dpWrapper wrapper) {
-        mServiceWrapper = wrapper;
-    }
-
     public boolean isConnectable() {
         return true;
     }
@@ -203,12 +193,12 @@
     }
 
     public boolean supportsHighQualityAudio(BluetoothDevice device) {
-        int support = mServiceWrapper.supportsOptionalCodecs(device);
+        int support = mService.supportsOptionalCodecs(device);
         return support == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED;
     }
 
     public boolean isHighQualityAudioEnabled(BluetoothDevice device) {
-        int enabled = mServiceWrapper.getOptionalCodecsEnabled(device);
+        int enabled = mService.getOptionalCodecsEnabled(device);
         if (enabled != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN) {
             return enabled == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED;
         } else if (getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED &&
@@ -219,8 +209,8 @@
             return true;
         }
         BluetoothCodecConfig codecConfig = null;
-        if (mServiceWrapper.getCodecStatus(device) != null) {
-            codecConfig = mServiceWrapper.getCodecStatus(device).getCodecConfig();
+        if (mService.getCodecStatus(device) != null) {
+            codecConfig = mService.getCodecStatus(device).getCodecConfig();
         }
         if (codecConfig != null)  {
             return !codecConfig.isMandatoryCodec();
@@ -233,7 +223,7 @@
         int prefValue = enabled
                 ? BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED
                 : BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED;
-        mServiceWrapper.setOptionalCodecsEnabled(device, prefValue);
+        mService.setOptionalCodecsEnabled(device, prefValue);
         if (getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED) {
             return;
         }
@@ -253,8 +243,8 @@
         // We want to get the highest priority codec, since that's the one that will be used with
         // this device, and see if it is high-quality (ie non-mandatory).
         BluetoothCodecConfig[] selectable = null;
-        if (mServiceWrapper.getCodecStatus(device) != null) {
-            selectable = mServiceWrapper.getCodecStatus(device).getCodecsSelectableCapabilities();
+        if (mService.getCodecStatus(device) != null) {
+            selectable = mService.getCodecStatus(device).getCodecsSelectableCapabilities();
             // To get the highest priority, we sort in reverse.
             Arrays.sort(selectable,
                     (a, b) -> {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index fb268ab..e7d7ab3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -490,6 +490,7 @@
     }
 
     private void dispatchAudioModeChanged() {
+        mDeviceManager.dispatchAudioModeChanged();
         synchronized (mCallbacks) {
             for (BluetoothCallback callback : mCallbacks) {
                 callback.onAudioModeChanged();
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 7d0587a..95e443c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -23,6 +23,7 @@
 import android.bluetooth.BluetoothUuid;
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.media.AudioManager;
 import android.os.ParcelUuid;
 import android.os.SystemClock;
 import android.text.TextUtils;
@@ -51,6 +52,7 @@
     private final Context mContext;
     private final LocalBluetoothAdapter mLocalAdapter;
     private final LocalBluetoothProfileManager mProfileManager;
+    private final AudioManager mAudioManager;
     private final BluetoothDevice mDevice;
     //TODO: consider remove, BluetoothDevice.getName() is already cached
     private String mName;
@@ -123,7 +125,6 @@
     private boolean mIsActiveDeviceA2dp = false;
     private boolean mIsActiveDeviceHeadset = false;
     private boolean mIsActiveDeviceHearingAid = false;
-
     /**
      * Describes the current device and profile for logging.
      *
@@ -185,6 +186,7 @@
         mContext = context;
         mLocalAdapter = adapter;
         mProfileManager = profileManager;
+        mAudioManager = context.getSystemService(AudioManager.class);
         mDevice = device;
         mProfileConnectionState = new HashMap<LocalBluetoothProfile, Integer>();
         fillData();
@@ -538,6 +540,12 @@
     }
 
     /**
+     * Update the profile audio state.
+     */
+    void onAudioModeChanged() {
+        dispatchAttributesChanged();
+    }
+    /**
      * Get the device status as active or non-active per Bluetooth profile.
      *
      * @param bluetoothProfile the Bluetooth profile
@@ -972,12 +980,14 @@
 
     /**
      * @return resource for string that discribes the connection state of this device.
+     * case 1: idle or playing media, show "Active" on the only one A2DP active device.
+     * case 2: in phone call, show "Active" on the only one HFP active device
      */
     public String getConnectionSummary() {
-        boolean profileConnected = false;       // at least one profile is connected
-        boolean a2dpNotConnected = false;       // A2DP is preferred but not connected
-        boolean hfpNotConnected = false;    // HFP is preferred but not connected
-        boolean hearingAidNotConnected = false; // Hearing Aid is preferred but not connected
+        boolean profileConnected = false;    // Updated as long as BluetoothProfile is connected
+        boolean a2dpConnected = true;        // A2DP is connected
+        boolean hfpConnected = true;         // HFP is connected
+        boolean hearingAidConnected = true;  // Hearing Aid is connected
 
         for (LocalBluetoothProfile profile : getProfiles()) {
             int connectionStatus = getProfileConnectionState(profile);
@@ -994,13 +1004,13 @@
                 case BluetoothProfile.STATE_DISCONNECTED:
                     if (profile.isProfileReady()) {
                         if ((profile instanceof A2dpProfile) ||
-                            (profile instanceof A2dpSinkProfile)){
-                            a2dpNotConnected = true;
+                                (profile instanceof A2dpSinkProfile)) {
+                            a2dpConnected = false;
                         } else if ((profile instanceof HeadsetProfile) ||
-                                   (profile instanceof HfpClientProfile)) {
-                            hfpNotConnected = true;
-                        } else if (profile instanceof  HearingAidProfile) {
-                            hearingAidNotConnected = true;
+                                (profile instanceof HfpClientProfile)) {
+                            hfpConnected = false;
+                        } else if (profile instanceof HearingAidProfile) {
+                            hearingAidConnected = false;
                         }
                     }
                     break;
@@ -1019,65 +1029,50 @@
                     com.android.settingslib.Utils.formatPercentage(batteryLevel);
         }
 
-        // Prepare the string for the Active Device summary
-        String[] activeDeviceStringsArray = mContext.getResources().getStringArray(
-                R.array.bluetooth_audio_active_device_summaries);
-        String activeDeviceString = activeDeviceStringsArray[0];  // Default value: not active
-        if (mIsActiveDeviceA2dp && mIsActiveDeviceHeadset) {
-            activeDeviceString = activeDeviceStringsArray[1];     // Active for Media and Phone
-        } else {
-            if (mIsActiveDeviceA2dp) {
-                activeDeviceString = activeDeviceStringsArray[2]; // Active for Media only
-            }
-            if (mIsActiveDeviceHeadset) {
-                activeDeviceString = activeDeviceStringsArray[3]; // Active for Phone only
-            }
-        }
-        if (!hearingAidNotConnected && mIsActiveDeviceHearingAid) {
-            activeDeviceString = activeDeviceStringsArray[1];
-            return mContext.getString(R.string.bluetooth_connected, activeDeviceString);
-        }
-
+        int stringRes = R.string.bluetooth_pairing;
+        //when profile is connected, information would be available
         if (profileConnected) {
-            if (a2dpNotConnected && hfpNotConnected) {
+            if (a2dpConnected || hfpConnected || hearingAidConnected) {
+                //contain battery information
                 if (batteryLevelPercentageString != null) {
-                    return mContext.getString(
-                            R.string.bluetooth_connected_no_headset_no_a2dp_battery_level,
-                            batteryLevelPercentageString, activeDeviceString);
+                    //device is in phone call
+                    if (com.android.settingslib.Utils.isAudioModeOngoingCall(mContext)) {
+                        if (mIsActiveDeviceHeadset) {
+                            stringRes = R.string.bluetooth_active_battery_level;
+                        } else {
+                            stringRes = R.string.bluetooth_battery_level;
+                        }
+                    } else {//device is not in phone call(ex. idle or playing media)
+                        //need to check if A2DP and HearingAid are exclusive
+                        if (mIsActiveDeviceHearingAid || mIsActiveDeviceA2dp) {
+                            stringRes = R.string.bluetooth_active_battery_level;
+                        } else {
+                            stringRes = R.string.bluetooth_battery_level;
+                        }
+                    }
                 } else {
-                    return mContext.getString(R.string.bluetooth_connected_no_headset_no_a2dp,
-                            activeDeviceString);
+                    //no battery information
+                    if (com.android.settingslib.Utils.isAudioModeOngoingCall(mContext)) {
+                        if (mIsActiveDeviceHeadset) {
+                            stringRes = R.string.bluetooth_active_no_battery_level;
+                        }
+                    } else {
+                        if (mIsActiveDeviceHearingAid || mIsActiveDeviceA2dp) {
+                            stringRes = R.string.bluetooth_active_no_battery_level;
+                        }
+                    }
                 }
-
-            } else if (a2dpNotConnected) {
+            } else {//unknown profile with battery information
                 if (batteryLevelPercentageString != null) {
-                    return mContext.getString(R.string.bluetooth_connected_no_a2dp_battery_level,
-                            batteryLevelPercentageString, activeDeviceString);
-                } else {
-                    return mContext.getString(R.string.bluetooth_connected_no_a2dp,
-                            activeDeviceString);
-                }
-
-            } else if (hfpNotConnected) {
-                if (batteryLevelPercentageString != null) {
-                    return mContext.getString(R.string.bluetooth_connected_no_headset_battery_level,
-                            batteryLevelPercentageString, activeDeviceString);
-                } else {
-                    return mContext.getString(R.string.bluetooth_connected_no_headset,
-                            activeDeviceString);
-                }
-            } else {
-                if (batteryLevelPercentageString != null) {
-                    return mContext.getString(R.string.bluetooth_connected_battery_level,
-                            batteryLevelPercentageString, activeDeviceString);
-                } else {
-                    return mContext.getString(R.string.bluetooth_connected, activeDeviceString);
+                    stringRes = R.string.bluetooth_battery_level;
                 }
             }
         }
 
-        return getBondState() == BluetoothDevice.BOND_BONDING ?
-                mContext.getString(R.string.bluetooth_pairing) : null;
+        return (stringRes != R.string.bluetooth_pairing
+                || getBondState() == BluetoothDevice.BOND_BONDING)
+                ? mContext.getString(stringRes, batteryLevelPercentageString)
+                : null;
     }
 
     /**
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index 3b1e4ce..15f6983 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -358,6 +358,12 @@
         }
     }
 
+    public synchronized void dispatchAudioModeChanged() {
+        for (CachedBluetoothDevice cachedDevice : mCachedDevices) {
+            cachedDevice.onAudioModeChanged();
+        }
+    }
+
     private void log(String msg) {
         if (DEBUG) {
             Log.d(TAG, msg);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
index 5f7ba586..38c8a88 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
@@ -24,6 +24,7 @@
 import android.os.ParcelUuid;
 import android.util.Log;
 
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -248,4 +249,8 @@
     public int getMaxConnectedAudioDevices() {
         return mAdapter.getMaxConnectedAudioDevices();
     }
+
+    public List<Integer> getSupportedProfiles() {
+        return mAdapter.getSupportedProfiles();
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index b499fda..1c7c855 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -40,6 +40,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 
@@ -158,9 +159,13 @@
         addProfile(mPbapProfile, PbapServerProfile.NAME,
              BluetoothPbap.ACTION_CONNECTION_STATE_CHANGED);
 
-        mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager, this);
-        addProfile(mHearingAidProfile, HearingAidProfile.NAME,
-                   BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+        List<Integer> supportedList = mLocalAdapter.getSupportedProfiles();
+        if (supportedList.contains(BluetoothProfile.HEARING_AID)) {
+            mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager,
+                                                       this);
+            addProfile(mHearingAidProfile, HearingAidProfile.NAME,
+                       BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+        }
         if (DEBUG) Log.d(TAG, "LocalBluetoothProfileManager construction complete");
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java b/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java
new file mode 100644
index 0000000..55723f9
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java
@@ -0,0 +1,101 @@
+/*
+ * 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.settingslib.display;
+
+import android.util.MathUtils;
+
+public class BrightnessUtils {
+
+    public static final int GAMMA_SPACE_MAX = 1023;
+
+    // Hybrid Log Gamma constant values
+    private static final float R = 0.5f;
+    private static final float A = 0.17883277f;
+    private static final float B = 0.28466892f;
+    private static final float C = 0.55991073f;
+
+    /**
+     * A function for converting from the gamma space that the slider works in to the
+     * linear space that the setting works in.
+     *
+     * The gamma space effectively provides us a way to make linear changes to the slider that
+     * result in linear changes in perception. If we made changes to the slider in the linear space
+     * then we'd see an approximately logarithmic change in perception (c.f. Fechner's Law).
+     *
+     * Internally, this implements the Hybrid Log Gamma electro-optical transfer function, which is
+     * a slight improvement to the typical gamma transfer function for displays whose max
+     * brightness exceeds the 120 nit reference point, but doesn't set a specific reference
+     * brightness like the PQ function does.
+     *
+     * Note that this transfer function is only valid if the display's backlight value is a linear
+     * control. If it's calibrated to be something non-linear, then a different transfer function
+     * should be used.
+     *
+     * @param val The slider value.
+     * @param min The minimum acceptable value for the setting.
+     * @param max The maximum acceptable value for the setting.
+     * @return The corresponding setting value.
+     */
+    public static final int convertGammaToLinear(int val, int min, int max) {
+        final float normalizedVal = MathUtils.norm(0, GAMMA_SPACE_MAX, val);
+        final float ret;
+        if (normalizedVal <= R) {
+            ret = MathUtils.sq(normalizedVal / R);
+        } else {
+            ret = MathUtils.exp((normalizedVal - C) / A) + B;
+        }
+
+        // HLG is normalized to the range [0, 12], so we need to re-normalize to the range [0, 1]
+        // in order to derive the correct setting value.
+        return Math.round(MathUtils.lerp(min, max, ret / 12));
+    }
+
+    /**
+     * A function for converting from the linear space that the setting works in to the
+     * gamma space that the slider works in.
+     *
+     * The gamma space effectively provides us a way to make linear changes to the slider that
+     * result in linear changes in perception. If we made changes to the slider in the linear space
+     * then we'd see an approximately logarithmic change in perception (c.f. Fechner's Law).
+     *
+     * Internally, this implements the Hybrid Log Gamma opto-electronic transfer function, which is
+     * a slight improvement to the typical gamma transfer function for displays whose max
+     * brightness exceeds the 120 nit reference point, but doesn't set a specific reference
+     * brightness like the PQ function does.
+     *
+     * Note that this transfer function is only valid if the display's backlight value is a linear
+     * control. If it's calibrated to be something non-linear, then a different transfer function
+     * should be used.
+     *
+     * @param val The brightness setting value.
+     * @param min The minimum acceptable value for the setting.
+     * @param max The maximum acceptable value for the setting.
+     * @return The corresponding slider value
+     */
+    public static final int convertLinearToGamma(int val, int min, int max) {
+        // For some reason, HLG normalizes to the range [0, 12] rather than [0, 1]
+        final float normalizedVal = MathUtils.norm(min, max, val) * 12;
+        final float ret;
+        if (normalizedVal <= 1f) {
+            ret = MathUtils.sqrt(normalizedVal) * R;
+        } else {
+            ret = A * MathUtils.log(normalizedVal - B) + C;
+        }
+
+        return Math.round(MathUtils.lerp(0, GAMMA_SPACE_MAX, ret));
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
index eb9bbf5..026bbd4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
@@ -48,6 +48,7 @@
     private static final boolean DEBUG = false;
     private static final String TAG = "InputMethdAndSubtypeUtl";
 
+    private static final String SUBTYPE_MODE_KEYBOARD = "keyboard";
     private static final char INPUT_METHOD_SEPARATER = ':';
     private static final char INPUT_METHOD_SUBTYPE_SEPARATER = ';';
     private static final int NOT_A_SUBTYPE_ID = -1;
@@ -177,7 +178,7 @@
             final boolean isCurrentInputMethod = imiId.equals(currentInputMethodId);
             final boolean systemIme = imi.isSystem();
             if ((!hasHardKeyboard && InputMethodSettingValuesWrapper.getInstance(
-                    context.getActivity()).isAlwaysCheckedIme(imi, context.getActivity()))
+                    context.getActivity()).isAlwaysCheckedIme(imi))
                     || isImeChecked) {
                 if (!enabledIMEsAndSubtypesMap.containsKey(imiId)) {
                     // imiId has just been enabled
@@ -416,4 +417,19 @@
         }
         return configurationLocale;
     }
+
+    public static boolean isValidSystemNonAuxAsciiCapableIme(InputMethodInfo imi) {
+        if (imi.isAuxiliaryIme() || !imi.isSystem()) {
+            return false;
+        }
+        final int subtypeCount = imi.getSubtypeCount();
+        for (int i = 0; i < subtypeCount; ++i) {
+            final InputMethodSubtype subtype = imi.getSubtypeAt(i);
+            if (SUBTYPE_MODE_KEYBOARD.equalsIgnoreCase(subtype.getMode())
+                    && subtype.isAsciiCapable()) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
index 442a35f..2dec6c3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
@@ -124,7 +124,7 @@
         }
         mInputMethodSettingValues = InputMethodSettingValuesWrapper.getInstance(context);
         mHasPriorityInSorting = imi.isSystem()
-                && mInputMethodSettingValues.isValidSystemNonAuxAsciiCapableIme(imi, context);
+                && InputMethodAndSubtypeUtil.isValidSystemNonAuxAsciiCapableIme(imi);
         setOnPreferenceClickListener(this);
         setOnPreferenceChangeListener(this);
     }
@@ -197,8 +197,7 @@
     }
 
     public void updatePreferenceViews() {
-        final boolean isAlwaysChecked = mInputMethodSettingValues.isAlwaysCheckedIme(
-                mImi, getContext());
+        final boolean isAlwaysChecked = mInputMethodSettingValues.isAlwaysCheckedIme(mImi);
         // When this preference has a switch and an input method should be always enabled,
         // this preference should be disabled to prevent accidentally disabling an input method.
         // This preference should also be disabled in case the admin does not allow this input
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java
index ab017e2..b6786d4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java
@@ -22,15 +22,11 @@
 import android.util.Log;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodSubtype;
-
-import com.android.internal.inputmethod.InputMethodUtils;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Locale;
 
 /**
  * This class is a wrapper for {@link InputMethodManager} and
@@ -47,7 +43,6 @@
     private final ArrayList<InputMethodInfo> mMethodList = new ArrayList<>();
     private final ContentResolver mContentResolver;
     private final InputMethodManager mImm;
-    private final HashSet<InputMethodInfo> mAsciiCapableEnabledImis = new HashSet<>();
 
     public static InputMethodSettingValuesWrapper getInstance(Context context) {
         if (sInstance == null) {
@@ -70,50 +65,32 @@
     public void refreshAllInputMethodAndSubtypes() {
         mMethodList.clear();
         mMethodList.addAll(mImm.getInputMethodList());
-        updateAsciiCapableEnabledImis();
-    }
-
-    // TODO: Add a cts to ensure at least one AsciiCapableSubtypeEnabledImis exist
-    private void updateAsciiCapableEnabledImis() {
-        mAsciiCapableEnabledImis.clear();
-        final List<InputMethodInfo> enabledImis = getEnabledInputMethodList();
-        for (final InputMethodInfo imi : enabledImis) {
-            final int subtypeCount = imi.getSubtypeCount();
-            for (int i = 0; i < subtypeCount; ++i) {
-                final InputMethodSubtype subtype = imi.getSubtypeAt(i);
-                if (InputMethodUtils.SUBTYPE_MODE_KEYBOARD.equalsIgnoreCase(subtype.getMode())
-                        && subtype.isAsciiCapable()) {
-                    mAsciiCapableEnabledImis.add(imi);
-                    break;
-                }
-            }
-        }
     }
 
     public List<InputMethodInfo> getInputMethodList() {
         return new ArrayList<>(mMethodList);
     }
 
-    public boolean isAlwaysCheckedIme(InputMethodInfo imi, Context context) {
+    public boolean isAlwaysCheckedIme(InputMethodInfo imi) {
         final boolean isEnabled = isEnabledImi(imi);
         if (getEnabledInputMethodList().size() <= 1 && isEnabled) {
             return true;
         }
 
         final int enabledValidSystemNonAuxAsciiCapableImeCount =
-                getEnabledValidSystemNonAuxAsciiCapableImeCount(context);
+                getEnabledValidSystemNonAuxAsciiCapableImeCount();
 
         return enabledValidSystemNonAuxAsciiCapableImeCount <= 1
                 && !(enabledValidSystemNonAuxAsciiCapableImeCount == 1 && !isEnabled)
                 && imi.isSystem()
-                && isValidSystemNonAuxAsciiCapableIme(imi, context);
+                && InputMethodAndSubtypeUtil.isValidSystemNonAuxAsciiCapableIme(imi);
     }
 
-    private int getEnabledValidSystemNonAuxAsciiCapableImeCount(Context context) {
+    private int getEnabledValidSystemNonAuxAsciiCapableImeCount() {
         int count = 0;
         final List<InputMethodInfo> enabledImis = getEnabledInputMethodList();
         for (final InputMethodInfo imi : enabledImis) {
-            if (isValidSystemNonAuxAsciiCapableIme(imi, context)) {
+            if (InputMethodAndSubtypeUtil.isValidSystemNonAuxAsciiCapableIme(imi)) {
                 ++count;
             }
         }
@@ -133,25 +110,6 @@
         return false;
     }
 
-    public boolean isValidSystemNonAuxAsciiCapableIme(InputMethodInfo imi, Context context) {
-        if (imi.isAuxiliaryIme()) {
-            return false;
-        }
-        final Locale systemLocale = context.getResources().getConfiguration().locale;
-        if (InputMethodUtils.isSystemImeThatHasSubtypeOf(imi, context,
-                    true /* checkDefaultAttribute */, systemLocale, false /* checkCountry */,
-                    InputMethodUtils.SUBTYPE_MODE_ANY)) {
-            return true;
-        }
-        if (mAsciiCapableEnabledImis.isEmpty()) {
-            Log.w(TAG, "ascii capable subtype enabled imi not found. Fall back to English"
-                    + " Keyboard subtype.");
-            return InputMethodUtils.containsSubtypeOf(imi, Locale.ENGLISH, false /* checkCountry */,
-                    InputMethodUtils.SUBTYPE_MODE_KEYBOARD);
-        }
-        return mAsciiCapableEnabledImis.contains(imi);
-    }
-
     /**
      * Returns the list of the enabled {@link InputMethodInfo} determined by
      * {@link android.provider.Settings.Secure#ENABLED_INPUT_METHODS} rather than just returning
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSubtypePreference.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSubtypePreference.java
index 83c00ea..bb43581 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSubtypePreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSubtypePreference.java
@@ -23,7 +23,6 @@
 import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.inputmethod.InputMethodUtils;
 
 import java.text.Collator;
 import java.util.Locale;
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
index 113256f..e2faf6a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
@@ -354,20 +354,15 @@
             return;
         }
 
-        if (userInfo.isGuest()) {
-            switchToGuest(userInfo.name);
-            return;
-        }
-
         switchToUserId(userInfo.id);
     }
 
     /**
-     * Creates a guest session and switches into the guest session.
+     * Creates a new guest session and switches into the guest session.
      *
      * @param guestName Username for the guest user.
      */
-    public void switchToGuest(String guestName) {
+    public void startNewGuestSession(String guestName) {
         UserInfo guest = mUserManager.createGuest(mContext, guestName);
         if (guest == null) {
             // Couldn't create user, most likely because there are too many, but we haven't
@@ -375,6 +370,7 @@
             Log.w(TAG, "can't create user.");
             return;
         }
+        assignDefaultIcon(guest);
         switchToUserId(guest.id);
     }
 
@@ -417,6 +413,27 @@
         mUserManager.setUserName(user.id, name);
     }
 
+    /**
+     * Gets a bitmap representing the user's default avatar.
+     *
+     * @param userInfo User whose avatar should be returned.
+     * @return Default user icon
+     */
+    public Bitmap getUserDefaultIcon(UserInfo userInfo) {
+        return UserIcons.convertToBitmap(
+                UserIcons.getDefaultUserIcon(mContext.getResources(), userInfo.id, false));
+    }
+
+    /**
+     * Gets a bitmap representing the default icon for a Guest user.
+     *
+     * @return Degault guest icon
+     */
+    public Bitmap getGuestDefaultIcon() {
+        return UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon(
+                mContext.getResources(), UserHandle.USER_NULL, false));
+    }
+
     private void registerReceiver() {
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_REMOVED);
@@ -435,8 +452,7 @@
      * @return Bitmap that has been assigned to the user.
      */
     private Bitmap assignDefaultIcon(UserInfo userInfo) {
-        Bitmap bitmap = UserIcons.convertToBitmap(
-                UserIcons.getDefaultUserIcon(mContext.getResources(), userInfo.id, false));
+        Bitmap bitmap = userInfo.isGuest() ? getGuestDefaultIcon() : getUserDefaultIcon(userInfo);
         mUserManager.setUserIcon(userInfo.id, bitmap);
         return bitmap;
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/wrapper/BluetoothA2dpWrapper.java b/packages/SettingsLib/src/com/android/settingslib/wrapper/BluetoothA2dpWrapper.java
deleted file mode 100644
index 17e3401..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/wrapper/BluetoothA2dpWrapper.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2017 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.settingslib.wrapper;
-
-import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothCodecStatus;
-import android.bluetooth.BluetoothDevice;
-
-/**
- * This class replicates some methods of android.bluetooth.BluetoothA2dp that are new and not
- * yet available in our current version of Robolectric. It provides a thin wrapper to call the real
- * methods in production and a mock in tests.
- */
-public class BluetoothA2dpWrapper {
-
-    private BluetoothA2dp mService;
-
-    public BluetoothA2dpWrapper(BluetoothA2dp service) {
-        mService = service;
-    }
-
-    /**
-     * @return the real {@code BluetoothA2dp} object
-     */
-    public BluetoothA2dp getService() {
-        return mService;
-    }
-
-    /**
-     * Wraps {@code BluetoothA2dp.getCodecStatus}
-     */
-    public BluetoothCodecStatus getCodecStatus(BluetoothDevice device) {
-        return mService.getCodecStatus(device);
-    }
-
-    /**
-     * Wraps {@code BluetoothA2dp.supportsOptionalCodecs}
-     */
-    public int supportsOptionalCodecs(BluetoothDevice device) {
-        return mService.supportsOptionalCodecs(device);
-    }
-
-    /**
-     * Wraps {@code BluetoothA2dp.getOptionalCodecsEnabled}
-     */
-    public int getOptionalCodecsEnabled(BluetoothDevice device) {
-        return mService.getOptionalCodecsEnabled(device);
-    }
-
-    /**
-     * Wraps {@code BluetoothA2dp.setOptionalCodecsEnabled}
-     */
-    public void setOptionalCodecsEnabled(BluetoothDevice device, int value) {
-        mService.setOptionalCodecsEnabled(device, value);
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wrapper/LocationManagerWrapper.java b/packages/SettingsLib/src/com/android/settingslib/wrapper/LocationManagerWrapper.java
deleted file mode 100644
index 1a268a6..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/wrapper/LocationManagerWrapper.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2017 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.settingslib.wrapper;
-
-import android.location.LocationManager;
-import android.os.UserHandle;
-
-/**
- * This class replicates some methods of android.location.LocationManager that are new and not
- * yet available in our current version of Robolectric. It provides a thin wrapper to call the real
- * methods in production and a mock in tests.
- */
-public class LocationManagerWrapper {
-
-    private LocationManager mLocationManager;
-
-    public LocationManagerWrapper(LocationManager locationManager) {
-        mLocationManager = locationManager;
-    }
-
-    /** Returns the real {@code LocationManager} object */
-    public LocationManager getLocationManager() {
-        return mLocationManager;
-    }
-
-    /** Wraps {@code LocationManager.isProviderEnabled} method */
-    public boolean isProviderEnabled(String provider) {
-        return mLocationManager.isProviderEnabled(provider);
-    }
-
-    /** Wraps {@code LocationManager.setProviderEnabledForUser} method */
-    public void setProviderEnabledForUser(String provider, boolean enabled, UserHandle userHandle) {
-        mLocationManager.setProviderEnabledForUser(provider, enabled, userHandle);
-    }
-
-    /** Wraps {@code LocationManager.isLocationEnabled} method */
-    public boolean isLocationEnabled() {
-        return mLocationManager.isLocationEnabled();
-    }
-
-    /** Wraps {@code LocationManager.isLocationEnabledForUser} method */
-    public boolean isLocationEnabledForUser(UserHandle userHandle) {
-        return mLocationManager.isLocationEnabledForUser(userHandle);
-    }
-
-    /** Wraps {@code LocationManager.setLocationEnabledForUser} method */
-    public void setLocationEnabledForUser(boolean enabled, UserHandle userHandle) {
-        mLocationManager.setLocationEnabledForUser(enabled, userHandle);
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wrapper/PackageManagerWrapper.java b/packages/SettingsLib/src/com/android/settingslib/wrapper/PackageManagerWrapper.java
deleted file mode 100644
index 235daf2..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/wrapper/PackageManagerWrapper.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2017 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.settingslib.wrapper;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageDeleteObserver;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-import android.os.storage.VolumeInfo;
-
-import java.util.List;
-
-/**
- * A thin wrapper class that simplifies testing by putting a mockable layer between the application
- * and the PackageManager. This class only provides access to the minimum number of functions from
- * the PackageManager needed for DeletionHelper to work.
- */
-public class PackageManagerWrapper {
-
-    private final PackageManager mPm;
-
-    public PackageManagerWrapper(PackageManager pm) {
-        mPm = pm;
-    }
-
-    /**
-     * Returns the real {@code PackageManager} object.
-     */
-    public PackageManager getPackageManager() {
-        return mPm;
-    }
-
-    /**
-     * Calls {@code PackageManager.getInstalledApplicationsAsUser()}.
-     *
-     * @see android.content.pm.PackageManager#getInstalledApplicationsAsUser
-     */
-    public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
-        return mPm.getInstalledApplicationsAsUser(flags, userId);
-    }
-
-    /**
-     * Calls {@code PackageManager.getInstalledPackagesAsUser}
-     */
-    public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
-        return mPm.getInstalledPackagesAsUser(flags, userId);
-    }
-
-    /**
-     * Calls {@code PackageManager.hasSystemFeature()}.
-     *
-     * @see android.content.pm.PackageManager#hasSystemFeature
-     */
-    public boolean hasSystemFeature(String name) {
-        return mPm.hasSystemFeature(name);
-    }
-
-    /**
-     * Calls {@code PackageManager.queryIntentActivitiesAsUser()}.
-     *
-     * @see android.content.pm.PackageManager#queryIntentActivitiesAsUser
-     */
-    public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
-        return mPm.queryIntentActivitiesAsUser(intent, flags, userId);
-    }
-
-    /**
-     * Calls {@code PackageManager.getInstallReason()}.
-     *
-     * @see android.content.pm.PackageManager#getInstallReason
-     */
-    public int getInstallReason(String packageName, UserHandle user) {
-        return mPm.getInstallReason(packageName, user);
-    }
-
-    /**
-     * Calls {@code PackageManager.getApplicationInfoAsUser}
-     */
-    public ApplicationInfo getApplicationInfoAsUser(String packageName, int i, int userId)
-            throws PackageManager.NameNotFoundException {
-        return mPm.getApplicationInfoAsUser(packageName, i, userId);
-    }
-
-    /**
-     * Calls {@code PackageManager.setDefaultBrowserPackageNameAsUser}
-     */
-    public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
-        return mPm.setDefaultBrowserPackageNameAsUser(packageName, userId);
-    }
-
-    /**
-     * Calls {@code PackageManager.getDefaultBrowserPackageNameAsUser}
-     */
-    public String getDefaultBrowserPackageNameAsUser(int userId) {
-        return mPm.getDefaultBrowserPackageNameAsUser(userId);
-    }
-
-    /**
-     * Calls {@code PackageManager.getHomeActivities}
-     */
-    public ComponentName getHomeActivities(List<ResolveInfo> homeActivities) {
-        return mPm.getHomeActivities(homeActivities);
-    }
-
-    /**
-     * Calls {@code PackageManager.queryIntentServicesAsUser}
-     */
-    public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int i, int user) {
-        return mPm.queryIntentServicesAsUser(intent, i, user);
-    }
-
-    /**
-     * Calls {@code PackageManager.queryIntentServices}
-     */
-    public List<ResolveInfo> queryIntentServices(Intent intent, int i) {
-        return mPm.queryIntentServices(intent, i);
-    }
-
-    /**
-     * Calls {@code PackageManager.replacePreferredActivity}
-     */
-    public void replacePreferredActivity(IntentFilter homeFilter, int matchCategoryEmpty,
-            ComponentName[] componentNames, ComponentName component) {
-        mPm.replacePreferredActivity(homeFilter, matchCategoryEmpty, componentNames, component);
-    }
-
-    /**
-     * Gets information about a particular package from the package manager.
-     *
-     * @param packageName The name of the package we would like information about.
-     * @param i           additional options flags. see javadoc for
-     *                    {@link PackageManager#getPackageInfo(String, int)}
-     * @return The PackageInfo for the requested package
-     */
-    public PackageInfo getPackageInfo(String packageName, int i) throws NameNotFoundException {
-        return mPm.getPackageInfo(packageName, i);
-    }
-
-    /**
-     * Retrieves the icon associated with this particular set of ApplicationInfo
-     *
-     * @param info The ApplicationInfo to retrieve the icon for
-     * @return The icon as a drawable.
-     */
-    public Drawable getUserBadgedIcon(ApplicationInfo info) {
-        return mPm.getUserBadgedIcon(mPm.loadUnbadgedItemIcon(info, info),
-                new UserHandle(UserHandle.getUserId(info.uid)));
-    }
-
-    /**
-     * Retrieves the label associated with the particular set of ApplicationInfo
-     *
-     * @param app The ApplicationInfo to retrieve the label for
-     * @return the label as a CharSequence
-     */
-    public CharSequence loadLabel(ApplicationInfo app) {
-        return app.loadLabel(mPm);
-    }
-
-    /**
-     * Retrieve all activities that can be performed for the given intent.
-     */
-    public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
-        return mPm.queryIntentActivities(intent, flags);
-    }
-
-    /**
-     * Calls {@code PackageManager.getPrimaryStorageCurrentVolume}
-     */
-    public VolumeInfo getPrimaryStorageCurrentVolume() {
-        return mPm.getPrimaryStorageCurrentVolume();
-    }
-
-    /**
-     * Calls {@code PackageManager.deletePackageAsUser}
-     */
-    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags,
-            int userId) {
-        mPm.deletePackageAsUser(packageName, observer, flags, userId);
-    }
-
-    /**
-     * Calls {@code PackageManager.getPackageUidAsUser}
-     */
-    public int getPackageUidAsUser(String pkg, int userId)
-            throws PackageManager.NameNotFoundException {
-        return mPm.getPackageUidAsUser(pkg, userId);
-    }
-
-    /**
-     * Calls {@code PackageManager.setApplicationEnabledSetting}
-     */
-    public void setApplicationEnabledSetting(String packageName, int newState, int flags) {
-        mPm.setApplicationEnabledSetting(packageName, newState, flags);
-    }
-
-    /**
-     * Calls {@code PackageManager.getApplicationEnabledSetting}
-     */
-    public int getApplicationEnabledSetting(String packageName) {
-        return mPm.getApplicationEnabledSetting(packageName);
-    }
-
-    /**
-     * Calls {@code PackageManager.setComponentEnabledSetting}
-     */
-    public void setComponentEnabledSetting(ComponentName componentName, int newState, int flags) {
-        mPm.setComponentEnabledSetting(componentName, newState, flags);
-    }
-
-    /**
-     * Calls {@code PackageManager.getApplicationInfo}
-     */
-    public ApplicationInfo getApplicationInfo(String packageName, int flags)
-            throws NameNotFoundException {
-        return mPm.getApplicationInfo(packageName, flags);
-    }
-
-    /**
-     * Calls {@code PackageManager.getApplicationLabel}
-     */
-    public CharSequence getApplicationLabel(ApplicationInfo info) {
-        return mPm.getApplicationLabel(info);
-    }
-
-    /**
-     * Calls {@code PackageManager.queryBroadcastReceivers}
-     */
-    public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
-        return mPm.queryBroadcastReceivers(intent, flags);
-    }
-}
-
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/inputmethod/InputMethodPreferenceTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/inputmethod/InputMethodPreferenceTest.java
index ab2b97f..93b038e 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/inputmethod/InputMethodPreferenceTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/inputmethod/InputMethodPreferenceTest.java
@@ -125,6 +125,7 @@
         final InputMethodSubtype systemLocaleSubtype =
                 new InputMethodSubtype.InputMethodSubtypeBuilder()
                         .setIsAsciiCapable(true)
+                        .setSubtypeMode("keyboard")
                         .setSubtypeLocale(systemLocale.getLanguage())
                         .build();
 
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java
index 15f7770..54510b2 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java
@@ -247,13 +247,13 @@
     }
 
     @Test
-    public void switchToGuest() {
-        mHelper.switchToGuest("Test Guest");
+    public void startNewGuestSession() {
+        mHelper.startNewGuestSession("Test Guest");
         verify(mUserManager).createGuest(mContext, "Test Guest");
 
         UserInfo guestInfo = new UserInfo(21, "Test Guest", UserInfo.FLAG_GUEST);
         when(mUserManager.createGuest(mContext, "Test Guest")).thenReturn(guestInfo);
-        mHelper.switchToGuest("Test Guest");
+        mHelper.startNewGuestSession("Test Guest");
         verify(mActivityManager).switchUser(21);
     }
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
index 5f60868..710dbc22 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
@@ -32,6 +32,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
+import android.os.UserHandle;
 import android.os.UserManager;
 
 import org.junit.Before;
@@ -42,6 +43,7 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.Arrays;
+import java.util.Collections;
 
 @RunWith(SettingsLibRobolectricTestRunner.class)
 public class RestrictedLockUtilsTest {
@@ -77,6 +79,42 @@
     }
 
     @Test
+    public void checkIfRestrictionEnforced_deviceOwner() {
+        UserManager.EnforcingUser enforcingUser = new UserManager.EnforcingUser(mUserId,
+                UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
+        final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+        when(mUserManager.getUserRestrictionSources(userRestriction,
+                UserHandle.of(mUserId))).
+                thenReturn(Collections.singletonList(enforcingUser));
+        setUpDeviceOwner(mAdmin1);
+
+        EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
+                userRestriction, mUserId);
+
+        assertThat(enforcedAdmin).isNotNull();
+        assertThat(enforcedAdmin.enforcedRestriction).isEqualTo(userRestriction);
+        assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
+    }
+
+    @Test
+    public void checkIfRestrictionEnforced_profileOwner() {
+        UserManager.EnforcingUser enforcingUser = new UserManager.EnforcingUser(mUserId,
+                UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
+        final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+        when(mUserManager.getUserRestrictionSources(userRestriction,
+                UserHandle.of(mUserId))).
+                thenReturn(Collections.singletonList(enforcingUser));
+        setUpProfileOwner(mAdmin1, mUserId);
+
+        EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
+                userRestriction, mUserId);
+
+        assertThat(enforcedAdmin).isNotNull();
+        assertThat(enforcedAdmin.enforcedRestriction).isEqualTo(userRestriction);
+        assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
+    }
+
+    @Test
     public void checkIfDevicePolicyServiceDisabled_noEnforceAdminForManagedProfile() {
         when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(null);
         final EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfAccountManagementDisabled(
@@ -263,4 +301,12 @@
         when(mDevicePolicyManager.getActiveAdminsAsUser(userId))
                 .thenReturn(Arrays.asList(activeAdmins));
     }
+
+    private void setUpDeviceOwner(ComponentName admin) {
+        when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(admin);
+    }
+
+    private void setUpProfileOwner(ComponentName admin, int userId) {
+        when(mDevicePolicyManager.getProfileOwnerAsUser(userId)).thenReturn(admin);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
index 706d0c0..09a2bd2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
 
 import android.app.ActivityManager;
 import android.content.ContentResolver;
@@ -33,14 +34,13 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.location.LocationManager;
+import android.media.AudioManager;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
 import android.text.TextUtils;
 
-import com.android.settingslib.wrapper.LocationManagerWrapper;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -52,6 +52,7 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowAudioManager;
 import org.robolectric.shadows.ShadowSettings;
 
 import java.util.HashMap;
@@ -60,7 +61,7 @@
 @RunWith(SettingsLibRobolectricTestRunner.class)
 @Config(shadows = {
             UtilsTest.ShadowSecure.class,
-            UtilsTest.ShadowLocationManagerWrapper.class})
+            UtilsTest.ShadowLocationManager.class})
 public class UtilsTest {
     private static final double[] TEST_PERCENTAGES = {0, 0.4, 0.5, 0.6, 49, 49.3, 49.8, 50, 100};
     private static final String PERCENTAGE_0 = "0%";
@@ -69,6 +70,7 @@
     private static final String PERCENTAGE_50 = "50%";
     private static final String PERCENTAGE_100 = "100%";
 
+    private ShadowAudioManager mShadowAudioManager;
     private Context mContext;
     @Mock
     private LocationManager mLocationManager;
@@ -79,6 +81,7 @@
         mContext = spy(RuntimeEnvironment.application);
         when(mContext.getSystemService(Context.LOCATION_SERVICE)).thenReturn(mLocationManager);
         ShadowSecure.reset();
+        mShadowAudioManager = shadowOf(mContext.getSystemService(AudioManager.class));
     }
 
     @Test
@@ -187,12 +190,40 @@
         }
     }
 
-    @Implements(value = LocationManagerWrapper.class)
-    public static class ShadowLocationManagerWrapper {
+    @Implements(value = LocationManager.class)
+    public static class ShadowLocationManager {
 
         @Implementation
         public void setLocationEnabledForUser(boolean enabled, UserHandle userHandle) {
             // Do nothing
         }
     }
+
+    @Test
+    public void isAudioModeOngoingCall_modeInCommunication_returnTrue() {
+        mShadowAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
+
+        assertThat(Utils.isAudioModeOngoingCall(mContext)).isTrue();
+    }
+
+    @Test
+    public void isAudioModeOngoingCall_modeInCall_returnTrue() {
+        mShadowAudioManager.setMode(AudioManager.MODE_IN_CALL);
+
+        assertThat(Utils.isAudioModeOngoingCall(mContext)).isTrue();
+    }
+
+    @Test
+    public void isAudioModeOngoingCall_modeRingtone_returnTrue() {
+        mShadowAudioManager.setMode(AudioManager.MODE_RINGTONE);
+
+        assertThat(Utils.isAudioModeOngoingCall(mContext)).isTrue();
+    }
+
+    @Test
+    public void isAudioModeOngoingCall_modeNormal_returnFalse() {
+        mShadowAudioManager.setMode(AudioManager.MODE_NORMAL);
+
+        assertThat(Utils.isAudioModeOngoingCall(mContext)).isFalse();
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/DefaultAppInfoTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/DefaultAppInfoTest.java
index 6a161d0..01f0d78 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/DefaultAppInfoTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/DefaultAppInfoTest.java
@@ -33,7 +33,6 @@
 import android.graphics.drawable.Drawable;
 
 import com.android.settingslib.SettingsLibRobolectricTestRunner;
-import com.android.settingslib.wrapper.PackageManagerWrapper;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -41,7 +40,6 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
 
 @RunWith(SettingsLibRobolectricTestRunner.class)
 public class DefaultAppInfoTest {
@@ -53,8 +51,6 @@
     @Mock
     private PackageManager mPackageManager;
     @Mock
-    private PackageManagerWrapper mPackageManagerWrapper;
-    @Mock
     private ApplicationInfo mApplicationInfo;
     @Mock
     private Drawable mIcon;
@@ -67,8 +63,7 @@
         MockitoAnnotations.initMocks(this);
         mContext = spy(RuntimeEnvironment.application);
         doReturn(mPackageManager).when(mContext).getPackageManager();
-        when(mPackageManagerWrapper.getPackageManager()).thenReturn(mPackageManager);
-        when(mPackageManagerWrapper.getApplicationInfoAsUser(anyString(), anyInt(),
+        when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(),
                 anyInt())).thenReturn(mApplicationInfo);
         when(mPackageManager.loadUnbadgedItemIcon(mPackageItemInfo, mApplicationInfo)).thenReturn(
                 mIcon);
@@ -77,7 +72,7 @@
     @Test
     public void initInfoWithActivityInfo_shouldLoadInfo() {
         mPackageItemInfo.packageName = "test";
-        mInfo = new DefaultAppInfo(mContext, mPackageManagerWrapper, mPackageItemInfo);
+        mInfo = new DefaultAppInfo(mContext, mPackageManager, mPackageItemInfo);
         mInfo.loadLabel();
         Drawable icon = mInfo.loadIcon();
 
@@ -90,7 +85,7 @@
     public void initInfoWithComponent_shouldLoadInfo() {
         when(mComponentName.getPackageName()).thenReturn("com.android.settings");
 
-        mInfo = new DefaultAppInfo(mContext, mPackageManagerWrapper, 0 /* uid */, mComponentName);
+        mInfo = new DefaultAppInfo(mContext, mPackageManager, 0 /* uid */, mComponentName);
         mInfo.getKey();
 
         verify(mComponentName).flattenToString();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
index 334ea16..ef13a5f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
@@ -31,7 +31,6 @@
 import android.content.res.Resources;
 
 import com.android.settingslib.R;
-import com.android.settingslib.wrapper.BluetoothA2dpWrapper;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -49,7 +48,6 @@
     @Mock LocalBluetoothProfileManager mProfileManager;
     @Mock BluetoothDevice mDevice;
     @Mock BluetoothA2dp mBluetoothA2dp;
-    @Mock BluetoothA2dpWrapper mBluetoothA2dpWrapper;
     BluetoothProfile.ServiceListener mServiceListener;
 
     A2dpProfile mProfile;
@@ -68,31 +66,30 @@
 
         mProfile = new A2dpProfile(mContext, mAdapter, mDeviceManager, mProfileManager);
         mServiceListener.onServiceConnected(BluetoothProfile.A2DP, mBluetoothA2dp);
-        mProfile.setBluetoothA2dpWrapper(mBluetoothA2dpWrapper);
     }
 
     @Test
     public void supportsHighQualityAudio() {
-        when(mBluetoothA2dpWrapper.supportsOptionalCodecs(any())).thenReturn(
+        when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
         assertThat(mProfile.supportsHighQualityAudio(mDevice)).isTrue();
 
-        when(mBluetoothA2dpWrapper.supportsOptionalCodecs(any())).thenReturn(
+        when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
         assertThat(mProfile.supportsHighQualityAudio(mDevice)).isFalse();
 
-        when(mBluetoothA2dpWrapper.supportsOptionalCodecs(any())).thenReturn(
+        when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN);
         assertThat(mProfile.supportsHighQualityAudio(mDevice)).isFalse();
     }
 
     @Test
     public void isHighQualityAudioEnabled() {
-        when(mBluetoothA2dpWrapper.getOptionalCodecsEnabled(any())).thenReturn(
+        when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED);
         assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isTrue();
 
-        when(mBluetoothA2dpWrapper.getOptionalCodecsEnabled(any())).thenReturn(
+        when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED);
         assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isFalse();
 
@@ -100,23 +97,23 @@
         // then isHighQualityAudioEnabled() should return true or false based on whether optional
         // codecs are supported. If the device is connected then we should ask it directly, but if
         // the device isn't connected then rely on the stored pref about such support.
-        when(mBluetoothA2dpWrapper.getOptionalCodecsEnabled(any())).thenReturn(
+        when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN);
         when(mBluetoothA2dp.getConnectionState(any())).thenReturn(
                 BluetoothProfile.STATE_DISCONNECTED);
 
-        when(mBluetoothA2dpWrapper.supportsOptionalCodecs(any())).thenReturn(
+        when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
         assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isFalse();
 
-        when(mBluetoothA2dpWrapper.supportsOptionalCodecs(any())).thenReturn(
+        when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
         assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isTrue();
 
         when(mBluetoothA2dp.getConnectionState(any())).thenReturn(
                 BluetoothProfile.STATE_CONNECTED);
         BluetoothCodecStatus status = mock(BluetoothCodecStatus.class);
-        when(mBluetoothA2dpWrapper.getCodecStatus(mDevice)).thenReturn(status);
+        when(mBluetoothA2dp.getCodecStatus(mDevice)).thenReturn(status);
         BluetoothCodecConfig config = mock(BluetoothCodecConfig.class);
         when(status.getCodecConfig()).thenReturn(config);
         when(config.isMandatoryCodec()).thenReturn(false);
@@ -151,14 +148,14 @@
 
         // Most tests want to simulate optional codecs being supported by the device, so do that
         // by default here.
-        when(mBluetoothA2dpWrapper.supportsOptionalCodecs(any())).thenReturn(
+        when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
     }
 
     @Test
     public void getLableCodecsNotSupported() {
         setupLabelTest();
-        when(mBluetoothA2dpWrapper.supportsOptionalCodecs(any())).thenReturn(
+        when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
                 BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
         assertThat(mProfile.getHighQualityAudioOptionLabel(mDevice)).isEqualTo(UNKNOWN_CODEC_LABEL);
     }
@@ -179,7 +176,7 @@
         BluetoothCodecStatus status = mock(BluetoothCodecStatus.class);
         BluetoothCodecConfig config = mock(BluetoothCodecConfig.class);
         BluetoothCodecConfig[] configs = {config};
-        when(mBluetoothA2dpWrapper.getCodecStatus(mDevice)).thenReturn(status);
+        when(mBluetoothA2dp.getCodecStatus(mDevice)).thenReturn(status);
         when(status.getCodecsSelectableCapabilities()).thenReturn(configs);
 
         when(config.isMandatoryCodec()).thenReturn(true);
@@ -194,7 +191,7 @@
         BluetoothCodecStatus status = mock(BluetoothCodecStatus.class);
         BluetoothCodecConfig config = mock(BluetoothCodecConfig.class);
         BluetoothCodecConfig[] configs = {config};
-        when(mBluetoothA2dpWrapper.getCodecStatus(mDevice)).thenReturn(status);
+        when(mBluetoothA2dp.getCodecStatus(mDevice)).thenReturn(status);
         when(status.getCodecsSelectableCapabilities()).thenReturn(configs);
 
         when(config.isMandatoryCodec()).thenReturn(false);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 7863fc5..5853dca 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -23,23 +23,25 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
 
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
+import android.media.AudioManager;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowAudioManager;
 
-@RunWith(RobolectricTestRunner.class)
-@Config(resourceDir = "../../res")
+@RunWith(SettingsLibRobolectricTestRunner.class)
 public class CachedBluetoothDeviceTest {
     private final static String DEVICE_NAME = "TestName";
     private final static String DEVICE_ALIAS = "TestAlias";
@@ -60,6 +62,7 @@
     @Mock
     private BluetoothDevice mDevice;
     private CachedBluetoothDevice mCachedDevice;
+    private ShadowAudioManager mShadowAudioManager;
     private Context mContext;
     private int mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
 
@@ -67,6 +70,7 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
+        mShadowAudioManager = shadowOf(mContext.getSystemService(AudioManager.class));
         when(mDevice.getAddress()).thenReturn(DEVICE_ADDRESS);
         when(mAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
         when(mHfpProfile.isProfileReady()).thenReturn(true);
@@ -83,7 +87,7 @@
         // Test without battery level
         // Set PAN profile to be connected and test connection state summary
         mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");
+        assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Set PAN profile to be disconnected and test connection state summary
         mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
@@ -93,7 +97,7 @@
         mBatteryLevel = 10;
         // Set PAN profile to be connected and test connection state summary
         mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, battery 10%");
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("10% battery");
 
         // Set PAN profile to be disconnected and test connection state summary
         mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
@@ -104,7 +108,7 @@
 
         // Set PAN profile to be connected and test connection state summary
         mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");
+        assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Set PAN profile to be disconnected and test connection state summary
         mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
@@ -119,23 +123,23 @@
         mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, battery 10%");
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("10% battery");
 
         // Disconnect HFP only and test connection state summary
         mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
-                "Connected (no phone), battery 10%");
+                "10% battery");
 
         // Disconnect A2DP only and test connection state summary
         mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
-                "Connected (no media), battery 10%");
+                "10% battery");
 
         // Disconnect both HFP and A2DP and test connection state summary
         mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
-                "Connected (no phone or media), battery 10%");
+                "10% battery");
 
         // Disconnect all profiles and test connection state summary
         mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
@@ -147,16 +151,16 @@
         // Test without battery level
         // Set A2DP profile to be connected and test connection state summary
         mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");
+        assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Set device as Active for A2DP and test connection state summary
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(media)");
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active");
 
         // Test with battery level
         mBatteryLevel = 10;
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
-                "Connected, battery 10%, active(media)");
+       assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
+                "Active, 10% battery");
 
         // Set A2DP profile to be disconnected and test connection state summary
         mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
@@ -167,7 +171,7 @@
         // Set A2DP profile to be connected, Active and test connection state summary
         mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(media)");
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active");
 
         // Set A2DP profile to be disconnected and test connection state summary
         mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
@@ -179,16 +183,18 @@
         // Test without battery level
         // Set HFP profile to be connected and test connection state summary
         mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");
+        assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Set device as Active for HFP and test connection state summary
+        mCachedDevice.onAudioModeChanged();
+        mShadowAudioManager.setMode(AudioManager.MODE_IN_CALL);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(phone)");
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active");
 
         // Test with battery level
         mBatteryLevel = 10;
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
-                "Connected, battery 10%, active(phone)");
+       assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
+                "Active, 10% battery");
 
         // Set HFP profile to be disconnected and test connection state summary
         mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
@@ -199,7 +205,7 @@
         // Set HFP profile to be connected, Active and test connection state summary
         mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active(phone)");
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active");
 
         // Set HFP profile to be disconnected and test connection state summary
         mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
@@ -211,15 +217,16 @@
         // Test without battery level
         // Set Hearing Aid profile to be connected and test connection state summary
         mCachedDevice.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");
+        assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Set device as Active for Hearing Aid and test connection state summary
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active");
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active");
 
         // Set Hearing Aid profile to be disconnected and test connection state summary
         mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEARING_AID);
-        mCachedDevice.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_DISCONNECTED);
+        mCachedDevice.
+                onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isNull();
     }
 
@@ -229,23 +236,23 @@
         // Set A2DP and HFP profiles to be connected and test connection state summary
         mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected");
+        assertThat(mCachedDevice.getConnectionSummary()).isNull();
 
         // Set device as Active for A2DP and HFP and test connection state summary
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active");
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active");
 
         // Test with battery level
         mBatteryLevel = 10;
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
-                "Connected, battery 10%, active");
+                "Active, 10% battery");
 
         // Disconnect A2DP only and test connection state summary
         mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.A2DP);
         mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
-                "Connected (no media), battery 10%, active(phone)");
+                "10% battery");
 
         // Disconnect HFP only and test connection state summary
         mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEADSET);
@@ -253,7 +260,7 @@
         mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
         assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
-                "Connected (no phone), battery 10%, active(media)");
+                "Active, 10% battery");
 
         // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
         mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
@@ -262,7 +269,7 @@
         mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
         mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
-        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Connected, active");
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active");
 
         // Set A2DP and HFP profiles to be disconnected and test connection state summary
         mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/display/BrightnessUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/display/BrightnessUtilsTest.java
new file mode 100644
index 0000000..eb7ad6d
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/display/BrightnessUtilsTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.settingslib.display;
+
+import static com.android.settingslib.display.BrightnessUtils.GAMMA_SPACE_MAX;
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+public class BrightnessUtilsTest {
+
+    private static final int MIN = 1;
+    private static final int MAX = 255;
+
+    @Test
+    public void linearToGamma_minValue_shouldReturn0() {
+        assertThat(BrightnessUtils.convertLinearToGamma(MIN, MIN, MAX)).isEqualTo(0);
+    }
+
+    @Test
+    public void linearToGamma_maxValue_shouldReturnGammaSpaceMax() {
+        assertThat(BrightnessUtils.convertLinearToGamma(MAX, MIN, MAX)).isEqualTo(GAMMA_SPACE_MAX);
+    }
+
+    @Test
+    public void gammaToLinear_minValue_shouldReturnMin() {
+        assertThat(BrightnessUtils.convertGammaToLinear(MIN, MIN, MAX)).isEqualTo(MIN);
+    }
+
+    @Test
+    public void gammaToLinear_gammaSpaceValue_shouldReturnMax() {
+        assertThat(BrightnessUtils.convertGammaToLinear(GAMMA_SPACE_MAX, MIN, MAX)).isEqualTo(MAX);
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilTest.java
index 0eec247..d0a0686 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtilTest.java
@@ -22,6 +22,14 @@
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
 
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodSubtype;
+import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
+
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 
@@ -187,4 +195,75 @@
                 + "|ime3;subtype2;subtype3:ime0;subtype1;subtype0"
                 + "|ime4;subtype3;subtype2:ime0;subtype1;subtype0");
     }
+
+    @Test
+    public void isValidSystemNonAuxAsciiCapableIme() {
+        // System IME w/ no subtype
+        assertThat(InputMethodAndSubtypeUtil.isValidSystemNonAuxAsciiCapableIme(
+                createDummyIme(true, false)))
+                .isFalse();
+
+        // System IME w/ non-Aux and non-ASCII-capable "keyboard" subtype
+        assertThat(InputMethodAndSubtypeUtil.isValidSystemNonAuxAsciiCapableIme(
+                createDummyIme(true, false, createDummySubtype("keyboard", false, false))))
+                .isFalse();
+
+        // System IME w/ non-Aux and ASCII-capable "keyboard" subtype
+        assertThat(InputMethodAndSubtypeUtil.isValidSystemNonAuxAsciiCapableIme(
+                createDummyIme(true, false, createDummySubtype("keyboard", false, true))))
+                .isTrue();
+
+        // System IME w/ Aux and ASCII-capable "keyboard" subtype
+        assertThat(InputMethodAndSubtypeUtil.isValidSystemNonAuxAsciiCapableIme(
+                createDummyIme(true, true, createDummySubtype("keyboard", true, true))))
+                .isFalse();
+
+        // System IME w/ non-Aux and ASCII-capable "voice" subtype
+        assertThat(InputMethodAndSubtypeUtil.isValidSystemNonAuxAsciiCapableIme(
+                createDummyIme(true, false, createDummySubtype("voice", false, true))))
+                .isFalse();
+
+        // System IME w/ non-Aux and non-ASCII-capable subtype + Non-Aux and ASCII-capable subtype
+        assertThat(InputMethodAndSubtypeUtil.isValidSystemNonAuxAsciiCapableIme(
+                createDummyIme(true, false,
+                        createDummySubtype("keyboard", false, true),
+                        createDummySubtype("keyboard", false, false))))
+                .isTrue();
+
+        // Non-system IME w/ non-Aux and ASCII-capable "keyboard" subtype
+        assertThat(InputMethodAndSubtypeUtil.isValidSystemNonAuxAsciiCapableIme(
+                createDummyIme(false, false, createDummySubtype("keyboard", false, true))))
+                .isFalse();
+   }
+
+    private static InputMethodInfo createDummyIme(boolean isSystem, boolean isAuxIme,
+            InputMethodSubtype... subtypes) {
+        final ResolveInfo ri = new ResolveInfo();
+        final ServiceInfo si = new ServiceInfo();
+        final ApplicationInfo ai = new ApplicationInfo();
+        ai.packageName = "com.example.android.dummyime";
+        ai.enabled = true;
+        ai.flags |= (isSystem ? ApplicationInfo.FLAG_SYSTEM : 0);
+        si.applicationInfo = ai;
+        si.enabled = true;
+        si.packageName = "com.example.android.dummyime";
+        si.name = "Dummy IME";
+        si.exported = true;
+        si.nonLocalizedLabel = "Dummy IME";
+        ri.serviceInfo = si;
+        return new InputMethodInfo(ri, isAuxIme, "",  Arrays.asList(subtypes), 1, false);
+    }
+
+    private static InputMethodSubtype createDummySubtype(
+            String mode, boolean isAuxiliary, boolean isAsciiCapable) {
+        return new InputMethodSubtypeBuilder()
+                .setSubtypeNameResId(0)
+                .setSubtypeIconResId(0)
+                .setSubtypeLocale("en_US")
+                .setLanguageTag("en-US")
+                .setSubtypeMode(mode)
+                .setIsAuxiliary(isAuxiliary)
+                .setIsAsciiCapable(isAsciiCapable)
+                .build();
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/UserManagerHelperRoboTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/UserManagerHelperRoboTest.java
index f2ea3a4..890abef 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/UserManagerHelperRoboTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/UserManagerHelperRoboTest.java
@@ -185,12 +185,7 @@
         mHelper.switchToUser(createUserInfoForId(20));
         assertThat(ShadowActivityManager.getShadow().getSwitchUserCalled()).isFalse();
 
-        // Switching to Guest calls createGuest.
-        UserInfo guestInfo = new UserInfo(21, "Test Guest", UserInfo.FLAG_GUEST);
-        mHelper.switchToUser(guestInfo);
-        verify(mUserManager).createGuest(mContext, "Test Guest");
-
-        // Switching to non-current, non-guest user, simply calls switchUser.
+        // Switching to non-foreground user, simply calls switchUser.
         UserInfo userToSwitchTo = new UserInfo(22, "Test User", 0);
         mHelper.switchToUser(userToSwitchTo);
         assertThat(ShadowActivityManager.getShadow().getSwitchUserCalled()).isTrue();
diff --git a/packages/SettingsProvider/Android.mk b/packages/SettingsProvider/Android.mk
index db57fd1..ccde571 100644
--- a/packages/SettingsProvider/Android.mk
+++ b/packages/SettingsProvider/Android.mk
@@ -3,6 +3,8 @@
 
 LOCAL_MODULE_TAGS := optional
 
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
     src/com/android/providers/settings/EventLogTags.logtags
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 4c98bb8..7a994a8 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -17,7 +17,6 @@
 package com.android.providers.settings;
 
 import android.os.Process;
-import com.android.internal.R;
 import com.android.internal.app.LocalePicker;
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -30,13 +29,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
-import android.hardware.display.DisplayManager;
 import android.icu.util.ULocale;
 import android.location.LocationManager;
 import android.media.AudioManager;
 import android.media.RingtoneManager;
 import android.net.Uri;
-import android.os.IPowerManager;
 import android.os.LocaleList;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -46,16 +43,16 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArraySet;
-import android.util.Slog;
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Locale;
 
 public class SettingsHelper {
     private static final String TAG = "SettingsHelper";
     private static final String SILENT_RINGTONE = "_silent";
+    private static final float FLOAT_TOLERANCE = 0.01f;
+
     private Context mContext;
     private AudioManager mAudioManager;
     private TelephonyManager mTelephonyManager;
@@ -259,9 +256,14 @@
             case Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES:
             case Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES:
             case Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER:
-            case Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE:
                 return !TextUtils.isEmpty(Settings.Secure.getString(
                         mContext.getContentResolver(), name));
+            case Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE:
+                float defaultScale = mContext.getResources().getFraction(
+                        R.fraction.def_accessibility_display_magnification_scale, 1, 1);
+                float currentScale = Settings.Secure.getFloat(
+                        mContext.getContentResolver(), name, defaultScale);
+                return Math.abs(currentScale - defaultScale) >= FLOAT_TOLERANCE;
             case Settings.System.FONT_SCALE:
                 return Settings.System.getFloat(mContext.getContentResolver(), name, 1.0f) != 1.0f;
             default:
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 1d3e521..32aafea 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2935,7 +2935,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 164;
+            private static final int SETTINGS_VERSION = 165;
 
             private final int mUserId;
 
@@ -3710,17 +3710,7 @@
                 }
 
                 if (currentVersion == 162) {
-                    // Version 162: Add a gesture for silencing phones
-                    final SettingsState settings = getGlobalSettingsLocked();
-                    final Setting currentSetting = settings.getSettingLocked(
-                            Global.SHOW_ZEN_UPGRADE_NOTIFICATION);
-                    if (!currentSetting.isNull()
-                            && TextUtils.equals("0", currentSetting.getValue())) {
-                        settings.insertSettingLocked(
-                                Global.SHOW_ZEN_UPGRADE_NOTIFICATION, "1",
-                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
-                    }
-
+                    // Version 162: REMOVED: Add a gesture for silencing phones
                     currentVersion = 163;
                 }
 
@@ -3742,6 +3732,21 @@
                     currentVersion = 164;
                 }
 
+                if (currentVersion == 164) {
+                    // Version 164: Add a gesture for silencing phones
+                    final SettingsState settings = getGlobalSettingsLocked();
+                    final Setting currentSetting = settings.getSettingLocked(
+                            Global.SHOW_ZEN_UPGRADE_NOTIFICATION);
+                    if (!currentSetting.isNull()
+                            && TextUtils.equals("0", currentSetting.getValue())) {
+                        settings.insertSettingLocked(
+                                Global.SHOW_ZEN_UPGRADE_NOTIFICATION, "1",
+                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+                    }
+
+                    currentVersion = 165;
+                }
+
                 // vXXX: Add new settings above this point.
 
                 if (currentVersion != newVersion) {
diff --git a/packages/SettingsProvider/test/Android.mk b/packages/SettingsProvider/test/Android.mk
index bd5b1f2..0d681ed 100644
--- a/packages/SettingsProvider/test/Android.mk
+++ b/packages/SettingsProvider/test/Android.mk
@@ -14,6 +14,10 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.base
 
+LOCAL_RESOURCE_DIR := frameworks/base/packages/SettingsProvider/res
+
+LOCAL_AAPT_FLAGS += --auto-add-overlay --extra-packages com.android.providers.settings
+
 LOCAL_PACKAGE_NAME := SettingsProviderTest
 LOCAL_PRIVATE_PLATFORM_APIS := true
 
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java
new file mode 100644
index 0000000..b5324e5
--- /dev/null
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperRestoreTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.providers.settings;
+
+import static junit.framework.Assert.assertEquals;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Build;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link SettingsHelper#restoreValue(Context, ContentResolver, ContentValues, Uri,
+ * String, String, int)}. Specifically verifies that we restore critical accessibility settings only
+ * if the user has not already configured these in SUW.
+ */
+@RunWith(AndroidJUnit4.class)
+public class SettingsHelperRestoreTest {
+    private static final float FLOAT_TOLERANCE = 0.01f;
+
+    private Context mContext;
+    private ContentResolver mContentResolver;
+    private SettingsHelper mSettingsHelper;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getContext();
+        mContentResolver = mContext.getContentResolver();
+        mSettingsHelper = new SettingsHelper(mContext);
+    }
+
+    /** Tests for {@link Settings.Secure#ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE}. */
+    @Test
+    public void
+            testRestoreAccessibilityDisplayMagnificationScale_alreadyConfigured_doesNotRestoreValue()
+                    throws Exception {
+        float defaultSettingValue = setDefaultAccessibilityDisplayMagnificationScale();
+        String settingName = Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE;
+        float restoreSettingValue = defaultSettingValue + 0.5f;
+
+        // Simulate already configuring setting via SUW.
+        float configuredSettingValue = defaultSettingValue + 1.0f;
+        Settings.Secure.putFloat(mContentResolver, settingName, configuredSettingValue);
+
+        mSettingsHelper.restoreValue(
+                mContext,
+                mContentResolver,
+                new ContentValues(2),
+                Settings.Secure.getUriFor(settingName),
+                settingName,
+                String.valueOf(restoreSettingValue),
+                Build.VERSION.SDK_INT);
+
+        assertEquals(
+                configuredSettingValue,
+                Settings.Secure.getFloat(mContentResolver, settingName),
+                FLOAT_TOLERANCE);
+    }
+
+    @Test
+    public void
+            testRestoreAccessibilityDisplayMagnificationScale_notAlreadyConfigured_restoresValue()
+                    throws Exception {
+        float defaultSettingValue = setDefaultAccessibilityDisplayMagnificationScale();
+        String settingName = Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE;
+        float restoreSettingValue = defaultSettingValue + 0.5f;
+
+        mSettingsHelper.restoreValue(
+                mContext,
+                mContentResolver,
+                new ContentValues(2),
+                Settings.Secure.getUriFor(settingName),
+                settingName,
+                String.valueOf(restoreSettingValue),
+                Build.VERSION.SDK_INT);
+
+        assertEquals(
+                restoreSettingValue,
+                Settings.Secure.getFloat(mContentResolver, settingName),
+                FLOAT_TOLERANCE);
+    }
+
+    /**
+     * Simulate {@link Settings.Secure#ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE} value at boot by
+     * loading the default.
+     *
+     * @return the default value.
+     */
+    private float setDefaultAccessibilityDisplayMagnificationScale() {
+        float defaultSettingValue =
+                mContext.getResources()
+                        .getFraction(
+                                R.fraction.def_accessibility_display_magnification_scale, 1, 1);
+        Settings.Secure.putFloat(
+                mContentResolver,
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
+                defaultSettingValue);
+        return defaultSettingValue;
+    }
+}
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
index 6dea493..3193101 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
@@ -46,8 +46,7 @@
                 style="@style/widget_big_thin"
                 android:format12Hour="@string/keyguard_widget_12_hours_format"
                 android:format24Hour="@string/keyguard_widget_24_hours_format"
-                android:baselineAligned="true"
-                android:layout_marginBottom="@dimen/bottom_text_spacing_digital" />
+                android:baselineAligned="true" />
 
             <include layout="@layout/keyguard_status_area" />
             <ImageView
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
index 611aa43..db03ed2 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
@@ -28,12 +28,14 @@
     android:clipToPadding="false"
     android:orientation="vertical"
     android:layout_centerHorizontal="true">
-    <TextView android:id="@+id/title"
+    <com.android.systemui.statusbar.AlphaOptimizedTextView
+              android:id="@+id/title"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
-              android:layout_marginBottom="7dp"
+              android:layout_marginBottom="@dimen/widget_title_bottom_margin"
               android:paddingStart="64dp"
               android:paddingEnd="64dp"
+              android:visibility="gone"
               android:textColor="?attr/wallpaperTextColor"
               android:theme="@style/TextAppearance.Keyguard"
     />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index fa14d1b..ba05ccf 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -67,21 +67,17 @@
                 android:singleLine="true"
                 style="@style/widget_big_thin"
                 android:format12Hour="@string/keyguard_widget_12_hours_format"
-                android:format24Hour="@string/keyguard_widget_24_hours_format"
-                android:layout_marginBottom="@dimen/bottom_text_spacing_digital" />
+                android:format24Hour="@string/keyguard_widget_24_hours_format" />
             <View
                 android:id="@+id/clock_separator"
                 android:layout_width="@dimen/widget_separator_width"
                 android:layout_height="@dimen/widget_separator_thickness"
-                android:layout_marginTop="22dp"
                 android:layout_below="@id/clock_view"
                 android:background="#f00"
-                android:backgroundTint="?attr/wallpaperTextColor"
                 android:layout_centerHorizontal="true" />
 
             <include layout="@layout/keyguard_status_area"
                 android:id="@+id/keyguard_status_area"
-                android:layout_marginTop="20dp"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_below="@id/clock_separator" />
diff --git a/packages/SystemUI/res-keyguard/values-sw600dp/dimens.xml b/packages/SystemUI/res-keyguard/values-sw600dp/dimens.xml
index 4ae7cb9..fdca44d 100644
--- a/packages/SystemUI/res-keyguard/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values-sw600dp/dimens.xml
@@ -28,7 +28,6 @@
     <!-- Overload default clock widget parameters -->
     <dimen name="widget_big_font_size">100dp</dimen>
     <dimen name="widget_label_font_size">16sp</dimen>
-    <dimen name="bottom_text_spacing_digital">-1dp</dimen>
 
     <!-- EmergencyCarrierArea overlap - amount to overlap the emergency button and carrier text.
          Should be 0 on devices with plenty of room (e.g. tablets) -->
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 37de433..712b6e5 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -41,14 +41,14 @@
          Should be 0 on devices with plenty of room (e.g. tablets) -->
     <dimen name="eca_overlap">-10dip</dimen>
 
-    <!-- Default clock parameters -->
-    <dimen name="bottom_text_spacing_digital">-24dp</dimen>
     <!-- Slice header -->
-    <dimen name="widget_title_font_size">24sp</dimen>
-    <!-- Slice subtitle  -->
-    <dimen name="widget_label_font_size">16sp</dimen>
+    <dimen name="widget_title_font_size">24dp</dimen>
+    <dimen name="widget_title_bottom_margin">7dp</dimen>
+    <dimen name="bottom_text_spacing_digital">0dp</dimen>
+    <!-- Slice subtitle -->
+    <dimen name="widget_label_font_size">16dp</dimen>
     <!-- Slice offset when pulsing -->
-    <dimen name="widget_pulsing_bottom_padding">24dp</dimen>
+    <dimen name="widget_pulsing_bottom_padding">48dp</dimen>
     <!-- Clock without header -->
     <dimen name="widget_big_font_size">64dp</dimen>
     <!-- Clock with header -->
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 5f52e2a..b90b4dd 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -53,6 +53,7 @@
     </style>
     <style name="widget_big_thin">
         <item name="android:textSize">@dimen/widget_big_font_size</item>
+        <item name="android:paddingBottom">@dimen/bottom_text_spacing_digital</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamilyLight</item>
         <item name="android:fontFeatureSettings">@*android:string/config_headlineFontFeatureSettings</item>
     </style>
@@ -89,6 +90,7 @@
     <style name="TextAppearance.Keyguard.Secondary">
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
+        <item name="android:lines">1</item>
         <item name="android:textSize">@dimen/widget_label_font_size</item>
     </style>
 
diff --git a/packages/SystemUI/res/anim/car_arrow_fade_in_rotate_down.xml b/packages/SystemUI/res/anim/car_arrow_fade_in_rotate_down.xml
new file mode 100644
index 0000000..74f38d4
--- /dev/null
+++ b/packages/SystemUI/res/anim/car_arrow_fade_in_rotate_down.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:ordering="together">
+  <objectAnimator
+      android:propertyName="rotation"
+      android:duration="0"
+      android:valueFrom="180"
+      android:valueTo="0"
+      android:interpolator="@android:interpolator/fast_out_slow_in" />
+  <objectAnimator
+      android:propertyName="alpha"
+      android:valueFrom="0.0"
+      android:valueTo="1.0"
+      android:valueType="floatType"
+      android:duration="300"
+      android:interpolator="@android:interpolator/fast_out_slow_in" />
+  <objectAnimator
+      android:propertyName="scaleX"
+      android:valueFrom="0.8"
+      android:valueTo="1.0"
+      android:valueType="floatType"
+      android:duration="300"
+      android:interpolator="@android:interpolator/fast_out_slow_in" />
+  <objectAnimator
+      android:propertyName="scaleY"
+      android:valueFrom="0.8"
+      android:valueTo="1.0"
+      android:valueType="floatType"
+      android:duration="300"
+      android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/car_arrow_fade_in_rotate_up.xml b/packages/SystemUI/res/anim/car_arrow_fade_in_rotate_up.xml
new file mode 100644
index 0000000..0f28297
--- /dev/null
+++ b/packages/SystemUI/res/anim/car_arrow_fade_in_rotate_up.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:ordering="together">
+  <objectAnimator
+      android:propertyName="rotation"
+      android:duration="0"
+      android:valueFrom="0"
+      android:valueTo="180"
+      android:interpolator="@android:interpolator/fast_out_slow_in" />
+  <objectAnimator
+      android:propertyName="alpha"
+      android:valueFrom="0.0"
+      android:valueTo="1.0"
+      android:valueType="floatType"
+      android:duration="300"
+      android:interpolator="@android:interpolator/fast_out_slow_in" />
+  <objectAnimator
+      android:propertyName="scaleX"
+      android:valueFrom="0.8"
+      android:valueTo="1.0"
+      android:valueType="floatType"
+      android:duration="300"
+      android:interpolator="@android:interpolator/fast_out_slow_in" />
+  <objectAnimator
+      android:propertyName="scaleY"
+      android:valueFrom="0.8"
+      android:valueTo="1.0"
+      android:valueType="floatType"
+      android:duration="300"
+      android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/car_arrow_fade_out.xml b/packages/SystemUI/res/anim/car_arrow_fade_out.xml
new file mode 100644
index 0000000..e6757d2
--- /dev/null
+++ b/packages/SystemUI/res/anim/car_arrow_fade_out.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:ordering="together">
+  <objectAnimator
+      android:propertyName="alpha"
+      android:valueFrom="1.0"
+      android:valueTo="0.0"
+      android:valueType="floatType"
+      android:duration="300"
+      android:interpolator="@android:interpolator/fast_out_slow_in" />
+  <objectAnimator
+      android:propertyName="scaleX"
+      android:valueFrom="1.0"
+      android:valueTo="0.8"
+      android:valueType="floatType"
+      android:duration="300"
+      android:interpolator="@android:interpolator/fast_out_slow_in" />
+  <objectAnimator
+      android:propertyName="scaleY"
+      android:valueFrom="1.0"
+      android:valueTo="0.8"
+      android:valueType="floatType"
+      android:duration="300"
+      android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/car_ic_keyboard_arrow_down.xml b/packages/SystemUI/res/drawable/car_ic_keyboard_arrow_down.xml
new file mode 100644
index 0000000..3709aa5
--- /dev/null
+++ b/packages/SystemUI/res/drawable/car_ic_keyboard_arrow_down.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~
+  ~ Copyright (C) 2018 Google Inc.
+  ~
+  ~ 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="44dp"
+    android:height="44dp"
+    android:viewportWidth="48.0"
+    android:viewportHeight="48.0">
+  <path
+      android:pathData="M14.83 16.42L24 25.59l9.17-9.17L36 19.25l-12 12-12-12z"
+      android:fillColor="#ffffff"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/car_ic_music.xml b/packages/SystemUI/res/drawable/car_ic_music.xml
new file mode 100644
index 0000000..f90cd69
--- /dev/null
+++ b/packages/SystemUI/res/drawable/car_ic_music.xml
@@ -0,0 +1,30 @@
+<!--
+    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="56dp"
+    android:height="56dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48">
+
+  <path
+      android:fillAlpha=".1"
+      android:strokeAlpha=".1"
+      android:pathData="M0 0h48v48H0z" />
+  <path
+      android:fillColor="@color/car_grey_50"
+      android:pathData="M24 2C14.06 2 6 10.06 6 20v14c0 3.31 2.69 6 6 6h6V24h-8v-4c0-7.73 6.27-14
+14-14s14 6.27 14 14v4h-8v16h6c3.31 0 6-2.69 6-6V20c0-9.94-8.06-18-18-18z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/car_ic_navigation.xml b/packages/SystemUI/res/drawable/car_ic_navigation.xml
new file mode 100644
index 0000000..328efa0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/car_ic_navigation.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="32dp"
+    android:height="37dp"
+    android:viewportWidth="32.0"
+    android:viewportHeight="37.0">
+  <path
+      android:pathData="M16.62,0.61L31.33,35.21C31.55,35.72 31.31,36.3 30.8,36.52C30.48,36.66 30.12,36.62 29.83,36.42L15.7,26.44L1.58,36.42C1.13,36.73 0.5,36.63 0.18,36.18C-0.02,35.89 -0.06,35.53 0.08,35.21L14.78,0.61C15,0.1 15.59,-0.14 16.1,0.08C16.33,0.18 16.52,0.37 16.62,0.61Z"
+      android:strokeColor="#00000000"
+      android:fillType="evenOdd"
+      android:fillColor="@color/car_grey_50"
+      android:strokeWidth="1"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/car_ic_notification_2.xml b/packages/SystemUI/res/drawable/car_ic_notification_2.xml
new file mode 100644
index 0000000..c74ae15
--- /dev/null
+++ b/packages/SystemUI/res/drawable/car_ic_notification_2.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="32dp"
+    android:height="38dp"
+    android:viewportWidth="32"
+    android:viewportHeight="38" >
+  <group
+      android:translateX="-6"
+      android:translateY="-3">
+    <path
+        android:pathData="M26.6195649,6.98115478 C31.5083629,8.85235985 34.9817444,13.6069337 34.9817444,19.1767606 L34.9817444,27.9542254 L38,27.9542254 L38,34.2161972 L6,34.2161972 L6,27.9542254 L9.01825558,27.9542254 L9.01825558,19.1767606 C9.01825558,13.6069337 12.4916371,8.85235985 17.3804351,6.98115478 C17.723241,4.726863 19.6609451,3 22,3 C24.3390549,3 26.276759,4.726863 26.6195649,6.98115478 Z M17.326572,36.3035211 L26.673428,36.3035211 C26.673428,38.8973148 24.581063,41 22,41 C19.418937,41 17.326572,38.8973148 17.326572,36.3035211 Z"
+        android:strokeColor="#00000000"
+        android:fillType="evenOdd"
+        android:fillColor="@color/car_grey_50" />
+  </group>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_lock_lockdown.xml b/packages/SystemUI/res/drawable/ic_lock_lockdown.xml
index 65b9813..d591aa8 100644
--- a/packages/SystemUI/res/drawable/ic_lock_lockdown.xml
+++ b/packages/SystemUI/res/drawable/ic_lock_lockdown.xml
@@ -17,10 +17,10 @@
         android:width="24.0dp"
         android:height="24.0dp"
         android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
+        android:viewportHeight="24.0"
+        android:tint="?attr/colorControlNormal">
 
     <path
         android:fillColor="#000000"
-        android:alpha="0.87"
         android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM12.0,17.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0c1.1,0.0 2.0,0.9 2.0,2.0S13.1,17.0 12.0,17.0zM15.1,8.0L8.9,8.0L8.9,6.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1L15.1,8.0z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/smart_reply_button_background.xml b/packages/SystemUI/res/drawable/smart_reply_button_background.xml
index c464ba6..93adaa0 100644
--- a/packages/SystemUI/res/drawable/smart_reply_button_background.xml
+++ b/packages/SystemUI/res/drawable/smart_reply_button_background.xml
@@ -21,9 +21,9 @@
     <item>
         <inset
             android:insetLeft="0dp"
-            android:insetTop="7dp"
+            android:insetTop="8dp"
             android:insetRight="0dp"
-            android:insetBottom="5dp">
+            android:insetBottom="8dp">
             <shape android:shape="rectangle">
                 <corners android:radius="8dp" />
                 <stroke android:width="1dp" android:color="@color/smart_reply_button_stroke" />
diff --git a/packages/SystemUI/res/layout/car_volume_dialog.xml b/packages/SystemUI/res/layout/car_volume_dialog.xml
index 36bc85d..a6beaa1 100644
--- a/packages/SystemUI/res/layout/car_volume_dialog.xml
+++ b/packages/SystemUI/res/layout/car_volume_dialog.xml
@@ -13,26 +13,19 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<FrameLayout
+<androidx.car.widget.PagedListView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/volume_dialog"
-    android:clipChildren="false"
+    android:background="@drawable/car_card_rounded_background"
+    android:id="@+id/volume_list"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_marginStart="@dimen/car_margin"
     android:layout_marginEnd="@dimen/car_margin"
-    android:theme="@style/qs_theme" >
-    <androidx.car.widget.PagedListView
-        android:id="@+id/volume_list"
-        android:background="@drawable/car_rounded_bg_bottom"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:minWidth="@dimen/volume_dialog_panel_width"
-        android:theme="?attr/dialogListTheme"
-        app:dividerStartMargin="@dimen/car_keyline_1"
-        app:dividerEndMargin="@dimen/car_keyline_1"
-        app:gutter="none"
-        app:showPagedListViewDivider="true"
-        app:scrollBarEnabled="false" />
-</FrameLayout>
+    android:minWidth="@dimen/volume_dialog_panel_width"
+    android:theme="@style/Theme.Car.NoActionBar"
+    app:dividerStartMargin="@dimen/car_keyline_1"
+    app:dividerEndMargin="@dimen/car_keyline_1"
+    app:gutter="none"
+    app:showPagedListViewDivider="true"
+    app:scrollBarEnabled="false" />
diff --git a/packages/SystemUI/res/layout/hybrid_notification.xml b/packages/SystemUI/res/layout/hybrid_notification.xml
index f4501da..bccf207 100644
--- a/packages/SystemUI/res/layout/hybrid_notification.xml
+++ b/packages/SystemUI/res/layout/hybrid_notification.xml
@@ -34,7 +34,6 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:singleLine="true"
-        android:textAppearance="@*android:style/TextAppearance.Material.Notification"
         style="?attr/hybridNotificationTextStyle"
     />
 </com.android.systemui.statusbar.notification.HybridNotificationView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/hybrid_overflow_number.xml b/packages/SystemUI/res/layout/hybrid_overflow_number.xml
index 792f424..08f8f94 100644
--- a/packages/SystemUI/res/layout/hybrid_overflow_number.xml
+++ b/packages/SystemUI/res/layout/hybrid_overflow_number.xml
@@ -16,10 +16,10 @@
   -->
 <TextView
     xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@*android:style/Widget.Material.Notification.Text"
     android:id="@+id/notification_text"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:textAppearance="@*android:style/TextAppearance.Material.Notification"
     android:paddingEnd="@dimen/group_overflow_number_padding"
     android:gravity="end"
     android:singleLine="true"
diff --git a/packages/SystemUI/res/layout/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml
index 49d142a..8ca867f 100644
--- a/packages/SystemUI/res/layout/qs_tile_label.xml
+++ b/packages/SystemUI/res/layout/qs_tile_label.xml
@@ -41,7 +41,6 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:clickable="false"
-            android:maxLines="2"
             android:padding="0dp"
             android:gravity="center"
             android:ellipsize="marquee"
diff --git a/packages/SystemUI/res/layout/quick_qs_status_icons.xml b/packages/SystemUI/res/layout/quick_qs_status_icons.xml
index 5f73bef..4301fdb 100644
--- a/packages/SystemUI/res/layout/quick_qs_status_icons.xml
+++ b/packages/SystemUI/res/layout/quick_qs_status_icons.xml
@@ -18,13 +18,15 @@
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/quick_qs_status_icons"
     android:layout_width="match_parent"
-    android:layout_height="20dp"
+    android:layout_height="wrap_content"
     android:layout_marginTop="8dp"
     android:layout_marginBottom="14dp"
-    android:layout_marginStart="8dp"
-    android:layout_marginEnd="@dimen/notification_side_paddings"
+    android:layout_marginStart="@dimen/status_bar_padding_start"
+    android:layout_marginEnd="@dimen/status_bar_padding_end"
     android:layout_below="@id/quick_status_bar_system_icons"
-    android:paddingEnd="@dimen/status_bar_padding_end" >
+    android:clipChildren="false"
+    android:clipToPadding="false"
+    android:minHeight="20dp" >
 
     <com.android.systemui.statusbar.policy.DateView
         android:id="@+id/date"
diff --git a/packages/SystemUI/res/layout/quick_settings_header_info.xml b/packages/SystemUI/res/layout/quick_settings_header_info.xml
index 54baa4a..0892f73 100644
--- a/packages/SystemUI/res/layout/quick_settings_header_info.xml
+++ b/packages/SystemUI/res/layout/quick_settings_header_info.xml
@@ -45,14 +45,16 @@
             android:layout_width="@dimen/qs_header_alarm_icon_size"
             android:layout_height="@dimen/qs_header_alarm_icon_size"
             android:src="@drawable/stat_sys_alarm"
-            android:tint="?android:attr/textColorPrimary" />
+            android:tint="?android:attr/textColorPrimary"
+            android:visibility="gone"/>
 
         <TextView
             android:id="@+id/next_alarm_text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
-            android:textAppearance="@style/TextAppearance.QS.TileLabel" />
+            android:textAppearance="@style/TextAppearance.QS.TileLabel"
+            android:visibility="gone"/>
 
         <View
             android:id="@+id/status_separator"
@@ -61,20 +63,23 @@
             android:layout_marginStart="10dp"
             android:layout_marginEnd="10dp"
             android:background="@android:color/white"
-            android:backgroundTint="?android:attr/textColorPrimary" />
+            android:backgroundTint="?android:attr/textColorPrimary"
+            android:visibility="gone"/>
 
         <ImageView
             android:id="@+id/ringer_mode_icon"
             android:layout_width="@dimen/qs_header_alarm_icon_size"
             android:layout_height="@dimen/qs_header_alarm_icon_size"
-            android:tint="?android:attr/textColorPrimary" />
+            android:tint="?android:attr/textColorPrimary"
+            android:visibility="gone"/>
 
         <TextView
             android:id="@+id/ringer_mode_text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
-            android:textAppearance="@style/TextAppearance.QS.TileLabel" />
+            android:textAppearance="@style/TextAppearance.QS.TileLabel"
+            android:visibility="gone"/>
 
     </LinearLayout>
 
diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
index a9fe862..d40534e 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
@@ -20,15 +20,12 @@
     android:id="@+id/quick_status_bar_system_icons"
     android:layout_width="match_parent"
     android:layout_height="@*android:dimen/quick_qs_offset_height"
-    android:layout_marginRight="@dimen/notification_side_paddings"
-    android:layout_marginLeft="@dimen/notification_side_paddings"
-    android:layout_alignParentEnd="true"
     android:clipChildren="false"
     android:clipToPadding="false"
     android:gravity="center"
+    android:orientation="horizontal"
     android:paddingStart="@dimen/status_bar_padding_start"
-    android:paddingEnd="@dimen/status_bar_padding_end"
-    android:orientation="horizontal">
+    android:paddingEnd="@dimen/status_bar_padding_end" >
 
     <com.android.systemui.statusbar.policy.Clock
         android:id="@+id/clock"
diff --git a/packages/SystemUI/res/layout/smart_reply_button.xml b/packages/SystemUI/res/layout/smart_reply_button.xml
index 98e6e82..a490c4b 100644
--- a/packages/SystemUI/res/layout/smart_reply_button.xml
+++ b/packages/SystemUI/res/layout/smart_reply_button.xml
@@ -26,7 +26,7 @@
         android:paddingVertical="@dimen/smart_reply_button_padding_vertical"
         android:background="@drawable/smart_reply_button_background"
         android:gravity="center"
-        android:fontFamily="sans-serif-medium"
+        android:fontFamily="roboto-medium"
         android:textSize="@dimen/smart_reply_button_font_size"
         android:lineSpacingExtra="@dimen/smart_reply_button_line_spacing_extra"
         android:textColor="@color/smart_reply_button_text"
diff --git a/packages/SystemUI/res/layout/smart_reply_view.xml b/packages/SystemUI/res/layout/smart_reply_view.xml
index 9b2dd95..aa5549f 100644
--- a/packages/SystemUI/res/layout/smart_reply_view.xml
+++ b/packages/SystemUI/res/layout/smart_reply_view.xml
@@ -23,7 +23,6 @@
     android:id="@+id/smart_reply_view"
     android:layout_height="wrap_content"
     android:layout_width="wrap_content"
-    android:layout_marginStart="12dp"
     systemui:spacing="@dimen/smart_reply_button_spacing"
     systemui:singleLineButtonPaddingHorizontal="@dimen/smart_reply_button_padding_horizontal_single_line"
     systemui:doubleLineButtonPaddingHorizontal="@dimen/smart_reply_button_padding_horizontal_double_line">
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index df46fab..f0436de 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -28,6 +28,7 @@
     android:orientation="vertical"
     android:focusable="false"
     android:descendantFocusability="afterDescendants"
+    android:accessibilityPaneTitle="@string/status_bar"
     >
 
     <ImageView
diff --git a/packages/SystemUI/res/layout/status_bar_dnd_suppressing_notifications.xml b/packages/SystemUI/res/layout/status_bar_dnd_suppressing_notifications.xml
new file mode 100644
index 0000000..eff9b36
--- /dev/null
+++ b/packages/SystemUI/res/layout/status_bar_dnd_suppressing_notifications.xml
@@ -0,0 +1,34 @@
+<!--
+    Copyright 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.
+-->
+
+<!-- Extends Framelayout -->
+<com.android.systemui.statusbar.DndSuppressingNotificationsView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/hidden_container"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:visibility="gone">
+    <TextView
+        android:id="@+id/hidden_notifications"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:minHeight="64dp"
+        android:paddingTop="28dp"
+        android:gravity="top|center_horizontal"
+        android:textColor="?attr/wallpaperTextColor"
+        android:textSize="16sp"
+        android:text="@string/dnd_suppressing_shade_text"/>
+</com.android.systemui.statusbar.DndSuppressingNotificationsView>
diff --git a/packages/SystemUI/res/layout/volume_dnd_icon.xml b/packages/SystemUI/res/layout/volume_dnd_icon.xml
index 215b230..ac235b7 100644
--- a/packages/SystemUI/res/layout/volume_dnd_icon.xml
+++ b/packages/SystemUI/res/layout/volume_dnd_icon.xml
@@ -15,16 +15,16 @@
 -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="14dp"
-    android:layout_height="14dp"
-    android:layout_marginTop="6dp"
-    android:layout_marginRight="6dp"
-    android:layout_gravity="right|top">
+    android:id="@+id/dnd_icon"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
 
     <ImageView
-        android:id="@+id/dnd_icon"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
+        android:layout_width="14dp"
+        android:layout_height="14dp"
+        android:layout_marginTop="6dp"
+        android:layout_marginRight="6dp"
+        android:layout_gravity="right|top"
         android:src="@drawable/ic_dnd"
         android:tint="?android:attr/textColorTertiary"/>
 </FrameLayout>
diff --git a/packages/SystemUI/res/values/config_car.xml b/packages/SystemUI/res/values/config_car.xml
index db829f2..2c549bc 100644
--- a/packages/SystemUI/res/values/config_car.xml
+++ b/packages/SystemUI/res/values/config_car.xml
@@ -27,4 +27,5 @@
     <bool name="config_enableLeftNavigationBar">false</bool>
     <bool name="config_enableRightNavigationBar">false</bool>
     <bool name="config_enableBottomNavigationBar">true</bool>
+    <bool name="config_hideNavWhenKeyguardBouncerShown">true</bool>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 875000c..eb71911 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -140,6 +140,9 @@
     notification panel collapses -->
     <dimen name="shelf_appear_translation">42dp</dimen>
 
+    <!-- Vertical translation of pulsing notification animations -->
+    <dimen name="pulsing_notification_appear_translation">10dp</dimen>
+
     <!-- The amount the content shifts upwards when transforming into the icon -->
     <dimen name="notification_icon_transform_content_shift">32dp</dimen>
 
@@ -326,7 +329,7 @@
     <dimen name="pull_span_min">25dp</dimen>
 
     <dimen name="qs_tile_height">106dp</dimen>
-    <dimen name="qs_tile_layout_margin_side">9dp</dimen>
+    <dimen name="qs_tile_layout_margin_side">6dp</dimen>
     <dimen name="qs_tile_margin_horizontal">18dp</dimen>
     <dimen name="qs_tile_margin_vertical">24dp</dimen>
     <dimen name="qs_tile_margin_top_bottom">12dp</dimen>
@@ -917,6 +920,8 @@
     <dimen name="edge_margin">8dp</dimen>
 
     <dimen name="rounded_corner_radius">0dp</dimen>
+    <dimen name="rounded_corner_radius_top">0dp</dimen>
+    <dimen name="rounded_corner_radius_bottom">0dp</dimen>
     <dimen name="rounded_corner_content_padding">0dp</dimen>
     <dimen name="nav_content_padding">0dp</dimen>
     <dimen name="nav_quick_scrub_track_edge_padding">42dp</dimen>
@@ -925,12 +930,13 @@
     <!-- Home button padding for sizing -->
     <dimen name="home_padding">16dp</dimen>
 
-    <!-- Smart reply button -->
+    <!-- Smart reply button. Total height 48dp, visible height 32dp. -->
     <dimen name="smart_reply_button_spacing">8dp</dimen>
-    <dimen name="smart_reply_button_padding_vertical">10dp</dimen>
-    <dimen name="smart_reply_button_padding_horizontal_single_line">16dp</dimen>
-    <dimen name="smart_reply_button_padding_horizontal_double_line">16dp</dimen>
-    <dimen name="smart_reply_button_min_height">32dp</dimen>
+    <dimen name="smart_reply_button_padding_vertical">14dp</dimen>
+    <!-- Note: The following two paddings need to be different until b/78876518 is fixed. -->
+    <dimen name="smart_reply_button_padding_horizontal_single_line">20dp</dimen>
+    <dimen name="smart_reply_button_padding_horizontal_double_line">19dp</dimen>
+    <dimen name="smart_reply_button_min_height">48dp</dimen>
     <dimen name="smart_reply_button_font_size">14sp</dimen>
     <dimen name="smart_reply_button_line_spacing_extra">6sp</dimen> <!-- Total line height 20sp. -->
 
diff --git a/core/res/res/drawable/notification_reply_background.xml b/packages/SystemUI/res/values/ids_car.xml
similarity index 66%
rename from core/res/res/drawable/notification_reply_background.xml
rename to packages/SystemUI/res/values/ids_car.xml
index 08e22f2..27ed2e2 100644
--- a/core/res/res/drawable/notification_reply_background.xml
+++ b/packages/SystemUI/res/values/ids_car.xml
@@ -1,5 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ Copyright (C) 2017 The Android Open Source Project
+  ~ 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.
@@ -14,11 +15,8 @@
   ~ limitations under the License
   -->
 
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="oval">
-    <solid
-        android:color="#ff757575"/>
-    <size
-        android:width="16dp"
-        android:height="16dp"/>
-</shape>
+<resources>
+    <!-- Values used for finding elements on the system ui nav bars -->
+    <item type="id" name="lock_screen_nav_buttons"/>
+    <item type="id" name="nav_buttons"/>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 6c507be..50e7b5c 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -59,7 +59,7 @@
     <string name="status_bar_latest_events_title">Notifications</string>
 
     <!-- When the battery is low, this is displayed to the user in a dialog.  The title of the low battery alert.  [CHAR LIMIT=NONE]-->
-    <string name="battery_low_title">Battery is low</string>
+    <string name="battery_low_title">Battery may run out soon</string>
 
     <!-- A message that appears when the battery level is getting low in a dialog.  This is
         appended to the subtitle of the low battery alert.  "percentage" is the percentage of battery
@@ -240,6 +240,8 @@
     <string name="accessibility_waiting_for_fingerprint">Waiting for fingerprint</string>
     <!-- Accessibility action of the unlock button when fingerpint is on (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_unlock_without_fingerprint">Unlock without using your fingerprint</string>
+    <!-- Content description of the Trusted Face icon for accessibility. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_scanning_face">Scanning face</string>
     <!-- Click action label for accessibility for the smart reply buttons (not shown on-screen).". [CHAR LIMIT=NONE] -->
     <string name="accessibility_send_smart_reply">Send</string>
     <!-- Click action label for accessibility for the unlock button. [CHAR LIMIT=NONE] -->
@@ -1062,7 +1064,7 @@
     <string name="manage_notifications_text">Manage notifications</string>
 
     <!-- The text to show in the notifications shade when dnd is suppressing notifications. [CHAR LIMIT=100] -->
-    <string name="dnd_suppressing_shade_text">Do Not Disturb is hiding notifications</string>
+    <string name="dnd_suppressing_shade_text">Notifications hidden by Do Not Disturb</string>
 
     <!-- Media projection permission dialog action text. [CHAR LIMIT=60] -->
     <string name="media_projection_action_text">Start now</string>
@@ -2223,4 +2225,6 @@
     <!-- An action on the dialog that tells that scheduled (i.e. automatic) battery saver: user acknowledges and closes the dialog.  [CHAR LIMIT=NONE]-->
     <string name="auto_saver_okay_action">Got it</string>
 
+    <!-- URl of the webpage that explains battery saver. -->
+    <string name="help_uri_battery_saver_learn_more_link_target" translatable="false"></string>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 804ca2c..1e19534 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -137,7 +137,8 @@
         <item name="android:layout_marginTop">4dp</item>
     </style>
 
-    <style name="hybrid_notification_text">
+    <style name="hybrid_notification_text"
+           parent="@*android:style/Widget.Material.Notification.Text">
         <item name="android:paddingEnd">4dp</item>
     </style>
 
@@ -360,10 +361,6 @@
         parent="@*android:style/TextAppearance.Material.Notification.Info">
     </style>
 
-    <style name="TextAppearance.Material.Notification.HybridNotificationDivider"
-        parent="@*android:style/TextAppearance.Material.Notification">
-    </style>
-
     <style name="SearchPanelCircle">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">match_parent</item>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/MetricsLoggerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/MetricsLoggerCompat.java
new file mode 100644
index 0000000..e93e78d
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/MetricsLoggerCompat.java
@@ -0,0 +1,40 @@
+/*
+ * 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.systemui.shared.system;
+
+import com.android.internal.logging.MetricsLogger;
+
+public class MetricsLoggerCompat {
+
+    private final MetricsLogger mMetricsLogger;
+
+    public MetricsLoggerCompat() {
+        mMetricsLogger = new MetricsLogger();
+    }
+
+    public void action(int category) {
+        mMetricsLogger.action(category);
+    }
+
+    public void action(int category, int value) {
+        mMetricsLogger.action(category, value);
+    }
+
+    public void visible(int category) {
+        mMetricsLogger.visible(category);
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
index 8d451c1..5a0dddc 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
@@ -33,10 +33,21 @@
      * touch slop is when the respected operation will occur when exceeded. Touch slop must be
      * larger than the drag slop.
      */
-    public static final int QUICK_STEP_DRAG_SLOP_PX = convertDpToPixel(10);
-    public static final int QUICK_SCRUB_DRAG_SLOP_PX = convertDpToPixel(20);
-    public static final int QUICK_STEP_TOUCH_SLOP_PX = convertDpToPixel(24);
-    public static final int QUICK_SCRUB_TOUCH_SLOP_PX = convertDpToPixel(35);
+    public static int getQuickStepDragSlopPx() {
+        return convertDpToPixel(10);
+    }
+
+    public static int getQuickScrubDragSlopPx() {
+        return convertDpToPixel(20);
+    }
+
+    public static int getQuickStepTouchSlopPx() {
+        return convertDpToPixel(24);
+    }
+
+    public static int getQuickScrubTouchSlopPx() {
+        return convertDpToPixel(35);
+    }
 
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({HIT_TARGET_NONE, HIT_TARGET_BACK, HIT_TARGET_HOME, HIT_TARGET_OVERVIEW})
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
index 07b980e..ed2f831 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
@@ -26,6 +26,10 @@
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
+
 import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
 import com.android.systemui.shared.recents.view.RecentsTransition;
 
@@ -58,6 +62,11 @@
     public static final int TRANSIT_KEYGUARD_OCCLUDE = WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
     public static final int TRANSIT_KEYGUARD_UNOCCLUDE = WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
 
+    public static final int NAV_BAR_POS_INVALID = -1;
+    public static final int NAV_BAR_POS_LEFT = NAV_BAR_LEFT;
+    public static final int NAV_BAR_POS_RIGHT = NAV_BAR_RIGHT;
+    public static final int NAV_BAR_POS_BOTTOM = NAV_BAR_BOTTOM;
+
     public static final int ACTIVITY_TYPE_STANDARD = WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 
     public static final int WINDOWING_MODE_UNDEFINED = WindowConfiguration.WINDOWING_MODE_UNDEFINED;
@@ -141,4 +150,20 @@
             Log.w(TAG, "Failed to set recents visibility");
         }
     }
+
+    /**
+     * @return The side of the screen where navigation bar is positioned.
+     * @see #NAV_BAR_POS_RIGHT
+     * @see #NAV_BAR_POS_LEFT
+     * @see #NAV_BAR_POS_BOTTOM
+     * @see #NAV_BAR_POS_INVALID
+     */
+    public int getNavBarPosition() {
+        try {
+            return WindowManagerGlobal.getWindowManagerService().getNavBarPosition();
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to get nav bar position");
+        }
+        return NAV_BAR_POS_INVALID;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index e936c3b..5ce3339 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -34,6 +34,7 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.animation.Animation;
 import android.widget.Button;
 import android.widget.LinearLayout;
@@ -46,8 +47,9 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.keyguard.KeyguardSliceProvider;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.tuner.TunerService;
-import com.android.systemui.util.wakelock.WakeLock;
+import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
 
 import java.util.HashMap;
 import java.util.List;
@@ -64,21 +66,29 @@
  * View visible under the clock on the lock screen and AoD.
  */
 public class KeyguardSliceView extends LinearLayout implements View.OnClickListener,
-        Observer<Slice>, TunerService.Tunable {
+        Observer<Slice>, TunerService.Tunable, ConfigurationController.ConfigurationListener {
 
     private static final String TAG = "KeyguardSliceView";
+    public static final int DEFAULT_ANIM_DURATION = 550;
+
     private final HashMap<View, PendingIntent> mClickActions;
     private Uri mKeyguardSliceUri;
-    private TextView mTitle;
-    private LinearLayout mRow;
+    @VisibleForTesting
+    TextView mTitle;
+    private Row mRow;
     private int mTextColor;
     private float mDarkAmount = 0;
 
     private LiveData<Slice> mLiveData;
     private int mIconSize;
-    private Consumer<Boolean> mListener;
+    /**
+     * Listener called whenever the view contents change.
+     * Boolean will be true when the change happens animated.
+     */
+    private Consumer<Boolean> mContentChangeListener;
     private boolean mHasHeader;
-    private boolean mHideContent;
+    private Slice mSlice;
+    private boolean mPulsing;
 
     public KeyguardSliceView(Context context) {
         this(context, null, 0);
@@ -95,6 +105,18 @@
         tunerService.addTunable(this, Settings.Secure.KEYGUARD_SLICE_URI);
 
         mClickActions = new HashMap<>();
+
+        LayoutTransition transition = new LayoutTransition();
+        transition.setStagger(LayoutTransition.CHANGE_APPEARING, DEFAULT_ANIM_DURATION / 2);
+        transition.setDuration(LayoutTransition.APPEARING, DEFAULT_ANIM_DURATION);
+        transition.setDuration(LayoutTransition.DISAPPEARING, DEFAULT_ANIM_DURATION / 2);
+        transition.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
+        transition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
+        transition.setInterpolator(LayoutTransition.APPEARING, Interpolators.FAST_OUT_SLOW_IN);
+        transition.setInterpolator(LayoutTransition.DISAPPEARING, Interpolators.ALPHA_OUT);
+        transition.setAnimateParentHierarchy(false);
+        transition.addTransitionListener(new SliceViewTransitionListener());
+        setLayoutTransition(transition);
     }
 
     @Override
@@ -112,6 +134,7 @@
 
         // Make sure we always have the most current slice
         mLiveData.observeForever(this);
+        Dependency.get(ConfigurationController.class).addCallback(this);
     }
 
     @Override
@@ -119,17 +142,29 @@
         super.onDetachedFromWindow();
 
         mLiveData.removeObserver(this);
+        Dependency.get(ConfigurationController.class).removeCallback(this);
     }
 
-    private void showSlice(Slice slice) {
+    private void showSlice() {
+        if (mPulsing) {
+            mTitle.setVisibility(GONE);
+            mRow.setVisibility(GONE);
+            mContentChangeListener.accept(getLayoutTransition() != null);
+            return;
+        }
 
-        ListContent lc = new ListContent(getContext(), slice);
+        if (mSlice == null) {
+            return;
+        }
+
+        ListContent lc = new ListContent(getContext(), mSlice);
         mHasHeader = lc.hasHeader();
         List<SliceItem> subItems = lc.getRowItems();
         if (!mHasHeader) {
             mTitle.setVisibility(GONE);
         } else {
             mTitle.setVisibility(VISIBLE);
+
             // If there's a header it'll be the first subitem
             RowContent header = new RowContent(getContext(), subItems.get(0),
                     true /* showStartItem */);
@@ -154,6 +189,7 @@
         final int subItemsCount = subItems.size();
         final int blendedColor = getTextColor();
         final int startIndex = mHasHeader ? 1 : 0; // First item is header; skip it
+        mRow.setVisibility(subItemsCount > 0 ? VISIBLE : GONE);
         for (int i = startIndex; i < subItemsCount; i++) {
             SliceItem item = subItems.get(i);
             RowContent rc = new RowContent(getContext(), item, true /* showStartItem */);
@@ -200,15 +236,20 @@
             }
         }
 
-        updateVisibility();
-        mListener.accept(mHasHeader);
+        if (mContentChangeListener != null) {
+            mContentChangeListener.accept(getLayoutTransition() != null);
+        }
     }
 
-    private void updateVisibility() {
-        final boolean hasContent = mHasHeader || mRow.getChildCount() > 0;
-        final int visibility = hasContent && !mHideContent ? VISIBLE : GONE;
-        if (visibility != getVisibility()) {
-            setVisibility(visibility);
+    public void setPulsing(boolean pulsing, boolean animate) {
+        mPulsing = pulsing;
+        LayoutTransition transition = getLayoutTransition();
+        if (!animate) {
+            setLayoutTransition(null);
+        }
+        showSlice();
+        if (!animate) {
+            setLayoutTransition(transition);
         }
     }
 
@@ -252,8 +293,9 @@
         return optimalString.toString();
     }
 
-    public void setDark(float darkAmount) {
+    public void setDarkAmount(float darkAmount) {
         mDarkAmount = darkAmount;
+        mRow.setDarkAmount(darkAmount);
         updateTextColors();
     }
 
@@ -281,12 +323,17 @@
         }
     }
 
-    public void setListener(Consumer<Boolean> listener) {
-        mListener = listener;
+    /**
+     * Listener that gets invoked every time the title or the row visibility changes.
+     * Parameter will be {@code true} whenever the change happens animated.
+     * @param contentChangeListener The listener.
+     */
+    public void setContentChangeListener(Consumer<Boolean> contentChangeListener) {
+        mContentChangeListener = contentChangeListener;
     }
 
     public boolean hasHeader() {
-        return mHasHeader;
+        return mTitle.getVisibility() == VISIBLE;
     }
 
     /**
@@ -295,7 +342,8 @@
      */
     @Override
     public void onChanged(Slice slice) {
-        showSlice(slice);
+        mSlice = slice;
+        showSlice();
     }
 
     @Override
@@ -333,15 +381,20 @@
         updateTextColors();
     }
 
-    public void setHideContent(boolean hideContent) {
-        mHideContent = hideContent;
-        updateVisibility();
+    @Override
+    public void onDensityOrFontScaleChanged() {
+        mIconSize = mContext.getResources().getDimensionPixelSize(R.dimen.widget_icon_size);
     }
 
     public static class Row extends LinearLayout {
 
-        private static final long ROW_ANIM_DURATION = 350;
-        private final WakeLock mAnimationWakeLock;
+        /**
+         * This view is visible in AOD, which means that the device will sleep if we
+         * don't hold a wake lock. We want to enter doze only after all views have reached
+         * their desired positions.
+         */
+        private final Animation.AnimationListener mKeepAwakeListener;
+        private float mDarkAmount;
 
         public Row(Context context) {
             this(context, null);
@@ -357,16 +410,13 @@
 
         public Row(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
             super(context, attrs, defStyleAttr, defStyleRes);
-            mAnimationWakeLock = WakeLock.createPartial(context, "slice animation");
+            mKeepAwakeListener = new KeepAwakeAnimationListener(mContext);
         }
 
         @Override
         protected void onFinishInflate() {
             LayoutTransition transition = new LayoutTransition();
-            transition.setDuration(ROW_ANIM_DURATION);
-            transition.setStagger(LayoutTransition.CHANGING, ROW_ANIM_DURATION);
-            transition.setStagger(LayoutTransition.CHANGE_APPEARING, ROW_ANIM_DURATION);
-            transition.setStagger(LayoutTransition.CHANGE_DISAPPEARING, ROW_ANIM_DURATION);
+            transition.setDuration(DEFAULT_ANIM_DURATION);
 
             PropertyValuesHolder left = PropertyValuesHolder.ofInt("left", 0, 1);
             PropertyValuesHolder right = PropertyValuesHolder.ofInt("right", 0, 1);
@@ -378,7 +428,8 @@
                     Interpolators.ACCELERATE_DECELERATE);
             transition.setInterpolator(LayoutTransition.CHANGE_DISAPPEARING,
                     Interpolators.ACCELERATE_DECELERATE);
-            transition.setStartDelay(LayoutTransition.CHANGE_APPEARING, ROW_ANIM_DURATION);
+            transition.setStartDelay(LayoutTransition.CHANGE_APPEARING, DEFAULT_ANIM_DURATION);
+            transition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, DEFAULT_ANIM_DURATION);
 
             ObjectAnimator appearAnimator = ObjectAnimator.ofFloat(null, "alpha", 0f, 1f);
             transition.setAnimator(LayoutTransition.APPEARING, appearAnimator);
@@ -386,31 +437,11 @@
 
             ObjectAnimator disappearAnimator = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f);
             transition.setInterpolator(LayoutTransition.DISAPPEARING, Interpolators.ALPHA_OUT);
-            transition.setDuration(LayoutTransition.DISAPPEARING, ROW_ANIM_DURATION / 2);
+            transition.setDuration(LayoutTransition.DISAPPEARING, DEFAULT_ANIM_DURATION / 4);
             transition.setAnimator(LayoutTransition.DISAPPEARING, disappearAnimator);
 
             transition.setAnimateParentHierarchy(false);
             setLayoutTransition(transition);
-
-            // This view is visible in AOD, which means that the device will sleep if we
-            // don't hold a wake lock. We want to enter doze only after all views have reached
-            // their desired positions.
-            setLayoutAnimationListener(new Animation.AnimationListener() {
-                @Override
-                public void onAnimationStart(Animation animation) {
-                    mAnimationWakeLock.acquire();
-                }
-
-                @Override
-                public void onAnimationEnd(Animation animation) {
-                    mAnimationWakeLock.release();
-                }
-
-                @Override
-                public void onAnimationRepeat(Animation animation) {
-
-                }
-            });
         }
 
         @Override
@@ -424,23 +455,58 @@
             }
             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         }
+
+        public void setDarkAmount(float darkAmount) {
+            boolean isAwake = darkAmount != 0;
+            boolean wasAwake = mDarkAmount != 0;
+            if (isAwake == wasAwake) {
+                return;
+            }
+            mDarkAmount = darkAmount;
+            setLayoutAnimationListener(isAwake ? null : mKeepAwakeListener);
+        }
+
+        @Override
+        public boolean hasOverlappingRendering() {
+            return false;
+        }
     }
 
     /**
      * Representation of an item that appears under the clock on main keyguard message.
      */
-    private class KeyguardSliceButton extends Button {
+    @VisibleForTesting
+    static class KeyguardSliceButton extends Button implements
+            ConfigurationController.ConfigurationListener {
+        private final Context mContext;
 
         public KeyguardSliceButton(Context context) {
             super(context, null /* attrs */, 0 /* styleAttr */,
                     com.android.keyguard.R.style.TextAppearance_Keyguard_Secondary);
-            int horizontalPadding = (int) context.getResources()
+            mContext = context;
+            onDensityOrFontScaleChanged();
+            setEllipsize(TruncateAt.END);
+        }
+
+        @Override
+        protected void onAttachedToWindow() {
+            super.onAttachedToWindow();
+            Dependency.get(ConfigurationController.class).addCallback(this);
+        }
+
+        @Override
+        protected void onDetachedFromWindow() {
+            super.onDetachedFromWindow();
+            Dependency.get(ConfigurationController.class).removeCallback(this);
+        }
+
+        @Override
+        public void onDensityOrFontScaleChanged() {
+            int horizontalPadding = (int) mContext.getResources()
                     .getDimension(R.dimen.widget_horizontal_padding);
             setPadding(horizontalPadding / 2, 0, horizontalPadding / 2, 0);
-            setCompoundDrawablePadding((int) context.getResources()
+            setCompoundDrawablePadding((int) mContext.getResources()
                     .getDimension(R.dimen.widget_icon_padding));
-            setMaxLines(1);
-            setEllipsize(TruncateAt.END);
         }
 
         @Override
@@ -465,4 +531,38 @@
             }
         }
     }
+
+    private class SliceViewTransitionListener implements LayoutTransition.TransitionListener {
+        @Override
+        public void startTransition(LayoutTransition transition, ViewGroup container, View view,
+                int transitionType) {
+            switch (transitionType) {
+                case  LayoutTransition.APPEARING:
+                    int translation = getResources().getDimensionPixelSize(
+                            R.dimen.pulsing_notification_appear_translation);
+                    view.setTranslationY(translation);
+                    view.animate()
+                            .translationY(0)
+                            .setDuration(DEFAULT_ANIM_DURATION)
+                            .setInterpolator(Interpolators.ALPHA_IN)
+                            .start();
+                    break;
+                case LayoutTransition.DISAPPEARING:
+                    if (view == mTitle) {
+                        // Translate the view to the inverse of its height, so the layout event
+                        // won't misposition it.
+                        LayoutParams params = (LayoutParams) mTitle.getLayoutParams();
+                        int margin = params.topMargin + params.bottomMargin;
+                        mTitle.setTranslationY(-mTitle.getHeight() - margin);
+                    }
+                    break;
+            }
+        }
+
+        @Override
+        public void endTransition(LayoutTransition transition, ViewGroup container, View view,
+                int transitionType) {
+
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index a4a3d14..ff182de3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -16,12 +16,11 @@
 
 package com.android.keyguard;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.app.ActivityManager;
-import android.app.AlarmManager;
 import android.app.IActivityManager;
 import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Color;
 import android.os.Handler;
@@ -37,18 +36,24 @@
 import android.util.Slog;
 import android.util.TypedValue;
 import android.view.View;
-import android.view.ViewGroup;
 import android.widget.GridLayout;
+import android.widget.RelativeLayout;
 import android.widget.TextClock;
 import android.widget.TextView;
 
 import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.ViewClippingUtil;
+import com.android.systemui.Dependency;
+import com.android.systemui.Interpolators;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
 
 import com.google.android.collect.Sets;
 
 import java.util.Locale;
 
-public class KeyguardStatusView extends GridLayout {
+public class KeyguardStatusView extends GridLayout implements
+        ConfigurationController.ConfigurationListener, View.OnLayoutChangeListener {
     private static final boolean DEBUG = KeyguardConstants.DEBUG;
     private static final String TAG = "KeyguardStatusView";
     private static final int MARQUEE_DELAY_MS = 2000;
@@ -56,13 +61,11 @@
     private final LockPatternUtils mLockPatternUtils;
     private final IActivityManager mIActivityManager;
     private final float mSmallClockScale;
-    private final float mWidgetPadding;
 
     private TextView mLogoutView;
     private TextClock mClockView;
     private View mClockSeparator;
     private TextView mOwnerInfo;
-    private ViewGroup mClockContainer;
     private KeyguardSliceView mKeyguardSlice;
     private Runnable mPendingMarqueeStart;
     private Handler mHandler;
@@ -71,19 +74,22 @@
     private boolean mPulsing;
     private float mDarkAmount = 0;
     private int mTextColor;
+    private float mWidgetPadding;
+    private boolean mAnimateLayout;
+    private int mLastLayoutHeight;
 
     private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
 
         @Override
         public void onTimeChanged() {
-            refresh();
+            refreshTime();
         }
 
         @Override
         public void onKeyguardVisibilityChanged(boolean showing) {
             if (showing) {
                 if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing);
-                refresh();
+                refreshTime();
                 updateOwnerInfo();
                 updateLogoutView();
             }
@@ -101,7 +107,7 @@
 
         @Override
         public void onUserSwitchComplete(int userId) {
-            refresh();
+            refreshFormat();
             updateOwnerInfo();
             updateLogoutView();
         }
@@ -127,7 +133,7 @@
         mHandler = new Handler(Looper.myLooper());
         mSmallClockScale = getResources().getDimension(R.dimen.widget_small_font_size)
                 / getResources().getDimension(R.dimen.widget_big_font_size);
-        mWidgetPadding = getResources().getDimension(R.dimen.widget_vertical_padding);
+        onDensityOrFontScaleChanged();
     }
 
     private void setEnableMarquee(boolean enabled) {
@@ -160,7 +166,6 @@
         mLogoutView = findViewById(R.id.logout);
         mLogoutView.setOnClickListener(this::onLogoutClicked);
 
-        mClockContainer = findViewById(R.id.keyguard_clock_container);
         mClockView = findViewById(R.id.clock_view);
         mClockView.setShowCurrentUserTime(true);
         if (KeyguardClockAccessibilityDelegate.isNeeded(mContext)) {
@@ -169,46 +174,111 @@
         mOwnerInfo = findViewById(R.id.owner_info);
         mKeyguardSlice = findViewById(R.id.keyguard_status_area);
         mClockSeparator = findViewById(R.id.clock_separator);
-        mVisibleInDoze = Sets.newArraySet(mClockView, mKeyguardSlice, mClockSeparator);
+        mVisibleInDoze = Sets.newArraySet(mClockView, mKeyguardSlice);
         mTextColor = mClockView.getCurrentTextColor();
 
-        mKeyguardSlice.setListener(this::onSliceContentChanged);
-        onSliceContentChanged(mKeyguardSlice.hasHeader());
+        mClockView.addOnLayoutChangeListener(this);
+        mClockSeparator.addOnLayoutChangeListener(this);
+        mKeyguardSlice.setContentChangeListener(this::onSliceContentChanged);
+        onSliceContentChanged(false /* animated */);
 
         boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
         setEnableMarquee(shouldMarquee);
-        refresh();
+        refreshFormat();
         updateOwnerInfo();
         updateLogoutView();
+        updateDark();
 
         // Disable elegant text height because our fancy colon makes the ymin value huge for no
         // reason.
         mClockView.setElegantTextHeight(false);
     }
 
-    private void onSliceContentChanged(boolean hasHeader) {
-        final boolean smallClock = hasHeader || mPulsing;
-        final float clockScale = smallClock ? mSmallClockScale : 1;
-        float translation = (mClockView.getHeight() - (mClockView.getHeight() * clockScale)) / 2f;
-        if (smallClock) {
-            translation -= mWidgetPadding;
+    private void onSliceContentChanged(boolean animated) {
+        mAnimateLayout = animated;
+        boolean smallClock = mKeyguardSlice.hasHeader() || mPulsing;
+        float clockScale = smallClock ? mSmallClockScale : 1;
+
+        RelativeLayout.LayoutParams layoutParams =
+                (RelativeLayout.LayoutParams) mClockView.getLayoutParams();
+        int height = mClockView.getHeight();
+        layoutParams.bottomMargin = (int) -(height - (clockScale * height));
+        mClockView.setLayoutParams(layoutParams);
+
+        layoutParams = (RelativeLayout.LayoutParams) mClockSeparator.getLayoutParams();
+        layoutParams.topMargin = smallClock ? (int) mWidgetPadding : 0;
+        layoutParams.bottomMargin = layoutParams.topMargin;
+        mClockSeparator.setLayoutParams(layoutParams);
+    }
+
+    /**
+     * Animate clock and its separator when necessary.
+     */
+    @Override
+    public void onLayoutChange(View view, int left, int top, int right, int bottom,
+            int oldLeft, int oldTop, int oldRight, int oldBottom) {
+        int heightOffset = mPulsing ? 0 : getHeight() - mLastLayoutHeight;
+        boolean hasHeader = mKeyguardSlice.hasHeader();
+        boolean smallClock = hasHeader || mPulsing;
+        long duration = KeyguardSliceView.DEFAULT_ANIM_DURATION;
+        long delay = smallClock ? 0 : duration / 4;
+
+        if (view == mClockView) {
+            float clockScale = smallClock ? mSmallClockScale : 1;
+            if (mAnimateLayout) {
+                mClockView.setY(oldTop + heightOffset);
+                mClockView.animate().cancel();
+                mClockView.animate()
+                        .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                        .setDuration(duration)
+                        .setListener(new ClipChildrenAnimationListener())
+                        .setStartDelay(delay)
+                        .y(top)
+                        .scaleX(clockScale)
+                        .scaleY(clockScale)
+                        .start();
+            } else {
+                mClockView.setY(top);
+                mClockView.setScaleX(clockScale);
+                mClockView.setScaleY(clockScale);
+            }
+        } else if (view == mClockSeparator) {
+            boolean hasSeparator = hasHeader && !mPulsing;
+            float alpha = hasSeparator ? 1 : 0;
+            if (mAnimateLayout) {
+                boolean isAwake = mDarkAmount != 0;
+                mClockSeparator.setY(oldTop + heightOffset);
+                mClockSeparator.animate().cancel();
+                mClockSeparator.animate()
+                        .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                        .setDuration(duration)
+                        .setListener(isAwake ? null : new KeepAwakeAnimationListener(getContext()))
+                        .setStartDelay(delay)
+                        .y(top)
+                        .alpha(alpha)
+                        .start();
+            } else {
+                mClockSeparator.setY(top);
+                mClockSeparator.setAlpha(alpha);
+            }
         }
-        mClockView.setTranslationY(translation);
-        mClockView.setScaleX(clockScale);
-        mClockView.setScaleY(clockScale);
-        mClockSeparator.setVisibility(hasHeader && !mPulsing ? VISIBLE : GONE);
     }
 
     @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        mClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
-                getResources().getDimensionPixelSize(R.dimen.widget_big_font_size));
-        // Some layouts like burmese have a different margin for the clock
-        MarginLayoutParams layoutParams = (MarginLayoutParams) mClockView.getLayoutParams();
-        layoutParams.bottomMargin = getResources().getDimensionPixelSize(
-                R.dimen.bottom_text_spacing_digital);
-        mClockView.setLayoutParams(layoutParams);
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        mClockView.setPivotX(mClockView.getWidth() / 2);
+        mClockView.setPivotY(0);
+        mLastLayoutHeight = getHeight();
+    }
+
+    @Override
+    public void onDensityOrFontScaleChanged() {
+        mWidgetPadding = getResources().getDimension(R.dimen.widget_vertical_padding);
+        if (mClockView != null) {
+            mClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+                    getResources().getDimensionPixelSize(R.dimen.widget_big_font_size));
+        }
         if (mOwnerInfo != null) {
             mOwnerInfo.setTextSize(TypedValue.COMPLEX_UNIT_PX,
                     getResources().getDimensionPixelSize(R.dimen.widget_label_font_size));
@@ -219,17 +289,10 @@
         mClockView.refresh();
     }
 
-    private void refresh() {
+    private void refreshFormat() {
         Patterns.update(mContext);
-        refreshTime();
-    }
-
-    public int getClockBottom() {
-        if (mOwnerInfo != null && mOwnerInfo.getVisibility() == VISIBLE) {
-            return mOwnerInfo.getBottom();
-        } else {
-            return mClockContainer.getBottom();
-        }
+        mClockView.setFormat12Hour(Patterns.clockView12);
+        mClockView.setFormat24Hour(Patterns.clockView24);
     }
 
     public int getLogoutButtonHeight() {
@@ -249,34 +312,8 @@
 
     private void updateOwnerInfo() {
         if (mOwnerInfo == null) return;
-        String ownerInfo = getOwnerInfo();
-        if (!TextUtils.isEmpty(ownerInfo)) {
-            mOwnerInfo.setVisibility(View.VISIBLE);
-            mOwnerInfo.setText(ownerInfo);
-        } else {
-            mOwnerInfo.setVisibility(View.GONE);
-        }
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mInfoCallback);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mInfoCallback);
-    }
-
-    private String getOwnerInfo() {
-        String info = null;
-        if (mLockPatternUtils.isDeviceOwnerInfoEnabled()) {
-            // Use the device owner information set by device policy client via
-            // device policy manager.
-            info = mLockPatternUtils.getDeviceOwnerInfo();
-        } else {
+        String info = mLockPatternUtils.getDeviceOwnerInfo();
+        if (info == null) {
             // Use the current user owner information if enabled.
             final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled(
                     KeyguardUpdateMonitor.getCurrentUser());
@@ -284,7 +321,26 @@
                 info = mLockPatternUtils.getOwnerInfo(KeyguardUpdateMonitor.getCurrentUser());
             }
         }
-        return info;
+        mOwnerInfo.setText(info);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mInfoCallback);
+        Dependency.get(ConfigurationController.class).addCallback(this);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mInfoCallback);
+        Dependency.get(ConfigurationController.class).removeCallback(this);
+    }
+
+    @Override
+    public void onLocaleListChanged() {
+        refreshFormat();
     }
 
     @Override
@@ -329,32 +385,27 @@
             return;
         }
         mDarkAmount = darkAmount;
-
-        boolean dark = darkAmount == 1;
-        mLogoutView.setAlpha(dark ? 0 : 1);
-        final int N = mClockContainer.getChildCount();
-        for (int i = 0; i < N; i++) {
-            View child = mClockContainer.getChildAt(i);
-            if (mVisibleInDoze.contains(child)) {
-                continue;
-            }
-            child.setAlpha(dark ? 0 : 1);
-        }
-        if (mOwnerInfo != null) {
-            mOwnerInfo.setAlpha(dark ? 0 : 1);
-        }
-
-        final int blendedTextColor = ColorUtils.blendARGB(mTextColor, Color.WHITE, darkAmount);
-        updateDozeVisibleViews();
-        mKeyguardSlice.setDark(darkAmount);
-        mClockView.setTextColor(blendedTextColor);
-        mClockSeparator.setBackgroundTintList(ColorStateList.valueOf(blendedTextColor));
+        updateDark();
     }
 
-    public void setPulsing(boolean pulsing) {
+    private void updateDark() {
+        boolean dark = mDarkAmount == 1;
+        mLogoutView.setAlpha(dark ? 0 : 1);
+        if (mOwnerInfo != null) {
+            boolean hasText = !TextUtils.isEmpty(mOwnerInfo.getText());
+            mOwnerInfo.setVisibility(hasText && mDarkAmount != 1 ? VISIBLE : GONE);
+        }
+
+        final int blendedTextColor = ColorUtils.blendARGB(mTextColor, Color.WHITE, mDarkAmount);
+        updateDozeVisibleViews();
+        mKeyguardSlice.setDarkAmount(mDarkAmount);
+        mClockView.setTextColor(blendedTextColor);
+        mClockSeparator.setBackgroundColor(blendedTextColor);
+    }
+
+    public void setPulsing(boolean pulsing, boolean animate) {
         mPulsing = pulsing;
-        mKeyguardSlice.setHideContent(pulsing);
-        onSliceContentChanged(mKeyguardSlice.hasHeader());
+        mKeyguardSlice.setPulsing(pulsing, animate);
         updateDozeVisibleViews();
     }
 
@@ -378,4 +429,24 @@
             Log.e(TAG, "Failed to logout user", re);
         }
     }
+
+    private class ClipChildrenAnimationListener extends AnimatorListenerAdapter implements
+            ViewClippingUtil.ClippingParameters {
+
+        ClipChildrenAnimationListener() {
+            ViewClippingUtil.setClippingDeactivated(mClockView, true /* deactivated */,
+                    this /* clippingParams */);
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            ViewClippingUtil.setClippingDeactivated(mClockView, false /* deactivated */,
+                    this /* clippingParams */);
+        }
+
+        @Override
+        public boolean shouldFinish(View view) {
+            return view == getParent();
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index c826aaa..fb13925 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -29,8 +29,11 @@
 import static android.os.BatteryManager.EXTRA_PLUGGED;
 import static android.os.BatteryManager.EXTRA_STATUS;
 
+import android.annotation.AnyThread;
+import android.annotation.MainThread;
 import android.app.ActivityManager;
 import android.app.AlarmManager;
+import android.app.Instrumentation;
 import android.app.PendingIntent;
 import android.app.UserSwitchObserver;
 import android.app.admin.DevicePolicyManager;
@@ -44,7 +47,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.database.ContentObserver;
-import android.graphics.Bitmap;
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
 import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
@@ -68,6 +70,7 @@
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
 import android.telephony.TelephonyManager;
 import android.util.Log;
+import android.util.Slog;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 
@@ -76,6 +79,7 @@
 import com.android.internal.telephony.IccCardConstants.State;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.Preconditions;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -87,7 +91,6 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map.Entry;
 
@@ -355,6 +358,7 @@
 
     private static int sCurrentUser;
     private Runnable mUpdateFingerprintListeningState = this::updateFingerprintListeningState;
+    private static boolean sDisableHandlerCheckForTesting;
 
     public synchronized static void setCurrentUser(int currentUser) {
         sCurrentUser = currentUser;
@@ -366,6 +370,7 @@
 
     @Override
     public void onTrustChanged(boolean enabled, int userId, int flags) {
+        checkIsHandlerThread();
         mUserHasTrust.put(userId, enabled);
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -383,7 +388,7 @@
         dispatchErrorMessage(message);
     }
 
-    protected void handleSimSubscriptionInfoChanged() {
+    private void handleSimSubscriptionInfoChanged() {
         if (DEBUG_SIM_STATES) {
             Log.v(TAG, "onSubscriptionInfoChanged()");
             List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
@@ -400,9 +405,16 @@
         // Hack level over 9000: Because the subscription id is not yet valid when we see the
         // first update in handleSimStateChange, we need to force refresh all all SIM states
         // so the subscription id for them is consistent.
-        List<Integer> changedSubscriptionIds = refreshSimState(subscriptionInfos);
-        for (int i = 0; i < changedSubscriptionIds.size(); i++) {
-            SimData data = mSimDatas.get(changedSubscriptionIds.get(i));
+        ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
+        for (int i = 0; i < subscriptionInfos.size(); i++) {
+            SubscriptionInfo info = subscriptionInfos.get(i);
+            boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
+            if (changed) {
+                changedSubscriptions.add(info);
+            }
+        }
+        for (int i = 0; i < changedSubscriptions.size(); i++) {
+            SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
             for (int j = 0; j < mCallbacks.size(); j++) {
                 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
                 if (cb != null) {
@@ -444,6 +456,7 @@
 
     @Override
     public void onTrustManagedChanged(boolean managed, int userId) {
+        checkIsHandlerThread();
         mUserTrustIsManaged.put(userId, managed);
 
         for (int i = 0; i < mCallbacks.size(); i++) {
@@ -631,6 +644,7 @@
     }
 
     private void notifyFingerprintRunningStateChanged() {
+        checkIsHandlerThread();
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -639,6 +653,7 @@
         }
     }
     private void handleFaceUnlockStateChanged(boolean running, int userId) {
+        checkIsHandlerThread();
         mUserFaceUnlockRunning.put(userId, running);
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -698,6 +713,7 @@
     }
 
     private void notifyStrongAuthStateChanged(int userId) {
+        checkIsHandlerThread();
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -1118,20 +1134,6 @@
         updateFingerprintListeningState();
     }
 
-    /**
-     * IMPORTANT: Must be called from UI thread.
-     */
-    public void dispatchSetBackground(Bitmap bmp) {
-        if (DEBUG) Log.d(TAG, "dispatchSetBackground");
-        final int count = mCallbacks.size();
-        for (int i = 0; i < count; i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onSetBackground(bmp);
-            }
-        }
-    }
-
     private void handleUserInfoChanged(int userId) {
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -1343,6 +1345,7 @@
      * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
      */
     public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
+        checkIsHandlerThread();
         if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
             mHasLockscreenWallpaper = hasLockscreenWallpaper;
             for (int i = mCallbacks.size() - 1; i >= 0; i--) {
@@ -1364,7 +1367,7 @@
     /**
      * Handle {@link #MSG_DPM_STATE_CHANGED}
      */
-    protected void handleDevicePolicyManagerStateChanged() {
+    private void handleDevicePolicyManagerStateChanged() {
         updateFingerprintListeningState();
         for (int i = mCallbacks.size() - 1; i >= 0; i--) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -1377,7 +1380,7 @@
     /**
      * Handle {@link #MSG_USER_SWITCHING}
      */
-    protected void handleUserSwitching(int userId, IRemoteCallback reply) {
+    private void handleUserSwitching(int userId, IRemoteCallback reply) {
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -1393,7 +1396,7 @@
     /**
      * Handle {@link #MSG_USER_SWITCH_COMPLETE}
      */
-    protected void handleUserSwitchComplete(int userId) {
+    private void handleUserSwitchComplete(int userId) {
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -1415,7 +1418,7 @@
     /**
      * Handle {@link #MSG_BOOT_COMPLETED}
      */
-    protected void handleBootCompleted() {
+    private void handleBootCompleted() {
         if (mBootCompleted) return;
         mBootCompleted = true;
         for (int i = 0; i < mCallbacks.size(); i++) {
@@ -1437,7 +1440,7 @@
     /**
      * Handle {@link #MSG_DEVICE_PROVISIONED}
      */
-    protected void handleDeviceProvisioned() {
+    private void handleDeviceProvisioned() {
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -1454,7 +1457,7 @@
     /**
      * Handle {@link #MSG_PHONE_STATE_CHANGED}
      */
-    protected void handlePhoneStateChanged(String newState) {
+    private void handlePhoneStateChanged(String newState) {
         if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
         if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
             mPhoneState = TelephonyManager.CALL_STATE_IDLE;
@@ -1474,7 +1477,7 @@
     /**
      * Handle {@link #MSG_RINGER_MODE_CHANGED}
      */
-    protected void handleRingerModeChange(int mode) {
+    private void handleRingerModeChange(int mode) {
         if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
         mRingMode = mode;
         for (int i = 0; i < mCallbacks.size(); i++) {
@@ -1519,8 +1522,8 @@
      * Handle {@link #MSG_SIM_STATE_CHANGE}
      */
     @VisibleForTesting
-    protected void handleSimStateChange(int subId, int slotId, State state) {
-
+    void handleSimStateChange(int subId, int slotId, State state) {
+        checkIsHandlerThread();
         if (DEBUG_SIM_STATES) {
             Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
                     + slotId + ", state=" + state +")");
@@ -1583,6 +1586,7 @@
      * <p>Needs to be called from the main thread.
      */
     public void onKeyguardVisibilityChanged(boolean showing) {
+        checkIsHandlerThread();
         if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
         mKeyguardIsVisible = showing;
         for (int i = 0; i < mCallbacks.size(); i++) {
@@ -1673,6 +1677,7 @@
      * @param callback The callback to remove
      */
     public void removeCallback(KeyguardUpdateMonitorCallback callback) {
+        checkIsHandlerThread();
         if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
         for (int i = mCallbacks.size() - 1; i >= 0; i--) {
             if (mCallbacks.get(i).get() == callback) {
@@ -1687,6 +1692,7 @@
      * @param callback The callback to register
      */
     public void registerCallback(KeyguardUpdateMonitorCallback callback) {
+        checkIsHandlerThread();
         if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
         // Prevent adding duplicate callbacks
         for (int i = 0; i < mCallbacks.size(); i++) {
@@ -1705,6 +1711,7 @@
         return mSwitchingUser;
     }
 
+    @AnyThread
     public void setSwitchingUser(boolean switching) {
         mSwitchingUser = switching;
         // Since this comes in on a binder thread, we need to post if first
@@ -1748,6 +1755,7 @@
      * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
      * through mHandler, this *must* be called from the UI thread.
      */
+    @MainThread
     public void reportSimUnlocked(int subId) {
         if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
         int slotId = SubscriptionManager.getSlotIndex(subId);
@@ -1766,6 +1774,7 @@
         if (!bypassHandler) {
             mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
         } else {
+            checkIsHandlerThread();
             handleReportEmergencyCallAction();
         }
     }
@@ -1839,61 +1848,34 @@
     };
 
     /**
-     * @return A list of changed subscriptions, maybe empty but never null
+     * @return true if and only if the state has changed for the specified {@code slotId}
      */
-    private List<Integer> refreshSimState(final List<SubscriptionInfo> activeSubscriptionInfos) {
+    private boolean refreshSimState(int subId, int slotId) {
 
         // This is awful. It exists because there are two APIs for getting the SIM status
         // that don't return the complete set of values and have different types. In Keyguard we
         // need IccCardConstants, but TelephonyManager would only give us
         // TelephonyManager.SIM_STATE*, so we retrieve it manually.
         final TelephonyManager tele = TelephonyManager.from(mContext);
-        ArrayList<Integer> changedSubscriptionIds = new ArrayList<>();
-        HashSet<Integer> activeSubIds = new HashSet<>();
-        HashSet<Integer> activeSlotIds = new HashSet<>();
-
-        for (SubscriptionInfo info : activeSubscriptionInfos) {
-            int subId = info.getSubscriptionId();
-            int slotId = info.getSimSlotIndex();
-            int simState =  tele.getSimState(slotId);
-            State state;
-            try {
-                state = State.intToState(simState);
-            } catch(IllegalArgumentException ex) {
-                Log.w(TAG, "Unknown sim state: " + simState);
-                state = State.UNKNOWN;
-            }
-
-            SimData data = mSimDatas.get(subId);
-            final boolean changed;
-            if (data == null) {
-                data = new SimData(state, slotId, subId);
-                mSimDatas.put(subId, data);
-                changed = true;               // no data yet; force update
-            } else {
-                changed = data.simState != state;
-                data.simState = state;
-            }
-            if (changed) {
-                changedSubscriptionIds.add(subId);
-            }
-
-            activeSubIds.add(subId);
-            activeSlotIds.add(slotId);
+        int simState =  tele.getSimState(slotId);
+        State state;
+        try {
+            state = State.intToState(simState);
+        } catch(IllegalArgumentException ex) {
+            Log.w(TAG, "Unknown sim state: " + simState);
+            state = State.UNKNOWN;
         }
-
-        for (SimData data : mSimDatas.values()) {
-            if (!activeSubIds.contains(data.subId)
-                && !activeSlotIds.contains(data.slotId)
-                && data.simState != State.ABSENT) {
-                // for the inactive subscriptions, reset state to ABSENT
-                if (DEBUG_SIM_STATES) Log.d(TAG, "reset state to ABSENT for subId:" + data.subId);
-                data.simState = State.ABSENT;
-                changedSubscriptionIds.add(data.subId);
-            }
+        SimData data = mSimDatas.get(subId);
+        final boolean changed;
+        if (data == null) {
+            data = new SimData(state, slotId, subId);
+            mSimDatas.put(subId, data);
+            changed = true; // no data yet; force update
+        } else {
+            changed = data.simState != state;
+            data.simState = state;
         }
-
-        return changedSubscriptionIds;
+        return changed;
     }
 
     public static boolean isSimPinSecure(IccCardConstants.State state) {
@@ -1995,6 +1977,7 @@
     }
 
     private void updateLogoutEnabled() {
+        checkIsHandlerThread();
         boolean logoutEnabled = mDevicePolicyManager.isLogoutEnabled();
         if (mLogoutEnabled != logoutEnabled) {
             mLogoutEnabled = logoutEnabled;
@@ -2007,6 +1990,36 @@
         }
     }
 
+    private void checkIsHandlerThread() {
+        if (sDisableHandlerCheckForTesting) {
+            return;
+        }
+        if (!mHandler.getLooper().isCurrentThread()) {
+            Log.wtf(TAG, "must call on mHandler's thread "
+                    + mHandler.getLooper().getThread() + ", not " + Thread.currentThread());
+        }
+    }
+
+    /**
+     * Turn off the handler check for testing.
+     *
+     * This is necessary because currently tests are not too careful about which thread they call
+     * into this class on.
+     *
+     * Note that this must be called before scheduling any work involving KeyguardUpdateMonitor
+     * instances.
+     *
+     * TODO: fix the tests and remove this.
+     */
+    @VisibleForTesting
+    public static void disableHandlerCheckForTesting(Instrumentation instrumentation) {
+        Preconditions.checkNotNull(instrumentation, "Must only call this method in tests!");
+        // Don't need synchronization here *if* the callers follow the contract and call this only
+        // before scheduling work for KeyguardUpdateMonitor on other threads, because the scheduling
+        // of that work forces a happens-before relationship.
+        sDisableHandlerCheckForTesting = true;
+    }
+
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("KeyguardUpdateMonitor state:");
         pw.println("  SIM States:");
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 5fce0a6..7d19784 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -21,6 +21,7 @@
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Process;
+import android.os.ServiceManager;
 import android.util.ArrayMap;
 import android.view.IWindowManager;
 import android.view.WindowManagerGlobal;
@@ -28,6 +29,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.ColorDisplayController;
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.Preconditions;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.systemui.assist.AssistManager;
@@ -320,6 +322,9 @@
 
         mProviders.put(VibratorHelper.class, () -> new VibratorHelper(mContext));
 
+        mProviders.put(IStatusBarService.class, () -> IStatusBarService.Stub.asInterface(
+                ServiceManager.getService(Context.STATUS_BAR_SERVICE)));
+
         // Put all dependencies above here so the factory can override them if it wants.
         SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 0715933..c3412f2d 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -78,6 +78,8 @@
             SystemProperties.getBoolean("debug.screenshot_rounded_corners", false);
 
     private int mRoundedDefault;
+    private int mRoundedDefaultTop;
+    private int mRoundedDefaultBottom;
     private View mOverlay;
     private View mBottomOverlay;
     private float mDensity;
@@ -89,9 +91,14 @@
         mWindowManager = mContext.getSystemService(WindowManager.class);
         mRoundedDefault = mContext.getResources().getDimensionPixelSize(
                 R.dimen.rounded_corner_radius);
-        if (mRoundedDefault != 0 || shouldDrawCutout()) {
+        mRoundedDefaultTop = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_radius_top);
+        mRoundedDefaultBottom = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_radius_bottom);
+        if (hasRoundedCorners() || shouldDrawCutout()) {
             setupDecorations();
         }
+
         int padding = mContext.getResources().getDimensionPixelSize(
                 R.dimen.rounded_corner_content_padding);
         if (padding != 0) {
@@ -208,11 +215,15 @@
     private void updateWindowVisibility(View overlay) {
         boolean visibleForCutout = shouldDrawCutout()
                 && overlay.findViewById(R.id.display_cutout).getVisibility() == View.VISIBLE;
-        boolean visibleForRoundedCorners = mRoundedDefault > 0;
+        boolean visibleForRoundedCorners = hasRoundedCorners();
         overlay.setVisibility(visibleForCutout || visibleForRoundedCorners
                 ? View.VISIBLE : View.GONE);
     }
 
+    private boolean hasRoundedCorners() {
+        return mRoundedDefault > 0 || mRoundedDefaultBottom > 0 || mRoundedDefaultTop > 0;
+    }
+
     private boolean shouldDrawCutout() {
         return shouldDrawCutout(mContext);
     }
@@ -284,14 +295,26 @@
         if (mOverlay == null) return;
         if (SIZE.equals(key)) {
             int size = mRoundedDefault;
-            try {
-                size = (int) (Integer.parseInt(newValue) * mDensity);
-            } catch (Exception e) {
+            int sizeTop = mRoundedDefaultTop;
+            int sizeBottom = mRoundedDefaultBottom;
+            if (newValue != null) {
+                try {
+                    size = (int) (Integer.parseInt(newValue) * mDensity);
+                } catch (Exception e) {
+                }
             }
-            setSize(mOverlay.findViewById(R.id.left), size);
-            setSize(mOverlay.findViewById(R.id.right), size);
-            setSize(mBottomOverlay.findViewById(R.id.left), size);
-            setSize(mBottomOverlay.findViewById(R.id.right), size);
+
+            if (sizeTop == 0) {
+                sizeTop = size;
+            }
+            if (sizeBottom == 0) {
+                sizeBottom = size;
+            }
+
+            setSize(mOverlay.findViewById(R.id.left), sizeTop);
+            setSize(mOverlay.findViewById(R.id.right), sizeTop);
+            setSize(mBottomOverlay.findViewById(R.id.left), sizeBottom);
+            setSize(mBottomOverlay.findViewById(R.id.right), sizeBottom);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index ac4da73..721890f 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.util.ArrayMap;
 import android.util.Log;
-import android.view.View;
 import android.view.ViewGroup;
 
 import com.android.internal.logging.MetricsLogger;
@@ -43,12 +42,11 @@
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.NotificationViewHierarchyManager;
 import com.android.systemui.statusbar.ScrimView;
-import com.android.systemui.statusbar.SmartReplyLogger;
+import com.android.systemui.statusbar.SmartReplyController;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
-import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.LockIcon;
 import com.android.systemui.statusbar.phone.LockscreenWallpaper;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -58,7 +56,6 @@
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.SmartReplyConstants;
 
 import java.util.function.Consumer;
@@ -150,6 +147,6 @@
                 () -> new NotificationViewHierarchyManager(context));
         providers.put(NotificationEntryManager.class, () -> new NotificationEntryManager(context));
         providers.put(KeyguardDismissUtil.class, KeyguardDismissUtil::new);
-        providers.put(SmartReplyLogger.class, () -> new SmartReplyLogger(context));
+        providers.put(SmartReplyController.class, () -> new SmartReplyController());
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java
index 9459ce1..cc9fec0 100644
--- a/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java
@@ -17,17 +17,29 @@
 
 import android.content.Context;
 import android.util.ArrayMap;
+import android.view.View;
 
+import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.Dependency.DependencyProvider;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.statusbar.NotificationEntryManager;
 import com.android.systemui.statusbar.car.CarFacetButtonController;
+import com.android.systemui.statusbar.car.CarStatusBar;
+import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.car.hvac.HvacController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 
 /**
  * Class factory to provide car specific SystemUI components.
  */
 public class CarSystemUIFactory extends SystemUIFactory {
+
+    public StatusBarKeyguardViewManager createStatusBarKeyguardViewManager(Context context,
+            ViewMediatorCallback viewMediatorCallback, LockPatternUtils lockPatternUtils) {
+        return new CarStatusBarKeyguardViewManager(context, viewMediatorCallback, lockPatternUtils);
+    }
+
     @Override
     public void injectDependencies(ArrayMap<Object, DependencyProvider> providers,
             Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
index 913e781..a265a5e 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
@@ -28,6 +28,7 @@
 import android.os.PowerManager;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.view.InputDevice;
 import android.view.MotionEvent;
 import android.view.accessibility.AccessibilityManager;
 
@@ -74,6 +75,7 @@
     private boolean mEnforceBouncer = false;
     private boolean mBouncerOn = false;
     private boolean mSessionActive = false;
+    private boolean mIsTouchScreen = true;
     private int mState = StatusBarState.SHADE;
     private boolean mScreenOn;
     private boolean mShowingAod;
@@ -236,6 +238,11 @@
             // already sufficiently prevents false unlocks.
             return false;
         }
+        if (!mIsTouchScreen) {
+            // Unlocking with input devices besides the touchscreen should already be sufficiently
+            // anti-falsed.
+            return false;
+        }
         return mHumanInteractionClassifier.isFalseTouch();
     }
 
@@ -450,6 +457,9 @@
     }
 
     public void onTouchEvent(MotionEvent event, int width, int height) {
+        if (event.getAction() == MotionEvent.ACTION_DOWN) {
+            mIsTouchScreen = event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN);
+        }
         if (mSessionActive && !mBouncerOn) {
             mDataCollector.onTouchEvent(event, width, height);
             mHumanInteractionClassifier.onTouchEvent(event);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
index a0fdb9d..90140ff 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
@@ -36,7 +36,13 @@
      * Delay entering low power mode when animating to make sure that we'll have
      * time to move all elements into their final positions while still at 60 fps.
      */
-    private static final int ENTER_DOZE_DELAY = 3000;
+    private static final int ENTER_DOZE_DELAY = 6000;
+    /**
+     * Hide wallpaper earlier when entering low power mode. The gap between
+     * hiding the wallpaper and changing the display mode is necessary to hide
+     * the black frame that's inherent to hardware specs.
+     */
+    public static final int ENTER_DOZE_HIDE_WALLPAPER_DELAY = 2000;
 
     private final DozeMachine.Service mDozeService;
     private final Handler mHandler;
@@ -74,7 +80,9 @@
         }
 
         boolean messagePending = mHandler.hasCallbacks(mApplyPendingScreenState);
-        if (messagePending || oldState == DozeMachine.State.INITIALIZED) {
+        boolean pulseEnding = oldState  == DozeMachine.State.DOZE_PULSE_DONE
+                && newState == DozeMachine.State.DOZE_AOD;
+        if (messagePending || oldState == DozeMachine.State.INITIALIZED || pulseEnding) {
             // During initialization, we hide the navigation bar. That is however only applied after
             // a traversal; setting the screen state here is immediate however, so it can happen
             // that the screen turns on again before the navigation bar is hidden. To work around
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index a7975d7..087d481 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -1380,6 +1380,15 @@
             mHardwareLayout = HardwareUiLayout.get(mListView);
             mHardwareLayout.setOutsideTouchListener(view -> dismiss());
             setTitle(R.string.global_actions);
+            mListView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
+                @Override
+                public boolean dispatchPopulateAccessibilityEvent(
+                        View host, AccessibilityEvent event) {
+                    // Populate the title here, just as Activity does
+                    event.getText().add(mContext.getString(R.string.global_actions));
+                    return true;
+                }
+            });
         }
 
         private void updateList() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 5993c39..6809e76 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -165,6 +165,7 @@
     private static final int NOTIFY_SCREEN_TURNED_ON = 15;
     private static final int NOTIFY_SCREEN_TURNED_OFF = 16;
     private static final int NOTIFY_STARTED_GOING_TO_SLEEP = 17;
+    private static final int SYSTEM_READY = 18;
 
     /**
      * The default amount of time we stay awake (used for all key input)
@@ -502,9 +503,6 @@
                     break;
                 default:
                     if (DEBUG_SIM_STATES) Log.v(TAG, "Unspecific state: " + simState);
-                    synchronized (KeyguardViewMediator.this) {
-                        onSimAbsentLocked();
-                    }
                     break;
             }
         }
@@ -778,6 +776,10 @@
      * Let us know that the system is ready after startup.
      */
     public void onSystemReady() {
+        mHandler.obtainMessage(SYSTEM_READY).sendToTarget();
+    }
+
+    private void handleSystemReady() {
         synchronized (this) {
             if (DEBUG) Log.d(TAG, "onSystemReady");
             mSystemReady = true;
@@ -1606,6 +1608,9 @@
                     Log.w(TAG, "Timeout while waiting for activity drawn!");
                     Trace.endSection();
                     break;
+                case SYSTEM_READY:
+                    handleSystemReady();
+                    break;
             }
         }
     };
@@ -1857,6 +1862,8 @@
         synchronized (KeyguardViewMediator.this) {
 
             if (!mHiding) {
+                // Tell ActivityManager that we canceled the keyguardExitAnimation.
+                setShowingLocked(mShowing, mAodShowing, mSecondaryDisplayShowing, true /* force */);
                 return;
             }
             mHiding = false;
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 8cc47eb..5b76627 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -19,17 +19,29 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.media.AudioAttributes;
+import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.PowerManager;
 import android.os.UserHandle;
-import androidx.annotation.VisibleForTesting;
+import android.text.Annotation;
+import android.text.Layout;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
+import android.text.TextPaint;
+import android.text.TextUtils;
+import android.text.method.LinkMovementMethod;
+import android.text.style.URLSpan;
+import android.util.Log;
 import android.util.Slog;
+import android.view.View;
+import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.settingslib.Utils;
@@ -42,6 +54,8 @@
 
 import java.io.PrintWriter;
 import java.text.NumberFormat;
+import java.util.Locale;
+import java.util.Objects;
 
 public class PowerNotificationWarnings implements PowerUI.WarningsUI {
     private static final String TAG = PowerUI.TAG + ".Notification";
@@ -87,6 +101,8 @@
     private static final String SETTINGS_ACTION_OPEN_BATTERY_SAVER_SETTING =
             "android.settings.BATTERY_SAVER_SETTINGS";
 
+    private static final String BATTERY_SAVER_DESCRIPTION_URL_KEY = "url";
+
     private static final AudioAttributes AUDIO_ATTRIBUTES = new AudioAttributes.Builder()
             .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
             .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
@@ -463,7 +479,16 @@
         if (mSaverConfirmation != null) return;
         final SystemUIDialog d = new SystemUIDialog(mContext);
         d.setTitle(R.string.battery_saver_confirmation_title);
-        d.setMessage(com.android.internal.R.string.battery_saver_description);
+        d.setMessage(getBatterySaverDescription());
+
+        // Sad hack for http://b/78261259 and http://b/78298335. Otherwise "Battery" may be split
+        // into "Bat-tery".
+        if (isEnglishLocale()) {
+            d.setMessageHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE);
+        }
+        // We need to set LinkMovementMethod to make the link clickable.
+        d.setMessageMovementMethod(LinkMovementMethod.getInstance());
+
         d.setNegativeButton(android.R.string.cancel, null);
         d.setPositiveButton(R.string.battery_saver_confirmation_ok,
                 (dialog, which) -> setSaverMode(true, false));
@@ -473,6 +498,79 @@
         mSaverConfirmation = d;
     }
 
+    private boolean isEnglishLocale() {
+        return Objects.equals(Locale.getDefault().getLanguage(),
+                Locale.ENGLISH.getLanguage());
+    }
+
+    /**
+     * Generates the message for the "want to start battery saver?" dialog with a "learn more" link.
+     */
+    private CharSequence getBatterySaverDescription() {
+        final String learnMoreUrl = mContext.getText(
+                R.string.help_uri_battery_saver_learn_more_link_target).toString();
+
+        // If there's no link, use the string with no "learn more".
+        if (TextUtils.isEmpty(learnMoreUrl)) {
+            return mContext.getText(
+                    com.android.internal.R.string.battery_saver_description);
+        }
+
+        // If we have a link, use the string with the "learn more" link.
+        final CharSequence rawText = mContext.getText(
+                com.android.internal.R.string.battery_saver_description_with_learn_more);
+        final SpannableString message = new SpannableString(rawText);
+        final SpannableStringBuilder builder = new SpannableStringBuilder(message);
+
+        // Look for the "learn more" part of the string, and set a URL span on it.
+        // We use a customized URLSpan to add FLAG_RECEIVER_FOREGROUND to the intent, and
+        // also to close the dialog.
+        for (Annotation annotation : message.getSpans(0, message.length(), Annotation.class)) {
+            final String key = annotation.getValue();
+
+            if (!BATTERY_SAVER_DESCRIPTION_URL_KEY.equals(key)) {
+                continue;
+            }
+            final int start = message.getSpanStart(annotation);
+            final int end = message.getSpanEnd(annotation);
+
+            // Replace the "learn more" with a custom URL span, with
+            // - No underline.
+            // - When clicked, close the dialog and the notification shade.
+            final URLSpan urlSpan = new URLSpan(learnMoreUrl) {
+                @Override
+                public void updateDrawState(TextPaint ds) {
+                    super.updateDrawState(ds);
+                    ds.setUnderlineText(false);
+                }
+
+                @Override
+                public void onClick(View widget) {
+                    // Close the parent dialog.
+                    if (mSaverConfirmation != null) {
+                        mSaverConfirmation.dismiss();
+                    }
+                    // Also close the notification shade, if it's open.
+                    mContext.sendBroadcast(
+                            new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
+                            .setFlags(Intent.FLAG_RECEIVER_FOREGROUND));
+
+                    final Uri uri = Uri.parse(getURL());
+                    Context context = widget.getContext();
+                    Intent intent = new Intent(Intent.ACTION_VIEW, uri)
+                            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                    try {
+                        context.startActivity(intent);
+                    } catch (ActivityNotFoundException e) {
+                        Log.w(TAG, "Activity was not found for intent, " + intent.toString());
+                    }
+                }
+            };
+            builder.setSpan(urlSpan, start, end, message.getSpanFlags(urlSpan));
+        }
+        return builder;
+    }
+
     private void showAutoSaverEnabledConfirmation() {
         if (mSaverEnabledConfirmation != null) return;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index a44f9433..d8bf990 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -40,7 +40,7 @@
     private int mHeightOverride = -1;
     private QSPanel mQSPanel;
     private View mQSDetail;
-    private View mHeader;
+    private QuickStatusBarHeader mHeader;
     private float mQsExpansion;
     private QSCustomizer mQSCustomizer;
     private View mQSFooter;
@@ -178,7 +178,7 @@
         setMargins(mBackground);
         setMargins(mQSFooter);
         mQSPanel.setMargins(mSideMargins);
-        setMargins(mHeader);
+        mHeader.setMargins(mSideMargins);
     }
 
     private void setMargins(View view) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 7a24a60..3d326ae 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -41,6 +41,7 @@
 import android.view.View;
 import android.view.WindowInsets;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
@@ -592,4 +593,16 @@
     public static float getColorIntensity(@ColorInt int color) {
         return color == Color.WHITE ? 0 : 1;
     }
+
+    public void setMargins(int sideMargins) {
+        for (int i = 0; i < getChildCount(); i++) {
+            View v = getChildAt(i);
+            if (v == mSystemIconsView || v == mQuickQsStatusIcons || v == mHeaderQsPanel) {
+                continue;
+            }
+            RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
+            lp.leftMargin = sideMargins;
+            lp.rightMargin = sideMargins;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
index 5649f7f..22ad550 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
@@ -36,6 +36,7 @@
 
 /** View that represents a standard quick settings tile. **/
 public class QSTileView extends QSTileBaseView {
+    private static final int MAX_LABEL_LINES = 2;
     private static final boolean DUAL_TARGET_ALLOWED = false;
     private View mDivider;
     protected TextView mLabel;
@@ -98,9 +99,10 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 
-        // Remeasure view if the secondary label text will be cut off.
-        if (!TextUtils.isEmpty(mSecondLine.getText())
-                && mSecondLine.getLineHeight() > mSecondLine.getHeight()) {
+        // Remeasure view if the primary label requires more then 2 lines or the secondary label
+        // text will be cut off.
+        if (mLabel.getLineCount() > MAX_LABEL_LINES || !TextUtils.isEmpty(mSecondLine.getText())
+                        && mSecondLine.getLineHeight() > mSecondLine.getHeight()) {
             mLabel.setSingleLine();
             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index a25c466..cd00311 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -124,8 +124,9 @@
         final boolean transientEnabling = arg == ARG_SHOW_TRANSIENT_ENABLING;
         final boolean enabled = transientEnabling || mController.isBluetoothEnabled();
         final boolean connected = mController.isBluetoothConnected();
-        state.isTransient = transientEnabling || mController.isBluetoothConnecting()
-                || mController.getBluetoothState() == BluetoothAdapter.STATE_TURNING_ON;
+        final boolean connecting = mController.isBluetoothConnecting();
+        state.isTransient = transientEnabling || connecting ||
+                mController.getBluetoothState() == BluetoothAdapter.STATE_TURNING_ON;
         state.dualTarget = true;
         state.value = enabled;
         if (state.slash == null) {
@@ -134,7 +135,7 @@
         state.slash.isSlashed = !enabled;
         state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
         state.secondaryLabel = TextUtils.emptyIfNull(
-                getSecondaryLabel(enabled, connected, state.isTransient));
+                getSecondaryLabel(enabled, connecting, connected, state.isTransient));
         if (enabled) {
             if (connected) {
                 state.icon = new BluetoothConnectedTileIcon();
@@ -170,13 +171,17 @@
      * Returns the secondary label to use for the given bluetooth connection in the form of the
      * battery level or bluetooth profile name. If the bluetooth is disabled, there's no connected
      * devices, or we can't map the bluetooth class to a profile, this instead returns {@code null}.
-     *
      * @param enabled whether bluetooth is enabled
+     * @param connecting whether bluetooth is connecting to a device
      * @param connected whether there's a device connected via bluetooth
      * @param isTransient whether bluetooth is currently in a transient state turning on
      */
     @Nullable
-    private String getSecondaryLabel(boolean enabled, boolean connected, boolean isTransient) {
+    private String getSecondaryLabel(boolean enabled, boolean connecting, boolean connected,
+            boolean isTransient) {
+        if (connecting) {
+            return mContext.getString(R.string.quick_settings_connecting);
+        }
         if (isTransient) {
             return mContext.getString(R.string.quick_settings_bluetooth_secondary_label_transient);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index 1736f38..be0aa11 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -16,6 +16,10 @@
 
 package com.android.systemui.settings;
 
+import static com.android.settingslib.display.BrightnessUtils.GAMMA_SPACE_MAX;
+import static com.android.settingslib.display.BrightnessUtils.convertGammaToLinear;
+import static com.android.settingslib.display.BrightnessUtils.convertLinearToGamma;
+
 import android.animation.ValueAnimator;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -24,7 +28,6 @@
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Handler;
-import android.os.IPowerManager;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
@@ -36,7 +39,6 @@
 import android.service.vr.IVrManager;
 import android.service.vr.IVrStateCallbacks;
 import android.util.Log;
-import android.util.MathUtils;
 import android.widget.ImageView;
 
 import com.android.internal.logging.MetricsLogger;
@@ -50,15 +52,8 @@
     private static final String TAG = "StatusBar.BrightnessController";
     private static final boolean SHOW_AUTOMATIC_ICON = false;
 
-    private static final int SLIDER_MAX = 1023;
     private static final int SLIDER_ANIMATION_DURATION = 3000;
 
-    // Hybrid Log Gamma constant values
-    private static final float R = 0.5f;
-    private static final float A = 0.17883277f;
-    private static final float B = 0.28466892f;
-    private static final float C = 0.55991073f;
-
     private static final int MSG_UPDATE_ICON = 0;
     private static final int MSG_UPDATE_SLIDER = 1;
     private static final int MSG_SET_CHECKED = 2;
@@ -273,7 +268,7 @@
         mContext = context;
         mIcon = icon;
         mControl = control;
-        mControl.setMax(SLIDER_MAX);
+        mControl.setMax(GAMMA_SPACE_MAX);
         mBackgroundHandler = new Handler((Looper) Dependency.get(Dependency.BG_LOOPER));
         mUserTracker = new CurrentUserTracker(mContext) {
             @Override
@@ -481,76 +476,4 @@
         mSliderAnimator.start();
     }
 
-    /**
-     * A function for converting from the linear space that the setting works in to the
-     * gamma space that the slider works in.
-     *
-     * The gamma space effectively provides us a way to make linear changes to the slider that
-     * result in linear changes in perception. If we made changes to the slider in the linear space
-     * then we'd see an approximately logarithmic change in perception (c.f. Fechner's Law).
-     *
-     * Internally, this implements the Hybrid Log Gamma opto-electronic transfer function, which is
-     * a slight improvement to the typical gamma transfer function for displays whose max
-     * brightness exceeds the 120 nit reference point, but doesn't set a specific reference
-     * brightness like the PQ function does.
-     *
-     * Note that this transfer function is only valid if the display's backlight value is a linear
-     * control. If it's calibrated to be something non-linear, then a different transfer function
-     * should be used.
-     *
-     * @param val The brightness setting value.
-     * @param min The minimum acceptable value for the setting.
-     * @param max The maximum acceptable value for the setting.
-     *
-     * @return The corresponding slider value
-     */
-    private static final int convertLinearToGamma(int val, int min, int max) {
-        // For some reason, HLG normalizes to the range [0, 12] rather than [0, 1]
-        final float normalizedVal = MathUtils.norm(min, max, val) * 12;
-        final float ret;
-        if (normalizedVal <= 1f) {
-            ret = MathUtils.sqrt(normalizedVal) * R;
-        } else {
-            ret = A * MathUtils.log(normalizedVal - B) + C;
-        }
-
-        return Math.round(MathUtils.lerp(0, SLIDER_MAX, ret));
-    }
-
-    /**
-     * A function for converting from the gamma space that the slider works in to the
-     * linear space that the setting works in.
-     *
-     * The gamma space effectively provides us a way to make linear changes to the slider that
-     * result in linear changes in perception. If we made changes to the slider in the linear space
-     * then we'd see an approximately logarithmic change in perception (c.f. Fechner's Law).
-     *
-     * Internally, this implements the Hybrid Log Gamma electro-optical transfer function, which is
-     * a slight improvement to the typical gamma transfer function for displays whose max
-     * brightness exceeds the 120 nit reference point, but doesn't set a specific reference
-     * brightness like the PQ function does.
-     *
-     * Note that this transfer function is only valid if the display's backlight value is a linear
-     * control. If it's calibrated to be something non-linear, then a different transfer function
-     * should be used.
-     *
-     * @param val The slider value.
-     * @param min The minimum acceptable value for the setting.
-     * @param max The maximum acceptable value for the setting.
-     *
-     * @return The corresponding setting value.
-     */
-    private static final int convertGammaToLinear(int val, int min, int max) {
-        final float normalizedVal = MathUtils.norm(0, SLIDER_MAX, val);
-        final float ret;
-        if (normalizedVal <= R) {
-            ret = MathUtils.sq(normalizedVal/R);
-        } else {
-            ret = MathUtils.exp((normalizedVal - C) / A) + B;
-        }
-
-        // HLG is normalized to the range [0, 12], so we need to re-normalize to the range [0, 1]
-        // in order to derive the correct setting value.
-        return Math.round(MathUtils.lerp(min, max, ret / 12));
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 1149ad1..79fea9f 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -21,6 +21,8 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
 import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
+import static android.view.WindowManager.DOCKED_LEFT;
+import static android.view.WindowManager.DOCKED_RIGHT;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -364,14 +366,7 @@
         if (mStableInsets.isEmpty()) {
             SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
         }
-        int position = (int) (mState.mRatioPositionBeforeMinimized *
-                (isHorizontalDivision() ? mDisplayHeight : mDisplayWidth));
-        mSnapAlgorithm = null;
-        initializeSnapAlgorithm();
-
-        // Set the snap target before minimized but do not save until divider is attached and not
-        // minimized because it does not know its minimized state yet.
-        mSnapTargetBeforeMinimized = mSnapAlgorithm.calculateNonDismissingSnapTarget(position);
+        repositionSnapTargetBeforeMinimized();
     }
 
     public WindowManagerProxy getWindowManagerProxy() {
@@ -878,9 +873,36 @@
     }
 
     public void notifyDockSideChanged(int newDockSide) {
+        int oldDockSide = mDockSide;
         mDockSide = newDockSide;
         mMinimizedShadow.setDockSide(mDockSide);
         requestLayout();
+
+        // Update the snap position to the new docked side with correct insets
+        SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
+        mMinimizedSnapAlgorithm = null;
+        initializeSnapAlgorithm();
+
+        if (oldDockSide == DOCKED_LEFT && mDockSide == DOCKED_RIGHT
+                || oldDockSide == DOCKED_RIGHT && mDockSide == DOCKED_LEFT) {
+            repositionSnapTargetBeforeMinimized();
+        }
+
+        // Landscape to seascape rotation requires minimized to resize docked app correctly
+        if (mHomeStackResizable && mDockedStackMinimized) {
+            resizeStack(mMinimizedSnapAlgorithm.getMiddleTarget());
+        }
+    }
+
+    private void repositionSnapTargetBeforeMinimized() {
+        int position = (int) (mState.mRatioPositionBeforeMinimized *
+                (isHorizontalDivision() ? mDisplayHeight : mDisplayWidth));
+        mSnapAlgorithm = null;
+        initializeSnapAlgorithm();
+
+        // Set the snap target before minimized but do not save until divider is attached and not
+        // minimized because it does not know its minimized state yet.
+        mSnapTargetBeforeMinimized = mSnapAlgorithm.calculateNonDismissingSnapTarget(position);
     }
 
     private void updateDisplayInfo() {
@@ -962,6 +984,12 @@
         if (mHomeStackResizable && mIsInMinimizeInteraction) {
             calculateBoundsForPosition(mSnapTargetBeforeMinimized.position, mDockSide,
                     mDockedTaskRect);
+
+            // Move a right-docked-app to line up with the divider while dragging it
+            if (mDockSide == DOCKED_RIGHT) {
+                mDockedTaskRect.offset(Math.max(position, mStableInsets.left - mDividerSize)
+                        - mDockedTaskRect.left + mDividerSize, 0);
+            }
             calculateBoundsForPosition(mSnapTargetBeforeMinimized.position,
                     DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect);
             mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedTaskRect,
@@ -976,6 +1004,12 @@
                 calculateBoundsForPosition(isHorizontalDivision() ? mDisplayHeight : mDisplayWidth,
                         mDockSide, mDockedTaskRect);
             }
+
+            // Move a docked app if from the right in position with the divider up to insets
+            if (mDockSide == DOCKED_RIGHT) {
+                mDockedTaskRect.offset(Math.max(position,
+                        mStableInsets.left) - mDockedTaskRect.left, 0);
+            }
             calculateBoundsForPosition(taskPosition, DockedDividerUtils.invertDockSide(mDockSide),
                     mOtherTaskRect);
             mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, null,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedTextView.java
new file mode 100644
index 0000000..742005d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AlphaOptimizedTextView.java
@@ -0,0 +1,49 @@
+/*
+ * 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.systemui.statusbar;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+/**
+ * A TextView which does not have overlapping renderings commands and therefore does not need a
+ * layer when alpha is changed.
+ */
+public class AlphaOptimizedTextView extends TextView {
+    public AlphaOptimizedTextView(Context context) {
+        super(context);
+    }
+
+    public AlphaOptimizedTextView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public AlphaOptimizedTextView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public AlphaOptimizedTextView(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    public boolean hasOverlappingRendering() {
+        return false;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DndSuppressingNotificationsView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DndSuppressingNotificationsView.java
new file mode 100644
index 0000000..db3a02d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DndSuppressingNotificationsView.java
@@ -0,0 +1,91 @@
+/*
+ * 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.systemui.statusbar;
+
+import android.annotation.ColorInt;
+import android.annotation.DrawableRes;
+import android.annotation.IntegerRes;
+import android.annotation.StringRes;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Configuration;
+import android.graphics.drawable.Icon;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.stack.ExpandableViewState;
+import com.android.systemui.statusbar.stack.StackScrollState;
+
+public class DndSuppressingNotificationsView extends StackScrollerDecorView {
+
+    private TextView mText;
+    private @StringRes int mTextId = R.string.dnd_suppressing_shade_text;
+
+    public DndSuppressingNotificationsView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        mText.setText(mTextId);
+    }
+
+    @Override
+    protected View findContentView() {
+        return findViewById(R.id.hidden_container);
+    }
+
+    @Override
+    protected View findSecondaryView() {
+        return null;
+    }
+
+    public void setColor(@ColorInt int color) {
+        mText.setTextColor(color);
+    }
+
+    public void setOnContentClickListener(OnClickListener listener) {
+        mText.setOnClickListener(listener);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mText = findViewById(R.id.hidden_notifications);
+    }
+
+    @Override
+    public ExpandableViewState createNewViewState(StackScrollState stackScrollState) {
+        return new DndSuppressingViewState();
+    }
+
+    public class DndSuppressingViewState extends ExpandableViewState {
+        @Override
+        public void applyToView(View view) {
+            super.applyToView(view);
+            if (view instanceof DndSuppressingNotificationsView) {
+                DndSuppressingNotificationsView dndView = (DndSuppressingNotificationsView) view;
+                boolean visible = this.clipTopAmount <= mText.getPaddingTop() * 0.6f;
+                dndView.performVisibilityAnimation(visible && !dndView.willBeGone());
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 42c774e..3efeb6e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -76,6 +76,7 @@
 import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
 import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
 import com.android.systemui.statusbar.notification.HybridNotificationView;
+import com.android.systemui.statusbar.notification.NotificationCounters;
 import com.android.systemui.statusbar.notification.NotificationInflater;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.NotificationViewWrapper;
@@ -1252,6 +1253,8 @@
                 Dependency.get(NotificationBlockingHelperManager.class);
         boolean isBlockingHelperShown = manager.perhapsShowBlockingHelper(this, mMenuRow);
 
+        Dependency.get(MetricsLogger.class).count(NotificationCounters.NOTIFICATION_DISMISSED, 1);
+
         // Continue with dismiss since we don't want the blocking helper to be directly associated
         // with a certain notification.
         performDismiss(fromAccessibility);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index e527be1..5477468 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -81,7 +81,7 @@
 
     private SmartReplyConstants mSmartReplyConstants;
     private SmartReplyView mExpandedSmartReplyView;
-    private SmartReplyLogger mSmartReplyLogger;
+    private SmartReplyController mSmartReplyController;
 
     private NotificationViewWrapper mContractedWrapper;
     private NotificationViewWrapper mExpandedWrapper;
@@ -154,7 +154,7 @@
         super(context, attrs);
         mHybridGroupManager = new HybridGroupManager(getContext(), this);
         mSmartReplyConstants = Dependency.get(SmartReplyConstants.class);
-        mSmartReplyLogger = Dependency.get(SmartReplyLogger.class);
+        mSmartReplyController = Dependency.get(SmartReplyController.class);
         initView();
     }
 
@@ -1359,7 +1359,7 @@
                     applySmartReplyView(mExpandedChild, remoteInput, pendingIntent, entry);
             if (mExpandedSmartReplyView != null && remoteInput != null
                     && remoteInput.getChoices() != null && remoteInput.getChoices().length > 0) {
-                mSmartReplyLogger.smartRepliesAdded(entry, remoteInput.getChoices().length);
+                mSmartReplyController.smartRepliesAdded(entry, remoteInput.getChoices().length);
             }
         }
     }
@@ -1377,6 +1377,13 @@
             smartReplyContainer.setVisibility(View.GONE);
             return null;
         }
+        // If we are showing the spinner we don't want to add the buttons.
+        boolean showingSpinner = entry.notification.getNotification()
+                .extras.getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false);
+        if (showingSpinner) {
+            smartReplyContainer.setVisibility(View.GONE);
+            return null;
+        }
         SmartReplyView smartReplyView = null;
         if (smartReplyContainer.getChildCount() == 0) {
             smartReplyView = SmartReplyView.inflate(mContext, smartReplyContainer);
@@ -1389,7 +1396,7 @@
         }
         if (smartReplyView != null) {
             smartReplyView.setRepliesFromRemoteInput(remoteInput, pendingIntent,
-                    mSmartReplyLogger, entry);
+                    mSmartReplyController, entry, smartReplyContainer);
             smartReplyContainer.setVisibility(View.VISIBLE);
         }
         return smartReplyView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
index 3a79e70..7681530 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
@@ -474,37 +474,12 @@
         if (FORCE_REMOTE_INPUT_HISTORY
                 && shouldKeepForRemoteInput(entry)
                 && entry.row != null && !entry.row.isDismissed()) {
-            StatusBarNotification sbn = entry.notification;
-
-            Notification.Builder b = Notification.Builder
-                    .recoverBuilder(mContext, sbn.getNotification().clone());
-            CharSequence[] oldHistory = sbn.getNotification().extras
-                    .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
-            CharSequence[] newHistory;
-            if (oldHistory == null) {
-                newHistory = new CharSequence[1];
-            } else {
-                newHistory = new CharSequence[oldHistory.length + 1];
-                System.arraycopy(oldHistory, 0, newHistory, 1, oldHistory.length);
-            }
             CharSequence remoteInputText = entry.remoteInputText;
             if (TextUtils.isEmpty(remoteInputText)) {
                 remoteInputText = entry.remoteInputTextWhenReset;
             }
-            newHistory[0] = String.valueOf(remoteInputText);
-            b.setRemoteInputHistory(newHistory);
-
-            Notification newNotification = b.build();
-
-            // Undo any compatibility view inflation
-            newNotification.contentView = sbn.getNotification().contentView;
-            newNotification.bigContentView = sbn.getNotification().bigContentView;
-            newNotification.headsUpContentView = sbn.getNotification().headsUpContentView;
-
-            StatusBarNotification newSbn = new StatusBarNotification(sbn.getPackageName(),
-                    sbn.getOpPkg(),
-                    sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(),
-                    newNotification, sbn.getUser(), sbn.getOverrideGroupKey(), sbn.getPostTime());
+            StatusBarNotification newSbn = rebuildNotificationWithRemoteInput(entry,
+                    remoteInputText, false /* showSpinner */);
             boolean updated = false;
             entry.onRemoteInputInserted();
             try {
@@ -554,6 +529,39 @@
         mCallback.onNotificationRemoved(key, old);
     }
 
+    public StatusBarNotification rebuildNotificationWithRemoteInput(NotificationData.Entry entry,
+            CharSequence remoteInputText, boolean showSpinner) {
+        StatusBarNotification sbn = entry.notification;
+
+        Notification.Builder b = Notification.Builder
+                .recoverBuilder(mContext, sbn.getNotification().clone());
+        CharSequence[] oldHistory = sbn.getNotification().extras
+                .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
+        CharSequence[] newHistory;
+        if (oldHistory == null) {
+            newHistory = new CharSequence[1];
+        } else {
+            newHistory = new CharSequence[oldHistory.length + 1];
+            System.arraycopy(oldHistory, 0, newHistory, 1, oldHistory.length);
+        }
+        newHistory[0] = String.valueOf(remoteInputText);
+        b.setRemoteInputHistory(newHistory);
+        b.setShowRemoteInputSpinner(showSpinner);
+
+        Notification newNotification = b.build();
+
+        // Undo any compatibility view inflation
+        newNotification.contentView = sbn.getNotification().contentView;
+        newNotification.bigContentView = sbn.getNotification().bigContentView;
+        newNotification.headsUpContentView = sbn.getNotification().headsUpContentView;
+
+        StatusBarNotification newSbn = new StatusBarNotification(sbn.getPackageName(),
+                sbn.getOpPkg(),
+                sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(),
+                newNotification, sbn.getUser(), sbn.getOverrideGroupKey(), sbn.getPostTime());
+        return newSbn;
+    }
+
     private boolean shouldKeepForRemoteInput(NotificationData.Entry entry) {
         if (entry == null) {
             return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 65fb2da..a581049 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -30,6 +30,7 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.FrameLayout;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
@@ -270,7 +271,8 @@
 
 
     /** Animates out the guts view via either a fade or a circular reveal. */
-    private void animateClose(int x, int y, boolean shouldDoCircularReveal) {
+    @VisibleForTesting
+    void animateClose(int x, int y, boolean shouldDoCircularReveal) {
         if (shouldDoCircularReveal) {
             // Circular reveal originating at (x, y)
             if (x == -1 || y == -1) {
@@ -340,7 +342,8 @@
         }
     }
 
-    private void setExposed(boolean exposed, boolean needsFalsingProtection) {
+    @VisibleForTesting
+    void setExposed(boolean exposed, boolean needsFalsingProtection) {
         final boolean wasExposed = mExposed;
         mExposed = exposed;
         mNeedsFalsingProtection = needsFalsingProtection;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 6a1740c..ec49f43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -54,17 +54,20 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.notification.NotificationCounters;
 
 import java.util.List;
 
 /**
- * The guts of a notification revealed when performing a long press.
+ * The guts of a notification revealed when performing a long press. This also houses the blocking
+ * helper affordance that allows a user to keep/stop notifications after swiping one away.
  */
 public class NotificationInfo extends LinearLayout implements NotificationGuts.GutsContent {
     private static final String TAG = "InfoGuts";
 
     private INotificationManager mINotificationManager;
     private PackageManager mPm;
+    private MetricsLogger mMetricsLogger;
 
     private String mPackageName;
     private String mAppName;
@@ -84,17 +87,27 @@
     private OnAppSettingsClickListener mAppSettingsClickListener;
     private NotificationGuts mGutsContainer;
 
-    /** Whether this view is being shown as part of the blocking helper */
+    /** Whether this view is being shown as part of the blocking helper. */
     private boolean mIsForBlockingHelper;
     private boolean mNegativeUserSentiment;
 
-    private OnClickListener mOnKeepShowing = this::closeControls;
+    /** Counter tag that describes how the user exit or quit out of this view. */
+    private String mExitReasonCounter = NotificationCounters.BLOCKING_HELPER_DISMISSED;
+
+    private OnClickListener mOnKeepShowing = v -> {
+        mExitReasonCounter = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
+        closeControls(v);
+    };
 
     private OnClickListener mOnStopOrMinimizeNotifications = v -> {
+        mExitReasonCounter = NotificationCounters.BLOCKING_HELPER_STOP_NOTIFICATIONS;
         swapContent(false);
     };
 
     private OnClickListener mOnUndo = v -> {
+        // Reset exit counter that we'll log and record an undo event separately (not an exit event)
+        mExitReasonCounter = NotificationCounters.BLOCKING_HELPER_DISMISSED;
+        logBlockingHelperCounter(NotificationCounters.BLOCKING_HELPER_UNDO);
         swapContent(true);
     };
 
@@ -151,6 +164,7 @@
             boolean isUserSentimentNegative)
             throws RemoteException {
         mINotificationManager = iNotificationManager;
+        mMetricsLogger = Dependency.get(MetricsLogger.class);
         mPackageName = pkg;
         mNumUniqueChannelsInRow = numUniqueChannelsInRow;
         mSbn = sbn;
@@ -183,6 +197,8 @@
         bindHeader();
         bindPrompt();
         bindButtons();
+
+        logBlockingHelperCounter(NotificationCounters.BLOCKING_HELPER_SHOWN);
     }
 
     private void bindHeader() throws RemoteException {
@@ -235,6 +251,8 @@
             final int appUidF = mAppUid;
             settingsButton.setOnClickListener(
                     (View view) -> {
+                        logBlockingHelperCounter(
+                                NotificationCounters.BLOCKING_HELPER_NOTIF_SETTINGS);
                         mOnSettingsClickListener.onClick(view,
                                 mNumUniqueChannelsInRow > 1 ? null : mSingleNotificationChannel,
                                 appUidF);
@@ -269,6 +287,13 @@
         }
     }
 
+    @VisibleForTesting
+    void logBlockingHelperCounter(String counterTag) {
+        if (mIsForBlockingHelper) {
+            mMetricsLogger.count(counterTag, 1);
+        }
+    }
+
     private boolean hasImportanceChanged() {
         return mSingleNotificationChannel != null && mStartingUserImportance != mChosenImportance;
     }
@@ -437,25 +462,15 @@
      */
     @VisibleForTesting
     void closeControls(View v) {
-        if (mIsForBlockingHelper) {
-            NotificationBlockingHelperManager manager =
-                    Dependency.get(NotificationBlockingHelperManager.class);
-            manager.dismissCurrentBlockingHelper();
-
-            // Since this won't get a callback via gutsContainer.closeControls, save the new
-            // importance values immediately.
-            saveImportance();
-        } else {
-            int[] parentLoc = new int[2];
-            int[] targetLoc = new int[2];
-            mGutsContainer.getLocationOnScreen(parentLoc);
-            v.getLocationOnScreen(targetLoc);
-            final int centerX = v.getWidth() / 2;
-            final int centerY = v.getHeight() / 2;
-            final int x = targetLoc[0] - parentLoc[0] + centerX;
-            final int y = targetLoc[1] - parentLoc[1] + centerY;
-            mGutsContainer.closeControls(x, y, true /* save */, false /* force */);
-        }
+        int[] parentLoc = new int[2];
+        int[] targetLoc = new int[2];
+        mGutsContainer.getLocationOnScreen(parentLoc);
+        v.getLocationOnScreen(targetLoc);
+        final int centerX = v.getWidth() / 2;
+        final int centerY = v.getHeight() / 2;
+        final int x = targetLoc[0] - parentLoc[0] + centerX;
+        final int y = targetLoc[1] - parentLoc[1] + centerY;
+        mGutsContainer.closeControls(x, y, true /* save */, false /* force */);
     }
 
     @Override
@@ -480,6 +495,7 @@
         if (save) {
             saveImportance();
         }
+        logBlockingHelperCounter(mExitReasonCounter);
         return false;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index abc261e..f737a8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -172,27 +172,28 @@
                 }
             }
 
-            if (mediaNotification != null) {
-                mMediaNotificationKey = mediaNotification.notification.getKey();
-                if (DEBUG_MEDIA) {
-                    Log.v(TAG, "DEBUG_MEDIA: Found new media notification: key="
-                            + mMediaNotificationKey + " controller=" + mMediaController);
-                }
-            }
-
             if (controller != null && !sameSessions(mMediaController, controller)) {
                 // We have a new media session
-                clearCurrentMediaNotification();
+                clearCurrentMediaNotificationSession();
                 mMediaController = controller;
                 mMediaController.registerCallback(mMediaListener);
                 mMediaMetadata = mMediaController.getMetadata();
                 if (DEBUG_MEDIA) {
-                    Log.v(TAG, "DEBUG_MEDIA: insert listener, receive metadata: "
-                            + mMediaMetadata);
+                    Log.v(TAG, "DEBUG_MEDIA: insert listener, found new controller: "
+                            + mMediaController + ", receive metadata: " + mMediaMetadata);
                 }
 
                 metaDataChanged = true;
             }
+
+            if (mediaNotification != null
+                    && !mediaNotification.notification.getKey().equals(mMediaNotificationKey)) {
+                mMediaNotificationKey = mediaNotification.notification.getKey();
+                if (DEBUG_MEDIA) {
+                    Log.v(TAG, "DEBUG_MEDIA: Found new media notification: key="
+                            + mMediaNotificationKey);
+                }
+            }
         }
 
         if (metaDataChanged) {
@@ -203,15 +204,7 @@
 
     public void clearCurrentMediaNotification() {
         mMediaNotificationKey = null;
-        mMediaMetadata = null;
-        if (mMediaController != null) {
-            if (DEBUG_MEDIA) {
-                Log.v(TAG, "DEBUG_MEDIA: Disconnecting from old controller: "
-                        + mMediaController.getPackageName());
-            }
-            mMediaController.unregisterCallback(mMediaListener);
-        }
-        mMediaController = null;
+        clearCurrentMediaNotificationSession();
     }
 
     @Override
@@ -265,4 +258,16 @@
                 entry.getExpandedContentView()
                         .findViewById(com.android.internal.R.id.media_actions) != null;
     }
+
+    private void clearCurrentMediaNotificationSession() {
+        mMediaMetadata = null;
+        if (mMediaController != null) {
+            if (DEBUG_MEDIA) {
+                Log.v(TAG, "DEBUG_MEDIA: Disconnecting from old controller: "
+                        + mMediaController.getPackageName());
+            }
+            mMediaController.unregisterCallback(mMediaListener);
+        }
+        mMediaController = null;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 44136c5..d3caf03 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -407,13 +407,14 @@
         boolean needsContinuousClipping = ViewState.isAnimatingY(icon) && !mAmbientState.isDark();
         boolean isContinuousClipping = icon.getTag(TAG_CONTINUOUS_CLIPPING) != null;
         if (needsContinuousClipping && !isContinuousClipping) {
+            final ViewTreeObserver observer = icon.getViewTreeObserver();
             ViewTreeObserver.OnPreDrawListener predrawListener =
                     new ViewTreeObserver.OnPreDrawListener() {
                         @Override
                         public boolean onPreDraw() {
                             boolean animatingY = ViewState.isAnimatingY(icon);
-                            if (!animatingY || !icon.isAttachedToWindow()) {
-                                icon.getViewTreeObserver().removeOnPreDrawListener(this);
+                            if (!animatingY) {
+                                observer.removeOnPreDrawListener(this);
                                 icon.setTag(TAG_CONTINUOUS_CLIPPING, null);
                                 return true;
                             }
@@ -421,7 +422,20 @@
                             return true;
                         }
                     };
-            icon.getViewTreeObserver().addOnPreDrawListener(predrawListener);
+            observer.addOnPreDrawListener(predrawListener);
+            icon.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
+                @Override
+                public void onViewAttachedToWindow(View v) {
+                }
+
+                @Override
+                public void onViewDetachedFromWindow(View v) {
+                    if (v == icon) {
+                        observer.removeOnPreDrawListener(predrawListener);
+                        icon.setTag(TAG_CONTINUOUS_CLIPPING, null);
+                    }
+                }
+            });
             icon.setTag(TAG_CONTINUOUS_CLIPPING, predrawListener);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
similarity index 64%
rename from packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyLogger.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
index 75dd77d..67da68c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
@@ -15,24 +15,32 @@
  */
 package com.android.systemui.statusbar;
 
-import android.content.Context;
 import android.os.RemoteException;
-import android.os.ServiceManager;
+import android.service.notification.StatusBarNotification;
+
 import com.android.internal.statusbar.IStatusBarService;
+import com.android.systemui.Dependency;
+
 
 /**
- * Handles reporting when smart replies are added to a notification
+ * Handles when smart replies are added to a notification
  * and clicked upon.
  */
-public class SmartReplyLogger {
-    protected IStatusBarService mBarService;
+public class SmartReplyController {
+    private IStatusBarService mBarService;
+    private NotificationEntryManager mNotificationEntryManager;
 
-    public SmartReplyLogger(Context context) {
-        mBarService = IStatusBarService.Stub.asInterface(
-                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+    public SmartReplyController() {
+        mBarService = Dependency.get(IStatusBarService.class);
+        mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
     }
 
-    public void smartReplySent(NotificationData.Entry entry, int replyIndex) {
+    public void smartReplySent(NotificationData.Entry entry, int replyIndex, CharSequence reply) {
+        StatusBarNotification newSbn =
+                mNotificationEntryManager.rebuildNotificationWithRemoteInput(entry, reply,
+                        true /* showSpinner */);
+        mNotificationEntryManager.updateNotification(newSbn, null /* ranking */);
+
         try {
             mBarService.onNotificationSmartReplySent(entry.notification.getKey(),
                     replyIndex);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
index f4e45812..5748ec9b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
@@ -100,13 +100,13 @@
         }
 
         if (mState == null) {
-            mState = state;
+            mState = state.copy();
             initViewState();
             return;
         }
 
         if (!mState.equals(state)) {
-            updateState(state);
+            updateState(state.copy());
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
index 0e2714d..bf94c1f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
@@ -64,6 +64,7 @@
     private WifiIconState mState;
     private String mSlot;
     private float mDarkIntensity = 0;
+    private int mVisibleState = -1;
 
     private ContextThemeWrapper mDarkContext;
     private ContextThemeWrapper mLightContext;
@@ -73,6 +74,7 @@
         StatusBarWifiView v = (StatusBarWifiView) inflater.inflate(R.layout.status_bar_wifi_group, null);
         v.setSlot(slot);
         v.init();
+        v.setVisibleState(STATE_ICON);
         return v;
     }
 
@@ -123,6 +125,11 @@
 
     @Override
     public void setVisibleState(int state) {
+        if (state == mVisibleState) {
+            return;
+        }
+        mVisibleState = state;
+
         switch (state) {
             case STATE_ICON:
                 mWifiGroup.setVisibility(View.VISIBLE);
@@ -139,12 +146,6 @@
         }
     }
 
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        int width = MeasureSpec.getSize(widthMeasureSpec);
-    }
-
     private void init() {
         int dualToneLightTheme = Utils.getThemeAttr(mContext, R.attr.lightIconTheme);
         int dualToneDarkTheme = Utils.getThemeAttr(mContext, R.attr.darkIconTheme);
@@ -180,12 +181,12 @@
         }
 
         if (mState == null) {
-            mState = state;
+            mState = state.copy();
             initViewState();
         }
 
         if (!mState.equals(state)) {
-            updateState(state);
+            updateState(state.copy());
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
index 8160f90..20986ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
@@ -7,6 +7,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.view.Display;
+import android.view.View;
 
 import java.util.HashMap;
 import java.util.List;
@@ -73,36 +74,43 @@
      */
     public void taskChanged(List<ActivityManager.StackInfo> stackInfoList) {
         int displayId = getDisplayId();
+        ActivityManager.StackInfo validStackInfo = null;
         for (ActivityManager.StackInfo stackInfo :stackInfoList) {
-            // if the display id is known and does not match the stack we skip
-            if (displayId != -1 && displayId != stackInfo.displayId ||
-                    stackInfo.topActivity == null) {
-                continue;
-            }
-
-            if (mSelectedFacetButton != null) {
-                mSelectedFacetButton.setSelected(false);
-            }
-
-            String packageName = stackInfo.topActivity.getPackageName();
-            CarFacetButton facetButton = findFacetButtongByComponentName(stackInfo.topActivity);
-            if (facetButton == null) {
-                facetButton = mButtonsByPackage.get(packageName);
-            }
-
-            if (facetButton == null) {
-                String category = getPackageCategory(packageName);
-                if (category != null) {
-                    facetButton = mButtonsByCategory.get(category);
-                }
-            }
-
-            if (facetButton != null) {
-                facetButton.setSelected(true);
-                mSelectedFacetButton = facetButton;
-                return;
+            // If the display id is unknown or it matches the stack, it's valid for use
+            if ((displayId == -1 || displayId == stackInfo.displayId) &&
+                    stackInfo.topActivity != null) {
+                validStackInfo = stackInfo;
+                break;
             }
         }
+
+        if (validStackInfo == null) {
+            // No stack was found that was on the same display as the facet buttons thus return
+            return;
+        }
+
+        if (mSelectedFacetButton != null) {
+            mSelectedFacetButton.setSelected(false);
+        }
+
+        String packageName = validStackInfo.topActivity.getPackageName();
+        CarFacetButton facetButton = findFacetButtongByComponentName(validStackInfo.topActivity);
+        if (facetButton == null) {
+            facetButton = mButtonsByPackage.get(packageName);
+        }
+
+        if (facetButton == null) {
+            String category = getPackageCategory(packageName);
+            if (category != null) {
+                facetButton = mButtonsByCategory.get(category);
+            }
+        }
+
+        if (facetButton != null && facetButton.getVisibility() == View.VISIBLE) {
+            facetButton.setSelected(true);
+            mSelectedFacetButton = facetButton;
+        }
+
     }
 
     private int getDisplayId() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
index b2cef16..9ed0929 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
@@ -36,10 +36,11 @@
  * in a linear layout.
  */
 class CarNavigationBarView extends LinearLayout {
-    private LinearLayout mNavButtons;
+    private View mNavButtons;
     private AlphaOptimizedImageButton mNotificationsButton;
     private CarStatusBar mCarStatusBar;
     private Context mContext;
+    private View mLockScreenButtons;
 
     public CarNavigationBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -49,6 +50,7 @@
     @Override
     public void onFinishInflate() {
         mNavButtons = findViewById(R.id.nav_buttons);
+        mLockScreenButtons = findViewById(R.id.lock_screen_nav_buttons);
 
         mNotificationsButton = findViewById(R.id.notifications);
         if (mNotificationsButton != null) {
@@ -74,4 +76,28 @@
     protected void onNotificationsClick(View v) {
         mCarStatusBar.togglePanel();
     }
+
+    /**
+     * If there are buttons declared in the layout they will be shown and the normal
+     * Nav buttons will be hidden.
+     */
+    public void showKeyguardButtons() {
+        if (mLockScreenButtons == null) {
+            return;
+        }
+        mLockScreenButtons.setVisibility(View.VISIBLE);
+        mNavButtons.setVisibility(View.GONE);
+    }
+
+    /**
+     * If there are buttons declared in the layout they will be hidden and the normal
+     * Nav buttons will be shown.
+     */
+    public void hideKeyguardButtons() {
+        if (mLockScreenButtons == null) {
+            return;
+        }
+        mNavButtons.setVisibility(View.VISIBLE);
+        mLockScreenButtons.setVisibility(View.GONE);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 9c60f5c..83021ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -141,6 +141,52 @@
         buildNavBarContent();
     }
 
+    /**
+     * Allows for showing or hiding just the navigation bars. This is indented to be used when
+     * the full screen user selector is shown.
+     */
+     void setNavBarVisibility(@View.Visibility int visibility) {
+        if (mNavigationBarWindow != null) {
+            mNavigationBarWindow.setVisibility(visibility);
+        }
+        if (mLeftNavigationBarWindow != null) {
+            mLeftNavigationBarWindow.setVisibility(visibility);
+        }
+        if (mRightNavigationBarWindow != null) {
+            mRightNavigationBarWindow.setVisibility(visibility);
+        }
+    }
+
+
+    @Override
+    public boolean hideKeyguard() {
+        boolean result = super.hideKeyguard();
+        if (mNavigationBarView != null) {
+            mNavigationBarView.hideKeyguardButtons();
+        }
+        if (mLeftNavigationBarView != null) {
+            mLeftNavigationBarView.hideKeyguardButtons();
+        }
+        if (mRightNavigationBarView != null) {
+            mRightNavigationBarView.hideKeyguardButtons();
+        }
+        return result;
+    }
+
+
+    @Override
+    public void showKeyguard() {
+        super.showKeyguard();
+        if (mNavigationBarView != null) {
+            mNavigationBarView.showKeyguardButtons();
+        }
+        if (mLeftNavigationBarView != null) {
+            mLeftNavigationBarView.showKeyguardButtons();
+        }
+        if (mRightNavigationBarView != null) {
+            mRightNavigationBarView.showKeyguardButtons();
+        }
+    }
 
     @Override
     public void destroy() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
new file mode 100644
index 0000000..7a8d22b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
@@ -0,0 +1,31 @@
+package com.android.systemui.statusbar.car;
+
+import android.content.Context;
+import android.view.View;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+
+public class CarStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager {
+
+    protected boolean mShouldHideNavBar;
+
+    public CarStatusBarKeyguardViewManager(Context context,
+            ViewMediatorCallback callback,
+            LockPatternUtils lockPatternUtils) {
+        super(context, callback, lockPatternUtils);
+        mShouldHideNavBar =context.getResources()
+                .getBoolean(R.bool.config_hideNavWhenKeyguardBouncerShown);
+    }
+
+    @Override
+    protected void updateNavigationBarVisibility(boolean navBarVisible) {
+        if(!mShouldHideNavBar) {
+            return;
+        }
+        CarStatusBar statusBar = (CarStatusBar) mStatusBar;
+        statusBar.setNavBarVisibility(navBarVisible ? View.VISIBLE : View.GONE);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
index a950cd5..a54c778 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
@@ -207,7 +207,7 @@
 
                 // If the user selects Guest, start the guest session.
                 if (userRecord.mIsStartGuestSession) {
-                    mUserManagerHelper.switchToGuest(mGuestName);
+                    mUserManagerHelper.startNewGuestSession(mGuestName);
                     return;
                 }
 
@@ -241,8 +241,7 @@
 
         private Bitmap getUserRecordIcon(UserRecord userRecord) {
             if (userRecord.mIsStartGuestSession) {
-                return UserIcons.convertToBitmap(UserIcons.getDefaultUserIcon(
-                    mContext.getResources(), UserHandle.USER_NULL, false));
+                return mUserManagerHelper.getGuestDefaultIcon();
             }
 
             if (userRecord.mIsAddUser) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
new file mode 100644
index 0000000..8143c13
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 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.systemui.statusbar.car.hvac;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.R;
+
+/**
+ * Simple text display of HVAC properties, It is designed to show temperature and is configured in
+ * the XML.
+ * XML properties:
+ * hvacPropertyId - Example: CarHvacManager.ID_ZONED_TEMP_SETPOINT (16385)
+ * hvacAreaId - Example: VehicleSeat.SEAT_ROW_1_LEFT (1)
+ * hvacTempFormat - Example: "%.1f\u00B0" (1 decimal and the degree symbol)
+ *
+ * Note: It registers itself with {@link HvacController}
+ */
+public class TemperatureTextView extends TextView implements TemperatureView {
+
+    private final int mAreaId;
+    private final int mPropertyId;
+    private final String mTempFormat;
+
+    public TemperatureTextView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TemperatureView);
+        mAreaId = typedArray.getInt(R.styleable.TemperatureView_hvacAreaId,-1);
+        mPropertyId = typedArray.getInt(R.styleable.TemperatureView_hvacPropertyId, -1);
+        String format = typedArray.getString(R.styleable.TemperatureView_hvacTempFormat);
+        mTempFormat = (format == null) ? "%.1f\u00B0" : format;
+
+        // register with controller
+        HvacController hvacController = Dependency.get(HvacController.class);
+        hvacController.addHvacTextView(this);
+    }
+
+    /**
+     * Formats the float for display
+     * @param temp - The current temp or NaN
+     */
+    @Override
+    public void setTemp(float temp) {
+        if (Float.isNaN(temp)) {
+            setText("--");
+            return;
+        }
+        setText(String.format(mTempFormat, temp));
+    }
+
+    /**
+     * @return propertiyId  Example: CarHvacManager.ID_ZONED_TEMP_SETPOINT (16385)
+     */
+    @Override
+    public int getPropertyId() {
+        return mPropertyId;
+    }
+
+    /**
+     * @return hvac AreaId - Example: VehicleSeat.SEAT_ROW_1_LEFT (1)
+     */
+    @Override
+    public int getAreaId() {
+        return mAreaId;
+    }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureView.java
index 4049ec3..7651356 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureView.java
@@ -16,67 +16,25 @@
 
 package com.android.systemui.statusbar.car.hvac;
 
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.widget.TextView;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.R;
-
 /**
- * Simple text display of HVAC properties, It is designed to show temperature and is configured in
- * the XML.
- * XML properties:
- * hvacPropertyId - Example: CarHvacManager.ID_ZONED_TEMP_SETPOINT (16385)
- * hvacAreaId - Example: VehicleSeat.SEAT_ROW_1_LEFT (1)
- * hvacTempFormat - Example: "%.1f\u00B0" (1 decimal and the degree symbol)
- *
- * Note: It registers itself with {@link HvacController}
+ * Interface for Views that display temperature HVAC properties
  */
-public class TemperatureView extends TextView {
-
-    private final int mAreaId;
-    private final int mPropertyId;
-    private final String mTempFormat;
-
-    public TemperatureView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TemperatureView);
-        mAreaId = typedArray.getInt(R.styleable.TemperatureView_hvacAreaId,-1);
-        mPropertyId = typedArray.getInt(R.styleable.TemperatureView_hvacPropertyId, -1);
-        String format = typedArray.getString(R.styleable.TemperatureView_hvacTempFormat);
-        mTempFormat = (format == null) ? "%.1f\u00B0" : format;
-
-        // register with controller
-        HvacController hvacController = Dependency.get(HvacController.class);
-        hvacController.addHvacTextView(this);
-    }
-
+public interface TemperatureView {
     /**
      * Formats the float for display
+     *
      * @param temp - The current temp or NaN
      */
-    public void setTemp(float temp) {
-        if (Float.isNaN(temp)) {
-            setText("--");
-            return;
-        }
-        setText(String.format(mTempFormat, temp));
-    }
+    void setTemp(float temp);
+
 
     /**
      * @return propertiyId  Example: CarHvacManager.ID_ZONED_TEMP_SETPOINT (16385)
      */
-    public int getPropertyId() {
-        return mPropertyId;
-    }
+    int getPropertyId();
 
     /**
      * @return hvac AreaId - Example: VehicleSeat.SEAT_ROW_1_LEFT (1)
      */
-    public int getAreaId() {
-        return mAreaId;
-    }
+    int getAreaId();
 }
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index b8bce95..20ab64c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -123,83 +123,102 @@
                 IRemoteAnimationFinishedCallback iRemoteAnimationFinishedCallback)
                     throws RemoteException {
             mSourceNotification.post(() -> {
-                for (RemoteAnimationTarget app : remoteAnimationTargets) {
-                    if (app.mode == RemoteAnimationTarget.MODE_OPENING) {
-                        setExpandAnimationRunning(true);
-                        mInstantCollapsePanel = app.position.y == 0
-                                && app.sourceContainerBounds.height()
-                                        >= mNotificationPanel.getHeight();
-                        if (!mInstantCollapsePanel) {
-                            mNotificationPanel.collapseWithDuration(ANIMATION_DURATION);
+                RemoteAnimationTarget primary = getPrimaryRemoteAnimationTarget(
+                        remoteAnimationTargets);
+                if (primary == null) {
+                    setAnimationPending(false);
+                    invokeCallback(iRemoteAnimationFinishedCallback);
+                    return;
+                }
+
+                setExpandAnimationRunning(true);
+                mInstantCollapsePanel = primary.position.y == 0
+                        && primary.sourceContainerBounds.height()
+                                >= mNotificationPanel.getHeight();
+                if (!mInstantCollapsePanel) {
+                    mNotificationPanel.collapseWithDuration(ANIMATION_DURATION);
+                }
+                ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+                mParams.startPosition = mSourceNotification.getLocationOnScreen();
+                mParams.startTranslationZ = mSourceNotification.getTranslationZ();
+                mParams.startClipTopAmount = mSourceNotification.getClipTopAmount();
+                if (mSourceNotification.isChildInGroup()) {
+                    int parentClip = mSourceNotification
+                            .getNotificationParent().getClipTopAmount();
+                    mParams.parentStartClipTopAmount = parentClip;
+                    // We need to calculate how much the child is clipped by the parent
+                    // because children always have 0 clipTopAmount
+                    if (parentClip != 0) {
+                        float childClip = parentClip
+                                - mSourceNotification.getTranslationY();
+                        if (childClip > 0.0f) {
+                            mParams.startClipTopAmount = (int) Math.ceil(childClip);
                         }
-                        ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
-                        mParams.startPosition = mSourceNotification.getLocationOnScreen();
-                        mParams.startTranslationZ = mSourceNotification.getTranslationZ();
-                        mParams.startClipTopAmount = mSourceNotification.getClipTopAmount();
-                        if (mSourceNotification.isChildInGroup()) {
-                            int parentClip = mSourceNotification
-                                    .getNotificationParent().getClipTopAmount();
-                            mParams.parentStartClipTopAmount = parentClip;
-                            // We need to calculate how much the child is clipped by the parent
-                            // because children always have 0 clipTopAmount
-                            if (parentClip != 0) {
-                                float childClip = parentClip
-                                        - mSourceNotification.getTranslationY();
-                                if (childClip > 0.0f) {
-                                    mParams.startClipTopAmount = (int) Math.ceil(childClip);
-                                }
-                            }
-                        }
-                        int targetWidth = app.sourceContainerBounds.width();
-                        int notificationHeight = mSourceNotification.getActualHeight()
-                                - mSourceNotification.getClipBottomAmount();
-                        int notificationWidth = mSourceNotification.getWidth();
-                        anim.setDuration(ANIMATION_DURATION);
-                        anim.setInterpolator(Interpolators.LINEAR);
-                        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-                            @Override
-                            public void onAnimationUpdate(ValueAnimator animation) {
-                                mParams.linearProgress = animation.getAnimatedFraction();
-                                float progress
-                                        = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(
-                                                mParams.linearProgress);
-                                int newWidth = (int) MathUtils.lerp(notificationWidth,
-                                        targetWidth, progress);
-                                mParams.left = (int) ((targetWidth - newWidth) / 2.0f);
-                                mParams.right = mParams.left + newWidth;
-                                mParams.top = (int) MathUtils.lerp(mParams.startPosition[1],
-                                        app.position.y, progress);
-                                mParams.bottom = (int) MathUtils.lerp(mParams.startPosition[1]
-                                                + notificationHeight,
-                                        app.position.y + app.sourceContainerBounds.bottom,
-                                        progress);
-                                applyParamsToWindow(app);
-                                applyParamsToNotification(mParams);
-                                applyParamsToNotificationList(mParams);
-                            }
-                        });
-                        anim.addListener(new AnimatorListenerAdapter() {
-                            @Override
-                            public void onAnimationEnd(Animator animation) {
-                                setExpandAnimationRunning(false);
-                                if (mInstantCollapsePanel) {
-                                    mStatusBar.collapsePanel(false /* animate */);
-                                }
-                                try {
-                                    iRemoteAnimationFinishedCallback.onAnimationFinished();
-                                } catch (RemoteException e) {
-                                    e.printStackTrace();
-                                }
-                            }
-                        });
-                        anim.start();
-                        break;
                     }
                 }
+                int targetWidth = primary.sourceContainerBounds.width();
+                int notificationHeight = mSourceNotification.getActualHeight()
+                        - mSourceNotification.getClipBottomAmount();
+                int notificationWidth = mSourceNotification.getWidth();
+                anim.setDuration(ANIMATION_DURATION);
+                anim.setInterpolator(Interpolators.LINEAR);
+                anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                    @Override
+                    public void onAnimationUpdate(ValueAnimator animation) {
+                        mParams.linearProgress = animation.getAnimatedFraction();
+                        float progress
+                                = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(
+                                        mParams.linearProgress);
+                        int newWidth = (int) MathUtils.lerp(notificationWidth,
+                                targetWidth, progress);
+                        mParams.left = (int) ((targetWidth - newWidth) / 2.0f);
+                        mParams.right = mParams.left + newWidth;
+                        mParams.top = (int) MathUtils.lerp(mParams.startPosition[1],
+                                primary.position.y, progress);
+                        mParams.bottom = (int) MathUtils.lerp(mParams.startPosition[1]
+                                        + notificationHeight,
+                                primary.position.y + primary.sourceContainerBounds.bottom,
+                                progress);
+                        applyParamsToWindow(primary);
+                        applyParamsToNotification(mParams);
+                        applyParamsToNotificationList(mParams);
+                    }
+                });
+                anim.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        setExpandAnimationRunning(false);
+                        if (mInstantCollapsePanel) {
+                            mStatusBar.collapsePanel(false /* animate */);
+                        }
+                        invokeCallback(iRemoteAnimationFinishedCallback);
+                    }
+                });
+                anim.start();
                 setAnimationPending(false);
             });
         }
 
+        private void invokeCallback(IRemoteAnimationFinishedCallback callback) {
+            try {
+                callback.onAnimationFinished();
+            } catch (RemoteException e) {
+                e.printStackTrace();
+            }
+        }
+
+        private RemoteAnimationTarget getPrimaryRemoteAnimationTarget(
+                RemoteAnimationTarget[] remoteAnimationTargets) {
+            RemoteAnimationTarget primary = null;
+            for (RemoteAnimationTarget app : remoteAnimationTargets) {
+                if (app.mode == RemoteAnimationTarget.MODE_OPENING) {
+                    primary = app;
+                    break;
+                }
+            }
+            return primary;
+        }
+
         private void setExpandAnimationRunning(boolean running) {
             mNotificationPanel.setLaunchingNotification(running);
             mSourceNotification.setExpandAnimationRunning(running);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCounters.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCounters.java
new file mode 100644
index 0000000..9a12e8b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCounters.java
@@ -0,0 +1,44 @@
+/*
+ * 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.systemui.statusbar.notification;
+
+/**
+ * Constants for counter tags for Notification-related actions/views.
+ */
+public class NotificationCounters {
+    /** Counter tag for notification dismissal. */
+    public static final String NOTIFICATION_DISMISSED = "notification_dismissed";
+
+    /** Counter tag for when the blocking helper is shown to the user. */
+    public static final String BLOCKING_HELPER_SHOWN = "blocking_helper_shown";
+    /** Counter tag for when the blocking helper is dismissed via a miscellaneous interaction. */
+    public static final String BLOCKING_HELPER_DISMISSED = "blocking_helper_dismissed";
+    /** Counter tag for when the user hits 'stop notifications' in the blocking helper. */
+    public static final String BLOCKING_HELPER_STOP_NOTIFICATIONS =
+            "blocking_helper_stop_notifications";
+    /** Counter tag for when the user hits 'keep showing' in the blocking helper. */
+    public static final String BLOCKING_HELPER_KEEP_SHOWING =
+            "blocking_helper_keep_showing";
+    /**
+     * Counter tag for when the user hits undo in context of the blocking helper - this can happen
+     * multiple times per view.
+     */
+    public static final String BLOCKING_HELPER_UNDO = "blocking_helper_undo";
+    /** Counter tag for when the user hits the notification settings icon in the blocking helper. */
+    public static final String BLOCKING_HELPER_NOTIF_SETTINGS =
+            "blocking_helper_notif_settings";
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
index 5f7b638..c9dcc5c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -16,16 +16,25 @@
 
 package com.android.systemui.statusbar.notification;
 
+import android.app.PendingIntent;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.graphics.Color;
+import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.service.notification.StatusBarNotification;
+import android.util.ArraySet;
 import android.view.View;
+import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import com.android.internal.util.NotificationColorUtil;
 import com.android.internal.widget.NotificationActionListLayout;
+import com.android.systemui.Dependency;
+import com.android.systemui.UiOffloadThread;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.TransformableView;
@@ -43,12 +52,14 @@
     private TextView mTitle;
     private TextView mText;
     protected View mActionsContainer;
-    private View mReplyAction;
+    private ImageView mReplyAction;
     private Rect mTmpRect = new Rect();
 
     private int mContentHeight;
     private int mMinHeightHint;
     private NotificationActionListLayout mActions;
+    private ArraySet<PendingIntent> mCancelledPendingIntents = new ArraySet<>();
+    private UiOffloadThread mUiOffloadThread;
 
     protected NotificationTemplateViewWrapper(Context ctx, View view,
             ExpandableNotificationRow row) {
@@ -137,6 +148,98 @@
         mActionsContainer = mView.findViewById(com.android.internal.R.id.actions_container);
         mActions = mView.findViewById(com.android.internal.R.id.actions);
         mReplyAction = mView.findViewById(com.android.internal.R.id.reply_icon_action);
+        updatePendingIntentCancellations();
+    }
+
+    private void updatePendingIntentCancellations() {
+        if (mActions != null) {
+            int numActions = mActions.getChildCount();
+            for (int i = 0; i < numActions; i++) {
+                Button action = (Button) mActions.getChildAt(i);
+                performOnPendingIntentCancellation(action, () -> {
+                    if (action.isEnabled()) {
+                        action.setEnabled(false);
+                        // The visual appearance doesn't look disabled enough yet, let's add the
+                        // alpha as well. Since Alpha doesn't play nicely right now with the
+                        // transformation, we rather blend it manually with the background color.
+                        ColorStateList textColors = action.getTextColors();
+                        int[] colors = textColors.getColors();
+                        int[] newColors = new int[colors.length];
+                        float disabledAlpha = mView.getResources().getFloat(
+                                com.android.internal.R.dimen.notification_action_disabled_alpha);
+                        for (int j = 0; j < colors.length; j++) {
+                            int color = colors[j];
+                            color = blendColorWithBackground(color, disabledAlpha);
+                            newColors[j] = color;
+                        }
+                        ColorStateList newColorStateList = new ColorStateList(
+                                textColors.getStates(), newColors);
+                        action.setTextColor(newColorStateList);
+                    }
+                });
+            }
+        }
+        if (mReplyAction != null) {
+            performOnPendingIntentCancellation(mReplyAction, () -> {
+                if (mReplyAction != null && mReplyAction.isEnabled()) {
+                    mReplyAction.setEnabled(false);
+                    // The visual appearance doesn't look disabled enough yet, let's add the
+                    // alpha as well. Since Alpha doesn't play nicely right now with the
+                    // transformation, we rather blend it manually with the background color.
+                    Drawable drawable = mReplyAction.getDrawable().mutate();
+                    PorterDuffColorFilter colorFilter =
+                            (PorterDuffColorFilter) drawable.getColorFilter();
+                    float disabledAlpha = mView.getResources().getFloat(
+                            com.android.internal.R.dimen.notification_action_disabled_alpha);
+                    if (colorFilter != null) {
+                        int color = colorFilter.getColor();
+                        color = blendColorWithBackground(color, disabledAlpha);
+                        drawable.mutate().setColorFilter(color, colorFilter.getMode());
+                    } else {
+                        mReplyAction.setAlpha(disabledAlpha);
+                    }
+                }
+            });
+        }
+    }
+
+    private int blendColorWithBackground(int color, float alpha) {
+        // alpha doesn't go well for color filters, so let's blend it manually
+        return NotificationColorUtil.compositeColors(Color.argb((int) (alpha * 255),
+                Color.red(color), Color.green(color), Color.blue(color)), resolveBackgroundColor());
+    }
+
+    private void performOnPendingIntentCancellation(View view, Runnable cancellationRunnable) {
+        PendingIntent pendingIntent = (PendingIntent) view.getTag(
+                com.android.internal.R.id.pending_intent_tag);
+        if (pendingIntent == null) {
+            return;
+        }
+        if (mCancelledPendingIntents.contains(pendingIntent)) {
+            cancellationRunnable.run();
+        } else {
+            PendingIntent.CancelListener listener = (PendingIntent intent) -> {
+                mView.post(() -> {
+                    mCancelledPendingIntents.add(pendingIntent);
+                    cancellationRunnable.run();
+                });
+            };
+            if (mUiOffloadThread == null) {
+                mUiOffloadThread = Dependency.get(UiOffloadThread.class);
+            }
+            mUiOffloadThread.submit(() -> pendingIntent.registerCancelListener(listener));
+            view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+                @Override
+                public void onViewAttachedToWindow(View v) {
+                    mUiOffloadThread.submit(() -> pendingIntent.registerCancelListener(listener));
+                }
+
+                @Override
+                public void onViewDetachedFromWindow(View v) {
+                    mUiOffloadThread.submit(() -> pendingIntent.unregisterCancelListener(listener));
+                }
+            });
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
index 10ddff5..66fc934 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -175,6 +175,15 @@
         return mRow.isSummaryWithChildren() ? 0 : mBackgroundColor;
     }
 
+    protected int resolveBackgroundColor() {
+        int customBackgroundColor = getCustomBackgroundColor();
+        if (customBackgroundColor != 0) {
+            return customBackgroundColor;
+        }
+        return mView.getContext().getColor(
+                com.android.internal.R.color.notification_material_background_color);
+    }
+
     public void setLegacy(boolean legacy) {
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index d2d9c4c..85fac16 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -30,6 +30,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.doze.AlwaysOnDisplayPolicy;
+import com.android.systemui.doze.DozeScreenState;
 import com.android.systemui.tuner.TunerService;
 
 import java.io.PrintWriter;
@@ -153,7 +154,8 @@
      * @return duration in millis.
      */
     public long getWallpaperAodDuration() {
-        return mAlwaysOnPolicy.wallpaperVisibilityDuration;
+        return shouldControlScreenOff() ? DozeScreenState.ENTER_DOZE_HIDE_WALLPAPER_DELAY
+                : mAlwaysOnPolicy.wallpaperVisibilityDuration;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 264f574..4b66ee5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -55,6 +55,7 @@
     private final UnlockMethodCache mUnlockMethodCache;
     private AccessibilityController mAccessibilityController;
     private boolean mHasFingerPrintIcon;
+    private boolean mHasFaceUnlockIcon;
     private int mDensity;
 
     private final Runnable mDrawOffTimeout = () -> update(true /* forceUpdate */);
@@ -130,6 +131,7 @@
         }
         int state = getState();
         boolean anyFingerprintIcon = state == STATE_FINGERPRINT || state == STATE_FINGERPRINT_ERROR;
+        mHasFaceUnlockIcon = state == STATE_FACE_UNLOCK;
         boolean useAdditionalPadding = anyFingerprintIcon;
         boolean trustHidden = anyFingerprintIcon;
         if (state != mLastState || mDeviceInteractive != mLastDeviceInteractive
@@ -179,6 +181,11 @@
             setRestingAlpha(
                     anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
             setImageDrawable(icon, false);
+            if (mHasFaceUnlockIcon) {
+                announceForAccessibility(getContext().getString(
+                    R.string.accessibility_scanning_face));
+            }
+
             mHasFingerPrintIcon = anyFingerprintIcon;
             if (animation != null && isAnim) {
                 animation.forceAnimationOnUI();
@@ -228,6 +235,11 @@
             info.addAction(unlock);
             info.setHintText(getContext().getString(
                     R.string.accessibility_waiting_for_fingerprint));
+        } else if (mHasFaceUnlockIcon){
+            //Avoid 'button' to be spoken for scanning face
+            info.setClassName(LockIcon.class.getName());
+            info.setContentDescription(getContext().getString(
+                R.string.accessibility_scanning_face));
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index f6ec493..c4570db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -281,6 +281,7 @@
 
         IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
         filter.addAction(Intent.ACTION_SCREEN_ON);
+        filter.addAction(Intent.ACTION_USER_SWITCHED);
         getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
         notifyNavigationBarScreenOn();
         mOverviewProxyService.addCallback(mOverviewProxyListener);
@@ -521,7 +522,7 @@
 
         // Clear any pending suggestion flag as it has either been nullified or is being shown
         mPendingRotationSuggestion = false;
-        getView().removeCallbacks(mCancelPendingRotationProposal);
+        if (getView() != null) getView().removeCallbacks(mCancelPendingRotationProposal);
 
         // Handle the visibility change and animation
         if (visible) { // Appear and change (cannot force)
@@ -1084,6 +1085,10 @@
                     || Intent.ACTION_SCREEN_ON.equals(action)) {
                 notifyNavigationBarScreenOn();
             }
+            if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+                // The accessibility settings may be different for the new user
+                updateAccessibilityServicesState(mAccessibilityManager);
+            };
         }
     };
 
@@ -1141,6 +1146,7 @@
         private final Runnable mRipple = new Runnable() {
             @Override
             public void run() { // Cause the ripple to fire via false presses
+                if (!mRoot.isAttachedToWindow()) return;
                 mRoot.setPressed(true);
                 mRoot.setPressed(false);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index a0a97c5..8bb73da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -199,6 +199,7 @@
     private ValueAnimator mQsSizeChangeAnimator;
 
     private boolean mShowEmptyShadeView;
+    private boolean mShowDndView;
 
     private boolean mQsScrimEnabled = true;
     private boolean mLastAnnouncementWasQuickSettings;
@@ -392,6 +393,8 @@
         if (mQs != null) {
             mQsMinExpansionHeight = mKeyguardShowing ? 0 : mQs.getQsMinExpansionHeight();
             mQsMaxExpansionHeight = mQs.getDesiredHeight();
+            mNotificationStackScroller.setMaxTopPadding(
+                    mQsMaxExpansionHeight + mQsNotificationTopPadding);
         }
         positionClockAndNotifications();
         if (mQsExpanded && mQsFullyExpanded) {
@@ -588,6 +591,19 @@
         mNotificationStackScroller.resetScrollPosition();
     }
 
+    @Override
+    public void collapse(boolean delayed, float speedUpFactor) {
+        if (!canPanelBeCollapsed()) {
+            return;
+        }
+
+        if (mQsExpanded) {
+            mQsExpandImmediate = true;
+            mNotificationStackScroller.setShouldShowShelfOnly(true);
+        }
+        super.collapse(delayed, speedUpFactor);
+    }
+
     public void closeQs() {
         cancelQsAnimation();
         setQsExpansion(mQsMinExpansionHeight);
@@ -615,6 +631,7 @@
     public void expandWithQs() {
         if (mQsExpansionEnabled) {
             mQsExpandImmediate = true;
+            mNotificationStackScroller.setShouldShowShelfOnly(true);
         }
         expand(true /* animate */);
     }
@@ -878,6 +895,7 @@
                 && event.getY(event.getActionIndex()) < mStatusBarMinHeight) {
             MetricsLogger.count(mContext, COUNTER_PANEL_OPEN_QS, 1);
             mQsExpandImmediate = true;
+            mNotificationStackScroller.setShouldShowShelfOnly(true);
             requestPanelHeightUpdate();
 
             // Normally, we start listening when the panel is expanded, but here we need to start
@@ -1321,7 +1339,9 @@
 
     protected void updateQsExpansion() {
         if (mQs == null) return;
-        mQs.setQsExpansion(getQsExpansionFraction(), getHeaderTranslation());
+        float qsExpansionFraction = getQsExpansionFraction();
+        mQs.setQsExpansion(qsExpansionFraction, getHeaderTranslation());
+        mNotificationStackScroller.setQsExpansionFraction(qsExpansionFraction);
     }
 
     private String determineAccessibilityPaneTitle() {
@@ -1357,7 +1377,6 @@
         } else if (mQsSizeChangeAnimator != null) {
             return (int) mQsSizeChangeAnimator.getAnimatedValue();
         } else if (mKeyguardShowing) {
-
             // We can only do the smoother transition on Keyguard when we also are not collapsing
             // from a scrolled quick settings.
             return interpolate(getQsExpansionFraction(),
@@ -1527,7 +1546,6 @@
                 // On Keyguard, interpolate the QS expansion linearly to the panel expansion
                 t = expandedHeight / (getMaxPanelHeight());
             } else {
-
                 // In Shade, interpolate linearly such that QS is closed whenever panel height is
                 // minimum QS expansion + minStackHeight
                 float panelHeightQsCollapsed = mNotificationStackScroller.getIntrinsicPadding()
@@ -1582,8 +1600,8 @@
         // When only empty shade view is visible in QS collapsed state, simulate that we would have
         // it in expanded QS state as well so we don't run into troubles when fading the view in/out
         // and expanding/collapsing the whole panel from/to quick settings.
-        if (mNotificationStackScroller.getNotGoneChildCount() == 0
-                && mShowEmptyShadeView) {
+        if ((mNotificationStackScroller.getNotGoneChildCount() == 0
+                && mShowEmptyShadeView) || mShowDndView) {
             notificationHeight = mNotificationStackScroller.getEmptyShadeViewHeight();
         }
         int maxQsHeight = mQsMaxExpansionHeight;
@@ -1776,6 +1794,7 @@
             setListening(true);
         }
         mQsExpandImmediate = false;
+        mNotificationStackScroller.setShouldShowShelfOnly(false);
         mTwoFingerQsExpandPossible = false;
         mIsExpansionFromHeadsUp = false;
         notifyListenersTrackingHeadsUp(null);
@@ -1827,6 +1846,7 @@
         super.onTrackingStarted();
         if (mQsFullyExpanded) {
             mQsExpandImmediate = true;
+            mNotificationStackScroller.setShouldShowShelfOnly(true);
         }
         if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
                 || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
@@ -1866,7 +1886,7 @@
         if (view == null && mQsExpanded) {
             return;
         }
-        if (needsAnimation) {
+        if (needsAnimation && mDarkAmount == 0) {
             mAnimateNextPositionUpdate = true;
         }
         ExpandableView firstChildNotGone = mNotificationStackScroller.getFirstChildNotGone();
@@ -1894,6 +1914,8 @@
         if (mAccessibilityManager.isEnabled()) {
             setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
         }
+        mNotificationStackScroller.setMaxTopPadding(
+                mQsMaxExpansionHeight + mQsNotificationTopPadding);
     }
 
     @Override
@@ -2222,13 +2244,17 @@
         return mDozing;
     }
 
+    public void showDndView(boolean dndViewVisible) {
+        mShowDndView = dndViewVisible;
+        mNotificationStackScroller.updateDndView(mShowDndView && !mQsExpanded);
+    }
+
     public void showEmptyShadeView(boolean emptyShadeViewVisible) {
         mShowEmptyShadeView = emptyShadeViewVisible;
         updateEmptyShadeView();
     }
 
     private void updateEmptyShadeView() {
-
         // Hide "No notifications" in QS.
         mNotificationStackScroller.updateEmptyShadeView(mShowEmptyShadeView && !mQsExpanded);
     }
@@ -2652,10 +2678,13 @@
 
     public void setPulsing(boolean pulsing) {
         mPulsing = pulsing;
-        mKeyguardStatusView.setPulsing(pulsing);
-        positionClockAndNotifications();
-        mNotificationStackScroller.setPulsing(pulsing, mKeyguardStatusView.getLocationOnScreen()[1]
-                + mKeyguardStatusView.getClockBottom());
+        final boolean canAnimatePulse =
+                !DozeParameters.getInstance(mContext).getDisplayNeedsBlanking();
+        if (canAnimatePulse) {
+            mAnimateNextPositionUpdate = true;
+        }
+        mNotificationStackScroller.setPulsing(pulsing, canAnimatePulse);
+        mKeyguardStatusView.setPulsing(pulsing, canAnimatePulse);
     }
 
     public void setAmbientIndicationBottomPadding(int ambientIndicationBottomPadding) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index 762fb05..5ae8529 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -34,7 +34,6 @@
 import android.util.Slog;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewConfiguration;
 import android.view.WindowManagerGlobal;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
@@ -45,16 +44,13 @@
 import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.utilities.Utilities;
+import com.android.systemui.shared.system.NavigationBarCompat;
 
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
 import static com.android.systemui.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
 import static com.android.systemui.OverviewProxyService.TAG_OPS;
 import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
-import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_SCRUB_DRAG_SLOP_PX;
-import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_SCRUB_TOUCH_SLOP_PX;
-import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_STEP_DRAG_SLOP_PX;
-import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_STEP_TOUCH_SLOP_PX;
 
 /**
  * Class to detect gestures on the navigation bar and implement quick scrub.
@@ -215,17 +211,23 @@
                 int pos, touchDown, offset, trackSize;
 
                 if (mIsVertical) {
-                    exceededScrubTouchSlop = yDiff > QUICK_SCRUB_TOUCH_SLOP_PX && yDiff > xDiff;
-                    exceededSwipeUpTouchSlop = xDiff > QUICK_STEP_TOUCH_SLOP_PX && xDiff > yDiff;
-                    exceededScrubDragSlop = yDiff > QUICK_SCRUB_DRAG_SLOP_PX && yDiff > xDiff;
+                    exceededScrubTouchSlop =
+                            yDiff > NavigationBarCompat.getQuickScrubTouchSlopPx() && yDiff > xDiff;
+                    exceededSwipeUpTouchSlop =
+                            xDiff > NavigationBarCompat.getQuickStepTouchSlopPx() && xDiff > yDiff;
+                    exceededScrubDragSlop =
+                            yDiff > NavigationBarCompat.getQuickScrubDragSlopPx() && yDiff > xDiff;
                     pos = y;
                     touchDown = mTouchDownY;
                     offset = pos - mTrackRect.top;
                     trackSize = mTrackRect.height();
                 } else {
-                    exceededScrubTouchSlop = xDiff > QUICK_SCRUB_TOUCH_SLOP_PX && xDiff > yDiff;
-                    exceededSwipeUpTouchSlop = yDiff > QUICK_STEP_TOUCH_SLOP_PX && yDiff > xDiff;
-                    exceededScrubDragSlop = xDiff > QUICK_SCRUB_DRAG_SLOP_PX && xDiff > yDiff;
+                    exceededScrubTouchSlop =
+                            xDiff > NavigationBarCompat.getQuickScrubTouchSlopPx() && xDiff > yDiff;
+                    exceededSwipeUpTouchSlop =
+                            yDiff > NavigationBarCompat.getQuickStepTouchSlopPx() && yDiff > xDiff;
+                    exceededScrubDragSlop =
+                            xDiff > NavigationBarCompat.getQuickScrubDragSlopPx() && xDiff > yDiff;
                     pos = x;
                     touchDown = mTouchDownX;
                     offset = pos - mTrackRect.left;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 1d64088..57a3556 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -20,10 +20,13 @@
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 import static android.app.StatusBarManager.windowStateToString;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
+import static android.provider.Settings.Global.ZEN_MODE_OFF;
 
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
+import static com.android.systemui.shared.system.WindowManagerWrapper.NAV_BAR_POS_LEFT;
+import static com.android.systemui.shared.system.WindowManagerWrapper.NAV_BAR_POS_INVALID;
 import static com.android.systemui.statusbar.NotificationLockscreenUserManager
         .NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION;
 import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
@@ -166,6 +169,7 @@
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.VolumeDialogController;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
 import com.android.systemui.qs.QSFragment;
@@ -178,6 +182,7 @@
 import com.android.systemui.recents.events.activity.AppTransitionFinishedEvent;
 import com.android.systemui.recents.events.activity.UndockingTaskEvent;
 import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.shared.system.WindowManagerWrapper;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.stackdivider.WindowManagerProxy;
 import com.android.systemui.statusbar.ActivatableNotificationView;
@@ -185,6 +190,7 @@
 import com.android.systemui.statusbar.BackDropView;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CrossFadeHelper;
+import com.android.systemui.statusbar.DndSuppressingNotificationsView;
 import com.android.systemui.statusbar.DragDownHelper;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -207,14 +213,12 @@
 import com.android.systemui.statusbar.NotificationViewHierarchyManager;
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.ScrimView;
-import com.android.systemui.statusbar.SignalClusterView;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.notification.AboveShelfObserver;
 import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
-import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
@@ -412,7 +416,7 @@
     protected NotificationViewHierarchyManager mViewHierarchyManager;
     protected AppOpsListener mAppOpsListener;
     protected KeyguardViewMediator mKeyguardViewMediator;
-    private ZenModeController mZenController;
+    protected ZenModeController mZenController;
 
     /**
      * Helper that is responsible for showing the right toast when a disallowed activity operation
@@ -877,6 +881,7 @@
         mVisualStabilityManager.setVisibilityLocationProvider(mStackScroller);
 
         inflateEmptyShadeView();
+        inflateDndView();
         inflateFooterView();
 
         mBackdrop = mStatusBarWindow.findViewById(R.id.backdrop);
@@ -1144,6 +1149,7 @@
     protected void reevaluateStyles() {
         inflateFooterView();
         updateFooter();
+        inflateDndView();
         inflateEmptyShadeView();
         updateEmptyShadeView();
     }
@@ -1165,6 +1171,19 @@
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
     }
 
+    private void inflateDndView() {
+        if (mStackScroller == null) {
+            return;
+        }
+        mDndView = (DndSuppressingNotificationsView) LayoutInflater.from(mContext).inflate(
+                R.layout.status_bar_dnd_suppressing_notifications, mStackScroller, false);
+        mDndView.setOnContentClickListener(v -> {
+            Intent intent = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
+            startActivity(intent, true, true, Intent.FLAG_ACTIVITY_SINGLE_TOP);
+        });
+        mStackScroller.setDndView(mDndView);
+    }
+
     private void inflateFooterView() {
         if (mStackScroller == null) {
             return;
@@ -1339,8 +1358,15 @@
         }
         int dockSide = WindowManagerProxy.getInstance().getDockSide();
         if (dockSide == WindowManager.DOCKED_INVALID) {
-            return mRecents.splitPrimaryTask(NavigationBarGestureHelper.DRAG_MODE_NONE,
-                    ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null, metricsDockAction);
+            final int navbarPos = WindowManagerWrapper.getInstance().getNavBarPosition();
+            if (navbarPos == NAV_BAR_POS_INVALID) {
+                return false;
+            }
+            int createMode = navbarPos == NAV_BAR_POS_LEFT
+                    ? ActivityManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT
+                    : ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
+            return mRecents.splitPrimaryTask(NavigationBarGestureHelper.DRAG_MODE_NONE, createMode,
+                    null, metricsDockAction);
         } else {
             Divider divider = getComponent(Divider.class);
             if (divider != null && divider.isMinimized() && !divider.isHomeStackResizable()) {
@@ -1452,9 +1478,11 @@
     @VisibleForTesting
     protected void updateFooter() {
         boolean showFooterView = mState != StatusBarState.KEYGUARD
+                && !areNotificationsHidden()
                 && mEntryManager.getNotificationData().getActiveNotifications().size() != 0
                 && !mRemoteInputManager.getController().isRemoteInputActive();
         boolean showDismissView = mClearAllEnabled && mState != StatusBarState.KEYGUARD
+                && !areNotificationsHidden()
                 && hasActiveClearableNotifications();
 
         mStackScroller.updateFooterView(showFooterView, showDismissView);
@@ -1477,10 +1505,13 @@
         return false;
     }
 
-    private void updateEmptyShadeView() {
-        boolean showEmptyShadeView =
-                mState != StatusBarState.KEYGUARD &&
-                        mEntryManager.getNotificationData().getActiveNotifications().size() == 0;
+    @VisibleForTesting
+    protected void updateEmptyShadeView() {
+        boolean showDndView = mState != StatusBarState.KEYGUARD && areNotificationsHidden();
+        boolean showEmptyShadeView = !showDndView
+                && mState != StatusBarState.KEYGUARD
+                && mEntryManager.getNotificationData().getActiveNotifications().size() == 0;
+        mNotificationPanel.showDndView(showDndView);
         mNotificationPanel.showEmptyShadeView(showEmptyShadeView);
     }
 
@@ -1896,6 +1927,13 @@
             }
         }
 
+        if (!panelsEnabled()) {
+            if (DEBUG) {
+                Log.d(TAG, "No peeking: disabled panel : " + sbn.getKey());
+            }
+            return false;
+        }
+
         if (sbn.getNotification().fullScreenIntent != null) {
             if (mAccessibilityManager.isTouchExplorationEnabled()) {
                 if (DEBUG) Log.d(TAG, "No peeking: accessible fullscreen: " + sbn.getKey());
@@ -4973,6 +5011,7 @@
     protected NotificationShelf mNotificationShelf;
     protected FooterView mFooterView;
     protected EmptyShadeView mEmptyShadeView;
+    protected DndSuppressingNotificationsView mDndView;
 
     protected AssistManager mAssistManager;
 
@@ -5457,6 +5496,11 @@
                     mStackScroller.getChildCount() - offsetFromEnd++);
         }
 
+        if (mDndView != null) {
+            mStackScroller.changeViewPosition(mDndView,
+                    mStackScroller.getChildCount() - offsetFromEnd++);
+        }
+
         mStackScroller.changeViewPosition(mEmptyShadeView,
                 mStackScroller.getChildCount() - offsetFromEnd++);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index b4e7575..24a5896 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -88,7 +88,7 @@
         List<Slot> allSlots = getSlots();
         for (int i = 0; i < allSlots.size(); i++) {
             Slot slot = allSlots.get(i);
-            List<StatusBarIconHolder> holders = slot.getHolderList();
+            List<StatusBarIconHolder> holders = slot.getHolderListInViewOrder();
             boolean blocked = mIconBlacklist.contains(slot.getName());
 
             for (StatusBarIconHolder holder : holders) {
@@ -121,7 +121,7 @@
         // Remove all the icons.
         for (int i = currentSlots.size() - 1; i >= 0; i--) {
             Slot s = currentSlots.get(i);
-            slotsToReAdd.put(s, s.getHolderList());
+            slotsToReAdd.put(s, s.getHolderListInViewOrder());
             removeAllIconsForSlot(s.getName());
         }
 
@@ -281,7 +281,7 @@
         mIconLogger.onIconHidden(slotName);
 
         int slotIndex = getSlotIndex(slotName);
-        List<StatusBarIconHolder> iconsToRemove = slot.getHolderList();
+        List<StatusBarIconHolder> iconsToRemove = slot.getHolderListInViewOrder();
         for (StatusBarIconHolder holder : iconsToRemove) {
             int viewIndex = getViewIndex(slotIndex, holder.getTag());
             slot.removeForTag(holder.getTag());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java
index e854dd0..c4ff85f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java
@@ -110,6 +110,10 @@
     }
 
     public void setVisible(boolean visible) {
+        if (isVisible() == visible) {
+            return;
+        }
+
         switch (mType) {
             case TYPE_ICON:
                 mIcon.visible = visible;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
index c773170..b7e1cfb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
@@ -211,7 +211,7 @@
         }
 
         /**
-         * View index is backwards from regular index
+         * View index is inverted from regular index, because they are laid out back-to-front
          * @param tag the tag of the holder being viewed
          * @return (1 + mSubSlots.size() - indexOfTag)
          */
@@ -228,14 +228,22 @@
             return subSlots - getIndexForTag(tag) - 1;
         }
 
-        public List<StatusBarIconHolder> getHolderList() {
+        /**
+         * Build a list of the {@link StatusBarIconHolder}s in the same order they appear in their
+         * view group. This provides a safe list that can be iterated and inserted into its group.
+         *
+         * @return all holders contained here, in view order
+         */
+        public List<StatusBarIconHolder> getHolderListInViewOrder() {
             ArrayList<StatusBarIconHolder> holders = new ArrayList<>();
-            if (mHolder != null) {
-                holders.add(mHolder);
+            if (mSubSlots != null) {
+                for (int i = mSubSlots.size() - 1; i >= 0; i--) {
+                    holders.add(mSubSlots.get(i));
+                }
             }
 
-            if (mSubSlots != null) {
-                holders.addAll(mSubSlots);
+            if (mHolder != null) {
+                holders.add(mHolder);
             }
 
             return holders;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index e63a2e5..b517d11 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -586,20 +586,7 @@
         boolean navBarVisible = isNavBarVisible();
         boolean lastNavBarVisible = getLastNavBarVisible();
         if (navBarVisible != lastNavBarVisible || mFirstUpdate) {
-            if (mStatusBar.getNavigationBarView() != null) {
-                if (navBarVisible) {
-                    long delay = getNavBarShowDelay();
-                    if (delay == 0) {
-                        mMakeNavigationBarVisibleRunnable.run();
-                    } else {
-                        mContainer.postOnAnimationDelayed(mMakeNavigationBarVisibleRunnable,
-                                delay);
-                    }
-                } else {
-                    mContainer.removeCallbacks(mMakeNavigationBarVisibleRunnable);
-                    mStatusBar.getNavigationBarView().getRootView().setVisibility(View.GONE);
-                }
-            }
+            updateNavigationBarVisibility(navBarVisible);
         }
 
         if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
@@ -626,6 +613,23 @@
         mStatusBar.onKeyguardViewManagerStatesUpdated();
     }
 
+    protected void updateNavigationBarVisibility(boolean navBarVisible) {
+        if (mStatusBar.getNavigationBarView() != null) {
+            if (navBarVisible) {
+                long delay = getNavBarShowDelay();
+                if (delay == 0) {
+                    mMakeNavigationBarVisibleRunnable.run();
+                } else {
+                    mContainer.postOnAnimationDelayed(mMakeNavigationBarVisibleRunnable,
+                            delay);
+                }
+            } else {
+                mContainer.removeCallbacks(mMakeNavigationBarVisibleRunnable);
+                mStatusBar.getNavigationBarView().getRootView().setVisibility(View.GONE);
+            }
+        }
+    }
+
     /**
      * @return Whether the navigation bar should be made visible based on the current state.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
index 669a8c8..7cd433a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
@@ -388,6 +388,12 @@
                             typeContentDescription);
         }
 
+        public MobileIconState copy() {
+            MobileIconState copy = new MobileIconState(this.subId);
+            copyTo(copy);
+            return copy;
+        }
+
         public void copyTo(MobileIconState other) {
             super.copyTo(other);
             other.subId = subId;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 2437c51..fadc0ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -108,7 +108,6 @@
         mLp.gravity = Gravity.TOP;
         mLp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
         mLp.setTitle("StatusBar");
-        mLp.accessibilityTitle = mContext.getString(R.string.status_bar);
         mLp.packageName = mContext.getPackageName();
         mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
         mStatusBarView = statusBarView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index 44e87ff..8df51db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -234,6 +234,7 @@
         mEnabled = bluetoothState == BluetoothAdapter.STATE_ON
                 || bluetoothState == BluetoothAdapter.STATE_TURNING_ON;
         mState = bluetoothState;
+        updateConnected();
         mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 22a48f0..85cfde8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -49,12 +49,11 @@
 import com.android.systemui.R;
 import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider.ButtonInterface;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.NavigationBarCompat;
 
 import static android.view.KeyEvent.KEYCODE_HOME;
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
-import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_SCRUB_TOUCH_SLOP_PX;
-import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_STEP_TOUCH_SLOP_PX;
 
 public class KeyButtonView extends ImageView implements ButtonInterface {
     private static final String TAG = KeyButtonView.class.getSimpleName();
@@ -234,10 +233,12 @@
                 x = (int)ev.getRawX();
                 y = (int)ev.getRawY();
 
-                boolean exceededTouchSlopX = Math.abs(x - mTouchDownX) >
-                        (mIsVertical ? QUICK_SCRUB_TOUCH_SLOP_PX : QUICK_STEP_TOUCH_SLOP_PX);
-                boolean exceededTouchSlopY = Math.abs(y - mTouchDownY) >
-                        (mIsVertical ? QUICK_STEP_TOUCH_SLOP_PX : QUICK_SCRUB_TOUCH_SLOP_PX);
+                boolean exceededTouchSlopX = Math.abs(x - mTouchDownX) > (mIsVertical
+                        ? NavigationBarCompat.getQuickScrubTouchSlopPx()
+                        : NavigationBarCompat.getQuickStepTouchSlopPx());
+                boolean exceededTouchSlopY = Math.abs(y - mTouchDownY) > (mIsVertical
+                        ? NavigationBarCompat.getQuickStepTouchSlopPx()
+                        : NavigationBarCompat.getQuickScrubTouchSlopPx());
                 if (exceededTouchSlopX || exceededTouchSlopY) {
                     // When quick step is enabled, prevent animating the ripple triggered by
                     // setPressed and decide to run it on touch up
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index 1431682..b4fa2e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -26,7 +26,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.NotificationData;
-import com.android.systemui.statusbar.SmartReplyLogger;
+import com.android.systemui.statusbar.SmartReplyController;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
 
@@ -73,6 +73,8 @@
 
     private PriorityQueue<Button> mCandidateButtonQueueForSqueezing;
 
+    private View mSmartReplyContainer;
+
     public SmartReplyView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mConstants = Dependency.get(SmartReplyConstants.class);
@@ -133,7 +135,9 @@
     }
 
     public void setRepliesFromRemoteInput(RemoteInput remoteInput, PendingIntent pendingIntent,
-            SmartReplyLogger smartReplyLogger, NotificationData.Entry entry) {
+            SmartReplyController smartReplyController, NotificationData.Entry entry,
+            View smartReplyContainer) {
+        mSmartReplyContainer = smartReplyContainer;
         removeAllViews();
         if (remoteInput != null && pendingIntent != null) {
             CharSequence[] choices = remoteInput.getChoices();
@@ -141,7 +145,7 @@
                 for (int i = 0; i < choices.length; ++i) {
                     Button replyButton = inflateReplyButton(
                             getContext(), this, i, choices[i], remoteInput, pendingIntent,
-                            smartReplyLogger, entry);
+                            smartReplyController, entry);
                     addView(replyButton);
                 }
             }
@@ -157,7 +161,7 @@
     @VisibleForTesting
     Button inflateReplyButton(Context context, ViewGroup root, int replyIndex,
             CharSequence choice, RemoteInput remoteInput, PendingIntent pendingIntent,
-            SmartReplyLogger smartReplyLogger, NotificationData.Entry entry) {
+            SmartReplyController smartReplyController, NotificationData.Entry entry) {
         Button b = (Button) LayoutInflater.from(context).inflate(
                 R.layout.smart_reply_button, root, false);
         b.setText(choice);
@@ -173,7 +177,8 @@
             } catch (PendingIntent.CanceledException e) {
                 Log.w(TAG, "Unable to send smart reply", e);
             }
-            smartReplyLogger.smartReplySent(entry, replyIndex);
+            smartReplyController.smartReplySent(entry, replyIndex, b.getText());
+            mSmartReplyContainer.setVisibility(View.GONE);
             return false; // do not defer
         };
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 897d13b..5ca5752 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -69,6 +69,7 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.keyguard.KeyguardSliceView;
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
 import com.android.systemui.ExpandHelper;
@@ -80,6 +81,7 @@
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.statusbar.ActivatableNotificationView;
+import com.android.systemui.statusbar.DndSuppressingNotificationsView;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
@@ -168,6 +170,7 @@
     private int mCollapsedSize;
     private int mPaddingBetweenElements;
     private int mIncreasedPaddingBetweenElements;
+    private int mMaxTopPadding;
     private int mRegularTopPadding;
     private int mDarkTopPadding;
     // Current padding, will be either mRegularTopPadding or mDarkTopPadding
@@ -176,6 +179,7 @@
     private int mDarkSeparatorPadding;
     private int mBottomMargin;
     private int mBottomInset = 0;
+    private float mQsExpansionFraction;
 
     /**
      * The algorithm which calculates the properties for our children
@@ -229,9 +233,11 @@
     private boolean mPanelTracking;
     private boolean mExpandingNotification;
     private boolean mExpandedInThisMotion;
+    private boolean mShouldShowShelfOnly;
     protected boolean mScrollingEnabled;
     protected FooterView mFooterView;
     protected EmptyShadeView mEmptyShadeView;
+    protected DndSuppressingNotificationsView mDndView;
     private boolean mDismissAllInProgress;
     private boolean mFadeNotificationsOnDismiss;
 
@@ -370,6 +376,7 @@
     private boolean mGroupExpandedForMeasure;
     private boolean mScrollable;
     private View mForcedScroll;
+    private View mNeedingPulseAnimation;
     private float mDarkAmount = 0f;
     private static final Property<NotificationStackScrollLayout, Float> DARK_AMOUNT =
             new FloatProperty<NotificationStackScrollLayout>("darkAmount") {
@@ -406,7 +413,6 @@
     private final int mSeparatorWidth;
     private final int mSeparatorThickness;
     private final Rect mBackgroundAnimationRect = new Rect();
-    private int mClockBottom;
     private int mAntiBurnInOffsetX;
     private ArrayList<BiConsumer<Float, Float>> mExpandedHeightListeners = new ArrayList<>();
     private int mHeadsUpInset;
@@ -717,11 +723,7 @@
     }
 
     private void updateAlgorithmHeightAndPadding() {
-        if (mPulsing) {
-            mTopPadding = mClockBottom;
-        } else {
-            mTopPadding = (int) MathUtils.lerp(mRegularTopPadding, mDarkTopPadding, mDarkAmount);
-        }
+        mTopPadding = (int) MathUtils.lerp(mRegularTopPadding, mDarkTopPadding, mDarkAmount);
         mAmbientState.setLayoutHeight(getLayoutHeight());
         updateAlgorithmLayoutMinHeight();
         mAmbientState.setTopPadding(mTopPadding);
@@ -886,7 +888,20 @@
         float appearFraction = 1.0f;
         if (height >= appearEndPosition) {
             translationY = 0;
-            stackHeight = (int) height;
+            if (mShouldShowShelfOnly) {
+                stackHeight = mTopPadding + mShelf.getIntrinsicHeight();
+            } else if (mQsExpanded) {
+                int stackStartPosition = mContentHeight - mTopPadding + mIntrinsicPadding;
+                int stackEndPosition = mMaxTopPadding + mShelf.getIntrinsicHeight();
+                if (stackStartPosition <= stackEndPosition) {
+                    stackHeight = stackEndPosition;
+                } else {
+                    stackHeight = (int) NotificationUtils.interpolate(stackStartPosition,
+                            stackEndPosition, mQsExpansionFraction);
+                }
+            } else {
+                stackHeight = (int) height;
+            }
         } else {
             appearFraction = getAppearFraction(height);
             if (appearFraction >= 0) {
@@ -993,7 +1008,8 @@
     private float getAppearEndPosition() {
         int appearPosition;
         int notGoneChildCount = getNotGoneChildCount();
-        if (mEmptyShadeView.getVisibility() == GONE && notGoneChildCount != 0) {
+        if ((mEmptyShadeView.getVisibility() == GONE && mDndView.getVisibility() == GONE)
+                && notGoneChildCount != 0) {
             if (isHeadsUpTransition()
                     || (mHeadsUpManager.hasPinnedHeadsUp() && !mAmbientState.isDark())) {
                 appearPosition = getTopHeadsUpPinnedHeight();
@@ -1003,6 +1019,8 @@
                     appearPosition += mShelf.getIntrinsicHeight();
                 }
             }
+        } else if (mEmptyShadeView.getVisibility() == GONE) {
+            appearPosition = mDndView.getHeight();
         } else {
             appearPosition = mEmptyShadeView.getHeight();
         }
@@ -2584,6 +2602,10 @@
         setExpandedHeight(mExpandedHeight);
     }
 
+    public void setMaxTopPadding(int maxTopPadding) {
+        mMaxTopPadding = maxTopPadding;
+    }
+
     public int getLayoutMinHeight() {
         if (isHeadsUpTransition()) {
             return getTopHeadsUpPinnedHeight();
@@ -2591,19 +2613,6 @@
         return mShelf.getVisibility() == GONE ? 0 : mShelf.getIntrinsicHeight();
     }
 
-    public int getFirstChildIntrinsicHeight() {
-        final ExpandableView firstChild = getFirstChildNotGone();
-        int firstChildMinHeight = firstChild != null
-                ? firstChild.getIntrinsicHeight()
-                : mEmptyShadeView != null
-                        ? mEmptyShadeView.getIntrinsicHeight()
-                        : mCollapsedSize;
-        if (mOwnScrollY > 0) {
-            firstChildMinHeight = Math.max(firstChildMinHeight - mOwnScrollY, mCollapsedSize);
-        }
-        return firstChildMinHeight;
-    }
-
     public float getTopPaddingOverflow() {
         return mTopPaddingOverflow;
     }
@@ -3174,6 +3183,7 @@
         generateViewResizeEvent();
         generateGroupExpansionEvent();
         generateAnimateEverythingEvent();
+        generatePulsingAnimationEvent();
         mNeedsAnimation = false;
     }
 
@@ -3900,6 +3910,7 @@
         final int textColor = Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColor);
         mFooterView.setTextColor(textColor);
         mEmptyShadeView.setTextColor(textColor);
+        mDndView.setColor(textColor);
     }
 
     public void goToFullShade(long delay) {
@@ -3907,6 +3918,7 @@
             mFooterView.setInvisible();
         }
         mEmptyShadeView.setInvisible();
+        mDndView.setInvisible();
         mGoToFullShadeNeedsAnimation = true;
         mGoToFullShadeDelay = delay;
         mNeedsAnimation = true;
@@ -4058,25 +4070,39 @@
         int newVisibility = visible ? VISIBLE : GONE;
 
         boolean changedVisibility = oldVisibility != newVisibility;
-        if (changedVisibility || newVisibility != GONE) {
+        if (changedVisibility) {
             if (newVisibility != GONE) {
-                int oldText = mEmptyShadeView.getTextResource();
-                int newText;
-                if (mStatusBar.areNotificationsHidden()) {
-                    newText = R.string.dnd_suppressing_shade_text;
-                } else {
-                    newText = R.string.empty_shade_text;
-                }
-                if (changedVisibility || !Objects.equals(oldText, newText)) {
-                    mEmptyShadeView.setText(newText);
-                    showFooterView(mEmptyShadeView);
-                }
+                showFooterView(mEmptyShadeView);
             } else {
                 hideFooterView(mEmptyShadeView, true);
             }
         }
     }
 
+    public void setDndView(DndSuppressingNotificationsView dndView) {
+        int index = -1;
+        if (mDndView != null) {
+            index = indexOfChild(mDndView);
+            removeView(mDndView);
+        }
+        mDndView = dndView;
+        addView(mDndView, index);
+    }
+
+    public void updateDndView(boolean visible) {
+        int oldVisibility = mDndView.willBeGone() ? GONE : mDndView.getVisibility();
+        int newVisibility = visible ? VISIBLE : GONE;
+
+        boolean changedVisibility = oldVisibility != newVisibility;
+        if (changedVisibility) {
+            if (newVisibility != GONE) {
+                showFooterView(mDndView);
+            } else {
+                hideFooterView(mDndView, true);
+            }
+        }
+    }
+
     public void updateFooterView(boolean visible, boolean showDismissView) {
         if (mFooterView == null) {
             return;
@@ -4101,10 +4127,16 @@
         } else {
             footerView.setInvisible();
         }
-        footerView.setVisibility(VISIBLE);
-        footerView.setWillBeGone(false);
-        updateContentHeight();
-        notifyHeightChangeListener(footerView);
+        Runnable onShowFinishRunnable = new Runnable() {
+            @Override
+            public void run() {
+                footerView.setVisibility(VISIBLE);
+                footerView.setWillBeGone(false);
+                updateContentHeight();
+                notifyHeightChangeListener(footerView);
+            }
+        };
+        footerView.performVisibilityAnimation(true, onShowFinishRunnable);
     }
 
     private void hideFooterView(StackScrollerDecorView footerView, boolean isButtonVisible) {
@@ -4428,18 +4460,28 @@
         return mIsExpanded;
     }
 
-    public void setPulsing(boolean pulsing, int clockBottom) {
+    public void setPulsing(boolean pulsing, boolean animated) {
         if (!mPulsing && !pulsing) {
             return;
         }
         mPulsing = pulsing;
-        mClockBottom = clockBottom;
+        mNeedingPulseAnimation = animated ? getFirstChildNotGone() : null;
         mAmbientState.setPulsing(pulsing);
         updateNotificationAnimationStates();
         updateAlgorithmHeightAndPadding();
         updateContentHeight();
-        notifyHeightChangeListener(mShelf);
         requestChildrenUpdate();
+        notifyHeightChangeListener(null, animated);
+        mNeedsAnimation |= animated;
+    }
+
+    private void generatePulsingAnimationEvent() {
+        if (mNeedingPulseAnimation != null) {
+            int type = mPulsing ? AnimationEvent.ANIMATION_TYPE_PULSE_APPEAR
+                    : AnimationEvent.ANIMATION_TYPE_PULSE_DISAPPEAR;
+            mAnimationEvents.add(new AnimationEvent(mNeedingPulseAnimation, type));
+            mNeedingPulseAnimation = null;
+        }
     }
 
     public void setFadingOut(boolean fadingOut) {
@@ -4476,6 +4518,10 @@
         updateAlgorithmLayoutMinHeight();
     }
 
+    public void setQsExpansionFraction(float qsExpansionFraction) {
+        mQsExpansionFraction = qsExpansionFraction;
+    }
+
     public void setOwnScrollY(int ownScrollY) {
         if (ownScrollY != mOwnScrollY) {
             // We still want to call the normal scrolled changed for accessibility reasons
@@ -4511,6 +4557,11 @@
         }
     }
 
+    public void setShouldShowShelfOnly(boolean shouldShowShelfOnly) {
+        mShouldShowShelfOnly =  shouldShowShelfOnly;
+        updateAlgorithmLayoutMinHeight();
+    }
+
     public int getMinExpansionHeight() {
         return mShelf.getIntrinsicHeight() - (mShelf.getIntrinsicHeight() - mStatusBarHeight) / 2;
     }
@@ -4566,7 +4617,8 @@
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println(String.format("[%s: pulsing=%s qsCustomizerShowing=%s visibility=%s"
-                        + " alpha:%f scrollY:%d]",
+                        + " alpha:%f scrollY:%d maxTopPadding:%d showShelfOnly=%s"
+                        + " qsExpandFraction=%f]",
                 this.getClass().getSimpleName(),
                 mPulsing ? "T":"f",
                 mAmbientState.isQsCustomizerShowing() ? "T":"f",
@@ -4574,7 +4626,10 @@
                         : getVisibility() == View.GONE ? "gone"
                                 : "invisible",
                 getAlpha(),
-                mAmbientState.getScrollY()));
+                mAmbientState.getScrollY(),
+                mMaxTopPadding,
+                mShouldShowShelfOnly ? "T":"f",
+                mQsExpansionFraction));
     }
 
     public boolean isFullyDark() {
@@ -5007,6 +5062,16 @@
                         .animateTopInset()
                         .animateY()
                         .animateZ(),
+
+                // ANIMATION_TYPE_PULSE_APPEAR
+                new AnimationFilter()
+                        .animateAlpha()
+                        .animateY(),
+
+                // ANIMATION_TYPE_PULSE_DISAPPEAR
+                new AnimationFilter()
+                        .animateAlpha()
+                        .animateY(),
         };
 
         static int[] LENGTHS = new int[] {
@@ -5067,6 +5132,12 @@
 
                 // ANIMATION_TYPE_EVERYTHING
                 StackStateAnimator.ANIMATION_DURATION_STANDARD,
+
+                // ANIMATION_TYPE_PULSE_APPEAR
+                KeyguardSliceView.DEFAULT_ANIM_DURATION,
+
+                // ANIMATION_TYPE_PULSE_DISAPPEAR
+                KeyguardSliceView.DEFAULT_ANIM_DURATION / 2,
         };
 
         static final int ANIMATION_TYPE_ADD = 0;
@@ -5088,6 +5159,8 @@
         static final int ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK = 16;
         static final int ANIMATION_TYPE_HEADS_UP_OTHER = 17;
         static final int ANIMATION_TYPE_EVERYTHING = 18;
+        static final int ANIMATION_TYPE_PULSE_APPEAR = 19;
+        static final int ANIMATION_TYPE_PULSE_DISAPPEAR = 20;
 
         static final int DARK_ANIMATION_ORIGIN_INDEX_ABOVE = -1;
         static final int DARK_ANIMATION_ORIGIN_INDEX_BELOW = -2;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index c80bdc6..d01db14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -60,6 +60,7 @@
     public static final int ANIMATION_DELAY_HEADS_UP_CLICKED= 120;
 
     private final int mGoToFullShadeAppearingTranslation;
+    private final int mPulsingAppearingTranslation;
     private final ExpandableViewState mTmpState = new ExpandableViewState();
     private final AnimationProperties mAnimationProperties;
     public NotificationStackScrollLayout mHostLayout;
@@ -90,6 +91,9 @@
         mGoToFullShadeAppearingTranslation =
                 hostLayout.getContext().getResources().getDimensionPixelSize(
                         R.dimen.go_to_full_shade_appearing_translation);
+        mPulsingAppearingTranslation =
+                hostLayout.getContext().getResources().getDimensionPixelSize(
+                        R.dimen.pulsing_notification_appear_translation);
         mAnimationProperties = new AnimationProperties() {
             @Override
             public AnimationFilter getAnimationFilter() {
@@ -427,6 +431,18 @@
                 ExpandableNotificationRow row = (ExpandableNotificationRow) event.changingView;
                 row.prepareExpansionChanged(finalState);
             } else if (event.animationType == NotificationStackScrollLayout
+                    .AnimationEvent.ANIMATION_TYPE_PULSE_APPEAR) {
+                ExpandableViewState viewState = finalState.getViewStateForView(changingView);
+                mTmpState.copyFrom(viewState);
+                mTmpState.yTranslation += mPulsingAppearingTranslation;
+                mTmpState.alpha = 0;
+                mTmpState.applyToView(changingView);
+            } else if (event.animationType == NotificationStackScrollLayout
+                    .AnimationEvent.ANIMATION_TYPE_PULSE_DISAPPEAR) {
+                ExpandableViewState viewState = finalState.getViewStateForView(changingView);
+                viewState.yTranslation += mPulsingAppearingTranslation;
+                viewState.alpha = 0;
+            } else if (event.animationType == NotificationStackScrollLayout
                     .AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR) {
                 // This item is added, initialize it's properties.
                 ExpandableViewState viewState = finalState.getViewStateForView(changingView);
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListener.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListener.java
new file mode 100644
index 0000000..a54b0e1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListener.java
@@ -0,0 +1,73 @@
+/*
+ * 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.systemui.util.wakelock;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.content.Context;
+import android.view.animation.Animation;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.util.Assert;
+
+public class KeepAwakeAnimationListener extends AnimatorListenerAdapter
+        implements Animation.AnimationListener {
+    @VisibleForTesting
+    static WakeLock sWakeLock;
+
+    public KeepAwakeAnimationListener(Context context) {
+        Assert.isMainThread();
+        if (sWakeLock == null) {
+            sWakeLock = WakeLock.createPartial(context, "animation");
+        }
+    }
+
+    @Override
+    public void onAnimationStart(Animation animation) {
+        onStart();
+    }
+
+    @Override
+    public void onAnimationEnd(Animation animation) {
+        onEnd();
+    }
+
+    @Override
+    public void onAnimationRepeat(Animation animation) {
+
+    }
+
+    @Override
+    public void onAnimationStart(Animator animation) {
+        onStart();
+    }
+
+    @Override
+    public void onAnimationEnd(Animator animation) {
+        onEnd();
+    }
+
+    private void onStart() {
+        Assert.isMainThread();
+        sWakeLock.acquire();
+    }
+
+    private void onEnd() {
+        Assert.isMainThread();
+        sWakeLock.release();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
index 64abfe2..f1a7183 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
@@ -16,6 +16,9 @@
 
 package com.android.systemui.volume;
 
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
 import android.annotation.Nullable;
 import android.app.Dialog;
 import android.app.KeyguardManager;
@@ -24,6 +27,7 @@
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.media.AudioSystem;
 import android.os.Debug;
@@ -80,7 +84,6 @@
 
     private Window mWindow;
     private CustomDialog mDialog;
-    private ViewGroup mDialogView;
     private PagedListView mListView;
     private ListItemAdapter mPagedListAdapter;
     private final List<ListItem> mVolumeLineItems = new ArrayList<>();
@@ -99,29 +102,6 @@
     private boolean mHovering = false;
     private boolean mExpanded;
 
-    private final View.OnClickListener mSupplementalIconListener = v -> {
-        mExpanded = !mExpanded;
-        if (mExpanded) {
-            for (VolumeRow row : mRows) {
-                // Adding the items which are not coming from default stream.
-                if (!row.defaultStream) {
-                    addSeekbarListItem(row, null);
-                }
-            }
-        } else {
-            // Only keeping the default stream if it is not expended.
-            Iterator itr = mVolumeLineItems.iterator();
-            while (itr.hasNext()) {
-                SeekbarListItem item = (SeekbarListItem) itr.next();
-                VolumeRow row = findRow(item);
-                if (!row.defaultStream) {
-                    itr.remove();
-                }
-            }
-        }
-        mPagedListAdapter.notifyDataSetChanged();
-    };
-
     public CarVolumeDialogImpl(Context context) {
         mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
         mController = Dependency.get(VolumeDialogController.class);
@@ -175,31 +155,31 @@
         mDialog.setCanceledOnTouchOutside(true);
         mDialog.setContentView(R.layout.car_volume_dialog);
         mDialog.setOnShowListener(dialog -> {
-            mDialogView.setTranslationY(-mDialogView.getHeight());
-            mDialogView.setAlpha(0);
-            mDialogView.animate()
+            mListView.setTranslationY(-mListView.getHeight());
+            mListView.setAlpha(0);
+            mListView.animate()
                 .alpha(1)
                 .translationY(0)
                 .setDuration(300)
                 .setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
                 .start();
         });
-        mDialogView = (ViewGroup) mDialog.findViewById(R.id.volume_dialog);
-        mDialogView.setOnHoverListener((v, event) -> {
+        mListView = (PagedListView) mWindow.findViewById(R.id.volume_list);
+        mListView.setOnHoverListener((v, event) -> {
             int action = event.getActionMasked();
             mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
                 || (action == MotionEvent.ACTION_HOVER_MOVE);
             rescheduleTimeoutH();
             return true;
         });
-        mListView = (PagedListView) mWindow.findViewById(R.id.volume_list);
 
-        // TODO: apply tint to the supplement icon.
-        addSeekbarListItem(addVolumeRow(AudioManager.STREAM_MUSIC, R.drawable.ic_volume_media,
-            R.drawable.car_ic_arrow_drop_up, true, true), mSupplementalIconListener);
-        addVolumeRow(AudioManager.STREAM_RING, R.drawable.ic_volume_ringer, 0,
+        addSeekbarListItem(addVolumeRow(AudioManager.STREAM_MUSIC, R.drawable.car_ic_music,
+            R.drawable.car_ic_keyboard_arrow_down, true, true),
+            new ExpandIconListener());
+        // We map AudioManager.STREAM_RING to a navigation icon for demo.
+        addVolumeRow(AudioManager.STREAM_RING, R.drawable.car_ic_navigation, 0,
             true, false);
-        addVolumeRow(AudioManager.STREAM_ALARM, R.drawable.ic_volume_alarm, 0,
+        addVolumeRow(AudioManager.STREAM_NOTIFICATION, R.drawable.car_ic_notification_2, 0,
             true, false);
 
         mPagedListAdapter = new ListItemAdapter(mContext, new ListProvider(mVolumeLineItems),
@@ -248,9 +228,13 @@
         SeekbarListItem listItem =
             new SeekbarListItem(mContext, volumeMax, currentVolume,
                 new VolumeSeekBarChangeListener(volumeRow), null);
-        listItem.setPrimaryActionIcon(volumeRow.primaryActionIcon);
+        Drawable primaryIcon = mContext.getResources().getDrawable(volumeRow.primaryActionIcon);
+        listItem.setPrimaryActionIcon(primaryIcon);
         if (volumeRow.supplementalIcon != 0) {
-            listItem.setSupplementalIcon(volumeRow.supplementalIcon, true, supplementalIconOnClickListener);
+            Drawable supplementalIcon = mContext.getResources()
+                .getDrawable(volumeRow.supplementalIcon);
+            listItem.setSupplementalIcon(supplementalIcon, true,
+                supplementalIconOnClickListener);
         } else {
             listItem.setSupplementalEmptyIcon(true);
         }
@@ -309,14 +293,14 @@
         mHandler.removeMessages(H.DISMISS);
         mHandler.removeMessages(H.SHOW);
         if (!mShowing) return;
-        mDialogView.animate().cancel();
+        mListView.animate().cancel();
         mShowing = false;
 
-        mDialogView.setTranslationY(0);
-        mDialogView.setAlpha(1);
-        mDialogView.animate()
+        mListView.setTranslationY(0);
+        mListView.setAlpha(1);
+        mListView.animate()
             .alpha(0)
-            .translationY(-mDialogView.getHeight())
+            .translationY(-mListView.getHeight())
             .setDuration(250)
             .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
             .withEndAction(() -> mHandler.postDelayed(() -> {
@@ -487,7 +471,7 @@
 
         @Override
         public void onLayoutDirectionChanged(int layoutDirection) {
-            mDialogView.setLayoutDirection(layoutDirection);
+            mListView.setLayoutDirection(layoutDirection);
         }
 
         @Override
@@ -642,6 +626,45 @@
         }
     }
 
+    private final class ExpandIconListener implements View.OnClickListener {
+        @Override
+        public void onClick(final View v) {
+            mExpanded = !mExpanded;
+            Animator inAnimator;
+            if (mExpanded) {
+                for (VolumeRow row : mRows) {
+                    // Adding the items which are not coming from default stream.
+                    if (!row.defaultStream) {
+                        addSeekbarListItem(row, null);
+                    }
+                }
+                inAnimator = AnimatorInflater.loadAnimator(
+                    mContext, R.anim.car_arrow_fade_in_rotate_up);
+            } else {
+                // Only keeping the default stream if it is not expended.
+                Iterator itr = mVolumeLineItems.iterator();
+                while (itr.hasNext()) {
+                    SeekbarListItem item = (SeekbarListItem) itr.next();
+                    VolumeRow row = findRow(item);
+                    if (!row.defaultStream) {
+                        itr.remove();
+                    }
+                }
+                inAnimator = AnimatorInflater.loadAnimator(
+                    mContext, R.anim.car_arrow_fade_in_rotate_down);
+            }
+
+            Animator outAnimator = AnimatorInflater.loadAnimator(
+                mContext, R.anim.car_arrow_fade_out);
+            inAnimator.setStartDelay(100);
+            AnimatorSet animators = new AnimatorSet();
+            animators.playTogether(outAnimator, inAnimator);
+            animators.setTarget(v);
+            animators.start();
+            mPagedListAdapter.notifyDataSetChanged();
+        }
+    }
+
     private static class VolumeRow {
         private int stream;
         private StreamState ss;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 5c7ce59..b5071de 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -53,7 +53,6 @@
 import android.os.Message;
 import android.os.SystemClock;
 import android.os.VibrationEffect;
-import android.os.Vibrator;
 import android.provider.Settings;
 import android.provider.Settings.Global;
 import android.text.InputFilter;
@@ -73,8 +72,8 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
 import android.view.animation.DecelerateInterpolator;
+import android.widget.FrameLayout;
 import android.widget.ImageButton;
-import android.widget.ImageView;
 import android.widget.SeekBar;
 import android.widget.SeekBar.OnSeekBarChangeListener;
 import android.widget.TextView;
@@ -122,7 +121,7 @@
     private ImageButton mRingerIcon;
     private View mSettingsView;
     private ImageButton mSettingsIcon;
-    private ImageView mZenIcon;
+    private FrameLayout mZenIcon;
     private final List<VolumeRow> mRows = new ArrayList<>();
     private ConfigurableTexts mConfigurableTexts;
     private final SparseBooleanArray mDynamic = new SparseBooleanArray();
@@ -132,7 +131,6 @@
     private final Accessibility mAccessibility = new Accessibility();
     private final ColorStateList mActiveTint;
     private final ColorStateList mInactiveTint;
-    private final Vibrator mVibrator;
 
     private boolean mShowing;
     private boolean mShowA11yStream;
@@ -153,7 +151,6 @@
         mActiveTint = ColorStateList.valueOf(Utils.getColorAccent(mContext));
         mInactiveTint = loadColorStateList(R.color.volume_slider_inactive);
         mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
-        mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
     }
 
     public void init(int windowType, Callback callback) {
@@ -673,7 +670,28 @@
      * @param enable whether to enable volume row views and hide dnd icon
      */
     private void enableVolumeRowViewsH(VolumeRow row, boolean enable) {
-        row.dndIcon.setVisibility(enable ? GONE : VISIBLE);
+        boolean showDndIcon = !enable;
+        row.dndIcon.setVisibility(showDndIcon ? VISIBLE : GONE);
+
+        if (showDndIcon && getNumVisibleRows() == 1) {
+            row.dndIcon.setLayoutParams(new FrameLayout.LayoutParams(
+                    mContext.getResources().getDimensionPixelSize(
+                            R.dimen.volume_dialog_panel_width),
+                    FrameLayout.LayoutParams.WRAP_CONTENT));
+        } else if (row.view.getVisibility() == VISIBLE) {
+            row.dndIcon.setLayoutParams(new FrameLayout.LayoutParams(
+                    FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));
+        }
+    }
+
+    private int getNumVisibleRows() {
+        int count = 0;
+        for (int i = 0; i < mRows.size(); i++) {
+            if (mRows.get(i).view.getVisibility() == VISIBLE) {
+                count++;
+            }
+        }
+        return count;
     }
 
     /**
@@ -724,8 +742,11 @@
             updateVolumeRowH(row);
         }
         updateRingerH();
-        mWindow.setTitle(mContext.getString(R.string.volume_dialog_title,
-                getStreamLabelH(getActiveRow().ss)));
+        mWindow.setTitle(composeWindowTitle());
+    }
+
+    CharSequence composeWindowTitle() {
+        return mContext.getString(R.string.volume_dialog_title, getStreamLabelH(getActiveRow().ss));
     }
 
     private void updateVolumeRowH(VolumeRow row) {
@@ -1196,6 +1217,13 @@
         }
 
         @Override
+        public boolean dispatchPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
+            // Activities populate their title here. Follow that example.
+            event.getText().add(composeWindowTitle());
+            return true;
+        }
+
+        @Override
         public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child,
                 AccessibilityEvent event) {
             rescheduleTimeoutH();
@@ -1241,6 +1269,6 @@
         private ObjectAnimator anim;  // slider progress animation for non-touch-related updates
         private int animTargetProgress;
         private int lastAudibleLevel = 1;
-        private ImageView dndIcon;
+        private FrameLayout dndIcon;
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java b/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java
index fe23541..6792bc0 100644
--- a/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java
+++ b/packages/SystemUI/tests/src/com/android/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java
@@ -14,7 +14,10 @@
 
 package com.android;
 
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
 
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
@@ -31,11 +34,11 @@
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
 
 import java.io.IOException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -72,9 +75,9 @@
 
     @Test
     public void testAllClassInheritance() throws Throwable {
-        boolean anyClassWrong = false;
+        ArrayList<String> fails = new ArrayList<>();
         for (String className : getClassNamesFromClassPath()) {
-            Class<?> cls = Class.forName(className, false, this.getClass().getClassLoader());		
+            Class<?> cls = Class.forName(className, false, this.getClass().getClassLoader());
             if (!isTestClass(cls)) continue;
 
             boolean hasParent = false;
@@ -86,17 +89,15 @@
             }
             boolean hasSize = hasSize(cls);
             if (!hasSize) {
-                anyClassWrong = true;
-                Log.e(TAG, cls.getName() + " does not have size annotation, such as @SmallTest");
+                fails.add(cls.getName() + " does not have size annotation, such as @SmallTest");
             }
             if (!hasParent) {
-                anyClassWrong = true;
-                Log.e(TAG, cls.getName() + " does not extend any of " + getClsStr());
+                fails.add(cls.getName() + " does not extend any of " + getClsStr());
             }
         }
 
-        assertFalse("All sysui test classes must have size and extend one of " + getClsStr(),
-                anyClassWrong);
+        assertThat("All sysui test classes must have size and extend one of " + getClsStr(),
+                fails, is(empty()));
     }
 
     private boolean hasSize(Class<?> cls) {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
index 7686948..56bce5d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
@@ -16,39 +16,78 @@
 package com.android.keyguard;
 
 import android.graphics.Color;
+import android.net.Uri;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.MeasureSpec;
+import android.view.ViewGroup;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.KeyguardSliceProvider;
 
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Collections;
+import java.util.HashSet;
+
+import androidx.slice.SliceProvider;
+import androidx.slice.SliceSpecs;
+import androidx.slice.builders.ListBuilder;
+
 @SmallTest
-@RunWithLooper
+@RunWithLooper(setAsMainLooper = true)
 @RunWith(AndroidTestingRunner.class)
 public class KeyguardSliceViewTest extends SysuiTestCase {
     private KeyguardSliceView mKeyguardSliceView;
+    private Uri mSliceUri;
 
     @Before
     public void setUp() throws Exception {
         mKeyguardSliceView = (KeyguardSliceView) LayoutInflater.from(getContext())
                 .inflate(R.layout.keyguard_status_area, null);
+        mSliceUri = Uri.parse(KeyguardSliceProvider.KEYGUARD_SLICE_URI);
+        SliceProvider.setSpecs(new HashSet<>(Collections.singletonList(SliceSpecs.LIST)));
+    }
+
+    @Test
+    public void showSlice_notifiesListener() {
+        ListBuilder builder = new ListBuilder(getContext(), mSliceUri);
+        boolean[] notified = {false};
+        mKeyguardSliceView.setContentChangeListener((hasHeader)-> {
+            notified[0] = true;
+        });
+        mKeyguardSliceView.onChanged(builder.build());
+        Assert.assertTrue("Listener should be notified about slice changes.", notified[0]);
+    }
+
+    @Test
+    public void hasHeader_readsSliceData() {
+        ListBuilder builder = new ListBuilder(getContext(), mSliceUri);
+        mKeyguardSliceView.onChanged(builder.build());
+        Assert.assertFalse("View should not have a header", mKeyguardSliceView.hasHeader());
+
+        builder.setHeader((ListBuilder.HeaderBuilder headerBuilder) -> {
+            headerBuilder.setTitle("header title!");
+        });
+        mKeyguardSliceView.onChanged(builder.build());
+        Assert.assertTrue("View should have a header", mKeyguardSliceView.hasHeader());
     }
 
     @Test
     public void getTextColor_whiteTextWhenAOD() {
         // Set text color to red since the default is white and test would always pass
         mKeyguardSliceView.setTextColor(Color.RED);
-        mKeyguardSliceView.setDark(0);
+        mKeyguardSliceView.setDarkAmount(0);
         Assert.assertEquals("Should be using regular text color", Color.RED,
                 mKeyguardSliceView.getTextColor());
-        mKeyguardSliceView.setDark(1);
+        mKeyguardSliceView.setDarkAmount(1);
         Assert.assertEquals("Should be using AOD text color", Color.WHITE,
                 mKeyguardSliceView.getTextColor());
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index 7475cd7..a35ca46 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -28,6 +28,8 @@
 import android.testing.LeakCheck;
 import android.util.Log;
 
+import com.android.keyguard.KeyguardUpdateMonitor;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -70,6 +72,7 @@
                     "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext");
         });
         InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments());
+        KeyguardUpdateMonitor.disableHandlerCheckForTesting(inst);
     }
 
     @After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
index 7cfd7a3..8172626 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
@@ -367,4 +367,44 @@
         mEntryManager.tagForeground(mEntry.notification);
         Assert.assertEquals(0, mEntry.mActiveAppOps.size());
     }
+
+    @Test
+    public void testRebuildWithRemoteInput_noExistingInputNoSpinner() {
+        StatusBarNotification newSbn =
+                mEntryManager.rebuildNotificationWithRemoteInput(mEntry, "A Reply", false);
+        CharSequence[] messages = newSbn.getNotification().extras
+                .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
+        Assert.assertEquals(1, messages.length);
+        Assert.assertEquals("A Reply", messages[0]);
+        Assert.assertFalse(newSbn.getNotification().extras
+                .getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false));
+    }
+
+    @Test
+    public void testRebuildWithRemoteInput_noExistingInputWithSpinner() {
+        StatusBarNotification newSbn =
+                mEntryManager.rebuildNotificationWithRemoteInput(mEntry, "A Reply", true);
+        CharSequence[] messages = newSbn.getNotification().extras
+                .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
+        Assert.assertEquals(1, messages.length);
+        Assert.assertEquals("A Reply", messages[0]);
+        Assert.assertTrue(newSbn.getNotification().extras
+                .getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false));
+    }
+
+    @Test
+    public void testRebuildWithRemoteInput_withExistingInput() {
+        // Setup a notification entry with 1 remote input.
+        StatusBarNotification newSbn =
+                mEntryManager.rebuildNotificationWithRemoteInput(mEntry, "A Reply", false);
+        NotificationData.Entry entry = new NotificationData.Entry(newSbn);
+
+        // Try rebuilding to add another reply.
+        newSbn = mEntryManager.rebuildNotificationWithRemoteInput(entry, "Reply 2", true);
+        CharSequence[] messages = newSbn.getNotification().extras
+                .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
+        Assert.assertEquals(2, messages.length);
+        Assert.assertEquals("Reply 2", messages[0]);
+        Assert.assertEquals("A Reply", messages[1]);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index b0530c8..65fd7f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -33,9 +33,12 @@
 import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -44,7 +47,6 @@
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
-import android.app.NotificationManager;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
@@ -52,7 +54,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Drawable;
-import android.os.Looper;
+import android.os.IBinder;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -65,6 +67,7 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
@@ -100,7 +103,7 @@
     private StatusBarNotification mSbn;
 
     @Rule public MockitoRule mockito = MockitoJUnit.rule();
-    private Looper mLooper;
+    @Mock private MetricsLogger mMetricsLogger;
     @Mock private INotificationManager mMockINotificationManager;
     @Mock private PackageManager mMockPackageManager;
     @Mock private NotificationBlockingHelperManager mBlockingHelperManager;
@@ -112,6 +115,7 @@
                 mBlockingHelperManager);
         mTestableLooper = TestableLooper.get(this);
         mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
+        mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
         // Inflate the layout
         final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
         mNotificationInfo = (NotificationInfo) layoutInflater.inflate(R.layout.notification_info,
@@ -301,6 +305,24 @@
     }
 
     @Test
+    public void testLogBlockingHelperCounter_doesntLogForNormalGutsView() throws Exception {
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false);
+        mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent");
+        verify(mMetricsLogger, times(0)).count(anyString(), anyInt());
+    }
+
+    @Test
+    public void testLogBlockingHelperCounter_logsForBlockingHelper() throws Exception {
+        // Bind notification logs an event, so this counts as one invocation for the metrics logger.
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false, true,
+                true);
+        mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent");
+        verify(mMetricsLogger, times(2)).count(anyString(), anyInt());
+    }
+
+    @Test
     public void testOnClickListenerPassesNullChannelForBundle() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -471,6 +493,13 @@
                 false /* isNonblockable */, true /* isForBlockingHelper */,
                 true /* isUserSentimentNegative */);
 
+        NotificationGuts guts = spy(new NotificationGuts(mContext, null));
+        when(guts.getWindowToken()).thenReturn(mock(IBinder.class));
+        doNothing().when(guts).animateClose(anyInt(), anyInt(), anyBoolean());
+        doNothing().when(guts).setExposed(anyBoolean(), anyBoolean());
+        guts.setGutsContent(mNotificationInfo);
+        mNotificationInfo.setGutsParent(guts);
+
         mNotificationInfo.findViewById(R.id.keep).performClick();
 
         verify(mBlockingHelperManager).dismissCurrentBlockingHelper();
@@ -495,6 +524,9 @@
                 false /* isNonblockable */,
                 true /* isForBlockingHelper */,
                 false /* isUserSentimentNegative */);
+        NotificationGuts guts = mock(NotificationGuts.class);
+        doCallRealMethod().when(guts).closeControls(anyInt(), anyInt(), anyBoolean(), anyBoolean());
+        mNotificationInfo.setGutsParent(guts);
 
         mNotificationInfo.closeControls(mNotificationInfo);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
new file mode 100644
index 0000000..84dceae
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.systemui.statusbar;
+
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Notification;
+import android.os.RemoteException;
+import android.service.notification.StatusBarNotification;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+@SmallTest
+public class SmartReplyControllerTest extends SysuiTestCase {
+    private static final String TEST_NOTIFICATION_KEY = "akey";
+    private static final String TEST_CHOICE_TEXT = "A Reply";
+    private static final int TEST_CHOICE_INDEX = 2;
+    private static final int TEST_CHOICE_COUNT = 4;
+
+    private Notification mNotification;
+    private NotificationData.Entry mEntry;
+
+    @Mock
+    private NotificationEntryManager mNotificationEntryManager;
+    @Mock
+    private IStatusBarService mIStatusBarService;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mDependency.injectTestDependency(NotificationEntryManager.class,
+                mNotificationEntryManager);
+        mDependency.injectTestDependency(IStatusBarService.class, mIStatusBarService);
+
+        mNotification = new Notification.Builder(mContext, "")
+                .setSmallIcon(R.drawable.ic_person)
+                .setContentTitle("Title")
+                .setContentText("Text").build();
+        StatusBarNotification sbn = mock(StatusBarNotification.class);
+        when(sbn.getNotification()).thenReturn(mNotification);
+        when(sbn.getKey()).thenReturn(TEST_NOTIFICATION_KEY);
+        mEntry = new NotificationData.Entry(sbn);
+    }
+
+    @Test
+    public void testSendSmartReply_updatesRemoteInput() throws RemoteException {
+        StatusBarNotification sbn = mock(StatusBarNotification.class);
+        when(sbn.getKey()).thenReturn(TEST_NOTIFICATION_KEY);
+        when(mNotificationEntryManager.rebuildNotificationWithRemoteInput(
+                argThat(entry -> entry.notification.getKey().equals(TEST_NOTIFICATION_KEY)),
+                eq(TEST_CHOICE_TEXT), eq(true))).thenReturn(sbn);
+
+        SmartReplyController controller = new SmartReplyController();
+        controller.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT);
+
+        // Sending smart reply should make calls to NotificationEntryManager
+        // to update the notification with reply and spinner.
+        verify(mNotificationEntryManager).rebuildNotificationWithRemoteInput(
+                argThat(entry -> entry.notification.getKey().equals(TEST_NOTIFICATION_KEY)),
+                eq(TEST_CHOICE_TEXT), eq(true));
+        verify(mNotificationEntryManager).updateNotification(
+                argThat(sbn2 -> sbn2.getKey().equals(TEST_NOTIFICATION_KEY)), isNull());
+    }
+
+    @Test
+    public void testSendSmartReply_logsToStatusBar() throws RemoteException {
+        StatusBarNotification sbn = mock(StatusBarNotification.class);
+        when(sbn.getKey()).thenReturn(TEST_NOTIFICATION_KEY);
+        when(mNotificationEntryManager.rebuildNotificationWithRemoteInput(
+                argThat(entry -> entry.notification.getKey().equals(TEST_NOTIFICATION_KEY)),
+                eq(TEST_CHOICE_TEXT), eq(true))).thenReturn(sbn);
+
+        SmartReplyController controller = new SmartReplyController();
+        controller.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT);
+
+        // Check we log the result to the status bar service.
+        verify(mIStatusBarService).onNotificationSmartReplySent(TEST_NOTIFICATION_KEY,
+                TEST_CHOICE_INDEX);
+    }
+
+    @Test
+    public void testShowSmartReply_logsToStatusBar() throws RemoteException {
+        SmartReplyController controller = new SmartReplyController();
+        controller.smartRepliesAdded(mEntry, TEST_CHOICE_COUNT);
+
+        // Check we log the result to the status bar service.
+        verify(mIStatusBarService).onNotificationSmartRepliesAdded(TEST_NOTIFICATION_KEY,
+                TEST_CHOICE_COUNT);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconListTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconListTest.java
index 07ac11b..e529e4c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconListTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconListTest.java
@@ -132,7 +132,7 @@
      */
 
     @Test
-    public void testSlot_OrderIsPreserved() {
+    public void testSlot_ViewOrder() {
         Slot testSlot = new Slot("test_name", null);
 
         // no tag bc it defaults to 0
@@ -144,17 +144,18 @@
         int sb3Tag = 2;
         when(sbHolder3.getTag()).thenReturn(sb3Tag);
 
-        ArrayList<StatusBarIconHolder> expected = new ArrayList<>();
-        expected.add(sbHolder1);
-        expected.add(sbHolder2);
-        expected.add(sbHolder3);
-
-
         // Add 3 icons in the same slot, and verify that the list we get is equal to what we gave
-        for (StatusBarIconHolder holder : expected) {
-            testSlot.addHolder(holder);
-        }
-        assertTrue(listsEqual(expected, testSlot.getHolderList()));
+        testSlot.addHolder(sbHolder1);
+        testSlot.addHolder(sbHolder2);
+        testSlot.addHolder(sbHolder3);
+
+        // View order is reverse of the order added
+        ArrayList<StatusBarIconHolder> expected = new ArrayList<>();
+        expected.add(sbHolder3);
+        expected.add(sbHolder2);
+        expected.add(sbHolder1);
+
+        assertTrue(listsEqual(expected, testSlot.getHolderListInViewOrder()));
     }
 
     private boolean listsEqual(List<StatusBarIconHolder> list1, List<StatusBarIconHolder> list2) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
index 550a35d..532019f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
@@ -22,6 +22,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.doze.DozeScreenState;
 import com.android.systemui.statusbar.phone.DozeParameters.IntInOutMatcher;
 
 import org.junit.Assert;
@@ -218,6 +219,15 @@
         verify(dozeParameters.getPowerManager()).setDozeAfterScreenOff(eq(false));
     }
 
+    @Test
+    public void test_getWallpaperAodDuration_when_shouldControlScreenOff() {
+        TestableDozeParameters dozeParameters = new TestableDozeParameters(getContext());
+        dozeParameters.setControlScreenOffAnimation(true);
+        Assert.assertEquals("wallpaper hides faster when controlling screen off",
+                dozeParameters.getWallpaperAodDuration(),
+                DozeScreenState.ENTER_DOZE_HIDE_WALLPAPER_DELAY);
+    }
+
     private class TestableDozeParameters extends DozeParameters {
         private PowerManager mPowerManager;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index d3cb5a6..41cf869 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -78,6 +78,7 @@
 import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.AppOpsListener;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.DndSuppressingNotificationsView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.FooterView;
 import com.android.systemui.statusbar.FooterViewButton;
@@ -103,6 +104,7 @@
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.KeyguardMonitorImpl;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 import org.junit.Before;
@@ -132,6 +134,7 @@
     @Mock private ScrimController mScrimController;
     @Mock private ArrayList<Entry> mNotificationList;
     @Mock private FingerprintUnlockController mFingerprintUnlockController;
+    @Mock private ZenModeController mZenController;
     @Mock private NotificationData mNotificationData;
 
     // Mock dependencies:
@@ -163,6 +166,7 @@
         mDependency.injectTestDependency(NotificationListener.class, mNotificationListener);
         mDependency.injectTestDependency(KeyguardMonitor.class, mock(KeyguardMonitorImpl.class));
         mDependency.injectTestDependency(AppOpsListener.class, mock(AppOpsListener.class));
+        mDependency.injectTestDependency(ZenModeController.class, mZenController);
 
         mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
         mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
@@ -213,7 +217,7 @@
                 mRemoteInputManager, mock(NotificationGroupManager.class),
                 mock(FalsingManager.class), mock(StatusBarWindowManager.class),
                 mock(NotificationIconAreaController.class), mock(DozeScrimController.class),
-                mock(NotificationShelf.class), mLockscreenUserManager,
+                mock(NotificationShelf.class), mLockscreenUserManager, mZenController,
                 mock(CommandQueue.class));
         mStatusBar.mContext = mContext;
         mStatusBar.mComponents = mContext.getComponents();
@@ -443,6 +447,30 @@
     }
 
     @Test
+    public void testPeek_disabledStatusBar() {
+        Notification n = new Notification.Builder(getContext(), "a").build();
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+                UserHandle.of(0), null, 0);
+        NotificationData.Entry entry = new NotificationData.Entry(sbn);
+        mStatusBar.disable(StatusBarManager.DISABLE_EXPAND, 0, false /* animate */);
+
+        assertFalse("The panel shouldn't allow peek while disabled",
+                mStatusBar.shouldPeek(entry, sbn));
+    }
+
+    @Test
+    public void testPeek_disabledNotificationShade() {
+        Notification n = new Notification.Builder(getContext(), "a").build();
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+                UserHandle.of(0), null, 0);
+        NotificationData.Entry entry = new NotificationData.Entry(sbn);
+        mStatusBar.disable(0, StatusBarManager.DISABLE2_NOTIFICATION_SHADE, false /* animate */);
+
+        assertFalse("The panel shouldn't allow peek while notitifcation shade disabled",
+                mStatusBar.shouldPeek(entry, sbn));
+    }
+
+    @Test
     public void testLogHidden() {
         try {
             mStatusBar.handleVisibleToUserChanged(false);
@@ -652,6 +680,60 @@
     }
 
     @Test
+    public void testDNDView_atEnd() {
+        // add footer
+        mStatusBar.reevaluateStyles();
+
+        // add notification
+        ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
+        mStackScroller.addContainerView(row);
+
+        mStatusBar.onUpdateRowStates();
+
+        // move dnd view to end
+        verify(mStackScroller).changeViewPosition(any(FooterView.class), eq(-1 /* end */));
+        verify(mStackScroller).changeViewPosition(any(DndSuppressingNotificationsView.class),
+                eq(-2 /* end */));
+    }
+
+    @Test
+    public void updateEmptyShade_nonNotificationsDndOff() {
+        mStatusBar.setBarStateForTest(StatusBarState.SHADE);
+        when(mNotificationData.getActiveNotifications()).thenReturn(new ArrayList<>());
+        assertEquals(0, mEntryManager.getNotificationData().getActiveNotifications().size());
+
+        mStatusBar.updateEmptyShadeView();
+        verify(mNotificationPanelView).showDndView(false);
+        verify(mNotificationPanelView).showEmptyShadeView(true);
+    }
+
+    @Test
+    public void updateEmptyShade_noNotificationsDndOn() {
+        mStatusBar.setBarStateForTest(StatusBarState.SHADE);
+        when(mNotificationData.getActiveNotifications()).thenReturn(new ArrayList<>());
+        assertEquals(0, mEntryManager.getNotificationData().getActiveNotifications().size());
+        when(mZenController.areNotificationsHiddenInShade()).thenReturn(true);
+
+        mStatusBar.updateEmptyShadeView();
+        verify(mNotificationPanelView).showDndView(true);
+        verify(mNotificationPanelView).showEmptyShadeView(false);
+    }
+
+    @Test
+    public void updateEmptyShade_yesNotificationsDndOff() {
+        mStatusBar.setBarStateForTest(StatusBarState.SHADE);
+        ArrayList<Entry> entries = new ArrayList<>();
+        entries.add(mock(Entry.class));
+        when(mNotificationData.getActiveNotifications()).thenReturn(entries);
+        assertEquals(1, mEntryManager.getNotificationData().getActiveNotifications().size());
+        when(mZenController.areNotificationsHiddenInShade()).thenReturn(false);
+
+        mStatusBar.updateEmptyShadeView();
+        verify(mNotificationPanelView).showDndView(false);
+        verify(mNotificationPanelView).showEmptyShadeView(false);
+    }
+
+    @Test
     public void testSetState_changesIsFullScreenUserSwitcherState() {
         mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
         assertFalse(mStatusBar.isFullScreenUserSwitcherState());
@@ -697,6 +779,7 @@
                 DozeScrimController dozeScrimController,
                 NotificationShelf notificationShelf,
                 NotificationLockscreenUserManager notificationLockscreenUserManager,
+                ZenModeController zenController,
                 CommandQueue commandQueue) {
             mStatusBarKeyguardViewManager = man;
             mUnlockMethodCache = unlock;
@@ -725,6 +808,7 @@
             mDozeScrimController = dozeScrimController;
             mNotificationShelf = notificationShelf;
             mLockscreenUserManager = notificationLockscreenUserManager;
+            mZenController = zenController;
             mCommandQueue = commandQueue;
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
index 54153a7..d246350 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
@@ -16,6 +16,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -162,4 +163,38 @@
             mainLooper.destroy();
         }
     }
+
+    @Test
+    public void testOnServiceConnected_updatesConnectionState() {
+        when(mMockAdapter.getConnectionState()).thenReturn(BluetoothAdapter.STATE_CONNECTING);
+
+        mBluetoothControllerImpl.onServiceConnected();
+
+        assertTrue(mBluetoothControllerImpl.isBluetoothConnecting());
+        assertFalse(mBluetoothControllerImpl.isBluetoothConnected());
+    }
+
+    @Test
+    public void testOnBluetoothStateChange_updatesBluetoothState() {
+        mBluetoothControllerImpl.onBluetoothStateChanged(BluetoothAdapter.STATE_OFF);
+
+        assertEquals(BluetoothAdapter.STATE_OFF, mBluetoothControllerImpl.getBluetoothState());
+
+        mBluetoothControllerImpl.onBluetoothStateChanged(BluetoothAdapter.STATE_ON);
+
+        assertEquals(BluetoothAdapter.STATE_ON, mBluetoothControllerImpl.getBluetoothState());
+    }
+
+    @Test
+    public void testOnBluetoothStateChange_updatesConnectionState() {
+        when(mMockAdapter.getConnectionState()).thenReturn(
+                BluetoothAdapter.STATE_CONNECTING,
+                BluetoothAdapter.STATE_DISCONNECTED);
+
+        mBluetoothControllerImpl.onServiceConnected();
+        mBluetoothControllerImpl.onBluetoothStateChanged(BluetoothAdapter.STATE_OFF);
+
+        assertFalse(mBluetoothControllerImpl.isBluetoothConnecting());
+        assertFalse(mBluetoothControllerImpl.isBluetoothConnected());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index 2bb8106..99c06e6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -23,9 +23,10 @@
 import static junit.framework.Assert.fail;
 
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
+import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.RemoteInput;
 import android.content.Intent;
@@ -44,7 +45,7 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.NotificationData;
-import com.android.systemui.statusbar.SmartReplyLogger;
+import com.android.systemui.statusbar.SmartReplyController;
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
 
 import java.util.concurrent.atomic.AtomicReference;
@@ -64,19 +65,22 @@
     private static final String TEST_ACTION = "com.android.SMART_REPLY_VIEW_ACTION";
 
     private static final String[] TEST_CHOICES = new String[]{"Hello", "What's up?", "I'm here"};
+    private static final String TEST_NOTIFICATION_KEY = "akey";
 
     private static final int WIDTH_SPEC = MeasureSpec.makeMeasureSpec(500, MeasureSpec.EXACTLY);
     private static final int HEIGHT_SPEC = MeasureSpec.makeMeasureSpec(400, MeasureSpec.AT_MOST);
 
     private BlockingQueueIntentReceiver mReceiver;
     private SmartReplyView mView;
+    private View mContainer;
 
     private int mSingleLinePaddingHorizontal;
     private int mDoubleLinePaddingHorizontal;
     private int mSpacing;
 
-    @Mock private SmartReplyLogger mLogger;
+    @Mock private SmartReplyController mLogger;
     private NotificationData.Entry mEntry;
+    private Notification mNotification;
 
     @Before
     public void setUp() {
@@ -86,6 +90,7 @@
         mDependency.get(KeyguardDismissUtil.class).setDismissHandler(
             (action, cancelAction, afterKeyguardGone) -> action.onDismiss());
 
+        mContainer = new View(mContext, null);
         mView = SmartReplyView.inflate(mContext, null);
 
 
@@ -96,9 +101,14 @@
                 R.dimen.smart_reply_button_padding_horizontal_double_line);
         mSpacing = res.getDimensionPixelSize(R.dimen.smart_reply_button_spacing);
 
-        StatusBarNotification notification = mock(StatusBarNotification.class);
-        when(notification.getKey()).thenReturn("akey");
-        mEntry = new NotificationData.Entry(notification);
+        mNotification = new Notification.Builder(mContext, "")
+                .setSmallIcon(R.drawable.ic_person)
+                .setContentTitle("Title")
+                .setContentText("Text").build();
+        StatusBarNotification sbn = mock(StatusBarNotification.class);
+        when(sbn.getNotification()).thenReturn(mNotification);
+        when(sbn.getKey()).thenReturn(TEST_NOTIFICATION_KEY);
+        mEntry = new NotificationData.Entry(sbn);
     }
 
     @After
@@ -155,10 +165,18 @@
     }
 
     @Test
-    public void testSendSmartReply_LoggerCall() {
+    public void testSendSmartReply_controllerCalled() {
         setRepliesFromRemoteInput(TEST_CHOICES);
         mView.getChildAt(2).performClick();
-        verify(mLogger).smartReplySent(mEntry, 2);
+        verify(mLogger).smartReplySent(mEntry, 2, TEST_CHOICES[2]);
+    }
+
+    @Test
+    public void testSendSmartReply_hidesContainer() {
+        mContainer.setVisibility(View.VISIBLE);
+        setRepliesFromRemoteInput(TEST_CHOICES);
+        mView.getChildAt(0).performClick();
+        assertEquals(View.GONE, mContainer.getVisibility());
     }
 
     @Test
@@ -340,7 +358,7 @@
         PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0,
                 new Intent(TEST_ACTION), 0);
         RemoteInput input = new RemoteInput.Builder(TEST_RESULT_KEY).setChoices(choices).build();
-        mView.setRepliesFromRemoteInput(input, pendingIntent, mLogger, mEntry);
+        mView.setRepliesFromRemoteInput(input, pendingIntent, mLogger, mEntry, mContainer);
     }
 
     /** Builds a {@link ViewGroup} whose measures and layout mirror a {@link SmartReplyView}. */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
index eeb4209..3d17ec4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
@@ -18,6 +18,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
@@ -34,6 +35,7 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.TestableDependency;
+import com.android.systemui.statusbar.DndSuppressingNotificationsView;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.FooterView;
 import com.android.systemui.statusbar.NotificationBlockingHelperManager;
@@ -69,6 +71,7 @@
     @Mock private NotificationGroupManager mGroupManager;
     @Mock private ExpandHelper mExpandHelper;
     @Mock private EmptyShadeView mEmptyShadeView;
+    @Mock private DndSuppressingNotificationsView mDndView;
 
     @Before
     @UiThreadTest
@@ -86,6 +89,7 @@
         mStackScroller.setHeadsUpManager(mHeadsUpManager);
         mStackScroller.setGroupManager(mGroupManager);
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
+        mStackScroller.setDndView(mDndView);
 
         // Stub out functionality that isn't necessary to test.
         doNothing().when(mBar)
@@ -120,40 +124,6 @@
     }
 
     @Test
-    public void updateEmptyView_dndSuppressing() {
-        when(mEmptyShadeView.willBeGone()).thenReturn(true);
-        when(mBar.areNotificationsHidden()).thenReturn(true);
-
-        mStackScroller.updateEmptyShadeView(true);
-
-        verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
-    }
-
-    @Test
-    public void updateEmptyView_dndNotSuppressing() {
-        mStackScroller.setEmptyShadeView(mEmptyShadeView);
-        when(mEmptyShadeView.willBeGone()).thenReturn(true);
-        when(mBar.areNotificationsHidden()).thenReturn(false);
-
-        mStackScroller.updateEmptyShadeView(true);
-
-        verify(mEmptyShadeView).setText(R.string.empty_shade_text);
-    }
-
-    @Test
-    public void updateEmptyView_noNotificationsToDndSuppressing() {
-        mStackScroller.setEmptyShadeView(mEmptyShadeView);
-        when(mEmptyShadeView.willBeGone()).thenReturn(true);
-        when(mBar.areNotificationsHidden()).thenReturn(false);
-        mStackScroller.updateEmptyShadeView(true);
-        verify(mEmptyShadeView).setText(R.string.empty_shade_text);
-
-        when(mBar.areNotificationsHidden()).thenReturn(true);
-        mStackScroller.updateEmptyShadeView(true);
-        verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
-    }
-
-    @Test
     @UiThreadTest
     public void testSetExpandedHeight_blockingHelperManagerReceivedCallbacks() {
         mStackScroller.setExpandedHeight(0f);
@@ -173,7 +143,7 @@
 
         mStackScroller.updateFooterView(true, false);
 
-        verify(view).setVisibility(View.VISIBLE);
+        verify(view).performVisibilityAnimation(eq(true), any());
         verify(view).performSecondaryVisibilityAnimation(false);
     }
 
@@ -186,7 +156,7 @@
 
         mStackScroller.updateFooterView(true, true);
 
-        verify(view).setVisibility(View.VISIBLE);
+        verify(view).performVisibilityAnimation(eq(true), any());
         verify(view).performSecondaryVisibilityAnimation(true);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListenerTest.java
new file mode 100644
index 0000000..43942f7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListenerTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.systemui.util.wakelock;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.animation.Animator;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@RunWith(AndroidTestingRunner.class)
+public class KeepAwakeAnimationListenerTest extends SysuiTestCase {
+    @Mock WakeLock mWakeLock;
+    KeepAwakeAnimationListener mKeepAwakeAnimationListener;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        KeepAwakeAnimationListener.sWakeLock = mWakeLock;
+        mKeepAwakeAnimationListener = new KeepAwakeAnimationListener(getContext());
+    }
+
+    @Test
+    public void onAnimationStart_holdsWakeLock() {
+        mKeepAwakeAnimationListener.onAnimationStart((Animator) null);
+        verify(mWakeLock).acquire();
+        verify(mWakeLock, never()).release();
+
+        mKeepAwakeAnimationListener.onAnimationEnd((Animator) null);
+        verify(mWakeLock).release();
+    }
+}
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 5d8a065..0ee6236 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -5717,6 +5717,29 @@
     // OS: P
     SETTINGS_ZEN_NOTIFICATIONS = 1400;
 
+    // An event category for slices.
+    // OPEN: Slice became visible.
+    // CLOSE: Slice became invisible.
+    // ACTION: Slice was tapped.
+    SLICE = 1401;
+
+    // The authority part of the slice URI
+    FIELD_SLICE_AUTHORITY = 1402;
+
+    // The path part of the slice URI
+    FIELD_SLICE_PATH = 1403;
+
+    // The authority part of the subslice URI
+    FIELD_SUBSLICE_AUTHORITY = 1404;
+
+    // The path part of the subslice URI
+    FIELD_SUBSLICE_PATH = 1405;
+
+    // OPEN: DND onboarding activity > don't update button
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_ZEN_ONBOARDING_KEEP_CURRENT_SETTINGS = 1406;
+
     // ---- End P Constants, all P constants go above this line ----
 
     // First Q constant in master goes here:
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 08aa063..7798cf7 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -2232,7 +2232,7 @@
                         }
                         if (service != null) {
                             mFingerprintGestureDispatcher = new FingerprintGestureDispatcher(
-                                    service, mLock);
+                                    service, mContext.getResources(), mLock);
                             break;
                         }
                     }
diff --git a/services/accessibility/java/com/android/server/accessibility/FingerprintGestureDispatcher.java b/services/accessibility/java/com/android/server/accessibility/FingerprintGestureDispatcher.java
index fe787b3..96418aac 100644
--- a/services/accessibility/java/com/android/server/accessibility/FingerprintGestureDispatcher.java
+++ b/services/accessibility/java/com/android/server/accessibility/FingerprintGestureDispatcher.java
@@ -17,6 +17,7 @@
 package com.android.server.accessibility;
 
 import android.accessibilityservice.FingerprintGestureController;
+import android.content.res.Resources;
 import android.hardware.fingerprint.IFingerprintClientActiveCallback;
 import android.hardware.fingerprint.IFingerprintService;
 import android.os.Binder;
@@ -42,6 +43,7 @@
     private final Object mLock;
     private final IFingerprintService mFingerprintService;
     private final Handler mHandler;
+    private final boolean mHardwareSupportsGestures;
 
     // This field is ground truth for whether or not we are registered. Only write to it in handler.
     private boolean mRegisteredReadOnlyExceptInHandler;
@@ -50,8 +52,11 @@
      * @param fingerprintService The system's fingerprint service
      * @param lock A lock to use when managing internal state
      */
-    public FingerprintGestureDispatcher(IFingerprintService fingerprintService, Object lock) {
+    public FingerprintGestureDispatcher(IFingerprintService fingerprintService,
+            Resources resources, Object lock) {
         mFingerprintService = fingerprintService;
+        mHardwareSupportsGestures = resources.getBoolean(
+                com.android.internal.R.bool.config_fingerprintSupportsGestures);
         mLock = lock;
         mHandler = new Handler(this);
     }
@@ -61,9 +66,11 @@
      * @param lock A lock to use when managing internal state
      * @param handler A handler to use internally. Used for testing.
      */
-    public FingerprintGestureDispatcher(IFingerprintService fingerprintService, Object lock,
-            Handler handler) {
+    public FingerprintGestureDispatcher(IFingerprintService fingerprintService,
+            Resources resources, Object lock, Handler handler) {
         mFingerprintService = fingerprintService;
+        mHardwareSupportsGestures = resources.getBoolean(
+                com.android.internal.R.bool.config_fingerprintSupportsGestures);
         mLock = lock;
         mHandler = handler;
     }
@@ -74,6 +81,8 @@
      * @param clientList The list of potential clients.
      */
     public void updateClientList(List<? extends FingerprintGestureClient> clientList) {
+        if (!mHardwareSupportsGestures) return;
+
         synchronized (mLock) {
             mCapturingClients.clear();
             for (int i = 0; i < clientList.size(); i++) {
@@ -96,6 +105,8 @@
 
     @Override
     public void onClientActiveChanged(boolean nonGestureFingerprintClientActive) {
+        if (!mHardwareSupportsGestures) return;
+
         synchronized (mLock) {
             for (int i = 0; i < mCapturingClients.size(); i++) {
                 mCapturingClients.get(i).onFingerprintGestureDetectionActiveChanged(
@@ -105,6 +116,8 @@
     }
 
     public boolean isFingerprintGestureDetectionAvailable() {
+        if (!mHardwareSupportsGestures) return false;
+
         long identity = Binder.clearCallingIdentity();
         try {
             return !mFingerprintService.isClientActive();
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 3253f2e..51c0488 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -219,6 +219,8 @@
                     final String activePackageName = getActiveAutofillServicePackageName();
                     if (packageName.equals(activePackageName)) {
                         removeCachedServiceLocked(getChangingUserId());
+                    } else {
+                        handlePackageUpdateLocked(packageName);
                     }
                 }
             }
@@ -250,6 +252,8 @@
                                 return true;
                             }
                             removeCachedServiceLocked(getChangingUserId());
+                        } else {
+                          handlePackageUpdateLocked(pkg);
                         }
                     }
                 }
@@ -274,6 +278,14 @@
                 }
                 return serviceComponent.getPackageName();
             }
+
+            @GuardedBy("mLock")
+            private void handlePackageUpdateLocked(String packageName) {
+                final int size = mServicesCache.size();
+                for (int i = 0; i < size; i++) {
+                    mServicesCache.valueAt(i).handlePackageUpdateLocked(packageName);
+                }
+            }
         };
 
         // package changes
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 0bb29a7..e582daa 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -626,9 +626,25 @@
     }
 
     @GuardedBy("mLock")
+    void handlePackageUpdateLocked(String packageName) {
+        final ServiceInfo serviceInfo = mFieldClassificationStrategy.getServiceInfo();
+        if (serviceInfo != null && serviceInfo.packageName.equals(packageName)) {
+            resetExtServiceLocked();
+        }
+    }
+
+    @GuardedBy("mLock")
+    void resetExtServiceLocked() {
+        if (sVerbose) Slog.v(TAG, "reset autofill service.");
+        mFieldClassificationStrategy.reset();
+    }
+
+    @GuardedBy("mLock")
     void destroyLocked() {
         if (sVerbose) Slog.v(TAG, "destroyLocked()");
 
+        resetExtServiceLocked();
+
         final int numSessions = mSessions.size();
         final ArraySet<RemoteFillService> remoteFillServices = new ArraySet<>(numSessions);
         for (int i = 0; i < numSessions; i++) {
diff --git a/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java b/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
index da52201..9bec856 100644
--- a/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
+++ b/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
@@ -83,7 +83,7 @@
     }
 
     @Nullable
-    private ServiceInfo getServiceInfo() {
+    ServiceInfo getServiceInfo() {
         final String packageName =
                 mContext.getPackageManager().getServicesSystemSharedLibraryPackageName();
         if (packageName == null) {
@@ -119,6 +119,18 @@
         return name;
     }
 
+    void reset() {
+        synchronized (mLock) {
+            if (mServiceConnection != null) {
+                if (sDebug) Slog.d(TAG, "reset(): unbinding service.");
+                mContext.unbindService(mServiceConnection);
+                mServiceConnection = null;
+            } else {
+                if (sDebug) Slog.d(TAG, "reset(): service is not bound. Do nothing.");
+            }
+        }
+    }
+
     /**
      * Run a command, starting the service connection if necessary.
      */
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 0038e89..bd59ec0 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -2079,7 +2079,8 @@
         }
 
         getUiForShowing().showFillUi(filledId, response, filterText,
-                mService.getServicePackageName(), mComponentName.getPackageName(), this);
+                mService.getServicePackageName(), mComponentName.getPackageName(),
+                mService.getServiceLabel(), mService.getServiceIcon(), this);
 
         synchronized (mLock) {
             if (mUiShownTime == 0) {
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 21a39e4..ee18dc2 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -163,11 +163,14 @@
      * @param filterText text of the view to be filled
      * @param servicePackageName package name of the autofill service filling the activity
      * @param packageName package name of the activity that is filled
+     * @param serviceLabel label of autofill service
+     * @param serviceIcon icon of autofill service
      * @param callback Identifier for the caller
      */
     public void showFillUi(@NonNull AutofillId focusedId, @NonNull FillResponse response,
             @Nullable String filterText, @Nullable String servicePackageName,
-            @NonNull String packageName, @NonNull AutoFillUiCallback callback) {
+            @NonNull String packageName, @NonNull CharSequence serviceLabel,
+            @NonNull Drawable serviceIcon, @NonNull AutoFillUiCallback callback) {
         if (sDebug) {
             final int size = filterText == null ? 0 : filterText.length();
             Slog.d(TAG, "showFillUi(): id=" + focusedId + ", filter=" + size + " chars");
@@ -185,7 +188,7 @@
             }
             hideAllUiThread(callback);
             mFillUi = new FillUi(mContext, response, focusedId,
-                    filterText, mOverlayControl, new FillUi.Callback() {
+                    filterText, mOverlayControl, serviceLabel, serviceIcon, new FillUi.Callback() {
                 @Override
                 public void onResponsePicked(FillResponse response) {
                     log.setType(MetricsEvent.TYPE_DETAIL);
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index d29ca05..1aeb3b9 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -26,6 +26,8 @@
 import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.view.ContextThemeWrapper;
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.pm.PackageManager;
@@ -53,9 +55,11 @@
 import android.widget.Filter;
 import android.widget.Filterable;
 import android.widget.FrameLayout;
+import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.ListView;
 import android.widget.RemoteViews;
+import android.widget.TextView;
 
 import com.android.internal.R;
 import com.android.server.UiThread;
@@ -72,30 +76,10 @@
 final class FillUi {
     private static final String TAG = "FillUi";
 
+    private static final int THEME_ID = com.android.internal.R.style.Theme_DeviceDefault_Autofill;
+
     private static final TypedValue sTempTypedValue = new TypedValue();
 
-    public static final class AutofillFrameLayout extends FrameLayout {
-
-        OnKeyListener mUnhandledListener;
-
-        public AutofillFrameLayout(Context context, AttributeSet attrs) {
-            super(context, attrs);
-        }
-
-        public AutofillFrameLayout(Context context, AttributeSet attrs, @AttrRes int defStyleAttr) {
-            super(context, attrs, defStyleAttr);
-        }
-
-        @Override
-        public boolean dispatchKeyEvent(KeyEvent event) {
-            boolean handled = super.dispatchKeyEvent(event);
-            if (!handled) {
-                handled = mUnhandledListener.onKey(this, event.getKeyCode(), event);
-            }
-            return handled;
-        }
-    }
-
     interface Callback {
         void onResponsePicked(@NonNull FillResponse response);
         void onDatasetPicked(@NonNull Dataset dataset);
@@ -146,51 +130,64 @@
 
     FillUi(@NonNull Context context, @NonNull FillResponse response,
            @NonNull AutofillId focusedViewId, @NonNull @Nullable String filterText,
-           @NonNull OverlayControl overlayControl, @NonNull Callback callback) {
-        mContext = context;
+           @NonNull OverlayControl overlayControl, @NonNull CharSequence serviceLabel,
+           @NonNull Drawable serviceIcon, @NonNull Callback callback) {
         mCallback = callback;
         mFullScreen = isFullScreen(context);
-
-        final LayoutInflater inflater = LayoutInflater.from(context);
+        mContext = new ContextThemeWrapper(context, THEME_ID);
+        final LayoutInflater inflater = LayoutInflater.from(mContext);
 
         final RemoteViews headerPresentation = response.getHeader();
         final RemoteViews footerPresentation = response.getFooter();
         final ViewGroup decor;
-        if (headerPresentation != null || footerPresentation != null) {
-            decor = (ViewGroup) inflater.inflate(
-                    mFullScreen ? R.layout.autofill_dataset_picker_header_footer_fullscreen
-                            : R.layout.autofill_dataset_picker_header_footer, null);
+        if (mFullScreen) {
+            decor = (ViewGroup) inflater.inflate(R.layout.autofill_dataset_picker_fullscreen, null);
+        } else if (headerPresentation != null || footerPresentation != null) {
+            decor = (ViewGroup) inflater.inflate(R.layout.autofill_dataset_picker_header_footer,
+                    null);
         } else {
-            decor = (ViewGroup) inflater.inflate(
-                    mFullScreen ? R.layout.autofill_dataset_picker_fullscreen
-                            : R.layout.autofill_dataset_picker, null);
+            decor = (ViewGroup) inflater.inflate(R.layout.autofill_dataset_picker, null);
+        }
+        final TextView titleView = decor.findViewById(R.id.autofill_dataset_title);
+        if (titleView != null) {
+            titleView.setText(mContext.getString(R.string.autofill_window_title, serviceLabel));
+        }
+        final ImageView iconView = decor.findViewById(R.id.autofill_dataset_icon);
+        if (iconView != null) {
+            iconView.setImageDrawable(serviceIcon);
         }
 
-        // if autofill ui is not fullscreen, send unhandled keyevent to app window.
-        if (!mFullScreen) {
-            if (decor instanceof AutofillFrameLayout) {
-                ((AutofillFrameLayout) decor).mUnhandledListener =
-                        (View view, int keyCode, KeyEvent event) -> {
-                            switch (keyCode) {
-                                case KeyEvent.KEYCODE_BACK:
-                                case KeyEvent.KEYCODE_ESCAPE:
-                                case KeyEvent.KEYCODE_ENTER:
-                                case KeyEvent.KEYCODE_DPAD_CENTER:
-                                case KeyEvent.KEYCODE_DPAD_LEFT:
-                                case KeyEvent.KEYCODE_DPAD_UP:
-                                case KeyEvent.KEYCODE_DPAD_RIGHT:
-                                case KeyEvent.KEYCODE_DPAD_DOWN:
-                                    return false;
-                                default:
-                                    mCallback.dispatchUnhandledKey(event);
-                                    return true;
-                            }
-                        };
-            } else {
-                Slog.wtf(TAG, "Unable to send unhandled key");
+        // In full screen we only initialize size once assuming screen size never changes
+        if (mFullScreen) {
+            final Point outPoint = mTempPoint;
+            mContext.getDisplay().getSize(outPoint);
+            // full with of screen and half height of screen
+            mContentWidth = LayoutParams.MATCH_PARENT;
+            mContentHeight = outPoint.y / 2;
+            if (sVerbose) {
+                Slog.v(TAG, "initialized fillscreen LayoutParams "
+                        + mContentWidth + "," + mContentHeight);
             }
         }
 
+        // Send unhandled keyevent to app window.
+        decor.addOnUnhandledKeyEventListener((View view, KeyEvent event) -> {
+            switch (event.getKeyCode() ) {
+                case KeyEvent.KEYCODE_BACK:
+                case KeyEvent.KEYCODE_ESCAPE:
+                case KeyEvent.KEYCODE_ENTER:
+                case KeyEvent.KEYCODE_DPAD_CENTER:
+                case KeyEvent.KEYCODE_DPAD_LEFT:
+                case KeyEvent.KEYCODE_DPAD_UP:
+                case KeyEvent.KEYCODE_DPAD_RIGHT:
+                case KeyEvent.KEYCODE_DPAD_DOWN:
+                    return false;
+                default:
+                    mCallback.dispatchUnhandledKey(event);
+                    return true;
+            }
+        });
+
         if (sVisibleDatasetsMaxCount > 0) {
             mVisibleDatasetsMaxCount = sVisibleDatasetsMaxCount;
             if (sVerbose) {
@@ -218,14 +215,12 @@
             mFooter = null;
             mAdapter = null;
 
-            // insert authentication item under autofill_dataset_container or decor
-            ViewGroup container = decor.findViewById(R.id.autofill_dataset_container);
-            if (container == null) {
-                container = decor;
-            }
+            // insert authentication item under autofill_dataset_picker
+            ViewGroup container = decor.findViewById(R.id.autofill_dataset_picker);
             final View content;
             try {
-                content = response.getPresentation().apply(context, decor, interceptionHandler);
+                response.getPresentation().setApplyTheme(THEME_ID);
+                content = response.getPresentation().apply(mContext, decor, interceptionHandler);
                 container.addView(content);
             } catch (RuntimeException e) {
                 callback.onCanceled();
@@ -236,20 +231,22 @@
             decor.setFocusable(true);
             decor.setOnClickListener(v -> mCallback.onResponsePicked(response));
 
-            final Point maxSize = mTempPoint;
-            resolveMaxWindowSize(context, maxSize);
-            // fullScreen mode occupy the full width defined by autofill_dataset_picker_max_width
-            content.getLayoutParams().width = mFullScreen ? maxSize.x
-                    : ViewGroup.LayoutParams.WRAP_CONTENT;
-            content.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
-            final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxSize.x,
-                    MeasureSpec.AT_MOST);
-            final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxSize.y,
-                    MeasureSpec.AT_MOST);
+            if (!mFullScreen) {
+                final Point maxSize = mTempPoint;
+                resolveMaxWindowSize(mContext, maxSize);
+                // fullScreen mode occupy the full width defined by autofill_dataset_picker_max_width
+                content.getLayoutParams().width = mFullScreen ? maxSize.x
+                        : ViewGroup.LayoutParams.WRAP_CONTENT;
+                content.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
+                final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxSize.x,
+                        MeasureSpec.AT_MOST);
+                final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxSize.y,
+                        MeasureSpec.AT_MOST);
 
-            decor.measure(widthMeasureSpec, heightMeasureSpec);
-            mContentWidth = content.getMeasuredWidth();
-            mContentHeight = content.getMeasuredHeight();
+                decor.measure(widthMeasureSpec, heightMeasureSpec);
+                mContentWidth = content.getMeasuredWidth();
+                mContentHeight = content.getMeasuredHeight();
+            }
 
             mWindow = new AnchoredWindow(decor, overlayControl);
             requestShowFillUi();
@@ -263,7 +260,8 @@
             RemoteViews.OnClickHandler clickBlocker = null;
             if (headerPresentation != null) {
                 clickBlocker = newClickBlocker();
-                mHeader = headerPresentation.apply(context, null, clickBlocker);
+                headerPresentation.setApplyTheme(THEME_ID);
+                mHeader = headerPresentation.apply(mContext, null, clickBlocker);
                 final LinearLayout headerContainer =
                         decor.findViewById(R.id.autofill_dataset_header);
                 if (sVerbose) Slog.v(TAG, "adding header");
@@ -274,15 +272,21 @@
             }
 
             if (footerPresentation != null) {
-                if (clickBlocker == null) { // already set for header
-                    clickBlocker = newClickBlocker();
-                }
-                mFooter = footerPresentation.apply(context, null, clickBlocker);
                 final LinearLayout footerContainer =
                         decor.findViewById(R.id.autofill_dataset_footer);
-                if (sVerbose) Slog.v(TAG, "adding footer");
-                footerContainer.addView(mFooter);
-                footerContainer.setVisibility(View.VISIBLE);
+                if (footerContainer != null) {
+                    if (clickBlocker == null) { // already set for header
+                        clickBlocker = newClickBlocker();
+                    }
+                    footerPresentation.setApplyTheme(THEME_ID);
+                    mFooter = footerPresentation.apply(mContext, null, clickBlocker);
+                    // Footer not supported on some platform e.g. TV
+                    if (sVerbose) Slog.v(TAG, "adding footer");
+                    footerContainer.addView(mFooter);
+                    footerContainer.setVisibility(View.VISIBLE);
+                } else {
+                    mFooter = null;
+                }
             } else {
                 mFooter = null;
             }
@@ -301,7 +305,8 @@
                     final View view;
                     try {
                         if (sVerbose) Slog.v(TAG, "setting remote view for " + focusedViewId);
-                        view = presentation.apply(context, null, interceptionHandler);
+                        presentation.setApplyTheme(THEME_ID);
+                        view = presentation.apply(mContext, null, interceptionHandler);
                     } catch (RuntimeException e) {
                         Slog.e(TAG, "Error inflating remote views", e);
                         continue;
@@ -352,12 +357,7 @@
     }
 
     void requestShowFillUi() {
-        if (mFullScreen) {
-            mCallback.requestShowFillUi(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
-                    mWindowPresenter);
-        } else {
-            mCallback.requestShowFillUi(mContentWidth, mContentHeight, mWindowPresenter);
-        }
+        mCallback.requestShowFillUi(mContentWidth, mContentHeight, mWindowPresenter);
     }
 
     /**
@@ -388,12 +388,6 @@
                 mCallback.requestHideFillUi();
             } else {
                 if (updateContentSize()) {
-                    if (mFullScreen) {
-                        LayoutParams lp = mListView.getLayoutParams();
-                        lp.width = mContentWidth;
-                        lp.height = mContentHeight;
-                        mListView.setLayoutParams(lp);
-                    }
                     requestShowFillUi();
                 }
                 if (mAdapter.getCount() > mVisibleDatasetsMaxCount) {
@@ -452,6 +446,10 @@
         if (mAdapter == null) {
             return false;
         }
+        if (mFullScreen) {
+            // always request show fill window with fixed size for fullscreen
+            return true;
+        }
         boolean changed = false;
         if (mAdapter.getCount() <= 0) {
             if (mContentWidth != 0) {
@@ -476,11 +474,6 @@
         final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxSize.y,
                 MeasureSpec.AT_MOST);
         final int itemCount = mAdapter.getCount();
-        if (mFullScreen) {
-            // fullScreen mode occupy the full width defined by autofill_dataset_picker_max_width
-            changed = true;
-            mContentWidth = maxSize.x;
-        }
 
         if (mHeader != null) {
             mHeader.measure(widthMeasureSpec, heightMeasureSpec);
@@ -491,20 +484,9 @@
         for (int i = 0; i < itemCount; i++) {
             final View view = mAdapter.getItem(i).view;
             view.measure(widthMeasureSpec, heightMeasureSpec);
-            if (mFullScreen) {
-                // for fullscreen, add up all children height until hit max height.
-                final int newContentHeight = mContentHeight + view.getMeasuredHeight();
-                final int clampedNewHeight = Math.min(newContentHeight, maxSize.y);
-                if (clampedNewHeight != mContentHeight) {
-                    mContentHeight = clampedNewHeight;
-                } else if (view.getMeasuredHeight() > 0) {
-                    break;
-                }
-            } else {
-                changed |= updateWidth(view, maxSize);
-                if (i < mVisibleDatasetsMaxCount) {
-                    changed |= updateHeight(view, maxSize);
-                }
+            changed |= updateWidth(view, maxSize);
+            if (i < mVisibleDatasetsMaxCount) {
+                changed |= updateHeight(view, maxSize);
             }
         }
 
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index f96fa7c2..80903c1 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -42,6 +42,7 @@
 import android.util.ArraySet;
 import android.util.Pair;
 import android.util.Slog;
+import android.view.ContextThemeWrapper;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -70,6 +71,9 @@
 
     private static final String TAG = "AutofillSaveUi";
 
+    private static final int THEME_ID =
+            com.android.internal.R.style.Theme_DeviceDefault_Autofill_Save;
+
     public interface OnSaveListener {
         void onSave();
         void onCancel(IntentSender listener);
@@ -144,6 +148,7 @@
         mServicePackageName = servicePackageName;
         mPackageName = packageName;
 
+        context = new ContextThemeWrapper(context, THEME_ID);
         final LayoutInflater inflater = LayoutInflater.from(context);
         final View view = inflater.inflate(R.layout.autofill_save, null);
 
@@ -222,7 +227,7 @@
         final View yesButton = view.findViewById(R.id.autofill_save_yes);
         yesButton.setOnClickListener((v) -> mListener.onSave());
 
-        mDialog = new Dialog(context, R.style.Theme_DeviceDefault_Light_Panel);
+        mDialog = new Dialog(context, THEME_ID);
         mDialog.setContentView(view);
 
         // Dialog can be dismissed when touched outside, but the negative listener should not be
@@ -309,6 +314,7 @@
 
         try {
             // Create the remote view peer.
+            template.setApplyTheme(THEME_ID);
             final View customSubtitleView = template.apply(context, null, handler);
 
             // And apply batch updates (if any).
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
index 821cca1..44edabc 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java
@@ -421,7 +421,7 @@
 
                 // after the app's agent runs to handle its private filesystem
                 // contents, back up any OBB content it has on its behalf.
-                if (mIncludeObbs) {
+                if (mIncludeObbs && !isSharedStorage) {
                     boolean obbOkay = obbConnection.backupObbs(pkg, out);
                     if (!obbOkay) {
                         throw new RuntimeException("Failure writing OBB stack for " + pkg);
diff --git a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
index 90baea0..1f2d898 100644
--- a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
+++ b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
@@ -269,7 +269,6 @@
         if (mOriginalQueue.isEmpty() && mPendingFullBackups.isEmpty()) {
             Slog.w(TAG, "Backup begun with an empty queue - nothing to do.");
             backupManagerService.addBackupTrace("queue empty at begin");
-            BackupObserverUtils.sendBackupFinished(mObserver, BackupManager.SUCCESS);
             executeNextState(BackupState.FINAL);
             return;
         }
@@ -349,8 +348,6 @@
                 // restage everything and try again later.
                 backupManagerService.resetBackupState(mStateDir);  // Just to make sure.
                 // In case of any other error, it's backup transport error.
-                BackupObserverUtils.sendBackupFinished(mObserver,
-                        BackupManager.ERROR_TRANSPORT_ABORTED);
                 executeNextState(BackupState.FINAL);
             }
         }
@@ -384,21 +381,11 @@
                 // if things went wrong at this point, we need to
                 // restage everything and try again later.
                 backupManagerService.resetBackupState(mStateDir);  // Just to make sure.
-                BackupObserverUtils.sendBackupFinished(mObserver,
-                        invokeAgentToObserverError(mStatus));
                 executeNextState(BackupState.FINAL);
             }
         }
     }
 
-    private int invokeAgentToObserverError(int error) {
-        if (error == BackupTransport.AGENT_ERROR) {
-            return BackupManager.ERROR_AGENT_FAILURE;
-        } else {
-            return BackupManager.ERROR_TRANSPORT_ABORTED;
-        }
-    }
-
     // Transport has been initialized and the PM metadata submitted successfully
     // if that was warranted.  Now we process the single next thing in the queue.
     private void invokeNextAgent() {
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index b860191..d818bd6 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -39,6 +39,7 @@
 import android.os.ServiceManager;
 import android.os.ShellCallback;
 import android.os.ShellCommand;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageManagerInternal;
@@ -77,14 +78,24 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import static android.app.AppOpsManager.UID_STATE_BACKGROUND;
+import static android.app.AppOpsManager.UID_STATE_CACHED;
+import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
+import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
+import static android.app.AppOpsManager._NUM_UID_STATE;
+import static android.app.AppOpsManager.UID_STATE_PERSISTENT;
+import static android.app.AppOpsManager.UID_STATE_TOP;
+
 public class AppOpsService extends IAppOpsService.Stub {
     static final String TAG = "AppOps";
     static final boolean DEBUG = false;
@@ -100,6 +111,64 @@
     // Constant meaning that any UID should be matched when dispatching callbacks
     private static final int UID_ANY = -2;
 
+    // Map from process states to the uid states we track.
+    private static final int[] PROCESS_STATE_TO_UID_STATE = new int[] {
+        UID_STATE_PERSISTENT,           // ActivityManager.PROCESS_STATE_PERSISTENT
+        UID_STATE_PERSISTENT,           // ActivityManager.PROCESS_STATE_PERSISTENT_UI
+        UID_STATE_TOP,                  // ActivityManager.PROCESS_STATE_TOP
+        UID_STATE_FOREGROUND_SERVICE,   // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
+        UID_STATE_FOREGROUND,           // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
+        UID_STATE_FOREGROUND,           // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
+        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
+        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_BACKUP
+        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_SERVICE
+        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_RECEIVER
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_TOP_SLEEPING
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_HOME
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_CACHED_RECENT
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_CACHED_EMPTY
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_NONEXISTENT
+    };
+
+    static final String[] UID_STATE_NAMES = new String[] {
+            "pers ",    // UID_STATE_PERSISTENT
+            "top  ",    // UID_STATE_TOP
+            "fgsvc",    // UID_STATE_FOREGROUND_SERVICE
+            "fg   ",    // UID_STATE_FOREGROUND
+            "bg   ",    // UID_STATE_BACKGROUND
+            "cch  ",    // UID_STATE_CACHED
+    };
+
+    static final String[] UID_STATE_TIME_ATTRS = new String[] {
+            "tp",       // UID_STATE_PERSISTENT
+            "tt",       // UID_STATE_TOP
+            "tfs",      // UID_STATE_FOREGROUND_SERVICE
+            "tf",       // UID_STATE_FOREGROUND
+            "tb",       // UID_STATE_BACKGROUND
+            "tc",       // UID_STATE_CACHED
+    };
+
+    static final String[] UID_STATE_REJECT_ATTRS = new String[] {
+            "rp",       // UID_STATE_PERSISTENT
+            "rt",       // UID_STATE_TOP
+            "rfs",      // UID_STATE_FOREGROUND_SERVICE
+            "rf",       // UID_STATE_FOREGROUND
+            "rb",       // UID_STATE_BACKGROUND
+            "rc",       // UID_STATE_CACHED
+    };
+
+    static final String[] MODE_NAMES = new String[] {
+            "allow",        // MODE_ALLOWED
+            "ignore",       // MODE_IGNORED
+            "deny",         // MODE_ERRORED
+            "default",      // MODE_DEFAULT
+    };
+
     Context mContext;
     final AtomicFile mFile;
     final Handler mHandler;
@@ -133,6 +202,8 @@
     @VisibleForTesting
     static final class UidState {
         public final int uid;
+        public int state = UID_STATE_CACHED;
+        public int startNesting;
         public ArrayMap<String, Ops> pkgOps;
         public SparseIntArray opModes;
 
@@ -151,36 +222,51 @@
         }
     }
 
-    public final static class Ops extends SparseArray<Op> {
-        public final String packageName;
-        public final UidState uidState;
-        public final boolean isPrivileged;
+    final static class Ops extends SparseArray<Op> {
+        final String packageName;
+        final UidState uidState;
+        final boolean isPrivileged;
 
-        public Ops(String _packageName, UidState _uidState, boolean _isPrivileged) {
+        Ops(String _packageName, UidState _uidState, boolean _isPrivileged) {
             packageName = _packageName;
             uidState = _uidState;
             isPrivileged = _isPrivileged;
         }
     }
 
-    public final static class Op {
-        public final int uid;
-        public final String packageName;
-        public int proxyUid = -1;
-        public String proxyPackageName;
-        public final int op;
-        public int mode;
-        public int duration;
-        public long time;
-        public long rejectTime;
-        public int nesting;
+    final static class Op {
+        final UidState uidState;
+        final int uid;
+        final String packageName;
+        final int op;
+        int proxyUid = -1;
+        String proxyPackageName;
+        int mode;
+        int duration;
+        long time[] = new long[_NUM_UID_STATE];
+        long rejectTime[] = new long[_NUM_UID_STATE];
+        int startNesting;
+        long startRealtime;
 
-        public Op(int _uid, String _packageName, int _op) {
-            uid = _uid;
+        Op(UidState _uidState, String _packageName, int _op) {
+            uidState = _uidState;
+            uid = _uidState.uid;
             packageName = _packageName;
             op = _op;
             mode = AppOpsManager.opToDefaultMode(op);
         }
+
+        boolean hasAnyTime() {
+            for (int i = 0; i < AppOpsManager._NUM_UID_STATE; i++) {
+                if (time[i] != 0) {
+                    return true;
+                }
+                if (rejectTime[i] != 0) {
+                    return true;
+                }
+            }
+            return false;
+        }
     }
 
     final SparseArray<ArraySet<ModeCallback>> mOpModeWatchers = new SparseArray<>();
@@ -189,13 +275,13 @@
     final ArrayMap<IBinder, SparseArray<ActiveCallback>> mActiveWatchers = new ArrayMap<>();
     final SparseArray<SparseArray<Restriction>> mAudioRestrictions = new SparseArray<>();
 
-    public final class ModeCallback implements DeathRecipient {
+    final class ModeCallback implements DeathRecipient {
         final IAppOpsCallback mCallback;
         final int mWatchingUid;
         final int mCallingUid;
         final int mCallingPid;
 
-        public ModeCallback(IAppOpsCallback callback, int watchingUid, int callingUid,
+        ModeCallback(IAppOpsCallback callback, int watchingUid, int callingUid,
                 int callingPid) {
             mCallback = callback;
             mWatchingUid = watchingUid;
@@ -222,7 +308,7 @@
             return sb.toString();
         }
 
-        public void unlinkToDeath() {
+        void unlinkToDeath() {
             mCallback.asBinder().unlinkToDeath(this, 0);
         }
 
@@ -232,13 +318,13 @@
         }
     }
 
-    public final class ActiveCallback implements DeathRecipient {
+    final class ActiveCallback implements DeathRecipient {
         final IAppOpsActiveCallback mCallback;
         final int mWatchingUid;
         final int mCallingUid;
         final int mCallingPid;
 
-        public ActiveCallback(IAppOpsActiveCallback callback, int watchingUid, int callingUid,
+        ActiveCallback(IAppOpsActiveCallback callback, int watchingUid, int callingUid,
                 int callingPid) {
             mCallback = callback;
             mWatchingUid = watchingUid;
@@ -265,7 +351,7 @@
             return sb.toString();
         }
 
-        public void destroy() {
+        void destroy() {
             mCallback.asBinder().unlinkToDeath(this, 0);
         }
 
@@ -277,12 +363,12 @@
 
     final ArrayMap<IBinder, ClientState> mClients = new ArrayMap<>();
 
-    public final class ClientState extends Binder implements DeathRecipient {
+    final class ClientState extends Binder implements DeathRecipient {
         final ArrayList<Op> mStartedOps = new ArrayList<>();
         final IBinder mAppToken;
         final int mPid;
 
-        public ClientState(IBinder appToken) {
+        ClientState(IBinder appToken) {
             mAppToken = appToken;
             mPid = Binder.getCallingPid();
             // Watch only for remote processes dying
@@ -453,7 +539,7 @@
                     if (uid == op.uid && packageName.equals(op.packageName)) {
                         finishOperationLocked(op, /*finishNested*/ true);
                         client.mStartedOps.remove(j);
-                        if (op.nesting <= 0) {
+                        if (op.startNesting <= 0) {
                             scheduleOpActiveChangedIfNeededLocked(op.op,
                                     uid, packageName, false);
                         }
@@ -485,6 +571,31 @@
         }
     }
 
+    public void updateUidProcState(int uid, int procState) {
+        synchronized (this) {
+            final UidState uidState = getUidStateLocked(uid, true);
+            final int newState = PROCESS_STATE_TO_UID_STATE[procState];
+            if (uidState != null && uidState.state != newState) {
+                if (uidState.startNesting != 0) {
+                    // There is some actively running operation...  need to find it
+                    // and appropriately update its state.
+                    final long now = System.currentTimeMillis();
+                    for (int i = uidState.pkgOps.size() - 1; i >= 0; i--) {
+                        final Ops ops = uidState.pkgOps.valueAt(i);
+                        for (int j = ops.size() - 1; j >= 0; j--) {
+                            final Op op = ops.valueAt(j);
+                            if (op.startNesting > 0) {
+                                op.time[uidState.state] = now;
+                                op.time[newState] = now;
+                            }
+                        }
+                    }
+                }
+                uidState.state = newState;
+            }
+        }
+    }
+
     public void shutdown() {
         Slog.w(TAG, "Writing app ops before shutdown...");
         boolean doWrite = false;
@@ -501,12 +612,16 @@
 
     private ArrayList<AppOpsManager.OpEntry> collectOps(Ops pkgOps, int[] ops) {
         ArrayList<AppOpsManager.OpEntry> resOps = null;
+        final long elapsedNow = SystemClock.elapsedRealtime();
         if (ops == null) {
-            resOps = new ArrayList<AppOpsManager.OpEntry>();
+            resOps = new ArrayList<>();
             for (int j=0; j<pkgOps.size(); j++) {
                 Op curOp = pkgOps.valueAt(j);
+                long duration = curOp.duration == -1
+                        ? (elapsedNow - curOp.startRealtime)
+                        : curOp.duration;
                 resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
-                        curOp.rejectTime, curOp.duration, curOp.proxyUid,
+                        curOp.rejectTime, (int) duration, curOp.proxyUid,
                         curOp.proxyPackageName));
             }
         } else {
@@ -514,10 +629,13 @@
                 Op curOp = pkgOps.get(ops[j]);
                 if (curOp != null) {
                     if (resOps == null) {
-                        resOps = new ArrayList<AppOpsManager.OpEntry>();
+                        resOps = new ArrayList<>();
                     }
+                    long duration = curOp.duration == -1
+                            ? (elapsedNow - curOp.startRealtime)
+                            : curOp.duration;
                     resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
-                            curOp.rejectTime, curOp.duration, curOp.proxyUid,
+                            curOp.rejectTime, (int) duration, curOp.proxyUid,
                             curOp.proxyPackageName));
                 }
             }
@@ -628,7 +746,7 @@
     }
 
     private void pruneOp(Op op, int uid, String packageName) {
-        if (op.time == 0 && op.rejectTime == 0) {
+        if (!op.hasAnyTime()) {
             Ops ops = getOpsRawLocked(uid, packageName, false /* edit */,
                     false /* uidMismatchExpected */);
             if (ops != null) {
@@ -946,7 +1064,7 @@
                                     mOpModeWatchers.get(curOp.op));
                             callbacks = addCallbacks(callbacks, curOp.op, curOp.uid, packageName,
                                     mPackageModeWatchers.get(packageName));
-                            if (curOp.time == 0 && curOp.rejectTime == 0) {
+                            if (!curOp.hasAnyTime()) {
                                 pkgOps.removeAt(j);
                             }
                         }
@@ -1212,24 +1330,25 @@
     private int noteOperationUnchecked(int code, int uid, String packageName,
             int proxyUid, String proxyPackageName) {
         synchronized (this) {
-            Ops ops = getOpsRawLocked(uid, packageName, true /* edit */,
+            final Ops ops = getOpsRawLocked(uid, packageName, true /* edit */,
                     false /* uidMismatchExpected */);
             if (ops == null) {
                 if (DEBUG) Slog.d(TAG, "noteOperation: no op for code " + code + " uid " + uid
                         + " package " + packageName);
                 return AppOpsManager.MODE_ERRORED;
             }
-            Op op = getOpLocked(ops, code, true);
+            final Op op = getOpLocked(ops, code, true);
             if (isOpRestrictedLocked(uid, code, packageName)) {
                 return AppOpsManager.MODE_IGNORED;
             }
+            final UidState uidState = ops.uidState;
             if (op.duration == -1) {
                 Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName
-                        + " code " + code + " time=" + op.time + " duration=" + op.duration);
+                        + " code " + code + " time=" + op.time[uidState.state]
+                        + " duration=" + op.duration);
             }
             op.duration = 0;
             final int switchCode = AppOpsManager.opToSwitch(code);
-            UidState uidState = ops.uidState;
             // If there is a non-default per UID policy (we set UID op mode only if
             // non-default) it takes over, otherwise use the per package policy.
             if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) {
@@ -1238,7 +1357,7 @@
                     if (DEBUG) Slog.d(TAG, "noteOperation: reject #" + op.mode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
                             + packageName);
-                    op.rejectTime = System.currentTimeMillis();
+                    op.rejectTime[uidState.state] = System.currentTimeMillis();
                     return uidMode;
                 }
             } else {
@@ -1247,14 +1366,14 @@
                     if (DEBUG) Slog.d(TAG, "noteOperation: reject #" + op.mode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
                             + packageName);
-                    op.rejectTime = System.currentTimeMillis();
+                    op.rejectTime[uidState.state] = System.currentTimeMillis();
                     return switchOp.mode;
                 }
             }
             if (DEBUG) Slog.d(TAG, "noteOperation: allowing code " + code + " uid " + uid
                     + " package " + packageName);
-            op.time = System.currentTimeMillis();
-            op.rejectTime = 0;
+            op.time[uidState.state] = System.currentTimeMillis();
+            op.rejectTime[uidState.state] = 0;
             op.proxyUid = proxyUid;
             op.proxyPackageName = proxyPackageName;
             return AppOpsManager.MODE_ALLOWED;
@@ -1323,19 +1442,19 @@
         }
         ClientState client = (ClientState)token;
         synchronized (this) {
-            Ops ops = getOpsRawLocked(uid, resolvedPackageName, true /* edit */,
+            final Ops ops = getOpsRawLocked(uid, resolvedPackageName, true /* edit */,
                     false /* uidMismatchExpected */);
             if (ops == null) {
                 if (DEBUG) Slog.d(TAG, "startOperation: no op for code " + code + " uid " + uid
                         + " package " + resolvedPackageName);
                 return AppOpsManager.MODE_ERRORED;
             }
-            Op op = getOpLocked(ops, code, true);
+            final Op op = getOpLocked(ops, code, true);
             if (isOpRestrictedLocked(uid, code, resolvedPackageName)) {
                 return AppOpsManager.MODE_IGNORED;
             }
             final int switchCode = AppOpsManager.opToSwitch(code);
-            UidState uidState = ops.uidState;
+            final UidState uidState = ops.uidState;
             // If there is a non-default per UID policy (we set UID op mode only if
             // non-default) it takes over, otherwise use the per package policy.
             if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) {
@@ -1345,7 +1464,7 @@
                     if (DEBUG) Slog.d(TAG, "noteOperation: reject #" + op.mode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
                             + resolvedPackageName);
-                    op.rejectTime = System.currentTimeMillis();
+                    op.rejectTime[uidState.state] = System.currentTimeMillis();
                     return uidMode;
                 }
             } else {
@@ -1355,19 +1474,21 @@
                     if (DEBUG) Slog.d(TAG, "startOperation: reject #" + op.mode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
                             + resolvedPackageName);
-                    op.rejectTime = System.currentTimeMillis();
+                    op.rejectTime[uidState.state] = System.currentTimeMillis();
                     return switchOp.mode;
                 }
             }
             if (DEBUG) Slog.d(TAG, "startOperation: allowing code " + code + " uid " + uid
                     + " package " + resolvedPackageName);
-            if (op.nesting == 0) {
-                op.time = System.currentTimeMillis();
-                op.rejectTime = 0;
+            if (op.startNesting == 0) {
+                op.startRealtime = SystemClock.elapsedRealtime();
+                op.time[uidState.state] = System.currentTimeMillis();
+                op.rejectTime[uidState.state] = 0;
                 op.duration = -1;
                 scheduleOpActiveChangedIfNeededLocked(code, uid, packageName, true);
             }
-            op.nesting++;
+            op.startNesting++;
+            uidState.startNesting++;
             if (client.mStartedOps != null) {
                 client.mStartedOps.add(op);
             }
@@ -1415,7 +1536,7 @@
                 return;
             }
             finishOperationLocked(op, /*finishNested*/ false);
-            if (op.nesting <= 0) {
+            if (op.startNesting <= 0) {
                 scheduleOpActiveChangedIfNeededLocked(code, uid, packageName, false);
             }
         }
@@ -1476,18 +1597,22 @@
     }
 
     void finishOperationLocked(Op op, boolean finishNested) {
-        if (op.nesting <= 1 || finishNested) {
-            if (op.nesting == 1 || finishNested) {
-                op.duration = (int)(System.currentTimeMillis() - op.time);
-                op.time += op.duration;
+        if (op.startNesting <= 1 || finishNested) {
+            if (op.startNesting == 1 || finishNested) {
+                op.duration = (int)(SystemClock.elapsedRealtime() - op.startRealtime);
+                op.time[op.uidState.state] = System.currentTimeMillis();
             } else {
                 Slog.w(TAG, "Finishing op nesting under-run: uid " + op.uid + " pkg "
                         + op.packageName + " code " + op.op + " time=" + op.time
-                        + " duration=" + op.duration + " nesting=" + op.nesting);
+                        + " duration=" + op.duration + " nesting=" + op.startNesting);
             }
-            op.nesting = 0;
+            if (op.startNesting >= 1) {
+                op.uidState.startNesting -= op.startNesting;
+            }
+            op.startNesting = 0;
         } else {
-            op.nesting--;
+            op.startNesting--;
+            op.uidState.startNesting--;
         }
     }
 
@@ -1617,7 +1742,7 @@
             if (!edit) {
                 return null;
             }
-            op = new Op(ops.uidState.uid, ops.packageName, code);
+            op = new Op(ops.uidState, ops.packageName, code);
             ops.put(code, op);
         }
         if (edit) {
@@ -1750,7 +1875,7 @@
                 if (ops != null) {
                     final Op op = ops.get(AppOpsManager.OP_RUN_IN_BACKGROUND);
                     if (op != null && op.mode != AppOpsManager.opToDefaultMode(op.op)) {
-                        final Op copy = new Op(op.uid, op.packageName,
+                        final Op copy = new Op(op.uidState, op.packageName,
                                 AppOpsManager.OP_RUN_ANY_IN_BACKGROUND);
                         copy.mode = op.mode;
                         ops.put(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, copy);
@@ -1860,37 +1985,86 @@
 
             String tagName = parser.getName();
             if (tagName.equals("op")) {
-                Op op = new Op(uid, pkgName, Integer.parseInt(parser.getAttributeValue(null, "n")));
-                String mode = parser.getAttributeValue(null, "m");
-                if (mode != null) {
-                    op.mode = Integer.parseInt(mode);
-                }
-                String time = parser.getAttributeValue(null, "t");
-                if (time != null) {
-                    op.time = Long.parseLong(time);
-                }
-                time = parser.getAttributeValue(null, "r");
-                if (time != null) {
-                    op.rejectTime = Long.parseLong(time);
-                }
-                String dur = parser.getAttributeValue(null, "d");
-                if (dur != null) {
-                    op.duration = Integer.parseInt(dur);
-                }
-                String proxyUid = parser.getAttributeValue(null, "pu");
-                if (proxyUid != null) {
-                    op.proxyUid = Integer.parseInt(proxyUid);
-                }
-                String proxyPackageName = parser.getAttributeValue(null, "pp");
-                if (proxyPackageName != null) {
-                    op.proxyPackageName = proxyPackageName;
-                }
-
                 UidState uidState = getUidStateLocked(uid, true);
                 if (uidState.pkgOps == null) {
                     uidState.pkgOps = new ArrayMap<>();
                 }
 
+                Op op = new Op(uidState, pkgName,
+                        Integer.parseInt(parser.getAttributeValue(null, "n")));
+
+                for (int i = parser.getAttributeCount()-1; i >= 0; i--) {
+                    final String name = parser.getAttributeName(i);
+                    final String value = parser.getAttributeValue(i);
+                    switch (name) {
+                        case "m":
+                            op.mode = Integer.parseInt(value);
+                            break;
+                        case "d":
+                            op.duration = Integer.parseInt(value);
+                            break;
+                        case "pu":
+                            op.proxyUid = Integer.parseInt(value);
+                            break;
+                        case "pp":
+                            op.proxyPackageName = value;
+                            break;
+                        case "tp":
+                            op.time[AppOpsManager.UID_STATE_PERSISTENT] = Long.parseLong(value);
+                            break;
+                        case "tt":
+                            op.time[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value);
+                            break;
+                        case "tfs":
+                            op.time[AppOpsManager.UID_STATE_FOREGROUND_SERVICE]
+                                    = Long.parseLong(value);
+                            break;
+                        case "tf":
+                            op.time[AppOpsManager.UID_STATE_FOREGROUND] = Long.parseLong(value);
+                            break;
+                        case "tb":
+                            op.time[AppOpsManager.UID_STATE_BACKGROUND] = Long.parseLong(value);
+                            break;
+                        case "tc":
+                            op.time[AppOpsManager.UID_STATE_CACHED] = Long.parseLong(value);
+                            break;
+                        case "rp":
+                            op.rejectTime[AppOpsManager.UID_STATE_PERSISTENT]
+                                    = Long.parseLong(value);
+                            break;
+                        case "rt":
+                            op.rejectTime[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value);
+                            break;
+                        case "rfs":
+                            op.rejectTime[AppOpsManager.UID_STATE_FOREGROUND_SERVICE]
+                                    = Long.parseLong(value);
+                            break;
+                        case "rf":
+                            op.rejectTime[AppOpsManager.UID_STATE_FOREGROUND]
+                                    = Long.parseLong(value);
+                            break;
+                        case "rb":
+                            op.rejectTime[AppOpsManager.UID_STATE_BACKGROUND]
+                                    = Long.parseLong(value);
+                            break;
+                        case "rc":
+                            op.rejectTime[AppOpsManager.UID_STATE_CACHED]
+                                    = Long.parseLong(value);
+                            break;
+                        case "t":
+                            // Backwards compat.
+                            op.time[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value);
+                            break;
+                        case "r":
+                            // Backwards compat.
+                            op.rejectTime[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value);
+                            break;
+                        default:
+                            Slog.w(TAG, "Unknown attribute in 'op' tag: " + name);
+                            break;
+                    }
+                }
+
                 Ops ops = uidState.pkgOps.get(pkgName);
                 if (ops == null) {
                     ops = new Ops(pkgName, uidState, isPrivileged);
@@ -1977,13 +2151,17 @@
                             if (op.getMode() != AppOpsManager.opToDefaultMode(op.getOp())) {
                                 out.attribute(null, "m", Integer.toString(op.getMode()));
                             }
-                            long time = op.getTime();
-                            if (time != 0) {
-                                out.attribute(null, "t", Long.toString(time));
-                            }
-                            time = op.getRejectTime();
-                            if (time != 0) {
-                                out.attribute(null, "r", Long.toString(time));
+                            for (int k = 0; k < _NUM_UID_STATE; k++) {
+                                final long time = op.getTimeFor(k);
+                                if (time != 0) {
+                                    out.attribute(null, UID_STATE_TIME_ATTRS[k],
+                                            Long.toString(time));
+                                }
+                                final long rejectTime = op.getRejectTimeFor(k);
+                                if (rejectTime != 0) {
+                                    out.attribute(null, UID_STATE_REJECT_ATTRS[k],
+                                            Long.toString(rejectTime));
+                                }
                             }
                             int dur = op.getDuration();
                             if (dur != 0) {
@@ -2069,15 +2247,10 @@
         }
 
         int strModeToMode(String modeStr, PrintWriter err) {
-            switch (modeStr) {
-                case "allow":
-                    return AppOpsManager.MODE_ALLOWED;
-                case "deny":
-                    return AppOpsManager.MODE_ERRORED;
-                case "ignore":
-                    return AppOpsManager.MODE_IGNORED;
-                case "default":
-                    return AppOpsManager.MODE_DEFAULT;
+            for (int i = MODE_NAMES.length - 1; i >= 0; i--) {
+                if (MODE_NAMES[i].equals(modeStr)) {
+                    return i;
+                }
             }
             try {
                 return Integer.parseInt(modeStr);
@@ -2466,6 +2639,34 @@
         pw.println("  none");
     }
 
+    private void dumpTimesLocked(PrintWriter pw, String firstPrefix, String prefix, long[] times,
+            long now, SimpleDateFormat sdf, Date date) {
+        boolean hasTime = false;
+        for (int i = 0; i < _NUM_UID_STATE; i++) {
+            if (times[i] != 0) {
+                hasTime = true;
+                break;
+            }
+        }
+        if (!hasTime) {
+            return;
+        }
+        boolean first = true;
+        for (int i = 0; i < _NUM_UID_STATE; i++) {
+            if (times[i] != 0) {
+                pw.print(first ? firstPrefix : prefix);
+                first = false;
+                pw.print(UID_STATE_NAMES[i]);
+                pw.print(" = ");
+                date.setTime(times[i]);
+                pw.print(sdf.format(date));
+                pw.print(" (");
+                TimeUtils.formatDuration(times[i]-now, pw);
+                pw.println(")");
+            }
+        }
+    }
+
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
@@ -2491,6 +2692,9 @@
         synchronized (this) {
             pw.println("Current AppOps Service state:");
             final long now = System.currentTimeMillis();
+            final long nowElapsed = SystemClock.elapsedRealtime();
+            final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+            final Date date = new Date();
             boolean needSep = false;
             if (mOpModeWatchers.size() > 0) {
                 needSep = true;
@@ -2585,7 +2789,7 @@
                         pw.print("    "); pw.print(op);
                         pw.print(" usage="); pw.print(AudioAttributes.usageToString(usage));
                         Restriction r = restrictions.valueAt(i);
-                        pw.print(": mode="); pw.println(r.mode);
+                        pw.print(": mode="); pw.println(MODE_NAMES[r.mode]);
                         if (!r.exceptionPackages.isEmpty()) {
                             pw.println("      Exceptions:");
                             for (int j=0; j<r.exceptionPackages.size(); j++) {
@@ -2602,6 +2806,12 @@
                 UidState uidState = mUidStates.valueAt(i);
 
                 pw.print("  Uid "); UserHandle.formatUid(pw, uidState.uid); pw.println(":");
+                pw.print("    state=");
+                pw.println(UID_STATE_NAMES[uidState.state]);
+                if (uidState.startNesting != 0) {
+                    pw.print("    startNesting=");
+                    pw.println(uidState.startNesting);
+                }
                 needSep = true;
 
                 SparseIntArray opModes = uidState.opModes;
@@ -2611,7 +2821,7 @@
                         final int code = opModes.keyAt(j);
                         final int mode = opModes.valueAt(j);
                         pw.print("      "); pw.print(AppOpsManager.opToName(code));
-                        pw.print(": mode="); pw.println(mode);
+                        pw.print(": mode="); pw.println(MODE_NAMES[mode]);
                     }
                 }
 
@@ -2625,21 +2835,26 @@
                     for (int j=0; j<ops.size(); j++) {
                         Op op = ops.valueAt(j);
                         pw.print("      "); pw.print(AppOpsManager.opToName(op.op));
-                        pw.print(": mode="); pw.print(op.mode);
-                        if (op.time != 0) {
-                            pw.print("; time="); TimeUtils.formatDuration(now-op.time, pw);
-                            pw.print(" ago");
-                        }
-                        if (op.rejectTime != 0) {
-                            pw.print("; rejectTime="); TimeUtils.formatDuration(now-op.rejectTime, pw);
-                            pw.print(" ago");
-                        }
+                        pw.print(" ("); pw.print(MODE_NAMES[op.mode]); pw.println("): ");
+                        dumpTimesLocked(pw,
+                                "          Access: ",
+                                "                  ", op.time, now, sdf, date);
+                        dumpTimesLocked(pw,
+                                "          Reject: ",
+                                "                  ", op.rejectTime, now, sdf, date);
                         if (op.duration == -1) {
-                            pw.print(" (running)");
+                            pw.print("          Running start at: ");
+                            TimeUtils.formatDuration(nowElapsed-op.startRealtime, pw);
+                            pw.println();
                         } else if (op.duration != 0) {
-                            pw.print("; duration="); TimeUtils.formatDuration(op.duration, pw);
+                            pw.print("          duration=");
+                            TimeUtils.formatDuration(op.duration, pw);
+                            pw.println();
                         }
-                        pw.println();
+                        if (op.startNesting != 0) {
+                            pw.print("          startNesting=");
+                            pw.println(op.startNesting);
+                        }
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index ae14dfa..1cd853f 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -56,7 +56,10 @@
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (args != null) {
             for (final String arg : args) {
-                if ("--reset".equals(arg)) {
+                if ("-a".equals(arg)) {
+                    // We currently dump all information by default
+                    continue;
+                } else if ("--reset".equals(arg)) {
                     reset();
                     pw.println("binder_calls_stats reset.");
                     return;
@@ -78,7 +81,6 @@
                     return;
                 } else {
                     pw.println("Unknown option: " + arg);
-                    return;
                 }
             }
         }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 6bb9021..bc813d1 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -238,8 +238,9 @@
 
     private KeyStore mKeyStore;
 
+    @VisibleForTesting
     @GuardedBy("mVpns")
-    private final SparseArray<Vpn> mVpns = new SparseArray<Vpn>();
+    protected final SparseArray<Vpn> mVpns = new SparseArray<Vpn>();
 
     // TODO: investigate if mLockdownEnabled can be removed and replaced everywhere by
     // a direct call to LockdownVpnTracker.isEnabled().
@@ -929,6 +930,15 @@
                 deps);
     }
 
+    private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
+        final NetworkCapabilities netCap = new NetworkCapabilities();
+        netCap.addCapability(NET_CAPABILITY_INTERNET);
+        netCap.addCapability(NET_CAPABILITY_NOT_RESTRICTED);
+        netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
+        netCap.setSingleUid(uid);
+        return netCap;
+    }
+
     private NetworkRequest createDefaultInternetRequestForTransport(
             int transportType, NetworkRequest.Type type) {
         NetworkCapabilities netCap = new NetworkCapabilities();
@@ -1181,12 +1191,20 @@
         int vpnNetId = NETID_UNSET;
         synchronized (mVpns) {
             final Vpn vpn = mVpns.get(user);
+            // TODO : now that capabilities contain the UID, the appliesToUid test should
+            // be removed as the satisfying test below should be enough.
             if (vpn != null && vpn.appliesToUid(uid)) vpnNetId = vpn.getNetId();
         }
         NetworkAgentInfo nai;
         if (vpnNetId != NETID_UNSET) {
             nai = getNetworkAgentInfoForNetId(vpnNetId);
-            if (nai != null) return nai.network;
+            if (nai != null) {
+                final NetworkCapabilities requiredCaps =
+                    createDefaultNetworkCapabilitiesForUid(uid);
+                if (requiredCaps.satisfiedByNetworkCapabilities(nai.networkCapabilities)) {
+                    return nai.network;
+                }
+            }
         }
         nai = getDefaultNetwork();
         if (nai != null
@@ -1401,8 +1419,10 @@
     private NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions(
             NetworkCapabilities nc, int callerPid, int callerUid) {
         final NetworkCapabilities newNc = new NetworkCapabilities(nc);
-        if (!checkSettingsPermission(callerPid, callerUid)) newNc.setUids(null);
-        if (!checkSettingsPermission(callerPid, callerUid)) newNc.setSSID(null);
+        if (!checkSettingsPermission(callerPid, callerUid)) {
+            newNc.setUids(null);
+            newNc.setSSID(null);
+        }
         return newNc;
     }
 
@@ -4304,8 +4324,7 @@
         // the default network request. This allows callers to keep track of
         // the system default network.
         if (type == NetworkRequest.Type.TRACK_DEFAULT) {
-            networkCapabilities = new NetworkCapabilities(mDefaultRequest.networkCapabilities);
-            networkCapabilities.removeCapability(NET_CAPABILITY_NOT_VPN);
+            networkCapabilities = createDefaultNetworkCapabilitiesForUid(Binder.getCallingUid());
             enforceAccessPermission();
         } else {
             networkCapabilities = new NetworkCapabilities(networkCapabilities);
@@ -4562,7 +4581,7 @@
 
     // Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated.
     private final NetworkRequest mDefaultRequest;
-
+ 
     // Request used to optionally keep mobile data active even when higher
     // priority networks like Wi-Fi are active.
     private final NetworkRequest mDefaultMobileDataRequest;
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index aaa42e5..a4d0dc8 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -2411,19 +2411,26 @@
         // after moving out of the inactive state, so no need to worry about that.
         boolean becomeInactive = false;
         if (mState != STATE_ACTIVE) {
-            scheduleReportActiveLocked(type, Process.myUid());
+            // Motion shouldn't affect light state, if it's already in doze-light or maintenance
+            boolean lightIdle = mLightState == LIGHT_STATE_IDLE
+                    || mLightState == LIGHT_STATE_WAITING_FOR_NETWORK
+                    || mLightState == LIGHT_STATE_IDLE_MAINTENANCE;
+            if (!lightIdle) {
+                // Only switch to active state if we're not in either idle state
+                scheduleReportActiveLocked(type, Process.myUid());
+                addEvent(EVENT_NORMAL, type);
+            }
             mState = STATE_ACTIVE;
             mInactiveTimeout = timeout;
             mCurIdleBudget = 0;
             mMaintenanceStartTime = 0;
             EventLogTags.writeDeviceIdle(mState, type);
-            addEvent(EVENT_NORMAL, type);
             becomeInactive = true;
         }
         if (mLightState == LIGHT_STATE_OVERRIDE) {
             // We went out of light idle mode because we had started deep idle mode...  let's
             // now go back and reset things so we resume light idling if appropriate.
-            mLightState = STATE_ACTIVE;
+            mLightState = LIGHT_STATE_ACTIVE;
             EventLogTags.writeDeviceIdleLight(mLightState, type);
             becomeInactive = true;
         }
@@ -2811,6 +2818,8 @@
         pw.println("    If no DURATION is specified, 10 seconds is used");
         pw.println("    If [-r] option is used, then the package is removed from temp whitelist "
                 + "and any [-d] is ignored");
+        pw.println("  motion");
+        pw.println("    Simulate a motion event to bring the device out of deep doze");
     }
 
     class Shell extends ShellCommand {
@@ -3207,13 +3216,28 @@
                 }
             } else {
                 synchronized (this) {
-                    for (int j=0; j<mPowerSaveWhitelistApps.size(); j++) {
+                    for (int j = 0; j < mPowerSaveWhitelistApps.size(); j++) {
                         pw.print(mPowerSaveWhitelistApps.keyAt(j));
                         pw.print(",");
                         pw.println(mPowerSaveWhitelistApps.valueAt(j));
                     }
                 }
             }
+        } else if ("motion".equals(cmd)) {
+            getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
+                    null);
+            synchronized (this) {
+                long token = Binder.clearCallingIdentity();
+                try {
+                    motionLocked();
+                    pw.print("Light state: ");
+                    pw.print(lightStateToString(mLightState));
+                    pw.print(", deep state: ");
+                    pw.println(stateToString(mState));
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
         } else {
             return shell.handleDefaultCommands(cmd);
         }
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 2465ba2..d869734 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -33,10 +33,11 @@
 # It logs the time remaining before the device would've normally gone to sleep without the request.
 2731 power_soft_sleep_requested (savedwaketimems|2)
 # Power save state has changed. See BatterySaverController.java for the details.
-2739 battery_saver_mode (prevOffOrOn|1|5),(nowOffOrOn|1|5),(interactive|1|5),(features|3|5)
+2739 battery_saver_mode (prevOffOrOn|1|5),(nowOffOrOn|1|5),(interactive|1|5),(features|3|5),(reason|1|5)
 27390 battery_saving_stats (batterySaver|1|5),(interactive|1|5),(doze|1|5),(delta_duration|2|3),(delta_battery_drain|1|1),(delta_battery_drain_percent|1|6),(total_duration|2|3),(total_battery_drain|1|1),(total_battery_drain_percent|1|6)
 # Note when the user activity timeout has been overriden by ActivityManagerService
 27391 user_activity_timeout_override (override|2|3)
+27392 battery_saver_setting (threshold|1)
 
 #
 # Leave IDs through 2740 for more power logs (2730 used by battery_discharge above)
diff --git a/services/core/java/com/android/server/FgThread.java b/services/core/java/com/android/server/FgThread.java
index 021bfaa..fe30057 100644
--- a/services/core/java/com/android/server/FgThread.java
+++ b/services/core/java/com/android/server/FgThread.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Trace;
 
 /**
@@ -28,6 +29,9 @@
  * to be delayed for a user-noticeable amount of time.
  */
 public final class FgThread extends ServiceThread {
+    private static final long SLOW_DISPATCH_THRESHOLD_MS = 100;
+    private static final long SLOW_DELIVERY_THRESHOLD_MS = 200;
+
     private static FgThread sInstance;
     private static Handler sHandler;
 
@@ -39,7 +43,10 @@
         if (sInstance == null) {
             sInstance = new FgThread();
             sInstance.start();
-            sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
+            final Looper looper = sInstance.getLooper();
+            looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
+            looper.setSlowLogThresholdMs(
+                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
             sHandler = new Handler(sInstance.getLooper());
         }
     }
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index cd90e3f..33ca02f 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -1101,9 +1101,11 @@
                     new RefcountedResource<SpiRecord>(
                             new SpiRecord(resourceId, "", destinationAddress, spi), binder));
         } catch (ServiceSpecificException e) {
-            // TODO: Add appropriate checks when other ServiceSpecificException types are supported
-            return new IpSecSpiResponse(
-                    IpSecManager.Status.SPI_UNAVAILABLE, INVALID_RESOURCE_ID, spi);
+            if (e.errorCode == OsConstants.ENOENT) {
+                return new IpSecSpiResponse(
+                        IpSecManager.Status.SPI_UNAVAILABLE, INVALID_RESOURCE_ID, spi);
+            }
+            throw e;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1115,7 +1117,6 @@
      */
     private void releaseResource(RefcountedResourceArray resArray, int resourceId)
             throws RemoteException {
-
         resArray.getRefcountedResourceOrThrow(resourceId).userRelease();
     }
 
@@ -1315,15 +1316,12 @@
             releaseNetId(ikey);
             releaseNetId(okey);
             throw e.rethrowFromSystemServer();
-        } catch (ServiceSpecificException e) {
-            // FIXME: get the error code and throw is at an IOException from Errno Exception
+        } catch (Throwable t) {
+            // Release keys if we got an error.
+            releaseNetId(ikey);
+            releaseNetId(okey);
+            throw t;
         }
-
-        // If we make it to here, then something has gone wrong and we couldn't create a VTI.
-        // Release the keys that we reserved, and return an error status.
-        releaseNetId(ikey);
-        releaseNetId(okey);
-        return new IpSecTunnelInterfaceResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE);
     }
 
     /**
@@ -1352,9 +1350,6 @@
                             localAddr.getPrefixLength());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
-        } catch (ServiceSpecificException e) {
-            // If we get here, one of the arguments provided was invalid. Wrap the SSE, and throw.
-            throw new IllegalArgumentException(e);
         }
     }
 
@@ -1384,9 +1379,6 @@
                             localAddr.getPrefixLength());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
-        } catch (ServiceSpecificException e) {
-            // If we get here, one of the arguments provided was invalid. Wrap the SSE, and throw.
-            throw new IllegalArgumentException(e);
         }
     }
 
@@ -1590,12 +1582,7 @@
         dependencies.add(refcountedSpiRecord);
         SpiRecord spiRecord = refcountedSpiRecord.getResource();
 
-        try {
-            createOrUpdateTransform(c, resourceId, spiRecord, socketRecord);
-        } catch (ServiceSpecificException e) {
-            // FIXME: get the error code and throw is at an IOException from Errno Exception
-            return new IpSecTransformResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE);
-        }
+        createOrUpdateTransform(c, resourceId, spiRecord, socketRecord);
 
         // SA was created successfully, time to construct a record and lock it away
         userRecord.mTransformRecords.put(
@@ -1642,23 +1629,15 @@
                 c.getMode() == IpSecTransform.MODE_TRANSPORT,
                 "Transform mode was not Transport mode; cannot be applied to a socket");
 
-        try {
-            mSrvConfig
-                    .getNetdInstance()
-                    .ipSecApplyTransportModeTransform(
-                            socket.getFileDescriptor(),
-                            resourceId,
-                            direction,
-                            c.getSourceAddress(),
-                            c.getDestinationAddress(),
-                            info.getSpiRecord().getSpi());
-        } catch (ServiceSpecificException e) {
-            if (e.errorCode == EINVAL) {
-                throw new IllegalArgumentException(e.toString());
-            } else {
-                throw e;
-            }
-        }
+        mSrvConfig
+                .getNetdInstance()
+                .ipSecApplyTransportModeTransform(
+                        socket.getFileDescriptor(),
+                        resourceId,
+                        direction,
+                        c.getSourceAddress(),
+                        c.getDestinationAddress(),
+                        info.getSpiRecord().getSpi());
     }
 
     /**
@@ -1670,13 +1649,9 @@
     @Override
     public synchronized void removeTransportModeTransforms(ParcelFileDescriptor socket)
             throws RemoteException {
-        try {
-            mSrvConfig
-                    .getNetdInstance()
-                    .ipSecRemoveTransportModeTransform(socket.getFileDescriptor());
-        } catch (ServiceSpecificException e) {
-            // FIXME: get the error code and throw is at an IOException from Errno Exception
-        }
+        mSrvConfig
+                .getNetdInstance()
+                .ipSecRemoveTransportModeTransform(socket.getFileDescriptor());
     }
 
     /**
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 309a75a..7b02a4f 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -86,6 +86,7 @@
 import com.android.server.location.GeocoderProxy;
 import com.android.server.location.GeofenceManager;
 import com.android.server.location.GeofenceProxy;
+import com.android.server.location.GnssBatchingProvider;
 import com.android.server.location.GnssLocationProvider;
 import com.android.server.location.GnssMeasurementsProvider;
 import com.android.server.location.GnssNavigationMessageProvider;
@@ -244,7 +245,7 @@
 
     private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider;
 
-    private GnssLocationProvider.GnssBatchingProvider mGnssBatchingProvider;
+    private GnssBatchingProvider mGnssBatchingProvider;
     private IBatchedLocationCallback mGnssBatchingCallback;
     private LinkedCallback mGnssBatchingDeathCallback;
     private boolean mGnssBatchingInProgress = false;
@@ -1176,7 +1177,7 @@
                 "Location Hardware permission not granted to access hardware batching");
 
         if (hasGnssPermissions(packageName) && mGnssBatchingProvider != null) {
-            return mGnssBatchingProvider.getSize();
+            return mGnssBatchingProvider.getBatchSize();
         } else {
             return 0;
         }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 60d11d7..41f413d 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -351,7 +351,7 @@
             mCallForwarding[i] =  false;
             mCellLocation[i] = new Bundle();
             mCellInfo.add(i, null);
-            mPhysicalChannelConfigs.add(i, null);
+            mPhysicalChannelConfigs.add(i, new ArrayList<PhysicalChannelConfig>());
         }
 
         // Note that location can be null for non-phone builds like
diff --git a/services/core/java/com/android/server/UiThread.java b/services/core/java/com/android/server/UiThread.java
index f813074..b2fa684 100644
--- a/services/core/java/com/android/server/UiThread.java
+++ b/services/core/java/com/android/server/UiThread.java
@@ -28,6 +28,7 @@
  */
 public final class UiThread extends ServiceThread {
     private static final long SLOW_DISPATCH_THRESHOLD_MS = 100;
+    private static final long SLOW_DELIVERY_THRESHOLD_MS = 200;
     private static UiThread sInstance;
     private static Handler sHandler;
 
@@ -48,7 +49,8 @@
             sInstance.start();
             final Looper looper = sInstance.getLooper();
             looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
-            looper.setSlowDispatchThresholdMs(SLOW_DISPATCH_THRESHOLD_MS);
+            looper.setSlowLogThresholdMs(
+                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
             sHandler = new Handler(sInstance.getLooper());
         }
     }
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 83d2bf7..ede870f 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -704,9 +704,11 @@
         VibrationEffect scaledEffect = null;
         if (vib.effect instanceof VibrationEffect.OneShot) {
             VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) vib.effect;
+            oneShot = oneShot.resolve(mDefaultVibrationAmplitude);
             scaledEffect = oneShot.scale(gamma, maxAmplitude);
         } else if (vib.effect instanceof VibrationEffect.Waveform) {
             VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) vib.effect;
+            waveform = waveform.resolve(mDefaultVibrationAmplitude);
             scaledEffect = waveform.scale(gamma, maxAmplitude);
         } else {
             Slog.w(TAG, "Unable to apply intensity scaling, unknown VibrationEffect type");
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 566e128..59093c1 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -92,6 +92,7 @@
 
     public static final List<String> HAL_INTERFACES_OF_INTEREST = Arrays.asList(
         "android.hardware.audio@2.0::IDevicesFactory",
+        "android.hardware.audio@4.0::IDevicesFactory",
         "android.hardware.bluetooth@1.0::IBluetoothHci",
         "android.hardware.camera.provider@2.4::ICameraProvider",
         "android.hardware.graphics.composer@2.1::IComposer",
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 228171f..f413639 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -422,13 +422,9 @@
         }
 
         // If we're starting indirectly (e.g. from PendingIntent), figure out whether
-        // we're launching into an app in a background state.
-        final int uidState = mAm.getUidStateLocked(r.appInfo.uid);
-        if (DEBUG_SERVICE) {
-            Slog.v(TAG_SERVICE, "Uid state " + uidState + " indirect starting " + r.shortName);
-        }
-        final boolean bgLaunch = (uidState >
-                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
+        // we're launching into an app in a background state.  This keys off of the same
+        // idleness state tracking as e.g. O+ background service start policy.
+        final boolean bgLaunch = !mAm.isUidActiveLocked(r.appInfo.uid);
 
         // If the app has strict background restrictions, we treat any bg service
         // start analogously to the legacy-app forced-restrictions case, regardless
@@ -1197,10 +1193,13 @@
 
                 if (!ignoreForeground &&
                         appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) {
-                    ignoreForeground = true;
                     Slog.w(TAG,
                             "Service.startForeground() not allowed due to bg restriction: service "
                             + r.shortName);
+                    // Back off of any foreground expectations around this service, since we've
+                    // just turned down its fg request.
+                    updateServiceForegroundLocked(r.app, false);
+                    ignoreForeground = true;
                 }
 
                 // Apps under strict background restrictions simply don't get to have foreground
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index fac3f92..0f42103 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -420,7 +420,9 @@
                 if (!otherStack.inSplitScreenSecondaryWindowingMode()) {
                     continue;
                 }
-                otherStack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+                otherStack.setWindowingMode(WINDOWING_MODE_FULLSCREEN, false /* animate */,
+                        false /* showRecents */, false /* enteringSplitScreenMode */,
+                        true /* deferEnsuringVisibility */);
             }
         } finally {
             final ActivityStack topFullscreenStack =
@@ -450,7 +452,7 @@
                 }
                 otherStack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY,
                         false /* animate */, false /* showRecents */,
-                        true /* enteringSplitScreenMode */);
+                        true /* enteringSplitScreenMode */, true /* deferEnsuringVisibility */);
             }
         } finally {
             mSupervisor.mWindowManager.continueSurfaceLayout();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f6467e6..c4d6ab5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5049,9 +5049,20 @@
     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
+        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
+                resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
+                true /*validateIncomingUser*/);
+    }
+
+    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
+            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
+            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
+            boolean validateIncomingUser) {
         enforceNotIsolatedCaller("startActivity");
-        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
-                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
+
+        userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
+                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
+
         // TODO: Switch to user app stacks here.
         return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                 .setCaller(caller)
@@ -5306,7 +5317,8 @@
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
-                mWindowManager.cancelRecentsAnimation(restoreHomeStackPosition
+                // Cancel the recents animation synchronously (do not hold the WM lock)
+                mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
                         ? REORDER_MOVE_TO_ORIGINAL_POSITION
                         : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation");
             }
@@ -8356,8 +8368,19 @@
         if (!(sender instanceof PendingIntentRecord)) {
             return;
         }
+        boolean isCancelled;
         synchronized(this) {
-            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
+            PendingIntentRecord pendingIntent = (PendingIntentRecord) sender;
+            isCancelled = pendingIntent.canceled;
+            if (!isCancelled) {
+                pendingIntent.registerCancelListenerLocked(receiver);
+            }
+        }
+        if (isCancelled) {
+            try {
+                receiver.send(Activity.RESULT_CANCELED, null);
+            } catch (RemoteException e) {
+            }
         }
     }
 
@@ -11133,7 +11156,7 @@
                     stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
                 }
                 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
-                        false /* enteringSplitScreenMode */);
+                        false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
                 return windowingMode != task.getWindowingMode();
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -22791,6 +22814,7 @@
 
     private void noteUidProcessState(final int uid, final int state) {
         mBatteryStatsService.noteUidProcessState(uid, state);
+        mAppOpsService.updateUidProcState(uid, state);
         if (mTrackingAssociations) {
             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
@@ -26205,6 +26229,16 @@
         }
 
         @Override
+        public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
+                Intent intent, Bundle options, int userId) {
+            return ActivityManagerService.this.startActivityAsUser(
+                    caller, callerPacakge, intent,
+                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                    null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
+                    false /*validateIncomingUser*/);
+        }
+
+        @Override
         public int getUidProcessState(int uid) {
             return getUidState(uid);
         }
@@ -26487,8 +26521,7 @@
         @Override
         public boolean isUidActive(int uid) {
             synchronized (ActivityManagerService.this) {
-                final UidRecord uidRec = mActiveUids.get(uid);
-                return (uidRec != null) && !uidRec.idle;
+                return isUidActiveLocked(uid);
             }
         }
 
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 16c5969..e73f42f 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1626,6 +1626,10 @@
         if (parent != null) {
             parent.onActivityStateChanged(this, state, reason);
         }
+
+        if (state == STOPPING) {
+            mWindowContainerController.notifyAppStopping();
+        }
     }
 
     ActivityState getState() {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 9fb3e11..e86850e 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -515,11 +515,11 @@
     @Override
     public void setWindowingMode(int windowingMode) {
         setWindowingMode(windowingMode, false /* animate */, false /* showRecents */,
-                false /* enteringSplitScreenMode */);
+                false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
     }
 
     void setWindowingMode(int preferredWindowingMode, boolean animate, boolean showRecents,
-            boolean enteringSplitScreenMode) {
+            boolean enteringSplitScreenMode, boolean deferEnsuringVisibility) {
         final boolean creating = mWindowContainerController == null;
         final int currentMode = getWindowingMode();
         final ActivityDisplay display = getDisplay();
@@ -555,7 +555,9 @@
                 // doesn't support split-screen mode, go ahead an dismiss split-screen and display a
                 // warning toast about it.
                 mService.mTaskChangeNotificationController.notifyActivityDismissingDockedStack();
-                display.getSplitScreenPrimaryStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+                display.getSplitScreenPrimaryStack().setWindowingMode(WINDOWING_MODE_FULLSCREEN,
+                        false /* animate */, false /* showRecents */,
+                        false /* enteringSplitScreenMode */, true /* deferEnsuringVisibility */);
             }
         }
 
@@ -646,9 +648,7 @@
             wm.continueSurfaceLayout();
         }
 
-        // Don't ensure visible activities if the windowing mode change was a side effect of us
-        // entering split-screen mode.
-        if (!enteringSplitScreenMode) {
+        if (!deferEnsuringVisibility) {
             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
             mStackSupervisor.resumeFocusedStackTopActivityLocked();
         }
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index e5565dc..4ace689 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1315,10 +1315,6 @@
         return aInfo;
     }
 
-    ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId) {
-        return resolveIntent(intent, resolvedType, userId, 0, Binder.getCallingUid());
-    }
-
     ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags,
             int filterCallingUid) {
         synchronized (mService) {
@@ -1330,9 +1326,19 @@
                             || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
                     modifiedFlags |= PackageManager.MATCH_INSTANT;
                 }
-                return mService.getPackageManagerInternalLocked().resolveIntent(
-                        intent, resolvedType, modifiedFlags, userId, true, filterCallingUid);
 
+                // In order to allow cross-profile lookup, we clear the calling identity here.
+                // Note the binder identity won't affect the result, but filterCallingUid will.
+
+                // Cross-user/profile call check are done at the entry points
+                // (e.g. AMS.startActivityAsUser).
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    return mService.getPackageManagerInternalLocked().resolveIntent(
+                            intent, resolvedType, modifiedFlags, userId, true, filterCallingUid);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
             } finally {
                 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
             }
@@ -2409,6 +2415,16 @@
                 if (stack.isCompatible(windowingMode, activityType)) {
                     return stack;
                 }
+                if (windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY
+                        && display.getSplitScreenPrimaryStack() == stack
+                        && candidateTask == stack.topTask()) {
+                    // This is a special case when we try to launch an activity that is currently on
+                    // top of split-screen primary stack, but is targeting split-screen secondary.
+                    // In this case we don't want to move it to another stack.
+                    // TODO(b/78788972): Remove after differentiating between preferred and required
+                    // launch options.
+                    return stack;
+                }
             }
         }
 
@@ -2890,10 +2906,8 @@
         try {
             ActivityRecord r = stack.topRunningActivityLocked();
             Rect insetBounds = null;
-            if (tempPinnedTaskBounds != null) {
-                // We always use 0,0 as the position for the inset rect because
-                // if we are getting insets at all in the pinned stack it must mean
-                // we are headed for fullscreen.
+            if (tempPinnedTaskBounds != null && stack.isAnimatingBoundsToFullscreen()) {
+                // Use 0,0 as the position for the inset rect because we are headed for fullscreen.
                 insetBounds = tempRect;
                 insetBounds.top = 0;
                 insetBounds.left = 0;
diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java
index 6c45546..5e29d10 100644
--- a/services/core/java/com/android/server/am/ActivityStartController.java
+++ b/services/core/java/com/android/server/am/ActivityStartController.java
@@ -233,7 +233,7 @@
      * ensures {@code targetUserId} is a real user ID and not a special user ID such as
      * {@link android.os.UserHandle#USER_ALL}, etc.
      */
-    private int checkTargetUser(int targetUserId, boolean validateIncomingUser,
+    int checkTargetUser(int targetUserId, boolean validateIncomingUser,
             int realCallingPid, int realCallingUid, String reason) {
         if (validateIncomingUser) {
             return mService.mUserController.handleIncomingUser(realCallingPid, realCallingUid,
@@ -350,7 +350,8 @@
                                 "FLAG_CANT_SAVE_STATE not supported here");
                     }
 
-                    final SafeActivityOptions checkedOptions = i == intents.length - 1
+                    final boolean top = i == intents.length - 1;
+                    final SafeActivityOptions checkedOptions = top
                             ? options
                             : null;
                     final int res = obtainStarter(intent, reason)
@@ -367,6 +368,10 @@
                             .setActivityOptions(checkedOptions)
                             .setComponentSpecified(componentSpecified)
                             .setOutActivity(outActivity)
+
+                            // Top activity decides on animation being run, so we allow only for the
+                            // top one as otherwise an activity below might consume it.
+                            .setAllowPendingRemoteAnimationRegistryLookup(top /* allowLookup*/)
                             .execute();
 
                     if (res < 0) {
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
index 5b6b508..8c3ff34 100644
--- a/services/core/java/com/android/server/am/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -203,7 +203,7 @@
         mResolvedType = null;
 
         final UserInfo parent = mUserManager.getProfileParent(mUserId);
-        mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id);
+        mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id, 0, mRealCallingUid);
         mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, null /*profilerInfo*/);
         return true;
     }
@@ -223,9 +223,11 @@
 
         final UserInfo parent = mUserManager.getProfileParent(mUserId);
         if (parent != null) {
-            mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id);
+            mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id, 0,
+                    mRealCallingUid);
         } else {
-            mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, mUserId);
+            mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, mUserId, 0,
+                    mRealCallingUid);
         }
         mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, null /*profilerInfo*/);
         return true;
@@ -244,7 +246,8 @@
         final Intent moreDetailsIntent = new Intent(Intent.ACTION_SHOW_SUSPENDED_APP_DETAILS)
                 .setPackage(suspendingPackage);
         final String requiredPermission = Manifest.permission.SEND_SHOW_SUSPENDED_APP_DETAILS;
-        final ResolveInfo resolvedInfo = mSupervisor.resolveIntent(moreDetailsIntent, null, userId);
+        final ResolveInfo resolvedInfo = mSupervisor.resolveIntent(moreDetailsIntent, null, userId,
+                0, mRealCallingUid);
         if (resolvedInfo != null && resolvedInfo.activityInfo != null
                 && requiredPermission.equals(resolvedInfo.activityInfo.permission)) {
             moreDetailsIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, suspendedPackage)
@@ -276,7 +279,7 @@
         mCallingPid = mRealCallingPid;
         mCallingUid = mRealCallingUid;
         mResolvedType = null;
-        mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, 0);
+        mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, mUserId, 0, mRealCallingUid);
         mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, null /*profilerInfo*/);
         return true;
     }
@@ -309,7 +312,7 @@
         }
 
         final UserInfo parent = mUserManager.getProfileParent(mUserId);
-        mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id);
+        mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id, 0, mRealCallingUid);
         mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, null /*profilerInfo*/);
         return true;
     }
@@ -362,7 +365,7 @@
         mCallingUid = mRealCallingUid;
         mResolvedType = null;
 
-        mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, mUserId);
+        mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, mUserId, 0, mRealCallingUid);
         mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, null /*profilerInfo*/);
         return true;
     }
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index fb89e67..fb4107c 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -314,6 +314,12 @@
         WaitResult waitResult;
 
         /**
+         * If set to {@code true}, allows this activity start to look into
+         * {@link PendingRemoteAnimationRegistry}
+         */
+        boolean allowPendingRemoteAnimationRegistryLookup;
+
+        /**
          * Indicates that we should wait for the result of the start request. This flag is set when
          * {@link ActivityStarter#setMayWait(int)} is called.
          * {@see ActivityStarter#startActivityMayWait}.
@@ -360,6 +366,7 @@
             waitResult = null;
             mayWait = false;
             avoidMoveToFront = false;
+            allowPendingRemoteAnimationRegistryLookup = true;
         }
 
         /**
@@ -395,6 +402,8 @@
             waitResult = request.waitResult;
             mayWait = request.mayWait;
             avoidMoveToFront = request.avoidMoveToFront;
+            allowPendingRemoteAnimationRegistryLookup
+                    = request.allowPendingRemoteAnimationRegistryLookup;
         }
     }
 
@@ -477,7 +486,8 @@
                         mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                         mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                         mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
-                        mRequest.inTask, mRequest.reason);
+                        mRequest.inTask, mRequest.reason,
+                        mRequest.allowPendingRemoteAnimationRegistryLookup);
             } else {
                 return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                         mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
@@ -486,7 +496,8 @@
                         mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                         mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                         mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
-                        mRequest.outActivity, mRequest.inTask, mRequest.reason);
+                        mRequest.outActivity, mRequest.inTask, mRequest.reason,
+                        mRequest.allowPendingRemoteAnimationRegistryLookup);
             }
         } finally {
             onExecutionComplete();
@@ -517,7 +528,8 @@
             IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
             String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
             SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
-            ActivityRecord[] outActivity, TaskRecord inTask, String reason) {
+            ActivityRecord[] outActivity, TaskRecord inTask, String reason,
+            boolean allowPendingRemoteAnimationRegistryLookup) {
 
         if (TextUtils.isEmpty(reason)) {
             throw new IllegalArgumentException("Need to specify a reason.");
@@ -530,7 +542,7 @@
                 aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                 callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                 options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
-                inTask);
+                inTask, allowPendingRemoteAnimationRegistryLookup);
 
         if (outActivity != null) {
             // mLastStartActivityRecord[0] is set in the call to startActivity above.
@@ -560,7 +572,7 @@
             String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
             SafeActivityOptions options,
             boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
-            TaskRecord inTask) {
+            TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
         int err = ActivityManager.START_SUCCESS;
         // Pull the optional Ephemeral Installer-only bundle out of the options early.
         final Bundle verificationBundle
@@ -709,8 +721,11 @@
         ActivityOptions checkedOptions = options != null
                 ? options.getOptions(intent, aInfo, callerApp, mSupervisor)
                 : null;
-        checkedOptions = mService.getActivityStartController().getPendingRemoteAnimationRegistry()
-                .overrideOptionsIfNeeded(callingPackage, checkedOptions);
+        if (allowPendingRemoteAnimationRegistryLookup) {
+            checkedOptions = mService.getActivityStartController()
+                    .getPendingRemoteAnimationRegistry()
+                    .overrideOptionsIfNeeded(callingPackage, checkedOptions);
+        }
         if (mService.mController != null) {
             try {
                 // The Intent we give to the watcher has the extra data
@@ -776,7 +791,7 @@
                 callingUid = realCallingUid;
                 callingPid = realCallingPid;
 
-                rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
+                rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0, realCallingUid);
                 aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
                         null /*profilerInfo*/);
 
@@ -928,7 +943,8 @@
             IBinder resultTo, String resultWho, int requestCode, int startFlags,
             ProfilerInfo profilerInfo, WaitResult outResult,
             Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
-            int userId, TaskRecord inTask, String reason) {
+            int userId, TaskRecord inTask, String reason,
+            boolean allowPendingRemoteAnimationRegistryLookup) {
         // Refuse possible leaked file descriptors
         if (intent != null && intent.hasFileDescriptors()) {
             throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -936,6 +952,9 @@
         mSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
         boolean componentSpecified = intent.getComponent() != null;
 
+        final int realCallingPid = Binder.getCallingPid();
+        final int realCallingUid = Binder.getCallingUid();
+
         // Save a copy in case ephemeral needs it
         final Intent ephemeralIntent = new Intent(intent);
         // Don't modify the client's object!
@@ -953,7 +972,8 @@
             componentSpecified = false;
         }
 
-        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
+        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
+                0 /* matchFlags */, realCallingUid);
         if (rInfo == null) {
             UserInfo userInfo = mSupervisor.getUserInfo(userId);
             if (userInfo != null && userInfo.isManagedProfile()) {
@@ -975,7 +995,7 @@
                     rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
                             PackageManager.MATCH_DIRECT_BOOT_AWARE
                                     | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                            Binder.getCallingUid());
+                            realCallingUid);
                 }
             }
         }
@@ -983,8 +1003,6 @@
         ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
 
         synchronized (mService) {
-            final int realCallingPid = Binder.getCallingPid();
-            final int realCallingUid = Binder.getCallingUid();
             int callingPid;
             if (callingUid >= 0) {
                 callingPid = -1;
@@ -1057,7 +1075,8 @@
                         callingUid = Binder.getCallingUid();
                         callingPid = Binder.getCallingPid();
                         componentSpecified = true;
-                        rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId);
+                        rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
+                                0 /* matchFlags */, realCallingUid);
                         aInfo = rInfo != null ? rInfo.activityInfo : null;
                         if (aInfo != null) {
                             aInfo = mService.getActivityInfoForUser(aInfo, userId);
@@ -1070,7 +1089,8 @@
             int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                     voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                     callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
-                    ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason);
+                    ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
+                    allowPendingRemoteAnimationRegistryLookup);
 
             Binder.restoreCallingIdentity(origId);
 
@@ -2567,6 +2587,11 @@
         return this;
     }
 
+    ActivityStarter setAllowPendingRemoteAnimationRegistryLookup(boolean allowLookup) {
+        mRequest.allowPendingRemoteAnimationRegistryLookup = allowLookup;
+        return this;
+    }
+
     void dump(PrintWriter pw, String prefix) {
         prefix = prefix + "  ";
         pw.print(prefix);
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 35b7f2b..a6dafbb 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -476,7 +476,8 @@
                     } catch (IllegalArgumentException e) {
                         // Hmm, that didn't work, app might have crashed before creating a
                         // recents entry. Let's see if we have a safe-to-restart intent.
-                        final Set<String> cats = task.intent.getCategories();
+                        final Set<String> cats = task.intent != null
+                                ? task.intent.getCategories() : null;
                         if (cats != null && cats.contains(Intent.CATEGORY_LAUNCHER)) {
                             mService.getActivityStartController().startActivityInPackage(
                                     task.mCallingUid, callingPid, callingUid, task.mCallingPackage,
diff --git a/services/core/java/com/android/server/am/AppWarnings.java b/services/core/java/com/android/server/am/AppWarnings.java
index 9f7db7b..30a3844 100644
--- a/services/core/java/com/android/server/am/AppWarnings.java
+++ b/services/core/java/com/android/server/am/AppWarnings.java
@@ -122,10 +122,7 @@
             return;
         }
 
-
-
-        // TODO(b/75318890): temp. fix to get q dogfoodable. Need to move this to when the app
-        // actually crashes.
+        // TODO(b/75318890): Need to move this to when the app actually crashes.
         if (/*ActivityManager.isRunningInTestHarness()
                 &&*/ !mAlwaysShowUnsupportedCompileSdkWarningActivities.contains(r.realActivity)) {
             // Don't show warning if we are running in a test harness and we don't have to always
diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
index 87194bc..49fa902 100644
--- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
@@ -103,6 +103,9 @@
     @GuardedBy("this")
     private Future<?> mWakelockChangesUpdate;
 
+    @GuardedBy("this")
+    private Future<?> mBatteryLevelSync;
+
     private final Object mWorkerLock = new Object();
 
     @GuardedBy("mWorkerLock")
@@ -197,35 +200,75 @@
 
     @Override
     public Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis) {
-        if (mExecutorService.isShutdown()) {
-            return CompletableFuture.failedFuture(new IllegalStateException("worker shutdown"));
+        synchronized (BatteryExternalStatsWorker.this) {
+            mWakelockChangesUpdate = scheduleDelayedSyncLocked(mWakelockChangesUpdate,
+                    () -> {
+                        scheduleSync("wakelock-change", UPDATE_CPU);
+                        scheduleRunnable(() -> mStats.postBatteryNeedsCpuUpdateMsg());
+                    },
+                    delayMillis);
+            return mWakelockChangesUpdate;
         }
-
-        if (mWakelockChangesUpdate != null) {
-            // If there's already a scheduled task, leave it as is if we're trying to re-schedule
-            // it again with a delay, otherwise cancel and re-schedule it.
-            if (delayMillis == 0) {
-                mWakelockChangesUpdate.cancel(false);
-            } else {
-                return mWakelockChangesUpdate;
-            }
-        }
-
-        mWakelockChangesUpdate = mExecutorService.schedule(() -> {
-            scheduleSync("wakelock-change", UPDATE_CPU);
-            scheduleRunnable(() -> mStats.postBatteryNeedsCpuUpdateMsg());
-            mWakelockChangesUpdate = null;
-        }, delayMillis, TimeUnit.MILLISECONDS);
-        return mWakelockChangesUpdate;
     }
 
     @Override
     public void cancelCpuSyncDueToWakelockChange() {
-        if (mWakelockChangesUpdate != null) {
-            mWakelockChangesUpdate.cancel(false);
+        synchronized (BatteryExternalStatsWorker.this) {
+            if (mWakelockChangesUpdate != null) {
+                mWakelockChangesUpdate.cancel(false);
+                mWakelockChangesUpdate = null;
+            }
         }
     }
 
+    @Override
+    public Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis) {
+        synchronized (BatteryExternalStatsWorker.this) {
+            mBatteryLevelSync = scheduleDelayedSyncLocked(mBatteryLevelSync,
+                    () -> scheduleSync("battery-level", UPDATE_ALL),
+                    delayMillis);
+            return mBatteryLevelSync;
+        }
+    }
+
+    @GuardedBy("this")
+    private void cancelSyncDueToBatteryLevelChangeLocked() {
+        if (mBatteryLevelSync != null) {
+            mBatteryLevelSync.cancel(false);
+            mBatteryLevelSync = null;
+        }
+    }
+
+    /**
+     * Schedule a sync {@param syncRunnable} with a delay. If there's already a scheduled sync, a
+     * new sync won't be scheduled unless it is being scheduled to run immediately (delayMillis=0).
+     *
+     * @param lastScheduledSync the task which was earlier scheduled to run
+     * @param syncRunnable the task that needs to be scheduled to run
+     * @param delayMillis time after which {@param syncRunnable} needs to be scheduled
+     * @return scheduled {@link Future} which can be used to check if task is completed or to
+     *         cancel it if needed
+     */
+    @GuardedBy("this")
+    private Future<?> scheduleDelayedSyncLocked(Future<?> lastScheduledSync, Runnable syncRunnable,
+            long delayMillis) {
+        if (mExecutorService.isShutdown()) {
+            return CompletableFuture.failedFuture(new IllegalStateException("worker shutdown"));
+        }
+
+        if (lastScheduledSync != null) {
+            // If there's already a scheduled task, leave it as is if we're trying to
+            // re-schedule it again with a delay, otherwise cancel and re-schedule it.
+            if (delayMillis == 0) {
+                lastScheduledSync.cancel(false);
+            } else {
+                return lastScheduledSync;
+            }
+        }
+
+        return mExecutorService.schedule(syncRunnable, delayMillis, TimeUnit.MILLISECONDS);
+    }
+
     public synchronized Future<?> scheduleWrite() {
         if (mExecutorService.isShutdown()) {
             return CompletableFuture.failedFuture(new IllegalStateException("worker shutdown"));
@@ -294,6 +337,12 @@
                 mUidsToRemove.clear();
                 mCurrentFuture = null;
                 mUseLatestStates = true;
+                if ((updateFlags & UPDATE_ALL) != 0) {
+                    cancelSyncDueToBatteryLevelChangeLocked();
+                }
+                if ((updateFlags & UPDATE_CPU) != 0) {
+                    cancelCpuSyncDueToWakelockChange();
+                }
             }
 
             try {
diff --git a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
index 676f0c7..1149e87 100644
--- a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
@@ -23,6 +23,7 @@
 import android.graphics.BitmapFactory;
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
+import android.os.UserManager;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.ImageView;
@@ -59,11 +60,14 @@
         View view = LayoutInflater.from(getContext()).inflate(R.layout.car_user_switching_dialog,
             null);
 
-        FileDescriptor fileDescriptor = UserManagerService.getInstance()
-                .getUserIcon(mNewUser.id).getFileDescriptor();
-        Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
-        ((ImageView) view.findViewById(R.id.user_loading_avatar))
-            .setImageBitmap(bitmap);
+        UserManager userManager =
+                (UserManager) getContext().getSystemService(Context.USER_SERVICE);
+        Bitmap bitmap = userManager.getUserIcon(mNewUser.id);
+        if (bitmap != null) {
+            ((ImageView) view.findViewById(R.id.user_loading_avatar))
+                    .setImageBitmap(bitmap);
+        }
+
         ((TextView) view.findViewById(R.id.user_loading))
             .setText(res.getString(R.string.car_loading_profile));
         setView(view);
diff --git a/services/core/java/com/android/server/am/DeprecatedTargetSdkVersionDialog.java b/services/core/java/com/android/server/am/DeprecatedTargetSdkVersionDialog.java
index 84dca7f..d9878cd 100644
--- a/services/core/java/com/android/server/am/DeprecatedTargetSdkVersionDialog.java
+++ b/services/core/java/com/android/server/am/DeprecatedTargetSdkVersionDialog.java
@@ -16,6 +16,9 @@
 
 package com.android.server.am;
 
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.Intent;
@@ -23,6 +26,7 @@
 import android.content.pm.PackageManager;
 import android.os.Build;
 import android.os.SystemPropertiesProto;
+import android.util.Log;
 import android.view.Window;
 import android.view.WindowManager;
 import android.widget.CheckBox;
@@ -31,6 +35,8 @@
 import com.android.server.utils.AppInstallerUtil;
 
 public class DeprecatedTargetSdkVersionDialog {
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "DeprecatedTargetSdkVersionDialog" : TAG_AM;
+
     private final AlertDialog mDialog;
     private final String mPackageName;
 
@@ -74,6 +80,7 @@
     }
 
     public void show() {
+        Log.w(TAG, "Showing SDK deprecation warning for package " + mPackageName);
         mDialog.show();
     }
 
diff --git a/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java
index 328426d..1366c21 100644
--- a/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/GlobalSettingsToPropertiesMapper.java
@@ -19,6 +19,7 @@
 import android.content.ContentResolver;
 import android.database.ContentObserver;
 import android.net.Uri;
+import android.os.Build;
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -98,7 +99,14 @@
         try {
             systemPropertiesSet(key, value);
         } catch (Exception e) {
-            Slog.e(TAG, "Unable to set property " + key + " value '" + value + "'", e);
+            // Failure to set a property can be caused by SELinux denial. This usually indicates
+            // that the property wasn't whitelisted in sepolicy.
+            // No need to report it on all user devices, only on debug builds.
+            if (Build.IS_DEBUGGABLE) {
+                Slog.wtf(TAG, "Unable to set property " + key + " value '" + value + "'", e);
+            } else {
+                Slog.e(TAG, "Unable to set property " + key + " value '" + value + "'", e);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index 1b7f75b..5764382 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -121,6 +121,8 @@
     void setKeyguardShown(boolean keyguardShowing, boolean aodShowing,
             int secondaryDisplayShowing) {
         boolean showingChanged = keyguardShowing != mKeyguardShowing || aodShowing != mAodShowing;
+        // If keyguard is going away, but SystemUI aborted the transition, need to reset state.
+        showingChanged |= mKeyguardGoingAway && keyguardShowing;
         if (!showingChanged && secondaryDisplayShowing == mSecondaryDisplayShowing) {
             return;
         }
diff --git a/services/core/java/com/android/server/am/LockTaskController.java b/services/core/java/com/android/server/am/LockTaskController.java
index bef650b..151ef49 100644
--- a/services/core/java/com/android/server/am/LockTaskController.java
+++ b/services/core/java/com/android/server/am/LockTaskController.java
@@ -555,11 +555,12 @@
             return;
         }
 
-        if (mLockTaskModeTasks.isEmpty()) {
+        final Intent taskIntent = task.intent;
+        if (mLockTaskModeTasks.isEmpty() && taskIntent != null) {
             mSupervisor.mRecentTasks.onLockTaskModeStateChanged(lockTaskModeState, task.userId);
             // Start lock task on the handler thread
             mHandler.post(() -> performStartLockTask(
-                    task.intent.getComponent().getPackageName(),
+                    taskIntent.getComponent().getPackageName(),
                     task.userId,
                     lockTaskModeState));
         }
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index 9964053..f60c5c3 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -1,4 +1,34 @@
+
+# Applications & Processes
+yamasani@google.com
+jsharkey@google.com
+hackbod@google.com
+omakoto@google.com
+fkupolov@google.com
+ctate@google.com
+huiyu@google.com
+mwachens@google.com
+sudheersai@google.com
+suprabh@google.com
+
+# Windows & Activities
+ogunwale@google.com
+jjaggi@google.com
+racarr@google.com
+chaviw@google.com
+brycelee@google.com
+akulian@google.com
+roosa@google.com
+
+# Permissions & Packages
+svetoslavganov@google.com
+toddke@google.com
+
+# Londoners
+michaelwr@google.com
+narayan@google.com
+
 per-file GlobalSettingsToPropertiesMapper.java=fkupolov@google.com
 per-file GlobalSettingsToPropertiesMapper.java=omakoto@google.com
 per-file GlobalSettingsToPropertiesMapper.java=svetoslavganov@google.com
-per-file GlobalSettingsToPropertiesMapper.java=yamasani@google.com
\ No newline at end of file
+per-file GlobalSettingsToPropertiesMapper.java=yamasani@google.com
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 550c37a..e0aa2a2 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -219,6 +219,9 @@
     }
 
     public void unregisterCancelListenerLocked(IResultReceiver receiver) {
+        if (mCancelCallbacks == null) {
+            return; // Already unregistered or detached.
+        }
         mCancelCallbacks.unregister(receiver);
         if (mCancelCallbacks.getRegisteredCallbackCount() <= 0) {
             mCancelCallbacks = null;
@@ -280,6 +283,14 @@
                 final int callingUid = Binder.getCallingUid();
                 final int callingPid = Binder.getCallingPid();
 
+                // Extract options before clearing calling identity
+                SafeActivityOptions mergedOptions = key.options;
+                if (mergedOptions == null) {
+                    mergedOptions = SafeActivityOptions.fromBundle(options);
+                } else {
+                    mergedOptions.setCallerOptions(ActivityOptions.fromBundle(options));
+                }
+
                 final long origId = Binder.clearCallingIdentity();
 
                 if (whitelistDuration != null) {
@@ -316,13 +327,6 @@
                 switch (key.type) {
                     case ActivityManager.INTENT_SENDER_ACTIVITY:
                         try {
-                            SafeActivityOptions mergedOptions = key.options;
-                            if (mergedOptions == null) {
-                                mergedOptions = SafeActivityOptions.fromBundle(options);
-                            } else {
-                                mergedOptions.setCallerOptions(ActivityOptions.fromBundle(options));
-                            }
-
                             // Note when someone has a pending intent, even from different
                             // users, then there's no need to ensure the calling user matches
                             // the target user, so validateIncomingUser is always false below.
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index a20452b..06a3078 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -22,8 +22,10 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -550,7 +552,7 @@
                 continue;
             }
 
-            ComponentName cn = tr.intent.getComponent();
+            ComponentName cn = tr.intent != null ? tr.intent.getComponent() : null;
             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
             if (sameComponent) {
@@ -1255,7 +1257,8 @@
         for (int i = 0; i < recentsCount; i++) {
             final TaskRecord tr = mTasks.get(i);
             if (task != tr) {
-                if (!task.hasCompatibleActivityType(tr) || task.userId != tr.userId) {
+                if (!hasCompatibleActivityTypeAndWindowingMode(task, tr)
+                        || task.userId != tr.userId) {
                     continue;
                 }
                 final Intent trIntent = tr.intent;
@@ -1547,4 +1550,29 @@
 
         return rti;
     }
+
+    /**
+     * @return Whether the activity types and windowing modes of the two tasks are considered
+     *         compatible. This is necessary because we currently don't persist the activity type
+     *         or the windowing mode with the task, so they can be undefined when restored.
+     */
+    private boolean hasCompatibleActivityTypeAndWindowingMode(TaskRecord t1, TaskRecord t2) {
+        final int activityType = t1.getActivityType();
+        final int windowingMode = t1.getWindowingMode();
+        final boolean isUndefinedType = activityType == ACTIVITY_TYPE_UNDEFINED;
+        final boolean isUndefinedMode = windowingMode == WINDOWING_MODE_UNDEFINED;
+        final int otherActivityType = t2.getActivityType();
+        final int otherWindowingMode = t2.getWindowingMode();
+        final boolean isOtherUndefinedType = otherActivityType == ACTIVITY_TYPE_UNDEFINED;
+        final boolean isOtherUndefinedMode = otherWindowingMode == WINDOWING_MODE_UNDEFINED;
+
+        // An activity type and windowing mode is compatible if they are the exact same type/mode,
+        // or if one of the type/modes is undefined
+        final boolean isCompatibleType = activityType == otherActivityType
+                || isUndefinedType || isOtherUndefinedType;
+        final boolean isCompatibleMode = windowingMode == otherWindowingMode
+                || isUndefinedMode || isOtherUndefinedMode;
+
+        return isCompatibleType && isCompatibleMode;
+    }
 }
diff --git a/services/core/java/com/android/server/am/RecentsAnimation.java b/services/core/java/com/android/server/am/RecentsAnimation.java
index f2ed6a2..b5047ae 100644
--- a/services/core/java/com/android/server/am/RecentsAnimation.java
+++ b/services/core/java/com/android/server/am/RecentsAnimation.java
@@ -101,9 +101,7 @@
                         : ACTIVITY_TYPE_HOME;
         final ActivityStack targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
                 mTargetActivityType);
-        ActivityRecord targetActivity = targetStack != null
-                ? targetStack.getTopActivity()
-                : null;
+        ActivityRecord targetActivity = getTargetActivity(targetStack, intent.getComponent());
         final boolean hasExistingActivity = targetActivity != null;
         if (hasExistingActivity) {
             final ActivityDisplay display = targetActivity.getDisplay();
@@ -149,6 +147,14 @@
                 display.moveStackBehindBottomMostVisibleStack(targetStack);
                 if (DEBUG) Slog.d(TAG, "Moved stack=" + targetStack + " behind stack="
                             + display.getStackAbove(targetStack));
+
+                // If there are multiple tasks in the target stack (ie. the home stack, with 3p
+                // and default launchers coexisting), then move the task to the top as a part of
+                // moving the stack to the front
+                if (targetStack.topTask() != targetActivity.getTask()) {
+                    targetStack.addTask(targetActivity.getTask(), true /* toTop */,
+                            "startRecentsActivity");
+                }
             } else {
                 // No recents activity
                 ActivityOptions options = ActivityOptions.makeBasic();
@@ -179,8 +185,9 @@
             targetActivity.mLaunchTaskBehind = true;
 
             // Fetch all the surface controls and pass them to the client to get the animation
-            // started
-            mWindowManager.cancelRecentsAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION,
+            // started. Cancel any existing recents animation running synchronously (do not hold the
+            // WM lock)
+            mWindowManager.cancelRecentsAnimationSynchronously(REORDER_MOVE_TO_ORIGINAL_POSITION,
                     "startRecentsActivity");
             mWindowManager.initializeRecentsAnimation(mTargetActivityType, recentsAnimationRunner,
                     this, display.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds());
@@ -200,12 +207,11 @@
         }
     }
 
-    @Override
-    public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode) {
+    private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode) {
         synchronized (mService) {
             if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller="
-                        + mWindowManager.getRecentsAnimationController()
-                        + " reorderMode=" + reorderMode);
+                    + mWindowManager.getRecentsAnimationController()
+                    + " reorderMode=" + reorderMode);
 
             // Cancel the associated assistant data request
             if (mAssistDataRequester != null) {
@@ -298,6 +304,16 @@
         }
     }
 
+    @Override
+    public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode,
+            boolean runSychronously) {
+        if (runSychronously) {
+            finishAnimation(reorderMode);
+        } else {
+            mService.mHandler.post(() -> finishAnimation(reorderMode));
+        }
+    }
+
     /**
      * Called only when the animation should be canceled prior to starting.
      */
@@ -322,4 +338,22 @@
         }
         return null;
     }
+
+    /**
+     * @return the top activity in the {@param targetStack} matching the {@param component}, or just
+     * the top activity of the top task if no task matches the component.
+     */
+    private ActivityRecord getTargetActivity(ActivityStack targetStack, ComponentName component) {
+        if (targetStack == null) {
+            return null;
+        }
+
+        for (int i = targetStack.getChildCount() - 1; i >= 0; i--) {
+            final TaskRecord task = (TaskRecord) targetStack.getChildAt(i);
+            if (task.getBaseIntent().getComponent().equals(component)) {
+                return task.getTopActivity();
+            }
+        }
+        return targetStack.getTopActivity();
+    }
 }
diff --git a/services/core/java/com/android/server/am/SafeActivityOptions.java b/services/core/java/com/android/server/am/SafeActivityOptions.java
index 2de75273..0fb69e7 100644
--- a/services/core/java/com/android/server/am/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/am/SafeActivityOptions.java
@@ -32,6 +32,7 @@
 import android.content.pm.ActivityInfo;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Process;
 import android.os.UserHandle;
 import android.util.Slog;
 import android.view.RemoteAnimationAdapter;
@@ -78,6 +79,9 @@
         mOriginalCallingPid = Binder.getCallingPid();
         mOriginalCallingUid = Binder.getCallingUid();
         mOriginalOptions = options;
+        if (mOriginalCallingPid == Process.myPid()) {
+            Slog.wtf(TAG, "Safe activity options constructed after clearing calling id");
+        }
     }
 
     /**
@@ -89,6 +93,9 @@
         mRealCallingPid = Binder.getCallingPid();
         mRealCallingUid = Binder.getCallingUid();
         mCallerOptions = options;
+        if (mRealCallingPid == Process.myPid()) {
+            Slog.wtf(TAG, "setCallerOptions called after clearing calling id");
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 0e418ad..9a5b1a6 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -203,7 +203,8 @@
     String rootAffinity;    // Initial base affinity, or null; does not change from initial root.
     final IVoiceInteractionSession voiceSession;    // Voice interaction session driving task
     final IVoiceInteractor voiceInteractor;         // Associated interactor to provide to app
-    Intent intent;          // The original intent that started the task.
+    Intent intent;          // The original intent that started the task. Note that this value can
+                            // be null.
     Intent affinityIntent;  // Intent of affinity-moved activity that started this task.
     int effectiveUid;       // The current effective uid of the identity of this task.
     ComponentName origActivity; // The non-alias activity component of the intent.
@@ -897,12 +898,12 @@
         // the real activity that will be launched not the alias, so we need to use an intent with
         // the component name pointing to the real activity not the alias in the activity record.
         intent.setComponent(r.realActivity);
-        return this.intent.filterEquals(intent);
+        return intent.filterEquals(this.intent);
     }
 
     boolean returnsToHomeStack() {
         final int returnHomeFlags = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME;
-        return (intent.getFlags() & returnHomeFlags) == returnHomeFlags;
+        return intent != null && (intent.getFlags() & returnHomeFlags) == returnHomeFlags;
     }
 
     void setPrevAffiliate(TaskRecord prevAffiliate) {
@@ -1819,7 +1820,7 @@
             final StackWindowController stackController = mStack.getWindowContainerController();
             stackController.adjustConfigurationForBounds(bounds, insetBounds,
                     mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density,
-                    config, parentConfig);
+                    config, parentConfig, getWindowingMode());
         } else {
             throw new IllegalArgumentException("Expected stack when calculating override config");
         }
@@ -2165,9 +2166,11 @@
             out.endTag(null, TAG_AFFINITYINTENT);
         }
 
-        out.startTag(null, TAG_INTENT);
-        intent.saveToXml(out);
-        out.endTag(null, TAG_INTENT);
+        if (intent != null) {
+            out.startTag(null, TAG_INTENT);
+            intent.saveToXml(out);
+            out.endTag(null, TAG_INTENT);
+        }
 
         final ArrayList<ActivityRecord> activities = mActivities;
         final int numActivities = activities.size();
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index db3efab..324df41 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -5671,8 +5671,6 @@
         // enable A2DP before notifying A2DP connection to avoid unnecessary processing in
         // audio policy manager
         VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];
-        sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
-                AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, streamState, 0);
         setBluetoothA2dpOnInt(true, eventSource);
         AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
                 AudioSystem.DEVICE_STATE_AVAILABLE, address, name);
@@ -5940,12 +5938,6 @@
         // address is not used for now, but may be used when multiple a2dp devices are supported
         synchronized (mA2dpAvrcpLock) {
             mAvrcpAbsVolSupported = support;
-            sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
-                    AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0,
-                    mStreamStates[AudioSystem.STREAM_MUSIC], 0);
-            sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
-                    AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0,
-                    mStreamStates[AudioSystem.STREAM_RING], 0);
         }
     }
 
@@ -7015,6 +7007,7 @@
     final int LOG_NB_EVENTS_WIRED_DEV_CONNECTION = 30;
     final int LOG_NB_EVENTS_FORCE_USE = 20;
     final int LOG_NB_EVENTS_VOLUME = 40;
+    final int LOG_NB_EVENTS_DYN_POLICY = 10;
 
     final private AudioEventLogger mModeLogger = new AudioEventLogger(LOG_NB_EVENTS_PHONE_STATE,
             "phone state (logged after successfull call to AudioSystem.setPhoneState(int))");
@@ -7031,6 +7024,9 @@
     final private AudioEventLogger mVolumeLogger = new AudioEventLogger(LOG_NB_EVENTS_VOLUME,
             "volume changes (logged when command received by AudioService)");
 
+    final private AudioEventLogger mDynPolicyLogger = new AudioEventLogger(LOG_NB_EVENTS_DYN_POLICY,
+            "dynamic policy events (logged when command received by AudioService)");
+
     private static final String[] RINGER_MODE_NAMES = new String[] {
             "SILENT",
             "VIBRATE",
@@ -7098,6 +7094,7 @@
         pw.print("  mAvrcpAbsVolSupported="); pw.println(mAvrcpAbsVolSupported);
 
         dumpAudioPolicies(pw);
+        mDynPolicyLogger.dump(pw);
 
         mPlaybackMonitor.dump(pw);
 
@@ -7422,8 +7419,6 @@
             boolean hasFocusListener, boolean isFocusPolicy, boolean isVolumeController) {
         AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback);
 
-        if (DEBUG_AP) Log.d(TAG, "registerAudioPolicy for " + pcb.asBinder()
-                + " with config:" + policyConfig);
         String regId = null;
         // error handling
         boolean hasPermissionForPolicy =
@@ -7435,6 +7430,8 @@
             return null;
         }
 
+        mDynPolicyLogger.log((new AudioEventLogger.StringEvent("registerAudioPolicy for "
+                + pcb.asBinder() + " with config:" + policyConfig)).printLog(TAG));
         synchronized (mAudioPolicies) {
             try {
                 if (mAudioPolicies.containsKey(pcb.asBinder())) {
@@ -7457,7 +7454,8 @@
     }
 
     public void unregisterAudioPolicyAsync(IAudioPolicyCallback pcb) {
-        if (DEBUG_AP) Log.d(TAG, "unregisterAudioPolicyAsync for " + pcb.asBinder());
+        mDynPolicyLogger.log((new AudioEventLogger.StringEvent("unregisterAudioPolicyAsync for "
+                + pcb.asBinder()).printLog(TAG)));
         synchronized (mAudioPolicies) {
             AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder());
             if (app == null) {
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index ff86453..dc564ba 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -267,6 +267,7 @@
 
     public void releasePlayer(int piid, int binderUid) {
         if (DEBUG) { Log.v(TAG, "releasePlayer() for piid=" + piid); }
+        boolean change = false;
         synchronized(mPlayerLock) {
             final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid));
             if (checkConfigurationCaller(piid, apc, binderUid)) {
@@ -275,9 +276,12 @@
                 mPlayers.remove(new Integer(piid));
                 mDuckingManager.removeReleased(apc);
                 checkVolumeForPrivilegedAlarm(apc, AudioPlaybackConfiguration.PLAYER_STATE_RELEASED);
-                apc.handleStateEvent(AudioPlaybackConfiguration.PLAYER_STATE_RELEASED);
+                change = apc.handleStateEvent(AudioPlaybackConfiguration.PLAYER_STATE_RELEASED);
             }
         }
+        if (change) {
+            dispatchPlaybackChange(true /*iplayerreleased*/);
+        }
     }
 
     // Implementation of AudioPlaybackConfiguration.PlayerDeathMonitor
diff --git a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
index 34309b6..2feea41 100644
--- a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
@@ -103,6 +103,9 @@
                 conf.dump(pw);
             }
         }
+        pw.println("\n");
+        // log
+        sEventLogger.dump(pw);
     }
 
     private ArrayList<AudioRecordingConfiguration> anonymizeForPublicConsumption(
@@ -190,6 +193,9 @@
             case AudioManager.RECORD_CONFIG_EVENT_STOP:
                 // return failure if an unknown recording session stopped
                 configChanged = (mRecordConfigs.remove(new Integer(session)) != null);
+                if (configChanged) {
+                    sEventLogger.log(new RecordingEvent(event, uid, session, source, null));
+                }
                 break;
             case AudioManager.RECORD_CONFIG_EVENT_START:
                 final AudioFormat clientFormat = new AudioFormat.Builder()
@@ -231,6 +237,9 @@
                     mRecordConfigs.put(sessionKey, updatedConfig);
                     configChanged = true;
                 }
+                if (configChanged) {
+                    sEventLogger.log(new RecordingEvent(event, uid, session, source, packageName));
+                }
                 break;
             default:
                 Log.e(TAG, String.format("Unknown event %d for session %d, source %d",
@@ -281,4 +290,36 @@
             mDispatcherCb.asBinder().unlinkToDeath(this, 0);
         }
     }
+
+    /**
+     * Inner class for recording event logging
+     */
+    private static final class RecordingEvent extends AudioEventLogger.Event {
+        private final int mRecEvent;
+        private final int mClientUid;
+        private final int mSession;
+        private final int mSource;
+        private final String mPackName;
+
+        RecordingEvent(int event, int uid, int session, int source, String packName) {
+            mRecEvent = event;
+            mClientUid = uid;
+            mSession = session;
+            mSource = source;
+            mPackName = packName;
+        }
+
+        @Override
+        public String eventToString() {
+            return new StringBuilder("rec ").append(
+                        mRecEvent == AudioManager.RECORD_CONFIG_EVENT_START ? "start" : "stop ")
+                    .append(" uid:").append(mClientUid)
+                    .append(" session:").append(mSession)
+                    .append(" src:").append(MediaRecorder.toLogFriendlyAudioSource(mSource))
+                    .append(mPackName == null ? "" : " pack:" + mPackName).toString();
+        }
+    }
+
+    private static final AudioEventLogger sEventLogger = new AudioEventLogger(50,
+            "recording activity as reported through AudioSystem.AudioRecordingCallback");
 }
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index f74ac47..5db20b0 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -621,7 +621,7 @@
 
     private boolean clipboardAccessAllowed(int op, String callingPackage, int callingUid) {
         // Check the AppOp.
-        if (mAppOps.checkOp(op, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) {
+        if (mAppOps.noteOp(op, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) {
             return false;
         }
         try {
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index e840a29..03d8f39 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -1279,7 +1279,9 @@
                 case Process.SYSTEM_UID:
                     break; // Okay
                 default:
-                    throw new SecurityException("Invalid extras specified.");
+                    final String msg = "Invalid extras specified.";
+                    Log.w(TAG, msg + " requestsync -f/-F needs to run on 'adb shell'");
+                    throw new SecurityException(msg);
             }
         }
     }
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index a55870f..5fa4245 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -68,6 +68,7 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
@@ -454,6 +455,7 @@
         }
     };
 
+    private final HandlerThread mThread;
     private final SyncHandler mSyncHandler;
     private final SyncManagerConstants mConstants;
 
@@ -604,7 +606,9 @@
 
         mSyncAdapters = new SyncAdaptersCache(mContext);
 
-        mSyncHandler = new SyncHandler(BackgroundThread.get().getLooper());
+        mThread = new HandlerThread("SyncManager", android.os.Process.THREAD_PRIORITY_BACKGROUND);
+        mThread.start();
+        mSyncHandler = new SyncHandler(mThread.getLooper());
 
         mSyncAdapters.setListener(new RegisteredServicesCacheListener<SyncAdapterType>() {
             @Override
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index f403953..0425844 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -316,7 +316,7 @@
         return true;
     }
 
-    private void resetShortTermModel() {
+    public void resetShortTermModel() {
         mBrightnessMapper.clearUserDataPoints();
         mShortTermModelValid = true;
         mShortTermModelAnchor = -1;
diff --git a/services/core/java/com/android/server/display/ColorDisplayService.java b/services/core/java/com/android/server/display/ColorDisplayService.java
index 37035c3..030c915 100644
--- a/services/core/java/com/android/server/display/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/ColorDisplayService.java
@@ -293,7 +293,7 @@
             mColorMatrixAnimator.cancel();
         }
 
-        setCoefficientMatrix(getContext(), mode == ColorDisplayController.COLOR_MODE_SATURATED);
+        setCoefficientMatrix(getContext(), DisplayTransformManager.isColorModeNative(mode));
         setMatrix(mController.getColorTemperature(), mMatrixNight);
 
         final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 46e883c..3b35d02 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -774,14 +774,8 @@
             brightness = mScreenBrightnessForVr;
         }
 
-        boolean setBrightnessToOverride = false;
         if (brightness < 0 && mPowerRequest.screenBrightnessOverride > 0) {
             brightness = mPowerRequest.screenBrightnessOverride;
-            // If there's a screen brightness override, we want to reset the brightness to it
-            // whenever the user changes it, to communicate that these changes aren't taking
-            // effect. However, for a nicer user experience, we don't do it here, but rather after
-            // the temporary brightness has been taken into account.
-            setBrightnessToOverride = true;
         }
 
         final boolean autoBrightnessEnabledInDoze =
@@ -804,12 +798,6 @@
             brightnessIsTemporary = true;
         }
 
-        // Reset the brightness to the screen brightness override to communicate to the user that
-        // her changes aren't taking effect.
-        if (setBrightnessToOverride && !brightnessIsTemporary) {
-            putScreenBrightnessSetting(brightness);
-        }
-
         final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment();
         if (autoBrightnessAdjustmentChanged) {
             mTemporaryAutoBrightnessAdjustment = Float.NaN;
@@ -1452,6 +1440,9 @@
         if (userSwitch) {
             // Don't treat user switches as user initiated change.
             mCurrentScreenBrightnessSetting = mPendingScreenBrightnessSetting;
+            if (mAutomaticBrightnessController != null) {
+                mAutomaticBrightnessController.resetShortTermModel();
+            }
         }
         mPendingAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
         // We don't bother with a pending variable for VR screen brightness since we just
diff --git a/services/core/java/com/android/server/display/DisplayTransformManager.java b/services/core/java/com/android/server/display/DisplayTransformManager.java
index a94f049..57d88e1 100644
--- a/services/core/java/com/android/server/display/DisplayTransformManager.java
+++ b/services/core/java/com/android/server/display/DisplayTransformManager.java
@@ -60,14 +60,24 @@
     private static final int SURFACE_FLINGER_TRANSACTION_DALTONIZER = 1014;
 
     private static final String PERSISTENT_PROPERTY_SATURATION = "persist.sys.sf.color_saturation";
-    private static final String PERSISTENT_PROPERTY_NATIVE_MODE = "persist.sys.sf.native_mode";
+    private static final String PERSISTENT_PROPERTY_DISPLAY_COLOR = "persist.sys.sf.native_mode";
 
+    /**
+     * SurfaceFlinger global saturation factor.
+     */
     private static final int SURFACE_FLINGER_TRANSACTION_SATURATION = 1022;
-    private static final int SURFACE_FLINGER_TRANSACTION_NATIVE_MODE = 1023;
+    /**
+     * SurfaceFlinger display color (managed, unmanaged, etc.).
+     */
+    private static final int SURFACE_FLINGER_TRANSACTION_DISPLAY_COLOR = 1023;
 
     private static final float COLOR_SATURATION_NATURAL = 1.0f;
     private static final float COLOR_SATURATION_BOOSTED = 1.1f;
 
+    private static final int DISPLAY_COLOR_MANAGED = 0;
+    private static final int DISPLAY_COLOR_UNMANAGED = 1;
+    private static final int DISPLAY_COLOR_ENHANCED = 2;
+
     /**
      * Map of level -> color transformation matrix.
      */
@@ -220,20 +230,37 @@
         }
     }
 
+    /**
+     * Return true when colors are stretched from the working color space to the
+     * native color space.
+     */
     public static boolean isNativeModeEnabled() {
-        return SystemProperties.getBoolean(PERSISTENT_PROPERTY_NATIVE_MODE, false);
+        return SystemProperties.getInt(PERSISTENT_PROPERTY_DISPLAY_COLOR,
+                DISPLAY_COLOR_MANAGED) != DISPLAY_COLOR_MANAGED;
+    }
+
+    /**
+     * Return true when the specified colorMode stretches colors from the
+     * working color space to the native color space.
+     */
+    public static boolean isColorModeNative(int colorMode) {
+        return !(colorMode == ColorDisplayController.COLOR_MODE_NATURAL ||
+                 colorMode == ColorDisplayController.COLOR_MODE_BOOSTED);
     }
 
     public boolean setColorMode(int colorMode, float[] nightDisplayMatrix) {
         if (colorMode == ColorDisplayController.COLOR_MODE_NATURAL) {
             applySaturation(COLOR_SATURATION_NATURAL);
-            setNativeMode(false);
+            setDisplayColor(DISPLAY_COLOR_MANAGED);
         } else if (colorMode == ColorDisplayController.COLOR_MODE_BOOSTED) {
             applySaturation(COLOR_SATURATION_BOOSTED);
-            setNativeMode(false);
+            setDisplayColor(DISPLAY_COLOR_MANAGED);
         } else if (colorMode == ColorDisplayController.COLOR_MODE_SATURATED) {
             applySaturation(COLOR_SATURATION_NATURAL);
-            setNativeMode(true);
+            setDisplayColor(DISPLAY_COLOR_UNMANAGED);
+        } else if (colorMode == ColorDisplayController.COLOR_MODE_AUTOMATIC) {
+            applySaturation(COLOR_SATURATION_NATURAL);
+            setDisplayColor(DISPLAY_COLOR_ENHANCED);
         }
         setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, nightDisplayMatrix);
 
@@ -265,17 +292,17 @@
     /**
      * Toggles native mode on/off in SurfaceFlinger.
      */
-    private void setNativeMode(boolean enabled) {
-        SystemProperties.set(PERSISTENT_PROPERTY_NATIVE_MODE, enabled ? "1" : "0");
+    private void setDisplayColor(int color) {
+        SystemProperties.set(PERSISTENT_PROPERTY_DISPLAY_COLOR, Integer.toString(color));
         final IBinder flinger = ServiceManager.getService(SURFACE_FLINGER);
         if (flinger != null) {
             final Parcel data = Parcel.obtain();
             data.writeInterfaceToken("android.ui.ISurfaceComposer");
-            data.writeInt(enabled ? 1 : 0);
+            data.writeInt(color);
             try {
-                flinger.transact(SURFACE_FLINGER_TRANSACTION_NATIVE_MODE, data, null, 0);
+                flinger.transact(SURFACE_FLINGER_TRANSACTION_DISPLAY_COLOR, data, null, 0);
             } catch (RemoteException ex) {
-                Log.e(TAG, "Failed to set native mode", ex);
+                Log.e(TAG, "Failed to set display color", ex);
             } finally {
                 data.recycle();
             }
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index ef40a1c..c9f92d2 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -619,6 +619,15 @@
 
     void startRemove(IBinder token, int fingerId, int groupId, int userId,
             IFingerprintServiceReceiver receiver, boolean restricted, boolean internal) {
+        if (token == null) {
+            Slog.w(TAG, "startRemove: token is null");
+            return;
+        }
+        if (receiver == null) {
+            Slog.w(TAG, "startRemove: receiver is null");
+            return;
+        }
+
         IBiometricsFingerprint daemon = getFingerprintDaemon();
         if (daemon == null) {
             Slog.w(TAG, "startRemove: no fingerprint HAL!");
diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
index fa48b5e..04d5795 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -90,7 +90,10 @@
                 return;
             } else if (job.hasTimingDelayConstraint() && evaluateTimingDelayConstraint(job,
                     nowElapsedMillis)) {
-                return;
+                if (!job.hasDeadlineConstraint()) {
+                    // If it doesn't have a deadline, we'll never have to touch it again.
+                    return;
+                }
             }
 
             boolean isInsert = false;
diff --git a/services/core/java/com/android/server/location/GnssBatchingProvider.java b/services/core/java/com/android/server/location/GnssBatchingProvider.java
new file mode 100644
index 0000000..f3918ee
--- /dev/null
+++ b/services/core/java/com/android/server/location/GnssBatchingProvider.java
@@ -0,0 +1,145 @@
+package com.android.server.location;
+
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Manages GNSS Batching operations.
+ *
+ * <p>This class is not thread safe (It's client's responsibility to make sure calls happen on
+ * the same thread).
+ */
+public class GnssBatchingProvider {
+
+    private static final String TAG = "GnssBatchingProvider";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final GnssBatchingProviderNative mNative;
+    private boolean mEnabled;
+    private boolean mStarted;
+    private long mPeriodNanos;
+    private boolean mWakeOnFifoFull;
+
+    GnssBatchingProvider() {
+        this(new GnssBatchingProviderNative());
+    }
+
+    @VisibleForTesting
+    GnssBatchingProvider(GnssBatchingProviderNative gnssBatchingProviderNative) {
+        mNative = gnssBatchingProviderNative;
+    }
+
+    /**
+     * Returns the GNSS batching size
+     */
+    public int getBatchSize() {
+        return mNative.getBatchSize();
+    }
+
+    /** Enable GNSS batching. */
+    public void enable() {
+        mEnabled = mNative.initBatching();
+        if (!mEnabled) {
+            Log.e(TAG, "Failed to initialize GNSS batching");
+        }
+    }
+
+    /**
+     * Starts the hardware batching operation
+     */
+    public boolean start(long periodNanos, boolean wakeOnFifoFull) {
+        if (!mEnabled) {
+            throw new IllegalStateException();
+        }
+        if (periodNanos <= 0) {
+            Log.e(TAG, "Invalid periodNanos " + periodNanos +
+                    " in batching request, not started");
+            return false;
+        }
+        mStarted = mNative.startBatch(periodNanos, wakeOnFifoFull);
+        if (mStarted) {
+            mPeriodNanos = periodNanos;
+            mWakeOnFifoFull = wakeOnFifoFull;
+        }
+        return mStarted;
+    }
+
+    /**
+     * Forces a flush of existing locations from the hardware batching
+     */
+    public void flush() {
+        if (!mStarted) {
+            Log.w(TAG, "Cannot flush since GNSS batching has not started.");
+            return;
+        }
+        mNative.flushBatch();
+    }
+
+    /**
+     * Stops the batching operation
+     */
+    public boolean stop() {
+        boolean stopped = mNative.stopBatch();
+        if (stopped) {
+            mStarted = false;
+        }
+        return stopped;
+    }
+
+    /** Disable GNSS batching. */
+    public void disable() {
+        stop();
+        mNative.cleanupBatching();
+        mEnabled = false;
+    }
+
+    // TODO(b/37460011): Use this with death recovery logic.
+    void resumeIfStarted() {
+        if (DEBUG) {
+            Log.d(TAG, "resumeIfStarted");
+        }
+        if (mStarted) {
+            mNative.startBatch(mPeriodNanos, mWakeOnFifoFull);
+        }
+    }
+
+    @VisibleForTesting
+    static class GnssBatchingProviderNative {
+        public int getBatchSize() {
+            return native_get_batch_size();
+        }
+
+        public boolean startBatch(long periodNanos, boolean wakeOnFifoFull) {
+            return native_start_batch(periodNanos, wakeOnFifoFull);
+        }
+
+        public void flushBatch() {
+            native_flush_batch();
+        }
+
+        public boolean stopBatch() {
+            return native_stop_batch();
+        }
+
+        public boolean initBatching() {
+            return native_init_batching();
+        }
+
+        public void cleanupBatching() {
+            native_cleanup_batching();
+        }
+    }
+
+    private static native int native_get_batch_size();
+
+    private static native boolean native_start_batch(long periodNanos, boolean wakeOnFifoFull);
+
+    private static native void native_flush_batch();
+
+    private static native boolean native_stop_batch();
+
+    private static native boolean native_init_batching();
+
+    private static native void native_cleanup_batching();
+}
diff --git a/services/core/java/com/android/server/location/GnssGeofenceProvider.java b/services/core/java/com/android/server/location/GnssGeofenceProvider.java
new file mode 100644
index 0000000..6ac4aeb
--- /dev/null
+++ b/services/core/java/com/android/server/location/GnssGeofenceProvider.java
@@ -0,0 +1,188 @@
+package com.android.server.location;
+
+import android.location.IGpsGeofenceHardware;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+
+/**
+ * Manages GNSS Geofence operations.
+ */
+class GnssGeofenceProvider extends IGpsGeofenceHardware.Stub {
+
+    private static final String TAG = "GnssGeofenceProvider";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    /** Holds the parameters of a geofence. */
+    private static class GeofenceEntry {
+        public int geofenceId;
+        public double latitude;
+        public double longitude;
+        public double radius;
+        public int lastTransition;
+        public int monitorTransitions;
+        public int notificationResponsiveness;
+        public int unknownTimer;
+        public boolean paused;
+    }
+
+    private final GnssGeofenceProviderNative mNative;
+    private final SparseArray<GeofenceEntry> mGeofenceEntries = new SparseArray<>();
+    private final Handler mHandler;
+
+    GnssGeofenceProvider(Looper looper) {
+        this(looper, new GnssGeofenceProviderNative());
+    }
+
+    @VisibleForTesting
+    GnssGeofenceProvider(Looper looper, GnssGeofenceProviderNative gnssGeofenceProviderNative) {
+        mHandler = new Handler(looper);
+        mNative = gnssGeofenceProviderNative;
+    }
+
+    // TODO(b/37460011): use this method in HAL death recovery.
+    void resumeIfStarted() {
+        if (DEBUG) {
+            Log.d(TAG, "resumeIfStarted");
+        }
+        mHandler.post(() -> {
+            for (int i = 0; i < mGeofenceEntries.size(); i++) {
+                GeofenceEntry entry = mGeofenceEntries.valueAt(i);
+                boolean added = mNative.addGeofence(entry.geofenceId, entry.latitude,
+                        entry.longitude,
+                        entry.radius,
+                        entry.lastTransition, entry.monitorTransitions,
+                        entry.notificationResponsiveness, entry.unknownTimer);
+                if (added && entry.paused) {
+                    mNative.pauseGeofence(entry.geofenceId);
+                }
+            }
+        });
+    }
+
+    private boolean runOnHandlerThread(Callable<Boolean> callable) {
+        FutureTask<Boolean> futureTask = new FutureTask<>(callable);
+        mHandler.post(futureTask);
+        try {
+            return futureTask.get();
+        } catch (InterruptedException | ExecutionException e) {
+            Log.e(TAG, "Failed running callable.", e);
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isHardwareGeofenceSupported() {
+        return runOnHandlerThread(mNative::isGeofenceSupported);
+    }
+
+    @Override
+    public boolean addCircularHardwareGeofence(int geofenceId, double latitude,
+            double longitude, double radius, int lastTransition, int monitorTransitions,
+            int notificationResponsiveness, int unknownTimer) {
+        return runOnHandlerThread(() -> {
+            boolean added = mNative.addGeofence(geofenceId, latitude, longitude, radius,
+                    lastTransition, monitorTransitions, notificationResponsiveness,
+                    unknownTimer);
+            if (added) {
+                GeofenceEntry entry = new GeofenceEntry();
+                entry.geofenceId = geofenceId;
+                entry.latitude = latitude;
+                entry.longitude = longitude;
+                entry.radius = radius;
+                entry.lastTransition = lastTransition;
+                entry.monitorTransitions = monitorTransitions;
+                entry.notificationResponsiveness = notificationResponsiveness;
+                entry.unknownTimer = unknownTimer;
+                mGeofenceEntries.put(geofenceId, entry);
+            }
+            return added;
+        });
+    }
+
+    @Override
+    public boolean removeHardwareGeofence(int geofenceId) {
+        return runOnHandlerThread(() -> {
+            boolean removed = mNative.removeGeofence(geofenceId);
+            if (removed) {
+                mGeofenceEntries.remove(geofenceId);
+            }
+            return removed;
+        });
+    }
+
+    @Override
+    public boolean pauseHardwareGeofence(int geofenceId) {
+        return runOnHandlerThread(() -> {
+            boolean paused = mNative.pauseGeofence(geofenceId);
+            if (paused) {
+                GeofenceEntry entry = mGeofenceEntries.get(geofenceId);
+                if (entry != null) {
+                    entry.paused = true;
+                }
+            }
+            return paused;
+        });
+    }
+
+    @Override
+    public boolean resumeHardwareGeofence(int geofenceId, int monitorTransitions) {
+        return runOnHandlerThread(() -> {
+            boolean resumed = mNative.resumeGeofence(geofenceId, monitorTransitions);
+            if (resumed) {
+                GeofenceEntry entry = mGeofenceEntries.get(geofenceId);
+                if (entry != null) {
+                    entry.paused = false;
+                    entry.monitorTransitions = monitorTransitions;
+                }
+            }
+            return resumed;
+        });
+    }
+
+    @VisibleForTesting
+    static class GnssGeofenceProviderNative {
+        public boolean isGeofenceSupported() {
+            return native_is_geofence_supported();
+        }
+
+        public boolean addGeofence(int geofenceId, double latitude, double longitude, double radius,
+                int lastTransition, int monitorTransitions, int notificationResponsiveness,
+                int unknownTimer) {
+            return native_add_geofence(geofenceId, latitude, longitude, radius, lastTransition,
+                    monitorTransitions, notificationResponsiveness, unknownTimer);
+        }
+
+        public boolean removeGeofence(int geofenceId) {
+            return native_remove_geofence(geofenceId);
+        }
+
+        public boolean resumeGeofence(int geofenceId, int transitions) {
+            return native_resume_geofence(geofenceId, transitions);
+        }
+
+        public boolean pauseGeofence(int geofenceId) {
+            return native_pause_geofence(geofenceId);
+        }
+    }
+
+    private static native boolean native_is_geofence_supported();
+
+    private static native boolean native_add_geofence(int geofenceId, double latitude,
+            double longitude, double radius, int lastTransition, int monitorTransitions,
+            int notificationResponsivenes, int unknownTimer);
+
+    private static native boolean native_remove_geofence(int geofenceId);
+
+    private static native boolean native_resume_geofence(int geofenceId, int transitions);
+
+    private static native boolean native_pause_geofence(int geofenceId);
+}
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index a808298..64750b0 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -418,6 +418,8 @@
     private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
     private final LocationChangeListener mFusedLocationListener = new FusedLocationListener();
     private final NtpTimeHelper mNtpTimeHelper;
+    private final GnssBatchingProvider mGnssBatchingProvider;
+    private final GnssGeofenceProvider mGnssGeofenceProvider;
 
     // Handler for processing events
     private Handler mHandler;
@@ -492,7 +494,7 @@
     }
 
     public IGpsGeofenceHardware getGpsGeofenceProxy() {
-        return mGpsGeofenceBinder;
+        return mGnssGeofenceProvider;
     }
 
     public GnssMeasurementsProvider getGnssMeasurementsProvider() {
@@ -816,37 +818,7 @@
             }
         };
 
-        mGnssMeasurementsProvider = new GnssMeasurementsProvider(mHandler) {
-            @Override
-            public boolean isAvailableInPlatform() {
-                return native_is_measurement_supported();
-            }
-
-            @Override
-            protected int registerWithService() {
-                int devOptions = Settings.Secure.getInt(mContext.getContentResolver(),
-                        Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0);
-                int fullTrackingToggled = Settings.Global.getInt(mContext.getContentResolver(),
-                        Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING , 0);
-                boolean result = false;
-                if (devOptions == 1 /* Developer Mode enabled */
-                        && fullTrackingToggled == 1 /* Raw Measurements Full Tracking enabled */) {
-                    result =  native_start_measurement_collection(true /* enableFullTracking */);
-                } else {
-                    result =  native_start_measurement_collection(false /* enableFullTracking */);
-                }
-                if (result) {
-                    return RemoteListenerHelper.RESULT_SUCCESS;
-                } else {
-                    return RemoteListenerHelper.RESULT_INTERNAL_ERROR;
-                }
-            }
-
-            @Override
-            protected void unregisterFromService() {
-                native_stop_measurement_collection();
-            }
-
+        mGnssMeasurementsProvider = new GnssMeasurementsProvider(mContext, mHandler) {
             @Override
             protected boolean isGpsEnabled() {
                 return isEnabled();
@@ -855,26 +827,6 @@
 
         mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mHandler) {
             @Override
-            protected boolean isAvailableInPlatform() {
-                return native_is_navigation_message_supported();
-            }
-
-            @Override
-            protected int registerWithService() {
-                boolean result = native_start_navigation_message_collection();
-                if (result) {
-                    return RemoteListenerHelper.RESULT_SUCCESS;
-                } else {
-                    return RemoteListenerHelper.RESULT_INTERNAL_ERROR;
-                }
-            }
-
-            @Override
-            protected void unregisterFromService() {
-                native_stop_navigation_message_collection();
-            }
-
-            @Override
             protected boolean isGpsEnabled() {
                 return isEnabled();
             }
@@ -885,6 +837,8 @@
         mGnssSatelliteBlacklistHelper = new GnssSatelliteBlacklistHelper(mContext,
                 looper, this);
         mHandler.post(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
+        mGnssBatchingProvider = new GnssBatchingProvider();
+        mGnssGeofenceProvider = new GnssGeofenceProvider(looper);
     }
 
     /**
@@ -1028,7 +982,7 @@
                 Log.e(TAG, "Invalid status to release SUPL connection: " + agpsDataConnStatus);
         }
     }
-    
+
     private void handleRequestLocation(boolean independentFromGnss) {
         if (isRequestLocationRateLimited()) {
             if (DEBUG) {
@@ -1061,6 +1015,12 @@
             locationListener = mFusedLocationListener;
         }
 
+        if (!locationManager.isProviderEnabled(provider)) {
+            Log.w(TAG, "Unable to request location since " + provider
+                    + " provider does not exist or is not enabled.");
+            return;
+        }
+
         Log.i(TAG,
                 String.format(
                         "GNSS HAL Requesting location updates from %s provider for %d millis.",
@@ -1267,7 +1227,7 @@
 
             mGnssMeasurementsProvider.onGpsEnabledChanged();
             mGnssNavigationMessageProvider.onGpsEnabledChanged();
-            enableBatching();
+            mGnssBatchingProvider.enable();
         } else {
             synchronized (mLock) {
                 mEnabled = false;
@@ -1299,7 +1259,7 @@
         mAlarmManager.cancel(mWakeupIntent);
         mAlarmManager.cancel(mTimeoutIntent);
 
-        disableBatching();
+        mGnssBatchingProvider.disable();
         // do this before releasing wakelock
         native_cleanup();
 
@@ -1493,31 +1453,6 @@
         }
     }
 
-    private IGpsGeofenceHardware mGpsGeofenceBinder = new IGpsGeofenceHardware.Stub() {
-        public boolean isHardwareGeofenceSupported() {
-            return native_is_geofence_supported();
-        }
-
-        public boolean addCircularHardwareGeofence(int geofenceId, double latitude,
-                double longitude, double radius, int lastTransition, int monitorTransitions,
-                int notificationResponsiveness, int unknownTimer) {
-            return native_add_geofence(geofenceId, latitude, longitude, radius,
-                    lastTransition, monitorTransitions, notificationResponsiveness, unknownTimer);
-        }
-
-        public boolean removeHardwareGeofence(int geofenceId) {
-            return native_remove_geofence(geofenceId);
-        }
-
-        public boolean pauseHardwareGeofence(int geofenceId) {
-            return native_pause_geofence(geofenceId);
-        }
-
-        public boolean resumeHardwareGeofence(int geofenceId, int monitorTransition) {
-            return native_resume_geofence(geofenceId, monitorTransition);
-        }
-    };
-
     private boolean deleteAidingData(Bundle extras) {
         int flags;
 
@@ -2001,58 +1936,11 @@
         };
     }
 
-    public interface GnssBatchingProvider {
-        /**
-         * Returns the GNSS batching size
-         */
-        int getSize();
-
-        /**
-         * Starts the hardware batching operation
-         */
-        boolean start(long periodNanos, boolean wakeOnFifoFull);
-
-        /**
-         * Forces a flush of existing locations from the hardware batching
-         */
-        void flush();
-
-        /**
-         * Stops the batching operation
-         */
-        boolean stop();
-    }
-
     /**
      * @hide
      */
     public GnssBatchingProvider getGnssBatchingProvider() {
-        return new GnssBatchingProvider() {
-            @Override
-            public int getSize() {
-                return native_get_batch_size();
-            }
-
-            @Override
-            public boolean start(long periodNanos, boolean wakeOnFifoFull) {
-                if (periodNanos <= 0) {
-                    Log.e(TAG, "Invalid periodNanos " + periodNanos +
-                            "in batching request, not started");
-                    return false;
-                }
-                return native_start_batch(periodNanos, wakeOnFifoFull);
-            }
-
-            @Override
-            public void flush() {
-                native_flush_batch();
-            }
-
-            @Override
-            public boolean stop() {
-                return native_stop_batch();
-            }
-        };
+        return mGnssBatchingProvider;
     }
 
     public interface GnssMetricsProvider {
@@ -2075,23 +1963,6 @@
     }
 
     /**
-     * Initialize Batching if enabled
-     */
-    private void enableBatching() {
-        if (!native_init_batching()) {
-            Log.e(TAG, "Failed to initialize GNSS batching");
-        }
-    }
-
-    /**
-     * Disable batching
-     */
-    private void disableBatching() {
-        native_stop_batch();
-        native_cleanup_batching();
-    }
-
-    /**
      * called from native code - GNSS location batch callback
      */
     private void reportLocationBatch(Location[] locationArray) {
@@ -2869,33 +2740,6 @@
     private native void native_update_network_state(boolean connected, int type,
             boolean roaming, boolean available, String extraInfo, String defaultAPN);
 
-    // Hardware Geofence support.
-    private static native boolean native_is_geofence_supported();
-
-    private static native boolean native_add_geofence(int geofenceId, double latitude,
-            double longitude, double radius, int lastTransition, int monitorTransitions,
-            int notificationResponsivenes, int unknownTimer);
-
-    private static native boolean native_remove_geofence(int geofenceId);
-
-    private static native boolean native_resume_geofence(int geofenceId, int transitions);
-
-    private static native boolean native_pause_geofence(int geofenceId);
-
-    // Gps Hal measurements support.
-    private static native boolean native_is_measurement_supported();
-
-    private native boolean native_start_measurement_collection(boolean enableFullTracking);
-
-    private native boolean native_stop_measurement_collection();
-
-    // Gps Navigation message support.
-    private static native boolean native_is_navigation_message_supported();
-
-    private native boolean native_start_navigation_message_collection();
-
-    private native boolean native_stop_navigation_message_collection();
-
     // GNSS Configuration
     private static native boolean native_set_supl_version(int version);
 
@@ -2912,19 +2756,5 @@
     private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn);
 
     private static native boolean native_set_satellite_blacklist(int[] constellations, int[] svIds);
-
-    // GNSS Batching
-    private static native int native_get_batch_size();
-
-    private static native boolean native_start_batch(long periodNanos, boolean wakeOnFifoFull);
-
-    private static native void native_flush_batch();
-
-    private static native boolean native_stop_batch();
-
-    private static native boolean native_init_batching();
-
-    private static native void native_cleanup_batching();
-
 }
 
diff --git a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
index 477dae6..0add863 100644
--- a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
@@ -16,12 +16,16 @@
 
 package com.android.server.location;
 
+import android.content.Context;
 import android.location.GnssMeasurementsEvent;
 import android.location.IGnssMeasurementsListener;
 import android.os.Handler;
 import android.os.RemoteException;
+import android.provider.Settings;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  * An base implementation for GPS measurements provider.
  * It abstracts out the responsibility of handling listeners, while still allowing technology
@@ -29,22 +33,73 @@
  *
  * @hide
  */
-public abstract class GnssMeasurementsProvider
-        extends RemoteListenerHelper<IGnssMeasurementsListener> {
+public abstract class GnssMeasurementsProvider extends
+        RemoteListenerHelper<IGnssMeasurementsListener> {
     private static final String TAG = "GnssMeasurementsProvider";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    protected GnssMeasurementsProvider(Handler handler) {
+    private final Context mContext;
+    private final GnssMeasurementProviderNative mNative;
+
+    private boolean mIsCollectionStarted;
+    private boolean mEnableFullTracking;
+
+    protected GnssMeasurementsProvider(Context context, Handler handler) {
+        this(context, handler, new GnssMeasurementProviderNative());
+    }
+
+    @VisibleForTesting
+    GnssMeasurementsProvider(Context context, Handler handler,
+            GnssMeasurementProviderNative aNative) {
         super(handler, TAG);
+        mContext = context;
+        mNative = aNative;
+    }
+
+    // TODO(b/37460011): Use this with death recovery logic.
+    void resumeIfStarted() {
+        if (DEBUG) {
+            Log.d(TAG, "resumeIfStarted");
+        }
+        if (mIsCollectionStarted) {
+            mNative.startMeasurementCollection(mEnableFullTracking);
+        }
+    }
+
+    @Override
+    public boolean isAvailableInPlatform() {
+        return mNative.isMeasurementSupported();
+    }
+
+    @Override
+    protected int registerWithService() {
+        int devOptions = Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
+        int fullTrackingToggled = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING, 0);
+        boolean enableFullTracking = (devOptions == 1 /* Developer Mode enabled */)
+                && (fullTrackingToggled == 1 /* Raw Measurements Full Tracking enabled */);
+        boolean result = mNative.startMeasurementCollection(enableFullTracking);
+        if (result) {
+            mIsCollectionStarted = true;
+            mEnableFullTracking = enableFullTracking;
+            return RemoteListenerHelper.RESULT_SUCCESS;
+        } else {
+            return RemoteListenerHelper.RESULT_INTERNAL_ERROR;
+        }
+    }
+
+    @Override
+    protected void unregisterFromService() {
+        boolean stopped = mNative.stopMeasurementCollection();
+        if (stopped) {
+            mIsCollectionStarted = false;
+        }
     }
 
     public void onMeasurementsAvailable(final GnssMeasurementsEvent event) {
         ListenerOperation<IGnssMeasurementsListener> operation =
-                new ListenerOperation<IGnssMeasurementsListener>() {
-                    @Override
-                    public void execute(IGnssMeasurementsListener listener) throws RemoteException {
-                        listener.onGnssMeasurementsReceived(event);
-                    }
-                };
+                listener -> listener.onGnssMeasurementsReceived(event);
         foreach(operation);
     }
 
@@ -98,4 +153,25 @@
             listener.onStatusChanged(mStatus);
         }
     }
+
+    @VisibleForTesting
+    static class GnssMeasurementProviderNative {
+        public boolean isMeasurementSupported() {
+            return native_is_measurement_supported();
+        }
+
+        public boolean startMeasurementCollection(boolean enableFullTracking) {
+            return native_start_measurement_collection(enableFullTracking);
+        }
+
+        public boolean stopMeasurementCollection() {
+            return native_stop_measurement_collection();
+        }
+    }
+
+    private static native boolean native_is_measurement_supported();
+
+    private static native boolean native_start_measurement_collection(boolean enableFullTracking);
+
+    private static native boolean native_stop_measurement_collection();
 }
diff --git a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
index df3c49b..1b4fd18 100644
--- a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
+++ b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
@@ -22,6 +22,8 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  * An base implementation for GPS navigation messages provider.
  * It abstracts out the responsibility of handling listeners, while still allowing technology
@@ -32,9 +34,53 @@
 public abstract class GnssNavigationMessageProvider
         extends RemoteListenerHelper<IGnssNavigationMessageListener> {
     private static final String TAG = "GnssNavigationMessageProvider";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final GnssNavigationMessageProviderNative mNative;
+    private boolean mCollectionStarted;
 
     protected GnssNavigationMessageProvider(Handler handler) {
+        this(handler, new GnssNavigationMessageProviderNative());
+    }
+
+    @VisibleForTesting
+    GnssNavigationMessageProvider(Handler handler, GnssNavigationMessageProviderNative aNative) {
         super(handler, TAG);
+        mNative = aNative;
+    }
+
+    // TODO(b/37460011): Use this with death recovery logic.
+    void resumeIfStarted() {
+        if (DEBUG) {
+            Log.d(TAG, "resumeIfStarted");
+        }
+        if (mCollectionStarted) {
+            mNative.startNavigationMessageCollection();
+        }
+    }
+
+    @Override
+    protected boolean isAvailableInPlatform() {
+        return mNative.isNavigationMessageSupported();
+    }
+
+    @Override
+    protected int registerWithService() {
+        boolean result = mNative.startNavigationMessageCollection();
+        if (result) {
+            mCollectionStarted = true;
+            return RemoteListenerHelper.RESULT_SUCCESS;
+        } else {
+            return RemoteListenerHelper.RESULT_INTERNAL_ERROR;
+        }
+    }
+
+    @Override
+    protected void unregisterFromService() {
+        boolean stopped = mNative.stopNavigationMessageCollection();
+        if (stopped) {
+            mCollectionStarted = false;
+        }
     }
 
     public void onNavigationMessageAvailable(final GnssNavigationMessage event) {
@@ -96,4 +142,25 @@
             listener.onStatusChanged(mStatus);
         }
     }
+
+    @VisibleForTesting
+    static class GnssNavigationMessageProviderNative {
+        public boolean isNavigationMessageSupported() {
+            return native_is_navigation_message_supported();
+        }
+
+        public boolean startNavigationMessageCollection() {
+            return native_start_navigation_message_collection();
+        }
+
+        public boolean stopNavigationMessageCollection() {
+            return native_stop_navigation_message_collection();
+        }
+    }
+
+    private static native boolean native_is_navigation_message_supported();
+
+    private static native boolean native_start_navigation_message_collection();
+
+    private static native boolean native_stop_navigation_message_collection();
 }
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index f1fd00b..1078f6e 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1742,7 +1742,8 @@
             if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
                 hash = LockPatternUtils.patternToHash(LockPatternUtils.stringToPattern(credential));
             } else {
-                hash = mLockPatternUtils.passwordToHash(credential, userId);
+                hash = mLockPatternUtils.legacyPasswordToHash(credential, userId)
+                        .getBytes(StandardCharsets.UTF_8);
             }
             if (Arrays.equals(hash, storedHash.hash)) {
                 if (storedHash.type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN) {
@@ -2532,6 +2533,33 @@
         mRecoverableKeyStoreManager.lockScreenSecretChanged(credentialType, credential, userId);
     }
 
+    /**
+     * Returns a fixed pseudorandom byte string derived from the user's synthetic password.
+     * This is used to salt the password history hash to protect the hash against offline
+     * bruteforcing, since rederiving this value requires a successful authentication.
+     */
+    @Override
+    public byte[] getHashFactor(String currentCredential, int userId) throws RemoteException {
+        checkPasswordReadPermission(userId);
+        if (TextUtils.isEmpty(currentCredential)) {
+            currentCredential = null;
+        }
+        synchronized (mSpManager) {
+            if (!isSyntheticPasswordBasedCredentialLocked(userId)) {
+                Slog.w(TAG, "Synthetic password not enabled");
+                return null;
+            }
+            long handle = getSyntheticPasswordHandleLocked(userId);
+            AuthenticationResult auth = mSpManager.unwrapPasswordBasedSyntheticPassword(
+                    getGateKeeperService(), handle, currentCredential, userId, null);
+            if (auth.authToken == null) {
+                Slog.w(TAG, "Current credential is incorrect");
+                return null;
+            }
+            return auth.authToken.derivePasswordHashFactor();
+        }
+    }
+
     private long addEscrowToken(byte[] token, int userId) throws RemoteException {
         if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId);
         synchronized (mSpManager) {
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index 0700ab3..596daeb 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -123,6 +123,7 @@
     private static final byte[] PERSONALIZATION_FBE_KEY = "fbe-key".getBytes();
     private static final byte[] PERSONALIZATION_AUTHSECRET_KEY = "authsecret-hal".getBytes();
     private static final byte[] PERSONALIZATION_SP_SPLIT = "sp-split".getBytes();
+    private static final byte[] PERSONALIZATION_PASSWORD_HASH = "pw-hash".getBytes();
     private static final byte[] PERSONALIZATION_E0 = "e0-encryption".getBytes();
     private static final byte[] PERSONALISATION_WEAVER_PASSWORD = "weaver-pwd".getBytes();
     private static final byte[] PERSONALISATION_WEAVER_KEY = "weaver-key".getBytes();
@@ -165,6 +166,11 @@
                     syntheticPassword.getBytes());
         }
 
+        public byte[] derivePasswordHashFactor() {
+            return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_PASSWORD_HASH,
+                    syntheticPassword.getBytes());
+        }
+
         private void initialize(byte[] P0, byte[] P1) {
             this.P1 = P1;
             this.syntheticPassword = String.valueOf(HexEncoding.encode(
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index b0ed85d..5eb7397 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -71,10 +71,8 @@
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Objects;
 import java.util.Set;
 import java.util.function.Predicate;
-import java.util.stream.Collectors;
 
 /**
  * Manages the lifecycle of application-provided services bound by system server.
@@ -406,15 +404,20 @@
             approvedByType = new ArrayMap<>();
             mApproved.put(userId, approvedByType);
         }
+
+        ArraySet<String> approvedList = approvedByType.get(isPrimary);
+        if (approvedList == null) {
+            approvedList = new ArraySet<>();
+            approvedByType.put(isPrimary, approvedList);
+        }
+
         String[] approvedArray = approved.split(ENABLED_SERVICES_SEPARATOR);
-        final ArraySet<String> approvedList = new ArraySet<>();
         for (String pkgOrComponent : approvedArray) {
             String approvedItem = getApprovedValue(pkgOrComponent);
             if (approvedItem != null) {
                 approvedList.add(approvedItem);
             }
         }
-        approvedByType.put(isPrimary, approvedList);
     }
 
     protected boolean isComponentEnabledForPackage(String pkg) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 17f6d5c..9ee28d8 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.notification;
 
+import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
 import static android.app.NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED;
 import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED;
 import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED;
@@ -711,7 +712,7 @@
                 StatusBarNotification sbn = r.sbn;
                 cancelNotification(callingUid, callingPid, sbn.getPackageName(), sbn.getTag(),
                         sbn.getId(), Notification.FLAG_AUTO_CANCEL,
-                        Notification.FLAG_FOREGROUND_SERVICE, false, r.getUserId(),
+                        FLAG_FOREGROUND_SERVICE, false, r.getUserId(),
                         REASON_CLICK, nv.rank, nv.count, null);
                 nv.recycle();
                 reportUserInteraction(r);
@@ -755,7 +756,7 @@
                 }
             }
             cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
-                    Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
+                    Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE,
                     true, userId, REASON_CANCEL, nv.rank, nv.count,null);
             nv.recycle();
         }
@@ -986,7 +987,7 @@
                     cancelNotification(record.sbn.getUid(), record.sbn.getInitialPid(),
                             record.sbn.getPackageName(), record.sbn.getTag(),
                             record.sbn.getId(), 0,
-                            Notification.FLAG_FOREGROUND_SERVICE, true, record.getUserId(),
+                            FLAG_FOREGROUND_SERVICE, true, record.getUserId(),
                             REASON_TIMEOUT, null);
                 }
             }
@@ -2085,7 +2086,7 @@
             // Don't allow client applications to cancel foreground service notis or autobundled
             // summaries.
             final int mustNotHaveFlags = isCallingUidSystem() ? 0 :
-                    (Notification.FLAG_FOREGROUND_SERVICE | Notification.FLAG_AUTOGROUP_SUMMARY);
+                    (FLAG_FOREGROUND_SERVICE | Notification.FLAG_AUTOGROUP_SUMMARY);
             cancelNotification(Binder.getCallingUid(), Binder.getCallingPid(), pkg, tag, id, 0,
                     mustNotHaveFlags, false, userId, REASON_APP_CANCEL, null);
         }
@@ -2100,7 +2101,7 @@
             // Calling from user space, don't allow the canceling of actively
             // running foreground services.
             cancelAllNotificationsInt(Binder.getCallingUid(), Binder.getCallingPid(),
-                    pkg, null, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId,
+                    pkg, null, 0, FLAG_FOREGROUND_SERVICE, true, userId,
                     REASON_APP_CANCEL_ALL, null);
         }
 
@@ -2686,7 +2687,7 @@
         private void cancelNotificationFromListenerLocked(ManagedServiceInfo info,
                 int callingUid, int callingPid, String pkg, String tag, int id, int userId) {
             cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
-                    Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
+                    Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE,
                     true,
                     userId, REASON_LISTENER_CANCEL, info);
         }
@@ -3877,7 +3878,9 @@
                     for (int j = 0; j < listenerSize; j++) {
                         if (i > 0) pw.print(',');
                         final ManagedServiceInfo listener = listeners.valueAt(i);
-                        pw.print(listener.component);
+                        if (listener != null) {
+                            pw.print(listener.component);
+                        }
                     }
                 }
                 pw.println(')');
@@ -3963,7 +3966,7 @@
             // FLAG_FOREGROUND_SERVICE, we have to revert to the flags we received
             // initially *and* force remove FLAG_FOREGROUND_SERVICE.
             sbn.getNotification().flags =
-                    (r.mOriginalFlags & ~Notification.FLAG_FOREGROUND_SERVICE);
+                    (r.mOriginalFlags & ~FLAG_FOREGROUND_SERVICE);
             mRankingHelper.sort(mNotificationList);
             mListeners.notifyPostedLocked(r, r);
         }
@@ -4049,7 +4052,7 @@
         final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
         r.setIsAppImportanceLocked(mRankingHelper.getIsAppImportanceLocked(pkg, callingUid));
 
-        if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0
+        if ((notification.flags & FLAG_FOREGROUND_SERVICE) != 0
                 && (channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0
                 && (r.getImportance() == IMPORTANCE_MIN || r.getImportance() == IMPORTANCE_NONE)) {
             // Increase the importance of foreground service notifications unless the user had an
@@ -4430,7 +4433,7 @@
                         mUsageStats.registerUpdatedByApp(r, old);
                         // Make sure we don't lose the foreground service state.
                         notification.flags |=
-                                old.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE;
+                                old.getNotification().flags & FLAG_FOREGROUND_SERVICE;
                         r.isUpdate = true;
                         r.setInterruptive(isVisuallyInterruptive(old, r));
                     }
@@ -4439,7 +4442,7 @@
 
                     // Ensure if this is a foreground service that the proper additional
                     // flags are set.
-                    if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
+                    if ((notification.flags & FLAG_FOREGROUND_SERVICE) != 0) {
                         notification.flags |= Notification.FLAG_ONGOING_EVENT
                                 | Notification.FLAG_NO_CLEAR;
                     }
@@ -4507,6 +4510,13 @@
         if (oldN.extras == null || newN.extras == null) {
             return false;
         }
+
+        // Ignore visual interruptions from foreground services because users
+        // consider them one 'session'. Count them for everything else.
+        if (r != null && (r.sbn.getNotification().flags & FLAG_FOREGROUND_SERVICE) != 0) {
+            return false;
+        }
+
         if (!Objects.equals(oldN.extras.get(Notification.EXTRA_TITLE),
                 newN.extras.get(Notification.EXTRA_TITLE))) {
             return true;
@@ -5810,7 +5820,7 @@
             final StatusBarNotification childSbn = childR.sbn;
             if ((childSbn.isGroup() && !childSbn.getNotification().isGroupSummary()) &&
                     childR.getGroupKey().equals(parentNotification.getGroupKey())
-                    && (childR.getFlags() & Notification.FLAG_FOREGROUND_SERVICE) == 0
+                    && (childR.getFlags() & FLAG_FOREGROUND_SERVICE) == 0
                     && (flagChecker == null || flagChecker.apply(childR.getFlags()))) {
                 EventLogTags.writeNotificationCancel(callingUid, callingPid, pkg, childSbn.getId(),
                         childSbn.getTag(), userId, 0, 0, reason, listenerName);
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 156f702..658c7f1 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -173,18 +173,6 @@
         }
     }
 
-    public boolean shouldSuppressWhenScreenOff() {
-        synchronized (mConfig) {
-            return !mConfig.allowWhenScreenOff;
-        }
-    }
-
-    public boolean shouldSuppressWhenScreenOn() {
-        synchronized (mConfig) {
-            return !mConfig.allowWhenScreenOn;
-        }
-    }
-
     public void addCallback(Callback callback) {
         mCallbacks.add(callback);
     }
@@ -592,14 +580,12 @@
             return;
         }
         pw.printf("allow(alarms=%b,media=%b,system=%b,calls=%b,callsFrom=%s,repeatCallers=%b,"
-                + "messages=%b,messagesFrom=%s,"
-                + "events=%b,reminders=%b,whenScreenOff=%b,whenScreenOn=%b)\n",
+                + "messages=%b,messagesFrom=%s,events=%b,reminders=%b)\n",
                 config.allowAlarms, config.allowMedia, config.allowSystem,
                 config.allowCalls, ZenModeConfig.sourceToString(config.allowCallsFrom),
                 config.allowRepeatCallers, config.allowMessages,
                 ZenModeConfig.sourceToString(config.allowMessagesFrom),
-                config.allowEvents, config.allowReminders, config.allowWhenScreenOff,
-                config.allowWhenScreenOn);
+                config.allowEvents, config.allowReminders);
         pw.printf(" disallow(visualEffects=%s)\n", config.suppressedVisualEffects);
         pw.print(prefix); pw.print("  manualRule="); pw.println(config.manualRule);
         if (config.automaticRules.isEmpty()) return;
@@ -1185,7 +1171,7 @@
 
     private void showZenUpgradeNotification(int zen) {
         final boolean showNotification = mIsBootComplete
-                && zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
+                && zen != Global.ZEN_MODE_OFF
                 && Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.SHOW_ZEN_UPGRADE_NOTIFICATION, 0) != 0;
 
@@ -1204,17 +1190,20 @@
                 mContext.getResources().getString(R.string.global_action_settings));
         int title = R.string.zen_upgrade_notification_title;
         int content = R.string.zen_upgrade_notification_content;
+        int drawable = R.drawable.ic_zen_24dp;
         if (NotificationManager.Policy.areAllVisualEffectsSuppressed(
                 getNotificationPolicy().suppressedVisualEffects)) {
             title = R.string.zen_upgrade_notification_visd_title;
             content = R.string.zen_upgrade_notification_visd_content;
+            drawable = R.drawable.ic_dnd_block_notifications;
         }
+
         Intent onboardingIntent = new Intent(Settings.ZEN_MODE_ONBOARDING);
         onboardingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
         return new Notification.Builder(mContext, SystemNotificationChannels.DO_NOT_DISTURB)
                 .setAutoCancel(true)
                 .setSmallIcon(R.drawable.ic_settings_24dp)
-                .setLargeIcon(Icon.createWithResource(mContext, R.drawable.ic_zen_24dp))
+                .setLargeIcon(Icon.createWithResource(mContext, drawable))
                 .setContentTitle(mContext.getResources().getString(title))
                 .setContentText(mContext.getResources().getString(content))
                 .setContentIntent(PendingIntent.getActivity(mContext, 0, onboardingIntent,
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 74eb2ea..c57f97b 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -254,7 +254,11 @@
     }
 
     /**
-     * Returns true if the settings were modified for this target.
+     * Update the state of any overlays for this target.
+     *
+     * Returns true if the system should refresh the app's overlay paths (i.e.
+     * if the settings were modified for this target, or there is at least one
+     * enabled framework overlay).
      */
     private boolean updateAllOverlaysForTarget(@NonNull final String targetPackageName,
             final int userId, final int flags) {
@@ -277,6 +281,10 @@
                 }
             }
         }
+
+        // check for enabled framework overlays
+        modified = modified || !getEnabledOverlayPackageNames("android", userId).isEmpty();
+
         return modified;
     }
 
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 595de9e..feac8e6 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -21,6 +21,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
 import android.app.AppGlobals;
+import android.app.IApplicationThread;
 import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.Context;
@@ -560,7 +561,7 @@
         }
 
         @Override
-        public void startActivityAsUser(String callingPackage,
+        public void startActivityAsUser(IApplicationThread caller, String callingPackage,
                 ComponentName component, Rect sourceBounds,
                 Bundle opts, UserHandle user) throws RemoteException {
             if (!canAccessProfile(user.getIdentifier(), "Cannot start activity")) {
@@ -574,6 +575,8 @@
                     | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
             launchIntent.setPackage(component.getPackageName());
 
+            boolean canLaunch = false;
+
             final int callingUid = injectBinderCallingUid();
             long ident = Binder.clearCallingIdentity();
             try {
@@ -604,35 +607,42 @@
                         // this component so ok to launch.
                         launchIntent.setPackage(null);
                         launchIntent.setComponent(component);
-                        mContext.startActivityAsUser(launchIntent, opts, user);
-                        return;
+                        canLaunch = true;
+                        break;
                     }
                 }
-                throw new SecurityException("Attempt to launch activity without "
-                        + " category Intent.CATEGORY_LAUNCHER " + component);
+                if (!canLaunch) {
+                    throw new SecurityException("Attempt to launch activity without "
+                            + " category Intent.CATEGORY_LAUNCHER " + component);
+                }
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
+            mActivityManagerInternal.startActivityAsUser(caller, callingPackage,
+                    launchIntent, opts, user.getIdentifier());
         }
 
         @Override
-        public void showAppDetailsAsUser(String callingPackage, ComponentName component,
+        public void showAppDetailsAsUser(IApplicationThread caller,
+                String callingPackage, ComponentName component,
                 Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException {
             if (!canAccessProfile(user.getIdentifier(), "Cannot show app details")) {
                 return;
             }
 
+            final Intent intent;
             long ident = Binder.clearCallingIdentity();
             try {
                 String packageName = component.getPackageName();
-                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
+                intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                         Uri.fromParts("package", packageName, null));
                 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                 intent.setSourceBounds(sourceBounds);
-                mContext.startActivityAsUser(intent, opts, user);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
+            mActivityManagerInternal.startActivityAsUser(caller, callingPackage,
+                    intent, opts, user.getIdentifier());
         }
 
         /** Checks if user is a profile of or same as listeningUser.
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2ac29e7..ad0ca6e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4227,6 +4227,11 @@
                     || appId == Process.ROOT_UID) {
                 return false;
             }
+            // Installer gets to see all static libs.
+            if (PackageManager.PERMISSION_GRANTED
+                    == checkUidPermission(Manifest.permission.INSTALL_PACKAGES, uid)) {
+                return false;
+            }
         }
 
         // No package means no static lib as it is always on internal storage
@@ -8428,7 +8433,7 @@
 
                 // Delete invalid userdata apps
                 if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&
-                        errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
+                        errorCode != PackageManager.INSTALL_SUCCEEDED) {
                     logCriticalInfo(Log.WARN,
                             "Deleting invalid package at " + parseResult.scanFile);
                     removeCodePathLI(parseResult.scanFile);
@@ -9989,8 +9994,12 @@
         }
 
         // Scan as privileged apps that share a user with a priv-app.
-        if (((scanFlags & SCAN_AS_PRIVILEGED) == 0) && !pkg.isPrivileged()
-                && (pkg.mSharedUserId != null)) {
+        final boolean skipVendorPrivilegeScan = ((scanFlags & SCAN_AS_VENDOR) != 0)
+                && SystemProperties.getInt("ro.vndk.version", 28) < 28;
+        if (((scanFlags & SCAN_AS_PRIVILEGED) == 0)
+                && !pkg.isPrivileged()
+                && (pkg.mSharedUserId != null)
+                && !skipVendorPrivilegeScan) {
             SharedUserSetting sharedUserSetting = null;
             try {
                 sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
@@ -13640,25 +13649,15 @@
             // install reason correctly.
             return installReason;
         }
-
-        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
-            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
-        if (dpm != null) {
-            ComponentName owner = null;
-            try {
-                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
-                if (owner == null) {
-                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
-                }
-            } catch (RemoteException e) {
-            }
-            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
-                // If the install is being performed by a device or profile owner, the install
-                // reason should be enterprise policy.
-                return PackageManager.INSTALL_REASON_POLICY;
-            }
+        final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(
+                UserHandle.getUserId(installerUid));
+        if (ownerPackage != null && ownerPackage.equals(installerPackageName)) {
+            // If the install is being performed by a device or profile owner, the install
+            // reason should be enterprise policy.
+            return PackageManager.INSTALL_REASON_POLICY;
         }
 
+
         if (installReason == PackageManager.INSTALL_REASON_POLICY) {
             // If the install is being performed by a regular app (i.e. neither system app nor
             // device or profile owner), we have no reason to believe that the app is acting on
@@ -14055,7 +14054,11 @@
             throw new IllegalArgumentException("CallingPackage " + callingPackage + " does not"
                     + " belong to calling app id " + UserHandle.getAppId(callingUid));
         }
-
+        if (!PLATFORM_PACKAGE_NAME.equals(callingPackage)
+                && mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId) != null) {
+            throw new UnsupportedOperationException("Cannot suspend/unsuspend packages. User "
+                    + userId + " has an active DO or PO");
+        }
         if (ArrayUtils.isEmpty(packageNames)) {
             return packageNames;
         }
@@ -22474,9 +22477,13 @@
         }
         final String volumeUuid = pkg.volumeUuid;
         final String packageName = pkg.packageName;
-        final ApplicationInfo app = (ps == null)
+
+        ApplicationInfo app = (ps == null)
                 ? pkg.applicationInfo
                 : PackageParser.generateApplicationInfo(pkg, 0, ps.readUserState(userId), userId);
+        if (app == null) {
+            app = pkg.applicationInfo;
+        }
 
         final int appId = UserHandle.getAppId(app.uid);
 
diff --git a/services/core/java/com/android/server/pm/ProtectedPackages.java b/services/core/java/com/android/server/pm/ProtectedPackages.java
index e67364a..a374e14 100644
--- a/services/core/java/com/android/server/pm/ProtectedPackages.java
+++ b/services/core/java/com/android/server/pm/ProtectedPackages.java
@@ -88,6 +88,13 @@
         return false;
     }
 
+    public synchronized String getDeviceOwnerOrProfileOwnerPackage(int userId) {
+        if (mDeviceOwnerUserId == userId) {
+            return mDeviceOwnerPackage;
+        }
+        return mProfileOwnerPackages.get(userId);
+    }
+
     /**
      * Returns {@code true} if a given package is protected. Otherwise, returns {@code false}.
      *
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index a35b193..9af02a1 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -234,6 +234,7 @@
 import android.util.proto.ProtoOutputStream;
 import android.view.Display;
 import android.view.DisplayCutout;
+import android.view.DisplayInfo;
 import android.view.Gravity;
 import android.view.HapticFeedbackConstants;
 import android.view.IApplicationToken;
@@ -6094,7 +6095,7 @@
         // Cancel any pending remote recents animations before handling the button itself. In the
         // case where we are going home and the recents animation has already started, just cancel
         // the recents animation, leaving the home stack in place for the pending start activity
-        if (isNavBarVirtKey && !down) {
+        if (isNavBarVirtKey && !down && !canceled) {
             boolean isHomeKey = keyCode == KeyEvent.KEYCODE_HOME;
             mActivityManagerInternal.cancelRecentsAnimation(!isHomeKey);
         }
@@ -7191,14 +7192,35 @@
     }
 
     @Override
-    public boolean isDockSideAllowed(int dockSide) {
+    public boolean isDockSideAllowed(int dockSide, int originalDockSide, int displayWidth,
+            int displayHeight, int displayRotation) {
+        final int barPosition = navigationBarPosition(displayWidth, displayHeight, displayRotation);
+        return isDockSideAllowed(dockSide, originalDockSide, barPosition, mNavigationBarCanMove);
+    }
 
-        // We do not allow all dock sides at which the navigation bar touches the docked stack.
-        if (!mNavigationBarCanMove) {
-            return dockSide == DOCKED_TOP || dockSide == DOCKED_LEFT || dockSide == DOCKED_RIGHT;
-        } else {
-            return dockSide == DOCKED_TOP || dockSide == DOCKED_LEFT;
+    @VisibleForTesting
+    static boolean isDockSideAllowed(int dockSide, int originalDockSide,
+            int navBarPosition, boolean navigationBarCanMove) {
+        if (dockSide == DOCKED_TOP) {
+            return true;
         }
+
+        if (navigationBarCanMove) {
+            // Only allow the dockside opposite to the nav bar position in landscape
+            return dockSide == DOCKED_LEFT && navBarPosition == NAV_BAR_RIGHT
+                    || dockSide == DOCKED_RIGHT && navBarPosition == NAV_BAR_LEFT;
+        }
+
+        // Side is the same as original side
+        if (dockSide == originalDockSide) {
+            return true;
+        }
+
+        // Only if original docked side was top in portrait will allow left for landscape
+        if (dockSide == DOCKED_LEFT && originalDockSide == DOCKED_TOP) {
+            return true;
+        }
+        return false;
     }
 
     void sendCloseSystemWindows() {
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index ccbf502..8690a83 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -1706,11 +1706,19 @@
             DisplayCutout displayCutout, Rect outInsets);
 
     /**
+     * @param displayRotation the current display rotation
+     * @param displayWidth the current display width
+     * @param displayHeight the current display height
+     * @param dockSide the dockside asking if allowed
+     * @param originalDockSide the side that was original docked to in split screen
      * @return True if a specified {@param dockSide} is allowed on the current device, or false
      *         otherwise. It is guaranteed that at least one dock side for a particular orientation
      *         is allowed, so for example, if DOCKED_RIGHT is not allowed, DOCKED_LEFT is allowed.
+     *         If navigation bar is movable then the docked side would bias towards the
+     *         {@param originalDockSide}.
      */
-    public boolean isDockSideAllowed(int dockSide);
+    public boolean isDockSideAllowed(int dockSide, int originalDockSide, int displayWidth,
+            int displayHeight, int displayRotation);
 
     /**
      * Called when the configuration has changed, and it's safe to load new values from resources.
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 20283a7..a492672 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -719,13 +719,14 @@
      * Plays the wireless charging sound for both wireless and non-wireless charging
      */
     private void playChargingStartedSound() {
-        // TODO (b/77912907): add back charging sound enabled check & default to charging sounds ON
+        final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.CHARGING_SOUNDS_ENABLED, 1) != 0;
         final boolean dndOff = Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
                 == Settings.Global.ZEN_MODE_OFF;
         final String soundPath = Settings.Global.getString(mContext.getContentResolver(),
                 Settings.Global.CHARGING_STARTED_SOUND);
-        if (dndOff && soundPath != null) {
+        if (enabled && dndOff && soundPath != null) {
             final Uri soundUri = Uri.parse("file://" + soundPath);
             if (soundUri != null) {
                 final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
index c527533..cb84cf3 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
@@ -90,6 +90,16 @@
      */
     private final Plugin[] mPlugins;
 
+    public static final int REASON_AUTOMATIC_ON = 0;
+    public static final int REASON_AUTOMATIC_OFF = 1;
+    public static final int REASON_MANUAL_ON = 2;
+    public static final int REASON_MANUAL_OFF = 3;
+    public static final int REASON_STICKY_RESTORE = 4;
+    public static final int REASON_INTERACTIVE_CHANGED = 5;
+    public static final int REASON_POLICY_CHANGED = 6;
+    public static final int REASON_PLUGGED_IN = 7;
+    public static final int REASON_SETTING_CHANGED = 8;
+
     /**
      * Plugin interface. All methods are guaranteed to be called on the same (handler) thread.
      */
@@ -113,7 +123,8 @@
                         return; // No need to send it if not enabled.
                     }
                     // Don't send the broadcast, because we never did so in this case.
-                    mHandler.postStateChanged(/*sendBroadcast=*/ false);
+                    mHandler.postStateChanged(/*sendBroadcast=*/ false,
+                            REASON_INTERACTIVE_CHANGED);
                     break;
                 case Intent.ACTION_BATTERY_CHANGED:
                     synchronized (mLock) {
@@ -184,7 +195,7 @@
         if (!isEnabled()) {
             return; // No need to send it if not enabled.
         }
-        mHandler.postStateChanged(/*sendBroadcast=*/ true);
+        mHandler.postStateChanged(/*sendBroadcast=*/ true, REASON_POLICY_CHANGED);
     }
 
     private class MyHandler extends Handler {
@@ -199,9 +210,9 @@
             super(looper);
         }
 
-        public void postStateChanged(boolean sendBroadcast) {
+        public void postStateChanged(boolean sendBroadcast, int reason) {
             obtainMessage(MSG_STATE_CHANGED, sendBroadcast ?
-                    ARG_SEND_BROADCAST : ARG_DONT_SEND_BROADCAST, 0).sendToTarget();
+                    ARG_SEND_BROADCAST : ARG_DONT_SEND_BROADCAST, reason).sendToTarget();
         }
 
         public void postSystemReady() {
@@ -212,7 +223,9 @@
         public void dispatchMessage(Message msg) {
             switch (msg.what) {
                 case MSG_STATE_CHANGED:
-                    handleBatterySaverStateChanged(msg.arg1 == ARG_SEND_BROADCAST);
+                    handleBatterySaverStateChanged(
+                            msg.arg1 == ARG_SEND_BROADCAST,
+                            msg.arg2);
                     break;
 
                 case MSG_SYSTEM_READY:
@@ -227,14 +240,14 @@
     /**
      * Called by {@link PowerManagerService} to update the battery saver stete.
      */
-    public void enableBatterySaver(boolean enable) {
+    public void enableBatterySaver(boolean enable, int reason) {
         synchronized (mLock) {
             if (mEnabled == enable) {
                 return;
             }
             mEnabled = enable;
 
-            mHandler.postStateChanged(/*sendBroadcast=*/ true);
+            mHandler.postStateChanged(/*sendBroadcast=*/ true, reason);
         }
     }
 
@@ -275,7 +288,7 @@
      * - When battery saver is on the interactive state changes.
      * - When battery saver is on the battery saver policy changes.
      */
-    void handleBatterySaverStateChanged(boolean sendBroadcast) {
+    void handleBatterySaverStateChanged(boolean sendBroadcast, int reason) {
         final LowPowerModeListener[] listeners;
 
         final boolean enabled;
@@ -287,7 +300,8 @@
                     mPreviouslyEnabled ? 1 : 0, // Previously off or on.
                     mEnabled ? 1 : 0, // Now off or on.
                     isInteractive ?  1 : 0, // Device interactive state.
-                    mEnabled ? mBatterySaverPolicy.toEventLogString() : "");
+                    mEnabled ? mBatterySaverPolicy.toEventLogString() : "",
+                    reason);
             mPreviouslyEnabled = mEnabled;
 
             listeners = mListeners.toArray(new LowPowerModeListener[mListeners.size()]);
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
index 2860521..b9f31b1 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
@@ -18,6 +18,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
+import android.os.Handler;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.Global;
@@ -27,6 +28,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.BackgroundThread;
+import com.android.server.EventLogTags;
 import com.android.server.power.BatterySaverPolicy;
 import com.android.server.power.BatterySaverStateMachineProto;
 
@@ -95,6 +97,18 @@
     @GuardedBy("mLock")
     private boolean mBatterySaverSnoozing;
 
+    /**
+     * Last reason passed to {@link #enableBatterySaverLocked}.
+     */
+    @GuardedBy("mLock")
+    private int mLastChangedIntReason;
+
+    /**
+     * Last reason passed to {@link #enableBatterySaverLocked}.
+     */
+    @GuardedBy("mLock")
+    private String mLastChangedStrReason;
+
     private final ContentObserver mSettingsObserver = new ContentObserver(null) {
         @Override
         public void onChange(boolean selfChange) {
@@ -149,11 +163,25 @@
         });
     }
 
+    /**
+     * Run a {@link Runnable} on a background handler.
+     */
     @VisibleForTesting
     void runOnBgThread(Runnable r) {
         BackgroundThread.getHandler().post(r);
     }
 
+    /**
+     * Run a {@link Runnable} on a background handler, but lazily. If the same {@link Runnable},
+     * it'll be first removed before a new one is posted.
+     */
+    @VisibleForTesting
+    void runOnBgThreadLazy(Runnable r, int delayMillis) {
+        final Handler h = BackgroundThread.getHandler();
+        h.removeCallbacks(r);
+        h.postDelayed(r, delayMillis);
+    }
+
     void refreshSettingsLocked() {
         final ContentResolver cr = mContext.getContentResolver();
 
@@ -199,14 +227,23 @@
         mSettingBatterySaverEnabledSticky = batterySaverEnabledSticky;
         mSettingBatterySaverTriggerThreshold = batterySaverTriggerThreshold;
 
+        if (thresholdChanged) {
+            // To avoid spamming the event log, we throttle logging here.
+            runOnBgThreadLazy(mThresholdChangeLogger, 2000);
+        }
+
         if (enabledChanged) {
             final String reason = batterySaverEnabled
                     ? "Global.low_power changed to 1" : "Global.low_power changed to 0";
             enableBatterySaverLocked(/*enable=*/ batterySaverEnabled, /*manual=*/ true,
-                    reason);
+                    BatterySaverController.REASON_SETTING_CHANGED, reason);
         }
     }
 
+    private final Runnable mThresholdChangeLogger = () -> {
+        EventLogTags.writeBatterySaverSetting(mSettingBatterySaverTriggerThreshold);
+    };
+
     /**
      * {@link com.android.server.power.PowerManagerService} calls it when battery state changes.
      *
@@ -257,18 +294,26 @@
         }
         if (mIsPowered) {
             updateSnoozingLocked(false, "Plugged in");
-            enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false, "Plugged in");
+            enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false,
+                    BatterySaverController.REASON_PLUGGED_IN,
+                    "Plugged in");
 
         } else if (mSettingBatterySaverEnabledSticky) {
             // Re-enable BS.
-            enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ true, "Sticky restore");
+            enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ true,
+                    BatterySaverController.REASON_STICKY_RESTORE,
+                    "Sticky restore");
 
         } else if (mIsBatteryLevelLow) {
             if (!mBatterySaverSnoozing && isAutoBatterySaverConfigured()) {
-                enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ false, "Auto ON");
+                enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ false,
+                        BatterySaverController.REASON_AUTOMATIC_ON,
+                        "Auto ON");
             }
         } else { // Battery not low
-            enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false, "Auto OFF");
+            enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false,
+                    BatterySaverController.REASON_AUTOMATIC_OFF,
+                    "Auto OFF");
         }
     }
 
@@ -284,6 +329,8 @@
         }
         synchronized (mLock) {
             enableBatterySaverLocked(/*enable=*/ enabled, /*manual=*/ true,
+                    (enabled ? BatterySaverController.REASON_MANUAL_ON
+                            : BatterySaverController.REASON_MANUAL_OFF),
                     (enabled ? "Manual ON" : "Manual OFF"));
         }
     }
@@ -292,10 +339,11 @@
      * Actually enable / disable battery saver. Write the new state to the global settings
      * and propagate it to {@link #mBatterySaverController}.
      */
-    private void enableBatterySaverLocked(boolean enable, boolean manual, String reason) {
+    private void enableBatterySaverLocked(boolean enable, boolean manual, int intReason,
+            String strReason) {
         if (DEBUG) {
             Slog.d(TAG, "enableBatterySaver: enable=" + enable + " manual=" + manual
-                    + " reason=" + reason);
+                    + " reason=" + strReason + "(" + intReason + ")");
         }
         final boolean wasEnabled = mBatterySaverController.isEnabled();
 
@@ -309,6 +357,8 @@
             if (DEBUG) Slog.d(TAG, "Can't enable: isPowered");
             return;
         }
+        mLastChangedIntReason = intReason;
+        mLastChangedStrReason = strReason;
 
         if (manual) {
             if (enable) {
@@ -330,12 +380,12 @@
             mSettingBatterySaverEnabledSticky = enable;
             putGlobalSetting(Global.LOW_POWER_MODE_STICKY, enable ? 1 : 0);
         }
-        mBatterySaverController.enableBatterySaver(enable);
+        mBatterySaverController.enableBatterySaver(enable, intReason);
 
         if (DEBUG) {
             Slog.d(TAG, "Battery saver: Enabled=" + enable
                     + " manual=" + manual
-                    + " reason=" + reason);
+                    + " reason=" + strReason + "(" + intReason + ")");
         }
     }
 
@@ -365,6 +415,11 @@
             pw.print("  Enabled=");
             pw.println(mBatterySaverController.isEnabled());
 
+            pw.print("  mLastChangedIntReason=");
+            pw.println(mLastChangedIntReason);
+            pw.print("  mLastChangedStrReason=");
+            pw.println(mLastChangedStrReason);
+
             pw.print("  mBootCompleted=");
             pw.println(mBootCompleted);
             pw.print("  mSettingsLoaded=");
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index a9cdafd..507f0a8 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -155,11 +155,10 @@
         enforceAccess(pkg, uri);
         int user = Binder.getCallingUserHandle().getIdentifier();
         uri = maybeAddUserId(uri, user);
-        getOrCreatePinnedSlice(uri, pkg).pin(pkg, specs, token);
+        String slicePkg = getProviderPkg(uri, user);
+        getOrCreatePinnedSlice(uri, slicePkg).pin(pkg, specs, token);
 
-        Uri finalUri = uri;
         mHandler.post(() -> {
-            String slicePkg = getProviderPkg(finalUri, user);
             if (slicePkg != null && !Objects.equals(pkg, slicePkg)) {
                 mAppUsageStats.reportEvent(slicePkg, user,
                         isAssistant(pkg, user) || isDefaultHomeApp(pkg, user)
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index c761754..2f174c2 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -984,6 +984,7 @@
                 (height - thumbnailSize) / 2,
                 (width + thumbnailSize) / 2,
                 (height + thumbnailSize) / 2);
+        drawable.setTint(mContext.getColor(android.R.color.white));
         drawable.draw(canvas);
         picture.endRecording();
 
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 165a409..644e3c3 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -671,6 +671,17 @@
         }
     }
 
+    public void notifyAppStopping() {
+        synchronized(mWindowMap) {
+            if (mContainer == null) {
+                Slog.w(TAG_WM, "Attempted to notify stopping on non-existing app token: "
+                        + mToken);
+                return;
+            }
+            mContainer.detachChildren();
+        }
+    }
+
     public void notifyAppStopped() {
         synchronized(mWindowMap) {
             if (mContainer == null) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index a701d42..966ca41 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -913,12 +913,16 @@
         // try and clean up it's child surfaces. We need to prevent this from
         // happening, so we sever the children, transfering their ownership
         // from the client it-self to the parent surface (owned by us).
+        detachChildren();
+
+        mPendingRelaunchCount++;
+    }
+
+    void detachChildren() {
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final WindowState w = mChildren.get(i);
             w.mWinAnimator.detachChildren();
         }
-
-        mPendingRelaunchCount++;
     }
 
     void finishRelaunching() {
@@ -1984,7 +1988,7 @@
         final Rect frame = win.mFrame;
         final int thumbnailDrawableRes = getTask().mUserId == mService.mCurrentUserId
                 ? R.drawable.ic_account_circle
-                : R.drawable.ic_corp_badge_no_background;
+                : R.drawable.ic_corp_badge;
         final GraphicBuffer thumbnail =
                 mService.mAppTransition
                         .createCrossProfileAppsThumbnail(thumbnailDrawableRes, frame);
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index 112d93c..b2a12be 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -401,12 +401,13 @@
                 + " replacing=" + replacing);
 
         if (replacing) {
-            if (existing.isAnimatingTo(to)) {
+            if (existing.isAnimatingTo(to) && (!moveToFullscreen || existing.mMoveToFullscreen)
+                    && (!moveFromFullscreen || existing.mMoveFromFullscreen)) {
                 // Just let the current animation complete if it has the same destination as the
-                // one we are trying to start.
-                if (DEBUG) Slog.d(TAG, "animateBounds: same destination as existing=" + existing
-                        + " ignoring...");
-
+                // one we are trying to start, and, if moveTo/FromFullscreen was requested, already
+                // has that flag set.
+                if (DEBUG) Slog.d(TAG, "animateBounds: same destination and moveTo/From flags as "
+                        + "existing=" + existing + ", ignoring...");
                 return existing;
             }
 
@@ -434,6 +435,13 @@
                 }
             }
 
+            // We need to keep the previous moveTo/FromFullscreen flag, unless the new animation
+            // specifies a direction.
+            if (!moveFromFullscreen && !moveToFullscreen) {
+                moveToFullscreen = existing.mMoveToFullscreen;
+                moveFromFullscreen = existing.mMoveFromFullscreen;
+            }
+
             // Since we are replacing, we skip both animation start and end callbacks
             existing.cancel();
         }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 4fd31ff..38fb30e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3906,7 +3906,7 @@
      * with {@link #WindowState#assignLayer}
      */
     void assignRelativeLayerForImeTargetChild(SurfaceControl.Transaction t, WindowContainer child) {
-        t.setRelativeLayer(child.getSurfaceControl(), mImeWindowsContainers.getSurfaceControl(), 1);
+        child.assignRelativeLayer(t, mImeWindowsContainers.getSurfaceControl(), 1);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 2cd2ef1..c8baced 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -170,7 +170,7 @@
             final int orientation = mTmpRect2.width() <= mTmpRect2.height()
                     ? ORIENTATION_PORTRAIT
                     : ORIENTATION_LANDSCAPE;
-            final int dockSide = TaskStack.getDockSideUnchecked(mTmpRect, mTmpRect2, orientation);
+            final int dockSide = getDockSide(mTmpRect, mTmpRect2, orientation);
             final int position = DockedDividerUtils.calculatePositionForBounds(mTmpRect, dockSide,
                     getContentWidth());
 
@@ -191,6 +191,39 @@
         return (int) (minWidth / mDisplayContent.getDisplayMetrics().density);
     }
 
+    /**
+     * Get the current docked side. Determined by its location of {@param bounds} within
+     * {@param displayRect} but if both are the same, it will try to dock to each side and determine
+     * if allowed in its respected {@param orientation}.
+     *
+     * @param bounds bounds of the docked task to get which side is docked
+     * @param displayRect bounds of the display that contains the docked task
+     * @param orientation the origination of device
+     * @return current docked side
+     */
+    int getDockSide(Rect bounds, Rect displayRect, int orientation) {
+        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+            // Portrait mode, docked either at the top or the bottom.
+            final int diff = (displayRect.bottom - bounds.bottom) - (bounds.top - displayRect.top);
+            if (diff > 0) {
+                return DOCKED_TOP;
+            } else if (diff < 0) {
+                return DOCKED_BOTTOM;
+            }
+            return canPrimaryStackDockTo(DOCKED_TOP) ? DOCKED_TOP : DOCKED_BOTTOM;
+        } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+            // Landscape mode, docked either on the left or on the right.
+            final int diff = (displayRect.right - bounds.right) - (bounds.left - displayRect.left);
+            if (diff > 0) {
+                return DOCKED_LEFT;
+            } else if (diff < 0) {
+                return DOCKED_RIGHT;
+            }
+            return canPrimaryStackDockTo(DOCKED_LEFT) ? DOCKED_LEFT : DOCKED_RIGHT;
+        }
+        return DOCKED_INVALID;
+    }
+
     void getHomeStackBoundsInDockedMode(Rect outBounds) {
         final DisplayInfo di = mDisplayContent.getDisplayInfo();
         mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
@@ -203,10 +236,20 @@
             outBounds.set(0, mTaskHeightInMinimizedMode + dividerSize + mTmpRect.top,
                     di.logicalWidth, di.logicalHeight);
         } else {
-            // In landscape append the left position with the statusbar height to match the
+            // In landscape also inset the left/right side with the statusbar height to match the
             // minimized size height in portrait mode.
-            outBounds.set(mTaskHeightInMinimizedMode + dividerSize + mTmpRect.left + mTmpRect.top,
-                    0, di.logicalWidth, di.logicalHeight);
+            final TaskStack stack = mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
+            final int primaryTaskWidth = mTaskHeightInMinimizedMode + dividerSize + mTmpRect.top;
+            int left = mTmpRect.left;
+            int right = di.logicalWidth - mTmpRect.right;
+            if (stack != null) {
+                if (stack.getDockSide() == DOCKED_LEFT) {
+                    left += primaryTaskWidth;
+                } else if (stack.getDockSide() == DOCKED_RIGHT) {
+                    right -= primaryTaskWidth;
+                }
+            }
+            outBounds.set(left, 0, right, di.logicalHeight);
         }
     }
 
@@ -420,21 +463,9 @@
      * @return true if the side provided is valid
      */
     boolean canPrimaryStackDockTo(int dockSide) {
-        if (mService.mPolicy.isDockSideAllowed(dockSide)) {
-            // Side is the same as original side
-            if (dockSide == mOriginalDockedSide) {
-                return true;
-            }
-            // Special rule that the top in portrait is always valid
-            if (dockSide == DOCKED_TOP) {
-                return true;
-            }
-            // Only if original docked side was top in portrait will allow left side for landscape
-            if (dockSide == DOCKED_LEFT && mOriginalDockedSide == DOCKED_TOP) {
-                return true;
-            }
-        }
-        return false;
+        final DisplayInfo di = mDisplayContent.getDisplayInfo();
+        return mService.mPolicy.isDockSideAllowed(dockSide, mOriginalDockedSide, di.logicalWidth,
+                di.logicalHeight, di.rotation);
     }
 
     void notifyDockedStackExistsChanged(boolean exists) {
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
new file mode 100644
index 0000000..fff42c5
--- /dev/null
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -0,0 +1,7 @@
+ogunwale@google.com
+jjaggi@google.com
+racarr@google.com
+chaviw@google.com
+brycelee@google.com
+akulian@google.com
+roosa@google.com
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index b057b1d..85e4ac7 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -83,9 +83,8 @@
     private final RecentsAnimationCallbacks mCallbacks;
     private final ArrayList<TaskAnimationAdapter> mPendingAnimations = new ArrayList<>();
     private final int mDisplayId;
-    private final Runnable mFailsafeRunnable = () -> {
-        cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "failSafeRunnable");
-    };
+    private final Runnable mFailsafeRunnable = () ->
+            cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "failSafeRunnable");
 
     // The recents component app token that is shown behind the visibile tasks
     private AppWindowToken mTargetAppToken;
@@ -112,7 +111,7 @@
     private boolean mLinkedToDeathOfRunner;
 
     public interface RecentsAnimationCallbacks {
-        void onAnimationFinished(@ReorderMode int reorderMode);
+        void onAnimationFinished(@ReorderMode int reorderMode, boolean runSychronously);
     }
 
     private final IRecentsAnimationController mController =
@@ -164,7 +163,8 @@
                 // prior to calling the callback
                 mCallbacks.onAnimationFinished(moveHomeToTop
                         ? REORDER_MOVE_TO_TOP
-                        : REORDER_MOVE_TO_ORIGINAL_POSITION);
+                        : REORDER_MOVE_TO_ORIGINAL_POSITION,
+                        true /* runSynchronously */);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -385,7 +385,17 @@
     }
 
     void cancelAnimation(@ReorderMode int reorderMode, String reason) {
-        if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "cancelAnimation(): reason=" + reason);
+        cancelAnimation(reorderMode, false /* runSynchronously */, reason);
+    }
+
+    void cancelAnimationSynchronously(@ReorderMode int reorderMode, String reason) {
+        cancelAnimation(reorderMode, true /* runSynchronously */, reason);
+    }
+
+    private void cancelAnimation(@ReorderMode int reorderMode, boolean runSynchronously,
+            String reason) {
+        if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "cancelAnimation(): reason=" + reason
+                + " runSynchronously=" + runSynchronously);
         synchronized (mService.getWindowManagerLock()) {
             if (mCanceled) {
                 // We've already canceled the animation
@@ -401,8 +411,7 @@
         }
 
         // Clean up and return to the previous app
-        // Don't hold the WM lock here as it calls back to AM/RecentsAnimation
-        mCallbacks.onAnimationFinished(reorderMode);
+        mCallbacks.onAnimationFinished(reorderMode, runSynchronously);
     }
 
     void cleanupAnimation(@ReorderMode int reorderMode) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index fd965fb..50d0d0a 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -692,6 +692,7 @@
                     wallpaperDestroyed = true;
                 }
                 win.destroySurfaceUnchecked();
+                win.mWinAnimator.destroyPreservedSurfaceLocked();
             } while (i > 0);
             mService.mDestroySurface.clear();
         }
diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java
index ddb67b4..653850a 100644
--- a/services/core/java/com/android/server/wm/StackWindowController.java
+++ b/services/core/java/com/android/server/wm/StackWindowController.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import android.app.WindowConfiguration;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Handler;
@@ -244,12 +245,15 @@
     }
 
     /**
-     * Adjusts the screen size in dp's for the {@param config} for the given params.
+     * Adjusts the screen size in dp's for the {@param config} for the given params. The provided
+     * params represent the desired state of a configuration change. Since this utility is used
+     * before mContainer has been updated, any relevant properties (like {@param windowingMode})
+     * need to be passed in.
      */
     public void adjustConfigurationForBounds(Rect bounds, Rect insetBounds,
             Rect nonDecorBounds, Rect stableBounds, boolean overrideWidth,
             boolean overrideHeight, float density, Configuration config,
-            Configuration parentConfig) {
+            Configuration parentConfig, int windowingMode) {
         synchronized (mWindowMap) {
             final TaskStack stack = mContainer;
             final DisplayContent displayContent = stack.getDisplayContent();
@@ -272,10 +276,10 @@
             config.windowConfiguration.setAppBounds(!bounds.isEmpty() ? bounds : null);
             boolean intersectParentBounds = false;
 
-            if (stack.getWindowConfiguration().tasksAreFloating()) {
+            if (WindowConfiguration.isFloating(windowingMode)) {
                 // Floating tasks should not be resized to the screen's bounds.
 
-                if (stack.inPinnedWindowingMode()
+                if (windowingMode == WindowConfiguration.WINDOWING_MODE_PINNED
                         && bounds.width() == mTmpDisplayBounds.width()
                         && bounds.height() == mTmpDisplayBounds.height()) {
                     // If the bounds we are animating is the same as the fullscreen stack
@@ -316,7 +320,7 @@
             config.screenWidthDp = width;
             config.screenHeightDp = height;
             config.smallestScreenWidthDp = getSmallestWidthForTaskBounds(
-                    insetBounds != null ? insetBounds : bounds, density);
+                    insetBounds != null ? insetBounds : bounds, density, windowingMode);
         }
     }
 
@@ -338,11 +342,12 @@
     }
 
     /**
-     * Calculates the smallest width for a task given the {@param bounds}.
+     * Calculates the smallest width for a task given the target {@param bounds} and
+     * {@param windowingMode}. Avoid using values from mContainer since they can be out-of-date.
      *
      * @return the smallest width to be used in the Configuration, in dips
      */
-    private int getSmallestWidthForTaskBounds(Rect bounds, float density) {
+    private int getSmallestWidthForTaskBounds(Rect bounds, float density, int windowingMode) {
         final DisplayContent displayContent = mContainer.getDisplayContent();
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
 
@@ -350,7 +355,7 @@
                 bounds.height() == displayInfo.logicalHeight)) {
             // If the bounds are fullscreen, return the value of the fullscreen configuration
             return displayContent.getConfiguration().smallestScreenWidthDp;
-        } else if (mContainer.getWindowConfiguration().tasksAreFloating()) {
+        } else if (WindowConfiguration.isFloating(windowingMode)) {
             // For floating tasks, calculate the smallest width from the bounds of the task
             return (int) (Math.min(bounds.width(), bounds.height()) / density);
         } else {
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 6b13edd..efc4e73 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -317,7 +317,7 @@
     @VisibleForTesting
     int getSnapshotMode(Task task) {
         final AppWindowToken topChild = task.getTopChild();
-        if (!task.isActivityTypeStandardOrUndefined()) {
+        if (!task.isActivityTypeStandardOrUndefined() && !task.isActivityTypeAssistant()) {
             return SNAPSHOT_MODE_NONE;
         } else if (topChild != null && topChild.shouldUseAppThemeSnapshot()) {
             return SNAPSHOT_MODE_APP_THEME;
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 7d4d7cb..891ee2e 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -1462,27 +1462,7 @@
         }
         dc.getBounds(mTmpRect);
         final int orientation = dc.getConfiguration().orientation;
-        return getDockSideUnchecked(bounds, mTmpRect, orientation);
-    }
-
-    static int getDockSideUnchecked(Rect bounds, Rect displayRect, int orientation) {
-        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
-            // Portrait mode, docked either at the top or the bottom.
-            if (bounds.top - displayRect.top <= displayRect.bottom - bounds.bottom) {
-                return DOCKED_TOP;
-            } else {
-                return DOCKED_BOTTOM;
-            }
-        } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
-            // Landscape mode, docked either on the left or on the right.
-            if (bounds.left - displayRect.left <= displayRect.right - bounds.right) {
-                return DOCKED_LEFT;
-            } else {
-                return DOCKED_RIGHT;
-            }
-        } else {
-            return DOCKED_INVALID;
-        }
+        return dc.getDockedDividerController().getDockSide(bounds, mTmpRect, orientation);
     }
 
     boolean hasTaskForUser(int userId) {
@@ -1722,6 +1702,9 @@
             return true;
         }
         final Task homeTask = homeStack.getTopChild();
+        if (homeTask == null) {
+            return true;
+        }
         final AppWindowToken homeApp = homeTask.getTopVisibleAppToken();
         if (!homeTask.isVisible() || homeApp == null) {
             return true;
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index eab391e..19c5a3d 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -922,6 +922,10 @@
      * @return Whether this WindowContainer should be magnified by the accessibility magnifier.
      */
     boolean shouldMagnify() {
+        if (mSurfaceControl == null) {
+            return false;
+        }
+
         for (int i = 0; i < mChildren.size(); i++) {
             if (!mChildren.get(i).shouldMagnify()) {
                 return false;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 94b853f..10dfdf2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2204,7 +2204,7 @@
             if (mInputMethodWindow == win) {
                 setInputMethodWindowLocked(null);
             }
-            boolean stopped = win.mAppToken != null ? win.mAppToken.mAppStopped : false;
+            boolean stopped = win.mAppToken != null ? win.mAppToken.mAppStopped : true;
             // We set mDestroying=true so AppWindowToken#notifyAppStopped in-to destroy surfaces
             // will later actually destroy the surface if we do not do so here. Normally we leave
             // this to the exit animation.
@@ -2732,17 +2732,15 @@
 
     /**
      * Cancels any running recents animation. The caller should NOT hold the WM lock while calling
-     * this method, as it can call back into AM, and locking will be done in the animation
-     * controller itself.
+     * this method, as it will call back into AM and may cause a deadlock. Any locking will be done
+     * in the animation controller itself.
      */
-    public void cancelRecentsAnimation(@RecentsAnimationController.ReorderMode int reorderMode,
-            String reason) {
-        // Note: Do not hold the WM lock, this will lock appropriately in the call which also
-        // calls through to AM/RecentsAnimation.onAnimationFinished()
+    public void cancelRecentsAnimationSynchronously(
+            @RecentsAnimationController.ReorderMode int reorderMode, String reason) {
         if (mRecentsAnimationController != null) {
             // This call will call through to cleanupAnimation() below after the animation is
             // canceled
-            mRecentsAnimationController.cancelAnimation(reorderMode, reason);
+            mRecentsAnimationController.cancelAnimationSynchronously(reorderMode, reason);
         }
     }
 
@@ -7491,7 +7489,7 @@
 
     boolean hasWideColorGamutSupport() {
         return mHasWideColorGamutSupport &&
-                !SystemProperties.getBoolean("persist.sys.sf.native_mode", false);
+                SystemProperties.getInt("persist.sys.sf.native_mode", 0) != 1;
     }
 
     void updateNonSystemOverlayWindowsVisibilityIfNeeded(WindowState win, boolean surfaceShown) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index d5ebfb6..1021f15 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3865,9 +3865,13 @@
         windowInfo.title = mAttrs.accessibilityTitle;
         // Panel windows have no public way to set the a11y title directly. Use the
         // regular title as a fallback.
-        if (TextUtils.isEmpty(windowInfo.title)
-                && (mAttrs.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW)
-                && (mAttrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW)) {
+        final boolean isPanelWindow = (mAttrs.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW)
+                && (mAttrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW);
+        // Accessibility overlays should have titles that work for accessibility, and can't set
+        // the a11y title themselves.
+        final boolean isAccessibilityOverlay =
+                windowInfo.type == WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
+        if (TextUtils.isEmpty(windowInfo.title) && (isPanelWindow || isAccessibilityOverlay)) {
             windowInfo.title = mAttrs.getTitle();
         }
         windowInfo.accessibilityIdOfAnchor = mAttrs.accessibilityIdOfAnchor;
@@ -4270,6 +4274,24 @@
         }
     }
 
+    private boolean skipDecorCrop() {
+        // The decor frame is used to specify the region not covered by the system
+        // decorations (nav bar, status bar). In case this is empty, for example with
+        // FLAG_TRANSLUCENT_NAVIGATION, we don't need to do any cropping.
+        if (mDecorFrame.isEmpty()) {
+            return true;
+        }
+
+        // But if we have a frame, and are an application window, then we must be cropped.
+        if (mAppToken != null) {
+            return false;
+        }
+
+        // For non application windows, we may be allowed to extend over the decor bars
+        // depending on our type and permissions assosciated with our token.
+        return mToken.canLayerAboveSystemBars();
+    }
+
     /**
      * Calculate the window crop according to system decor policy. In general this is
      * the system decor rect (see #calculateSystemDecorRect), but we also have some
@@ -4287,7 +4309,7 @@
             policyCrop.intersect(-mCompatFrame.left, -mCompatFrame.top,
                     displayInfo.logicalWidth - mCompatFrame.left,
                     displayInfo.logicalHeight - mCompatFrame.top);
-        } else if (mDecorFrame.isEmpty()) {
+        } else if (skipDecorCrop()) {
             // Windows without policy decor aren't cropped.
             policyCrop.set(0, 0, mCompatFrame.width(), mCompatFrame.height());
         } else {
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 14680d9..b97460a 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -17,7 +17,7 @@
 package com.android.server.wm;
 
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
-
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
@@ -336,4 +336,16 @@
     boolean okToAnimate() {
         return mDisplayContent != null && mDisplayContent.okToAnimate();
     }
+
+    /**
+     * Return whether windows from this token can layer above the
+     * system bars, or in other words extend outside of the "Decor Frame"
+     */
+    boolean canLayerAboveSystemBars() {
+        int layer = mService.mPolicy.getWindowLayerFromTypeLw(windowType,
+                mOwnerCanManageAppTokens);
+        int navLayer = mService.mPolicy.getWindowLayerFromTypeLw(TYPE_NAVIGATION_BAR,
+                mOwnerCanManageAppTokens);
+        return mOwnerCanManageAppTokens && (layer > navLayer);
+    }
 }
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index e18eee2..a3a7e1e 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -1745,12 +1745,12 @@
     }
 }
 
-static jboolean android_location_GnssLocationProvider_is_geofence_supported(
+static jboolean android_location_GnssGeofenceProvider_is_geofence_supported(
         JNIEnv* /* env */, jobject /* obj */) {
     return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
 }
 
-static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
+static jboolean android_location_GnssGeofenceProvider_add_geofence(JNIEnv* /* env */,
         jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
         jint last_transition, jint monitor_transition, jint notification_responsiveness,
         jint unknown_timer) {
@@ -1766,7 +1766,7 @@
     return JNI_FALSE;
 }
 
-static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
+static jboolean android_location_GnssGeofenceProvider_remove_geofence(JNIEnv* /* env */,
         jobject /* obj */, jint geofenceId) {
     if (gnssGeofencingIface != nullptr) {
         auto result = gnssGeofencingIface->removeGeofence(geofenceId);
@@ -1777,7 +1777,7 @@
     return JNI_FALSE;
 }
 
-static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
+static jboolean android_location_GnssGeofenceProvider_pause_geofence(JNIEnv* /* env */,
         jobject /* obj */, jint geofenceId) {
     if (gnssGeofencingIface != nullptr) {
         auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
@@ -1788,7 +1788,7 @@
     return JNI_FALSE;
 }
 
-static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
+static jboolean android_location_GnssGeofenceProvider_resume_geofence(JNIEnv* /* env */,
         jobject /* obj */, jint geofenceId, jint monitor_transition) {
     if (gnssGeofencingIface != nullptr) {
         auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
@@ -1799,7 +1799,7 @@
     return JNI_FALSE;
 }
 
-static jboolean android_location_GnssLocationProvider_is_measurement_supported(
+static jboolean android_location_GnssMeasurementsProvider_is_measurement_supported(
     JNIEnv* env, jclass clazz) {
     if (gnssMeasurementIface != nullptr) {
         return JNI_TRUE;
@@ -1808,7 +1808,7 @@
     return JNI_FALSE;
 }
 
-static jboolean android_location_GnssLocationProvider_start_measurement_collection(
+static jboolean android_location_GnssMeasurementsProvider_start_measurement_collection(
         JNIEnv* /* env */,
         jobject /* obj */,
         jboolean enableFullTracking) {
@@ -1842,7 +1842,7 @@
     return JNI_TRUE;
 }
 
-static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
+static jboolean android_location_GnssMeasurementsProvider_stop_measurement_collection(
         JNIEnv* env,
         jobject obj) {
     if (gnssMeasurementIface == nullptr) {
@@ -1854,7 +1854,7 @@
     return boolToJbool(result.isOk());
 }
 
-static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
+static jboolean android_location_GnssNavigationMessageProvider_is_navigation_message_supported(
         JNIEnv* env,
         jclass clazz) {
     if (gnssNavigationMessageIface != nullptr) {
@@ -1863,7 +1863,7 @@
     return JNI_FALSE;
 }
 
-static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
+static jboolean android_location_GnssNavigationMessageProvider_start_navigation_message_collection(
         JNIEnv* env,
         jobject obj) {
     if (gnssNavigationMessageIface == nullptr) {
@@ -1884,7 +1884,7 @@
     return JNI_TRUE;
 }
 
-static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
+static jboolean android_location_GnssNavigationMessageProvider_stop_navigation_message_collection(
         JNIEnv* env,
         jobject obj) {
     if (gnssNavigationMessageIface == nullptr) {
@@ -2050,7 +2050,7 @@
 }
 
 
-static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
+static jint android_location_GnssBatchingProvider_get_batch_size(JNIEnv*, jclass) {
     if (gnssBatchingIface == nullptr) {
         return 0; // batching not supported, size = 0
     }
@@ -2062,7 +2062,7 @@
     }
 }
 
-static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) {
+static jboolean android_location_GnssBatchingProvider_init_batching(JNIEnv*, jclass) {
     if (gnssBatchingIface == nullptr) {
         return JNI_FALSE; // batching not supported
     }
@@ -2071,14 +2071,14 @@
     return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
 }
 
-static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) {
+static void android_location_GnssBatchingProvider_cleanup_batching(JNIEnv*, jclass) {
     if (gnssBatchingIface == nullptr) {
         return; // batching not supported
     }
     gnssBatchingIface->cleanup();
 }
 
-static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass,
+static jboolean android_location_GnssBatchingProvider_start_batch(JNIEnv*, jclass,
         jlong periodNanos, jboolean wakeOnFifoFull) {
     if (gnssBatchingIface == nullptr) {
         return JNI_FALSE; // batching not supported
@@ -2095,7 +2095,7 @@
     return static_cast<jboolean>(gnssBatchingIface->start(options));
 }
 
-static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) {
+static void android_location_GnssBatchingProvider_flush_batch(JNIEnv*, jclass) {
     if (gnssBatchingIface == nullptr) {
         return; // batching not supported
     }
@@ -2103,7 +2103,7 @@
     gnssBatchingIface->flush();
 }
 
-static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) {
+static jboolean android_location_GnssBatchingProvider_stop_batch(JNIEnv*, jclass) {
     if (gnssBatchingIface == nullptr) {
         return JNI_FALSE; // batching not supported
     }
@@ -2178,44 +2178,6 @@
     {"native_update_network_state",
             "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
             reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
-    {"native_is_geofence_supported",
-            "()Z",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
-    {"native_add_geofence",
-            "(IDDDIIII)Z",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
-    {"native_remove_geofence",
-            "(I)Z",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
-    {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
-            android_location_GnssLocationProvider_pause_geofence)},
-    {"native_resume_geofence",
-            "(II)Z",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
-    {"native_is_measurement_supported",
-            "()Z",
-            reinterpret_cast<void *>(
-                    android_location_GnssLocationProvider_is_measurement_supported)},
-    {"native_start_measurement_collection",
-             "(Z)Z",
-            reinterpret_cast<void *>(
-                    android_location_GnssLocationProvider_start_measurement_collection)},
-    {"native_stop_measurement_collection",
-            "()Z",
-            reinterpret_cast<void *>(
-                    android_location_GnssLocationProvider_stop_measurement_collection)},
-    {"native_is_navigation_message_supported",
-            "()Z",
-            reinterpret_cast<void *>(
-                    android_location_GnssLocationProvider_is_navigation_message_supported)},
-    {"native_start_navigation_message_collection",
-            "()Z",
-            reinterpret_cast<void *>(
-                    android_location_GnssLocationProvider_start_navigation_message_collection)},
-    {"native_stop_navigation_message_collection",
-            "()Z",
-            reinterpret_cast<void *>(
-                    android_location_GnssLocationProvider_stop_navigation_message_collection)},
     {"native_set_supl_es",
             "(I)Z",
             reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
@@ -2241,30 +2203,101 @@
     {"native_set_satellite_blacklist",
             "([I[I)Z",
             reinterpret_cast<void *>(android_location_GnssLocationProvider_set_satellite_blacklist)},
+};
+
+static const JNINativeMethod sMethodsBatching[] = {
+     /* name, signature, funcPtr */
     {"native_get_batch_size",
             "()I",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
-    {"native_init_batching",
-            "()Z",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
+            reinterpret_cast<void *>(android_location_GnssBatchingProvider_get_batch_size)},
     {"native_start_batch",
             "(JZ)Z",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)},
+            reinterpret_cast<void *>(android_location_GnssBatchingProvider_start_batch)},
     {"native_flush_batch",
             "()V",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)},
+            reinterpret_cast<void *>(android_location_GnssBatchingProvider_flush_batch)},
     {"native_stop_batch",
             "()Z",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)},
+            reinterpret_cast<void *>(android_location_GnssBatchingProvider_stop_batch)},
     {"native_init_batching",
             "()Z",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
+            reinterpret_cast<void *>(android_location_GnssBatchingProvider_init_batching)},
     {"native_cleanup_batching",
             "()V",
-            reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)},
+            reinterpret_cast<void *>(android_location_GnssBatchingProvider_cleanup_batching)},
+};
+
+static const JNINativeMethod sGeofenceMethods[] = {
+     /* name, signature, funcPtr */
+    {"native_is_geofence_supported",
+            "()Z",
+            reinterpret_cast<void *>(android_location_GnssGeofenceProvider_is_geofence_supported)},
+    {"native_add_geofence",
+            "(IDDDIIII)Z",
+            reinterpret_cast<void *>(android_location_GnssGeofenceProvider_add_geofence)},
+    {"native_remove_geofence",
+            "(I)Z",
+            reinterpret_cast<void *>(android_location_GnssGeofenceProvider_remove_geofence)},
+    {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
+            android_location_GnssGeofenceProvider_pause_geofence)},
+    {"native_resume_geofence",
+            "(II)Z",
+            reinterpret_cast<void *>(android_location_GnssGeofenceProvider_resume_geofence)},
+};
+
+static const JNINativeMethod sMeasurementMethods[] = {
+     /* name, signature, funcPtr */
+    {"native_is_measurement_supported",
+            "()Z",
+            reinterpret_cast<void *>(
+                    android_location_GnssMeasurementsProvider_is_measurement_supported)},
+    {"native_start_measurement_collection",
+             "(Z)Z",
+            reinterpret_cast<void *>(
+                    android_location_GnssMeasurementsProvider_start_measurement_collection)},
+    {"native_stop_measurement_collection",
+            "()Z",
+            reinterpret_cast<void *>(
+                    android_location_GnssMeasurementsProvider_stop_measurement_collection)},
+};
+
+static const JNINativeMethod sNavigationMessageMethods[] = {
+     /* name, signature, funcPtr */
+    {"native_is_navigation_message_supported",
+            "()Z",
+            reinterpret_cast<void *>(
+                    android_location_GnssNavigationMessageProvider_is_navigation_message_supported)},
+    {"native_start_navigation_message_collection",
+            "()Z",
+            reinterpret_cast<void *>(
+                    android_location_GnssNavigationMessageProvider_start_navigation_message_collection)},
+    {"native_stop_navigation_message_collection",
+            "()Z",
+            reinterpret_cast<void *>(
+                    android_location_GnssNavigationMessageProvider_stop_navigation_message_collection)},
 };
 
 int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
+    jniRegisterNativeMethods(
+            env,
+            "com/android/server/location/GnssBatchingProvider",
+            sMethodsBatching,
+            NELEM(sMethodsBatching));
+    jniRegisterNativeMethods(
+            env,
+            "com/android/server/location/GnssGeofenceProvider",
+            sGeofenceMethods,
+            NELEM(sGeofenceMethods));
+    jniRegisterNativeMethods(
+            env,
+            "com/android/server/location/GnssMeasurementsProvider",
+            sMeasurementMethods,
+            NELEM(sMeasurementMethods));
+    jniRegisterNativeMethods(
+            env,
+            "com/android/server/location/GnssNavigationMessageProvider",
+            sNavigationMessageMethods,
+            NELEM(sNavigationMessageMethods));
     return jniRegisterNativeMethods(
             env,
             "com/android/server/location/GnssLocationProvider",
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 9e72216..ed75eb0 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -73,6 +73,9 @@
 import static com.android.server.devicepolicy.TransferOwnershipMetadataManager.ADMIN_TYPE_DEVICE_OWNER;
 import static com.android.server.devicepolicy.TransferOwnershipMetadataManager.ADMIN_TYPE_PROFILE_OWNER;
 
+
+import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
+
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
 import static org.xmlpull.v1.XmlPullParser.END_TAG;
 import static org.xmlpull.v1.XmlPullParser.TEXT;
@@ -3959,8 +3962,6 @@
         DevicePolicyData policy = getUserData(credentialOwner);
         PasswordMetrics metrics = getUserPasswordMetricsLocked(credentialOwner);
         if (metrics == null) {
-            Slog.wtf(LOG_TAG, "Should have had a valid password metrics for updating checkpoint " +
-                    "validity.");
             metrics = new PasswordMetrics();
         }
         policy.mPasswordValidAtLastCheckpoint =
@@ -4509,7 +4510,8 @@
         }
 
         if (metrics == null) {
-            Slog.wtf(LOG_TAG, "FBE device, should have been unlocked and had valid metrics.");
+            // This could happen if the user never had a password set, for example, so
+            // setActivePasswordState has never been called for it.
             metrics = new PasswordMetrics();
         }
         return isPasswordSufficientForUserWithoutCheckpointLocked(metrics, userHandle, parent);
@@ -9194,8 +9196,8 @@
 
             long id = mInjector.binderClearCallingIdentity();
             try {
-                return mIPackageManager.setPackagesSuspendedAsUser(
-                        packageNames, suspended, null, null, null, "android", callingUserId);
+                return mIPackageManager.setPackagesSuspendedAsUser(packageNames, suspended,
+                        null, null, null, PLATFORM_PACKAGE_NAME, callingUserId);
             } catch (RemoteException re) {
                 // Shouldn't happen.
                 Slog.e(LOG_TAG, "Failed talking to the package manager", re);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 7b6ebf4..70afbc3 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -156,6 +156,9 @@
     // 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;
+
     /*
      * Implementation class names. TODO: Move them to a codegen class or load
      * them from the build system somehow.
@@ -396,6 +399,8 @@
                 android.os.Process.THREAD_PRIORITY_FOREGROUND);
             android.os.Process.setCanSelfBackground(false);
             Looper.prepareMainLooper();
+            Looper.getMainLooper().setSlowLogThresholdMs(
+                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
 
             // Initialize native services.
             System.loadLibrary("android_servers");
diff --git a/services/net/java/android/net/apf/ApfCapabilities.java b/services/net/java/android/net/apf/ApfCapabilities.java
index 703b415..dec8ca2 100644
--- a/services/net/java/android/net/apf/ApfCapabilities.java
+++ b/services/net/java/android/net/apf/ApfCapabilities.java
@@ -49,4 +49,14 @@
         return String.format("%s{version: %d, maxSize: %d, format: %d}", getClass().getSimpleName(),
                 apfVersionSupported, maximumApfProgramSize, apfPacketFormat);
     }
+
+    /**
+     * Returns true if the APF interpreter advertises support for the data buffer access opcodes
+     * LDDW and STDW.
+     *
+     * Full LDDW and STDW support is present from APFv4 on.
+     */
+    public boolean hasDataAccess() {
+        return apfVersionSupported >= 4;
+    }
 }
diff --git a/services/net/java/android/net/apf/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java
index 9a97ba7..2bf6e92 100644
--- a/services/net/java/android/net/apf/ApfFilter.java
+++ b/services/net/java/android/net/apf/ApfFilter.java
@@ -24,6 +24,7 @@
 import static com.android.internal.util.BitUtils.getUint8;
 import static com.android.internal.util.BitUtils.uint32;
 
+import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -102,6 +103,70 @@
         UPDATE_EXPIRY   // APF program updated for expiry
     }
 
+    /**
+     * APF packet counters.
+     *
+     * Packet counters are 32bit big-endian values, and allocated near the end of the APF data
+     * buffer, using negative byte offsets, where -4 is equivalent to maximumApfProgramSize - 4,
+     * the last writable 32bit word.
+     */
+    @VisibleForTesting
+    private static enum Counter {
+        RESERVED_OOB,  // Points to offset 0 from the end of the buffer (out-of-bounds)
+        TOTAL_PACKETS,
+        PASSED_ARP,
+        PASSED_DHCP,
+        PASSED_IPV4,
+        PASSED_IPV6_NON_ICMP,
+        PASSED_IPV4_UNICAST,
+        PASSED_IPV6_ICMP,
+        PASSED_IPV6_UNICAST_NON_ICMP,
+        PASSED_ARP_NON_IPV4,
+        PASSED_ARP_UNKNOWN,
+        PASSED_ARP_UNICAST_REPLY,
+        PASSED_NON_IP_UNICAST,
+        DROPPED_ETH_BROADCAST,
+        DROPPED_RA,
+        DROPPED_GARP_REPLY,
+        DROPPED_ARP_OTHER_HOST,
+        DROPPED_IPV4_L2_BROADCAST,
+        DROPPED_IPV4_BROADCAST_ADDR,
+        DROPPED_IPV4_BROADCAST_NET,
+        DROPPED_IPV4_MULTICAST,
+        DROPPED_IPV6_ROUTER_SOLICITATION,
+        DROPPED_IPV6_MULTICAST_NA,
+        DROPPED_IPV6_MULTICAST,
+        DROPPED_IPV6_MULTICAST_PING,
+        DROPPED_IPV6_NON_ICMP_MULTICAST,
+        DROPPED_802_3_FRAME,
+        DROPPED_ETHERTYPE_BLACKLISTED;
+
+        // Returns the negative byte offset from the end of the APF data segment for
+        // a given counter.
+        public int offset() {
+            return - this.ordinal() * 4;  // Currently, all counters are 32bit long.
+        }
+
+        // Returns the total size of the data segment in bytes.
+        public static int totalSize() {
+            return (Counter.class.getEnumConstants().length - 1) * 4;
+        }
+    }
+
+    /**
+     * When APFv4 is supported, loads R1 with the offset of the specified counter.
+     */
+    private void maybeSetCounter(ApfGenerator gen, Counter c) {
+        if (mApfCapabilities.hasDataAccess()) {
+            gen.addLoadImmediate(Register.R1, c.offset());
+        }
+    }
+
+    // When APFv4 is supported, these point to the trampolines generated by emitEpilogue().
+    // Otherwise, they're just aliases for PASS_LABEL and DROP_LABEL.
+    private final String mCountAndPassLabel;
+    private final String mCountAndDropLabel;
+
     // Thread to listen for RAs.
     @VisibleForTesting
     class ReceiveThread extends Thread {
@@ -289,6 +354,16 @@
         mDrop802_3Frames = config.ieee802_3Filter;
         mContext = context;
 
+        if (mApfCapabilities.hasDataAccess()) {
+            mCountAndPassLabel = "countAndPass";
+            mCountAndDropLabel = "countAndDrop";
+        } else {
+            // APFv4 unsupported: turn jumps to the counter trampolines to immediately PASS or DROP,
+            // preserving the original pre-APFv4 behavior.
+            mCountAndPassLabel = ApfGenerator.PASS_LABEL;
+            mCountAndDropLabel = ApfGenerator.DROP_LABEL;
+        }
+
         // Now fill the black list from the passed array
         mEthTypeBlackList = filterEthTypeBlackList(config.ethTypeBlackList);
 
@@ -302,6 +377,10 @@
                 new IntentFilter(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED));
     }
 
+    public synchronized void setDataSnapshot(byte[] data) {
+        mDataSnapshot = data;
+    }
+
     private void log(String s) {
         Log.d(TAG, "(" + mInterfaceParams.name + "): " + s);
     }
@@ -350,6 +429,10 @@
         try {
             mHardwareAddress = mInterfaceParams.macAddr.toByteArray();
             synchronized(this) {
+                // Clear APF memory.
+                byte[] zeroes = new byte[mApfCapabilities.maximumApfProgramSize];
+                mIpClientCallback.installPacketFilter(zeroes);
+
                 // Install basic filters
                 installNewProgramLocked();
             }
@@ -729,7 +812,8 @@
                     gen.addJumpIfR0LessThan(filterLifetime, nextFilterLabel);
                 }
             }
-            gen.addJump(gen.DROP_LABEL);
+            maybeSetCounter(gen, Counter.DROPPED_RA);
+            gen.addJump(mCountAndDropLabel);
             gen.defineLabel(nextFilterLabel);
             return filterLifetime;
         }
@@ -764,6 +848,16 @@
     @GuardedBy("this")
     private byte[] mLastInstalledProgram;
 
+    /**
+     * For debugging only. Contains the latest APF buffer snapshot captured from the firmware.
+     *
+     * A typical size for this buffer is 4KB. It is present only if the WiFi HAL supports
+     * IWifiStaIface#readApfPacketFilterData(), and the APF interpreter advertised support for
+     * the opcodes to access the data buffer (LDDW and STDW).
+     */
+    @GuardedBy("this") @Nullable
+    private byte[] mDataSnapshot;
+
     // How many times the program was updated since we started.
     @GuardedBy("this")
     private int mNumProgramUpdates = 0;
@@ -799,31 +893,37 @@
 
         // Pass if not ARP IPv4.
         gen.addLoadImmediate(Register.R0, ARP_HEADER_OFFSET);
-        gen.addJumpIfBytesNotEqual(Register.R0, ARP_IPV4_HEADER, gen.PASS_LABEL);
+        maybeSetCounter(gen, Counter.PASSED_ARP_NON_IPV4);
+        gen.addJumpIfBytesNotEqual(Register.R0, ARP_IPV4_HEADER, mCountAndPassLabel);
 
         // Pass if unknown ARP opcode.
         gen.addLoad16(Register.R0, ARP_OPCODE_OFFSET);
         gen.addJumpIfR0Equals(ARP_OPCODE_REQUEST, checkTargetIPv4); // Skip to unicast check
-        gen.addJumpIfR0NotEquals(ARP_OPCODE_REPLY, gen.PASS_LABEL);
+        maybeSetCounter(gen, Counter.PASSED_ARP_UNKNOWN);
+        gen.addJumpIfR0NotEquals(ARP_OPCODE_REPLY, mCountAndPassLabel);
 
         // Pass if unicast reply.
         gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
-        gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, gen.PASS_LABEL);
+        maybeSetCounter(gen, Counter.PASSED_ARP_UNICAST_REPLY);
+        gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
 
         // Either a unicast request, a unicast reply, or a broadcast reply.
         gen.defineLabel(checkTargetIPv4);
         if (mIPv4Address == null) {
             // When there is no IPv4 address, drop GARP replies (b/29404209).
             gen.addLoad32(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
-            gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, gen.DROP_LABEL);
+            maybeSetCounter(gen, Counter.DROPPED_GARP_REPLY);
+            gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
         } else {
             // When there is an IPv4 address, drop unicast/broadcast requests
             // and broadcast replies with a different target IPv4 address.
             gen.addLoadImmediate(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
-            gen.addJumpIfBytesNotEqual(Register.R0, mIPv4Address, gen.DROP_LABEL);
+            maybeSetCounter(gen, Counter.DROPPED_ARP_OTHER_HOST);
+            gen.addJumpIfBytesNotEqual(Register.R0, mIPv4Address, mCountAndDropLabel);
         }
 
-        gen.addJump(gen.PASS_LABEL);
+        maybeSetCounter(gen, Counter.PASSED_ARP);
+        gen.addJump(mCountAndPassLabel);
     }
 
     /**
@@ -866,7 +966,8 @@
             // NOTE: Relies on R1 containing IPv4 header offset.
             gen.addAddR1();
             gen.addJumpIfBytesNotEqual(Register.R0, mHardwareAddress, skipDhcpv4Filter);
-            gen.addJump(gen.PASS_LABEL);
+            maybeSetCounter(gen, Counter.PASSED_DHCP);
+            gen.addJump(mCountAndPassLabel);
 
             // Drop all multicasts/broadcasts.
             gen.defineLabel(skipDhcpv4Filter);
@@ -874,24 +975,31 @@
             // If IPv4 destination address is in multicast range, drop.
             gen.addLoad8(Register.R0, IPV4_DEST_ADDR_OFFSET);
             gen.addAnd(0xf0);
-            gen.addJumpIfR0Equals(0xe0, gen.DROP_LABEL);
+            maybeSetCounter(gen, Counter.DROPPED_IPV4_MULTICAST);
+            gen.addJumpIfR0Equals(0xe0, mCountAndDropLabel);
 
             // If IPv4 broadcast packet, drop regardless of L2 (b/30231088).
+            maybeSetCounter(gen, Counter.DROPPED_IPV4_BROADCAST_ADDR);
             gen.addLoad32(Register.R0, IPV4_DEST_ADDR_OFFSET);
-            gen.addJumpIfR0Equals(IPV4_BROADCAST_ADDRESS, gen.DROP_LABEL);
+            gen.addJumpIfR0Equals(IPV4_BROADCAST_ADDRESS, mCountAndDropLabel);
             if (mIPv4Address != null && mIPv4PrefixLength < 31) {
+                maybeSetCounter(gen, Counter.DROPPED_IPV4_BROADCAST_NET);
                 int broadcastAddr = ipv4BroadcastAddress(mIPv4Address, mIPv4PrefixLength);
-                gen.addJumpIfR0Equals(broadcastAddr, gen.DROP_LABEL);
+                gen.addJumpIfR0Equals(broadcastAddr, mCountAndDropLabel);
             }
 
             // If L2 broadcast packet, drop.
+            // TODO: can we invert this condition to fall through to the common pass case below?
+            maybeSetCounter(gen, Counter.PASSED_IPV4_UNICAST);
             gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
-            gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, gen.PASS_LABEL);
-            gen.addJump(gen.DROP_LABEL);
+            gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
+            maybeSetCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST);
+            gen.addJump(mCountAndDropLabel);
         }
 
         // Otherwise, pass
-        gen.addJump(gen.PASS_LABEL);
+        maybeSetCounter(gen, Counter.PASSED_IPV4);
+        gen.addJump(mCountAndPassLabel);
     }
 
 
@@ -938,14 +1046,17 @@
 
             // Drop all other packets sent to ff00::/8 (multicast prefix).
             gen.defineLabel(dropAllIPv6MulticastsLabel);
+            maybeSetCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST);
             gen.addLoad8(Register.R0, IPV6_DEST_ADDR_OFFSET);
-            gen.addJumpIfR0Equals(0xff, gen.DROP_LABEL);
+            gen.addJumpIfR0Equals(0xff, mCountAndDropLabel);
             // Not multicast. Pass.
-            gen.addJump(gen.PASS_LABEL);
+            maybeSetCounter(gen, Counter.PASSED_IPV6_UNICAST_NON_ICMP);
+            gen.addJump(mCountAndPassLabel);
             gen.defineLabel(skipIPv6MulticastFilterLabel);
         } else {
             // If not ICMPv6, pass.
-            gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, gen.PASS_LABEL);
+            maybeSetCounter(gen, Counter.PASSED_IPV6_NON_ICMP);
+            gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, mCountAndPassLabel);
         }
 
         // If we got this far, the packet is ICMPv6.  Drop some specific types.
@@ -954,7 +1065,8 @@
         String skipUnsolicitedMulticastNALabel = "skipUnsolicitedMulticastNA";
         gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET);
         // Drop all router solicitations (b/32833400)
-        gen.addJumpIfR0Equals(ICMPV6_ROUTER_SOLICITATION, gen.DROP_LABEL);
+        maybeSetCounter(gen, Counter.DROPPED_IPV6_ROUTER_SOLICITATION);
+        gen.addJumpIfR0Equals(ICMPV6_ROUTER_SOLICITATION, mCountAndDropLabel);
         // If not neighbor announcements, skip filter.
         gen.addJumpIfR0NotEquals(ICMPV6_NEIGHBOR_ADVERTISEMENT, skipUnsolicitedMulticastNALabel);
         // If to ff02::1, drop.
@@ -962,7 +1074,8 @@
         gen.addLoadImmediate(Register.R0, IPV6_DEST_ADDR_OFFSET);
         gen.addJumpIfBytesNotEqual(Register.R0, IPV6_ALL_NODES_ADDRESS,
                 skipUnsolicitedMulticastNALabel);
-        gen.addJump(gen.DROP_LABEL);
+        maybeSetCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA);
+        gen.addJump(mCountAndDropLabel);
         gen.defineLabel(skipUnsolicitedMulticastNALabel);
     }
 
@@ -985,10 +1098,18 @@
      * </ul>
      */
     @GuardedBy("this")
-    private ApfGenerator beginProgramLocked() throws IllegalInstructionException {
+    private ApfGenerator emitPrologueLocked() throws IllegalInstructionException {
         // This is guaranteed to succeed because of the check in maybeCreate.
         ApfGenerator gen = new ApfGenerator(mApfCapabilities.apfVersionSupported);
 
+        if (mApfCapabilities.hasDataAccess()) {
+            // Increment TOTAL_PACKETS
+            maybeSetCounter(gen, Counter.TOTAL_PACKETS);
+            gen.addLoadData(Register.R0, 0);  // load counter
+            gen.addAdd(1);
+            gen.addStoreData(Register.R0, 0);  // write-back counter
+        }
+
         // Here's a basic summary of what the initial program does:
         //
         // if it's a 802.3 Frame (ethtype < 0x0600):
@@ -1009,12 +1130,14 @@
 
         if (mDrop802_3Frames) {
             // drop 802.3 frames (ethtype < 0x0600)
-            gen.addJumpIfR0LessThan(ETH_TYPE_MIN, gen.DROP_LABEL);
+            maybeSetCounter(gen, Counter.DROPPED_802_3_FRAME);
+            gen.addJumpIfR0LessThan(ETH_TYPE_MIN, mCountAndDropLabel);
         }
 
         // Handle ether-type black list
+        maybeSetCounter(gen, Counter.DROPPED_ETHERTYPE_BLACKLISTED);
         for (int p : mEthTypeBlackList) {
-            gen.addJumpIfR0Equals(p, gen.DROP_LABEL);
+            gen.addJumpIfR0Equals(p, mCountAndDropLabel);
         }
 
         // Add ARP filters:
@@ -1041,8 +1164,10 @@
 
         // Drop non-IP non-ARP broadcasts, pass the rest
         gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
-        gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, gen.PASS_LABEL);
-        gen.addJump(gen.DROP_LABEL);
+        maybeSetCounter(gen, Counter.PASSED_NON_IP_UNICAST);
+        gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
+        maybeSetCounter(gen, Counter.DROPPED_ETH_BROADCAST);
+        gen.addJump(mCountAndDropLabel);
 
         // Add IPv6 filters:
         gen.defineLabel(ipv6FilterLabel);
@@ -1051,6 +1176,39 @@
     }
 
     /**
+     * Append packet counting epilogue to the APF program.
+     *
+     * Currently, the epilogue consists of two trampolines which count passed and dropped packets
+     * before jumping to the actual PASS and DROP labels.
+     */
+    @GuardedBy("this")
+    private void emitEpilogue(ApfGenerator gen) throws IllegalInstructionException {
+        // If APFv4 is unsupported, no epilogue is necessary: if execution reached this far, it
+        // will just fall-through to the PASS label.
+        if (!mApfCapabilities.hasDataAccess()) return;
+
+        // Execution will reach the bottom of the program if none of the filters match,
+        // which will pass the packet to the application processor.
+        maybeSetCounter(gen, Counter.PASSED_IPV6_ICMP);
+
+        // Append the count & pass trampoline, which increments the counter at the data address
+        // pointed to by R1, then jumps to the pass label. This saves a few bytes over inserting
+        // the entire sequence inline for every counter.
+        gen.defineLabel(mCountAndPassLabel);
+        gen.addLoadData(Register.R0, 0);   // R0 = *(R1 + 0)
+        gen.addAdd(1);                     // R0++
+        gen.addStoreData(Register.R0, 0);  // *(R1 + 0) = R0
+        gen.addJump(gen.PASS_LABEL);
+
+        // Same as above for the count & drop trampoline.
+        gen.defineLabel(mCountAndDropLabel);
+        gen.addLoadData(Register.R0, 0);   // R0 = *(R1 + 0)
+        gen.addAdd(1);                     // R0++
+        gen.addStoreData(Register.R0, 0);  // *(R1 + 0) = R0
+        gen.addJump(gen.DROP_LABEL);
+    }
+
+    /**
      * Generate and install a new filter program.
      */
     @GuardedBy("this")
@@ -1060,22 +1218,39 @@
         ArrayList<Ra> rasToFilter = new ArrayList<>();
         final byte[] program;
         long programMinLifetime = Long.MAX_VALUE;
+        long maximumApfProgramSize = mApfCapabilities.maximumApfProgramSize;
+        if (mApfCapabilities.hasDataAccess()) {
+            // Reserve space for the counters.
+            maximumApfProgramSize -= Counter.totalSize();
+        }
+
         try {
             // Step 1: Determine how many RA filters we can fit in the program.
-            ApfGenerator gen = beginProgramLocked();
+            ApfGenerator gen = emitPrologueLocked();
+
+            // The epilogue normally goes after the RA filters, but add it early to include its
+            // length when estimating the total.
+            emitEpilogue(gen);
+
+            // Can't fit the program even without any RA filters?
+            if (gen.programLengthOverEstimate() > maximumApfProgramSize) {
+                Log.e(TAG, "Program exceeds maximum size " + maximumApfProgramSize);
+                return;
+            }
+
             for (Ra ra : mRas) {
                 ra.generateFilterLocked(gen);
                 // Stop if we get too big.
-                if (gen.programLengthOverEstimate() > mApfCapabilities.maximumApfProgramSize) break;
+                if (gen.programLengthOverEstimate() > maximumApfProgramSize) break;
                 rasToFilter.add(ra);
             }
+
             // Step 2: Actually generate the program
-            gen = beginProgramLocked();
+            gen = emitPrologueLocked();
             for (Ra ra : rasToFilter) {
                 programMinLifetime = Math.min(programMinLifetime, ra.generateFilterLocked(gen));
             }
-            // Execution will reach the end of the program if no filters match, which will pass the
-            // packet to the AP.
+            emitEpilogue(gen);
             program = gen.generate();
         } catch (IllegalInstructionException|IllegalStateException e) {
             Log.e(TAG, "Failed to generate APF program.", e);
@@ -1278,6 +1453,23 @@
         installNewProgramLocked();
     }
 
+    static public long counterValue(byte[] data, Counter counter)
+            throws ArrayIndexOutOfBoundsException {
+        // Follow the same wrap-around addressing scheme of the interpreter.
+        int offset = counter.offset();
+        if (offset < 0) {
+            offset = data.length + offset;
+        }
+
+        // Decode 32bit big-endian integer into a long so we can count up beyond 2^31.
+        long value = 0;
+        for (int i = 0; i < 4; i++) {
+            value = value << 8 | (data[offset] & 0xFF);
+            offset++;
+        }
+        return value;
+    }
+
     public synchronized void dump(IndentingPrintWriter pw) {
         pw.println("Capabilities: " + mApfCapabilities);
         pw.println("Receive thread: " + (mReceiveThread != null ? "RUNNING" : "STOPPED"));
@@ -1319,6 +1511,32 @@
             pw.println(HexDump.toHexString(mLastInstalledProgram, false /* lowercase */));
             pw.decreaseIndent();
         }
+
+        pw.println("APF packet counters: ");
+        pw.increaseIndent();
+        if (!mApfCapabilities.hasDataAccess()) {
+            pw.println("APF counters not supported");
+        } else if (mDataSnapshot == null) {
+            pw.println("No last snapshot.");
+        } else {
+            try {
+                Counter[] counters = Counter.class.getEnumConstants();
+                for (Counter c : Arrays.asList(counters).subList(1, counters.length)) {
+                    long value = counterValue(mDataSnapshot, c);
+                    // Only print non-zero counters
+                    if (value != 0) {
+                        pw.println(c.toString() + ": " + value);
+                    }
+                }
+            } catch (ArrayIndexOutOfBoundsException e) {
+                pw.println("Uh-oh: " + e);
+            }
+            if (VDBG) {
+                pw.println("Raw data dump: ");
+                pw.println(HexDump.dumpHexString(mDataSnapshot));
+            }
+        }
+        pw.decreaseIndent();
     }
 
     // TODO: move to android.net.NetworkUtils
diff --git a/services/net/java/android/net/apf/ApfGenerator.java b/services/net/java/android/net/apf/ApfGenerator.java
index 99b2fc6..87a1b5e 100644
--- a/services/net/java/android/net/apf/ApfGenerator.java
+++ b/services/net/java/android/net/apf/ApfGenerator.java
@@ -378,8 +378,7 @@
     }
 
     /**
-     * Returns true if the specified {@code version} is supported by the ApfGenerator, otherwise
-     * false.
+     * Returns true if the ApfGenerator supports the specified {@code version}, otherwise false.
      */
     public static boolean supportsVersion(int version) {
         return version >= MIN_APF_VERSION;
@@ -753,7 +752,7 @@
 
     /**
      * Add an instruction to the end of the program to jump to {@code target} if the bytes of the
-     * packet at, an offset specified by {@code register}, match {@code bytes}.
+     * packet at an offset specified by {@code register} match {@code bytes}.
      */
     public ApfGenerator addJumpIfBytesNotEqual(Register register, byte[] bytes, String target)
             throws IllegalInstructionException {
diff --git a/services/net/java/android/net/dns/ResolvUtil.java b/services/net/java/android/net/dns/ResolvUtil.java
index 97d20f4..a2a6615 100644
--- a/services/net/java/android/net/dns/ResolvUtil.java
+++ b/services/net/java/android/net/dns/ResolvUtil.java
@@ -62,4 +62,13 @@
         final long netidForResolv = NETID_USE_LOCAL_NAMESERVERS | (long) network.netId;
         return new Network((int) netidForResolv);
     }
+
+    public static Network makeNetworkWithPrivateDnsBypass(Network network) {
+        return new Network(network) {
+            @Override
+            public InetAddress[] getAllByName(String host) throws UnknownHostException {
+                return blockingResolveAllLocally(network, host);
+            }
+        };
+    }
 }
diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java
index 9fdb31e..d6999dd 100644
--- a/services/net/java/android/net/ip/IpClient.java
+++ b/services/net/java/android/net/ip/IpClient.java
@@ -624,7 +624,14 @@
     private ApfFilter mApfFilter;
     private boolean mMulticastFiltering;
     private long mStartTimeMillis;
-    private byte[] mApfDataSnapshot;
+
+    /**
+     * Reading the snapshot is an asynchronous operation initiated by invoking
+     * Callback.startReadPacketFilter() and completed when the WiFi Service responds with an
+     * EVENT_READ_PACKET_FILTER_COMPLETE message. The mApfDataSnapshotComplete condition variable
+     * signals when a new snapshot is ready.
+     */
+    private final ConditionVariable mApfDataSnapshotComplete = new ConditionVariable();
 
     public static class Dependencies {
         public INetworkManagementService getNMS() {
@@ -881,13 +888,21 @@
         final ProvisioningConfiguration provisioningConfig = mConfiguration;
         final ApfCapabilities apfCapabilities = (provisioningConfig != null)
                 ? provisioningConfig.mApfCapabilities : null;
-        final byte[] apfDataSnapshot = mApfDataSnapshot;
 
         IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
         pw.println(mTag + " APF dump:");
         pw.increaseIndent();
         if (apfFilter != null) {
+            if (apfCapabilities.hasDataAccess()) {
+                // Request a new snapshot, then wait for it.
+                mApfDataSnapshotComplete.close();
+                mCallback.startReadPacketFilter();
+                if (!mApfDataSnapshotComplete.block(1000)) {
+                    pw.print("TIMEOUT: DUMPING STALE APF SNAPSHOT");
+                }
+            }
             apfFilter.dump(pw);
+
         } else {
             pw.print("No active ApfFilter; ");
             if (provisioningConfig == null) {
@@ -899,15 +914,6 @@
             }
         }
         pw.decreaseIndent();
-        pw.println(mTag + " latest APF data snapshot: ");
-        pw.increaseIndent();
-        if (apfDataSnapshot != null) {
-            pw.println(HexDump.dumpHexString(apfDataSnapshot));
-        } else {
-            pw.println("No last snapshot.");
-        }
-        pw.decreaseIndent();
-
         pw.println();
         pw.println(mTag + " current ProvisioningConfiguration:");
         pw.increaseIndent();
@@ -1704,7 +1710,10 @@
                 }
 
                 case EVENT_READ_PACKET_FILTER_COMPLETE: {
-                    mApfDataSnapshot = (byte[]) msg.obj;
+                    if (mApfFilter != null) {
+                        mApfFilter.setDataSnapshot((byte[]) msg.obj);
+                    }
+                    mApfDataSnapshotComplete.open();
                     break;
                 }
 
diff --git a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
index 5e90b3f..de2e5c6 100644
--- a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
+++ b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
@@ -17,16 +17,16 @@
 package com.android.server.backup;
 
 import static com.android.server.backup.testing.BackupManagerServiceTestUtils.createBackupWakeLock;
-import static com.android.server.backup.testing.BackupManagerServiceTestUtils
-        .setUpBackupManagerServiceBasics;
-import static com.android.server.backup.testing.BackupManagerServiceTestUtils
-        .startBackupThreadAndGetLooper;
+import static com.android.server.backup.testing.BackupManagerServiceTestUtils.setUpBackupManagerServiceBasics;
+import static com.android.server.backup.testing.BackupManagerServiceTestUtils.startBackupThreadAndGetLooper;
 import static com.android.server.backup.testing.TestUtils.uncheck;
 import static com.android.server.backup.testing.TransportData.backupTransport;
-
 import static com.google.common.truth.Truth.assertThat;
-
+import static java.util.Collections.emptyList;
+import static java.util.stream.Collectors.toCollection;
+import static java.util.stream.Collectors.toList;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.argThat;
@@ -41,10 +41,6 @@
 import static org.mockito.Mockito.when;
 import static org.robolectric.Shadows.shadowOf;
 
-import static java.util.Collections.emptyList;
-import static java.util.stream.Collectors.toCollection;
-import static java.util.stream.Collectors.toList;
-
 import android.app.Application;
 import android.app.IBackupAgent;
 import android.app.backup.BackupAgent;
@@ -58,6 +54,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.os.DeadObjectException;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -66,7 +63,6 @@
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 import android.util.Pair;
-
 import com.android.internal.backup.IBackupTransport;
 import com.android.server.backup.internal.BackupHandler;
 import com.android.server.backup.internal.BackupRequest;
@@ -81,9 +77,14 @@
 import com.android.server.testing.SystemLoaderPackages;
 import com.android.server.testing.shadows.ShadowBackupDataInput;
 import com.android.server.testing.shadows.ShadowBackupDataOutput;
-
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentMatcher;
@@ -97,20 +98,15 @@
 import org.robolectric.shadows.ShadowPackageManager;
 import org.robolectric.shadows.ShadowQueuedWork;
 
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Stream;
-
 @RunWith(FrameworkRobolectricTestRunner.class)
 @Config(
-    manifest = Config.NONE,
-    sdk = 26,
-    shadows = {ShadowBackupDataInput.class, ShadowBackupDataOutput.class, ShadowQueuedWork.class}
-)
+        manifest = Config.NONE,
+        sdk = 26,
+        shadows = {
+            ShadowBackupDataInput.class,
+            ShadowBackupDataOutput.class,
+            ShadowQueuedWork.class
+        })
 @SystemLoaderPackages({"com.android.server.backup", "android.app.backup"})
 @SystemLoaderClasses({IBackupTransport.class, IBackupAgent.class, PackageInfo.class})
 @Presubmit
@@ -382,8 +378,7 @@
         runTask(task);
 
         verify(mListener).onFinished(any());
-        // TODO: Should it be 2 times? (PBT.beginBackup() and PBT.finalizeBackup())
-        verify(mObserver, times(2)).backupFinished(eq(BackupManager.ERROR_TRANSPORT_ABORTED));
+        verify(mObserver).backupFinished(eq(BackupManager.ERROR_TRANSPORT_ABORTED));
     }
 
     @Test
@@ -538,6 +533,57 @@
         verify(mObserver).backupFinished(BackupManager.SUCCESS);
     }
 
+    @Test
+    public void testRunTask_whenQueueEmpty() throws Exception {
+        TransportMock transportMock = setUpTransport(mTransport);
+        PerformBackupTask task =
+                createPerformBackupTask(
+                        transportMock.transportClient, mTransport.transportDirName, true);
+
+        runTask(task);
+
+        verify(mObserver).backupFinished(eq(BackupManager.SUCCESS));
+    }
+
+    @Test
+    public void testRunTask_whenIncrementalAndTransportUnavailableDuringPmBackup()
+            throws Exception {
+        TransportMock transportMock = setUpTransport(mTransport);
+        IBackupTransport transportBinder = transportMock.transport;
+        setUpAgent(PACKAGE_1);
+        when(transportBinder.getBackupQuota(
+                        eq(BackupManagerService.PACKAGE_MANAGER_SENTINEL), anyBoolean()))
+                .thenThrow(DeadObjectException.class);
+        PerformBackupTask task =
+                createPerformBackupTask(
+                        transportMock.transportClient,
+                        mTransport.transportDirName,
+                        false,
+                        PACKAGE_1);
+
+        runTask(task);
+
+        verify(mListener).onFinished(any());
+        verify(mObserver).backupFinished(eq(BackupManager.ERROR_TRANSPORT_ABORTED));
+    }
+
+    @Test
+    public void testRunTask_whenIncrementalAndAgentFails() throws Exception {
+        TransportMock transportMock = setUpTransport(mTransport);
+        createFakePmAgent();
+        PerformBackupTask task =
+                createPerformBackupTask(
+                        transportMock.transportClient,
+                        mTransport.transportDirName,
+                        false,
+                        PACKAGE_1);
+
+        runTask(task);
+
+        verify(mListener).onFinished(any());
+        verify(mObserver).backupFinished(eq(BackupManager.ERROR_TRANSPORT_ABORTED));
+    }
+
     private void runTask(PerformBackupTask task) {
         Message message = mBackupHandler.obtainMessage(BackupHandler.MSG_BACKUP_RESTORE_STEP, task);
         mBackupHandler.sendMessage(message);
@@ -637,6 +683,19 @@
         return pmAgent;
     }
 
+    /**
+     * Returns an implementation of PackageManagerBackupAgent that throws RuntimeException in {@link
+     * BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor)}
+     */
+    private PackageManagerBackupAgent createFakePmAgent() {
+        PackageManagerBackupAgent fakePmAgent =
+                new FakePackageManagerBackupAgent(mApplication.getPackageManager());
+        fakePmAgent.attach(mApplication);
+        fakePmAgent.onCreate();
+        when(mBackupManagerService.makeMetadataAgent()).thenReturn(fakePmAgent);
+        return fakePmAgent;
+    }
+
     /** Matches {@link PackageInfo} whose package name is {@code packageName}. */
     private static ArgumentMatcher<PackageInfo> packageInfo(String packageName) {
         // We have to test for packageInfo nulity because of Mockito's own stubbing with argThat().
@@ -713,4 +772,18 @@
             mBackupHandler.sendMessage(message);
         }
     }
+
+    private static class FakePackageManagerBackupAgent extends PackageManagerBackupAgent {
+        public FakePackageManagerBackupAgent(PackageManager packageMgr) {
+            super(packageMgr);
+        }
+
+        @Override
+        public void onBackup(
+                ParcelFileDescriptor oldState,
+                BackupDataOutput data,
+                ParcelFileDescriptor newState) {
+            throw new RuntimeException();
+        }
+    }
 }
diff --git a/services/robotests/src/com/android/server/location/GnssBatchingProviderTest.java b/services/robotests/src/com/android/server/location/GnssBatchingProviderTest.java
new file mode 100644
index 0000000..5046094
--- /dev/null
+++ b/services/robotests/src/com/android/server/location/GnssBatchingProviderTest.java
@@ -0,0 +1,91 @@
+package com.android.server.location;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.location.GnssBatchingProvider.GnssBatchingProviderNative;
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+/**
+ * Unit tests for {@link GnssBatchingProvider}.
+ */
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(
+        manifest = Config.NONE,
+        shadows = {
+        },
+        sdk = 27
+)
+@SystemLoaderPackages({"com.android.server.location"})
+@Presubmit
+public class GnssBatchingProviderTest {
+
+    private static final long PERIOD_NANOS = (long) 1e9;
+    private static final boolean WAKE_ON_FIFO_FULL = true;
+    private static final int BATCH_SIZE = 3;
+    @Mock
+    private GnssBatchingProviderNative mMockNative;
+    private GnssBatchingProvider mTestProvider;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mMockNative.initBatching()).thenReturn(true);
+        when(mMockNative.startBatch(anyLong(), anyBoolean())).thenReturn(true);
+        when(mMockNative.stopBatch()).thenReturn(true);
+        when(mMockNative.getBatchSize()).thenReturn(BATCH_SIZE);
+        mTestProvider = new GnssBatchingProvider(mMockNative);
+        mTestProvider.enable();
+        mTestProvider.start(PERIOD_NANOS, WAKE_ON_FIFO_FULL);
+    }
+
+    @Test
+    public void start_nativeStarted() {
+        verify(mMockNative).startBatch(eq(PERIOD_NANOS), eq(WAKE_ON_FIFO_FULL));
+    }
+
+    @Test
+    public void stop_nativeStopped() {
+        mTestProvider.stop();
+        verify(mMockNative).stopBatch();
+    }
+
+    @Test
+    public void flush_nativeFlushed() {
+        mTestProvider.flush();
+        verify(mMockNative).flushBatch();
+    }
+
+    @Test
+    public void getBatchSize_nativeGetBatchSize() {
+        assertThat(mTestProvider.getBatchSize()).isEqualTo(BATCH_SIZE);
+    }
+
+    @Test
+    public void started_resume_started() {
+        mTestProvider.resumeIfStarted();
+        verify(mMockNative, times(2)).startBatch(eq(PERIOD_NANOS), eq(WAKE_ON_FIFO_FULL));
+    }
+
+    @Test
+    public void stopped_resume_notStarted() {
+        mTestProvider.stop();
+        mTestProvider.resumeIfStarted();
+        verify(mMockNative, times(1)).startBatch(eq(PERIOD_NANOS), eq(WAKE_ON_FIFO_FULL));
+    }
+}
diff --git a/services/robotests/src/com/android/server/location/GnssGeofenceProviderTest.java b/services/robotests/src/com/android/server/location/GnssGeofenceProviderTest.java
new file mode 100644
index 0000000..187303c
--- /dev/null
+++ b/services/robotests/src/com/android/server/location/GnssGeofenceProviderTest.java
@@ -0,0 +1,121 @@
+package com.android.server.location;
+
+import static org.mockito.Matchers.anyDouble;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.Looper;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+/**
+ * Unit tests for {@link GnssGeofenceProvider}.
+ */
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(
+        manifest = Config.NONE,
+        sdk = 27
+)
+@SystemLoaderPackages({"com.android.server.location"})
+@Presubmit
+public class GnssGeofenceProviderTest {
+    private static final int GEOFENCE_ID = 12345;
+    private static final double LATITUDE = 10.0;
+    private static final double LONGITUDE = 20.0;
+    private static final double RADIUS = 5.0;
+    private static final int LAST_TRANSITION = 0;
+    private static final int MONITOR_TRANSITIONS = 0;
+    private static final int NOTIFICATION_RESPONSIVENESS = 0;
+    private static final int UNKNOWN_TIMER = 0;
+    @Mock
+    private GnssGeofenceProvider.GnssGeofenceProviderNative mMockNative;
+    private GnssGeofenceProvider mTestProvider;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mMockNative.addGeofence(anyInt(), anyDouble(), anyDouble(), anyDouble(), anyInt(),
+                anyInt(), anyInt(), anyInt())).thenReturn(true);
+        when(mMockNative.pauseGeofence(anyInt())).thenReturn(true);
+        when(mMockNative.removeGeofence(anyInt())).thenReturn(true);
+        when(mMockNative.resumeGeofence(anyInt(), anyInt())).thenReturn(true);
+        mTestProvider = new GnssGeofenceProvider(Looper.myLooper(), mMockNative);
+        mTestProvider.addCircularHardwareGeofence(GEOFENCE_ID, LATITUDE,
+                LONGITUDE, RADIUS, LAST_TRANSITION, MONITOR_TRANSITIONS,
+                NOTIFICATION_RESPONSIVENESS,
+                UNKNOWN_TIMER);
+    }
+
+    @Test
+    public void addGeofence_nativeAdded() {
+        verify(mMockNative).addGeofence(eq(GEOFENCE_ID), eq(LATITUDE), eq(LONGITUDE),
+                eq(RADIUS), eq(LAST_TRANSITION), eq(MONITOR_TRANSITIONS),
+                eq(NOTIFICATION_RESPONSIVENESS),
+                eq(UNKNOWN_TIMER));
+    }
+
+    @Test
+    public void pauseGeofence_nativePaused() {
+        mTestProvider.pauseHardwareGeofence(GEOFENCE_ID);
+        verify(mMockNative).pauseGeofence(eq(GEOFENCE_ID));
+    }
+
+    @Test
+    public void removeGeofence_nativeRemoved() {
+        mTestProvider.removeHardwareGeofence(GEOFENCE_ID);
+        verify(mMockNative).removeGeofence(eq(GEOFENCE_ID));
+    }
+
+    @Test
+    public void resumeGeofence_nativeResumed() {
+        mTestProvider.pauseHardwareGeofence(GEOFENCE_ID);
+        mTestProvider.resumeHardwareGeofence(GEOFENCE_ID, MONITOR_TRANSITIONS);
+        verify(mMockNative).resumeGeofence(eq(GEOFENCE_ID), eq(MONITOR_TRANSITIONS));
+    }
+
+    @Test
+    public void addGeofence_restart_added() throws RemoteException {
+        mTestProvider.resumeIfStarted();
+
+        verify(mMockNative, times(2)).addGeofence(eq(GEOFENCE_ID), eq(LATITUDE), eq(LONGITUDE),
+                eq(RADIUS), eq(LAST_TRANSITION), eq(MONITOR_TRANSITIONS),
+                eq(NOTIFICATION_RESPONSIVENESS),
+                eq(UNKNOWN_TIMER));
+    }
+
+    @Test
+    public void removeGeofence_restart_notAdded() throws RemoteException {
+        mTestProvider.removeHardwareGeofence(GEOFENCE_ID);
+        mTestProvider.resumeIfStarted();
+
+        verify(mMockNative, times(1)).addGeofence(eq(GEOFENCE_ID), eq(LATITUDE), eq(LONGITUDE),
+                eq(RADIUS), eq(LAST_TRANSITION), eq(MONITOR_TRANSITIONS),
+                eq(NOTIFICATION_RESPONSIVENESS),
+                eq(UNKNOWN_TIMER));
+    }
+
+    @Test
+    public void pauseGeofence_restart_paused() throws RemoteException {
+        mTestProvider.pauseHardwareGeofence(GEOFENCE_ID);
+        mTestProvider.resumeIfStarted();
+
+        verify(mMockNative, times(2)).addGeofence(eq(GEOFENCE_ID), eq(LATITUDE), eq(LONGITUDE),
+                eq(RADIUS), eq(LAST_TRANSITION), eq(MONITOR_TRANSITIONS),
+                eq(NOTIFICATION_RESPONSIVENESS),
+                eq(UNKNOWN_TIMER));
+        verify(mMockNative, times(2)).pauseGeofence(eq(GEOFENCE_ID));
+    }
+}
diff --git a/services/robotests/src/com/android/server/location/GnssMeasurementsProviderTest.java b/services/robotests/src/com/android/server/location/GnssMeasurementsProviderTest.java
new file mode 100644
index 0000000..23d6cf6
--- /dev/null
+++ b/services/robotests/src/com/android/server/location/GnssMeasurementsProviderTest.java
@@ -0,0 +1,90 @@
+package com.android.server.location;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+/**
+ * Unit tests for {@link GnssMeasurementsProvider}.
+ */
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(
+        manifest = Config.NONE,
+        sdk = 27
+)
+@SystemLoaderPackages({"com.android.server.location"})
+@Presubmit
+public class GnssMeasurementsProviderTest {
+    @Mock
+    private GnssMeasurementsProvider.GnssMeasurementProviderNative mMockNative;
+    private GnssMeasurementsProvider mTestProvider;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mMockNative.startMeasurementCollection(anyBoolean())).thenReturn(true);
+        when(mMockNative.stopMeasurementCollection()).thenReturn(true);
+
+        mTestProvider = new GnssMeasurementsProvider(RuntimeEnvironment.application,
+                new Handler(Looper.myLooper()), mMockNative) {
+            @Override
+            public boolean isGpsEnabled() {
+                return true;
+            }
+        };
+    }
+
+    @Test
+    public void register_nativeStarted() {
+        mTestProvider.registerWithService();
+        verify(mMockNative).startMeasurementCollection(anyBoolean());
+    }
+
+    @Test
+    public void unregister_nativeStopped() {
+        mTestProvider.registerWithService();
+        mTestProvider.unregisterFromService();
+        verify(mMockNative).stopMeasurementCollection();
+    }
+
+    @Test
+    public void isSupported_nativeIsSupported() {
+        when(mMockNative.isMeasurementSupported()).thenReturn(true);
+        assertThat(mTestProvider.isAvailableInPlatform()).isTrue();
+
+        when(mMockNative.isMeasurementSupported()).thenReturn(false);
+        assertThat(mTestProvider.isAvailableInPlatform()).isFalse();
+    }
+
+    @Test
+    public void register_resume_started() {
+        mTestProvider.registerWithService();
+        mTestProvider.resumeIfStarted();
+        verify(mMockNative, times(2)).startMeasurementCollection(anyBoolean());
+    }
+
+    @Test
+    public void unregister_resume_notStarted() {
+        mTestProvider.registerWithService();
+        mTestProvider.unregisterFromService();
+        mTestProvider.resumeIfStarted();
+        verify(mMockNative, times(1)).startMeasurementCollection(anyBoolean());
+    }
+}
diff --git a/services/robotests/src/com/android/server/location/GnssNavigationMessageProviderTest.java b/services/robotests/src/com/android/server/location/GnssNavigationMessageProviderTest.java
new file mode 100644
index 0000000..8d3de3c
--- /dev/null
+++ b/services/robotests/src/com/android/server/location/GnssNavigationMessageProviderTest.java
@@ -0,0 +1,89 @@
+package com.android.server.location;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+/**
+ * Unit tests for {@link GnssNavigationMessageProvider}.
+ */
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(
+        manifest = Config.NONE,
+        sdk = 27
+)
+@SystemLoaderPackages({"com.android.server.location"})
+@Presubmit
+public class GnssNavigationMessageProviderTest {
+    @Mock
+    private GnssNavigationMessageProvider.GnssNavigationMessageProviderNative mMockNative;
+    private GnssNavigationMessageProvider mTestProvider;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mMockNative.startNavigationMessageCollection()).thenReturn(true);
+        when(mMockNative.stopNavigationMessageCollection()).thenReturn(true);
+
+        mTestProvider = new GnssNavigationMessageProvider(new Handler(Looper.myLooper()),
+                mMockNative) {
+            @Override
+            public boolean isGpsEnabled() {
+                return true;
+            }
+        };
+    }
+
+    @Test
+    public void register_nativeStarted() {
+        mTestProvider.registerWithService();
+        verify(mMockNative).startNavigationMessageCollection();
+    }
+
+    @Test
+    public void unregister_nativeStopped() {
+        mTestProvider.registerWithService();
+        mTestProvider.unregisterFromService();
+        verify(mMockNative).stopNavigationMessageCollection();
+    }
+
+    @Test
+    public void isSupported_nativeIsSupported() {
+        when(mMockNative.isNavigationMessageSupported()).thenReturn(true);
+        assertThat(mTestProvider.isAvailableInPlatform()).isTrue();
+
+        when(mMockNative.isNavigationMessageSupported()).thenReturn(false);
+        assertThat(mTestProvider.isAvailableInPlatform()).isFalse();
+    }
+
+    @Test
+    public void register_resume_started() {
+        mTestProvider.registerWithService();
+        mTestProvider.resumeIfStarted();
+        verify(mMockNative, times(2)).startNavigationMessageCollection();
+    }
+
+    @Test
+    public void unregister_resume_notStarted() {
+        mTestProvider.registerWithService();
+        mTestProvider.unregisterFromService();
+        mTestProvider.resumeIfStarted();
+        verify(mMockNative, times(1)).startNavigationMessageCollection();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/ColorDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/ColorDisplayServiceTest.java
index 43701e9..c004074 100644
--- a/services/tests/servicestests/src/com/android/server/ColorDisplayServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ColorDisplayServiceTest.java
@@ -898,6 +898,10 @@
 
     @Test
     public void accessibility_colorInversion_transformActivated() {
+        if (!mContext.getResources().getConfiguration().isScreenWideColorGamut()) {
+            return;
+        }
+
         setAccessibilityColorInversion(true);
         setColorMode(ColorDisplayController.COLOR_MODE_NATURAL);
 
@@ -909,6 +913,10 @@
 
     @Test
     public void accessibility_colorCorrection_transformActivated() {
+        if (!mContext.getResources().getConfiguration().isScreenWideColorGamut()) {
+            return;
+        }
+
         setAccessibilityColorCorrection(true);
         setColorMode(ColorDisplayController.COLOR_MODE_NATURAL);
 
@@ -920,6 +928,10 @@
 
     @Test
     public void accessibility_all_transformActivated() {
+        if (!mContext.getResources().getConfiguration().isScreenWideColorGamut()) {
+            return;
+        }
+
         setAccessibilityColorCorrection(true);
         setAccessibilityColorInversion(true);
         setColorMode(ColorDisplayController.COLOR_MODE_NATURAL);
@@ -932,6 +944,10 @@
 
     @Test
     public void accessibility_none_transformActivated() {
+        if (!mContext.getResources().getConfiguration().isScreenWideColorGamut()) {
+            return;
+        }
+
         setAccessibilityColorCorrection(false);
         setAccessibilityColorInversion(false);
         setColorMode(ColorDisplayController.COLOR_MODE_NATURAL);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/FingerprintGestureDispatcherTest.java b/services/tests/servicestests/src/com/android/server/accessibility/FingerprintGestureDispatcherTest.java
index 98bf53c..6ce7bbe 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/FingerprintGestureDispatcherTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/FingerprintGestureDispatcherTest.java
@@ -17,14 +17,17 @@
 package com.android.server.accessibility;
 
 import android.accessibilityservice.FingerprintGestureController;
+import android.content.res.Resources;
 import android.hardware.fingerprint.IFingerprintService;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Message;
 import android.view.KeyEvent;
 
 import com.android.server.accessibility.FingerprintGestureDispatcher.FingerprintGestureClient;
 
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
@@ -49,16 +52,27 @@
     private @Mock IFingerprintService mMockFingerprintService;
     private @Mock FingerprintGestureClient mNonGestureCapturingClient;
     private @Mock FingerprintGestureClient mGestureCapturingClient;
-    private @Mock FingerprintGestureDispatcher mFingerprintGestureDispatcher;
+    private @Mock Resources mMockResources;
+
     private MessageCapturingHandler mMessageCapturingHandler;
+    private FingerprintGestureDispatcher mFingerprintGestureDispatcher;
+
+    @BeforeClass
+    public static void oneTimeInitialization() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+    }
 
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
+        // For most tests, we support fingerprint gestures
+        when(mMockResources.getBoolean(anyInt())).thenReturn(true);
         mMessageCapturingHandler = new MessageCapturingHandler(
                 msg -> mFingerprintGestureDispatcher.handleMessage(msg));
         mFingerprintGestureDispatcher = new FingerprintGestureDispatcher(mMockFingerprintService,
-                new Object(), mMessageCapturingHandler);
+                mMockResources, new Object(), mMessageCapturingHandler);
         when(mNonGestureCapturingClient.isCapturingFingerprintGestures()).thenReturn(false);
         when(mGestureCapturingClient.isCapturingFingerprintGestures()).thenReturn(true);
     }
@@ -149,10 +163,23 @@
     }
 
     @Test
-    public void testIsGestureDetectionActive_dependsOnFingerprintService() throws Exception {
+    public void testIsGestureDetectionAvailable_dependsOnFingerprintService() throws Exception {
         when(mMockFingerprintService.isClientActive()).thenReturn(true);
         assertFalse(mFingerprintGestureDispatcher.isFingerprintGestureDetectionAvailable());
         when(mMockFingerprintService.isClientActive()).thenReturn(false);
         assertTrue(mFingerprintGestureDispatcher.isFingerprintGestureDetectionAvailable());
     }
+
+    @Test
+    public void ifGestureDectionNotSupported_neverSaysAvailable() throws Exception {
+        when(mMockResources.getBoolean(anyInt())).thenReturn(false);
+        // Need to create a new dispatcher, since it picks up the resource value in its
+        // constructor. This is fine since hardware config values don't change dynamically.
+        FingerprintGestureDispatcher fingerprintGestureDispatcher =
+                new FingerprintGestureDispatcher(mMockFingerprintService, mMockResources,
+                        new Object(), mMessageCapturingHandler);
+
+        when(mMockFingerprintService.isClientActive()).thenReturn(false);
+        assertFalse(fingerprintGestureDispatcher.isFingerprintGestureDetectionAvailable());
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
index 9daea1a..1415ada 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -19,51 +19,44 @@
 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
 import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
+
 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
+import static com.android.server.am.ActivityStackSupervisor
+        .MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
+
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.ArgumentMatchers.any;
-
-import android.app.ActivityManager;
+import android.app.ActivityOptions;
 import android.app.WaitResult;
-import android.content.ComponentName;
-import android.content.res.Configuration;
 import android.graphics.Rect;
-import android.hardware.display.DisplayManager;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.util.SparseIntArray;
 
-import org.junit.runner.RunWith;
 import org.junit.Before;
 import org.junit.Test;
-
+import org.junit.runner.RunWith;
 import org.mockito.invocation.InvocationOnMock;
 
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
 
 /**
  * Tests for the {@link ActivityStackSupervisor} class.
@@ -378,4 +371,28 @@
         assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked(
                 true /* considerKeyguardState */));
     }
+
+    /**
+     * Verify that split-screen primary stack will be chosen if activity is launched that targets
+     * split-screen secondary, but a matching existing instance is found on top of split-screen
+     * primary stack.
+     */
+    @Test
+    public void testSplitScreenPrimaryChosenWhenTopActivityLaunchedToSecondary() throws Exception {
+        // Create primary split-screen stack with a task and an activity.
+        final ActivityStack primaryStack = mService.mStackSupervisor.getDefaultDisplay()
+                .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
+                        true /* onTop */);
+        final TaskRecord task = new TaskBuilder(mSupervisor).setStack(primaryStack).build();
+        final ActivityRecord r = new ActivityBuilder(mService).setTask(task).build();
+
+        // Find a launch stack for the top activity in split-screen primary, while requesting
+        // split-screen secondary.
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
+        final ActivityStack result = mSupervisor.getLaunchStack(r, options, task, true /* onTop */);
+
+        // Assert that the primary stack is returned.
+        assertEquals(primaryStack, result);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
index 592f7b1..b73ac89 100644
--- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -21,6 +21,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
@@ -303,6 +304,8 @@
 
     @Test
     public void testAddTaskCompatibleActivityType_expectRemove() throws Exception {
+        // Test with undefined activity type since the type is not persisted by the task persister
+        // and we want to ensure that a new task will match a restored task
         Configuration config1 = new Configuration();
         config1.windowConfiguration.setActivityType(ACTIVITY_TYPE_UNDEFINED);
         TaskRecord task1 = createTaskBuilder(".Task1")
@@ -355,6 +358,65 @@
     }
 
     @Test
+    public void testAddTaskCompatibleWindowingMode_expectRemove() throws Exception {
+        Configuration config1 = new Configuration();
+        config1.windowConfiguration.setWindowingMode(WINDOWING_MODE_UNDEFINED);
+        TaskRecord task1 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK)
+                .setStack(mStack)
+                .build();
+        task1.onConfigurationChanged(config1);
+        assertTrue(task1.getWindowingMode() == WINDOWING_MODE_UNDEFINED);
+        mRecentTasks.add(task1);
+        mCallbacksRecorder.clear();
+
+        Configuration config2 = new Configuration();
+        config2.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        TaskRecord task2 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK)
+                .setStack(mStack)
+                .build();
+        task2.onConfigurationChanged(config2);
+        assertTrue(task2.getWindowingMode() == WINDOWING_MODE_FULLSCREEN);
+        mRecentTasks.add(task2);
+
+        assertTrue(mCallbacksRecorder.added.size() == 1);
+        assertTrue(mCallbacksRecorder.added.contains(task2));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.size() == 1);
+        assertTrue(mCallbacksRecorder.removed.contains(task1));
+    }
+
+    @Test
+    public void testAddTaskIncompatibleWindowingMode_expectNoRemove() throws Exception {
+        Configuration config1 = new Configuration();
+        config1.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        TaskRecord task1 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK)
+                .setStack(mStack)
+                .build();
+        task1.onConfigurationChanged(config1);
+        assertTrue(task1.getWindowingMode() == WINDOWING_MODE_FULLSCREEN);
+        mRecentTasks.add(task1);
+
+        Configuration config2 = new Configuration();
+        config2.windowConfiguration.setWindowingMode(WINDOWING_MODE_PINNED);
+        TaskRecord task2 = createTaskBuilder(".Task1")
+                .setFlags(FLAG_ACTIVITY_NEW_TASK)
+                .setStack(mStack)
+                .build();
+        task2.onConfigurationChanged(config2);
+        assertTrue(task2.getWindowingMode() == WINDOWING_MODE_PINNED);
+        mRecentTasks.add(task2);
+
+        assertTrue(mCallbacksRecorder.added.size() == 2);
+        assertTrue(mCallbacksRecorder.added.contains(task1));
+        assertTrue(mCallbacksRecorder.added.contains(task2));
+        assertTrue(mCallbacksRecorder.trimmed.isEmpty());
+        assertTrue(mCallbacksRecorder.removed.isEmpty());
+    }
+
+    @Test
     public void testUsersTasks() throws Exception {
         mRecentTasks.setOnlyTestVisibleRange();
 
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java b/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
index c91e22f..057fdc8 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
@@ -17,6 +17,9 @@
 
 package com.android.server.am;
 
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -62,7 +65,7 @@
  * Tests for exercising {@link TaskRecord}.
  *
  * Build/Install/Run:
- *  bit FrameworksServicesTests:com.android.server.am.TaskRecordTests
+ *  atest FrameworksServicesTests:com.android.server.am.TaskRecordTests
  */
 @MediumTest
 @Presubmit
@@ -113,6 +116,18 @@
         assertTrue(factory.mCreated);
     }
 
+    @Test
+    public void testReturnsToHomeStack() throws Exception {
+        final TaskRecord task = createTaskRecord(1);
+        assertFalse(task.returnsToHomeStack());
+        task.intent = null;
+        assertFalse(task.returnsToHomeStack());
+        task.intent = new Intent();
+        assertFalse(task.returnsToHomeStack());
+        task.intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME);
+        assertTrue(task.returnsToHomeStack());
+    }
+
     private File serializeToFile(TaskRecord r) throws IOException, XmlPullParserException {
         final File tmpFile = File.createTempFile(r.taskId + "_task_", "xml");
 
diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java
index 64637f4..30665b5 100644
--- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java
@@ -28,12 +28,19 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.DOCKED_BOTTOM;
+import static android.view.WindowManager.DOCKED_LEFT;
+import static android.view.WindowManager.DOCKED_RIGHT;
+import static android.view.WindowManager.DOCKED_TOP;
 
+import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT;
 import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;
 import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import android.graphics.PixelFormat;
 import android.platform.test.annotations.Presubmit;
@@ -194,4 +201,53 @@
                 PhoneWindowManager.updateLightNavigationBarLw(0, opaqueDarkNavBar,
                         opaqueDarkNavBar, imeDrawLightNavBar, imeDrawLightNavBar));
     }
+
+    @Test
+    public void testIsDockSideAllowedDockTop() throws Exception {
+        // Docked top is always allowed
+        assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_TOP, DOCKED_LEFT, NAV_BAR_BOTTOM,
+                true /* navigationBarCanMove */));
+        assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_TOP, DOCKED_LEFT, NAV_BAR_BOTTOM,
+                false /* navigationBarCanMove */));
+    }
+
+    @Test
+    public void testIsDockSideAllowedDockBottom() throws Exception {
+        // Cannot dock bottom
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_BOTTOM, DOCKED_LEFT, NAV_BAR_BOTTOM,
+                true /* navigationBarCanMove */));
+    }
+
+    @Test
+    public void testIsDockSideAllowedNavigationBarMovable() throws Exception {
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT, NAV_BAR_BOTTOM,
+                true /* navigationBarCanMove */));
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT, NAV_BAR_LEFT,
+                true /* navigationBarCanMove */));
+        assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT, NAV_BAR_RIGHT,
+                true /* navigationBarCanMove */));
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT, NAV_BAR_BOTTOM,
+                true /* navigationBarCanMove */));
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT, NAV_BAR_RIGHT,
+                true /* navigationBarCanMove */));
+        assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT, NAV_BAR_LEFT,
+                true /* navigationBarCanMove */));
+    }
+
+    @Test
+    public void testIsDockSideAllowedNavigationBarNotMovable() throws Exception {
+        // Navigation bar is not movable such as tablets
+        assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_LEFT, NAV_BAR_BOTTOM,
+                false /* navigationBarCanMove */));
+        assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_TOP, NAV_BAR_BOTTOM,
+                false /* navigationBarCanMove */));
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_LEFT, DOCKED_RIGHT, NAV_BAR_BOTTOM,
+                false /* navigationBarCanMove */));
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_LEFT, NAV_BAR_BOTTOM,
+                false /* navigationBarCanMove */));
+        assertFalse(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_TOP, NAV_BAR_BOTTOM,
+                false /* navigationBarCanMove */));
+        assertTrue(PhoneWindowManager.isDockSideAllowed(DOCKED_RIGHT, DOCKED_RIGHT, NAV_BAR_BOTTOM,
+                false /* navigationBarCanMove */));
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
index 1367f58..62fe6b2 100644
--- a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
@@ -17,6 +17,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -144,6 +145,11 @@
         void runOnBgThread(Runnable r) {
             r.run();
         }
+
+        @Override
+        void runOnBgThreadLazy(Runnable r, int delayMillis) {
+            r.run();
+        }
     }
 
     @Before
@@ -153,7 +159,7 @@
         mMockBatterySaverController = mock(BatterySaverController.class);
 
         doAnswer((inv) -> mDevice.batterySaverEnabled = inv.getArgument(0))
-                .when(mMockBatterySaverController).enableBatterySaver(anyBoolean());
+                .when(mMockBatterySaverController).enableBatterySaver(anyBoolean(), anyInt());
         when(mMockBatterySaverController.isEnabled())
                 .thenAnswer((inv) -> mDevice.batterySaverEnabled);
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
index 6019958..ff631e7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
@@ -545,7 +545,7 @@
                 .restart(BOUNDS_SMALLER_FLOATING,
                         false /* expectStartedAndPipModeChangedCallback */)
                 .end()
-                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, MOVE_TO_FULLSCREEN);
     }
 
     /** !F->!F w/ CANCEL **/
diff --git a/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
index 51b019a..204e26c 100644
--- a/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -24,27 +24,29 @@
 public class RootWindowContainerTests extends WindowTestsBase {
     @Test
     public void testSetDisplayOverrideConfigurationIfNeeded() throws Exception {
-        // Add first stack we expect to be updated with configuration change.
-        final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
-        stack.getOverrideConfiguration().windowConfiguration.setBounds(new Rect(0, 0, 5, 5));
+        synchronized (sWm.mWindowMap) {
+            // Add first stack we expect to be updated with configuration change.
+            final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
+            stack.getOverrideConfiguration().windowConfiguration.setBounds(new Rect(0, 0, 5, 5));
 
-        // Add second task that will be set for deferred removal that should not be returned
-        // with the configuration change.
-        final TaskStack deferredDeletedStack = createTaskStackOnDisplay(mDisplayContent);
-        deferredDeletedStack.getOverrideConfiguration().windowConfiguration.setBounds(
-                new Rect(0, 0, 5, 5));
-        deferredDeletedStack.mDeferRemoval = true;
+            // Add second task that will be set for deferred removal that should not be returned
+            // with the configuration change.
+            final TaskStack deferredDeletedStack = createTaskStackOnDisplay(mDisplayContent);
+            deferredDeletedStack.getOverrideConfiguration().windowConfiguration.setBounds(
+                    new Rect(0, 0, 5, 5));
+            deferredDeletedStack.mDeferRemoval = true;
 
-        final Configuration override = new Configuration(
-                mDisplayContent.getOverrideConfiguration());
-        override.windowConfiguration.setBounds(new Rect(0, 0, 10, 10));
+            final Configuration override = new Configuration(
+                    mDisplayContent.getOverrideConfiguration());
+            override.windowConfiguration.setBounds(new Rect(0, 0, 10, 10));
 
-        // Set display override.
-        final int[] results = sWm.mRoot.setDisplayOverrideConfigurationIfNeeded(override,
-                        mDisplayContent.getDisplayId());
+            // Set display override.
+            final int[] results = sWm.mRoot.setDisplayOverrideConfigurationIfNeeded(override,
+                    mDisplayContent.getDisplayId());
 
-        // Ensure only first stack is returned.
-        assertTrue(results.length == 1);
-        assertTrue(results[0] == stack.mStackId);
+            // Ensure only first stack is returned.
+            assertTrue(results.length == 1);
+            assertTrue(results[0] == stack.mStackId);
+        }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 1c2d538..013c672 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -552,7 +552,8 @@
     }
 
     @Override
-    public boolean isDockSideAllowed(int dockSide) {
+    public boolean isDockSideAllowed(int dockSide, int originalDockSide, int displayWidth,
+            int displayHeight, int displayRotation) {
         return false;
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
index 41e446b..513c1ec 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
@@ -208,7 +208,8 @@
         final WindowConfiguration winConfig = config.windowConfiguration;
         stackController.adjustConfigurationForBounds(bounds, null /*insetBounds*/,
                 new Rect() /*nonDecorBounds*/, new Rect() /*stableBounds*/, false /*overrideWidth*/,
-                false /*overrideHeight*/, mDisplayInfo.logicalDensityDpi, config, parentConfig);
+                false /*overrideHeight*/, mDisplayInfo.logicalDensityDpi, config, parentConfig,
+                windowingMode);
         // Assert that both expected and actual are null or are equal to each other
 
         assertEquals(expectedConfigBounds, winConfig.getAppBounds());
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
index d74defc..2e4740b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -34,6 +34,7 @@
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.anyFloat;
+import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -72,7 +73,7 @@
             config.windowConfiguration.setBounds(bounds);
             return null;
         }).when(controller).adjustConfigurationForBounds(any(), any(), any(), any(),
-                anyBoolean(), anyBoolean(), anyFloat(), any(), any());
+                anyBoolean(), anyBoolean(), anyFloat(), any(), any(), anyInt());
 
         return controller;
     }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
index 895bbb1..d0a656c 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
@@ -267,6 +267,32 @@
     }
 
     @Test
+    public void testReadXml_appendsListOfApprovedComponents() throws Exception {
+        for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
+            ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
+                    mIpm, approvalLevel);
+
+            String preApprovedPackage = "some.random.package";
+            String preApprovedComponent = "some.random.package/C1";
+
+            List<String> packages = new ArrayList<>();
+            packages.add(preApprovedPackage);
+            addExpectedServices(service, packages, 0);
+
+            service.setPackageOrComponentEnabled(preApprovedComponent, 0, true, true);
+
+            loadXml(service);
+
+            verifyExpectedApprovedEntries(service);
+
+            String verifyValue  = (approvalLevel == APPROVAL_BY_COMPONENT)
+                    ? preApprovedComponent
+                    : preApprovedPackage;
+            assertTrue(service.isPackageOrComponentAllowed(verifyValue, 0));
+        }
+    }
+
+    @Test
     public void testWriteXml_trimsMissingServices() throws Exception {
         for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
             ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index eb1c997..8ffec40 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.notification;
 
+import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
 import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
@@ -134,6 +135,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Consumer;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -528,7 +530,7 @@
                 PKG, new ParceledListSlice(Arrays.asList(channel)));
 
         final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
-        sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
+        sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         waitForIdle();
@@ -557,7 +559,7 @@
                 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
 
         final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
-        sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
+        sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         waitForIdle();
@@ -601,7 +603,7 @@
         mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
 
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
-        sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
+        sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         waitForIdle();
@@ -759,7 +761,7 @@
     @Test
     public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
-        sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
+        sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
@@ -773,7 +775,7 @@
     @Test
     public void testCancelAllNotifications_IgnoreOtherPackages() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
-        sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
+        sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         mBinderService.cancelAllNotifications("other_pkg_name", sbn.getUserId());
@@ -901,7 +903,7 @@
     @Test
     public void testRemoveForegroundServiceFlag_ImmediatelyAfterEnqueue() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
-        sbn.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
+        sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", null,
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         mInternalService.removeForegroundServiceFlagFromNotification(PKG, sbn.getId(),
@@ -909,14 +911,14 @@
         waitForIdle();
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
-        assertEquals(0, notifs[0].getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE);
+        assertEquals(0, notifs[0].getNotification().flags & FLAG_FOREGROUND_SERVICE);
     }
 
     @Test
     public void testCancelAfterSecondEnqueueDoesNotSpecifyForegroundFlag() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
         sbn.getNotification().flags =
-                Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE;
+                Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT;
@@ -937,7 +939,7 @@
                 mTestNotificationChannel, 2, "group", false);
         final NotificationRecord child2 = generateNotificationRecord(
                 mTestNotificationChannel, 3, "group", false);
-        child2.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
+        child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         final NotificationRecord newGroup = generateNotificationRecord(
                 mTestNotificationChannel, 4, "group2", false);
         mService.addNotification(parent);
@@ -960,7 +962,7 @@
                 mTestNotificationChannel, 2, "group", false);
         final NotificationRecord child2 = generateNotificationRecord(
                 mTestNotificationChannel, 3, "group", false);
-        child2.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
+        child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         final NotificationRecord newGroup = generateNotificationRecord(
                 mTestNotificationChannel, 4, "group2", false);
         mService.addNotification(parent);
@@ -984,7 +986,7 @@
                 mTestNotificationChannel, 2, "group", false);
         final NotificationRecord child2 = generateNotificationRecord(
                 mTestNotificationChannel, 3, "group", false);
-        child2.getNotification().flags |= Notification.FLAG_FOREGROUND_SERVICE;
+        child2.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         final NotificationRecord newGroup = generateNotificationRecord(
                 mTestNotificationChannel, 4, "group2", false);
         mService.addNotification(parent);
@@ -2187,7 +2189,6 @@
     @Test
     public void testReadPolicyXml_readApprovedServicesFromXml() throws Exception {
         final String upgradeXml = "<notification-policy version=\"1\">"
-                + "<zen></zen>"
                 + "<ranking></ranking>"
                 + "<enabled_listeners>"
                 + "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
@@ -2215,7 +2216,6 @@
     @Test
     public void testReadPolicyXml_readApprovedServicesFromSettings() throws Exception {
         final String preupgradeXml = "<notification-policy version=\"1\">"
-                + "<zen></zen>"
                 + "<ranking></ranking>"
                 + "</notification-policy>";
         mService.readPolicyXml(
@@ -2257,7 +2257,7 @@
                 NotificationChannel.DEFAULT_CHANNEL_ID)
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
-                .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
+                .setFlag(FLAG_FOREGROUND_SERVICE, true)
                 .setPriority(Notification.PRIORITY_MIN);
 
         StatusBarNotification sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag", preOUid,
@@ -2272,7 +2272,7 @@
         nb = new Notification.Builder(mContext)
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
-                .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
+                .setFlag(FLAG_FOREGROUND_SERVICE, true)
                 .setPriority(Notification.PRIORITY_MIN);
 
         sbn = new StatusBarNotification(preOPkg, preOPkg, 9, "tag", preOUid,
@@ -2549,6 +2549,27 @@
     }
 
     @Test
+    public void testVisitUris() throws Exception {
+        final Uri audioContents = Uri.parse("content://com.example/audio");
+        final Uri backgroundImage = Uri.parse("content://com.example/background");
+
+        Bundle extras = new Bundle();
+        extras.putParcelable(Notification.EXTRA_AUDIO_CONTENTS_URI, audioContents);
+        extras.putString(Notification.EXTRA_BACKGROUND_IMAGE_URI, backgroundImage.toString());
+
+        Notification n = new Notification.Builder(mContext, "a")
+                .setContentTitle("notification with uris")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .addExtras(extras)
+                .build();
+
+        Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
+        n.visitUris(visitor);
+        verify(visitor, times(1)).accept(eq(audioContents));
+        verify(visitor, times(1)).accept(eq(backgroundImage));
+    }
+
+    @Test
     public void testSetNotificationPolicy_preP_setOldFields() {
         ZenModeHelper mZenModeHelper = mock(ZenModeHelper.class);
         mService.mZenModeHelper = mZenModeHelper;
@@ -2670,6 +2691,26 @@
     }
 
     @Test
+    public void testVisualDifference_foreground() {
+        Notification.Builder nb1 = new Notification.Builder(mContext, "")
+                .setContentTitle("foo");
+        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb1.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r1 =
+                new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
+
+        Notification.Builder nb2 = new Notification.Builder(mContext, "")
+                .setFlag(FLAG_FOREGROUND_SERVICE, true)
+                .setContentTitle("bar");
+        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb2.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r2 =
+                new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
+
+        assertFalse(mService.isVisuallyInterruptive(r1, r2));
+    }
+
+    @Test
     public void testVisualDifference_diffTitle() {
         Notification.Builder nb1 = new Notification.Builder(mContext, "")
                 .setContentTitle("foo");
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java
index d846d21..36ec221 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java
@@ -336,6 +336,90 @@
     }
 
     @Test
+    public void testRemoteViews_layoutChange() {
+        RemoteViews a = mock(RemoteViews.class);
+        when(a.getLayoutId()).thenReturn(234);
+        RemoteViews b = mock(RemoteViews.class);
+        when(b.getLayoutId()).thenReturn(189);
+
+        Notification.Builder n1 = new Notification.Builder(mContext, "test").setContent(a);
+        Notification.Builder n2 = new Notification.Builder(mContext, "test").setContent(b);
+        assertTrue(Notification.areRemoteViewsChanged(n1, n2));
+
+        n1 = new Notification.Builder(mContext, "test").setCustomBigContentView(a);
+        n2 = new Notification.Builder(mContext, "test").setCustomBigContentView(b);
+        assertTrue(Notification.areRemoteViewsChanged(n1, n2));
+
+        n1 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(a);
+        n2 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(b);
+        assertTrue(Notification.areRemoteViewsChanged(n1, n2));
+    }
+
+    @Test
+    public void testRemoteViews_layoutSame() {
+        RemoteViews a = mock(RemoteViews.class);
+        when(a.getLayoutId()).thenReturn(234);
+        RemoteViews b = mock(RemoteViews.class);
+        when(b.getLayoutId()).thenReturn(234);
+
+        Notification.Builder n1 = new Notification.Builder(mContext, "test").setContent(a);
+        Notification.Builder n2 = new Notification.Builder(mContext, "test").setContent(b);
+        assertFalse(Notification.areRemoteViewsChanged(n1, n2));
+
+        n1 = new Notification.Builder(mContext, "test").setCustomBigContentView(a);
+        n2 = new Notification.Builder(mContext, "test").setCustomBigContentView(b);
+        assertFalse(Notification.areRemoteViewsChanged(n1, n2));
+
+        n1 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(a);
+        n2 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(b);
+        assertFalse(Notification.areRemoteViewsChanged(n1, n2));
+    }
+
+    @Test
+    public void testRemoteViews_sequenceChange() {
+        RemoteViews a = mock(RemoteViews.class);
+        when(a.getLayoutId()).thenReturn(234);
+        when(a.getSequenceNumber()).thenReturn(1);
+        RemoteViews b = mock(RemoteViews.class);
+        when(b.getLayoutId()).thenReturn(234);
+        when(b.getSequenceNumber()).thenReturn(2);
+
+        Notification.Builder n1 = new Notification.Builder(mContext, "test").setContent(a);
+        Notification.Builder n2 = new Notification.Builder(mContext, "test").setContent(b);
+        assertTrue(Notification.areRemoteViewsChanged(n1, n2));
+
+        n1 = new Notification.Builder(mContext, "test").setCustomBigContentView(a);
+        n2 = new Notification.Builder(mContext, "test").setCustomBigContentView(b);
+        assertTrue(Notification.areRemoteViewsChanged(n1, n2));
+
+        n1 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(a);
+        n2 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(b);
+        assertTrue(Notification.areRemoteViewsChanged(n1, n2));
+    }
+
+    @Test
+    public void testRemoteViews_sequenceSame() {
+        RemoteViews a = mock(RemoteViews.class);
+        when(a.getLayoutId()).thenReturn(234);
+        when(a.getSequenceNumber()).thenReturn(1);
+        RemoteViews b = mock(RemoteViews.class);
+        when(b.getLayoutId()).thenReturn(234);
+        when(b.getSequenceNumber()).thenReturn(1);
+
+        Notification.Builder n1 = new Notification.Builder(mContext, "test").setContent(a);
+        Notification.Builder n2 = new Notification.Builder(mContext, "test").setContent(b);
+        assertFalse(Notification.areRemoteViewsChanged(n1, n2));
+
+        n1 = new Notification.Builder(mContext, "test").setCustomBigContentView(a);
+        n2 = new Notification.Builder(mContext, "test").setCustomBigContentView(b);
+        assertFalse(Notification.areRemoteViewsChanged(n1, n2));
+
+        n1 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(a);
+        n2 = new Notification.Builder(mContext, "test").setCustomHeadsUpContentView(b);
+        assertFalse(Notification.areRemoteViewsChanged(n1, n2));
+    }
+
+    @Test
     public void testActionsDifferent_null() {
         Notification n1 = new Notification.Builder(mContext, "test")
                 .build();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index d02a983..afc1263 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -17,6 +17,9 @@
 package com.android.server.notification;
 
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
 
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertEquals;
@@ -569,8 +572,6 @@
         mZenModeHelperSpy.mConfig.allowMessages = true;
         mZenModeHelperSpy.mConfig.allowEvents = true;
         mZenModeHelperSpy.mConfig.allowRepeatCallers= true;
-        mZenModeHelperSpy.mConfig.allowWhenScreenOff = true;
-        mZenModeHelperSpy.mConfig.allowWhenScreenOn = true;
         mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
         mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
         mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("a", "a");
@@ -593,8 +594,6 @@
         mZenModeHelperSpy.mConfig.allowMessages = true;
         mZenModeHelperSpy.mConfig.allowEvents = true;
         mZenModeHelperSpy.mConfig.allowRepeatCallers= true;
-        mZenModeHelperSpy.mConfig.allowWhenScreenOff = true;
-        mZenModeHelperSpy.mConfig.allowWhenScreenOn = true;
         mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
         mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
         mZenModeHelperSpy.mConfig.manualRule.zenMode =
@@ -645,6 +644,115 @@
     }
 
     @Test
+    public void testMigrateSuppressedVisualEffects_oneExistsButOff() throws Exception {
+        String xml = "<zen version=\"6\" user=\"0\">\n"
+                + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
+                + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
+                + "visualScreenOff=\"false\" alarms=\"true\" "
+                + "media=\"true\" system=\"false\" />\n"
+                + "<disallow visualEffects=\"511\" />"
+                + "</zen>";
+
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(
+                new ByteArrayInputStream(xml.getBytes())), null);
+        parser.nextTag();
+        mZenModeHelperSpy.readXml(parser, false);
+
+        assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+
+        xml = "<zen version=\"6\" user=\"0\">\n"
+                + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
+                + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
+                + "visualScreenOn=\"false\" alarms=\"true\" "
+                + "media=\"true\" system=\"false\" />\n"
+                + "<disallow visualEffects=\"511\" />"
+                + "</zen>";
+
+        parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(
+                new ByteArrayInputStream(xml.getBytes())), null);
+        parser.nextTag();
+        mZenModeHelperSpy.readXml(parser, false);
+
+        assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+    }
+
+    @Test
+    public void testMigrateSuppressedVisualEffects_bothExistButOff() throws Exception {
+        String xml = "<zen version=\"6\" user=\"0\">\n"
+                + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
+                + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
+                + "visualScreenOff=\"false\" visualScreenOn=\"false\" alarms=\"true\" "
+                + "media=\"true\" system=\"false\" />\n"
+                + "<disallow visualEffects=\"511\" />"
+                + "</zen>";
+
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(
+                new ByteArrayInputStream(xml.getBytes())), null);
+        parser.nextTag();
+        mZenModeHelperSpy.readXml(parser, false);
+
+        assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+    }
+
+    @Test
+    public void testMigrateSuppressedVisualEffects_bothExistButOn() throws Exception {
+        String xml = "<zen version=\"6\" user=\"0\">\n"
+                + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
+                + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
+                + "visualScreenOff=\"true\" visualScreenOn=\"true\" alarms=\"true\" "
+                + "media=\"true\" system=\"false\" />\n"
+                + "<disallow visualEffects=\"511\" />"
+                + "</zen>";
+
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(
+                new ByteArrayInputStream(xml.getBytes())), null);
+        parser.nextTag();
+        mZenModeHelperSpy.readXml(parser, false);
+
+        assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
+                | SUPPRESSED_EFFECT_LIGHTS
+                | SUPPRESSED_EFFECT_PEEK,
+                mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+
+        xml = "<zen version=\"6\" user=\"0\">\n"
+                + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
+                + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
+                + "visualScreenOff=\"false\" visualScreenOn=\"true\" alarms=\"true\" "
+                + "media=\"true\" system=\"false\" />\n"
+                + "<disallow visualEffects=\"511\" />"
+                + "</zen>";
+
+        parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(
+                new ByteArrayInputStream(xml.getBytes())), null);
+        parser.nextTag();
+        mZenModeHelperSpy.readXml(parser, false);
+
+        assertEquals(SUPPRESSED_EFFECT_PEEK, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+
+        xml = "<zen version=\"6\" user=\"0\">\n"
+                + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
+                + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
+                + "visualScreenOff=\"true\" visualScreenOn=\"false\" alarms=\"true\" "
+                + "media=\"true\" system=\"false\" />\n"
+                + "<disallow visualEffects=\"511\" />"
+                + "</zen>";
+
+        parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(
+                new ByteArrayInputStream(xml.getBytes())), null);
+        parser.nextTag();
+        mZenModeHelperSpy.readXml(parser, false);
+
+        assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT | SUPPRESSED_EFFECT_LIGHTS,
+                mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+    }
+
+    @Test
     public void testReadXmlResetDefaultRules() throws Exception {
         setupZenConfig();
 
@@ -705,16 +813,6 @@
         setupZenConfigMaintained();
     }
 
-    @Test
-    public void testPolicyReadsSuppressedEffects() {
-        mZenModeHelperSpy.mConfig.allowWhenScreenOff = true;
-        mZenModeHelperSpy.mConfig.allowWhenScreenOn = true;
-        mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
-
-        NotificationManager.Policy policy = mZenModeHelperSpy.getNotificationPolicy();
-        assertEquals(SUPPRESSED_EFFECT_BADGE, policy.suppressedVisualEffects);
-    }
-
     private void setupZenConfig() {
         mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         mZenModeHelperSpy.mConfig.allowAlarms = false;
@@ -725,8 +823,6 @@
         mZenModeHelperSpy.mConfig.allowMessages = true;
         mZenModeHelperSpy.mConfig.allowEvents = true;
         mZenModeHelperSpy.mConfig.allowRepeatCallers= true;
-        mZenModeHelperSpy.mConfig.allowWhenScreenOff = true;
-        mZenModeHelperSpy.mConfig.allowWhenScreenOn = true;
         mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
         mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
         mZenModeHelperSpy.mConfig.manualRule.zenMode =
@@ -746,8 +842,6 @@
         assertTrue(mZenModeHelperSpy.mConfig.allowMessages);
         assertTrue(mZenModeHelperSpy.mConfig.allowEvents);
         assertTrue(mZenModeHelperSpy.mConfig.allowRepeatCallers);
-        assertTrue(mZenModeHelperSpy.mConfig.allowWhenScreenOff);
-        assertTrue(mZenModeHelperSpy.mConfig.allowWhenScreenOn);
         assertEquals(SUPPRESSED_EFFECT_BADGE, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
     }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
index d49ba3e..43a4e27 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
@@ -93,7 +93,7 @@
 
         mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
         mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
-        verify(mService, times(1)).createPinnedSlice(eq(TEST_URI), eq("pkg"));
+        verify(mService, times(1)).createPinnedSlice(eq(TEST_URI), anyString());
     }
 
     @Test
@@ -126,4 +126,4 @@
         verify(mContextSpy).checkPermission(eq("perm2"), eq(Process.myPid()), eq(Process.myUid()));
     }
 
-}
\ No newline at end of file
+}
diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java
index 920a605..97c5ac9 100644
--- a/services/usage/java/com/android/server/usage/AppStandbyController.java
+++ b/services/usage/java/com/android/server/usage/AppStandbyController.java
@@ -81,7 +81,7 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
-import android.provider.Settings;
+import android.provider.Settings.Global;
 import android.telephony.TelephonyManager;
 import android.util.ArraySet;
 import android.util.KeyValueListParser;
@@ -1439,8 +1439,10 @@
         boolean isAppIdleEnabled() {
             final boolean buildFlag = mContext.getResources().getBoolean(
                     com.android.internal.R.bool.config_enableAutoPowerModes);
-            final boolean runtimeFlag = Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.APP_STANDBY_ENABLED, 1) == 1;
+            final boolean runtimeFlag = Global.getInt(mContext.getContentResolver(),
+                    Global.APP_STANDBY_ENABLED, 1) == 1
+                    && Global.getInt(mContext.getContentResolver(),
+                    Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, 1) == 1;
             return buildFlag && runtimeFlag;
         }
 
@@ -1489,8 +1491,8 @@
         }
 
         String getAppIdleSettings() {
-            return Settings.Global.getString(mContext.getContentResolver(),
-                    Settings.Global.APP_IDLE_CONSTANTS);
+            return Global.getString(mContext.getContentResolver(),
+                    Global.APP_IDLE_CONSTANTS);
         }
     }
 
@@ -1610,7 +1612,7 @@
     };
 
     /**
-     * Observe settings changes for {@link Settings.Global#APP_IDLE_CONSTANTS}.
+     * Observe settings changes for {@link Global#APP_IDLE_CONSTANTS}.
      */
     private class SettingsObserver extends ContentObserver {
         /**
@@ -1650,10 +1652,11 @@
         }
 
         void registerObserver() {
-            mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
-                    Settings.Global.APP_IDLE_CONSTANTS), false, this);
-            mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
-                    Settings.Global.APP_STANDBY_ENABLED), false, this);
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.registerContentObserver(Global.getUriFor(Global.APP_IDLE_CONSTANTS), false, this);
+            cr.registerContentObserver(Global.getUriFor(Global.APP_STANDBY_ENABLED), false, this);
+            cr.registerContentObserver(Global.getUriFor(Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED),
+                    false, this);
         }
 
         @Override
@@ -1665,11 +1668,14 @@
         void updateSettings() {
             if (DEBUG) {
                 Slog.d(TAG,
-                        "appidle=" + Settings.Global.getString(mContext.getContentResolver(),
-                                Settings.Global.APP_STANDBY_ENABLED));
-                Slog.d(TAG, "appidleconstants=" + Settings.Global.getString(
+                        "appidle=" + Global.getString(mContext.getContentResolver(),
+                                Global.APP_STANDBY_ENABLED));
+                Slog.d(TAG,
+                        "adaptivebat=" + Global.getString(mContext.getContentResolver(),
+                                Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED));
+                Slog.d(TAG, "appidleconstants=" + Global.getString(
                         mContext.getContentResolver(),
-                        Settings.Global.APP_IDLE_CONSTANTS));
+                        Global.APP_IDLE_CONSTANTS));
             }
             // Check if app_idle_enabled has changed
             setAppIdleEnabled(mInjector.isAppIdleEnabled());
diff --git a/services/usage/java/com/android/server/usage/IntervalStats.java b/services/usage/java/com/android/server/usage/IntervalStats.java
index c914689..0dce738 100644
--- a/services/usage/java/com/android/server/usage/IntervalStats.java
+++ b/services/usage/java/com/android/server/usage/IntervalStats.java
@@ -16,6 +16,7 @@
 package com.android.server.usage;
 
 import android.app.usage.ConfigurationStats;
+import android.app.usage.EventList;
 import android.app.usage.EventStats;
 import android.app.usage.TimeSparseArray;
 import android.app.usage.UsageEvents;
@@ -37,7 +38,7 @@
     public final ArrayMap<String, UsageStats> packageStats = new ArrayMap<>();
     public final ArrayMap<Configuration, ConfigurationStats> configurations = new ArrayMap<>();
     public Configuration activeConfiguration;
-    public TimeSparseArray<UsageEvents.Event> events;
+    public EventList events;
 
     // A string cache. This is important as when we're parsing XML files, we don't want to
     // keep hundreds of strings that have the same contents. We will read the string
diff --git a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
index fe3a884..aa832ad 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
@@ -22,12 +22,11 @@
 import org.xmlpull.v1.XmlSerializer;
 
 import android.app.usage.ConfigurationStats;
-import android.app.usage.TimeSparseArray;
+import android.app.usage.EventList;
 import android.app.usage.UsageEvents;
 import android.app.usage.UsageStats;
 import android.content.res.Configuration;
 import android.util.ArrayMap;
-import android.util.Pair;
 
 import java.io.IOException;
 import java.net.ProtocolException;
@@ -193,9 +192,9 @@
         }
 
         if (statsOut.events == null) {
-            statsOut.events = new TimeSparseArray<>();
+            statsOut.events = new EventList();
         }
-        statsOut.events.put(event.mTimeStamp, event);
+        statsOut.events.insert(event);
     }
 
     private static void writeUsageStats(XmlSerializer xml, final IntervalStats stats,
@@ -411,7 +410,7 @@
         xml.startTag(null, EVENT_LOG_TAG);
         final int eventCount = stats.events != null ? stats.events.size() : 0;
         for (int i = 0; i < eventCount; i++) {
-            writeEvent(xml, stats, stats.events.valueAt(i));
+            writeEvent(xml, stats, stats.events.get(i));
         }
         xml.endTag(null, EVENT_LOG_TAG);
     }
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index d9fc066..9cb98f3 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -17,15 +17,14 @@
 package com.android.server.usage;
 
 import android.app.usage.ConfigurationStats;
+import android.app.usage.EventList;
 import android.app.usage.EventStats;
-import android.app.usage.TimeSparseArray;
 import android.app.usage.UsageEvents;
 import android.app.usage.UsageStats;
 import android.app.usage.UsageStatsManager;
 import android.content.res.Configuration;
 import android.os.SystemClock;
 import android.content.Context;
-import android.text.format.DateFormat;
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -174,10 +173,10 @@
 
         // Add the event to the daily list.
         if (currentDailyStats.events == null) {
-            currentDailyStats.events = new TimeSparseArray<>();
+            currentDailyStats.events = new EventList();
         }
         if (event.mEventType != UsageEvents.Event.SYSTEM_INTERACTION) {
-            currentDailyStats.events.put(event.mTimeStamp, event);
+            currentDailyStats.events.insert(event);
         }
 
         boolean incrementAppLaunch = false;
@@ -367,18 +366,14 @@
                             return;
                         }
 
-                        final int startIndex = stats.events.closestIndexOnOrAfter(beginTime);
-                        if (startIndex < 0) {
-                            return;
-                        }
-
+                        final int startIndex = stats.events.firstIndexOnOrAfter(beginTime);
                         final int size = stats.events.size();
                         for (int i = startIndex; i < size; i++) {
-                            if (stats.events.keyAt(i) >= endTime) {
+                            if (stats.events.get(i).mTimeStamp >= endTime) {
                                 return;
                             }
 
-                            UsageEvents.Event event = stats.events.valueAt(i);
+                            UsageEvents.Event event = stats.events.get(i);
                             if (obfuscateInstantApps) {
                                 event = event.getObfuscatedIfInstantApp();
                             }
@@ -410,18 +405,14 @@
                         return;
                     }
 
-                    final int startIndex = stats.events.closestIndexOnOrAfter(beginTime);
-                    if (startIndex < 0) {
-                        return;
-                    }
-
+                    final int startIndex = stats.events.firstIndexOnOrAfter(beginTime);
                     final int size = stats.events.size();
                     for (int i = startIndex; i < size; i++) {
-                        if (stats.events.keyAt(i) >= endTime) {
+                        if (stats.events.get(i).mTimeStamp >= endTime) {
                             return;
                         }
 
-                        final UsageEvents.Event event = stats.events.valueAt(i);
+                        final UsageEvents.Event event = stats.events.get(i);
                         if (!packageName.equals(event.mPackage)) {
                             continue;
                         }
@@ -633,18 +624,14 @@
                             return;
                         }
 
-                        final int startIndex = stats.events.closestIndexOnOrAfter(beginTime);
-                        if (startIndex < 0) {
-                            return;
-                        }
-
+                        final int startIndex = stats.events.firstIndexOnOrAfter(beginTime);
                         final int size = stats.events.size();
                         for (int i = startIndex; i < size; i++) {
-                            if (stats.events.keyAt(i) >= endTime) {
+                            if (stats.events.get(i).mTimeStamp >= endTime) {
                                 return;
                             }
 
-                            UsageEvents.Event event = stats.events.valueAt(i);
+                            UsageEvents.Event event = stats.events.get(i);
                             if (pkg != null && !pkg.equals(event.mPackage)) {
                                 continue;
                             }
@@ -779,10 +766,10 @@
         if (!skipEvents) {
             pw.println("events");
             pw.increaseIndent();
-            final TimeSparseArray<UsageEvents.Event> events = stats.events;
+            final EventList events = stats.events;
             final int eventCount = events != null ? events.size() : 0;
             for (int i = 0; i < eventCount; i++) {
-                final UsageEvents.Event event = events.valueAt(i);
+                final UsageEvents.Event event = events.get(i);
                 if (pkg != null && !pkg.equals(event.mPackage)) {
                     continue;
                 }
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index cd524a5..f8526ef 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -32,7 +32,6 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -49,7 +48,6 @@
 import android.media.soundtrigger.ISoundTriggerDetectionService;
 import android.media.soundtrigger.ISoundTriggerDetectionServiceClient;
 import android.media.soundtrigger.SoundTriggerDetectionService;
-import android.media.soundtrigger.SoundTriggerManager;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -67,7 +65,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.ISoundTriggerService;
-import com.android.internal.util.DumpUtils;
 import com.android.internal.util.Preconditions;
 import com.android.server.SystemService;
 
@@ -100,7 +97,6 @@
     private final TreeMap<UUID, SoundModel> mLoadedModels;
     private Object mCallbacksLock;
     private final TreeMap<UUID, IRecognitionStatusCallback> mCallbacks;
-    private PowerManager.WakeLock mWakelock;
 
     /** Number of ops run by the {@link RemoteSoundTriggerDetectionService} per package name */
     @GuardedBy("mLock")
@@ -296,28 +292,17 @@
             Preconditions.checkNotNull(detectionService);
             Preconditions.checkNotNull(config);
 
-            return startRecognitionForInt(soundModelId,
-                new RemoteSoundTriggerDetectionService(soundModelId.getUuid(),
-                    params, detectionService, Binder.getCallingUserHandle(), config), config);
-
-        }
-
-        @Override
-        public int startRecognitionForIntent(ParcelUuid soundModelId, PendingIntent callbackIntent,
-                SoundTrigger.RecognitionConfig config) {
-            return startRecognitionForInt(soundModelId,
-                new LocalSoundTriggerRecognitionStatusIntentCallback(soundModelId.getUuid(),
-                    callbackIntent, config), config);
-        }
-
-        private int startRecognitionForInt(ParcelUuid soundModelId,
-            IRecognitionStatusCallback callback, SoundTrigger.RecognitionConfig config) {
             enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+
             if (!isInitialized()) return STATUS_ERROR;
             if (DEBUG) {
                 Slog.i(TAG, "startRecognition(): id = " + soundModelId);
             }
 
+            IRecognitionStatusCallback callback =
+                    new RemoteSoundTriggerDetectionService(soundModelId.getUuid(), params,
+                            detectionService, Binder.getCallingUserHandle(), config);
+
             synchronized (mLock) {
                 SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
                 if (soundModel == null) {
@@ -334,12 +319,6 @@
                 }
                 int ret;
                 switch (soundModel.type) {
-                    case SoundModel.TYPE_KEYPHRASE: {
-                        KeyphraseSoundModel keyphraseSoundModel = (KeyphraseSoundModel) soundModel;
-                        ret = mSoundTriggerHelper.startKeyphraseRecognition(
-                            keyphraseSoundModel.keyphrases[0].id, keyphraseSoundModel, callback,
-                            config);
-                    } break;
                     case SoundModel.TYPE_GENERIC_SOUND:
                         ret = mSoundTriggerHelper.startGenericRecognition(soundModel.uuid,
                             (GenericSoundModel) soundModel, callback, config);
@@ -361,7 +340,7 @@
         }
 
         @Override
-        public int stopRecognitionForIntent(ParcelUuid soundModelId) {
+        public int stopRecognitionForService(ParcelUuid soundModelId) {
             enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
             if (!isInitialized()) return STATUS_ERROR;
             if (DEBUG) {
@@ -384,10 +363,6 @@
                 }
                 int ret;
                 switch (soundModel.type) {
-                    case SoundModel.TYPE_KEYPHRASE:
-                        ret = mSoundTriggerHelper.stopKeyphraseRecognition(
-                                ((KeyphraseSoundModel)soundModel).keyphrases[0].id, callback);
-                        break;
                     case SoundModel.TYPE_GENERIC_SOUND:
                         ret = mSoundTriggerHelper.stopGenericRecognition(soundModel.uuid, callback);
                         break;
@@ -457,138 +432,6 @@
         }
     }
 
-    private final class LocalSoundTriggerRecognitionStatusIntentCallback
-            extends IRecognitionStatusCallback.Stub {
-        private UUID mUuid;
-        private PendingIntent mCallbackIntent;
-        private RecognitionConfig mRecognitionConfig;
-
-        public LocalSoundTriggerRecognitionStatusIntentCallback(UUID modelUuid,
-                PendingIntent callbackIntent,
-                RecognitionConfig config) {
-            mUuid = modelUuid;
-            mCallbackIntent = callbackIntent;
-            mRecognitionConfig = config;
-        }
-
-        @Override
-        public boolean pingBinder() {
-            return mCallbackIntent != null;
-        }
-
-        @Override
-        public void onKeyphraseDetected(SoundTrigger.KeyphraseRecognitionEvent event) {
-            if (mCallbackIntent == null) {
-                return;
-            }
-            grabWakeLock();
-
-            Slog.w(TAG, "Keyphrase sound trigger event: " + event);
-            Intent extras = new Intent();
-            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
-                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_EVENT);
-            extras.putExtra(SoundTriggerManager.EXTRA_RECOGNITION_EVENT, event);
-            try {
-                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
-                if (!mRecognitionConfig.allowMultipleTriggers) {
-                    removeCallback(/*releaseWakeLock=*/false);
-                }
-            } catch (PendingIntent.CanceledException e) {
-                removeCallback(/*releaseWakeLock=*/true);
-            }
-        }
-
-        @Override
-        public void onGenericSoundTriggerDetected(SoundTrigger.GenericRecognitionEvent event) {
-            if (mCallbackIntent == null) {
-                return;
-            }
-            grabWakeLock();
-
-            Slog.w(TAG, "Generic sound trigger event: " + event);
-            Intent extras = new Intent();
-            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
-                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_EVENT);
-            extras.putExtra(SoundTriggerManager.EXTRA_RECOGNITION_EVENT, event);
-            try {
-                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
-                if (!mRecognitionConfig.allowMultipleTriggers) {
-                    removeCallback(/*releaseWakeLock=*/false);
-                }
-            } catch (PendingIntent.CanceledException e) {
-                removeCallback(/*releaseWakeLock=*/true);
-            }
-        }
-
-        @Override
-        public void onError(int status) {
-            if (mCallbackIntent == null) {
-                return;
-            }
-            grabWakeLock();
-
-            Slog.i(TAG, "onError: " + status);
-            Intent extras = new Intent();
-            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
-                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_ERROR);
-            extras.putExtra(SoundTriggerManager.EXTRA_STATUS, status);
-            try {
-                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
-                // Remove the callback, but wait for the intent to finish before we let go of the
-                // wake lock
-                removeCallback(/*releaseWakeLock=*/false);
-            } catch (PendingIntent.CanceledException e) {
-                removeCallback(/*releaseWakeLock=*/true);
-            }
-        }
-
-        @Override
-        public void onRecognitionPaused() {
-            if (mCallbackIntent == null) {
-                return;
-            }
-            grabWakeLock();
-
-            Slog.i(TAG, "onRecognitionPaused");
-            Intent extras = new Intent();
-            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
-                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_PAUSED);
-            try {
-                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
-            } catch (PendingIntent.CanceledException e) {
-                removeCallback(/*releaseWakeLock=*/true);
-            }
-        }
-
-        @Override
-        public void onRecognitionResumed() {
-            if (mCallbackIntent == null) {
-                return;
-            }
-            grabWakeLock();
-
-            Slog.i(TAG, "onRecognitionResumed");
-            Intent extras = new Intent();
-            extras.putExtra(SoundTriggerManager.EXTRA_MESSAGE_TYPE,
-                    SoundTriggerManager.FLAG_MESSAGE_TYPE_RECOGNITION_RESUMED);
-            try {
-                mCallbackIntent.send(mContext, 0, extras, mCallbackCompletedHandler, null);
-            } catch (PendingIntent.CanceledException e) {
-                removeCallback(/*releaseWakeLock=*/true);
-            }
-        }
-
-        private void removeCallback(boolean releaseWakeLock) {
-            mCallbackIntent = null;
-            synchronized (mCallbacksLock) {
-                mCallbacks.remove(mUuid);
-                if (releaseWakeLock) {
-                    mWakelock.release();
-                }
-            }
-        }
-    }
-
     /**
      * Counts the number of operations added in the last 24 hours.
      */
@@ -1060,27 +903,6 @@
         }
     }
 
-    private void grabWakeLock() {
-        synchronized (mCallbacksLock) {
-            if (mWakelock == null) {
-                PowerManager pm = ((PowerManager) mContext.getSystemService(Context.POWER_SERVICE));
-                mWakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
-            }
-            mWakelock.acquire();
-        }
-    }
-
-    private PendingIntent.OnFinished mCallbackCompletedHandler = new PendingIntent.OnFinished() {
-        @Override
-        public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
-                String resultData, Bundle resultExtras) {
-            // We're only ever invoked when the callback is done, so release the lock.
-            synchronized (mCallbacksLock) {
-                mWakelock.release();
-            }
-        }
-    };
-
     public final class LocalSoundTriggerService extends SoundTriggerInternal {
         private final Context mContext;
         private SoundTriggerHelper mSoundTriggerHelper;
diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java
index 83ca470..0eb9917 100644
--- a/telecomm/java/android/telecom/Log.java
+++ b/telecomm/java/android/telecom/Log.java
@@ -46,6 +46,11 @@
     private static final int EVENTS_TO_CACHE = 10;
     private static final int EVENTS_TO_CACHE_DEBUG = 20;
 
+    /**
+     * When generating a bug report, include the last X dialable digits when logging phone numbers.
+     */
+    private static final int NUM_DIALABLE_DIGITS_TO_LOG = Build.IS_USER ? 0 : 2;
+
     // Generic tag for all Telecom logging
     @VisibleForTesting
     public static String TAG = "TelecomFramework";
@@ -384,9 +389,15 @@
 
             String textToObfuscate = uri.getSchemeSpecificPart();
             if (PhoneAccount.SCHEME_TEL.equals(scheme)) {
+                int numDigitsToObfuscate = getDialableCount(textToObfuscate)
+                        - NUM_DIALABLE_DIGITS_TO_LOG;
                 for (int i = 0; i < textToObfuscate.length(); i++) {
                     char c = textToObfuscate.charAt(i);
-                    sb.append(PhoneNumberUtils.isDialable(c) ? "*" : c);
+                    boolean isDialable = PhoneNumberUtils.isDialable(c);
+                    if (isDialable) {
+                        numDigitsToObfuscate--;
+                    }
+                    sb.append(isDialable && numDigitsToObfuscate >= 0 ? "*" : c);
                 }
             } else if (PhoneAccount.SCHEME_SIP.equals(scheme)) {
                 for (int i = 0; i < textToObfuscate.length(); i++) {
@@ -405,6 +416,21 @@
     }
 
     /**
+     * Determines the number of dialable characters in a string.
+     * @param toCount The string to count dialable characters in.
+     * @return The count of dialable characters.
+     */
+    private static int getDialableCount(String toCount) {
+        int numDialable = 0;
+        for (char c : toCount.toCharArray()) {
+            if (PhoneNumberUtils.isDialable(c)) {
+                numDialable++;
+            }
+        }
+        return numDialable;
+    }
+
+    /**
      * Redact personally identifiable information for production users.
      * If we are running in verbose mode, return the original string,
      * and return "***" otherwise.
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index f164bcd..e213d79 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -2964,12 +2964,30 @@
          * @hide
          */
         public static final int OWNED_BY_DPC = 0;
+
         /**
          * Possible value for the OWNED_BY field.
          * APN is owned by other sources.
          * @hide
          */
         public static final int OWNED_BY_OTHERS = 1;
+
+        /**
+         * The APN set id. When the user manually selects an APN or the framework sets an APN as
+         * preferred, all APNs with the same set id as the selected APN should be prioritized over
+         * APNs in other sets.
+         * @hide
+         */
+        public static final String APN_SET_ID = "apn_set_id";
+
+        /**
+         * Possible value for the APN_SET_ID field. By default APNs will not belong to a set. If the
+         * user manually selects an APN with no set set, there is no need to prioritize any specific
+         * APN set ids.
+         * @hide
+         */
+        public static final int NO_SET_SET = 0;
+
     }
 
     /**
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 3e73b93..88bed4e 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -16,6 +16,7 @@
 
 package android.telephony;
 
+import android.annotation.NonNull;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -596,7 +597,8 @@
      * @param configs List of the current {@link PhysicalChannelConfig}s
      * @hide
      */
-    public void onPhysicalChannelConfigurationChanged(List<PhysicalChannelConfig> configs) {
+    public void onPhysicalChannelConfigurationChanged(
+            @NonNull List<PhysicalChannelConfig> configs) {
         // default implementation empty
     }
 
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 5a2ef73..43ec716 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1877,7 +1877,7 @@
 
     /**
      * Returns the ISO country code equivalent of the MCC (Mobile Country Code) of the current
-     * registered operator, or nearby cell information if not registered.
+     * registered operator or the cell nearby, if available.
      * .
      * <p>
      * Note: Result may be unreliable on CDMA networks (use {@link #getPhoneType()} to determine
@@ -1889,7 +1889,7 @@
 
     /**
      * Returns the ISO country code equivalent of the MCC (Mobile Country Code) of the current
-     * registered operator, or nearby cell information if not registered.
+     * registered operator or the cell nearby, if available.
      * <p>
      * Note: Result may be unreliable on CDMA networks (use {@link #getPhoneType()} to determine
      * if on a CDMA network).
@@ -2786,6 +2786,22 @@
     }
 
     /**
+     * Test method to reload the UICC profile.
+     *
+     * @hide
+     */
+    @TestApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public void refreshUiccProfile() {
+        try {
+            ITelephony telephony = getITelephony();
+            telephony.refreshUiccProfile(mSubId);
+        } catch (RemoteException ex) {
+            Rlog.w(TAG, "RemoteException", ex);
+        }
+    }
+
+    /**
      * Map logicalSlot to physicalSlot, and activate the physicalSlot if it is inactive. For
      * example, passing the physicalSlots array [1, 0] means mapping the first item 1, which is
      * physical slot index 1, to the logical slot 0; and mapping the second item 0, which is
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 1d4faf1..f02f27d 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1514,4 +1514,10 @@
      * A test API to return installed carrier id list version.
      */
     int getCarrierIdListVersion(int subId);
+
+    /**
+     * A test API to reload the UICC profile.
+     * @hide
+     */
+    void refreshUiccProfile(int subId);
 }
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 482d6e1..5b73bba 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -84,6 +84,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.net.CaptivePortal;
 import android.net.ConnectivityManager;
@@ -201,6 +202,7 @@
     @Mock DefaultNetworkMetrics mDefaultNetworkMetrics;
     @Mock INetworkManagementService mNetworkManagementService;
     @Mock INetworkStatsService mStatsService;
+    @Mock Vpn mMockVpn;
 
     private ArgumentCaptor<String[]> mStringArrayCaptor = ArgumentCaptor.forClass(String[].class);
 
@@ -505,6 +507,7 @@
                 mWrappedNetworkMonitor.gen204ProbeResult = 204;
                 NetworkRequest request = new NetworkRequest.Builder()
                         .addTransportType(mNetworkCapabilities.getTransportTypes()[0])
+                        .clearCapabilities()
                         .build();
                 callback = new NetworkCallback() {
                     public void onCapabilitiesChanged(Network network,
@@ -888,6 +891,15 @@
             return mLastCreatedNetworkMonitor;
         }
 
+        public void mockVpn(int uid) {
+            synchronized (mVpns) {
+                // This has no effect unless the VPN is actually connected, because things like
+                // getActiveNetworkForUidInternal call getNetworkAgentInfoForNetId on the VPN
+                // netId, and check if that network is actually connected.
+                mVpns.put(UserHandle.getUserId(Process.myUid()), mMockVpn);
+            }
+        }
+
         public void waitForIdle(int timeoutMs) {
             waitForIdleHandler(mHandlerThread, timeoutMs);
         }
@@ -914,6 +926,7 @@
 
         MockitoAnnotations.initMocks(this);
         when(mMetricsService.defaultNetworkMetrics()).thenReturn(mDefaultNetworkMetrics);
+        when(mMockVpn.appliesToUid(Process.myUid())).thenReturn(true);
 
         // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
         // http://b/25897652 .
@@ -935,6 +948,7 @@
         // getSystemService() correctly.
         mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService);
         mService.systemReady();
+        mService.mockVpn(Process.myUid());
         mCm.bindProcessToNetwork(null);
 
         // Ensure that the default setting for Captive Portals is used for most tests
@@ -1347,6 +1361,7 @@
         private final static int TIMEOUT_MS = 100;
 
         private final LinkedBlockingQueue<CallbackInfo> mCallbacks = new LinkedBlockingQueue<>();
+        private Network mLastAvailableNetwork;
 
         protected void setLastCallback(CallbackState state, Network network, Object o) {
             mCallbacks.offer(new CallbackInfo(state, network, o));
@@ -1354,6 +1369,7 @@
 
         @Override
         public void onAvailable(Network network) {
+            mLastAvailableNetwork = network;
             setLastCallback(CallbackState.AVAILABLE, network, null);
         }
 
@@ -1389,9 +1405,14 @@
 
         @Override
         public void onLost(Network network) {
+            mLastAvailableNetwork = null;
             setLastCallback(CallbackState.LOST, network, null);
         }
 
+        public Network getLastAvailableNetwork() {
+            return mLastAvailableNetwork;
+        }
+
         CallbackInfo nextCallback(int timeoutMs) {
             CallbackInfo cb = null;
             try {
@@ -1658,6 +1679,7 @@
         callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
         defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         mWiFiNetworkAgent.connect(true);
         // We get AVAILABLE on wifi when wifi connects and satisfies our unmetered request.
@@ -1668,6 +1690,7 @@
         callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         mEthernetNetworkAgent.connect(true);
         callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent);
@@ -1676,11 +1699,13 @@
         callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent);
         defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent);
         assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         mEthernetNetworkAgent.disconnect();
         callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
         defaultCallback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
         defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         for (int i = 0; i < 4; i++) {
             MockNetworkAgent oldNetwork, newNetwork;
@@ -1709,6 +1734,7 @@
         defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, mWiFiNetworkAgent);
         defaultCallback.assertNoCallback();
         callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         // Wifi no longer satisfies our listen, which is for an unmetered network.
         // But because its score is 55, it's still up (and the default network).
@@ -1718,8 +1744,11 @@
         mWiFiNetworkAgent.disconnect();
         defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
         defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
         mCellNetworkAgent.disconnect();
         defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        waitForIdle();
+        assertEquals(null, mCm.getActiveNetwork());
 
         mCm.unregisterNetworkCallback(callback);
         waitForIdle();
@@ -1736,6 +1765,7 @@
         callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
         defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         // Bring up wifi with a score of 20.
         // Cell stays up because it would satisfy the default request if it validated.
@@ -1744,12 +1774,14 @@
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         mWiFiNetworkAgent.disconnect();
         callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
         defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
         defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         // Bring up wifi with a score of 70.
         // Cell is lingered because it would not satisfy any request, even if it validated.
@@ -1760,6 +1792,7 @@
         callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
         defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         // Tear down wifi.
         mWiFiNetworkAgent.disconnect();
@@ -1767,6 +1800,7 @@
         defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
         defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         // Bring up wifi, then validate it. Previous versions would immediately tear down cell, but
         // it's arguably correct to linger it, since it was the default network before it validated.
@@ -1778,6 +1812,7 @@
         callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         mWiFiNetworkAgent.disconnect();
         callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
@@ -1786,12 +1821,15 @@
         mCellNetworkAgent.disconnect();
         callback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
         defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        waitForIdle();
+        assertEquals(null, mCm.getActiveNetwork());
 
         // If a network is lingering, and we add and remove a request from it, resume lingering.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(true);
         callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
         defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(true);
         defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
@@ -1799,6 +1837,7 @@
         // TODO: Investigate sending validated before losing.
         callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
         callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         NetworkRequest cellRequest = new NetworkRequest.Builder()
                 .addTransportType(TRANSPORT_CELLULAR).build();
@@ -1815,6 +1854,7 @@
         callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
         defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
         defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         // Cell is now the default network. Pin it with a cell-specific request.
         noopCallback = new NetworkCallback();  // Can't reuse NetworkCallbacks. http://b/20701525
@@ -1825,6 +1865,7 @@
         mWiFiNetworkAgent.connect(true);
         callback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
         defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
         // The default request is lingering on cell, but nothing happens to cell, and we send no
         // callbacks for it, because it's kept up by cellRequest.
         callback.assertNoCallback();
@@ -1848,6 +1889,7 @@
         callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent);
         trackDefaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent);
         defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent);
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         // Let linger run its course.
         callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent, lingerTimeoutMs);
@@ -2496,23 +2538,27 @@
         mCellNetworkAgent.connect(true);
         cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
         defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+        assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         // Bring up wifi and expect CALLBACK_AVAILABLE.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(true);
         cellNetworkCallback.assertNoCallback();
         defaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
+        assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         // Bring down cell. Expect no default network callback, since it wasn't the default.
         mCellNetworkAgent.disconnect();
         cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
         defaultNetworkCallback.assertNoCallback();
+        assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         // Bring up cell. Expect no default network callback, since it won't be the default.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(true);
         cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
         defaultNetworkCallback.assertNoCallback();
+        assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         // Bring down wifi. Expect the default network callback to notified of LOST wifi
         // followed by AVAILABLE cell.
@@ -2523,6 +2569,23 @@
         mCellNetworkAgent.disconnect();
         cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
         defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        waitForIdle();
+        assertEquals(null, mCm.getActiveNetwork());
+
+        final int uid = Process.myUid();
+        final MockNetworkAgent vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN);
+        final ArraySet<UidRange> ranges = new ArraySet<>();
+        ranges.add(new UidRange(uid, uid));
+        when(mMockVpn.getNetId()).thenReturn(vpnNetworkAgent.getNetwork().netId);
+        vpnNetworkAgent.setUids(ranges);
+        vpnNetworkAgent.connect(true);
+        defaultNetworkCallback.expectAvailableThenValidatedCallbacks(vpnNetworkAgent);
+        assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
+
+        vpnNetworkAgent.disconnect();
+        defaultNetworkCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
+        waitForIdle();
+        assertEquals(null, mCm.getActiveNetwork());
     }
 
     @Test
@@ -4015,6 +4078,7 @@
         final TestNetworkCallback genericNotVpnNetworkCallback = new TestNetworkCallback();
         final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
         final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback();
+        final TestNetworkCallback defaultCallback = new TestNetworkCallback();
         final NetworkRequest genericNotVpnRequest = new NetworkRequest.Builder().build();
         final NetworkRequest genericRequest = new NetworkRequest.Builder()
                 .removeCapability(NET_CAPABILITY_NOT_VPN).build();
@@ -4027,6 +4091,8 @@
         mCm.registerNetworkCallback(genericNotVpnRequest, genericNotVpnNetworkCallback);
         mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
         mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback);
+        mCm.registerDefaultNetworkCallback(defaultCallback);
+        defaultCallback.assertNoCallback();
 
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(false);
@@ -4034,15 +4100,14 @@
         genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         genericNotVpnNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         wifiNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+        defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         vpnNetworkCallback.assertNoCallback();
-
-        // TODO : check callbacks agree with the return value of mCm.getActiveNetwork().
-        // Right now this is not possible because establish() is not adequately instrumented
-        // in this test.
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         final MockNetworkAgent vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN);
         final ArraySet<UidRange> ranges = new ArraySet<>();
         ranges.add(new UidRange(uid, uid));
+        when(mMockVpn.getNetId()).thenReturn(vpnNetworkAgent.getNetwork().netId);
         vpnNetworkAgent.setUids(ranges);
         vpnNetworkAgent.connect(false);
 
@@ -4050,10 +4115,14 @@
         genericNotVpnNetworkCallback.assertNoCallback();
         wifiNetworkCallback.assertNoCallback();
         vpnNetworkCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent);
+        defaultCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent);
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         genericNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, vpnNetworkAgent);
         genericNotVpnNetworkCallback.assertNoCallback();
         vpnNetworkCallback.expectCapabilitiesLike(nc -> null == nc.getUids(), vpnNetworkAgent);
+        defaultCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, vpnNetworkAgent);
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         ranges.clear();
         vpnNetworkAgent.setUids(ranges);
@@ -4063,6 +4132,14 @@
         wifiNetworkCallback.assertNoCallback();
         vpnNetworkCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
 
+        // TODO : The default network callback should actually get a LOST call here (also see the
+        // comment below for AVAILABLE). This is because ConnectivityService does not look at UID
+        // ranges at all when determining whether a network should be rematched. In practice, VPNs
+        // can't currently update their UIDs without disconnecting, so this does not matter too
+        // much, but that is the reason the test here has to check for an update to the
+        // capabilities instead of the expected LOST then AVAILABLE.
+        defaultCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, vpnNetworkAgent);
+
         ranges.add(new UidRange(uid, uid));
         vpnNetworkAgent.setUids(ranges);
 
@@ -4070,6 +4147,9 @@
         genericNotVpnNetworkCallback.assertNoCallback();
         wifiNetworkCallback.assertNoCallback();
         vpnNetworkCallback.expectAvailableCallbacksValidated(vpnNetworkAgent);
+        // TODO : Here like above, AVAILABLE would be correct, but because this can't actually
+        // happen outside of the test, ConnectivityService does not rematch callbacks.
+        defaultCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, vpnNetworkAgent);
 
         mWiFiNetworkAgent.disconnect();
 
@@ -4077,6 +4157,7 @@
         genericNotVpnNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
         wifiNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
         vpnNetworkCallback.assertNoCallback();
+        defaultCallback.assertNoCallback();
 
         vpnNetworkAgent.disconnect();
 
@@ -4084,9 +4165,61 @@
         genericNotVpnNetworkCallback.assertNoCallback();
         wifiNetworkCallback.assertNoCallback();
         vpnNetworkCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
+        defaultCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
+        assertEquals(null, mCm.getActiveNetwork());
 
         mCm.unregisterNetworkCallback(genericNetworkCallback);
         mCm.unregisterNetworkCallback(wifiNetworkCallback);
         mCm.unregisterNetworkCallback(vpnNetworkCallback);
+        mCm.unregisterNetworkCallback(defaultCallback);
+    }
+
+    @Test
+    public void testVpnWithAndWithoutInternet() {
+        final int uid = Process.myUid();
+
+        final TestNetworkCallback defaultCallback = new TestNetworkCallback();
+        mCm.registerDefaultNetworkCallback(defaultCallback);
+        defaultCallback.assertNoCallback();
+
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.connect(true);
+
+        defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
+
+        MockNetworkAgent vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN);
+        final ArraySet<UidRange> ranges = new ArraySet<>();
+        ranges.add(new UidRange(uid, uid));
+        when(mMockVpn.getNetId()).thenReturn(vpnNetworkAgent.getNetwork().netId);
+        vpnNetworkAgent.setUids(ranges);
+        vpnNetworkAgent.connect(true /* validated */, false /* hasInternet */);
+
+        defaultCallback.assertNoCallback();
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
+
+        vpnNetworkAgent.disconnect();
+        defaultCallback.assertNoCallback();
+
+        vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN);
+        when(mMockVpn.getNetId()).thenReturn(vpnNetworkAgent.getNetwork().netId);
+        vpnNetworkAgent.setUids(ranges);
+        vpnNetworkAgent.connect(true /* validated */, true /* hasInternet */);
+        defaultCallback.expectAvailableThenValidatedCallbacks(vpnNetworkAgent);
+        assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
+
+        vpnNetworkAgent.disconnect();
+        defaultCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
+        defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
+
+        vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN);
+        when(mMockVpn.getNetId()).thenReturn(vpnNetworkAgent.getNetwork().netId);
+        ranges.clear();
+        vpnNetworkAgent.setUids(ranges);
+
+        vpnNetworkAgent.connect(false /* validated */, true /* hasInternet */);
+        defaultCallback.assertNoCallback();
+
+        mCm.unregisterNetworkCallback(defaultCallback);
     }
 }
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp
index 6f213e1..34b46c5 100644
--- a/tools/aapt2/ResourceValues.cpp
+++ b/tools/aapt2/ResourceValues.cpp
@@ -117,8 +117,7 @@
 
 bool Reference::Flatten(android::Res_value* out_value) const {
   const ResourceId resid = id.value_or_default(ResourceId(0));
-  const bool dynamic = resid.is_valid_dynamic() && resid.package_id() != kFrameworkPackageId &&
-                       resid.package_id() < kAppPackageId;
+  const bool dynamic = resid.is_valid_dynamic() && is_dynamic;
 
   if (reference_type == Reference::Type::kResource) {
     if (dynamic) {
diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h
index 6371c4c..168ad61 100644
--- a/tools/aapt2/ResourceValues.h
+++ b/tools/aapt2/ResourceValues.h
@@ -157,6 +157,7 @@
   Maybe<ResourceId> id;
   Reference::Type reference_type;
   bool private_reference = false;
+  bool is_dynamic = false;
 
   Reference();
   explicit Reference(const ResourceNameRef& n, Type type = Type::kResource);
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 54509d9..75eba9e 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -131,6 +131,12 @@
   // Stable ID options.
   std::unordered_map<ResourceName, ResourceId> stable_id_map;
   Maybe<std::string> resource_id_map_path;
+
+  // When 'true', allow reserved package IDs to be used for applications. Pre-O, the platform
+  // treats negative resource IDs [those with a package ID of 0x80 or higher] as invalid.
+  // In order to work around this limitation, we allow the use of traditionally reserved
+  // resource IDs [those between 0x02 and 0x7E].
+  bool allow_reserved_package_id = false;
 };
 
 class LinkContext : public IAaptContext {
@@ -809,35 +815,39 @@
       return;
     }
 
-    xml::Attribute* attr = manifest_xml->root->FindAttribute(xml::kSchemaAndroid, "versionCode");
-    if (attr != nullptr) {
-      Maybe<std::string>& compile_sdk_version = options_.manifest_fixer_options.compile_sdk_version;
-      if (BinaryPrimitive* prim = ValueCast<BinaryPrimitive>(attr->compiled_value.get())) {
-        switch (prim->value.dataType) {
-          case Res_value::TYPE_INT_DEC:
-            compile_sdk_version = StringPrintf("%" PRId32, static_cast<int32_t>(prim->value.data));
-            break;
-          case Res_value::TYPE_INT_HEX:
-            compile_sdk_version = StringPrintf("%" PRIx32, prim->value.data);
-            break;
-          default:
-            break;
+    if (!options_.manifest_fixer_options.compile_sdk_version) {
+      xml::Attribute* attr = manifest_xml->root->FindAttribute(xml::kSchemaAndroid, "versionCode");
+      if (attr != nullptr) {
+        Maybe<std::string>& compile_sdk_version = options_.manifest_fixer_options.compile_sdk_version;
+        if (BinaryPrimitive* prim = ValueCast<BinaryPrimitive>(attr->compiled_value.get())) {
+          switch (prim->value.dataType) {
+            case Res_value::TYPE_INT_DEC:
+              compile_sdk_version = StringPrintf("%" PRId32, static_cast<int32_t>(prim->value.data));
+              break;
+            case Res_value::TYPE_INT_HEX:
+              compile_sdk_version = StringPrintf("%" PRIx32, prim->value.data);
+              break;
+            default:
+              break;
+          }
+        } else if (String* str = ValueCast<String>(attr->compiled_value.get())) {
+          compile_sdk_version = *str->value;
+        } else {
+          compile_sdk_version = attr->value;
         }
-      } else if (String* str = ValueCast<String>(attr->compiled_value.get())) {
-        compile_sdk_version = *str->value;
-      } else {
-        compile_sdk_version = attr->value;
       }
     }
 
-    attr = manifest_xml->root->FindAttribute(xml::kSchemaAndroid, "versionName");
-    if (attr != nullptr) {
-      Maybe<std::string>& compile_sdk_version_codename =
-          options_.manifest_fixer_options.compile_sdk_version_codename;
-      if (String* str = ValueCast<String>(attr->compiled_value.get())) {
-        compile_sdk_version_codename = *str->value;
-      } else {
-        compile_sdk_version_codename = attr->value;
+    if (!options_.manifest_fixer_options.compile_sdk_version_codename) {
+      xml::Attribute* attr = manifest_xml->root->FindAttribute(xml::kSchemaAndroid, "versionName");
+      if (attr != nullptr) {
+        Maybe<std::string>& compile_sdk_version_codename =
+            options_.manifest_fixer_options.compile_sdk_version_codename;
+        if (String* str = ValueCast<String>(attr->compiled_value.get())) {
+          compile_sdk_version_codename = *str->value;
+        } else {
+          compile_sdk_version_codename = attr->value;
+        }
       }
     }
   }
@@ -906,9 +916,7 @@
     // Capture the shared libraries so that the final resource table can be properly flattened
     // with support for shared libraries.
     for (auto& entry : asset_source->GetAssignedPackageIds()) {
-      if (entry.first > kFrameworkPackageId && entry.first < kAppPackageId) {
-        final_table_.included_packages_[entry.first] = entry.second;
-      } else if (entry.first == kAppPackageId) {
+      if (entry.first == kAppPackageId) {
         // Capture the included base feature package.
         included_feature_base_ = entry.second;
       } else if (entry.first == kFrameworkPackageId) {
@@ -922,6 +930,8 @@
           // android:versionCode from the framework AndroidManifest.xml.
           ExtractCompileSdkVersions(asset_source->GetAssetManager());
         }
+      } else if (asset_source->IsPackageDynamic(entry.first)) {
+        final_table_.included_packages_[entry.first] = entry.second;
       }
     }
 
@@ -1606,7 +1616,15 @@
     // If required, the package name is modifed before flattening, and then modified back
     // to its original name.
     ResourceTablePackage* package_to_rewrite = nullptr;
-    if (context_->GetPackageId() > kAppPackageId &&
+    // Pre-O, the platform treats negative resource IDs [those with a package ID of 0x80
+    // or higher] as invalid. In order to work around this limitation, we allow the use
+    // of traditionally reserved resource IDs [those between 0x02 and 0x7E]. Allow the
+    // definition of what a valid "split" package ID is to account for this.
+    const bool isSplitPackage = (options_.allow_reserved_package_id &&
+          context_->GetPackageId() != kAppPackageId &&
+          context_->GetPackageId() != kFrameworkPackageId)
+        || (!options_.allow_reserved_package_id && context_->GetPackageId() > kAppPackageId);
+    if (isSplitPackage &&
         included_feature_base_ == make_value(context_->GetCompilationPackage())) {
       // The base APK is included, and this is a feature split. If the base package is
       // the same as this package, then we are building an old style Android Instant Apps feature
@@ -2113,6 +2131,13 @@
           .OptionalFlag("--version-name",
                         "Version name to inject into the AndroidManifest.xml if none is present.",
                         &options.manifest_fixer_options.version_name_default)
+          .OptionalFlag("--compile-sdk-version-code",
+                        "Version code (integer) to inject into the AndroidManifest.xml if none is\n"
+                        "present.",
+                        &options.manifest_fixer_options.compile_sdk_version)
+          .OptionalFlag("--compile-sdk-version-name",
+                        "Version name to inject into the AndroidManifest.xml if none is present.",
+                        &options.manifest_fixer_options.compile_sdk_version_codename)
           .OptionalSwitch("--shared-lib", "Generates a shared Android runtime library.",
                           &shared_lib)
           .OptionalSwitch("--static-lib", "Generate a static Android library.", &static_lib)
@@ -2154,6 +2179,10 @@
                         "Generates a text file containing the resource symbols of the R class in\n"
                         "the specified folder.",
                         &options.generate_text_symbols_path)
+          .OptionalSwitch("--allow-reserved-package-id",
+                          "Allows the use of a reserved package ID. This should on be used for\n"
+                          "packages with a pre-O min-sdk\n",
+                          &options.allow_reserved_package_id)
           .OptionalSwitch("--auto-add-overlay",
                           "Allows the addition of new resources in overlays without\n"
                           "<add-resource> tags.",
@@ -2264,7 +2293,9 @@
     }
 
     const uint32_t package_id_int = maybe_package_id_int.value();
-    if (package_id_int < kAppPackageId || package_id_int > std::numeric_limits<uint8_t>::max()) {
+    if (package_id_int > std::numeric_limits<uint8_t>::max()
+        || package_id_int == kFrameworkPackageId
+        || (!options.allow_reserved_package_id && package_id_int < kAppPackageId)) {
       context.GetDiagnostics()->Error(
           DiagMessage() << StringPrintf(
               "invalid package ID 0x%02x. Must be in the range 0x7f-0xff.", package_id_int));
diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp
index 13d2a04..28e71cc 100644
--- a/tools/aapt2/link/ReferenceLinker.cpp
+++ b/tools/aapt2/link/ReferenceLinker.cpp
@@ -348,6 +348,7 @@
     // against libraries without assigned IDs.
     // Ex: Linking against own resources when building a static library.
     reference->id = s->id;
+    reference->is_dynamic = s->is_dynamic;
     return true;
   }
 
diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp
index f6f0a50..ef2e448 100644
--- a/tools/aapt2/process/SymbolTable.cpp
+++ b/tools/aapt2/process/SymbolTable.cpp
@@ -256,6 +256,10 @@
   return package_map;
 }
 
+bool AssetManagerSymbolSource::IsPackageDynamic(uint32_t packageId) const {
+  return assets_.getResources(false).isPackageDynamic(packageId);
+}
+
 static std::unique_ptr<SymbolTable::Symbol> LookupAttributeInTable(
     const android::ResTable& table, ResourceId id) {
   // Try as a bag.
@@ -359,6 +363,7 @@
   } else {
     s = util::make_unique<SymbolTable::Symbol>();
     s->id = res_id;
+    s->is_dynamic = table.isResourceDynamic(res_id.id);
   }
 
   if (s) {
@@ -383,7 +388,6 @@
     // Exit early and avoid the error logs from AssetManager.
     return {};
   }
-
   const android::ResTable& table = assets_.getResources(false);
   Maybe<ResourceName> maybe_name = GetResourceName(table, id);
   if (!maybe_name) {
@@ -399,6 +403,7 @@
   } else {
     s = util::make_unique<SymbolTable::Symbol>();
     s->id = id;
+    s->is_dynamic = table.isResourceDynamic(id.id);
   }
 
   if (s) {
diff --git a/tools/aapt2/process/SymbolTable.h b/tools/aapt2/process/SymbolTable.h
index c80e627..c798cbb 100644
--- a/tools/aapt2/process/SymbolTable.h
+++ b/tools/aapt2/process/SymbolTable.h
@@ -68,6 +68,7 @@
     Maybe<ResourceId> id;
     std::shared_ptr<Attribute> attribute;
     bool is_public = false;
+    bool is_dynamic = false;
   };
 
   SymbolTable(NameMangler* mangler);
@@ -205,6 +206,7 @@
 
   bool AddAssetPath(const android::StringPiece& path);
   std::map<size_t, std::string> GetAssignedPackageIds() const;
+  bool IsPackageDynamic(uint32_t packageId) const;
 
   std::unique_ptr<SymbolTable::Symbol> FindByName(
       const ResourceName& name) override;
diff --git a/tools/hiddenapi/checksorted_sha.sh b/tools/hiddenapi/checksorted_sha.sh
new file mode 100755
index 0000000..ceb705f
--- /dev/null
+++ b/tools/hiddenapi/checksorted_sha.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+set -e
+LOCAL_DIR="$( dirname ${BASH_SOURCE} )"
+git show --name-only --pretty=format: $1 | grep "config/hiddenapi-.*txt" | while read file; do
+    diff <(git show $1:$file) <(git show $1:$file | $LOCAL_DIR/sort_api.sh )  || {
+      echo -e "\e[1m\e[31m$file $1 is not sorted or contains duplicates. To sort it correctly:\e[0m"
+      echo -e "\e[33m${LOCAL_DIR}/sort_api.sh $2/frameworks/base/$file\e[0m"
+      exit 1
+    }
+done
diff --git a/tools/hiddenapi/sort_api.sh b/tools/hiddenapi/sort_api.sh
new file mode 100755
index 0000000..1c6eb1b
--- /dev/null
+++ b/tools/hiddenapi/sort_api.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+set -e
+if [ -z "$1" ]; then
+  source_list=/dev/stdin
+  dest_list=/dev/stdout
+else
+  source_list="$1"
+  dest_list="$1"
+fi
+# Load the file
+readarray A < "$source_list"
+# Sort
+IFS=$'\n'
+A=( $(LC_COLLATE=C sort -f <<< "${A[*]}") )
+A=( $(uniq <<< "${A[*]}") )
+unset IFS
+# Dump array back into the file
+printf '%s\n' "${A[@]}" > "$dest_list"
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index b333126..a7fffca 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -85,7 +85,7 @@
 
     boolean disableNetwork(int netId, String packageName);
 
-    void startScan(String packageName);
+    boolean startScan(String packageName);
 
     List<ScanResult> getScanResults(String callingPackage);
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 9c6c8a9..a19965d 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1635,8 +1635,7 @@
     public boolean startScan(WorkSource workSource) {
         try {
             String packageName = mContext.getOpPackageName();
-            mService.startScan(packageName);
-            return true;
+            return mService.startScan(packageName);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/wifi/tests/runtests.sh b/wifi/tests/runtests.sh
index ebcc2a2..4e52b8f 100755
--- a/wifi/tests/runtests.sh
+++ b/wifi/tests/runtests.sh
@@ -21,4 +21,5 @@
 
 adb install -r -g "$OUT/data/app/FrameworksWifiApiTests/FrameworksWifiApiTests.apk"
 
-adb shell am instrument -w "$@" 'android.net.wifi.test/android.support.test.runner.AndroidJUnitRunner'
+adb shell am instrument --no-hidden-api-checks -w "$@" \
+  'android.net.wifi.test/android.support.test.runner.AndroidJUnitRunner'
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index f3ffcad..20e49cd 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -1070,4 +1070,16 @@
             fail("setWifiApConfiguration should rethrow Exceptions from WifiService");
         } catch (SecurityException e) { }
     }
+
+    /**
+     * Check the call to startScan calls WifiService.
+     */
+    @Test
+    public void testStartScan() throws Exception {
+        when(mWifiService.startScan(TEST_PACKAGE_NAME)).thenReturn(true);
+        assertTrue(mWifiManager.startScan());
+
+        when(mWifiService.startScan(TEST_PACKAGE_NAME)).thenReturn(false);
+        assertFalse(mWifiManager.startScan());
+    }
 }