Merge "Add more light grey APIs." into pi-dev
diff --git a/Android.mk b/Android.mk
index 88394d6..bb37fa2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -448,6 +448,7 @@
 		-showAnnotation android.annotation.SystemApi \
 		-showAnnotation android.annotation.TestApi \
 		-privateDexApi $(INTERNAL_PLATFORM_PRIVATE_DEX_API_FILE) \
+		-removedDexApi $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE) \
 		-nodocs
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=external/doclava/res/assets/templates-sdk
@@ -456,7 +457,8 @@
 
 include $(BUILD_DROIDDOC)
 
-$(full_target): .KATI_IMPLICIT_OUTPUTS := $(INTERNAL_PLATFORM_PRIVATE_DEX_API_FILE)
+$(full_target): .KATI_IMPLICIT_OUTPUTS := $(INTERNAL_PLATFORM_PRIVATE_DEX_API_FILE) \
+                                          $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE)
 
 # ====  check javadoc comments but don't generate docs ========
 include $(CLEAR_VARS)
@@ -871,9 +873,16 @@
 # rules for building them. Other rules in the build system should depend on the
 # files in the build folder.
 
-# Automatically add all methods which match the following signatures.
-# These need to be greylisted in order to allow applications to write their
-# own serializers.
+# Merge light greylist from multiple files:
+#  (1) manual light greylist
+#  (2) list of usages from vendor apps
+#  (3) list of removed APIs
+#      @removed does not imply private in Doclava. We must take the subset also
+#      in PRIVATE_API.
+#  (4) list of serialization APIs
+#      Automatically adds all methods which match the signatures in
+#      REGEX_SERIALIZATION. These are greylisted in order to allow applications
+#      to write their own serializers.
 $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): REGEX_SERIALIZATION := \
     "readObject\(Ljava/io/ObjectInputStream;\)V" \
     "readObjectNoData\(\)V" \
@@ -883,14 +892,15 @@
     "writeObject\(Ljava/io/ObjectOutputStream;\)V" \
     "writeReplace\(\)Ljava/lang/Object;"
 $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): PRIVATE_API := $(INTERNAL_PLATFORM_PRIVATE_DEX_API_FILE)
-# Temporarily merge light greylist from two files. Vendor list will become dark
-# grey once we remove the UI toast.
+$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): REMOVED_API := $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE)
 $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): frameworks/base/config/hiddenapi-light-greylist.txt \
                                                frameworks/base/config/hiddenapi-vendor-list.txt \
-                                               $(INTERNAL_PLATFORM_PRIVATE_DEX_API_FILE)
+                                               $(INTERNAL_PLATFORM_PRIVATE_DEX_API_FILE) \
+                                               $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE)
 	sort frameworks/base/config/hiddenapi-light-greylist.txt \
 	     frameworks/base/config/hiddenapi-vendor-list.txt \
 	     <(grep -E "\->("$(subst $(space),"|",$(REGEX_SERIALIZATION))")$$" $(PRIVATE_API)) \
+	     <(comm -12 <(sort $(REMOVED_API)) <(sort $(PRIVATE_API))) \
 	> $@
 
 $(eval $(call copy-one-file,frameworks/base/config/hiddenapi-dark-greylist.txt,\
diff --git a/api/current.txt b/api/current.txt
index 26e4298..8703bf4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -162,6 +162,7 @@
   public static final class Manifest.permission_group {
     ctor public Manifest.permission_group();
     field public static final java.lang.String CALENDAR = "android.permission-group.CALENDAR";
+    field public static final java.lang.String CALL_LOG = "android.permission-group.CALL_LOG";
     field public static final java.lang.String CAMERA = "android.permission-group.CAMERA";
     field public static final java.lang.String CONTACTS = "android.permission-group.CONTACTS";
     field public static final java.lang.String LOCATION = "android.permission-group.LOCATION";
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 93875cd..e5bde0d 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -151,7 +151,8 @@
 }
 
 // ================================================================================
-Section::Section(int i, const int64_t timeoutMs) : id(i), timeoutMs(timeoutMs) {}
+Section::Section(int i, int64_t timeoutMs, bool deviceSpecific)
+    : id(i), timeoutMs(timeoutMs), deviceSpecific(deviceSpecific) {}
 
 Section::~Section() {}
 
@@ -236,8 +237,9 @@
 // ================================================================================
 static inline bool isSysfs(const char* filename) { return strncmp(filename, "/sys/", 5) == 0; }
 
-FileSection::FileSection(int id, const char* filename, const int64_t timeoutMs)
-    : Section(id, timeoutMs), mFilename(filename) {
+FileSection::FileSection(int id, const char* filename, const bool deviceSpecific,
+                         const int64_t timeoutMs)
+    : Section(id, timeoutMs, deviceSpecific), mFilename(filename) {
     name = filename;
     mIsSysfs = isSysfs(filename);
 }
@@ -250,7 +252,7 @@
     unique_fd fd(open(mFilename, O_RDONLY | O_CLOEXEC));
     if (fd.get() == -1) {
         ALOGW("FileSection '%s' failed to open file", this->name.string());
-        return -errno;
+        return this->deviceSpecific ? NO_ERROR : -errno;
     }
 
     FdBuffer buffer;
@@ -902,11 +904,16 @@
         // Read from the pipe concurrently to avoid blocking the child.
         FdBuffer buffer;
         err = buffer.readFully(dumpPipe.readFd().get());
+        // Wait on the child to avoid it becoming a zombie process.
+        status_t cStatus = wait_child(child);
         if (err != NO_ERROR) {
             ALOGW("TombstoneSection '%s' failed to read stack dump: %d", this->name.string(), err);
             dumpPipe.readFd().reset();
             break;
         }
+        if (cStatus != NO_ERROR) {
+            ALOGE("TombstoneSection '%s' child had an issue: %s\n", this->name.string(), strerror(-cStatus));
+        }
 
         auto dump = std::make_unique<char[]>(buffer.size());
         auto iterator = buffer.data();
diff --git a/cmds/incidentd/src/Section.h b/cmds/incidentd/src/Section.h
index 20ecdb1..577892e 100644
--- a/cmds/incidentd/src/Section.h
+++ b/cmds/incidentd/src/Section.h
@@ -40,9 +40,10 @@
 public:
     const int id;
     const int64_t timeoutMs;  // each section must have a timeout
+    const bool deviceSpecific;
     String8 name;
 
-    Section(int id, const int64_t timeoutMs = REMOTE_CALL_TIMEOUT_MS);
+    Section(int id, int64_t timeoutMs = REMOTE_CALL_TIMEOUT_MS, bool deviceSpecific = false);
     virtual ~Section();
 
     virtual status_t Execute(ReportRequestSet* requests) const = 0;
@@ -75,7 +76,8 @@
  */
 class FileSection : public Section {
 public:
-    FileSection(int id, const char* filename, const int64_t timeoutMs = 5000 /* 5 seconds */);
+    FileSection(int id, const char* filename, bool deviceSpecific = false,
+                int64_t timeoutMs = 5000 /* 5 seconds */);
     virtual ~FileSection();
 
     virtual status_t Execute(ReportRequestSet* requests) const;
@@ -105,7 +107,7 @@
  */
 class WorkerThreadSection : public Section {
 public:
-    WorkerThreadSection(int id, const int64_t timeoutMs = REMOTE_CALL_TIMEOUT_MS);
+    WorkerThreadSection(int id, int64_t timeoutMs = REMOTE_CALL_TIMEOUT_MS);
     virtual ~WorkerThreadSection();
 
     virtual status_t Execute(ReportRequestSet* requests) const;
@@ -118,7 +120,7 @@
  */
 class CommandSection : public Section {
 public:
-    CommandSection(int id, const int64_t timeoutMs, const char* command, ...);
+    CommandSection(int id, int64_t timeoutMs, const char* command, ...);
 
     CommandSection(int id, const char* command, ...);
 
@@ -168,7 +170,7 @@
  */
 class TombstoneSection : public WorkerThreadSection {
 public:
-    TombstoneSection(int id, const char* type, const int64_t timeoutMs = 30000 /* 30 seconds */);
+    TombstoneSection(int id, const char* type, int64_t timeoutMs = 30000 /* 30 seconds */);
     virtual ~TombstoneSection();
 
     virtual status_t BlockingCall(int pipeWriteFd) const;
diff --git a/cmds/incidentd/tests/Section_test.cpp b/cmds/incidentd/tests/Section_test.cpp
index 33f52062..3c338b3 100644
--- a/cmds/incidentd/tests/Section_test.cpp
+++ b/cmds/incidentd/tests/Section_test.cpp
@@ -143,8 +143,16 @@
     EXPECT_THAT(GetCapturedStdout(), StrEq("\xa\vatadtsetmai"));
 }
 
+TEST_F(SectionTest, FileSectionNotExist) {
+    FileSection fs1(NOOP_PARSER, "notexist", false, QUICK_TIMEOUT_MS);
+    ASSERT_EQ(NAME_NOT_FOUND, fs1.Execute(&requests));
+
+    FileSection fs2(NOOP_PARSER, "notexist", true, QUICK_TIMEOUT_MS);
+    ASSERT_EQ(NO_ERROR, fs2.Execute(&requests));
+}
+
 TEST_F(SectionTest, FileSectionTimeout) {
-    FileSection fs(TIMEOUT_PARSER, tf.path, QUICK_TIMEOUT_MS);
+    FileSection fs(TIMEOUT_PARSER, tf.path, false, QUICK_TIMEOUT_MS);
     ASSERT_EQ(NO_ERROR, fs.Execute(&requests));
     ASSERT_TRUE(requests.sectionStats(TIMEOUT_PARSER)->timed_out());
 }
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 5219885..763d49b 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define DEBUG true  // STOPSHIP if true
+#define DEBUG false // STOPSHIP if true
 #include "Log.h"
 #include "statslog.h"
 
@@ -162,6 +162,19 @@
     OnLogEvent(event, false);
 }
 
+void StatsLogProcessor::resetConfigs() {
+    std::lock_guard<std::mutex> lock(mMetricsMutex);
+    resetConfigsLocked(getElapsedRealtimeNs());
+}
+
+void StatsLogProcessor::resetConfigsLocked(const int64_t timestampNs) {
+    std::vector<ConfigKey> configKeys;
+    for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) {
+        configKeys.push_back(it->first);
+    }
+    resetConfigsLocked(timestampNs, configKeys);
+}
+
 void StatsLogProcessor::OnLogEvent(LogEvent* event, bool reconnected) {
     std::lock_guard<std::mutex> lock(mMetricsMutex);
     const int64_t currentTimestampNs = event->GetElapsedTimestampNs();
@@ -188,11 +201,7 @@
             WriteDataToDiskLocked(CONFIG_RESET);
             // We see fresher event before we see the checkpoint. We might have lost data.
             // The best we can do is to reset.
-            std::vector<ConfigKey> configKeys;
-            for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) {
-                configKeys.push_back(it->first);
-            }
-            resetConfigsLocked(currentTimestampNs, configKeys);
+            resetConfigsLocked(currentTimestampNs);
         } else {
             // Still in search of the CP. Keep going.
             return;
@@ -242,6 +251,7 @@
 void StatsLogProcessor::OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
                                         const StatsdConfig& config) {
     std::lock_guard<std::mutex> lock(mMetricsMutex);
+    WriteDataToDiskLocked(key, timestampNs, CONFIG_UPDATED);
     OnConfigUpdatedLocked(timestampNs, key, config);
 }
 
@@ -251,10 +261,6 @@
     sp<MetricsManager> newMetricsManager =
         new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap,
                            mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
-    auto it = mMetricsManagers.find(key);
-    if (it != mMetricsManagers.end()) {
-        WriteDataToDiskLocked(it->first, CONFIG_UPDATED);
-    }
     if (newMetricsManager->isConfigValid()) {
         mUidMap->OnConfigUpdated(key);
         if (newMetricsManager->shouldAddUidMapListener()) {
@@ -419,6 +425,7 @@
         }
     }
     if (configKeysTtlExpired.size() > 0) {
+        WriteDataToDiskLocked(CONFIG_RESET);
         resetConfigsLocked(timestampNs, configKeysTtlExpired);
     }
 }
@@ -427,7 +434,7 @@
     std::lock_guard<std::mutex> lock(mMetricsMutex);
     auto it = mMetricsManagers.find(key);
     if (it != mMetricsManagers.end()) {
-        WriteDataToDiskLocked(key, CONFIG_REMOVED);
+        WriteDataToDiskLocked(key, getElapsedRealtimeNs(), CONFIG_REMOVED);
         mMetricsManagers.erase(it);
         mUidMap->OnConfigRemoved(key);
     }
@@ -474,9 +481,13 @@
 }
 
 void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key,
+                                              const int64_t timestampNs,
                                               const DumpReportReason dumpReportReason) {
+    if (mMetricsManagers.find(key) == mMetricsManagers.end()) {
+        return;
+    }
     ProtoOutputStream proto;
-    onConfigMetricsReportLocked(key, getElapsedRealtimeNs(),
+    onConfigMetricsReportLocked(key, timestampNs,
                                 true /* include_current_partial_bucket*/,
                                 false /* include strings */, dumpReportReason, &proto);
     string file_name = StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR,
@@ -491,17 +502,19 @@
 }
 
 void StatsLogProcessor::WriteDataToDiskLocked(const DumpReportReason dumpReportReason) {
+    const int64_t timeNs = getElapsedRealtimeNs();
     for (auto& pair : mMetricsManagers) {
-        WriteDataToDiskLocked(pair.first, dumpReportReason);
+        WriteDataToDiskLocked(pair.first, timeNs, dumpReportReason);
     }
 }
 
-void StatsLogProcessor::WriteDataToDisk(bool isShutdown) {
+void StatsLogProcessor::WriteDataToDisk(const DumpReportReason dumpReportReason) {
     std::lock_guard<std::mutex> lock(mMetricsMutex);
-    WriteDataToDiskLocked(DEVICE_SHUTDOWN);
+    WriteDataToDiskLocked(dumpReportReason);
 }
 
 void StatsLogProcessor::informPullAlarmFired(const int64_t timestampNs) {
+    std::lock_guard<std::mutex> lock(mMetricsMutex);
     mStatsPullerManager.OnAlarmFired(timestampNs);
 }
 
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index c3c4663..a6c4d86 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -77,7 +77,10 @@
             unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
 
     /* Flushes data to disk. Data on memory will be gone after written to disk. */
-    void WriteDataToDisk(bool shutdown);
+    void WriteDataToDisk(const DumpReportReason dumpReportReason);
+
+    // Reset all configs.
+    void resetConfigs();
 
     inline sp<UidMap> getUidMap() {
         return mUidMap;
@@ -121,8 +124,9 @@
     void OnConfigUpdatedLocked(
         const int64_t currentTimestampNs, const ConfigKey& key, const StatsdConfig& config);
 
-    void WriteDataToDiskLocked(DumpReportReason dumpReportReason);
-    void WriteDataToDiskLocked(const ConfigKey& key, DumpReportReason dumpReportReason);
+    void WriteDataToDiskLocked(const DumpReportReason dumpReportReason);
+    void WriteDataToDiskLocked(const ConfigKey& key, const int64_t timestampNs,
+                               const DumpReportReason dumpReportReason);
 
     void onConfigMetricsReportLocked(const ConfigKey& key, const int64_t dumpTimeStampNs,
                                      const bool include_current_partial_bucket,
@@ -141,6 +145,9 @@
     // Handler over the isolated uid change event.
     void onIsolatedUidChangedEventLocked(const LogEvent& event);
 
+    // Reset all configs.
+    void resetConfigsLocked(const int64_t timestampNs);
+    // Reset the specified configs.
     void resetConfigsLocked(const int64_t timestampNs, const std::vector<ConfigKey>& configs);
 
     // Function used to send a broadcast so that receiver for the config key can call getData
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 0e7b4f9..811edb5 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -659,7 +659,7 @@
 
 status_t StatsService::cmd_write_data_to_disk(FILE* out) {
     fprintf(out, "Writing data to disk\n");
-    mProcessor->WriteDataToDisk(false);
+    mProcessor->WriteDataToDisk(ADB_DUMP);
     return NO_ERROR;
 }
 
@@ -816,10 +816,10 @@
     return Status::ok();
 }
 
-Status StatsService::informDeviceShutdown(bool isShutdown) {
+Status StatsService::informDeviceShutdown() {
     ENFORCE_UID(AID_SYSTEM);
     VLOG("StatsService::informDeviceShutdown");
-    mProcessor->WriteDataToDisk(isShutdown);
+    mProcessor->WriteDataToDisk(DEVICE_SHUTDOWN);
     return Status::ok();
 }
 
@@ -967,7 +967,12 @@
 
 void StatsService::binderDied(const wp <IBinder>& who) {
     ALOGW("statscompanion service died");
-    mProcessor->WriteDataToDisk(STATSCOMPANION_DIED);
+    StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec());
+    if (mProcessor != nullptr) {
+        ALOGW("Reset statsd upon system server restars.");
+        mProcessor->WriteDataToDisk(STATSCOMPANION_DIED);
+        mProcessor->resetConfigs();
+    }
     mAnomalyAlarmMonitor->setStatsCompanionService(nullptr);
     mPeriodicAlarmMonitor->setStatsCompanionService(nullptr);
     SubscriberReporter::getInstance().setStatsCompanionService(nullptr);
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index e409a71..af4cbff 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -66,7 +66,7 @@
                                     const vector<String16>& app);
     virtual Status informOnePackage(const String16& app, int32_t uid, int64_t version);
     virtual Status informOnePackageRemoved(const String16& app, int32_t uid);
-    virtual Status informDeviceShutdown(bool isShutdown);
+    virtual Status informDeviceShutdown();
 
     /**
      * Called right before we start processing events.
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.cpp b/cmds/statsd/src/anomaly/AlarmTracker.cpp
index c8e406f..8d73699 100644
--- a/cmds/statsd/src/anomaly/AlarmTracker.cpp
+++ b/cmds/statsd/src/anomaly/AlarmTracker.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define DEBUG true  // STOPSHIP if true
+#define DEBUG false  // STOPSHIP if true
 #include "Log.h"
 
 #include "anomaly/AlarmTracker.h"
diff --git a/cmds/statsd/src/anomaly/subscriber_util.cpp b/cmds/statsd/src/anomaly/subscriber_util.cpp
index 3f69a2c..ee9e9c0 100644
--- a/cmds/statsd/src/anomaly/subscriber_util.cpp
+++ b/cmds/statsd/src/anomaly/subscriber_util.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define DEBUG true  // STOPSHIP if true
+#define DEBUG false  // STOPSHIP if true
 #include "Log.h"
 
 #include <android/os/IIncidentManager.h>
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index ee3ed23..764366f 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -51,6 +51,7 @@
 const int FIELD_ID_LOGGER_ERROR_STATS = 11;
 const int FIELD_ID_PERIODIC_ALARM_STATS = 12;
 const int FIELD_ID_LOG_LOSS_STATS = 14;
+const int FIELD_ID_SYSTEM_SERVER_RESTART = 15;
 
 const int FIELD_ID_ATOM_STATS_TAG = 1;
 const int FIELD_ID_ATOM_STATS_COUNT = 2;
@@ -355,6 +356,15 @@
     mPushedAtomStats[atomId]++;
 }
 
+void StatsdStats::noteSystemServerRestart(int32_t timeSec) {
+    lock_guard<std::mutex> lock(mLock);
+
+    if (mSystemServerRestartSec.size() == kMaxSystemServerRestarts) {
+        mSystemServerRestartSec.pop_front();
+    }
+    mSystemServerRestartSec.push_back(timeSec);
+}
+
 void StatsdStats::noteLoggerError(int error) {
     lock_guard<std::mutex> lock(mLock);
     // grows strictly one at a time. so it won't > kMaxLoggerErrors
@@ -377,6 +387,7 @@
     mAnomalyAlarmRegisteredStats = 0;
     mPeriodicAlarmRegisteredStats = 0;
     mLoggerErrors.clear();
+    mSystemServerRestartSec.clear();
     mLogLossTimestampNs.clear();
     for (auto& config : mConfigStats) {
         config.second->broadcast_sent_time_sec.clear();
@@ -395,7 +406,7 @@
     time_t t = timeSec;
     struct tm* tm = localtime(&t);
     char timeBuffer[80];
-    strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p\n", tm);
+    strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p", tm);
     return string(timeBuffer);
 }
 
@@ -511,6 +522,12 @@
         strftime(buffer, sizeof(buffer), "%Y-%m-%d %I:%M%p\n", error_tm);
         fprintf(out, "Logger error %d at %s\n", error.second, buffer);
     }
+
+    for (const auto& restart : mSystemServerRestartSec) {
+        fprintf(out, "System server restarts at %s(%lld)\n",
+            buildTimeString(restart).c_str(), (long long)restart);
+    }
+
     for (const auto& loss : mLogLossTimestampNs) {
         fprintf(out, "Log loss detected at %lld (elapsedRealtimeNs)\n", (long long)loss);
     }
@@ -673,6 +690,11 @@
                     (long long)loss);
     }
 
+    for (const auto& restart : mSystemServerRestartSec) {
+        proto.write(FIELD_TYPE_INT32 | FIELD_ID_SYSTEM_SERVER_RESTART | FIELD_COUNT_REPEATED,
+                    restart);
+    }
+
     output->clear();
     size_t bufferSize = proto.size();
     output->resize(bufferSize);
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 65ba4f7..74541d3 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -104,6 +104,8 @@
 
     const static int kMaxLoggerErrors = 20;
 
+    const static int kMaxSystemServerRestarts = 20;
+
     const static int kMaxTimestampCount = 20;
 
     const static int kMaxLogSourceCount = 50;
@@ -275,6 +277,11 @@
      */
     void noteLoggerError(int error);
 
+    /*
+    * Records when system server restarts.
+    */
+    void noteSystemServerRestart(int32_t timeSec);
+
     /**
      * Records statsd skipped an event.
      */
@@ -338,6 +345,8 @@
     // Timestamps when we detect log loss after logd reconnect.
     std::list<int64_t> mLogLossTimestampNs;
 
+    std::list<int32_t> mSystemServerRestartSec;
+
     // Stores the number of times statsd modified the anomaly alarm registered with
     // StatsCompanionService.
     int mAnomalyAlarmRegisteredStats = 0;
@@ -366,6 +375,7 @@
     FRIEND_TEST(StatsdStatsTest, TestAtomLog);
     FRIEND_TEST(StatsdStatsTest, TestTimestampThreshold);
     FRIEND_TEST(StatsdStatsTest, TestAnomalyMonitor);
+    FRIEND_TEST(StatsdStatsTest, TestSystemServerCrash);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index 5ff8082..df08181 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define DEBUG true  // STOPSHIP if true
+#define DEBUG false  // STOPSHIP if true
 #include "Log.h"
 #include "MetricProducer.h"
 
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 9ca4daa..bf0f720 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#define DEBUG true  // STOPSHIP if true
+#define DEBUG false  // STOPSHIP if true
 #include "Log.h"
 #include "MetricsManager.h"
 #include "statslog.h"
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 9236864..2fe17da 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -383,4 +383,6 @@
     repeated SkippedLogEventStats skipped_log_event_stats = 13;
 
     repeated int64 log_loss_stats = 14;
+
+    repeated int32 system_restart_sec = 15;
 }
diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.cpp b/cmds/statsd/src/subscriber/IncidentdReporter.cpp
index 1c18f67..6e4b2c8 100644
--- a/cmds/statsd/src/subscriber/IncidentdReporter.cpp
+++ b/cmds/statsd/src/subscriber/IncidentdReporter.cpp
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#define DEBUG true
+#define DEBUG false
 #include "Log.h"
 
 #include "IncidentdReporter.h"
diff --git a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
index e99e402..967ef3c 100644
--- a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
+++ b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
@@ -298,6 +298,28 @@
     EXPECT_EQ(newTimestamp, configStats->dump_report_stats.back().first);
 }
 
+TEST(StatsdStatsTest, TestSystemServerCrash) {
+    StatsdStats stats;
+    vector<int32_t> timestamps;
+    for (int i = 0; i < StatsdStats::kMaxSystemServerRestarts; i++) {
+        timestamps.push_back(i);
+        stats.noteSystemServerRestart(timestamps[i]);
+    }
+    vector<uint8_t> output;
+    stats.dumpStats(&output, false);
+    StatsdStatsReport report;
+    EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
+    const int maxCount = StatsdStats::kMaxSystemServerRestarts;
+    EXPECT_EQ(maxCount, (int)report.system_restart_sec_size());
+
+    stats.noteSystemServerRestart(StatsdStats::kMaxSystemServerRestarts + 1);
+    output.clear();
+    stats.dumpStats(&output, false);
+    EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
+    EXPECT_EQ(maxCount, (int)report.system_restart_sec_size());
+    EXPECT_EQ(StatsdStats::kMaxSystemServerRestarts + 1, report.system_restart_sec(maxCount - 1));
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index dc48a47..e552ce9 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -212,6 +212,7 @@
 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;->getMode()I
 Landroid/app/AppOpsManager$OpEntry;->getRejectTime()J
 Landroid/app/AppOpsManager;->checkOp(IILjava/lang/String;)I
 Landroid/app/AppOpsManager;->checkOpNoThrow(IILjava/lang/String;)I
@@ -287,6 +288,7 @@
 Landroid/app/DownloadManager;->setAccessFilename(Z)V
 Landroid/app/Fragment;->mChildFragmentManager:Landroid/app/FragmentManagerImpl;
 Landroid/app/Fragment;->mWho:Ljava/lang/String;
+Landroid/app/FragmentManagerImpl;->loadAnimator(Landroid/app/Fragment;IZI)Landroid/animation/Animator;
 Landroid/app/FragmentManagerImpl;->mAdded:Ljava/util/ArrayList;
 Landroid/app/FragmentManagerImpl;->mStateSaved:Z
 Landroid/app/FragmentManagerImpl;->noteStateNotSaved()V
@@ -304,6 +306,7 @@
 Landroid/app/IActivityManager;->getConfiguration()Landroid/content/res/Configuration;
 Landroid/app/IActivityManager;->getIntentSender(ILjava/lang/String;Landroid/os/IBinder;Ljava/lang/String;I[Landroid/content/Intent;[Ljava/lang/String;ILandroid/os/Bundle;I)Landroid/content/IIntentSender;
 Landroid/app/IActivityManager;->getLaunchedFromPackage(Landroid/os/IBinder;)Ljava/lang/String;
+Landroid/app/IActivityManager;->getPackageProcessState(Ljava/lang/String;Ljava/lang/String;)I
 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
@@ -412,14 +415,12 @@
 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/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
@@ -452,11 +453,6 @@
 Landroid/app/SharedPreferencesImpl;-><init>(Ljava/io/File;I)V
 Landroid/app/SharedPreferencesImpl;->mFile:Ljava/io/File;
 Landroid/app/SharedPreferencesImpl;->startReloadIfChangedUnexpectedly()V
-Landroid/app/slice/Slice$Builder;-><init>(Landroid/net/Uri;)V
-Landroid/app/slice/Slice$Builder;->setSpec(Landroid/app/slice/SliceSpec;)Landroid/app/slice/Slice$Builder;
-Landroid/app/slice/SliceItem;->getTimestamp()J
-Landroid/app/slice/SliceManager;->bindSlice(Landroid/net/Uri;Ljava/util/List;)Landroid/app/slice/Slice;
-Landroid/app/slice/SliceManager;->pinSlice(Landroid/net/Uri;Ljava/util/List;)V
 Landroid/app/StatusBarManager;->collapsePanels()V
 Landroid/app/StatusBarManager;->disable(I)V
 Landroid/app/StatusBarManager;->expandNotificationsPanel()V
@@ -704,9 +700,11 @@
 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/IPackageDataObserver;->onRemoveCompleted(Ljava/lang/String;Z)V
+Landroid/content/pm/IPackageDeleteObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)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$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDeleteObserver2;
 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;
@@ -775,6 +773,7 @@
 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;->deletePackage(Ljava/lang/String;Landroid/content/pm/IPackageDeleteObserver;I)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
@@ -847,11 +846,11 @@
 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;->getUserHandle()Landroid/os/UserHandle;
 Landroid/content/pm/UserInfo;->id:I
 Landroid/content/pm/UserInfo;->isPrimary()Z
 Landroid/content/pm/UserInfo;->serialNumber:I
@@ -969,8 +968,8 @@
 Landroid/content/UriMatcher;->mText:Ljava/lang/String;
 Landroid/database/AbstractCursor;->mExtras:Landroid/os/Bundle;
 Landroid/database/AbstractCursor;->mNotifyUri:Landroid/net/Uri;
-Landroid/database/AbstractCursor;->mRowIdColumnIndex:I
 Landroid/database/AbstractWindowedCursor;->clearOrCreateWindow(Ljava/lang/String;)V
+Landroid/database/AbstractWindowedCursor;->closeWindow()V
 Landroid/database/CursorWindow;->mWindowPtr:J
 Landroid/database/CursorWindow;->sCursorWindowSize:I
 Landroid/database/CursorWindow;->sWindowToPidMap:Landroid/util/LongSparseArray;
@@ -979,6 +978,7 @@
 Landroid/database/sqlite/SQLiteCustomFunction;->name:Ljava/lang/String;
 Landroid/database/sqlite/SQLiteCustomFunction;->numArgs:I
 Landroid/database/sqlite/SQLiteDatabase;->CONFLICT_VALUES:[Ljava/lang/String;
+Landroid/database/sqlite/SQLiteDatabase;->getThreadSession()Landroid/database/sqlite/SQLiteSession;
 Landroid/database/sqlite/SQLiteDatabase;->mConfigurationLocked:Landroid/database/sqlite/SQLiteDatabaseConfiguration;
 Landroid/database/sqlite/SQLiteDatabase;->mConnectionPoolLocked:Landroid/database/sqlite/SQLiteConnectionPool;
 Landroid/database/sqlite/SQLiteDatabase;->reopenReadWrite()V
@@ -987,11 +987,10 @@
 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/SQLiteSession;->beginTransaction(ILandroid/database/sqlite/SQLiteTransactionListener;ILandroid/os/CancellationSignal;)V
 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;
@@ -1012,7 +1011,6 @@
 Landroid/graphics/Camera;->native_instance:J
 Landroid/graphics/Canvas;-><init>(J)V
 Landroid/graphics/Canvas;->release()V
-Landroid/graphics/Canvas;->save(I)I
 Landroid/graphics/ColorMatrixColorFilter;->setColorMatrix(Landroid/graphics/ColorMatrix;)V
 Landroid/graphics/drawable/AnimatedImageDrawable;->onAnimationEnd()V
 Landroid/graphics/drawable/AnimatedStateListDrawable$AnimatedStateListState;->mStateIds:Landroid/util/SparseIntArray;
@@ -1057,6 +1055,7 @@
 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;->createWithResource(Landroid/content/res/Resources;I)Landroid/graphics/drawable/Icon;
 Landroid/graphics/drawable/Icon;->getBitmap()Landroid/graphics/Bitmap;
 Landroid/graphics/drawable/Icon;->getDataBytes()[B
 Landroid/graphics/drawable/Icon;->getDataLength()I
@@ -1107,7 +1106,6 @@
 Landroid/graphics/NinePatch$InsetStruct;-><init>(IIIIIIIIFIF)V
 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/PorterDuffColorFilter;->setColor(I)V
 Landroid/graphics/PorterDuffColorFilter;->setMode(Landroid/graphics/PorterDuff$Mode;)V
@@ -1204,6 +1202,7 @@
 Landroid/hardware/display/WifiDisplayStatus;->mDisplays:[Landroid/hardware/display/WifiDisplay;
 Landroid/hardware/fingerprint/Fingerprint;->getFingerId()I
 Landroid/hardware/fingerprint/Fingerprint;->getName()Ljava/lang/CharSequence;
+Landroid/hardware/fingerprint/FingerprintManager;->getEnrolledFingerprints()Ljava/util/List;
 Landroid/hardware/fingerprint/IFingerprintService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/hardware/HardwareBuffer;-><init>(J)V
 Landroid/hardware/HardwareBuffer;->mNativeObject:J
@@ -1240,6 +1239,7 @@
 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;->captureSession:I
 Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;->data:[B
 Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->data:[B
 Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->uuid:Ljava/util/UUID;
@@ -1515,7 +1515,6 @@
 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;->requestRouteToHost(II)Z
 Landroid/net/ConnectivityManager;->requestRouteToHostAddress(ILjava/net/InetAddress;)Z
 Landroid/net/ConnectivityManager;->setBackgroundDataSetting(Z)V
 Landroid/net/ConnectivityManager;->TYPE_MOBILE_CBS:I
@@ -1575,7 +1574,6 @@
 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;->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;
@@ -1643,7 +1641,6 @@
 Landroid/net/wifi/ScanResult;->informationElements:[Landroid/net/wifi/ScanResult$InformationElement;
 Landroid/net/wifi/ScanResult;->numUsage:I
 Landroid/net/wifi/ScanResult;->seen:J
-Landroid/net/wifi/ScanResult;->untrusted:Z
 Landroid/net/wifi/ScanResult;->wifiSsid:Landroid/net/wifi/WifiSsid;
 Landroid/net/wifi/WifiConfiguration;->apBand:I
 Landroid/net/wifi/WifiConfiguration;->apChannel:I
@@ -1790,6 +1787,7 @@
 Landroid/os/HwParcel;-><init>(Z)V
 Landroid/os/HwRemoteBinder;-><init>()V
 Landroid/os/IBatteryPropertiesRegistrar$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/os/IDeviceIdleController;->getAppIdTempWhitelist()[I
 Landroid/os/IPermissionController$Stub$Proxy;->checkPermission(Ljava/lang/String;II)Z
 Landroid/os/IPermissionController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPermissionController;
 Landroid/os/IPowerManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -1837,9 +1835,7 @@
 Landroid/os/PowerManager;->getMinimumScreenBrightnessSetting()I
 Landroid/os/PowerManager;->isLightDeviceIdleMode()Z
 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(J)V
 Landroid/os/PowerManager;->wakeUp(JLjava/lang/String;)V
 Landroid/os/Process;->getFreeMemory()J
 Landroid/os/Process;->getParentPid(I)I
@@ -1847,6 +1843,7 @@
 Landroid/os/Process;->getTotalMemory()J
 Landroid/os/Process;->getUidForPid(I)I
 Landroid/os/Process;->isIsolated(I)Z
+Landroid/os/Process;->parseProcLine([BII[I[Ljava/lang/String;[J[F)Z
 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
@@ -1873,11 +1870,9 @@
 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;
-Landroid/os/storage/StorageManager;->getPrimaryVolume()Landroid/os/storage/StorageVolume;
 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()[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;
@@ -1888,6 +1883,7 @@
 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/StorageVolume;->mRemovable:Z
 Landroid/os/storage/VolumeInfo;->buildStorageVolume(Landroid/content/Context;IZ)Landroid/os/storage/StorageVolume;
 Landroid/os/storage/VolumeInfo;->getDisk()Landroid/os/storage/DiskInfo;
 Landroid/os/storage/VolumeInfo;->getEnvironmentForState(I)Ljava/lang/String;
@@ -1900,12 +1896,12 @@
 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;->sLastVmViolationTime:Ljava/util/HashMap;
 Landroid/os/StrictMode;->violationsBeingTimed:Ljava/lang/ThreadLocal;
 Landroid/os/SystemProperties;-><init>()V
 Landroid/os/SystemProperties;->addChangeCallback(Ljava/lang/Runnable;)V
@@ -1952,7 +1948,6 @@
 Landroid/os/UserHandle;->USER_SERIAL_SYSTEM:I
 Landroid/os/UserHandle;->USER_SYSTEM:I
 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
@@ -2027,17 +2022,8 @@
 Landroid/print/PrinterId;->getServiceName()Landroid/content/ComponentName;
 Landroid/print/PrintJobInfo;->getAdvancedOptions()Landroid/os/Bundle;
 Landroid/print/PrintJobInfo;->getDocumentInfo()Landroid/print/PrintDocumentInfo;
-Landroid/provider/Browser$BookmarkColumns;->DATE:Ljava/lang/String;
-Landroid/provider/Browser;->BOOKMARKS_URI:Landroid/net/Uri;
-Landroid/provider/Browser;->canClearHistory(Landroid/content/ContentResolver;)Z
-Landroid/provider/Browser;->clearHistory(Landroid/content/ContentResolver;)V
-Landroid/provider/Browser;->clearSearches(Landroid/content/ContentResolver;)V
-Landroid/provider/Browser;->deleteFromHistory(Landroid/content/ContentResolver;Ljava/lang/String;)V
 Landroid/provider/Browser;->getVisitedHistory(Landroid/content/ContentResolver;)[Ljava/lang/String;
-Landroid/provider/Browser;->HISTORY_PROJECTION:[Ljava/lang/String;
-Landroid/provider/Browser;->SEARCHES_URI:Landroid/net/Uri;
 Landroid/provider/Browser;->sendString(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)V
-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;
@@ -2083,7 +2069,6 @@
 Landroid/provider/Settings$System;->putStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;I)Z
 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/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;
@@ -2292,8 +2277,6 @@
 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/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$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/media/IMediaBrowserServiceCallbacks;
@@ -2305,8 +2288,6 @@
 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;
@@ -2375,6 +2356,9 @@
 Landroid/telecom/TelecomManager;->EXTRA_IS_HANDOVER:Ljava/lang/String;
 Landroid/telecom/TelecomManager;->getUserSelectedOutgoingPhoneAccount()Landroid/telecom/PhoneAccountHandle;
 Landroid/telecom/TelecomManager;->setUserSelectedOutgoingPhoneAccount(Landroid/telecom/PhoneAccountHandle;)V
+Landroid/telephony/CellIdentityGsm;->mBsic:I
+Landroid/telephony/CellSignalStrengthGsm;->mBitErrorRate:I
+Landroid/telephony/CellSignalStrengthGsm;->mSignalStrength:I
 Landroid/telephony/CellSignalStrengthLte;->mCqi:I
 Landroid/telephony/CellSignalStrengthLte;->mRsrp:I
 Landroid/telephony/CellSignalStrengthLte;->mRsrq:I
@@ -2409,6 +2393,8 @@
 Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_MODERATE:I
 Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_NONE_OR_UNKNOWN:I
 Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_POOR:I
+Landroid/telephony/SmsManager;->deleteMessageFromIcc(I)Z
+Landroid/telephony/SmsManager;->getAllMessagesFromIcc()Ljava/util/ArrayList;
 Landroid/telephony/SmsManager;->sendMultipartTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/util/ArrayList;Ljava/util/ArrayList;Ljava/util/ArrayList;IZI)V
 Landroid/telephony/SmsManager;->sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;IZI)V
 Landroid/telephony/SmsMessage;->getSubId()I
@@ -2435,6 +2421,7 @@
 Landroid/telephony/TelephonyManager;->getITelephony()Lcom/android/internal/telephony/ITelephony;
 Landroid/telephony/TelephonyManager;->getLine1Number(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getMultiSimConfiguration()Landroid/telephony/TelephonyManager$MultiSimVariants;
+Landroid/telephony/TelephonyManager;->getNai(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getNetworkClass(I)I
 Landroid/telephony/TelephonyManager;->getNetworkCountryIso(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getNetworkOperator(I)Ljava/lang/String;
@@ -2662,6 +2649,7 @@
 Landroid/view/IWindowManager;->getAnimationScale(I)F
 Landroid/view/IWindowManager;->hasNavigationBar()Z
 Landroid/view/IWindowManager;->setAnimationScale(IF)V
+Landroid/view/IWindowManager;->setAnimationScales([F)V
 Landroid/view/IWindowManager;->setShelfHeight(ZI)V
 Landroid/view/IWindowManager;->setStrictModeVisualIndicatorPreference(Ljava/lang/String;)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
@@ -2810,7 +2798,6 @@
 Landroid/view/View;->getViewRootImpl()Landroid/view/ViewRootImpl;
 Landroid/view/View;->getWindowDisplayFrame(Landroid/graphics/Rect;)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
@@ -2878,7 +2865,6 @@
 Landroid/view/View;->transformMatrixToLocal(Landroid/graphics/Matrix;)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
@@ -2919,6 +2905,7 @@
 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;->addPrivateFlags(I)V
 Landroid/view/Window;->mAppName:Ljava/lang/String;
 Landroid/view/Window;->mAppToken:Landroid/os/IBinder;
 Landroid/view/Window;->mCallback:Landroid/view/Window$Callback;
@@ -2970,6 +2957,7 @@
 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/IWebViewUpdateService$Stub$Proxy;->waitForAndGetProvider()Landroid/webkit/WebViewProviderResponse;
 Landroid/webkit/WebResourceResponse;->mImmutable:Z
 Landroid/webkit/WebSettings$TextSize;->value:I
 Landroid/webkit/WebSyncManager;->mHandler:Landroid/os/Handler;
@@ -2988,7 +2976,6 @@
 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;
@@ -3111,8 +3098,6 @@
 Landroid/widget/ListView;->fillDown(II)Landroid/view/View;
 Landroid/widget/ListView;->fillSpecific(II)Landroid/view/View;
 Landroid/widget/ListView;->fillUp(II)Landroid/view/View;
-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;
@@ -3121,7 +3106,9 @@
 Landroid/widget/MediaController;->mDecor:Landroid/view/View;
 Landroid/widget/MediaController;->mDecorLayoutParams:Landroid/view/WindowManager$LayoutParams;
 Landroid/widget/MediaController;->mWindowManager:Landroid/view/WindowManager;
+Landroid/widget/NumberPicker;->initializeSelectorWheelIndices()V
 Landroid/widget/NumberPicker;->mInputText:Landroid/widget/EditText;
+Landroid/widget/NumberPicker;->mMaxValue:I
 Landroid/widget/NumberPicker;->mSelectionDivider:Landroid/graphics/drawable/Drawable;
 Landroid/widget/NumberPicker;->mSelectionDividerHeight:I
 Landroid/widget/NumberPicker;->mSelectorWheelPaint:Landroid/graphics/Paint;
@@ -3219,7 +3206,6 @@
 Landroid/widget/TextView;->assumeLayout()V
 Landroid/widget/TextView;->createEditorIfNeeded()V
 Landroid/widget/TextView;->getHorizontallyScrolling()Z
-Landroid/widget/TextView;->getTextColor(Landroid/content/Context;Landroid/content/res/TypedArray;I)I
 Landroid/widget/TextView;->isSingleLine()Z
 Landroid/widget/TextView;->LINES:I
 Landroid/widget/TextView;->mCursorDrawableRes:I
@@ -3232,6 +3218,7 @@
 Landroid/widget/TextView;->mSingleLine:Z
 Landroid/widget/TextView;->mText:Ljava/lang/CharSequence;
 Landroid/widget/TextView;->mTextPaint:Landroid/text/TextPaint;
+Landroid/widget/TextView;->mTextSelectHandleLeftRes:I
 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;
@@ -3337,9 +3324,13 @@
 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/PackageMonitor;->onPackageRemoved(Ljava/lang/String;I)V
+Lcom/android/internal/content/PackageMonitor;->register(Landroid/content/Context;Landroid/os/Looper;Z)V
 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/logging/MetricsLogger;-><init>()V
+Lcom/android/internal/logging/MetricsLogger;->write(Landroid/metrics/LogMaker;)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;
@@ -3715,6 +3706,7 @@
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setUseSessionTickets(Z)V
 Lcom/android/org/conscrypt/OpenSSLX509Certificate;->mContext:J
 Lcom/android/org/conscrypt/TrustManagerImpl;-><init>(Ljava/security/KeyStore;)V
+Lcom/android/org/conscrypt/TrustManagerImpl;->checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List;
 Ldalvik/system/BaseDexClassLoader;->addDexPath(Ljava/lang/String;)V
 Ldalvik/system/BaseDexClassLoader;->getLdLibraryPath()Ljava/lang/String;
 Ldalvik/system/BaseDexClassLoader;->pathList:Ldalvik/system/DexPathList;
@@ -3740,6 +3732,7 @@
 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;->addNativePath(Ljava/util/Collection;)V
 Ldalvik/system/DexPathList;->definingContext:Ljava/lang/ClassLoader;
 Ldalvik/system/DexPathList;->dexElements:[Ldalvik/system/DexPathList$Element;
 Ldalvik/system/DexPathList;->loadDexFile(Ljava/io/File;Ljava/io/File;Ljava/lang/ClassLoader;[Ldalvik/system/DexPathList$Element;)Ldalvik/system/DexFile;
diff --git a/config/hiddenapi-vendor-list.txt b/config/hiddenapi-vendor-list.txt
index 4f878ac..fe10f41 100644
--- a/config/hiddenapi-vendor-list.txt
+++ b/config/hiddenapi-vendor-list.txt
@@ -100,11 +100,8 @@
 Landroid/content/pm/IPackageStatsObserver;->onGetStatsCompleted(Landroid/content/pm/PackageStats;Z)V
 Landroid/database/sqlite/SqliteWrapper;->insert(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;)Landroid/net/Uri;
 Landroid/database/sqlite/SqliteWrapper;->query(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
-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;)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
@@ -152,8 +149,6 @@
 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
@@ -355,8 +350,6 @@
 Landroid/os/Parcel;->readBlob()[B
 Landroid/os/Parcel;->readStringArray()[Ljava/lang/String;
 Landroid/os/Parcel;->writeBlob([B)V
-Landroid/os/PowerManager;->goToSleep(J)V
-Landroid/os/PowerManager;->isScreenBrightnessBoosted()Z
 Landroid/os/Registrant;-><init>(Landroid/os/Handler;ILjava/lang/Object;)V
 Landroid/os/Registrant;->clear()V
 Landroid/os/Registrant;->notifyRegistrant()V
@@ -514,12 +507,6 @@
 Landroid/telephony/TelephonyManager;->putIntAtIndex(Landroid/content/ContentResolver;Ljava/lang/String;II)Z
 Landroid/telephony/TelephonyManager;->setPreferredNetworkType(II)Z
 Landroid/text/TextUtils;->isPrintableAsciiOnly(Ljava/lang/CharSequence;)Z
-Landroid/util/FloatMath;->ceil(F)F
-Landroid/util/FloatMath;->cos(F)F
-Landroid/util/FloatMath;->exp(F)F
-Landroid/util/FloatMath;->floor(F)F
-Landroid/util/FloatMath;->sin(F)F
-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
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 037a87b..3f66747 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2683,7 +2683,7 @@
         // TODO(lifecycler): Can't switch to use #handleLaunchActivity() because it will try to
         // call #reportSizeConfigurations(), but the server might not know anything about the
         // activity if it was launched from LocalAcvitivyManager.
-        return performLaunchActivity(r);
+        return performLaunchActivity(r, null /* customIntent */);
     }
 
     public final Activity getActivity(IBinder token) {
@@ -2768,7 +2768,7 @@
     }
 
     /**  Core implementation of activity launch. */
-    private Activity performLaunchActivity(ActivityClientRecord r) {
+    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
         ActivityInfo aInfo = r.activityInfo;
         if (r.packageInfo == null) {
             r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
@@ -2838,6 +2838,9 @@
                         r.embeddedID, r.lastNonConfigurationInstances, config,
                         r.referrer, r.voiceInteractor, window, r.configCallback);
 
+                if (customIntent != null) {
+                    activity.mIntent = customIntent;
+                }
                 r.lastNonConfigurationInstances = null;
                 checkAndBlockForNetworkAccess();
                 activity.mStartedActivity = false;
@@ -2982,7 +2985,7 @@
      */
     @Override
     public Activity handleLaunchActivity(ActivityClientRecord r,
-            PendingTransactionActions pendingActions) {
+            PendingTransactionActions pendingActions, Intent customIntent) {
         // If we are getting ready to gc after going to the background, well
         // we are back active so skip it.
         unscheduleGcIdler();
@@ -3005,7 +3008,7 @@
         }
         WindowManagerGlobal.initialize();
 
-        final Activity a = performLaunchActivity(r);
+        final Activity a = performLaunchActivity(r, customIntent);
 
         if (a != null) {
             r.createdConfig = new Configuration(mConfiguration);
@@ -4699,6 +4702,8 @@
             List<ResultInfo> pendingResults, List<ReferrerIntent> pendingIntents,
             PendingTransactionActions pendingActions, boolean startsNotResumed,
             Configuration overrideConfig, String reason) {
+        // Preserve last used intent, it may be set from Activity#setIntent().
+        final Intent customIntent = r.activity.mIntent;
         // Need to ensure state is saved.
         if (!r.paused) {
             performPauseActivity(r, false, reason, null /* pendingActions */);
@@ -4731,7 +4736,7 @@
         r.startsNotResumed = startsNotResumed;
         r.overrideConfig = overrideConfig;
 
-        handleLaunchActivity(r, pendingActions);
+        handleLaunchActivity(r, pendingActions, customIntent);
     }
 
     @Override
@@ -5333,8 +5338,8 @@
                                         }
                                     }
                                 }
-                                final List<String> oldPaths =
-                                        sPackageManager.getPreviousCodePaths(packageName);
+                                final ArrayList<String> oldPaths = new ArrayList<>();
+                                LoadedApk.makePaths(this, pkgInfo.getApplicationInfo(), oldPaths);
                                 pkgInfo.updateApplicationInfo(aInfo, oldPaths);
                             } catch (RemoteException e) {
                             }
@@ -5512,6 +5517,7 @@
         Process.setArgV0(data.processName);
         android.ddm.DdmHandleAppName.setAppName(data.processName,
                                                 UserHandle.myUserId());
+        VMRuntime.setProcessPackageName(data.appInfo.packageName);
 
         if (mProfiler.profileFd != null) {
             mProfiler.startProfiling();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 796e406..07048f9 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -338,7 +338,9 @@
     /** @hide Any app start foreground service. */
     public static final int OP_START_FOREGROUND = 76;
     /** @hide */
-    public static final int _NUM_OP = 77;
+    public static final int OP_BLUETOOTH_SCAN = 77;
+    /** @hide */
+    public static final int _NUM_OP = 78;
 
     /** Access to coarse location information. */
     public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -580,6 +582,8 @@
     /** @hide */
     @SystemApi @TestApi
     public static final String OPSTR_START_FOREGROUND = "android:start_foreground";
+    /** @hide */
+    public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan";
 
     // Warning: If an permission is added here it also has to be added to
     // com.android.packageinstaller.permission.utils.EventLogger
@@ -717,6 +721,7 @@
             OP_ACCEPT_HANDOVER,                 // ACCEPT_HANDOVER
             OP_MANAGE_IPSEC_TUNNELS,            // MANAGE_IPSEC_HANDOVERS
             OP_START_FOREGROUND,                // START_FOREGROUND
+            OP_COARSE_LOCATION,                 // BLUETOOTH_SCAN
     };
 
     /**
@@ -800,6 +805,7 @@
             OPSTR_ACCEPT_HANDOVER,
             OPSTR_MANAGE_IPSEC_TUNNELS,
             OPSTR_START_FOREGROUND,
+            OPSTR_BLUETOOTH_SCAN,
     };
 
     /**
@@ -884,6 +890,7 @@
             "ACCEPT_HANDOVER",
             "MANAGE_IPSEC_TUNNELS",
             "START_FOREGROUND",
+            "BLUETOOTH_SCAN",
     };
 
     /**
@@ -968,6 +975,7 @@
             Manifest.permission.ACCEPT_HANDOVER,
             null, // no permission for OP_MANAGE_IPSEC_TUNNELS
             Manifest.permission.FOREGROUND_SERVICE,
+            null, // no permission for OP_BLUETOOTH_SCAN
     };
 
     /**
@@ -1053,6 +1061,7 @@
             null, // ACCEPT_HANDOVER
             null, // MANAGE_IPSEC_TUNNELS
             null, // START_FOREGROUND
+            null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN
     };
 
     /**
@@ -1137,6 +1146,7 @@
             false, // ACCEPT_HANDOVER
             false, // MANAGE_IPSEC_HANDOVERS
             false, // START_FOREGROUND
+            true, // BLUETOOTH_SCAN
     };
 
     /**
@@ -1220,6 +1230,7 @@
             AppOpsManager.MODE_ALLOWED,  // ACCEPT_HANDOVER
             AppOpsManager.MODE_ERRORED,  // MANAGE_IPSEC_TUNNELS
             AppOpsManager.MODE_ALLOWED,  // OP_START_FOREGROUND
+            AppOpsManager.MODE_ALLOWED,  // OP_BLUETOOTH_SCAN
     };
 
     /**
@@ -1307,6 +1318,7 @@
             false, // ACCEPT_HANDOVER
             false, // MANAGE_IPSEC_TUNNELS
             false, // START_FOREGROUND
+            false, // BLUETOOTH_SCAN
     };
 
     /**
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index 7257044..0ed50f2 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -25,6 +25,8 @@
 
 import dalvik.system.PathClassLoader;
 
+import java.util.Collection;
+
 /** @hide */
 public class ApplicationLoaders {
     public static ApplicationLoaders getDefault() {
@@ -121,6 +123,17 @@
         baseDexClassLoader.addDexPath(dexPath);
     }
 
+    /**
+     * @hide
+     */
+    void addNative(ClassLoader classLoader, Collection<String> libPaths) {
+        if (!(classLoader instanceof PathClassLoader)) {
+            throw new IllegalStateException("class loader is not a PathClassLoader");
+        }
+        final PathClassLoader baseDexClassLoader = (PathClassLoader) classLoader;
+        baseDexClassLoader.addNativePath(libPaths);
+    }
+
     private final ArrayMap<String, ClassLoader> mLoaders = new ArrayMap<>();
 
     private static final ApplicationLoaders gApplicationLoaders = new ApplicationLoaders();
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index ea0d703..d9c7cf3 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -18,6 +18,7 @@
 import android.app.servertransaction.ClientTransaction;
 import android.app.servertransaction.PendingTransactionActions;
 import android.app.servertransaction.TransactionExecutor;
+import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
@@ -140,7 +141,7 @@
 
     /** Perform activity launch. */
     public abstract Activity handleLaunchActivity(ActivityThread.ActivityClientRecord r,
-            PendingTransactionActions pendingActions);
+            PendingTransactionActions pendingActions, Intent customIntent);
 
     /** Perform activity start. */
     public abstract void handleStartActivity(ActivityThread.ActivityClientRecord r,
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index fc7d9a5..8c0cd23 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -90,6 +90,7 @@
 public final class LoadedApk {
     static final String TAG = "LoadedApk";
     static final boolean DEBUG = false;
+    private static final String PROPERTY_NAME_APPEND_NATIVE = "pi.append_native_lib_paths";
 
     private final ActivityThread mActivityThread;
     final String mPackageName;
@@ -723,6 +724,10 @@
             needToSetupJitProfiles = true;
         }
 
+        if (!libPaths.isEmpty() && SystemProperties.getBoolean(PROPERTY_NAME_APPEND_NATIVE, true)) {
+            ApplicationLoaders.getDefault().addNative(mClassLoader, libPaths);
+        }
+
         if (addedPaths != null && addedPaths.size() > 0) {
             final String add = TextUtils.join(File.pathSeparator, addedPaths);
             ApplicationLoaders.getDefault().addPath(mClassLoader, add);
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 9e47ced..ba355f9 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -76,6 +76,7 @@
     private static final String ATT_CONTENT_TYPE = "content_type";
     private static final String ATT_SHOW_BADGE = "show_badge";
     private static final String ATT_USER_LOCKED = "locked";
+    private static final String ATT_FG_SERVICE_SHOWN = "fgservice";
     private static final String ATT_GROUP = "group";
     private static final String ATT_BLOCKABLE_SYSTEM = "blockable_system";
     private static final String DELIMITER = ",";
@@ -144,6 +145,7 @@
     // Bitwise representation of fields that have been changed by the user, preventing the app from
     // making changes to these fields.
     private int mUserLockedFields;
+    private boolean mFgServiceShown;
     private boolean mVibrationEnabled;
     private boolean mShowBadge = DEFAULT_SHOW_BADGE;
     private boolean mDeleted = DEFAULT_DELETED;
@@ -200,6 +202,7 @@
         mLights = in.readByte() != 0;
         mVibration = in.createLongArray();
         mUserLockedFields = in.readInt();
+        mFgServiceShown = in.readByte() != 0;
         mVibrationEnabled = in.readByte() != 0;
         mShowBadge = in.readByte() != 0;
         mDeleted = in.readByte() != 0;
@@ -245,6 +248,7 @@
         dest.writeByte(mLights ? (byte) 1 : (byte) 0);
         dest.writeLongArray(mVibration);
         dest.writeInt(mUserLockedFields);
+        dest.writeByte(mFgServiceShown ? (byte) 1 : (byte) 0);
         dest.writeByte(mVibrationEnabled ? (byte) 1 : (byte) 0);
         dest.writeByte(mShowBadge ? (byte) 1 : (byte) 0);
         dest.writeByte(mDeleted ? (byte) 1 : (byte) 0);
@@ -281,6 +285,13 @@
     /**
      * @hide
      */
+    public void setFgServiceShown(boolean shown) {
+        mFgServiceShown = shown;
+    }
+
+    /**
+     * @hide
+     */
     public void setDeleted(boolean deleted) {
         mDeleted = deleted;
     }
@@ -576,6 +587,13 @@
     /**
      * @hide
      */
+    public boolean isFgServiceShown() {
+        return mFgServiceShown;
+    }
+
+    /**
+     * @hide
+     */
     public boolean isBlockableSystem() {
         return mBlockableSystem;
     }
@@ -620,6 +638,7 @@
         setDeleted(safeBool(parser, ATT_DELETED, false));
         setGroup(parser.getAttributeValue(null, ATT_GROUP));
         lockFields(safeInt(parser, ATT_USER_LOCKED, 0));
+        setFgServiceShown(safeBool(parser, ATT_FG_SERVICE_SHOWN, false));
         setBlockableSystem(safeBool(parser, ATT_BLOCKABLE_SYSTEM, false));
     }
 
@@ -724,6 +743,9 @@
         if (getUserLockedFields() != 0) {
             out.attribute(null, ATT_USER_LOCKED, Integer.toString(getUserLockedFields()));
         }
+        if (isFgServiceShown()) {
+            out.attribute(null, ATT_FG_SERVICE_SHOWN, Boolean.toString(isFgServiceShown()));
+        }
         if (canShowBadge()) {
             out.attribute(null, ATT_SHOW_BADGE, Boolean.toString(canShowBadge()));
         }
@@ -772,6 +794,7 @@
         record.put(ATT_LIGHT_COLOR, Integer.toString(getLightColor()));
         record.put(ATT_VIBRATION_ENABLED, Boolean.toString(shouldVibrate()));
         record.put(ATT_USER_LOCKED, Integer.toString(getUserLockedFields()));
+        record.put(ATT_FG_SERVICE_SHOWN, Boolean.toString(isFgServiceShown()));
         record.put(ATT_VIBRATION, longArrayToString(getVibrationPattern()));
         record.put(ATT_SHOW_BADGE, Boolean.toString(canShowBadge()));
         record.put(ATT_DELETED, Boolean.toString(isDeleted()));
@@ -933,6 +956,7 @@
                 + ", mLightColor=" + mLightColor
                 + ", mVibration=" + Arrays.toString(mVibration)
                 + ", mUserLockedFields=" + Integer.toHexString(mUserLockedFields)
+                + ", mFgServiceShown=" + mFgServiceShown
                 + ", mVibrationEnabled=" + mVibrationEnabled
                 + ", mShowBadge=" + mShowBadge
                 + ", mDeleted=" + mDeleted
@@ -963,6 +987,7 @@
             }
         }
         proto.write(NotificationChannelProto.USER_LOCKED_FIELDS, mUserLockedFields);
+        proto.write(NotificationChannelProto.FG_SERVICE_SHOWN, mFgServiceShown);
         proto.write(NotificationChannelProto.IS_VIBRATION_ENABLED, mVibrationEnabled);
         proto.write(NotificationChannelProto.SHOW_BADGE, mShowBadge);
         proto.write(NotificationChannelProto.IS_DELETED, mDeleted);
diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java
index 7be82bf..6bae359 100644
--- a/core/java/android/app/servertransaction/LaunchActivityItem.java
+++ b/core/java/android/app/servertransaction/LaunchActivityItem.java
@@ -75,7 +75,7 @@
                 mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                 mPendingResults, mPendingNewIntents, mIsForward,
                 mProfilerInfo, client);
-        client.handleLaunchActivity(r, pendingActions);
+        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
     }
 
diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java
index 5c803a5..43a2b4c 100644
--- a/core/java/android/app/servertransaction/TransactionExecutor.java
+++ b/core/java/android/app/servertransaction/TransactionExecutor.java
@@ -173,7 +173,8 @@
             log("Transitioning to state: " + state);
             switch (state) {
                 case ON_CREATE:
-                    mTransactionHandler.handleLaunchActivity(r, mPendingActions);
+                    mTransactionHandler.handleLaunchActivity(r, mPendingActions,
+                            null /* customIntent */);
                     break;
                 case ON_START:
                     mTransactionHandler.handleStartActivity(r, mPendingActions);
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index 6b1222f..0269b6c 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -96,7 +96,8 @@
         encryptionAware = directBootAware = orig.directBootAware;
     }
 
-    @Override public CharSequence loadLabel(PackageManager pm) {
+    /** @hide */
+    @Override public CharSequence loadUnsafeLabel(PackageManager pm) {
         if (nonLocalizedLabel != null) {
             return nonLocalizedLabel;
         }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 2be33e9..c988fa9 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -644,8 +644,6 @@
 
     boolean isPackageDeviceAdminOnAnyUser(String packageName);
 
-    List<String> getPreviousCodePaths(in String packageName);
-
     int getInstallReason(String packageName, int userId);
 
     ParceledListSlice getSharedLibraries(in String packageName, int flags, int userId);
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 53ffd55..07fbfb5 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -43,6 +43,8 @@
  */
 public class PackageItemInfo {
     private static final float MAX_LABEL_SIZE_PX = 500f;
+    /** The maximum length of a safe label, in characters */
+    private static final int MAX_SAFE_LABEL_LENGTH = 50000;
 
     private static volatile boolean sForceSafeLabels = false;
 
@@ -187,7 +189,8 @@
         // If the label contains new line characters it may push the UI
         // down to hide a part of it. Labels shouldn't have new line
         // characters, so just truncate at the first time one is seen.
-        final int labelLength = labelStr.length();
+        final int labelLength = Math.min(labelStr.length(), MAX_SAFE_LABEL_LENGTH);
+        final StringBuffer sb = new StringBuffer(labelLength);
         int offset = 0;
         while (offset < labelLength) {
             final int codePoint = labelStr.codePointAt(offset);
@@ -199,14 +202,19 @@
                 break;
             }
             // replace all non-break space to " " in order to be trimmed
+            final int charCount = Character.charCount(codePoint);
             if (type == Character.SPACE_SEPARATOR) {
-                labelStr = labelStr.substring(0, offset) + " " + labelStr.substring(offset +
-                        Character.charCount(codePoint));
+                sb.append(' ');
+            } else {
+                sb.append(labelStr.charAt(offset));
+                if (charCount == 2) {
+                    sb.append(labelStr.charAt(offset + 1));
+                }
             }
-            offset += Character.charCount(codePoint);
+            offset += charCount;
         }
 
-        labelStr = labelStr.trim();
+        labelStr = sb.toString().trim();
         if (labelStr.isEmpty()) {
             return packageName;
         }
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 19b5c45..193e56e 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -1905,6 +1905,10 @@
      * Return whether the screen has a wide color gamut and wide color gamut rendering
      * is supported by this device.
      *
+     * When true, it implies the screen is colorspace aware but not
+     * necessarily color-managed. The final colors may still be changed by the
+     * screen depending on user settings.
+     *
      * @return true if the screen has a wide color gamut and wide color gamut rendering
      * is supported, false otherwise
      */
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index c58cde0..7adea6a8 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -128,6 +128,14 @@
     private final ArrayList<WeakReference<Theme>> mThemeRefs = new ArrayList<>();
 
     /**
+     * To avoid leaking WeakReferences to garbage collected Themes on the
+     * mThemeRefs list, we flush the list of stale references any time the
+     * mThemeRefNextFlushSize is reached.
+     */
+    private static final int MIN_THEME_REFS_FLUSH_SIZE = 32;
+    private int mThemeRefsNextFlushSize = MIN_THEME_REFS_FLUSH_SIZE;
+
+    /**
      * Returns the most appropriate default theme for the specified target SDK version.
      * <ul>
      * <li>Below API 11: Gingerbread
@@ -1770,6 +1778,13 @@
         theme.setImpl(mResourcesImpl.newThemeImpl());
         synchronized (mThemeRefs) {
             mThemeRefs.add(new WeakReference<>(theme));
+
+            // Clean up references to garbage collected themes
+            if (mThemeRefs.size() > mThemeRefsNextFlushSize) {
+                mThemeRefs.removeIf(ref -> ref.get() == null);
+                mThemeRefsNextFlushSize = Math.max(MIN_THEME_REFS_FLUSH_SIZE,
+                        2 * mThemeRefs.size());
+            }
         }
         return theme;
     }
diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl
index 36c5deb..8c256be 100644
--- a/core/java/android/os/IStatsManager.aidl
+++ b/core/java/android/os/IStatsManager.aidl
@@ -56,7 +56,7 @@
     /**
      * Tells statsd that the device is about to shutdown.
      */
-    void informDeviceShutdown(boolean isShutdown);
+    void informDeviceShutdown();
 
     /**
      * Inform statsd what the version and package are for each uid. Note that each array should
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 9b20ed2..11afd21 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -157,8 +157,9 @@
     public static final String DISALLOW_CONFIG_LOCALE = "no_config_locale";
 
     /**
-     * Specifies if a user is disallowed from installing applications.
-     * The default value is <code>false</code>.
+     * Specifies if a user is disallowed from installing applications. This user restriction also
+     * prevents device owners and profile owners installing apps. The default value is
+     * {@code false}.
      *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index 9e3e386..5c99f6c 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -312,7 +312,7 @@
      * {@link android.Manifest.permission#WRITE_MEDIA_STORAGE}.
      */
     public File getInternalPathForUser(int userId) {
-        if (type == TYPE_PUBLIC && !isVisible()) {
+        if (type == TYPE_PUBLIC) {
             // TODO: plumb through cleaner path from vold
             return new File(path.replace("/storage/", "/mnt/media_rw/"));
         } else {
diff --git a/core/java/android/util/apk/ApkVerityBuilder.java b/core/java/android/util/apk/ApkVerityBuilder.java
index f15e1a1..2dd0117 100644
--- a/core/java/android/util/apk/ApkVerityBuilder.java
+++ b/core/java/android/util/apk/ApkVerityBuilder.java
@@ -134,7 +134,7 @@
         assertSigningBlockAlignedAndHasFullPages(signatureInfo);
         long signingBlockSize =
                 signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset;
-        long dataSize = apk.length() - signingBlockSize - ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE;
+        long dataSize = apk.length() - signingBlockSize;
         int[] levelOffset = calculateVerityLevelOffset(dataSize);
 
         if (treeOutput != null) {
@@ -346,8 +346,8 @@
 
         buffer.putLong(fileSize);           // original file size
 
-        buffer.put((byte) 0);               // auth block offset, disabled here
-        buffer.put((byte) 2);               // extension count
+        buffer.put((byte) 2);               // authenticated extension count
+        buffer.put((byte) 0);               // unauthenticated extension count
         buffer.put(salt);                   // salt (8 bytes)
         skip(buffer, 22);                   // reserved
 
@@ -359,12 +359,6 @@
             long signingBlockSize, long eocdOffset) {
         // Snapshot of the FSVerity structs (subject to change once upstreamed).
         //
-        // struct fsverity_extension {
-        //   __le16 length;
-        //   u8 type;
-        //   u8 reserved[5];
-        // };
-        //
         // struct fsverity_extension_elide {
         //   __le64 offset;
         //   __le64 length;
@@ -382,10 +376,10 @@
             // struct fsverity_extension #1
             final int kSizeOfFsverityElidedExtension = 16;
 
-            buffer.putShort((short)  // total size of extension, padded to 64-bit alignment
-                    (kSizeOfFsverityExtensionHeader + kSizeOfFsverityElidedExtension));
-            buffer.put((byte) 0);    // ID of elide extension
-            skip(buffer, 5);         // reserved
+            // First field is total size of extension, padded to 64-bit alignment
+            buffer.putInt(kSizeOfFsverityExtensionHeader + kSizeOfFsverityElidedExtension);
+            buffer.putShort((short) 1);  // ID of elide extension
+            skip(buffer, 2);             // reserved
 
             // struct fsverity_extension_elide
             buffer.putLong(signingBlockOffset);
@@ -398,9 +392,9 @@
                     + 8 // offset size
                     + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE;
 
-            buffer.putShort((short) kTotalSize);
-            buffer.put((byte) 1);    // ID of patch extension
-            skip(buffer, 5);         // reserved
+            buffer.putInt(kTotalSize);   // Total size of extension, padded to 64-bit alignment
+            buffer.putShort((short) 2);  // ID of patch extension
+            skip(buffer, 2);             // reserved
 
             // struct fsverity_extension_patch
             buffer.putLong(eocdOffset + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET);  // offset
@@ -412,7 +406,7 @@
             if (kPadding == kExtensionSizeAlignment) {
                 kPadding = 0;
             }
-            skip(buffer, kPadding);                              // padding
+            skip(buffer, kPadding);      // padding
         }
 
         buffer.flip();
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 5deee11..ed8b005 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -1580,6 +1580,20 @@
          */
         public Transaction destroy(SurfaceControl sc) {
             sc.checkNotReleased();
+
+            /**
+             * Perhaps it's safer to transfer the close guard to the Transaction
+             * but then we have a whole wonky scenario regarding merging, multiple
+             * close-guards per transaction etc...the whole scenario is kind of wonky
+             * and it seems really we'd like to just be able to call release here
+             * but the WindowManager has some code that looks like
+             * --- destroyInTransaction(a)
+             * --- reparentChildrenInTransaction(a)
+             * so we need to ensure the SC remains valid until the transaction
+             * is applied.
+             */
+            sc.mCloseGuard.close();
+
             nativeDestroy(mNativeObject, sc.mNativeObject);
             return this;
         }
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index da47bcb..24f531d 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -114,9 +114,10 @@
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
-    @StringDef({WIDGET_TYPE_TEXTVIEW, WIDGET_TYPE_WEBVIEW, WIDGET_TYPE_EDITTEXT,
-            WIDGET_TYPE_EDIT_WEBVIEW, WIDGET_TYPE_CUSTOM_TEXTVIEW, WIDGET_TYPE_CUSTOM_EDITTEXT,
-            WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW, WIDGET_TYPE_UNKNOWN})
+    @StringDef({WIDGET_TYPE_TEXTVIEW, WIDGET_TYPE_EDITTEXT, WIDGET_TYPE_UNSELECTABLE_TEXTVIEW,
+            WIDGET_TYPE_WEBVIEW, WIDGET_TYPE_EDIT_WEBVIEW, WIDGET_TYPE_CUSTOM_TEXTVIEW,
+            WIDGET_TYPE_CUSTOM_EDITTEXT, WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW,
+            WIDGET_TYPE_UNKNOWN})
     @interface WidgetType {}
 
     /** The widget involved in the text classification session is a standard
diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
index 4db3607..a22f345 100644
--- a/core/java/android/widget/DateTimeView.java
+++ b/core/java/android/widget/DateTimeView.java
@@ -104,8 +104,16 @@
             sReceiverInfo.set(ri);
         }
         ri.addView(this);
+        // The view may not be added to the view hierarchy immediately right after setTime()
+        // is called which means it won't get any update from intents before being added.
+        // In such case, the view might show the incorrect relative time after being added to the
+        // view hierarchy until the next update intent comes.
+        // So we update the time here if mShowRelativeTime is enabled to prevent this case.
+        if (mShowRelativeTime) {
+            update();
+        }
     }
-        
+
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index 08c4dc9..929496f 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -38,7 +38,6 @@
 import android.view.ContextThemeWrapper;
 import android.view.Display;
 import android.view.DisplayListCanvas;
-import android.view.LayoutInflater;
 import android.view.PixelCopy;
 import android.view.RenderNode;
 import android.view.Surface;
@@ -71,8 +70,6 @@
     private final int[] mViewCoordinatesInSurface;
     // The window containing the magnifier.
     private InternalPopupWindow mWindow;
-    // The center coordinates of the window containing the magnifier.
-    private final Point mWindowCoords = new Point();
     // The width of the window containing the magnifier.
     private final int mWindowWidth;
     // The height of the window containing the magnifier.
@@ -87,8 +84,18 @@
     private final float mWindowElevation;
     // The corner radius of the window containing the magnifier.
     private final float mWindowCornerRadius;
-    // The center coordinates of the content that is to be magnified.
+    // The parent surface for the magnifier surface.
+    private SurfaceInfo mParentSurface;
+    // The surface where the content will be copied from.
+    private SurfaceInfo mContentCopySurface;
+    // The center coordinates of the window containing the magnifier.
+    private final Point mWindowCoords = new Point();
+    // The center coordinates of the content to be magnified,
+    // which can potentially contain a region outside the magnified view.
     private final Point mCenterZoomCoords = new Point();
+    // The center coordinates of the content to be magnified,
+    // clamped inside the visible region of the magnified view.
+    private final Point mClampedCenterZoomCoords = new Point();
     // Variables holding previous states, used for detecting redundant calls and invalidation.
     private final Point mPrevStartCoordsInSurface = new Point(
             NONEXISTENT_PREVIOUS_CONFIG_VALUE, NONEXISTENT_PREVIOUS_CONFIG_VALUE);
@@ -108,8 +115,6 @@
     public Magnifier(@NonNull View view) {
         mView = Preconditions.checkNotNull(view);
         final Context context = mView.getContext();
-        final View content = LayoutInflater.from(context).inflate(R.layout.magnifier, null);
-        content.findViewById(R.id.magnifier_inner).setClipToOutline(true);
         mWindowWidth = context.getResources().getDimensionPixelSize(R.dimen.magnifier_width);
         mWindowHeight = context.getResources().getDimensionPixelSize(R.dimen.magnifier_height);
         mWindowElevation = context.getResources().getDimension(R.dimen.magnifier_elevation);
@@ -155,31 +160,17 @@
         xPosInView = Math.max(0, Math.min(xPosInView, mView.getWidth()));
         yPosInView = Math.max(0, Math.min(yPosInView, mView.getHeight()));
 
-        configureCoordinates(xPosInView, yPosInView);
+        obtainSurfaces();
+        obtainContentCoordinates(xPosInView, yPosInView);
+        obtainWindowCoordinates();
 
-        // Clamp the startX location to avoid magnifying content which does not belong
-        // to the magnified view. This will not take into account overlapping views.
-        final Rect viewVisibleRegion = new Rect();
-        mView.getGlobalVisibleRect(viewVisibleRegion);
-        if (mView.getViewRootImpl() != null) {
-            // Clamping coordinates relative to the surface, not to the window.
-            final Rect surfaceInsets = mView.getViewRootImpl().mWindowAttributes.surfaceInsets;
-            viewVisibleRegion.offset(surfaceInsets.left, surfaceInsets.top);
-        }
-        if (mView instanceof SurfaceView) {
-            // If we copy content from a SurfaceView, clamp coordinates relative to it.
-            viewVisibleRegion.offset(-mViewCoordinatesInSurface[0], -mViewCoordinatesInSurface[1]);
-        }
-        final int startX = Math.max(viewVisibleRegion.left, Math.min(
-                mCenterZoomCoords.x - mBitmapWidth / 2,
-                viewVisibleRegion.right - mBitmapWidth));
-        final int startY = mCenterZoomCoords.y - mBitmapHeight / 2;
-
+        final int startX = mClampedCenterZoomCoords.x - mBitmapWidth / 2;
+        final int startY = mClampedCenterZoomCoords.y - mBitmapHeight / 2;
         if (xPosInView != mPrevPosInView.x || yPosInView != mPrevPosInView.y) {
             if (mWindow == null) {
                 synchronized (mLock) {
                     mWindow = new InternalPopupWindow(mView.getContext(), mView.getDisplay(),
-                            getValidParentSurfaceForMagnifier(),
+                            mParentSurface.mSurface,
                             mWindowWidth, mWindowHeight, mWindowElevation, mWindowCornerRadius,
                             Handler.getMain() /* draw the magnifier on the UI thread */, mLock,
                             mCallback);
@@ -213,6 +204,7 @@
      */
     public void update() {
         if (mWindow != null) {
+            obtainSurfaces();
             // Update the content shown in the magnifier.
             performPixelCopy(mPrevStartCoordsInSurface.x, mPrevStartCoordsInSurface.y,
                     false /* update window position */);
@@ -257,26 +249,53 @@
                 mWindow.mLastDrawContentPositionY - surfaceInsets.top);
     }
 
-    @Nullable
-    private Surface getValidParentSurfaceForMagnifier() {
+    /**
+     * Retrieves the surfaces used by the magnifier:
+     * - a parent surface for the magnifier surface. This will usually be the main app window.
+     * - a surface where the magnified content will be copied from. This will be the main app
+     *   window unless the magnified view is a SurfaceView, in which case its backing surface
+     *   will be used.
+     */
+    private void obtainSurfaces() {
+        // Get the main window surface.
+        SurfaceInfo validMainWindowSurface = SurfaceInfo.NULL;
         if (mView.getViewRootImpl() != null) {
-            final Surface mainWindowSurface = mView.getViewRootImpl().mSurface;
+            final ViewRootImpl viewRootImpl = mView.getViewRootImpl();
+            final Surface mainWindowSurface = viewRootImpl.mSurface;
             if (mainWindowSurface != null && mainWindowSurface.isValid()) {
-                return mainWindowSurface;
+                final Rect surfaceInsets = viewRootImpl.mWindowAttributes.surfaceInsets;
+                final int surfaceWidth =
+                        viewRootImpl.getWidth() + surfaceInsets.left + surfaceInsets.right;
+                final int surfaceHeight =
+                        viewRootImpl.getHeight() + surfaceInsets.top + surfaceInsets.bottom;
+                validMainWindowSurface =
+                        new SurfaceInfo(mainWindowSurface, surfaceWidth, surfaceHeight, true);
             }
         }
+        // Get the surface backing the magnified view, if it is a SurfaceView.
+        SurfaceInfo validSurfaceViewSurface = SurfaceInfo.NULL;
         if (mView instanceof SurfaceView) {
-            final Surface surfaceViewSurface = ((SurfaceView) mView).getHolder().getSurface();
+            final SurfaceHolder surfaceHolder = ((SurfaceView) mView).getHolder();
+            final Surface surfaceViewSurface = surfaceHolder.getSurface();
             if (surfaceViewSurface != null && surfaceViewSurface.isValid()) {
-                return surfaceViewSurface;
+                final Rect surfaceFrame = surfaceHolder.getSurfaceFrame();
+                validSurfaceViewSurface = new SurfaceInfo(surfaceViewSurface,
+                        surfaceFrame.right, surfaceFrame.bottom, false);
             }
         }
-        return null;
+
+        // Choose the parent surface for the magnifier and the source surface for the content.
+        mParentSurface = validMainWindowSurface != SurfaceInfo.NULL
+                ? validMainWindowSurface : validSurfaceViewSurface;
+        mContentCopySurface = mView instanceof SurfaceView
+                ? validSurfaceViewSurface : validMainWindowSurface;
     }
 
-    private void configureCoordinates(final float xPosInView, final float yPosInView) {
-        // Compute the coordinates of the center of the content going to be displayed in the
-        // magnifier. These are relative to the surface the content is copied from.
+    /**
+     * Computes the coordinates of the center of the content going to be displayed in the
+     * magnifier. These are relative to the surface the content is copied from.
+     */
+    private void obtainContentCoordinates(final float xPosInView, final float yPosInView) {
         final float posX;
         final float posY;
         mView.getLocationInSurface(mViewCoordinatesInSurface);
@@ -291,78 +310,59 @@
         mCenterZoomCoords.x = Math.round(posX);
         mCenterZoomCoords.y = Math.round(posY);
 
+        // Clamp the x location to avoid magnifying content which does not belong
+        // to the magnified view. This will not take into account overlapping views.
+        final Rect viewVisibleRegion = new Rect();
+        mView.getGlobalVisibleRect(viewVisibleRegion);
+        if (mView.getViewRootImpl() != null) {
+            // Clamping coordinates relative to the surface, not to the window.
+            final Rect surfaceInsets = mView.getViewRootImpl().mWindowAttributes.surfaceInsets;
+            viewVisibleRegion.offset(surfaceInsets.left, surfaceInsets.top);
+        }
+        if (mView instanceof SurfaceView) {
+            // If we copy content from a SurfaceView, clamp coordinates relative to it.
+            viewVisibleRegion.offset(-mViewCoordinatesInSurface[0], -mViewCoordinatesInSurface[1]);
+        }
+        mClampedCenterZoomCoords.x = Math.max(viewVisibleRegion.left + mBitmapWidth / 2, Math.min(
+                mCenterZoomCoords.x, viewVisibleRegion.right - mBitmapWidth / 2));
+        mClampedCenterZoomCoords.y = mCenterZoomCoords.y;
+    }
+
+    private void obtainWindowCoordinates() {
         // Compute the position of the magnifier window. Again, this has to be relative to the
         // surface of the magnified view, as this surface is the parent of the magnifier surface.
         final int verticalOffset = mView.getContext().getResources().getDimensionPixelSize(
                 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];
-            }
+        if (mParentSurface != mContentCopySurface) {
+            mWindowCoords.x += mViewCoordinatesInSurface[0];
+            mWindowCoords.y += mViewCoordinatesInSurface[1];
         }
     }
 
     private void performPixelCopy(final int startXInSurface, final int startYInSurface,
             final boolean updateWindowPosition) {
-        // Get the view surface where the content will be copied from.
-        final Surface surface;
-        final int surfaceWidth;
-        final int surfaceHeight;
-        if (mView instanceof SurfaceView) {
-            final SurfaceHolder surfaceHolder = ((SurfaceView) mView).getHolder();
-            surface = surfaceHolder.getSurface();
-            surfaceWidth = surfaceHolder.getSurfaceFrame().right;
-            surfaceHeight = surfaceHolder.getSurfaceFrame().bottom;
-        } else if (mView.getViewRootImpl() != null) {
-            final ViewRootImpl viewRootImpl = mView.getViewRootImpl();
-            surface = viewRootImpl.mSurface;
-            final Rect surfaceInsets = viewRootImpl.mWindowAttributes.surfaceInsets;
-            surfaceWidth = viewRootImpl.getWidth() + surfaceInsets.left + surfaceInsets.right;
-            surfaceHeight = viewRootImpl.getHeight() + surfaceInsets.top + surfaceInsets.bottom;
-        } else {
-            surface = null;
-            surfaceWidth = NONEXISTENT_PREVIOUS_CONFIG_VALUE;
-            surfaceHeight = NONEXISTENT_PREVIOUS_CONFIG_VALUE;
-        }
-
-        if (surface == null || !surface.isValid()) {
+        if (mContentCopySurface.mSurface == null || !mContentCopySurface.mSurface.isValid()) {
             return;
         }
-
         // Clamp copy coordinates inside the surface to avoid displaying distorted content.
         final int clampedStartXInSurface = Math.max(0,
-                Math.min(startXInSurface, surfaceWidth - mBitmapWidth));
+                Math.min(startXInSurface, mContentCopySurface.mWidth - mBitmapWidth));
         final int clampedStartYInSurface = Math.max(0,
-                Math.min(startYInSurface, surfaceHeight - mBitmapHeight));
+                Math.min(startYInSurface, mContentCopySurface.mHeight - mBitmapHeight));
 
         // Clamp window coordinates inside the parent surface, to avoid displaying
         // the magnifier out of screen or overlapping with system insets.
-        Rect windowBounds = null;
-        if (mView.getViewRootImpl() != null) {
-            // TODO: deduplicate against the first part of #getValidParentSurfaceForMagnifier()
-            // TODO: deduplicate against the first part of the current method
-            final ViewRootImpl viewRootImpl = mView.getViewRootImpl();
-            final Surface parentSurface = viewRootImpl.mSurface;
-            final Rect surfaceInsets = viewRootImpl.mWindowAttributes.surfaceInsets;
-            final int parentWidth =
-                    viewRootImpl.getWidth() + surfaceInsets.left + surfaceInsets.right;
-            final int parentHeight =
-                    viewRootImpl.getHeight() + surfaceInsets.top + surfaceInsets.bottom;
-            if (parentSurface != null && parentSurface.isValid()) {
-                final Rect systemInsets = mView.getRootWindowInsets().getSystemWindowInsets();
-                windowBounds = new Rect(systemInsets.left, systemInsets.top,
-                         parentWidth - systemInsets.right, parentHeight - systemInsets.bottom);
-            }
+        final Rect windowBounds;
+        if (mParentSurface.mIsMainWindowSurface) {
+            final Rect systemInsets = mView.getRootWindowInsets().getSystemWindowInsets();
+            windowBounds = new Rect(systemInsets.left, systemInsets.top,
+                     mParentSurface.mWidth - systemInsets.right,
+                    mParentSurface.mHeight - systemInsets.bottom);
+        } else {
+            windowBounds = new Rect(0, 0, mParentSurface.mWidth, mParentSurface.mHeight);
         }
-        if (windowBounds == null && mView instanceof SurfaceView) {
-            windowBounds = ((SurfaceView) mView).getHolder().getSurfaceFrame();
-        }
-
         final int windowCoordsX = Math.max(windowBounds.left,
                 Math.min(windowBounds.right - mWindowWidth, mWindowCoords.x));
         final int windowCoordsY = Math.max(windowBounds.top,
@@ -376,7 +376,7 @@
         final InternalPopupWindow currentWindowInstance = mWindow;
         final Bitmap bitmap =
                 Bitmap.createBitmap(mBitmapWidth, mBitmapHeight, Bitmap.Config.ARGB_8888);
-        PixelCopy.request(surface, mPixelCopyRequestRect, bitmap,
+        PixelCopy.request(mContentCopySurface.mSurface, mPixelCopyRequestRect, bitmap,
                 result -> {
                     synchronized (mLock) {
                         if (mWindow != currentWindowInstance) {
@@ -396,6 +396,26 @@
     }
 
     /**
+     * Contains a surface and metadata corresponding to it.
+     */
+    private static class SurfaceInfo {
+        public static final SurfaceInfo NULL = new SurfaceInfo(null, 0, 0, false);
+
+        private Surface mSurface;
+        private int mWidth;
+        private int mHeight;
+        private boolean mIsMainWindowSurface;
+
+        SurfaceInfo(final Surface surface, final int width, final int height,
+                final boolean isMainWindowSurface) {
+            mSurface = surface;
+            mWidth = width;
+            mHeight = height;
+            mIsMainWindowSurface = isMainWindowSurface;
+        }
+    }
+
+    /**
      * Magnifier's own implementation of PopupWindow-similar floating window.
      * This exists to ensure frame-synchronization between window position updates and window
      * content updates. By using a PopupWindow, these events would happen in different frames,
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index a075705..b591163 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -85,6 +85,14 @@
 
     protected abstract Uri buildNotificationUri(String docId);
 
+    /**
+     * Callback indicating that the given document has been modified. This gives
+     * the provider a hook to invalidate cached data, such as {@code sdcardfs}.
+     */
+    protected void onDocIdChanged(String docId) {
+        // Default is no-op
+    }
+
     @Override
     public boolean onCreate() {
         throw new UnsupportedOperationException(
@@ -185,6 +193,7 @@
                 throw new IllegalStateException("Failed to mkdir " + file);
             }
             childId = getDocIdForFile(file);
+            onDocIdChanged(childId);
             addFolderToMediaStore(getFileForDocId(childId, true));
         } else {
             try {
@@ -192,6 +201,7 @@
                     throw new IllegalStateException("Failed to touch " + file);
                 }
                 childId = getDocIdForFile(file);
+                onDocIdChanged(childId);
             } catch (IOException e) {
                 throw new IllegalStateException("Failed to touch " + file + ": " + e);
             }
@@ -227,16 +237,20 @@
 
         final File before = getFileForDocId(docId);
         final File after = FileUtils.buildUniqueFile(before.getParentFile(), displayName);
-        final File visibleFileBefore = getFileForDocId(docId, true);
         if (!before.renameTo(after)) {
             throw new IllegalStateException("Failed to rename to " + after);
         }
 
         final String afterDocId = getDocIdForFile(after);
-        moveInMediaStore(visibleFileBefore, getFileForDocId(afterDocId, true));
+        onDocIdChanged(docId);
+        onDocIdChanged(afterDocId);
+
+        final File beforeVisibleFile = getFileForDocId(docId, true);
+        final File afterVisibleFile = getFileForDocId(afterDocId, true);
+        moveInMediaStore(beforeVisibleFile, afterVisibleFile);
 
         if (!TextUtils.equals(docId, afterDocId)) {
-            scanFile(after);
+            scanFile(afterVisibleFile);
             return afterDocId;
         } else {
             return null;
@@ -259,6 +273,8 @@
         }
 
         final String docId = getDocIdForFile(after);
+        onDocIdChanged(sourceDocumentId);
+        onDocIdChanged(docId);
         moveInMediaStore(visibleFileBefore, getFileForDocId(docId, true));
 
         return docId;
@@ -308,6 +324,7 @@
             throw new IllegalStateException("Failed to delete " + file);
         }
 
+        onDocIdChanged(docId);
         removeFromMediaStore(visibleFile, isDirectory);
     }
 
@@ -418,7 +435,10 @@
             try {
                 // When finished writing, kick off media scanner
                 return ParcelFileDescriptor.open(
-                        file, pfdMode, mHandler, (IOException e) -> scanFile(visibleFile));
+                        file, pfdMode, mHandler, (IOException e) -> {
+                            onDocIdChanged(documentId);
+                            scanFile(visibleFile);
+                        });
             } catch (IOException e) {
                 throw new FileNotFoundException("Failed to open for writing: " + e);
             }
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index a1e6fd8..c388148 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -282,7 +282,10 @@
         }
     }
 
-    private static void createNativeLibrarySubdir(File path) throws IOException {
+    /**
+     * @hide
+     */
+    public static void createNativeLibrarySubdir(File path) throws IOException {
         if (!path.isDirectory()) {
             path.delete();
 
diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java
index 98afebc5..c4d08c7 100644
--- a/core/java/com/android/internal/net/NetworkStatsFactory.java
+++ b/core/java/com/android/internal/net/NetworkStatsFactory.java
@@ -56,8 +56,6 @@
     private static final boolean USE_NATIVE_PARSING = true;
     private static final boolean SANITY_CHECK_NATIVE = false;
 
-    /** Path to {@code /proc/net/dev}. */
-    private final File mStatsIfaceDev;
     /** Path to {@code /proc/net/xt_qtaguid/iface_stat_all}. */
     private final File mStatsXtIfaceAll;
     /** Path to {@code /proc/net/xt_qtaguid/iface_stat_fmt}. */
@@ -133,47 +131,16 @@
 
     @VisibleForTesting
     public NetworkStatsFactory(File procRoot, boolean useBpfStats) {
-        mStatsIfaceDev = new File(procRoot, "net/dev");
         mStatsXtIfaceAll = new File(procRoot, "net/xt_qtaguid/iface_stat_all");
         mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt");
         mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
         mUseBpfStats = useBpfStats;
     }
 
-    @VisibleForTesting
-    public NetworkStats readNetworkStatsIfaceDev() throws IOException {
-        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
-
+    public NetworkStats readBpfNetworkStatsDev() throws IOException {
         final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
-        final NetworkStats.Entry entry = new NetworkStats.Entry();
-
-        BufferedReader reader = null;
-        try {
-            reader = new BufferedReader(new FileReader(mStatsIfaceDev));
-
-            // skip first two header lines
-            reader.readLine();
-            reader.readLine();
-
-            // parse remaining lines
-            String line;
-            while ((line = reader.readLine()) != null) {
-                String[] values = line.trim().split("\\:?\\s+");
-                entry.iface = values[0];
-                entry.uid = UID_ALL;
-                entry.set = SET_ALL;
-                entry.tag = TAG_NONE;
-                entry.rxBytes = Long.parseLong(values[1]);
-                entry.rxPackets = Long.parseLong(values[2]);
-                entry.txBytes = Long.parseLong(values[9]);
-                entry.txPackets = Long.parseLong(values[10]);
-                stats.addValues(entry);
-            }
-        } catch (NullPointerException|NumberFormatException e) {
-            throw new ProtocolException("problem parsing stats", e);
-        } finally {
-            IoUtils.closeQuietly(reader);
-            StrictMode.setThreadPolicy(savedPolicy);
+        if (nativeReadNetworkStatsDev(stats) != 0) {
+            throw new IOException("Failed to parse bpf iface stats");
         }
         return stats;
     }
@@ -188,9 +155,9 @@
      */
     public NetworkStats readNetworkStatsSummaryDev() throws IOException {
 
-        // Return the stats get from /proc/net/dev if switched to bpf module.
+        // Return xt_bpf stats if switched to bpf module.
         if (mUseBpfStats)
-            return readNetworkStatsIfaceDev();
+            return readBpfNetworkStatsDev();
 
         final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
 
@@ -244,9 +211,9 @@
      */
     public NetworkStats readNetworkStatsSummaryXt() throws IOException {
 
-        // Return the stats get from /proc/net/dev if qtaguid  module is replaced.
+        // Return xt_bpf stats if qtaguid  module is replaced.
         if (mUseBpfStats)
-            return readNetworkStatsIfaceDev();
+            return readBpfNetworkStatsDev();
 
         final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
 
@@ -408,4 +375,7 @@
     @VisibleForTesting
     public static native int nativeReadNetworkStatsDetail(NetworkStats stats, String path,
         int limitUid, String[] limitIfaces, int limitTag, boolean useBpfStats);
+
+    @VisibleForTesting
+    public static native int nativeReadNetworkStatsDev(NetworkStats stats);
 }
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index cc95df7..2db5739 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -308,10 +308,8 @@
     public void onDraw(Canvas c) {
         super.onDraw(c);
 
-        // When we are resizing, we need the fallback background to cover the area where we have our
-        // system bar background views as the navigation bar will be hidden during resizing.
-        mBackgroundFallback.draw(isResizing() ? this : mContentRoot, mContentRoot, c,
-                mWindow.mContentParent);
+        mBackgroundFallback.draw(this, mContentRoot, c, mWindow.mContentParent,
+                mStatusColorViewState.view, mNavigationColorViewState.view);
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/BackgroundFallback.java b/core/java/com/android/internal/widget/BackgroundFallback.java
index 309f80c..2b05f1e 100644
--- a/core/java/com/android/internal/widget/BackgroundFallback.java
+++ b/core/java/com/android/internal/widget/BackgroundFallback.java
@@ -46,8 +46,11 @@
      * @param root The view group containing the content.
      * @param c The canvas to draw the background onto.
      * @param content The view where the actual app content is contained in.
+     * @param coveringView1 A potentially opaque view drawn atop the content
+     * @param coveringView2 A potentially opaque view drawn atop the content
      */
-    public void draw(ViewGroup boundsView, ViewGroup root, Canvas c, View content) {
+    public void draw(ViewGroup boundsView, ViewGroup root, Canvas c, View content,
+            View coveringView1, View coveringView2) {
         if (!hasFallback()) {
             return;
         }
@@ -55,6 +58,10 @@
         // Draw the fallback in the padding.
         final int width = boundsView.getWidth();
         final int height = boundsView.getHeight();
+
+        final int rootOffsetX = root.getLeft();
+        final int rootOffsetY = root.getTop();
+
         int left = width;
         int top = height;
         int right = 0;
@@ -71,17 +78,58 @@
                         ((ViewGroup) child).getChildCount() == 0) {
                     continue;
                 }
-            } else if (child.getVisibility() != View.VISIBLE || childBg == null ||
-                    childBg.getOpacity() != PixelFormat.OPAQUE) {
+            } else if (child.getVisibility() != View.VISIBLE || !isOpaque(childBg)) {
                 // Potentially translucent or invisible children don't count, and we assume
                 // the content view will cover the whole area if we're in a background
                 // fallback situation.
                 continue;
             }
-            left = Math.min(left, child.getLeft());
-            top = Math.min(top, child.getTop());
-            right = Math.max(right, child.getRight());
-            bottom = Math.max(bottom, child.getBottom());
+            left = Math.min(left, rootOffsetX + child.getLeft());
+            top = Math.min(top, rootOffsetY + child.getTop());
+            right = Math.max(right, rootOffsetX + child.getRight());
+            bottom = Math.max(bottom, rootOffsetY + child.getBottom());
+        }
+
+        // If one of the bar backgrounds is a solid color and covers the entire padding on a side
+        // we can drop that padding.
+        boolean eachBarCoversTopInY = true;
+        for (int i = 0; i < 2; i++) {
+            View v = (i == 0) ? coveringView1 : coveringView2;
+            if (v == null || v.getVisibility() != View.VISIBLE
+                    || v.getAlpha() != 1f || !isOpaque(v.getBackground())) {
+                eachBarCoversTopInY = false;
+                continue;
+            }
+
+            // Bar covers entire left padding
+            if (v.getTop() <= 0 && v.getBottom() >= height
+                    && v.getLeft() <= 0 && v.getRight() >= left) {
+                left = 0;
+            }
+            // Bar covers entire right padding
+            if (v.getTop() <= 0 && v.getBottom() >= height
+                    && v.getLeft() <= right && v.getRight() >= width) {
+                right = width;
+            }
+            // Bar covers entire top padding
+            if (v.getTop() <= 0 && v.getBottom() >= top
+                    && v.getLeft() <= 0 && v.getRight() >= width) {
+                top = 0;
+            }
+            // Bar covers entire bottom padding
+            if (v.getTop() <= bottom && v.getBottom() >= height
+                    && v.getLeft() <= 0 && v.getRight() >= width) {
+                bottom = height;
+            }
+
+            eachBarCoversTopInY &= v.getTop() <= 0 && v.getBottom() >= top;
+        }
+
+        // Special case: Sometimes, both covering views together may cover the top inset, but
+        // neither does on its own.
+        if (eachBarCoversTopInY && (viewsCoverEntireWidth(coveringView1, coveringView2, width)
+                || viewsCoverEntireWidth(coveringView2, coveringView1, width))) {
+            top = 0;
         }
 
         if (left >= right || top >= bottom) {
@@ -106,4 +154,24 @@
             mBackgroundFallback.draw(c);
         }
     }
+
+    private boolean isOpaque(Drawable childBg) {
+        return childBg != null && childBg.getOpacity() == PixelFormat.OPAQUE;
+    }
+
+    /**
+     * Returns true if {@code view1} starts before or on {@code 0} and extends at least
+     * up to {@code view2}, and that view extends at least to {@code width}.
+     *
+     * @param view1 the first view to check if it covers the width
+     * @param view2 the second view to check if it covers the width
+     * @param width the width to check for
+     * @return returns true if both views together cover the entire width (and view1 is to the left
+     *         of view2)
+     */
+    private boolean viewsCoverEntireWidth(View view1, View view2, int width) {
+        return view1.getLeft() <= 0
+                && view1.getRight() >= view2.getLeft()
+                && view2.getRight() >= width;
+    }
 }
diff --git a/core/java/com/android/internal/widget/ImageFloatingTextView.java b/core/java/com/android/internal/widget/ImageFloatingTextView.java
index 1e7c11e..e143498 100644
--- a/core/java/com/android/internal/widget/ImageFloatingTextView.java
+++ b/core/java/com/android/internal/widget/ImageFloatingTextView.java
@@ -28,8 +28,6 @@
 import android.widget.RemoteViews;
 import android.widget.TextView;
 
-import com.android.internal.R;
-
 /**
  * A TextView that can float around an image on the end.
  *
@@ -44,9 +42,7 @@
     /** Resolved layout direction */
     private int mResolvedDirection = LAYOUT_DIRECTION_UNDEFINED;
     private int mMaxLinesForHeight = -1;
-    private boolean mFirstMeasure = true;
     private int mLayoutMaxLines = -1;
-    private boolean mBlockLayouts;
     private int mImageEndMargin;
 
     public ImageFloatingTextView(Context context) {
@@ -122,30 +118,31 @@
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int height = MeasureSpec.getSize(heightMeasureSpec);
-        // Lets calculate how many lines the given measurement allows us.
-        int availableHeight = height - mPaddingTop - mPaddingBottom;
-        int maxLines = availableHeight / getLineHeight();
-        maxLines = Math.max(1, maxLines);
-        if (getMaxLines() > 0) {
-            maxLines = Math.min(getMaxLines(), maxLines);
-        }
-        if (maxLines != mMaxLinesForHeight) {
-            mMaxLinesForHeight = maxLines;
-            if (getLayout() != null && mMaxLinesForHeight != mLayoutMaxLines) {
-                // Invalidate layout.
-                mBlockLayouts = true;
-                setHint(getHint());
-                mBlockLayouts = false;
-            }
+        int availableHeight = MeasureSpec.getSize(heightMeasureSpec) - mPaddingTop - mPaddingBottom;
+        if (getLayout() != null && getLayout().getHeight() != availableHeight) {
+            // We've been measured before and the new size is different than before, lets make sure
+            // we reset the maximum lines, otherwise we may be cut short
+            mMaxLinesForHeight = -1;
+            nullLayouts();
         }
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-    }
-
-    @Override
-    public void requestLayout() {
-        if (!mBlockLayouts) {
-            super.requestLayout();
+        Layout layout = getLayout();
+        if (layout.getHeight() > availableHeight) {
+            // With the existing layout, not all of our lines fit on the screen, let's find the
+            // first one that fits and ellipsize at that one.
+            int maxLines = layout.getLineCount() - 1;
+            while (maxLines > 1 && layout.getLineBottom(maxLines - 1) > availableHeight) {
+                maxLines--;
+            }
+            if (getMaxLines() > 0) {
+                maxLines = Math.min(getMaxLines(), maxLines);
+            }
+            // Only if the number of lines is different from the current layout, we recreate it.
+            if (maxLines != mLayoutMaxLines) {
+                mMaxLinesForHeight = maxLines;
+                nullLayouts();
+                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+            }
         }
     }
 
@@ -157,7 +154,8 @@
             mResolvedDirection = layoutDirection;
             if (mIndentLines > 0) {
                 // Invalidate layout.
-                setHint(getHint());
+                nullLayouts();
+                requestLayout();
             }
         }
     }
@@ -175,7 +173,8 @@
         if (mIndentLines != lines) {
             mIndentLines = lines;
             // Invalidate layout.
-            setHint(getHint());
+            nullLayouts();
+            requestLayout();
             return true;
         }
         return false;
diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java
index 4104b6ca9d..15b2718 100644
--- a/core/java/com/android/internal/widget/MessagingGroup.java
+++ b/core/java/com/android/internal/widget/MessagingGroup.java
@@ -276,9 +276,16 @@
         boolean hasNormal = false;
         for (int i = mMessageContainer.getChildCount() - 1; i >= 0; i--) {
             View child = mMessageContainer.getChildAt(i);
+            if (child.getVisibility() == GONE) {
+                continue;
+            }
             if (child instanceof MessagingLinearLayout.MessagingChild) {
                 int type = ((MessagingLinearLayout.MessagingChild) child).getMeasuredType();
-                if (type == MEASURED_TOO_SMALL) {
+                boolean tooSmall = type == MEASURED_TOO_SMALL;
+                final MessagingLinearLayout.LayoutParams lp =
+                        (MessagingLinearLayout.LayoutParams) child.getLayoutParams();
+                tooSmall |= lp.hide;
+                if (tooSmall) {
                     if (hasNormal) {
                         return MEASURED_SHORTENED;
                     } else {
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
index 99d9839..c15b7ee 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -205,37 +205,8 @@
     return 0;
 }
 
-static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, jstring path,
-                                  jint limitUid, jobjectArray limitIfacesObj, jint limitTag,
-                                  jboolean useBpfStats) {
-    ScopedUtfChars path8(env, path);
-    if (path8.c_str() == NULL) {
-        return -1;
-    }
-
-    std::vector<std::string> limitIfaces;
-    if (limitIfacesObj != NULL && env->GetArrayLength(limitIfacesObj) > 0) {
-        int num = env->GetArrayLength(limitIfacesObj);
-        for (int i = 0; i < num; i++) {
-            jstring string = (jstring)env->GetObjectArrayElement(limitIfacesObj, i);
-            ScopedUtfChars string8(env, string);
-            if (string8.c_str() != NULL) {
-                limitIfaces.push_back(std::string(string8.c_str()));
-            }
-        }
-    }
-    std::vector<stats_line> lines;
-
-
-    if (useBpfStats) {
-        if (parseBpfNetworkStatsDetail(&lines, limitIfaces, limitTag, limitUid) < 0)
-            return -1;
-    } else {
-        if (legacyReadNetworkStatsDetail(&lines, limitIfaces, limitTag,
-                                         limitUid, path8.c_str()) < 0)
-            return -1;
-    }
-
+static int statsLinesToNetworkStats(JNIEnv* env, jclass clazz, jobject stats,
+                            std::vector<stats_line>& lines) {
     int size = lines.size();
 
     bool grow = size > env->GetIntField(stats, gNetworkStatsClassInfo.capacity);
@@ -308,14 +279,58 @@
         env->SetObjectField(stats, gNetworkStatsClassInfo.txPackets, txPackets.getJavaArray());
         env->SetObjectField(stats, gNetworkStatsClassInfo.operations, operations.getJavaArray());
     }
-
     return 0;
 }
 
+static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, jstring path,
+                                  jint limitUid, jobjectArray limitIfacesObj, jint limitTag,
+                                  jboolean useBpfStats) {
+    ScopedUtfChars path8(env, path);
+    if (path8.c_str() == NULL) {
+        return -1;
+    }
+
+    std::vector<std::string> limitIfaces;
+    if (limitIfacesObj != NULL && env->GetArrayLength(limitIfacesObj) > 0) {
+        int num = env->GetArrayLength(limitIfacesObj);
+        for (int i = 0; i < num; i++) {
+            jstring string = (jstring)env->GetObjectArrayElement(limitIfacesObj, i);
+            ScopedUtfChars string8(env, string);
+            if (string8.c_str() != NULL) {
+                limitIfaces.push_back(std::string(string8.c_str()));
+            }
+        }
+    }
+    std::vector<stats_line> lines;
+
+
+    if (useBpfStats) {
+        if (parseBpfNetworkStatsDetail(&lines, limitIfaces, limitTag, limitUid) < 0)
+            return -1;
+    } else {
+        if (legacyReadNetworkStatsDetail(&lines, limitIfaces, limitTag,
+                                         limitUid, path8.c_str()) < 0)
+            return -1;
+    }
+
+    return statsLinesToNetworkStats(env, clazz, stats, lines);
+}
+
+static int readNetworkStatsDev(JNIEnv* env, jclass clazz, jobject stats) {
+    std::vector<stats_line> lines;
+
+    if (parseBpfNetworkStatsDev(&lines) < 0)
+            return -1;
+
+    return statsLinesToNetworkStats(env, clazz, stats, lines);
+}
+
 static const JNINativeMethod gMethods[] = {
         { "nativeReadNetworkStatsDetail",
                 "(Landroid/net/NetworkStats;Ljava/lang/String;I[Ljava/lang/String;IZ)I",
-                (void*) readNetworkStatsDetail }
+                (void*) readNetworkStatsDetail },
+        { "nativeReadNetworkStatsDev", "(Landroid/net/NetworkStats;)I",
+                (void*) readNetworkStatsDev },
 };
 
 int register_com_android_internal_net_NetworkStatsFactory(JNIEnv* env) {
diff --git a/core/proto/android/app/notification_channel.proto b/core/proto/android/app/notification_channel.proto
index 337aa1c..d3808e8 100644
--- a/core/proto/android/app/notification_channel.proto
+++ b/core/proto/android/app/notification_channel.proto
@@ -53,4 +53,5 @@
     optional android.media.AudioAttributesProto audio_attributes = 16;
     // If this is a blockable system notification channel.
     optional bool is_blockable_system = 17;
+    optional bool fg_service_shown = 18;
 }
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 503bd21..64e1239 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -161,6 +161,7 @@
 
     optional CpuFreqProto cpu_freq = 2004 [
         (section).type = SECTION_FILE,
+        (section).device_specific = true,
         (section).args = "/sys/devices/system/cpu/cpufreq/all_time_in_state"
     ];
 
@@ -170,7 +171,8 @@
     ];
 
     optional BatteryTypeProto battery_type = 2006 [
-        (section).type = SECTION_NONE, // disabled since the path is device specific!
+        (section).type = SECTION_FILE,
+        (section).device_specific = true,
         (section).args = "/sys/class/power_supply/bms/battery_type"
     ];
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 92560f3..1f8d43c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -840,6 +840,77 @@
         android:protectionLevel="dangerous|instant" />
 
     <!-- ====================================================================== -->
+    <!-- Permissions for accessing the call log                                 -->
+    <!-- ====================================================================== -->
+    <eat-comment />
+
+    <!-- Used for permissions that are associated telephony features. -->
+    <permission-group android:name="android.permission-group.CALL_LOG"
+        android:icon="@drawable/perm_group_phone_calls"
+        android:label="@string/permgrouplab_calllog"
+        android:description="@string/permgroupdesc_calllog"
+        android:request="@string/permgrouprequest_calllog"
+        android:priority="450" />
+
+    <!-- Allows an application to access the IMS call service: making and
+         modifying a call
+        <p>Protection level: signature|privileged
+        @hide
+    -->
+    <permission android:name="android.permission.ACCESS_IMS_CALL_SERVICE"
+        android:label="@string/permlab_accessImsCallService"
+        android:description="@string/permdesc_accessImsCallService"
+        android:protectionLevel="signature|privileged" />
+
+    <!-- Allows an application to read the user's call log.
+         <p class="note"><strong>Note:</strong> If your app uses the
+         {@link #READ_CONTACTS} permission and <em>both</em> your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+         minSdkVersion}</a> and <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
+         grants your app this permission. If you don't need this permission, be sure your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> is 16 or higher.</p>
+         <p>Protection level: dangerous
+    -->
+    <permission android:name="android.permission.READ_CALL_LOG"
+        android:permissionGroup="android.permission-group.CALL_LOG"
+        android:label="@string/permlab_readCallLog"
+        android:description="@string/permdesc_readCallLog"
+        android:protectionLevel="dangerous" />
+
+    <!-- Allows an application to write (but not read) the user's
+         call log data.
+         <p class="note"><strong>Note:</strong> If your app uses the
+         {@link #WRITE_CONTACTS} permission and <em>both</em> your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+         minSdkVersion}</a> and <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
+         grants your app this permission. If you don't need this permission, be sure your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> is 16 or higher.</p>
+         <p>Protection level: dangerous
+    -->
+    <permission android:name="android.permission.WRITE_CALL_LOG"
+        android:permissionGroup="android.permission-group.CALL_LOG"
+        android:label="@string/permlab_writeCallLog"
+        android:description="@string/permdesc_writeCallLog"
+        android:protectionLevel="dangerous" />
+
+    <!-- Allows an application to see the number being dialed during an outgoing
+         call with the option to redirect the call to a different number or
+         abort the call altogether.
+         <p>Protection level: dangerous
+    -->
+    <permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
+        android:permissionGroup="android.permission-group.CALL_LOG"
+        android:label="@string/permlab_processOutgoingCalls"
+        android:description="@string/permdesc_processOutgoingCalls"
+        android:protectionLevel="dangerous" />
+
+    <!-- ====================================================================== -->
     <!-- Permissions for accessing the device telephony                         -->
     <!-- ====================================================================== -->
     <eat-comment />
@@ -891,54 +962,6 @@
         android:description="@string/permdesc_callPhone"
         android:protectionLevel="dangerous" />
 
-    <!-- Allows an application to access the IMS call service: making and
-         modifying a call
-        <p>Protection level: signature|privileged
-        @hide
-    -->
-    <permission android:name="android.permission.ACCESS_IMS_CALL_SERVICE"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:label="@string/permlab_accessImsCallService"
-        android:description="@string/permdesc_accessImsCallService"
-        android:protectionLevel="signature|privileged" />
-
-    <!-- Allows an application to read the user's call log.
-         <p class="note"><strong>Note:</strong> If your app uses the
-         {@link #READ_CONTACTS} permission and <em>both</em> your <a
-         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
-         minSdkVersion}</a> and <a
-         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-         targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
-         grants your app this permission. If you don't need this permission, be sure your <a
-         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-         targetSdkVersion}</a> is 16 or higher.</p>
-         <p>Protection level: dangerous
-    -->
-    <permission android:name="android.permission.READ_CALL_LOG"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:label="@string/permlab_readCallLog"
-        android:description="@string/permdesc_readCallLog"
-        android:protectionLevel="dangerous" />
-
-    <!-- Allows an application to write (but not read) the user's
-         call log data.
-         <p class="note"><strong>Note:</strong> If your app uses the
-         {@link #WRITE_CONTACTS} permission and <em>both</em> your <a
-         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
-         minSdkVersion}</a> and <a
-         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-         targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
-         grants your app this permission. If you don't need this permission, be sure your <a
-         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-         targetSdkVersion}</a> is 16 or higher.</p>
-         <p>Protection level: dangerous
-    -->
-    <permission android:name="android.permission.WRITE_CALL_LOG"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:label="@string/permlab_writeCallLog"
-        android:description="@string/permdesc_writeCallLog"
-        android:protectionLevel="dangerous" />
-
     <!-- Allows an application to add voicemails into the system.
          <p>Protection level: dangerous
     -->
@@ -957,18 +980,6 @@
         android:label="@string/permlab_use_sip"
         android:protectionLevel="dangerous"/>
 
-    <!-- Allows an application to see the number being dialed during an outgoing
-         call with the option to redirect the call to a different number or
-         abort the call altogether.
-         <p>Protection level: dangerous
-    -->
-    <permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:label="@string/permlab_processOutgoingCalls"
-        android:description="@string/permdesc_processOutgoingCalls"
-        android:protectionLevel="dangerous" />
-
-
     <!-- Allows the app to answer an incoming phone call.
          <p>Protection level: dangerous
     -->
diff --git a/core/res/res/anim-ldrtl/cross_profile_apps_thumbnail_enter.xml b/core/res/res/anim-ldrtl/cross_profile_apps_thumbnail_enter.xml
new file mode 100644
index 0000000..6f3dc8c
--- /dev/null
+++ b/core/res/res/anim-ldrtl/cross_profile_apps_thumbnail_enter.xml
@@ -0,0 +1,76 @@
+<?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.
+*/
+-->
+<!-- This should be kept in sync with task_open_enter.xml -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false" android:zAdjustment="top">
+
+    <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 thumbnail around longer and fade out the thumbnail -->
+    <alpha android:fromAlpha="1.0" android:toAlpha="0"
+           android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+           android:interpolator="@interpolator/decelerate_quint"
+           android:startOffset="717"
+           android:duration="200"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/cross_profile_apps_thumbnail_enter.xml b/core/res/res/anim/cross_profile_apps_thumbnail_enter.xml
index 6f3dc8c..4c2559f 100644
--- a/core/res/res/anim/cross_profile_apps_thumbnail_enter.xml
+++ b/core/res/res/anim/cross_profile_apps_thumbnail_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/layout/magnifier.xml b/core/res/res/layout/magnifier.xml
deleted file mode 100644
index f3344c7..0000000
--- a/core/res/res/layout/magnifier.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ 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
-  -->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content">
-    <LinearLayout
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:id="@+id/magnifier_inner"
-        android:layout_width="@android:dimen/magnifier_width"
-        android:layout_height="@android:dimen/magnifier_height"
-        android:elevation="@android:dimen/magnifier_elevation"
-        android:background="?android:attr/floatingToolbarPopupBackgroundDrawable"
-        android:scaleType="fitXY">
-        <ImageView
-            android:id="@+id/magnifier_image"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent" />
-    </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 d1861d9..26eb4e7 100644
--- a/core/res/res/layout/notification_template_material_big_text.xml
+++ b/core/res/res/layout/notification_template_material_big_text.xml
@@ -24,7 +24,7 @@
     >
     <include layout="@layout/notification_template_header" />
 
-    <LinearLayout
+    <com.android.internal.widget.RemeasuringLinearLayout
             android:id="@+id/notification_action_list_margin_target"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
@@ -34,7 +34,7 @@
             android:clipToPadding="false"
             android:orientation="vertical">
 
-        <LinearLayout
+        <com.android.internal.widget.RemeasuringLinearLayout
             android:id="@+id/notification_main_column"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
@@ -62,7 +62,7 @@
                 android:visibility="gone"
                 android:textAlignment="viewStart"
                 />
-        </LinearLayout>
+        </com.android.internal.widget.RemeasuringLinearLayout>
 
         <ViewStub android:layout="@layout/notification_material_reply_text"
                 android:id="@+id/notification_material_reply_container"
@@ -75,6 +75,6 @@
                 android:layout_marginEnd="@dimen/notification_content_margin_end"
                 android:layout_marginTop="@dimen/notification_content_margin" />
         <include layout="@layout/notification_material_action_list" />
-    </LinearLayout>
+    </com.android.internal.widget.RemeasuringLinearLayout>
     <include layout="@layout/notification_template_right_icon" />
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_messaging_group.xml b/core/res/res/layout/notification_template_messaging_group.xml
index 08f8f57..0717d96 100644
--- a/core/res/res/layout/notification_template_messaging_group.xml
+++ b/core/res/res/layout/notification_template_messaging_group.xml
@@ -36,6 +36,7 @@
             android:id="@+id/message_name"
             style="@style/Widget.Material.Notification.MessagingName"
             android:layout_width="wrap_content"
+            android:textAlignment="viewStart"
         />
         <com.android.internal.widget.MessagingLinearLayout
             android:id="@+id/group_message_container"
diff --git a/core/res/res/layout/notification_template_messaging_text_message.xml b/core/res/res/layout/notification_template_messaging_text_message.xml
index e728e69..3611186 100644
--- a/core/res/res/layout/notification_template_messaging_text_message.xml
+++ b/core/res/res/layout/notification_template_messaging_text_message.xml
@@ -17,5 +17,6 @@
 <com.android.internal.widget.MessagingTextMessage
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/message_text"
+    android:textAlignment="viewStart"
     style="@style/Widget.Material.Notification.MessagingText"
 />
diff --git a/core/res/res/values-mcc405/config.xml b/core/res/res/values-mcc405/config.xml
index 6b77e9c..4cadef7 100644
--- a/core/res/res/values-mcc405/config.xml
+++ b/core/res/res/values-mcc405/config.xml
@@ -20,4 +20,6 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Whether camera shutter sound is forced or not  (country specific). -->
     <bool name="config_camera_sound_forced">true</bool>
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">true</bool>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index c7b65ef..791f7c6 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -247,7 +247,7 @@
     <dimen name="notification_header_shrink_min_width">72dp</dimen>
 
     <!-- The minimum height of the content if there are at least two lines or a picture-->
-    <dimen name="notification_min_content_height">41dp</dimen>
+    <dimen name="notification_min_content_height">39dp</dimen>
 
     <!-- The size of the media actions in the media notification. -->
     <dimen name="media_notification_action_button_size">48dp</dimen>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b92052b..bf7ca52 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -724,6 +724,14 @@
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to take pictures and record video?</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permgrouplab_calllog">Call logs</string>
+    <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permgroupdesc_calllog">read and write phone call log</string>
+    <!-- Message shown to the user when the apps requests permission from this group -->
+    <string name="permgrouprequest_calllog">Allow
+        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your phone call logs?</string>
+
+    <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_phone">Phone</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_phone">make and manage phone calls</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c3ab1a6..5edafec 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2587,9 +2587,6 @@
   <java-symbol type="attr" name="floatingToolbarDividerColor" />
 
   <!-- Magnifier -->
-  <java-symbol type="id" name="magnifier_image" />
-  <java-symbol type="id" name="magnifier_inner" />
-  <java-symbol type="layout" name="magnifier" />
   <java-symbol type="dimen" name="magnifier_width" />
   <java-symbol type="dimen" name="magnifier_height" />
   <java-symbol type="dimen" name="magnifier_elevation" />
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index 9ef58ab..1750dac 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -16,7 +16,11 @@
 
 package android.app.activity;
 
+import static android.content.Intent.ACTION_EDIT;
+import static android.content.Intent.ACTION_VIEW;
+
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import android.app.Activity;
 import android.app.ActivityThread;
@@ -27,6 +31,7 @@
 import android.app.servertransaction.ResumeActivityItem;
 import android.app.servertransaction.StopActivityItem;
 import android.content.Intent;
+import android.os.IBinder;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.rule.ActivityTestRule;
@@ -94,6 +99,36 @@
         });
     }
 
+    /** Verify that custom intent set via Activity#setIntent() is preserved on relaunch. */
+    @Test
+    public void testCustomIntentPreservedOnRelaunch() throws Exception {
+        final Intent initIntent = new Intent();
+        initIntent.setAction(ACTION_VIEW);
+        final Activity activity = mActivityTestRule.launchActivity(initIntent);
+        IBinder token = activity.getActivityToken();
+
+        final ActivityThread activityThread = activity.getActivityThread();
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+            // Recreate and check that intent is still the same.
+            activity.recreate();
+
+            final Activity newActivity = activityThread.getActivity(token);
+            assertTrue("Original intent must be preserved after recreate",
+                    initIntent.filterEquals(newActivity.getIntent()));
+
+            // Set custom intent, recreate and check if it is preserved.
+            final Intent customIntent = new Intent();
+            customIntent.setAction(ACTION_EDIT);
+            newActivity.setIntent(customIntent);
+
+            activity.recreate();
+
+            final Activity lastActivity = activityThread.getActivity(token);
+            assertTrue("Custom intent must be preserved after recreate",
+                    customIntent.filterEquals(lastActivity.getIntent()));
+        });
+    }
+
     private static ClientTransaction newRelaunchResumeTransaction(Activity activity) {
         final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(null,
                 null, 0, new MergedConfiguration(), false /* preserveWindow */);
diff --git a/core/tests/coretests/src/com/android/internal/widget/BackgroundFallbackTest.java b/core/tests/coretests/src/com/android/internal/widget/BackgroundFallbackTest.java
new file mode 100644
index 0000000..e21143d
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/widget/BackgroundFallbackTest.java
@@ -0,0 +1,262 @@
+/*
+ * 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.internal.widget;
+
+import static android.view.View.VISIBLE;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.support.test.InstrumentationRegistry;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+public class BackgroundFallbackTest {
+
+    private static final int NAVBAR_BOTTOM = 0;
+    private static final int NAVBAR_LEFT = 1;
+    private static final int NAVBAR_RIGHT = 2;
+
+    private static final int SCREEN_HEIGHT = 2000;
+    private static final int SCREEN_WIDTH = 1000;
+    private static final int STATUS_HEIGHT = 100;
+    private static final int NAV_SIZE = 200;
+
+    private static final boolean INSET_CONTENT_VIEWS = true;
+    private static final boolean DONT_INSET_CONTENT_VIEWS = false;
+
+    BackgroundFallback mFallback;
+    Drawable mDrawableMock;
+
+    ViewGroup mStatusBarView;
+    ViewGroup mNavigationBarView;
+
+    ViewGroup mDecorViewMock;
+    ViewGroup mContentRootMock;
+    ViewGroup mContentContainerMock;
+    ViewGroup mContentMock;
+
+    int mLastTop = 0;
+
+    @Before
+    public void setUp() throws Exception {
+        mFallback = new BackgroundFallback();
+        mDrawableMock = mock(Drawable.class);
+
+        mFallback.setDrawable(mDrawableMock);
+
+    }
+
+    @Test
+    public void hasFallback_withDrawable_true() {
+        mFallback.setDrawable(mDrawableMock);
+        assertThat(mFallback.hasFallback(), is(true));
+    }
+
+    @Test
+    public void hasFallback_withoutDrawable_false() {
+        mFallback.setDrawable(null);
+        assertThat(mFallback.hasFallback(), is(false));
+    }
+
+    @Test
+    public void draw_portrait_noFallback() {
+        setUpViewHierarchy(INSET_CONTENT_VIEWS, NAVBAR_BOTTOM);
+
+        mFallback.draw(mDecorViewMock, mContentRootMock, null /* canvas */, mContentContainerMock,
+                mStatusBarView, mNavigationBarView);
+
+        verifyNoMoreInteractions(mDrawableMock);
+    }
+
+    @Test
+    public void draw_portrait_translucentBars_fallback() {
+        setUpViewHierarchy(INSET_CONTENT_VIEWS, NAVBAR_BOTTOM);
+        setTranslucent(mStatusBarView);
+        setTranslucent(mNavigationBarView);
+
+        mFallback.draw(mDecorViewMock, mContentRootMock, null /* canvas */, mContentContainerMock,
+                mStatusBarView, mNavigationBarView);
+
+        verifyFallbackTop(STATUS_HEIGHT);
+        verifyFallbackBottom(NAV_SIZE);
+        verifyNoMoreInteractions(mDrawableMock);
+    }
+
+    @Test
+    public void draw_landscape_translucentBars_fallback() {
+        setUpViewHierarchy(INSET_CONTENT_VIEWS, NAVBAR_RIGHT);
+        setTranslucent(mStatusBarView);
+        setTranslucent(mNavigationBarView);
+
+        mFallback.draw(mDecorViewMock, mContentRootMock, null /* canvas */, mContentContainerMock,
+                mStatusBarView, mNavigationBarView);
+
+        verifyFallbackTop(STATUS_HEIGHT);
+        verifyFallbackRight(NAV_SIZE);
+        verifyNoMoreInteractions(mDrawableMock);
+    }
+
+    @Test
+    public void draw_seascape_translucentBars_fallback() {
+        setUpViewHierarchy(INSET_CONTENT_VIEWS, NAVBAR_LEFT);
+        setTranslucent(mStatusBarView);
+        setTranslucent(mNavigationBarView);
+
+        mFallback.draw(mDecorViewMock, mContentRootMock, null /* canvas */, mContentContainerMock,
+                mStatusBarView, mNavigationBarView);
+
+        verifyFallbackTop(STATUS_HEIGHT);
+        verifyFallbackLeft(NAV_SIZE);
+        verifyNoMoreInteractions(mDrawableMock);
+    }
+
+    @Test
+    public void draw_landscape_noFallback() {
+        setUpViewHierarchy(INSET_CONTENT_VIEWS, NAVBAR_RIGHT);
+
+        mFallback.draw(mDecorViewMock, mContentRootMock, null /* canvas */, mContentContainerMock,
+                mStatusBarView, mNavigationBarView);
+
+        verifyNoMoreInteractions(mDrawableMock);
+    }
+
+    @Test
+    public void draw_seascape_noFallback() {
+        setUpViewHierarchy(INSET_CONTENT_VIEWS, NAVBAR_LEFT);
+
+        mFallback.draw(mDecorViewMock, mContentRootMock, null /* canvas */, mContentContainerMock,
+                mStatusBarView, mNavigationBarView);
+
+        verifyNoMoreInteractions(mDrawableMock);
+    }
+
+    @Test
+    public void draw_seascape_translucentBars_noInsets_noFallback() {
+        setUpViewHierarchy(DONT_INSET_CONTENT_VIEWS, NAVBAR_LEFT);
+        setTranslucent(mStatusBarView);
+        setTranslucent(mNavigationBarView);
+
+        mFallback.draw(mDecorViewMock, mContentRootMock, null /* canvas */, mContentContainerMock,
+                mStatusBarView, mNavigationBarView);
+
+        verifyNoMoreInteractions(mDrawableMock);
+    }
+
+    private void verifyFallbackTop(int size) {
+        verify(mDrawableMock).setBounds(0, 0, SCREEN_WIDTH, size);
+        verify(mDrawableMock, atLeastOnce()).draw(any());
+        mLastTop = size;
+    }
+
+    private void verifyFallbackLeft(int size) {
+        verify(mDrawableMock).setBounds(0, mLastTop, size, SCREEN_HEIGHT);
+        verify(mDrawableMock, atLeastOnce()).draw(any());
+    }
+
+    private void verifyFallbackRight(int size) {
+        verify(mDrawableMock).setBounds(SCREEN_WIDTH - size, mLastTop, SCREEN_WIDTH, SCREEN_HEIGHT);
+        verify(mDrawableMock, atLeastOnce()).draw(any());
+    }
+
+    private void verifyFallbackBottom(int size) {
+        verify(mDrawableMock).setBounds(0, SCREEN_HEIGHT - size, SCREEN_WIDTH, SCREEN_HEIGHT);
+        verify(mDrawableMock, atLeastOnce()).draw(any());
+    }
+
+    private void setUpViewHierarchy(boolean insetContentViews, int navBarPosition) {
+        int insetLeft = 0;
+        int insetTop = 0;
+        int insetRight = 0;
+        int insetBottom = 0;
+
+        mStatusBarView = mockView(0, 0, SCREEN_WIDTH, STATUS_HEIGHT,
+                new ColorDrawable(Color.BLACK), VISIBLE, emptyList());
+        if (insetContentViews) {
+            insetTop = STATUS_HEIGHT;
+        }
+
+        switch (navBarPosition) {
+            case NAVBAR_BOTTOM:
+                mNavigationBarView = mockView(0, SCREEN_HEIGHT - NAV_SIZE, SCREEN_WIDTH,
+                        SCREEN_HEIGHT, new ColorDrawable(Color.BLACK), VISIBLE, emptyList());
+                if (insetContentViews) {
+                    insetBottom = NAV_SIZE;
+                }
+                break;
+            case NAVBAR_LEFT:
+                mNavigationBarView = mockView(0, 0, NAV_SIZE, SCREEN_HEIGHT,
+                        new ColorDrawable(Color.BLACK), VISIBLE, emptyList());
+                if (insetContentViews) {
+                    insetLeft = NAV_SIZE;
+                }
+                break;
+            case NAVBAR_RIGHT:
+                mNavigationBarView = mockView(SCREEN_WIDTH - NAV_SIZE, 0, SCREEN_WIDTH,
+                        SCREEN_HEIGHT, new ColorDrawable(Color.BLACK), VISIBLE, emptyList());
+                if (insetContentViews) {
+                    insetRight = NAV_SIZE;
+                }
+                break;
+        }
+
+        mContentMock = mockView(0, 0, SCREEN_WIDTH - insetLeft - insetRight,
+                SCREEN_HEIGHT - insetTop - insetBottom, null, VISIBLE, emptyList());
+        mContentContainerMock = mockView(0, 0, SCREEN_WIDTH - insetLeft - insetRight,
+                SCREEN_HEIGHT - insetTop - insetBottom, null, VISIBLE, asList(mContentMock));
+        mContentRootMock = mockView(insetLeft, insetTop, SCREEN_WIDTH - insetRight,
+                SCREEN_HEIGHT - insetBottom, null, VISIBLE, asList(mContentContainerMock));
+
+        mDecorViewMock = mockView(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, null, VISIBLE,
+                asList(mContentRootMock, mStatusBarView, mNavigationBarView));
+    }
+
+    private void setTranslucent(ViewGroup bar) {
+        bar.setBackground(new ColorDrawable(Color.TRANSPARENT));
+    }
+
+    private ViewGroup mockView(int left, int top, int right, int bottom, Drawable background,
+            int visibility, List<ViewGroup> children) {
+        final ViewGroup v = new FrameLayout(InstrumentationRegistry.getTargetContext());
+
+        v.layout(left, top, right, bottom);
+        v.setBackground(background);
+        v.setVisibility(visibility);
+
+        for (ViewGroup c : children) {
+            v.addView(c);
+        }
+
+        return v;
+    }
+}
\ No newline at end of file
diff --git a/libs/hwui/tests/common/TestListViewSceneBase.cpp b/libs/hwui/tests/common/TestListViewSceneBase.cpp
index a7f4d4d..fd33133 100644
--- a/libs/hwui/tests/common/TestListViewSceneBase.cpp
+++ b/libs/hwui/tests/common/TestListViewSceneBase.cpp
@@ -57,7 +57,8 @@
     int pxOffset = -(scrollPx % (mItemSpacing + mItemHeight));
 
     std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(
-            mListView->stagingProperties().getWidth(), mListView->stagingProperties().getHeight()));
+            mListView->stagingProperties().getWidth(), mListView->stagingProperties().getHeight(),
+            mListView.get()));
     for (size_t ci = 0; ci < mListItems.size(); ci++) {
         // update item position
         auto listItem = mListItems[(ci + itemIndexOffset) % mListItems.size()];
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 1bfa046..2752ae9 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -250,7 +250,8 @@
 
     static void recordNode(RenderNode& node, std::function<void(Canvas&)> contentCallback) {
         std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(
-                node.stagingProperties().getWidth(), node.stagingProperties().getHeight()));
+                node.stagingProperties().getWidth(), node.stagingProperties().getHeight(),
+                &node));
         contentCallback(*canvas.get());
         node.setStagingDisplayList(canvas->finishRecording());
     }
diff --git a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
index 38999cb..f0a5e9d 100644
--- a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
@@ -44,7 +44,8 @@
 
         std::unique_ptr<Canvas> canvas(
                 Canvas::create_recording_canvas(container->stagingProperties().getWidth(),
-                                                container->stagingProperties().getHeight()));
+                                                container->stagingProperties().getHeight(),
+                                                container.get()));
 
         Paint paint;
         paint.setAntiAlias(true);
diff --git a/libs/hwui/tests/common/scenes/TvApp.cpp b/libs/hwui/tests/common/scenes/TvApp.cpp
index 003d8e9..a64e844 100644
--- a/libs/hwui/tests/common/scenes/TvApp.cpp
+++ b/libs/hwui/tests/common/scenes/TvApp.cpp
@@ -194,7 +194,8 @@
 
         // re-recording card's canvas, not necessary but to add some burden to CPU
         std::unique_ptr<Canvas> cardcanvas(Canvas::create_recording_canvas(
-                card->stagingProperties().getWidth(), card->stagingProperties().getHeight()));
+                card->stagingProperties().getWidth(), card->stagingProperties().getHeight(),
+                card.get()));
         sp<RenderNode> image = mImages[ci];
         sp<RenderNode> infoArea = mInfoAreas[ci];
         cardcanvas->drawRenderNode(infoArea.get());
@@ -205,14 +206,16 @@
             sp<RenderNode> overlay = mOverlays[ci];
             std::unique_ptr<Canvas> canvas(
                     Canvas::create_recording_canvas(overlay->stagingProperties().getWidth(),
-                                                    overlay->stagingProperties().getHeight()));
+                                                    overlay->stagingProperties().getHeight(),
+                                                    overlay.get()));
             canvas->drawColor((curFrame % 150) << 24, SkBlendMode::kSrcOver);
             overlay->setStagingDisplayList(canvas->finishRecording());
             cardcanvas->drawRenderNode(overlay.get());
         } else {
             // re-recording image node's canvas, animating ColorFilter
             std::unique_ptr<Canvas> canvas(Canvas::create_recording_canvas(
-                    image->stagingProperties().getWidth(), image->stagingProperties().getHeight()));
+                    image->stagingProperties().getWidth(), image->stagingProperties().getHeight(),
+                    image.get()));
             SkPaint paint;
             sk_sp<SkColorFilter> filter(
                     SkColorFilter::MakeModeFilter((curFrame % 150) << 24, SkBlendMode::kSrcATop));
diff --git a/libs/incident/proto/android/section.proto b/libs/incident/proto/android/section.proto
index b3ed393..e8280ed 100644
--- a/libs/incident/proto/android/section.proto
+++ b/libs/incident/proto/android/section.proto
@@ -51,6 +51,7 @@
 message SectionFlags {
   optional SectionType type = 1 [default = SECTION_NONE];
   optional string args = 2;
+  optional bool device_specific = 3 [default = false];
 }
 
 extend google.protobuf.FieldOptions {
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index 1ca3c1d..cdaabdc 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -234,7 +234,9 @@
 
         DeviceChooserActivity activity = mActivity;
         if (activity != null) {
-            activity.mDeviceListView.removeFooterView(activity.mLoadingIndicator);
+            if (activity.mDeviceListView != null) {
+                activity.mDeviceListView.removeFooterView(activity.mLoadingIndicator);
+            }
             mActivity = null;
         }
 
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 2a82fc9..0a720a5 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -38,6 +38,9 @@
 import android.provider.DocumentsContract.Path;
 import android.provider.DocumentsContract.Root;
 import android.provider.Settings;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.DebugUtils;
@@ -360,14 +363,19 @@
 
     @Override
     protected File getFileForDocId(String docId, boolean visible) throws FileNotFoundException {
+        return getFileForDocId(docId, visible, true);
+    }
+
+    private File getFileForDocId(String docId, boolean visible, boolean mustExist)
+            throws FileNotFoundException {
         RootInfo root = getRootFromDocId(docId);
-        return buildFile(root, docId, visible);
+        return buildFile(root, docId, visible, mustExist);
     }
 
     private Pair<RootInfo, File> resolveDocId(String docId, boolean visible)
             throws FileNotFoundException {
         RootInfo root = getRootFromDocId(docId);
-        return Pair.create(root, buildFile(root, docId, visible));
+        return Pair.create(root, buildFile(root, docId, visible, true));
     }
 
     private RootInfo getRootFromDocId(String docId) throws FileNotFoundException {
@@ -385,7 +393,7 @@
         return root;
     }
 
-    private File buildFile(RootInfo root, String docId, boolean visible)
+    private File buildFile(RootInfo root, String docId, boolean visible, boolean mustExist)
             throws FileNotFoundException {
         final int splitIndex = docId.indexOf(':', 1);
         final String path = docId.substring(splitIndex + 1);
@@ -398,7 +406,7 @@
             target.mkdirs();
         }
         target = new File(target, path);
-        if (!target.exists()) {
+        if (mustExist && !target.exists()) {
             throw new FileNotFoundException("Missing file for " + docId + " at " + target);
         }
         return target;
@@ -410,6 +418,19 @@
     }
 
     @Override
+    protected void onDocIdChanged(String docId) {
+        try {
+            // Touch the visible path to ensure that any sdcardfs caches have
+            // been updated to reflect underlying changes on disk.
+            final File visiblePath = getFileForDocId(docId, true, false);
+            if (visiblePath != null) {
+                Os.access(visiblePath.getAbsolutePath(), OsConstants.F_OK);
+            }
+        } catch (FileNotFoundException | ErrnoException ignored) {
+        }
+    }
+
+    @Override
     public Cursor queryRoots(String[] projection) throws FileNotFoundException {
         final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection));
         synchronized (mRootsLock) {
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index cfcecbc..59e5cfb 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -250,19 +250,6 @@
         <item>Best Effort (Adaptive Bit Rate)</item>
     </string-array>
 
-    <!-- TODO: Enable for translation per b/73007419 -->
-    <!-- Summaries for Bluetooth Audio Active Device status. [CHAR LIMIT=50]-->
-    <string-array name="bluetooth_audio_active_device_summaries" translatable="false" >
-        <!-- Status message when the device is not Active. -->
-        <item></item>
-        <!-- Status message when the device is Active for Media and Phone. -->
-        <item>, active</item>
-        <!-- Status message when the device is Active for Media only. -->
-        <item>, active(media)</item>
-        <!-- Status message when the device is Active for Phone only. -->
-        <item>, active(phone)</item>
-    </string-array>
-
     <!-- Titles for logd limit size selection preference. [CHAR LIMIT=14] -->
     <string-array name="select_logd_size_titles">
         <item>Off</item>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 50c9b5c..a46c3e6 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -566,7 +566,7 @@
     <!-- UI debug setting: Trigger Bluetooth Audio LDAC Playback Quality Selection -->
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality">Bluetooth Audio LDAC Codec: Playback Quality</string>
     <!-- UI debug setting: Select Bluetooth Audio LDAC Codec: LDAC Playback Quality -->
-    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title">Trigger Bluetooth Audio LDAC Codec\u000ASelection: Playback Quality</string>
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title">Trigger Bluetooth Audio LDAC\u000ACodec Selection: Playback Quality</string>
 
     <!-- [CHAR LIMIT=NONE] Label for displaying Bluetooth Audio Codec Parameters while streaming -->
     <string name="bluetooth_select_a2dp_codec_streaming_label">Streaming: <xliff:g id="streaming_parameter">%1$s</xliff:g></string>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
index 3193101..87983b9 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
@@ -20,39 +20,54 @@
 <!-- This is a view that shows general status information in Keyguard. -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res-auto"
     android:id="@+id/presentation"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
-
+    <!-- This is mostly keyguard_status_view.xml with minor modifications -->
     <com.android.keyguard.KeyguardStatusView
         android:id="@+id/clock"
         android:orientation="vertical"
-        android:layout_width="wrap_content"
+        android:layout_width="410dp"
         android:layout_height="wrap_content">
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_gravity="center_horizontal|top"
-            android:orientation="vertical"
-            android:focusable="true">
-            <TextClock
-                android:id="@+id/clock_view"
-                android:layout_width="wrap_content"
+            android:orientation="vertical">
+            <RelativeLayout
+                android:id="@+id/keyguard_clock_container"
+                android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_gravity="center_horizontal|top"
-                android:textColor="?attr/wallpaperTextColor"
-                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:baselineAligned="true" />
-
-            <include layout="@layout/keyguard_status_area" />
+                android:layout_gravity="center_horizontal|top">
+                <TextClock
+                    android:id="@+id/clock_view"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_horizontal"
+                    android:layout_centerHorizontal="true"
+                    android:layout_alignParentTop="true"
+                    android:letterSpacing="0.03"
+                    android:textColor="?attr/wallpaperTextColor"
+                    android:singleLine="true"
+                    style="@style/widget_big_thin"
+                    android:format12Hour="@string/keyguard_widget_12_hours_format"
+                    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_below="@id/clock_view"
+                    android:background="#f00"
+                    android:layout_centerHorizontal="true" />
+                <include layout="@layout/keyguard_status_area"
+                         android:id="@+id/keyguard_status_area"
+                         android:layout_width="match_parent"
+                         android:layout_height="wrap_content"
+                         android:layout_below="@id/clock_separator" />
+            </RelativeLayout>
             <ImageView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="10dip"
+                android:layout_marginTop="@dimen/widget_vertical_padding"
                 android:layout_gravity="center_horizontal"
                 android:src="@drawable/kg_security_lock_normal" />
         </LinearLayout>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 712b6e5..d628ca8 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -77,7 +77,7 @@
     <dimen name="password_char_padding">8dp</dimen>
 
     <!-- The vertical margin between the date and the owner info. -->
-    <dimen name="date_owner_info_margin">2dp</dimen>
+    <dimen name="date_owner_info_margin">4dp</dimen>
 
     <!-- The translation for disappearing security views after having solved them. -->
     <dimen name="disappear_y_translation">-32dp</dimen>
diff --git a/packages/SystemUI/res/layout/app_ops_info.xml b/packages/SystemUI/res/layout/app_ops_info.xml
index 74a4c6e..676301e 100644
--- a/packages/SystemUI/res/layout/app_ops_info.xml
+++ b/packages/SystemUI/res/layout/app_ops_info.xml
@@ -21,6 +21,8 @@
         android:layout_height="wrap_content"
         android:id="@+id/app_ops_info"
         android:clickable="true"
+        android:clipChildren="false"
+        android:clipToPadding="false"
         android:orientation="vertical"
         android:paddingStart="@*android:dimen/notification_content_margin_start"
         android:paddingEnd="@*android:dimen/notification_content_margin_end"
@@ -63,10 +65,10 @@
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="horizontal"
         android:layout_marginTop="@dimen/notification_guts_button_spacing"
         android:layout_marginBottom="@dimen/notification_guts_button_spacing"
-        android:gravity="end" >
+        android:gravity="end"
+        android:orientation="horizontal">
 
         <TextView
             android:id="@+id/settings"
diff --git a/packages/SystemUI/res/layout/menu_ime.xml b/packages/SystemUI/res/layout/menu_ime.xml
index 5a0e767..1be3375 100644
--- a/packages/SystemUI/res/layout/menu_ime.xml
+++ b/packages/SystemUI/res/layout/menu_ime.xml
@@ -16,6 +16,7 @@
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/menu_container"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     >
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index b1cb6cf..095f181 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -17,10 +17,12 @@
 
 <com.android.systemui.statusbar.NotificationInfo
         xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/notification_guts"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:id="@+id/notification_guts"
         android:clickable="true"
+        android:clipChildren="false"
+        android:clipToPadding="false"
         android:orientation="vertical"
         android:paddingStart="@*android:dimen/notification_content_margin_start"
         android:paddingEnd="@*android:dimen/notification_content_margin_end"
@@ -33,8 +35,7 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:clipChildren="false"
-        android:clipToPadding="false"
-        android:layout_marginTop="2dp" >
+        android:clipToPadding="false">
         <ImageView
             android:id="@+id/pkgicon"
             android:layout_width="@dimen/notification_guts_header_height"
@@ -74,16 +75,16 @@
             android:layout_toEndOf="@id/pkg_group_divider" />
         <ImageButton
             android:id="@+id/info"
-            android:src="@drawable/ic_info"
-            android:tint="?android:attr/colorAccent"
-            android:layout_width="48dp"
-            android:layout_height="48dp"
-            android:padding="12dp"
-            android:layout_marginEnd="-12dp"
+            android:layout_width="56dp"
+            android:layout_height="56dp"
+            android:layout_alignParentEnd="true"
             android:layout_centerVertical="true"
-            android:contentDescription="@string/notification_more_settings"
+            android:layout_marginEnd="-16dp"
             android:background="@drawable/ripple_drawable"
-            android:layout_alignParentEnd="true" />
+            android:contentDescription="@string/notification_more_settings"
+            android:padding="16dp"
+            android:src="@drawable/ic_info"
+            android:tint="?android:attr/colorAccent" />
     </RelativeLayout>
 
     <LinearLayout
@@ -91,7 +92,8 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginBottom="@dimen/notification_guts_button_spacing"
-        android:layout_marginTop="@*android:dimen/notification_header_padding_top"
+        android:clipChildren="false"
+        android:clipToPadding="false"
         android:orientation="vertical">
 
         <!-- Channel Info Block -->
@@ -105,14 +107,13 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
-                android:layout_marginBottom="6dp"
-                style="@style/TextAppearance.NotificationInfo.Primary" />
+                style="@android:style/TextAppearance.Material.Notification.Title" />
             <!-- Question prompt -->
             <TextView
                 android:id="@+id/block_prompt"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                style="@style/TextAppearance.NotificationInfo.Secondary" />
+                style="@android:style/TextAppearance.Material.Notification" />
         </LinearLayout>
 
         <!-- Settings and Done buttons -->
@@ -139,12 +140,14 @@
                 android:text="@string/inline_stop_button"
                 android:layout_width="wrap_content"
                 android:layout_height="match_parent"
+                android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
                 style="@style/TextAppearance.NotificationInfo.Button"/>
             <TextView
                 android:id="@+id/minimize"
                 android:text="@string/inline_minimize_button"
                 android:layout_width="wrap_content"
                 android:layout_height="match_parent"
+                android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
                 style="@style/TextAppearance.NotificationInfo.Button" />
             <TextView
                 android:id="@+id/keep"
@@ -152,6 +155,7 @@
                 android:layout_width="wrap_content"
                 android:layout_height="match_parent"
                 android:layout_marginEnd="-8dp"
+                android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
                 style="@style/TextAppearance.NotificationInfo.Button"/>
         </LinearLayout>
     </LinearLayout>
@@ -160,22 +164,24 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginBottom="@dimen/notification_guts_button_spacing"
-        android:layout_marginTop="@*android:dimen/notification_header_padding_top"
+        android:layout_marginTop="@dimen/notification_guts_button_spacing"
         android:visibility="gone"
         android:orientation="horizontal" >
         <TextView
             android:id="@+id/confirmation_text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_centerVertical="true"
             android:text="@string/notification_channel_disabled"
             style="@style/TextAppearance.NotificationInfo.Confirmation"/>
         <TextView
             android:id="@+id/undo"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:text="@string/inline_undo"
             android:layout_alignParentEnd="true"
+            android:layout_centerVertical="true"
             android:layout_marginEnd="-8dp"
+            android:text="@string/inline_undo"
             style="@style/TextAppearance.NotificationInfo.Button"/>
     </RelativeLayout>
 </com.android.systemui.statusbar.NotificationInfo>
diff --git a/packages/SystemUI/res/layout/qs_paged_page.xml b/packages/SystemUI/res/layout/qs_paged_page.xml
index 25b1a2b..07f0c83 100644
--- a/packages/SystemUI/res/layout/qs_paged_page.xml
+++ b/packages/SystemUI/res/layout/qs_paged_page.xml
@@ -20,7 +20,7 @@
     android:id="@+id/tile_page"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:paddingLeft="@dimen/notification_side_paddings"
-    android:paddingRight="@dimen/notification_side_paddings"
+    android:paddingStart="@dimen/notification_side_paddings"
+    android:paddingEnd="@dimen/notification_side_paddings"
     android:clipChildren="false"
     android:clipToPadding="false" />
diff --git a/packages/SystemUI/res/layout/status_bar_dnd_suppressing_notifications.xml b/packages/SystemUI/res/layout/status_bar_dnd_suppressing_notifications.xml
deleted file mode 100644
index eff9b36..0000000
--- a/packages/SystemUI/res/layout/status_bar_dnd_suppressing_notifications.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<!--
-    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/status_bar_wifi_group.xml b/packages/SystemUI/res/layout/status_bar_wifi_group.xml
index 482f780..c419b90 100644
--- a/packages/SystemUI/res/layout/status_bar_wifi_group.xml
+++ b/packages/SystemUI/res/layout/status_bar_wifi_group.xml
@@ -28,8 +28,8 @@
         android:id="@+id/wifi_group"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
-        android:paddingStart="2dp"
         android:gravity="center_vertical"
+        android:layout_marginStart="2.5dp"
     >
         <FrameLayout
                 android:id="@+id/inout_container"
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index fd25c40..efcca63 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -95,7 +95,7 @@
     <color name="notification_gear_color">#ff757575</color>
 
     <!-- The "inside" of a notification, reached via longpress -->
-    <color name="notification_guts_bg_color">#eeeeee</color>
+    <color name="notification_guts_bg_color">#f8f9fa</color>
 
     <color name="assist_orb_color">#ffffff</color>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index eb71911..af343fb 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -158,8 +158,17 @@
     <!-- The space around a notification menu item  -->
     <dimen name="notification_menu_icon_padding">20dp</dimen>
 
-    <!-- The veritical space around the buttons in the inline settings -->
-    <dimen name="notification_guts_button_spacing">20dp</dimen>
+    <!-- The vertical space around the buttons in the inline settings -->
+    <dimen name="notification_guts_button_spacing">6dp</dimen>
+
+    <!-- The vertical padding a notification guts button has to fulfill the 48dp touch target -->
+    <dimen name="notification_guts_button_vertical_padding">14dp</dimen>
+
+    <!-- The horizontal padding for notification guts buttons-->
+    <dimen name="notification_guts_button_horizontal_padding">14dp</dimen>
+
+    <!-- The horizontal space around the buttons in the inline settings -->
+    <dimen name="notification_guts_button_horizontal_spacing">8dp</dimen>
 
     <!-- The height of the header in inline settings -->
     <dimen name="notification_guts_header_height">24dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 1b4b15e..f1f80c7 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1064,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">Notifications hidden by Do Not Disturb</string>
+    <string name="dnd_suppressing_shade_text">Do Not Disturb is hiding notifications</string>
 
     <!-- Media projection permission dialog action text. [CHAR LIMIT=60] -->
     <string name="media_projection_action_text">Start now</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 1e19534..c9b14dc 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -320,7 +320,7 @@
         <item name="wallpaperTextColor">@*android:color/primary_text_material_light</item>
         <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_light</item>
         <item name="android:colorError">@*android:color/error_color_material_light</item>
-        <item name="android:colorControlHighlight">@*android:color/primary_text_material_light</item>
+        <item name="android:colorControlHighlight">#40000000</item>
         <item name="passwordStyle">@style/PasswordTheme.Light</item>
     </style>
 
@@ -483,8 +483,10 @@
         <item name="android:background">@drawable/btn_borderless_rect</item>
         <item name="android:gravity">center</item>
         <item name="android:focusable">true</item>
-        <item name="android:paddingStart">8dp</item>
-        <item name="android:paddingEnd">8dp</item>
+        <item name="android:paddingTop">@dimen/notification_guts_button_vertical_padding</item>
+        <item name="android:paddingBottom">@dimen/notification_guts_button_vertical_padding</item>
+        <item name="android:paddingLeft">@dimen/notification_guts_button_horizontal_padding</item>
+        <item name="android:paddingRight">@dimen/notification_guts_button_horizontal_padding</item>
     </style>
 
     <style name="TextAppearance.HeadsUpStatusBarText"
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
index e93e78d..952c8ae 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/MetricsLoggerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/MetricsLoggerCompat.java
@@ -17,10 +17,12 @@
 package com.android.systemui.shared.system;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 
 public class MetricsLoggerCompat {
 
     private final MetricsLogger mMetricsLogger;
+    public static final int OVERVIEW_ACTIVITY = MetricsEvent.OVERVIEW_ACTIVITY;
 
     public MetricsLoggerCompat() {
         mMetricsLogger = new MetricsLogger();
@@ -37,4 +39,12 @@
     public void visible(int category) {
         mMetricsLogger.visible(category);
     }
+
+    public void hidden(int category) {
+        mMetricsLogger.hidden(category);
+    }
+
+    public void visibility(int category, boolean visible) {
+        mMetricsLogger.visibility(category, visible);
+    }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TonalCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TonalCompat.java
new file mode 100644
index 0000000..4a0f89b
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TonalCompat.java
@@ -0,0 +1,53 @@
+/*
+ * 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 android.app.WallpaperColors;
+import android.content.Context;
+
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.colorextraction.types.Tonal;
+
+public class TonalCompat {
+
+    private final Tonal mTonal;
+
+    public TonalCompat(Context context) {
+        mTonal = new Tonal(context);
+    }
+
+    public ExtractionInfo extractDarkColors(WallpaperColors colors) {
+        GradientColors darkColors = new GradientColors();
+        mTonal.extractInto(colors, new GradientColors(), darkColors, new GradientColors());
+
+        ExtractionInfo result = new ExtractionInfo();
+        result.mainColor = darkColors.getMainColor();
+        result.secondaryColor = darkColors.getSecondaryColor();
+        result.supportsDarkText = darkColors.supportsDarkText();
+        if (colors != null) {
+            result.supportsDarkTheme =
+                    (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
+        }
+        return result;
+    }
+
+    public static class ExtractionInfo {
+        public int mainColor;
+        public int secondaryColor;
+        public boolean supportsDarkText;
+        public boolean supportsDarkTheme;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index c31cea2..33cac3b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -145,17 +145,13 @@
     }
 
     private void showSlice() {
-        if (mPulsing) {
+        if (mPulsing || mSlice == null) {
             mTitle.setVisibility(GONE);
             mRow.setVisibility(GONE);
             mContentChangeListener.accept(getLayoutTransition() != null);
             return;
         }
 
-        if (mSlice == null) {
-            return;
-        }
-
         ListContent lc = new ListContent(getContext(), mSlice);
         mHasHeader = lc.hasHeader();
         List<SliceItem> subItems = lc.getRowItems();
@@ -170,18 +166,6 @@
             SliceItem mainTitle = header.getTitleItem();
             CharSequence title = mainTitle != null ? mainTitle.getText() : null;
             mTitle.setText(title);
-
-            // Check if we're already ellipsizing the text.
-            // We're going to figure out the best possible line break if not.
-            Layout layout = mTitle.getLayout();
-            if (layout != null){
-                final int lineCount = layout.getLineCount();
-                if (lineCount > 0) {
-                    if (layout.getEllipsisCount(lineCount - 1) == 0) {
-                        mTitle.setText(findBestLineBreak(title));
-                    }
-                }
-            }
         }
 
         mClickActions.clear();
@@ -385,6 +369,27 @@
         mIconSize = mContext.getResources().getDimensionPixelSize(R.dimen.widget_icon_size);
     }
 
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        // Find best ellipsis strategy for the title.
+        // Done on onMeasure since TextView#getLayout needs a measure pass to calculate its bounds.
+        Layout layout = mTitle.getLayout();
+        if (layout != null) {
+            final int lineCount = layout.getLineCount();
+            if (lineCount > 0) {
+                if (layout.getEllipsisCount(lineCount - 1) == 0) {
+                    CharSequence title = mTitle.getText();
+                    CharSequence bestLineBreak = findBestLineBreak(title);
+                    if (!TextUtils.equals(title, bestLineBreak)) {
+                        mTitle.setText(bestLineBreak);
+                    }
+                }
+            }
+        }
+    }
+
     public static class Row extends LinearLayout {
 
         /**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 727b62b..454528e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -164,7 +164,9 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         mLogoutView = findViewById(R.id.logout);
-        mLogoutView.setOnClickListener(this::onLogoutClicked);
+        if (mLogoutView != null) {
+            mLogoutView.setOnClickListener(this::onLogoutClicked);
+        }
 
         mClockView = findViewById(R.id.clock_view);
         mClockView.setShowCurrentUserTime(true);
@@ -296,6 +298,9 @@
     }
 
     public int getLogoutButtonHeight() {
+        if (mLogoutView == null) {
+            return 0;
+        }
         return mLogoutView.getVisibility() == VISIBLE ? mLogoutView.getHeight() : 0;
     }
 
@@ -304,6 +309,9 @@
     }
 
     private void updateLogoutView() {
+        if (mLogoutView == null) {
+            return;
+        }
         mLogoutView.setVisibility(shouldShowLogout() ? VISIBLE : GONE);
         // Logout button will stay in language of user 0 if we don't set that manually.
         mLogoutView.setText(mContext.getResources().getString(
@@ -390,7 +398,9 @@
 
     private void updateDark() {
         boolean dark = mDarkAmount == 1;
-        mLogoutView.setAlpha(dark ? 0 : 1);
+        if (mLogoutView != null) {
+            mLogoutView.setAlpha(dark ? 0 : 1);
+        }
         if (mOwnerInfo != null) {
             boolean hasText = !TextUtils.isEmpty(mOwnerInfo.getText());
             mOwnerInfo.setVisibility(hasText && mDarkAmount != 1 ? VISIBLE : GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
index 282a8f1..9307c22 100644
--- a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
@@ -66,6 +66,7 @@
     public static final String TAG_OPS = "OverviewProxyService";
     public static final boolean DEBUG_OVERVIEW_PROXY = false;
     private static final long BACKOFF_MILLIS = 5000;
+    private static final long DEFERRED_CALLBACK_MILLIS = 5000;
 
     private final Context mContext;
     private final Handler mHandler;
@@ -162,6 +163,12 @@
         }
     };
 
+    private final Runnable mDeferredConnectionCallback = () -> {
+        Log.w(TAG_OPS, "Binder supposed established connection but actual connection to service "
+            + "timed out, trying again");
+        internalConnectToCurrentUser();
+    };
+
     private final BroadcastReceiver mLauncherStateChangedReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -181,22 +188,33 @@
     private final ServiceConnection mOverviewServiceConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
-            if (service != null) {
-                mConnectionBackoffAttempts = 0;
-                mOverviewProxy = IOverviewProxy.Stub.asInterface(service);
-                // Listen for launcher's death
-                try {
-                    service.linkToDeath(mOverviewServiceDeathRcpt, 0);
-                } catch (RemoteException e) {
-                    Log.e(TAG_OPS, "Lost connection to launcher service", e);
-                }
-                try {
-                    mOverviewProxy.onBind(mSysUiProxy);
-                } catch (RemoteException e) {
-                    Log.e(TAG_OPS, "Failed to call onBind()", e);
-                }
-                notifyConnectionChanged();
+            mHandler.removeCallbacks(mDeferredConnectionCallback);
+            mConnectionBackoffAttempts = 0;
+            mOverviewProxy = IOverviewProxy.Stub.asInterface(service);
+            // Listen for launcher's death
+            try {
+                service.linkToDeath(mOverviewServiceDeathRcpt, 0);
+            } catch (RemoteException e) {
+                Log.e(TAG_OPS, "Lost connection to launcher service", e);
             }
+            try {
+                mOverviewProxy.onBind(mSysUiProxy);
+            } catch (RemoteException e) {
+                Log.e(TAG_OPS, "Failed to call onBind()", e);
+            }
+            notifyConnectionChanged();
+        }
+
+        @Override
+        public void onNullBinding(ComponentName name) {
+            Log.w(TAG_OPS, "Null binding of '" + name + "', try reconnecting");
+            internalConnectToCurrentUser();
+        }
+
+        @Override
+        public void onBindingDied(ComponentName name) {
+            Log.w(TAG_OPS, "Binding died of '" + name + "', try reconnecting");
+            internalConnectToCurrentUser();
         }
 
         @Override
@@ -262,6 +280,9 @@
 
         // If user has not setup yet or already connected, do not try to connect
         if (!mDeviceProvisionedController.isCurrentUserSetup() || !isEnabled()) {
+            Log.v(TAG_OPS, "Cannot attempt connection, is setup "
+                + mDeviceProvisionedController.isCurrentUserSetup() + ", is enabled "
+                + isEnabled());
             return;
         }
         mHandler.removeCallbacks(mConnectionRunnable);
@@ -275,11 +296,16 @@
         } catch (SecurityException e) {
             Log.e(TAG_OPS, "Unable to bind because of security error", e);
         }
-        if (!bound) {
+        if (bound) {
+            // Ensure that connection has been established even if it thinks it is bound
+            mHandler.postDelayed(mDeferredConnectionCallback, DEFERRED_CALLBACK_MILLIS);
+        } else {
             // Retry after exponential backoff timeout
             final long timeoutMs = (long) Math.scalb(BACKOFF_MILLIS, mConnectionBackoffAttempts);
             mHandler.postDelayed(mConnectionRunnable, timeoutMs);
             mConnectionBackoffAttempts++;
+            Log.w(TAG_OPS, "Failed to connect on attempt " + mConnectionBackoffAttempts
+                    + " will try again in " + timeoutMs + "ms");
         }
     }
 
@@ -351,6 +377,10 @@
         pw.print("  isCurrentUserSetup="); pw.println(mDeviceProvisionedController
                 .isCurrentUserSetup());
         pw.print("  isConnected="); pw.println(mOverviewProxy != null);
+        pw.print("  mRecentsComponentName="); pw.println(mRecentsComponentName);
+        pw.print("  mIsEnabled="); pw.println(isEnabled());
+        pw.print("  mInteractionFlags="); pw.println(mInteractionFlags);
+        pw.print("  mQuickStepIntent="); pw.println(mQuickStepIntent);
     }
 
     public interface OverviewProxyListener {
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index f595d77..a7163bb 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -94,6 +94,8 @@
         String OVERVIEW_OPENED_FROM_HOME_COUNT = "OverviewOpenedFromHomeCount";
         String HAS_SEEN_RECENTS_SWIPE_UP_ONBOARDING = "HasSeenRecentsSwipeUpOnboarding";
         String HAS_SEEN_RECENTS_QUICK_SCRUB_ONBOARDING = "HasSeenRecentsQuickScrubOnboarding";
+        String HAS_DISMISSED_RECENTS_QUICK_SCRUB_ONBOARDING_ONCE =
+                "HasDismissedRecentsQuickScrubOnboardingOnce";
         String SEEN_RINGER_GUIDANCE_COUNT = "RingerGuidanceCount";
         String QS_TILE_SPECS_REVEALED = "QsTileSpecsRevealed";
         String QS_HAS_TURNED_OFF_MOBILE_DATA = "QsHasTurnedOffMobileData";
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 087d481..ea3f95e 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -344,8 +344,8 @@
             } else if (GLOBAL_ACTION_KEY_SETTINGS.equals(actionKey)) {
                 mItems.add(getSettingsAction());
             } else if (GLOBAL_ACTION_KEY_LOCKDOWN.equals(actionKey)) {
-                if (Settings.Secure.getInt(mContext.getContentResolver(),
-                            Settings.Secure.LOCKDOWN_IN_POWER_MENU, 0) != 0
+                if (Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                            Settings.Secure.LOCKDOWN_IN_POWER_MENU, 0, getCurrentUser().id) != 0
                         && shouldDisplayLockdown()) {
                     mItems.add(getLockdownAction());
                     mHasLockdownButton = true;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 6d46e85..45d63e0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -93,7 +93,8 @@
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         final int numTiles = mRecords.size();
-        final int width = MeasureSpec.getSize(widthMeasureSpec) - mPaddingLeft - mPaddingRight;
+        final int width = MeasureSpec.getSize(widthMeasureSpec)
+                - getPaddingStart() - getPaddingEnd();
         final int numRows = (numTiles + mColumns - 1) / mColumns;
         mCellWidth = (width - mSidePadding * 2 - (mCellMarginHorizontal * mColumns)) / mColumns;
 
@@ -140,16 +141,8 @@
 
             final TileRecord record = mRecords.get(i);
             final int top = getRowTop(row);
-            final int right;
-            final int left;
-            if (isRtl) {
-                right = w - getColumnStart(column);
-                left = right - mCellWidth;
-            } else {
-                left = getColumnStart(column);
-                right = left + mCellWidth;
-            }
-
+            final int left = getColumnStart(isRtl ? mColumns - column - 1 : column);
+            final int right = left + mCellWidth;
             record.tileView.layout(left, top, right, top + record.tileView.getMeasuredHeight());
         }
     }
@@ -159,6 +152,7 @@
     }
 
     private int getColumnStart(int column) {
-        return column * (mCellWidth + mCellMarginHorizontal) + mCellMarginHorizontal + mPaddingLeft;
+        return getPaddingStart() + mSidePadding + mCellMarginHorizontal / 2 +
+                column *  (mCellWidth + mCellMarginHorizontal);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 441d29b..5adeec3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -67,6 +67,10 @@
     private static final long EDIT_ID = 10000;
     private static final long DIVIDER_ID = 20000;
 
+    private static final int ACTION_NONE = 0;
+    private static final int ACTION_ADD = 1;
+    private static final int ACTION_MOVE = 2;
+
     private final Context mContext;
 
     private final Handler mHandler = new Handler();
@@ -82,7 +86,7 @@
     private List<TileInfo> mAllTiles;
 
     private Holder mCurrentDrag;
-    private boolean mAccessibilityMoving;
+    private int mAccessibilityAction = ACTION_NONE;
     private int mAccessibilityFromIndex;
     private QSTileHost mHost;
 
@@ -172,7 +176,7 @@
 
     @Override
     public int getItemViewType(int position) {
-        if (mAccessibilityMoving && position == mEditIndex - 1) {
+        if (mAccessibilityAction == ACTION_ADD && position == mEditIndex - 1) {
             return TYPE_ACCESSIBLE_DROP;
         }
         if (position == mTileDividerIndex) {
@@ -266,18 +270,18 @@
         if (position > mEditIndex) {
             info.state.contentDescription = mContext.getString(
                     R.string.accessibility_qs_edit_add_tile_label, info.state.label);
-        } else if (mAccessibilityMoving) {
+        } else if (mAccessibilityAction != ACTION_NONE) {
             info.state.contentDescription = mContext.getString(
                     R.string.accessibility_qs_edit_position_label, position + 1);
         } else {
             info.state.contentDescription = mContext.getString(
                     R.string.accessibility_qs_edit_tile_label, position + 1, info.state.label);
         }
-        holder.mTileView.onStateChanged(info.state);
+        holder.mTileView.handleStateChanged(info.state);
         holder.mTileView.setShowAppLabel(position > mEditIndex && !info.isSystem);
 
         if (mAccessibilityManager.isTouchExplorationEnabled()) {
-            final boolean selectable = !mAccessibilityMoving || position < mEditIndex;
+            final boolean selectable = mAccessibilityAction == ACTION_NONE || position < mEditIndex;
             holder.mTileView.setClickable(selectable);
             holder.mTileView.setFocusable(selectable);
             holder.mTileView.setImportantForAccessibility(selectable
@@ -288,13 +292,13 @@
                     @Override
                     public void onClick(View v) {
                         int position = holder.getAdapterPosition();
-                        if (mAccessibilityMoving) {
+                        if (mAccessibilityAction != ACTION_NONE) {
                             selectPosition(position, v);
                         } else {
                             if (position < mEditIndex && canRemoveTiles()) {
                                 showAccessibilityDialog(position, v);
                             } else {
-                                startAccessibleDrag(position);
+                                startAccessibleAdd(position);
                             }
                         }
                     }
@@ -302,21 +306,21 @@
             }
         }
     }
-    
+
     private boolean canRemoveTiles() {
         return mCurrentSpecs.size() > MIN_NUM_TILES;
     }
 
     private void selectPosition(int position, View v) {
-        // Remove the placeholder.
-        mAccessibilityMoving = false;
-        mTiles.remove(mEditIndex--);
-        notifyItemRemoved(mEditIndex - 1);
-        // Don't remove items when the last position is selected.
-        if (position == mEditIndex) position--;
-
+        if (mAccessibilityAction == ACTION_ADD) {
+            // Remove the placeholder.
+            mTiles.remove(mEditIndex--);
+            notifyItemRemoved(mEditIndex);
+            // Don't remove items when the last position is selected.
+            if (position == mEditIndex - 1) position--;
+        }
+        mAccessibilityAction = ACTION_NONE;
         move(mAccessibilityFromIndex, position, v);
-
         notifyDataSetChanged();
     }
 
@@ -331,7 +335,7 @@
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
                         if (which == 0) {
-                            startAccessibleDrag(position);
+                            startAccessibleMove(position);
                         } else {
                             move(position, info.isSystem ? mEditIndex : mTileDividerIndex, v);
                             notifyItemChanged(mTileDividerIndex);
@@ -345,12 +349,18 @@
         dialog.show();
     }
 
-    private void startAccessibleDrag(int position) {
-        mAccessibilityMoving = true;
-        mNeedsFocus = true;
+    private void startAccessibleAdd(int position) {
         mAccessibilityFromIndex = position;
+        mAccessibilityAction = ACTION_ADD;
         // Add placeholder for last slot.
         mTiles.add(mEditIndex++, null);
+        mNeedsFocus = true;
+        notifyDataSetChanged();
+    }
+
+    private void startAccessibleMove(int position) {
+        mAccessibilityFromIndex = position;
+        mAccessibilityAction = ACTION_MOVE;
         notifyDataSetChanged();
     }
 
@@ -365,30 +375,26 @@
         CharSequence fromLabel = mTiles.get(from).state.label;
         move(from, to, mTiles);
         updateDividerLocations();
-        CharSequence announcement;
         if (to >= mEditIndex) {
             MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_REMOVE_SPEC,
                     strip(mTiles.get(to)));
             MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_REMOVE,
                     from);
-            announcement = mContext.getString(R.string.accessibility_qs_edit_tile_removed,
-                    fromLabel);
         } else if (from >= mEditIndex) {
             MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_ADD_SPEC,
                     strip(mTiles.get(to)));
             MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_ADD,
                     to);
-            announcement = mContext.getString(R.string.accessibility_qs_edit_tile_added,
-                    fromLabel, (to + 1));
+            v.announceForAccessibility(mContext.getString(R.string.accessibility_qs_edit_tile_added,
+                    fromLabel, (to + 1)));
         } else {
             MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_MOVE_SPEC,
                     strip(mTiles.get(to)));
             MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_MOVE,
                     to);
-            announcement = mContext.getString(R.string.accessibility_qs_edit_tile_moved,
-                    fromLabel, (to + 1));
+            v.announceForAccessibility(mContext.getString(R.string.accessibility_qs_edit_tile_moved,
+                    fromLabel, (to + 1)));
         }
-        v.announceForAccessibility(announcement);
         saveSpecs(mHost);
         return true;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index 63be4b7..c7191f8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -45,8 +45,8 @@
      * Pattern for {@link java.time.format.DateTimeFormatter} used to approximate the time to the
      * nearest hour and add on the AM/PM indicator.
      */
-    private static final String HOUR_MINUTE_DATE_TIME_PATTERN = "h a";
-    private static final String APPROXIMATE_HOUR_DATE_TIME_PATTERN = "h:m a";
+    private static final String PATTERN_HOUR = "h a";
+    private static final String PATTERN_HOUR_MINUTE = "h:mm a";
 
 
     private ColorDisplayController mController;
@@ -142,9 +142,7 @@
                 // Choose between just showing the hour or also showing the minutes (based on the
                 // user-selected toggle time). This helps reduce how much space the label takes.
                 toggleTimeFormat = DateTimeFormatter.ofPattern(
-                        toggleTime.getMinute() == 0
-                                ? HOUR_MINUTE_DATE_TIME_PATTERN
-                                : APPROXIMATE_HOUR_DATE_TIME_PATTERN);
+                        toggleTime.getMinute() == 0 ? PATTERN_HOUR : PATTERN_HOUR_MINUTE);
 
                 return mContext.getString(toggleTimeStringRes, toggleTime.format(toggleTimeFormat));
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
index ffa1444..31933d0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
@@ -19,6 +19,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 
+import static com.android.systemui.Prefs.Key.HAS_DISMISSED_RECENTS_QUICK_SCRUB_ONBOARDING_ONCE;
 import static com.android.systemui.Prefs.Key.HAS_SEEN_RECENTS_QUICK_SCRUB_ONBOARDING;
 import static com.android.systemui.Prefs.Key.HAS_SEEN_RECENTS_SWIPE_UP_ONBOARDING;
 import static com.android.systemui.Prefs.Key.OVERVIEW_OPENED_COUNT;
@@ -66,7 +67,7 @@
 
     private static final String TAG = "RecentsOnboarding";
     private static final boolean RESET_PREFS_FOR_DEBUG = false;
-    private static final boolean ONBOARDING_ENABLED = false;
+    private static final boolean ONBOARDING_ENABLED = true;
     private static final long SHOW_DELAY_MS = 500;
     private static final long SHOW_HIDE_DURATION_MS = 300;
     // Show swipe-up tips after opening overview from home this number of times.
@@ -76,9 +77,6 @@
     // After explicitly dismissing, show again after launching this number of apps for swipe-up
     // tips.
     private static final int SWIPE_UP_SHOW_ON_APP_LAUNCH_AFTER_DISMISS = 5;
-    // After explicitly dismissing, show again after launching this number of apps for QuickScrub
-    // tips.
-    private static final int QUICK_SCRUB_SHOW_ON_APP_LAUNCH_AFTER_DISMISS = 10;
 
     private final Context mContext;
     private final WindowManager mWindowManager;
@@ -99,7 +97,7 @@
     private boolean mHasDismissedSwipeUpTip;
     private boolean mHasDismissedQuickScrubTip;
     private int mNumAppsLaunchedSinceSwipeUpTipDismiss;
-    private int mNumAppsLaunchedSinceQuickScrubTipDismiss;
+    private int mOverviewOpenedCountSinceQuickScrubTipDismiss;
 
     private final SysUiTaskStackChangeListener mTaskListener = new SysUiTaskStackChangeListener() {
         @Override
@@ -145,10 +143,9 @@
                 } else {
                     if (getOpenedOverviewCount() >= QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) {
                         if (mHasDismissedQuickScrubTip) {
-                            mNumAppsLaunchedSinceQuickScrubTipDismiss++;
-                            if (mNumAppsLaunchedSinceQuickScrubTipDismiss
-                                    == QUICK_SCRUB_SHOW_ON_APP_LAUNCH_AFTER_DISMISS) {
-                                mNumAppsLaunchedSinceQuickScrubTipDismiss = 0;
+                            if (mOverviewOpenedCountSinceQuickScrubTipDismiss
+                                    == QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) {
+                                mOverviewOpenedCountSinceQuickScrubTipDismiss = 0;
                                 show(R.string.recents_quick_scrub_onboarding);
                             }
                         } else {
@@ -166,14 +163,19 @@
             new OverviewProxyService.OverviewProxyListener() {
                 @Override
                 public void onOverviewShown(boolean fromHome) {
-                    boolean alreadySeenRecentsOnboarding = hasSeenSwipeUpOnboarding();
-                    if (!alreadySeenRecentsOnboarding && !fromHome) {
+                    if (!hasSeenSwipeUpOnboarding() && !fromHome) {
                         setHasSeenSwipeUpOnboarding(true);
                     }
                     if (fromHome) {
                         setOpenedOverviewFromHomeCount(getOpenedOverviewFromHomeCount() + 1);
                     }
                     setOpenedOverviewCount(getOpenedOverviewCount() + 1);
+
+                    if (getOpenedOverviewCount() >= QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) {
+                        if (mHasDismissedQuickScrubTip) {
+                            mOverviewOpenedCountSinceQuickScrubTipDismiss++;
+                        }
+                    }
                 }
 
                 @Override
@@ -191,7 +193,11 @@
         public void onViewAttachedToWindow(View view) {
             if (view == mLayout) {
                 mLayoutAttachedToWindow = true;
-                mHasDismissedSwipeUpTip = false;
+                if (view.getTag().equals(R.string.recents_swipe_up_onboarding)) {
+                    mHasDismissedSwipeUpTip = false;
+                } else {
+                    mHasDismissedQuickScrubTip = false;
+                }
             }
         }
 
@@ -199,6 +205,17 @@
         public void onViewDetachedFromWindow(View view) {
             if (view == mLayout) {
                 mLayoutAttachedToWindow = false;
+                if (view.getTag().equals(R.string.recents_quick_scrub_onboarding)) {
+                    mHasDismissedQuickScrubTip = true;
+                    if (hasDismissedQuickScrubOnboardingOnce()) {
+                        // If user dismisses the quick scrub tip twice, we consider user has seen it
+                        // and do not show it again.
+                        setHasSeenQuickScrubOnboarding(true);
+                    } else {
+                        setHasDismissedQuickScrubOnboardingOnce(true);
+                    }
+                    mOverviewOpenedCountSinceQuickScrubTipDismiss = 0;
+                }
             }
         }
     };
@@ -228,15 +245,6 @@
             if (v.getTag().equals(R.string.recents_swipe_up_onboarding)) {
                 mHasDismissedSwipeUpTip = true;
                 mNumAppsLaunchedSinceSwipeUpTipDismiss = 0;
-            } else {
-                if (mHasDismissedQuickScrubTip) {
-                    // If user dismisses the quick scrub tip twice, we consider user has seen it
-                    // and do not show it again.
-                    setHasSeenQuickScrubOnboarding(true);
-                } else {
-                    mHasDismissedQuickScrubTip = true;
-                }
-                mNumAppsLaunchedSinceQuickScrubTipDismiss = 0;
             }
         });
 
@@ -252,6 +260,7 @@
         if (RESET_PREFS_FOR_DEBUG) {
             setHasSeenSwipeUpOnboarding(false);
             setHasSeenQuickScrubOnboarding(false);
+            setHasDismissedQuickScrubOnboardingOnce(false);
             setOpenedOverviewCount(0);
             setOpenedOverviewFromHomeCount(0);
         }
@@ -289,7 +298,7 @@
         mHasDismissedSwipeUpTip = false;
         mHasDismissedQuickScrubTip = false;
         mNumAppsLaunchedSinceSwipeUpTipDismiss = 0;
-        mNumAppsLaunchedSinceQuickScrubTipDismiss = 0;
+        mOverviewOpenedCountSinceQuickScrubTipDismiss = 0;
         hide(false);
     }
 
@@ -303,11 +312,15 @@
         if (!shouldShow()) {
             return;
         }
+        if (mLayoutAttachedToWindow) {
+            hide(false);
+        }
         mDismissView.setTag(stringRes);
+        mLayout.setTag(stringRes);
         mTextView.setText(stringRes);
         // Only show in portrait.
         int orientation = mContext.getResources().getConfiguration().orientation;
-        if (!mLayoutAttachedToWindow && orientation == Configuration.ORIENTATION_PORTRAIT) {
+        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
             mLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
 
             mWindowManager.addView(mLayout, getWindowLayoutParams());
@@ -348,11 +361,11 @@
                         .withLayer()
                         .setDuration(SHOW_HIDE_DURATION_MS)
                         .setInterpolator(new AccelerateInterpolator())
-                        .withEndAction(() -> mWindowManager.removeView(mLayout))
+                        .withEndAction(() -> mWindowManager.removeViewImmediate(mLayout))
                         .start();
             } else {
                 mLayout.animate().cancel();
-                mWindowManager.removeView(mLayout);
+                mWindowManager.removeViewImmediate(mLayout);
             }
         }
     }
@@ -400,6 +413,16 @@
         }
     }
 
+    private boolean hasDismissedQuickScrubOnboardingOnce() {
+        return Prefs.getBoolean(mContext, HAS_DISMISSED_RECENTS_QUICK_SCRUB_ONBOARDING_ONCE, false);
+    }
+
+    private void setHasDismissedQuickScrubOnboardingOnce(
+            boolean hasDismissedQuickScrubOnboardingOnce) {
+        Prefs.putBoolean(mContext, HAS_DISMISSED_RECENTS_QUICK_SCRUB_ONBOARDING_ONCE,
+                hasDismissedQuickScrubOnboardingOnce);
+    }
+
     private int getOpenedOverviewFromHomeCount() {
         return Prefs.getInt(mContext, OVERVIEW_OPENED_FROM_HOME_COUNT, 0);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 79fea9f..c8ee8735 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -376,15 +376,15 @@
     public Rect getNonMinimizedSplitScreenSecondaryBounds() {
         calculateBoundsForPosition(mSnapTargetBeforeMinimized.position,
                 DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect);
+        mOtherTaskRect.bottom -= mStableInsets.bottom;
         switch (mDockSide) {
             case WindowManager.DOCKED_LEFT:
+                mOtherTaskRect.top += mStableInsets.top;
                 mOtherTaskRect.right -= mStableInsets.right;
                 break;
             case WindowManager.DOCKED_RIGHT:
-                mOtherTaskRect.left -= mStableInsets.left;
-                break;
-            case WindowManager.DOCKED_TOP:
-                mOtherTaskRect.bottom -= mStableInsets.bottom;
+                mOtherTaskRect.top += mStableInsets.top;
+                mOtherTaskRect.left += mStableInsets.left;
                 break;
         }
         return mOtherTaskRect;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DndSuppressingNotificationsView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DndSuppressingNotificationsView.java
deleted file mode 100644
index db3a02d..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DndSuppressingNotificationsView.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.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 3efeb6e..27fa48a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -1635,6 +1635,7 @@
                 mTranslateableViews.get(i).setTranslationX(0);
             }
             invalidateOutline();
+            getEntry().expandedIcon.setScrollX(0);
         }
 
         mMenuRow.resetMenu();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index b442bb4..419e262 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -16,6 +16,11 @@
 
 package com.android.systemui.statusbar;
 
+import static android.app.Notification.CATEGORY_ALARM;
+import static android.app.Notification.CATEGORY_CALL;
+import static android.app.Notification.CATEGORY_EVENT;
+import static android.app.Notification.CATEGORY_MESSAGE;
+import static android.app.Notification.CATEGORY_REMINDER;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
@@ -52,6 +57,7 @@
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.policy.ZenModeController;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -68,6 +74,7 @@
     private final Environment mEnvironment;
     private HeadsUpManager mHeadsUpManager;
 
+    final ZenModeController mZen = Dependency.get(ZenModeController.class);
     final ForegroundServiceController mFsc = Dependency.get(ForegroundServiceController.class);
 
     public static final class Entry {
@@ -474,6 +481,10 @@
     }
 
     protected boolean isExemptFromDndVisualSuppression(Entry entry) {
+        if (isNotificationBlockedByPolicy(entry.notification.getNotification())) {
+            return false;
+        }
+
         if ((entry.notification.getNotification().flags
                 & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
             return true;
@@ -487,6 +498,26 @@
         return false;
     }
 
+    /**
+     * Categories that are explicitly called out on DND settings screens are always blocked, if
+     * DND has flagged them, even if they are foreground or system notifications that might
+     * otherwise visually bypass DND.
+     */
+    protected boolean isNotificationBlockedByPolicy(Notification n) {
+        if (isCategory(CATEGORY_CALL, n)
+                || isCategory(CATEGORY_MESSAGE, n)
+                || isCategory(CATEGORY_ALARM, n)
+                || isCategory(CATEGORY_EVENT, n)
+                || isCategory(CATEGORY_REMINDER, n)) {
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isCategory(String category, Notification n) {
+        return Objects.equals(n.category, category);
+    }
+
     public int getImportance(String key) {
         if (mRankingMap != null) {
             getRanking(key, mTmpRanking);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
index bf94c1f..c3b4fdd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
@@ -191,6 +191,7 @@
     }
 
     private void updateState(WifiIconState state) {
+        setContentDescription(state.contentDescription);
         if (mState.resId != state.resId && state.resId >= 0) {
             NeutralGoodDrawable drawable = NeutralGoodDrawable
                     .create(mLightContext, mDarkContext, state.resId);
@@ -212,6 +213,7 @@
     }
 
     private void initViewState() {
+        setContentDescription(mState.contentDescription);
         if (mState.resId >= 0) {
             NeutralGoodDrawable drawable = NeutralGoodDrawable.create(
                     mLightContext, mDarkContext, mState.resId);
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 5768fa2..fc76f78e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
@@ -38,6 +38,8 @@
 
 import androidx.car.widget.PagedListView;
 
+import androidx.core.graphics.drawable.RoundedBitmapDrawable;
+import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
 import com.android.internal.util.UserIcons;
 import com.android.settingslib.users.UserManagerHelper;
 import com.android.systemui.R;
@@ -193,7 +195,10 @@
         @Override
         public void onBindViewHolder(UserAdapterViewHolder holder, int position) {
             UserRecord userRecord = mUsers.get(position);
-            holder.mUserAvatarImageView.setImageBitmap(getUserRecordIcon(userRecord));
+            RoundedBitmapDrawable circleIcon = RoundedBitmapDrawableFactory.create(mRes,
+                getUserRecordIcon(userRecord));
+            circleIcon.setCircular(true);
+            holder.mUserAvatarImageView.setImageDrawable(circleIcon);
             holder.mUserNameTextView.setText(userRecord.mInfo.name);
             holder.mView.setOnClickListener(v -> {
                 if (userRecord == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
index fc8ceb6..8ede224 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
@@ -530,6 +530,7 @@
 
     protected void reset() {
         mTransformedView = null;
+        mTransformInfo = null;
         mSameAsAny = false;
         mTransformationEndX = UNDEFINED;
         mTransformationEndY = UNDEFINED;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
index 7284ee8..2161655 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
@@ -14,8 +14,12 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
 import android.view.View;
 
+import com.android.systemui.Interpolators;
 import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider.ButtonInterface;
 import com.android.systemui.statusbar.policy.KeyButtonDrawable;
 
@@ -26,6 +30,8 @@
  * multiples of the same nav bar icon appearing.
  */
 public class ButtonDispatcher {
+    private final static int FADE_DURATION_IN = 150;
+    private final static int FADE_DURATION_OUT = 100;
 
     private final ArrayList<View> mViews = new ArrayList<>();
 
@@ -36,13 +42,24 @@
     private View.OnLongClickListener mLongClickListener;
     private View.OnHoverListener mOnHoverListener;
     private Boolean mLongClickable;
-    private Integer mAlpha;
+    private Float mAlpha;
     private Float mDarkIntensity;
     private Integer mVisibility = -1;
     private Boolean mDelayTouchFeedback;
     private KeyButtonDrawable mImageDrawable;
     private View mCurrentView;
     private boolean mVertical;
+    private ValueAnimator mFadeAnimator;
+
+    private final ValueAnimator.AnimatorUpdateListener mAlphaListener = animation ->
+            setAlpha((float) animation.getAnimatedValue());
+
+    private final AnimatorListenerAdapter mFadeListener = new AnimatorListenerAdapter() {
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            setVisibility(getAlpha() == 1 ? View.VISIBLE : View.INVISIBLE);
+        }
+    };
 
     public ButtonDispatcher(int id) {
         mId = id;
@@ -64,19 +81,22 @@
         if (mAlpha != null) {
             view.setAlpha(mAlpha);
         }
-        if (mDarkIntensity != null) {
-            ((ButtonInterface) view).setDarkIntensity(mDarkIntensity);
-        }
-        if (mVisibility != null) {
+        if (mVisibility != null && mVisibility != -1) {
             view.setVisibility(mVisibility);
         }
-        if (mImageDrawable != null) {
-            ((ButtonInterface) view).setImageDrawable(mImageDrawable);
+        if (view instanceof ButtonInterface) {
+            final ButtonInterface button = (ButtonInterface) view;
+            if (mDarkIntensity != null) {
+                button.setDarkIntensity(mDarkIntensity);
+            }
+            if (mImageDrawable != null) {
+                button.setImageDrawable(mImageDrawable);
+            }
+            if (mDelayTouchFeedback != null) {
+                button.setDelayTouchFeedback(mDelayTouchFeedback);
+            }
+            button.setVertical(mVertical);
         }
-        if (mDelayTouchFeedback != null) {
-            ((ButtonInterface) view).setDelayTouchFeedback(mDelayTouchFeedback);
-        }
-        ((ButtonInterface) view).setVertical(mVertical);
     }
 
     public int getId() {
@@ -99,7 +119,9 @@
         mImageDrawable = drawable;
         final int N = mViews.size();
         for (int i = 0; i < N; i++) {
-            ((ButtonInterface) mViews.get(i)).setImageDrawable(mImageDrawable);
+            if (mViews.get(i) instanceof ButtonInterface) {
+                ((ButtonInterface) mViews.get(i)).setImageDrawable(mImageDrawable);
+            }
         }
     }
 
@@ -116,11 +138,13 @@
         // This seems to be an instantaneous thing, so not going to persist it.
         final int N = mViews.size();
         for (int i = 0; i < N; i++) {
-            ((ButtonInterface) mViews.get(i)).abortCurrentGesture();
+            if (mViews.get(i) instanceof ButtonInterface) {
+                ((ButtonInterface) mViews.get(i)).abortCurrentGesture();
+            }
         }
     }
 
-    public void setAlpha(int alpha) {
+    public void setAlpha(float alpha) {
         mAlpha = alpha;
         final int N = mViews.size();
         for (int i = 0; i < N; i++) {
@@ -132,7 +156,9 @@
         mDarkIntensity = darkIntensity;
         final int N = mViews.size();
         for (int i = 0; i < N; i++) {
-            ((ButtonInterface) mViews.get(i)).setDarkIntensity(darkIntensity);
+            if (mViews.get(i) instanceof ButtonInterface) {
+                ((ButtonInterface) mViews.get(i)).setDarkIntensity(darkIntensity);
+            }
         }
     }
 
@@ -140,7 +166,9 @@
         mDelayTouchFeedback = delay;
         final int N = mViews.size();
         for (int i = 0; i < N; i++) {
-            ((ButtonInterface) mViews.get(i)).setDelayTouchFeedback(delay);
+            if (mViews.get(i) instanceof ButtonInterface) {
+                ((ButtonInterface) mViews.get(i)).setDelayTouchFeedback(delay);
+            }
         }
     }
 
@@ -192,6 +220,19 @@
         }
     }
 
+    public void animateFade(boolean in) {
+        if (mFadeAnimator != null) {
+            mFadeAnimator.cancel();
+        }
+        mFadeAnimator = ValueAnimator.ofFloat(getAlpha(), in ? 1 : 0);
+        mFadeAnimator.setDuration(in? FADE_DURATION_IN : FADE_DURATION_OUT);
+        mFadeAnimator.setInterpolator(in ? Interpolators.ALPHA_IN : Interpolators.ALPHA_OUT);
+        mFadeAnimator.addListener(mFadeListener);
+        mFadeAnimator.addUpdateListener(mAlphaListener);
+        mFadeAnimator.start();
+        setVisibility(View.VISIBLE);
+    }
+
     public ArrayList<View> getViews() {
         return mViews;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
index 824960e..46b4078 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -24,6 +24,7 @@
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
 import android.widget.LinearLayout;
 
 import com.android.internal.statusbar.StatusBarIcon;
@@ -56,7 +57,14 @@
         mIconSize = iconSize;
         mColor = DarkIconDispatcher.DEFAULT_ICON_TINT;
 
+        if (statusIcons instanceof StatusIconContainer) {
+            setShouldRestrictIcons(((StatusIconContainer) statusIcons).isRestrictingIcons());
+        } else {
+            setShouldRestrictIcons(false);
+        }
         setLayoutParams(mStatusIcons.getLayoutParams());
+        setPadding(mStatusIcons.getPaddingLeft(),mStatusIcons.getPaddingTop(),
+                mStatusIcons.getPaddingRight(), mStatusIcons.getPaddingBottom());
         setOrientation(mStatusIcons.getOrientation());
         setGravity(Gravity.CENTER_VERTICAL); // no LL.getGravity()
         ViewGroup p = (ViewGroup) mStatusIcons.getParent();
@@ -77,6 +85,7 @@
         for (int i = 0; i < getChildCount(); i++) {
             StatusIconDisplayable child = (StatusIconDisplayable) getChildAt(i);
             child.setStaticDrawableColor(mColor);
+            child.setDecorColor(mColor);
         }
     }
 
@@ -189,11 +198,12 @@
         }
         StatusBarIcon icon = new StatusBarIcon(iconPkg, UserHandle.SYSTEM, iconId, 0, 0, "Demo");
         icon.visible = true;
-        StatusBarIconView v = new StatusBarIconView(getContext(), null, null);
+        StatusBarIconView v = new StatusBarIconView(getContext(), slot, null, false);
         v.setTag(slot);
         v.set(icon);
         v.setStaticDrawableColor(mColor);
-        addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
+        v.setDecorColor(mColor);
+        addView(v, 0, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize));
     }
 
     public void addDemoWifiView(WifiIconState state) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 91cf8f0..4885c2f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -168,10 +168,10 @@
         }
     }
 
-    public void setButtonDispatchers(SparseArray<ButtonDispatcher> buttonDisatchers) {
-        mButtonDispatchers = buttonDisatchers;
-        for (int i = 0; i < buttonDisatchers.size(); i++) {
-            initiallyFill(buttonDisatchers.valueAt(i));
+    public void setButtonDispatchers(SparseArray<ButtonDispatcher> buttonDispatchers) {
+        mButtonDispatchers = buttonDispatchers;
+        for (int i = 0; i < buttonDispatchers.size(); i++) {
+            initiallyFill(buttonDispatchers.valueAt(i));
         }
     }
 
@@ -220,7 +220,8 @@
             // and will only happen once.
             if (parent.getChildAt(i).getId() == buttonDispatcher.getId()) {
                 buttonDispatcher.addView(parent.getChildAt(i));
-            } else if (parent.getChildAt(i) instanceof ViewGroup) {
+            }
+            if (parent.getChildAt(i) instanceof ViewGroup) {
                 addAll(buttonDispatcher, (ViewGroup) parent.getChildAt(i));
             }
         }
@@ -411,7 +412,8 @@
             final int indexOfKey = mButtonDispatchers.indexOfKey(v.getId());
             if (indexOfKey >= 0) {
                 mButtonDispatchers.valueAt(indexOfKey).addView(v);
-            } else if (v instanceof ViewGroup) {
+            }
+            if (v instanceof ViewGroup) {
                 final ViewGroup viewGroup = (ViewGroup)v;
                 final int N = viewGroup.getChildCount();
                 for (int i = 0; i < N; i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 6dbe9f8..6cc96da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -260,6 +260,8 @@
                 new ButtonDispatcher(R.id.accessibility_button));
         mButtonDispatchers.put(R.id.rotate_suggestion,
                 new ButtonDispatcher(R.id.rotate_suggestion));
+        mButtonDispatchers.put(R.id.menu_container,
+                new ButtonDispatcher(R.id.menu_container));
         mDeadZone = new DeadZone(this);
     }
 
@@ -368,6 +370,10 @@
         return mButtonDispatchers.get(R.id.rotate_suggestion);
     }
 
+    public ButtonDispatcher getMenuContainer() {
+        return mButtonDispatchers.get(R.id.menu_container);
+    }
+
     public SparseArray<ButtonDispatcher> getButtonDispatchers() {
         return mButtonDispatchers;
     }
@@ -796,6 +802,10 @@
 
     public boolean isRotateButtonVisible() { return mShowRotateButton; }
 
+    public void setMenuContainerVisibility(boolean visible) {
+        getMenuContainer().animateFade(visible);
+    }
+
     @Override
     public void onFinishInflate() {
         mNavigationInflaterView = (NavigationBarInflaterView) findViewById(
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 8bb73da..b650944 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -199,7 +199,6 @@
     private ValueAnimator mQsSizeChangeAnimator;
 
     private boolean mShowEmptyShadeView;
-    private boolean mShowDndView;
 
     private boolean mQsScrimEnabled = true;
     private boolean mLastAnnouncementWasQuickSettings;
@@ -1600,8 +1599,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) || mShowDndView) {
+        if (mNotificationStackScroller.getNotGoneChildCount() == 0
+                && mShowEmptyShadeView) {
             notificationHeight = mNotificationStackScroller.getEmptyShadeViewHeight();
         }
         int maxQsHeight = mQsMaxExpansionHeight;
@@ -2244,17 +2243,13 @@
         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);
     }
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 6b0ac94..d9ba313 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -327,7 +327,7 @@
                 - mNavigationBarView.getPaddingTop();
         final int x1, x2, y1, y2;
         if (mIsVertical) {
-            x1 = (width - mTrackThickness) / 2 + mNavigationBarView.getPaddingStart();
+            x1 = (width - mTrackThickness) / 2 + mNavigationBarView.getPaddingLeft();
             x2 = x1 + mTrackThickness;
             y1 = mDragPositive ? height / 2 : mTrackPadding;
             y2 = y1 + height / 2 - mTrackPadding;
@@ -401,6 +401,10 @@
             mDarkTrackColor = mContext.getColor(R.color.quick_step_track_background_dark);
             mTrackAnimator.setFloatValues(0, 1);
             mTrackAnimator.start();
+
+            // Hide menu buttons on nav bar until quick scrub has ended
+            mNavigationBarView.setMenuContainerVisibility(false /* visible */);
+
             try {
                 mOverviewEventSender.getProxy().onQuickScrubStart();
                 if (DEBUG_OVERVIEW_PROXY) {
@@ -416,6 +420,10 @@
     private void endQuickScrub(boolean animate) {
         if (mQuickScrubActive || mDragScrubActive) {
             animateEnd();
+
+            // Restore the nav bar menu buttons visibility
+            mNavigationBarView.setMenuContainerVisibility(true /* visible */);
+
             if (mQuickScrubActive) {
                 try {
                     mOverviewEventSender.getProxy().onQuickScrubEnd();
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 5f07599..061677c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -20,7 +20,6 @@
 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;
@@ -169,7 +168,6 @@
 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;
@@ -190,7 +188,6 @@
 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;
@@ -416,7 +413,7 @@
     protected NotificationViewHierarchyManager mViewHierarchyManager;
     protected AppOpsListener mAppOpsListener;
     protected KeyguardViewMediator mKeyguardViewMediator;
-    protected ZenModeController mZenController;
+    private ZenModeController mZenController;
 
     /**
      * Helper that is responsible for showing the right toast when a disallowed activity operation
@@ -881,7 +878,6 @@
         mVisualStabilityManager.setVisibilityLocationProvider(mStackScroller);
 
         inflateEmptyShadeView();
-        inflateDndView();
         inflateFooterView();
 
         mBackdrop = mStatusBarWindow.findViewById(R.id.backdrop);
@@ -1149,7 +1145,6 @@
     protected void reevaluateStyles() {
         inflateFooterView();
         updateFooter();
-        inflateDndView();
         inflateEmptyShadeView();
         updateEmptyShadeView();
     }
@@ -1171,19 +1166,6 @@
         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;
@@ -1477,11 +1459,9 @@
     @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);
@@ -1504,13 +1484,10 @@
         return false;
     }
 
-    @VisibleForTesting
-    protected void updateEmptyShadeView() {
-        boolean showDndView = mState != StatusBarState.KEYGUARD && areNotificationsHidden();
-        boolean showEmptyShadeView = !showDndView
-                && mState != StatusBarState.KEYGUARD
-                && mEntryManager.getNotificationData().getActiveNotifications().size() == 0;
-        mNotificationPanel.showDndView(showDndView);
+    private void updateEmptyShadeView() {
+        boolean showEmptyShadeView =
+                mState != StatusBarState.KEYGUARD &&
+                        mEntryManager.getNotificationData().getActiveNotifications().size() == 0;
         mNotificationPanel.showEmptyShadeView(showEmptyShadeView);
     }
 
@@ -5017,7 +4994,6 @@
     protected NotificationShelf mNotificationShelf;
     protected FooterView mFooterView;
     protected EmptyShadeView mEmptyShadeView;
-    protected DndSuppressingNotificationsView mDndView;
 
     protected AssistManager mAssistManager;
 
@@ -5502,11 +5478,6 @@
                     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/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
index c97c8eb..8398879 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
@@ -73,19 +73,23 @@
 
     public StatusIconContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
+        initDimens();
+        setWillNotDraw(!DEBUG_OVERFLOW);
     }
 
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        setWillNotDraw(!DEBUG_OVERFLOW);
-        initDimens();
     }
 
     public void setShouldRestrictIcons(boolean should) {
         mShouldRestrictIcons = should;
     }
 
+    public boolean isRestrictingIcons() {
+        return mShouldRestrictIcons;
+    }
+
     private void initDimens() {
         // This is the same value that StatusBarIconView uses
         mIconDotFrameWidth = getResources().getDimensionPixelSize(
@@ -209,8 +213,8 @@
         int childCount = getChildCount();
         // Underflow === don't show content until that index
         int firstUnderflowIndex = -1;
-        if (DEBUG) android.util.Log.d(TAG, "calculateIconTransitions: start=" + translationX
-                + " width=" + width);
+        if (DEBUG) android.util.Log.d(TAG, "calculateIconTranslations: start=" + translationX
+                + " width=" + width + " underflow=" + mNeedsUnderflow);
 
         // Collect all of the states which want to be visible
         for (int i = childCount - 1; i >= 0; i--) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 6a8d3a5..48a9fb6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -20,6 +20,7 @@
 import android.app.Dialog;
 import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.UserHandle;
@@ -30,6 +31,7 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 
+
 /**
  * Base class for dialogs that should appear over panels and keyguard.
  */
@@ -99,24 +101,40 @@
     }
 
     public static void registerDismissListener(Dialog dialog) {
-        boolean[] registered = new boolean[1];
-        Context context = dialog.getContext();
-        final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                if (dialog != null) {
-                    dialog.dismiss();
-                }
-            }
-        };
-        context.registerReceiverAsUser(mReceiver, UserHandle.CURRENT,
-                new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), null, null);
-        registered[0] = true;
-        dialog.setOnDismissListener(d -> {
-            if (registered[0]) {
-                context.unregisterReceiver(mReceiver);
-                registered[0] = false;
-            }
-        });
+        DismissReceiver dismissReceiver = new DismissReceiver(dialog);
+        dismissReceiver.register();
     }
-}
+
+    private static class DismissReceiver extends BroadcastReceiver implements OnDismissListener {
+        private static final IntentFilter INTENT_FILTER = new IntentFilter();
+        static {
+            INTENT_FILTER.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+            INTENT_FILTER.addAction(Intent.ACTION_SCREEN_OFF);
+        }
+
+        private final Dialog mDialog;
+        private boolean mRegistered;
+
+        DismissReceiver(Dialog dialog) {
+            mDialog = dialog;
+        }
+
+        void register() {
+            mDialog.getContext()
+                    .registerReceiverAsUser(this, UserHandle.CURRENT, INTENT_FILTER, null, null);
+            mRegistered = true;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mDialog.dismiss();
+        }
+
+        @Override
+        public void onDismiss(DialogInterface dialog) {
+            if (mRegistered) {
+                mDialog.getContext().unregisterReceiver(this);
+                mRegistered = false;
+            }
+        }
+    }}
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 eeaa6cb..5275e27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -81,7 +81,6 @@
 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;
@@ -237,7 +236,6 @@
     protected boolean mScrollingEnabled;
     protected FooterView mFooterView;
     protected EmptyShadeView mEmptyShadeView;
-    protected DndSuppressingNotificationsView mDndView;
     private boolean mDismissAllInProgress;
     private boolean mFadeNotificationsOnDismiss;
 
@@ -1008,8 +1006,7 @@
     private float getAppearEndPosition() {
         int appearPosition;
         int notGoneChildCount = getNotGoneChildCount();
-        if ((mEmptyShadeView.getVisibility() == GONE && mDndView.getVisibility() == GONE)
-                && notGoneChildCount != 0) {
+        if (mEmptyShadeView.getVisibility() == GONE && notGoneChildCount != 0) {
             if (isHeadsUpTransition()
                     || (mHeadsUpManager.hasPinnedHeadsUp() && !mAmbientState.isDark())) {
                 appearPosition = getTopHeadsUpPinnedHeight();
@@ -1019,8 +1016,6 @@
                     appearPosition += mShelf.getIntrinsicHeight();
                 }
             }
-        } else if (mEmptyShadeView.getVisibility() == GONE) {
-            appearPosition = mDndView.getHeight();
         } else {
             appearPosition = mEmptyShadeView.getHeight();
         }
@@ -2613,6 +2608,19 @@
         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;
     }
@@ -3910,7 +3918,6 @@
         final int textColor = Utils.getColorAttr(context, R.attr.wallpaperTextColor);
         mFooterView.setTextColor(textColor);
         mEmptyShadeView.setTextColor(textColor);
-        mDndView.setColor(textColor);
     }
 
     public void goToFullShade(long delay) {
@@ -3918,7 +3925,6 @@
             mFooterView.setInvisible();
         }
         mEmptyShadeView.setInvisible();
-        mDndView.setInvisible();
         mGoToFullShadeNeedsAnimation = true;
         mGoToFullShadeDelay = delay;
         mNeedsAnimation = true;
@@ -4070,39 +4076,25 @@
         int newVisibility = visible ? VISIBLE : GONE;
 
         boolean changedVisibility = oldVisibility != newVisibility;
-        if (changedVisibility) {
+        if (changedVisibility || newVisibility != GONE) {
             if (newVisibility != GONE) {
-                showFooterView(mEmptyShadeView);
+                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);
+                }
             } 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;
@@ -4127,16 +4119,10 @@
         } else {
             footerView.setInvisible();
         }
-        Runnable onShowFinishRunnable = new Runnable() {
-            @Override
-            public void run() {
-                footerView.setVisibility(VISIBLE);
-                footerView.setWillBeGone(false);
-                updateContentHeight();
-                notifyHeightChangeListener(footerView);
-            }
-        };
-        footerView.performVisibilityAnimation(true, onShowFinishRunnable);
+        footerView.setVisibility(VISIBLE);
+        footerView.setWillBeGone(false);
+        updateContentHeight();
+        notifyHeightChangeListener(footerView);
     }
 
     private void hideFooterView(StackScrollerDecorView footerView, boolean isButtonVisible) {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
index 9a28657..210764a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
@@ -21,9 +21,6 @@
 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;
@@ -35,6 +32,7 @@
 
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import androidx.slice.SliceProvider;
 import androidx.slice.SliceSpecs;
@@ -58,12 +56,24 @@
     @Test
     public void showSlice_notifiesListener() {
         ListBuilder builder = new ListBuilder(getContext(), mSliceUri);
-        boolean[] notified = {false};
+        AtomicBoolean notified = new AtomicBoolean();
         mKeyguardSliceView.setContentChangeListener((hasHeader)-> {
-            notified[0] = true;
+            notified.set(true);
         });
         mKeyguardSliceView.onChanged(builder.build());
-        Assert.assertTrue("Listener should be notified about slice changes.", notified[0]);
+        Assert.assertTrue("Listener should be notified about slice changes.",
+                notified.get());
+    }
+
+    @Test
+    public void showSlice_emptySliceNotifiesListener() {
+        AtomicBoolean notified = new AtomicBoolean();
+        mKeyguardSliceView.setContentChangeListener((hasHeader)-> {
+            notified.set(true);
+        });
+        mKeyguardSliceView.onChanged(null);
+        Assert.assertTrue("Listener should be notified about slice changes.",
+                notified.get());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
index ab042d4..2a4a5ad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
@@ -298,4 +298,13 @@
 
         assertEquals(3, mGroupRow.getNumUniqueChannels());
     }
+
+    @Test
+    public void testIconScrollXAfterTranslationAndReset() throws Exception {
+        mGroupRow.setTranslation(50);
+        assertEquals(50, -mGroupRow.getEntry().expandedIcon.getScrollX());
+
+        mGroupRow.resetTranslation();
+        assertEquals(0, mGroupRow.getEntry().expandedIcon.getScrollX());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
index d3c3746..8bdaff9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
@@ -18,6 +18,11 @@
 
 import static android.app.AppOpsManager.OP_ACCEPT_HANDOVER;
 import static android.app.AppOpsManager.OP_CAMERA;
+import static android.app.Notification.CATEGORY_ALARM;
+import static android.app.Notification.CATEGORY_CALL;
+import static android.app.Notification.CATEGORY_EVENT;
+import static android.app.Notification.CATEGORY_MESSAGE;
+import static android.app.Notification.CATEGORY_REMINDER;
 
 import static junit.framework.Assert.assertEquals;
 
@@ -312,6 +317,40 @@
         assertFalse(mNotificationData.shouldSuppressAmbient(entry));
     }
 
+    @Test
+    public void testIsNotExemptFromDndVisualSuppression_hiddenCategories() {
+        initStatusBarNotification(false);
+        when(mMockStatusBarNotification.getKey()).thenReturn(
+                TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY);
+        NotificationData.Entry entry = new NotificationData.Entry(mMockStatusBarNotification);
+        entry.mIsSystemNotification = true;
+        when(mMockStatusBarNotification.getNotification()).thenReturn(
+                new Notification.Builder(mContext, "").setCategory(CATEGORY_CALL).build());
+
+        assertFalse(mNotificationData.isExemptFromDndVisualSuppression(entry));
+        assertTrue(mNotificationData.shouldSuppressAmbient(entry));
+
+        when(mMockStatusBarNotification.getNotification()).thenReturn(
+                new Notification.Builder(mContext, "").setCategory(CATEGORY_REMINDER).build());
+
+        assertFalse(mNotificationData.isExemptFromDndVisualSuppression(entry));
+
+        when(mMockStatusBarNotification.getNotification()).thenReturn(
+                new Notification.Builder(mContext, "").setCategory(CATEGORY_ALARM).build());
+
+        assertFalse(mNotificationData.isExemptFromDndVisualSuppression(entry));
+
+        when(mMockStatusBarNotification.getNotification()).thenReturn(
+                new Notification.Builder(mContext, "").setCategory(CATEGORY_EVENT).build());
+
+        assertFalse(mNotificationData.isExemptFromDndVisualSuppression(entry));
+
+        when(mMockStatusBarNotification.getNotification()).thenReturn(
+                new Notification.Builder(mContext, "").setCategory(CATEGORY_MESSAGE).build());
+
+        assertFalse(mNotificationData.isExemptFromDndVisualSuppression(entry));
+    }
+
     private void initStatusBarNotification(boolean allowDuringSetup) {
         Bundle bundle = new Bundle();
         bundle.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, allowDuringSetup);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java
new file mode 100644
index 0000000..5429153
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java
@@ -0,0 +1,41 @@
+/*
+ * 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.phone;
+
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class KeyguardPresentationTest extends SysuiTestCase {
+    @Test
+    public void testInflation_doesntCrash() {
+        LayoutInflater inflater = LayoutInflater.from(getContext());
+        inflater.inflate(R.layout.keyguard_presentation, null);
+    }
+}
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 41cf869..37e0005 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,7 +78,6 @@
 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;
@@ -104,7 +103,6 @@
 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;
@@ -134,7 +132,6 @@
     @Mock private ScrimController mScrimController;
     @Mock private ArrayList<Entry> mNotificationList;
     @Mock private FingerprintUnlockController mFingerprintUnlockController;
-    @Mock private ZenModeController mZenController;
     @Mock private NotificationData mNotificationData;
 
     // Mock dependencies:
@@ -166,7 +163,6 @@
         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));
@@ -217,7 +213,7 @@
                 mRemoteInputManager, mock(NotificationGroupManager.class),
                 mock(FalsingManager.class), mock(StatusBarWindowManager.class),
                 mock(NotificationIconAreaController.class), mock(DozeScrimController.class),
-                mock(NotificationShelf.class), mLockscreenUserManager, mZenController,
+                mock(NotificationShelf.class), mLockscreenUserManager,
                 mock(CommandQueue.class));
         mStatusBar.mContext = mContext;
         mStatusBar.mComponents = mContext.getComponents();
@@ -680,60 +676,6 @@
     }
 
     @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());
@@ -779,7 +721,6 @@
                 DozeScrimController dozeScrimController,
                 NotificationShelf notificationShelf,
                 NotificationLockscreenUserManager notificationLockscreenUserManager,
-                ZenModeController zenController,
                 CommandQueue commandQueue) {
             mStatusBarKeyguardViewManager = man;
             mUnlockMethodCache = unlock;
@@ -808,7 +749,6 @@
             mDozeScrimController = dozeScrimController;
             mNotificationShelf = notificationShelf;
             mLockscreenUserManager = notificationLockscreenUserManager;
-            mZenController = zenController;
             mCommandQueue = commandQueue;
         }
 
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 3d17ec4..eeb4209 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,7 +18,6 @@
 
 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;
@@ -35,7 +34,6 @@
 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;
@@ -71,7 +69,6 @@
     @Mock private NotificationGroupManager mGroupManager;
     @Mock private ExpandHelper mExpandHelper;
     @Mock private EmptyShadeView mEmptyShadeView;
-    @Mock private DndSuppressingNotificationsView mDndView;
 
     @Before
     @UiThreadTest
@@ -89,7 +86,6 @@
         mStackScroller.setHeadsUpManager(mHeadsUpManager);
         mStackScroller.setGroupManager(mGroupManager);
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
-        mStackScroller.setDndView(mDndView);
 
         // Stub out functionality that isn't necessary to test.
         doNothing().when(mBar)
@@ -124,6 +120,40 @@
     }
 
     @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);
@@ -143,7 +173,7 @@
 
         mStackScroller.updateFooterView(true, false);
 
-        verify(view).performVisibilityAnimation(eq(true), any());
+        verify(view).setVisibility(View.VISIBLE);
         verify(view).performSecondaryVisibilityAnimation(false);
     }
 
@@ -156,7 +186,7 @@
 
         mStackScroller.updateFooterView(true, true);
 
-        verify(view).performVisibilityAnimation(eq(true), any());
+        verify(view).setVisibility(View.VISIBLE);
         verify(view).performSecondaryVisibilityAnimation(true);
     }
 }
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 7dd85ba..d61f228 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -5740,6 +5740,41 @@
     // OS: P
     ACTION_ZEN_ONBOARDING_KEEP_CURRENT_SETTINGS = 1406;
 
+    // ACTION: Storage initialization wizard initialization choice of external/portable
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_STORAGE_INIT_EXTERNAL = 1407;
+
+    // ACTION: Storage initialization wizard initialization choice of internal/adoptable
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_STORAGE_INIT_INTERNAL = 1408;
+
+    // ACTION: Storage initialization wizard benchmark fast choice of continue
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_STORAGE_BENCHMARK_FAST_CONTINUE = 1409;
+
+    // ACTION: Storage initialization wizard benchmark slow choice of continue
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_STORAGE_BENCHMARK_SLOW_CONTINUE = 1410;
+
+    // ACTION: Storage initialization wizard benchmark slow choice of abort
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_STORAGE_BENCHMARK_SLOW_ABORT = 1411;
+
+    // ACTION: Storage initialization wizard migration choice of now
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_STORAGE_MIGRATE_NOW = 1412;
+
+    // ACTION: Storage initialization wizard migration choice of later
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_STORAGE_MIGRATE_LATER = 1413;
+
     // ---- End P Constants, all P constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
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..cc7304a 100644
--- a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
+++ b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
@@ -629,6 +629,8 @@
             mFullBackupTask.unregisterTask();
             switch (mStatus) {
                 case BackupTransport.TRANSPORT_OK:
+                case BackupTransport.TRANSPORT_QUOTA_EXCEEDED:
+                case BackupTransport.TRANSPORT_PACKAGE_REJECTED:
                     BackupObserverUtils.sendBackupFinished(mObserver,
                             BackupManager.SUCCESS);
                     break;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 99944625..72f9d74 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -132,6 +132,7 @@
 import com.android.internal.net.VpnConfig;
 import com.android.internal.net.VpnInfo;
 import com.android.internal.net.VpnProfile;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
@@ -1992,13 +1993,6 @@
         return ret;
     }
 
-    private boolean argsContain(String[] args, String target) {
-        for (String arg : args) {
-            if (target.equals(arg)) return true;
-        }
-        return false;
-    }
-
     private void dumpNetworkDiagnostics(IndentingPrintWriter pw) {
         final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>();
         final long DIAG_TIME_MS = 5000;
@@ -2027,10 +2021,10 @@
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
         if (asProto) return;
 
-        if (argsContain(args, DIAG_ARG)) {
+        if (ArrayUtils.contains(args, DIAG_ARG)) {
             dumpNetworkDiagnostics(pw);
             return;
-        } else if (argsContain(args, TETHERING_ARG)) {
+        } else if (ArrayUtils.contains(args, TETHERING_ARG)) {
             mTethering.dump(fd, pw, args);
             return;
         }
@@ -2098,7 +2092,7 @@
         pw.println();
         mMultipathPolicyTracker.dump(pw);
 
-        if (argsContain(args, SHORT_ARG) == false) {
+        if (ArrayUtils.contains(args, SHORT_ARG) == false) {
             pw.println();
             synchronized (mValidationLogs) {
                 pw.println("mValidationLogs (most recent first):");
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 6c35bda..00302b2 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -2541,11 +2541,6 @@
         synchronized (mLock) {
             mLocalUnlockedUsers = ArrayUtils.appendInt(mLocalUnlockedUsers, userId);
         }
-        if (userId == UserHandle.USER_SYSTEM) {
-            String propertyName = "sys.user." + userId + ".ce_available";
-            Slog.d(TAG, "Setting property: " + propertyName + "=true");
-            SystemProperties.set(propertyName, "true");
-        }
     }
 
     @Override
@@ -2685,7 +2680,8 @@
         }
 
         // Ignore requests to create directories if CE storage is not available
-        if (!SystemProperties.getBoolean(propertyName, false)) {
+        if ((userId == UserHandle.USER_SYSTEM)
+                && !SystemProperties.getBoolean(propertyName, false)) {
             throw new IllegalStateException("Failed to prepare " + appPath);
         }
 
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 26a8cf7..f24d8cd 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -71,6 +71,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.function.Predicate;
 
 public class TextServicesManagerService extends ITextServicesManager.Stub {
     private static final String TAG = TextServicesManagerService.class.getSimpleName();
@@ -396,10 +397,7 @@
                     final String packageName = sci.getPackageName();
                     final int change = isPackageDisappearing(packageName);
                     if (DBG) Slog.d(TAG, "Changing package name: " + packageName);
-                    if (// Package disappearing
-                            change == PACKAGE_PERMANENT_CHANGE || change == PACKAGE_TEMPORARY_CHANGE
-                                    // Package modified
-                                    || isPackageModified(packageName)) {
+                    if (change == PACKAGE_PERMANENT_CHANGE || change == PACKAGE_TEMPORARY_CHANGE) {
                         SpellCheckerInfo availSci =
                                 findAvailSystemSpellCheckerLocked(packageName, tsd);
                         // Set the spell checker settings if different than before
@@ -885,6 +883,11 @@
             }
             synchronized (mLock) {
                 mListeners.unregister(listener);
+                final IBinder scListenerBinder = listener.asBinder();
+                final Predicate<SessionRequest> removeCondition =
+                        request -> request.mScListener.asBinder() == scListenerBinder;
+                mPendingSessionRequests.removeIf(removeCondition);
+                mOnGoingSessionRequests.removeIf(removeCondition);
                 cleanLocked();
             }
         }
@@ -934,6 +937,7 @@
             if (mUnbindCalled) {
                 return;
             }
+            mListeners.register(request.mScListener);
             if (!mConnected) {
                 mPendingSessionRequests.add(request);
                 return;
@@ -959,7 +963,6 @@
                 if (mOnGoingSessionRequests.remove(request)) {
                     try {
                         request.mTsListener.onServiceConnected(newSession);
-                        mListeners.register(request.mScListener);
                     } catch (RemoteException e) {
                         // Technically this can happen if the spell checker client app is already
                         // dead.  We can just forget about this request; the request is already
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index f413639..b32ece7 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -108,6 +108,8 @@
 
     private static final boolean LOG_SERVICE_START_STOP = false;
 
+    private static final boolean SHOW_DUNGEON_NOTIFICATION = false;
+
     // How long we wait for a service to finish executing.
     static final int SERVICE_TIMEOUT = 20*1000;
 
@@ -942,6 +944,10 @@
             smap.mActiveForegroundAppsChanged = false;
         }
 
+        if (!SHOW_DUNGEON_NOTIFICATION) {
+            return;
+        }
+
         final NotificationManager nm = (NotificationManager) mAm.mContext.getSystemService(
                 Context.NOTIFICATION_SERVICE);
         final Context context = mAm.mContext;
diff --git a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
index 1149e87..7599afa 100644
--- a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
@@ -20,33 +20,41 @@
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.graphics.RectF;
 import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
 import android.os.UserManager;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.TextView;
 import com.android.internal.R;
-import com.android.server.pm.UserManagerService;
-import java.io.FileDescriptor;
+
 
 /**
  * Dialog to show when a user switch it about to happen for the car. The intent is to snapshot the
  * screen immediately after the dialog shows so that the user is informed that something is
  * happening in the background rather than just freeze the screen and not know if the user-switch
  * affordance was being handled.
- *
  */
 final class CarUserSwitchingDialog extends UserSwitchingDialog {
+
     private static final String TAG = "ActivityManagerCarUserSwitchingDialog";
 
     public CarUserSwitchingDialog(ActivityManagerService service, Context context, UserInfo oldUser,
-        UserInfo newUser, boolean aboveSystem, String switchingFromSystemUserMessage,
-        String switchingToSystemUserMessage) {
+            UserInfo newUser, boolean aboveSystem, String switchingFromSystemUserMessage,
+            String switchingToSystemUserMessage) {
         super(service, context, oldUser, newUser, aboveSystem, switchingFromSystemUserMessage,
-            switchingToSystemUserMessage);
+                switchingToSystemUserMessage);
 
         getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
     }
@@ -58,18 +66,104 @@
         Resources res = getContext().getResources();
         // Custom view due to alignment and font size requirements
         View view = LayoutInflater.from(getContext()).inflate(R.layout.car_user_switching_dialog,
-            null);
+                null);
 
         UserManager userManager =
                 (UserManager) getContext().getSystemService(Context.USER_SERVICE);
         Bitmap bitmap = userManager.getUserIcon(mNewUser.id);
         if (bitmap != null) {
+            CircleFramedDrawable drawable = CircleFramedDrawable.getInstance(bitmap,
+                    res.getDimension(R.dimen.car_fullscreen_user_pod_image_avatar_height));
             ((ImageView) view.findViewById(R.id.user_loading_avatar))
-                    .setImageBitmap(bitmap);
+                    .setImageDrawable(drawable);
         }
 
         ((TextView) view.findViewById(R.id.user_loading))
-            .setText(res.getString(R.string.car_loading_profile));
+                .setText(res.getString(R.string.car_loading_profile));
         setView(view);
     }
+
+    /**
+     * Converts the user icon to a circularly clipped one.  This is used in the User Picker and
+     * Settings.
+     */
+    static class CircleFramedDrawable extends Drawable {
+
+        private final Bitmap mBitmap;
+        private final int mSize;
+        private final Paint mPaint;
+
+        private float mScale;
+        private Rect mSrcRect;
+        private RectF mDstRect;
+
+        public static CircleFramedDrawable getInstance(Bitmap icon, float iconSize) {
+            CircleFramedDrawable instance = new CircleFramedDrawable(icon, (int) iconSize);
+            return instance;
+        }
+
+        public CircleFramedDrawable(Bitmap icon, int size) {
+            super();
+            mSize = size;
+
+            mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888);
+            final Canvas canvas = new Canvas(mBitmap);
+
+            final int width = icon.getWidth();
+            final int height = icon.getHeight();
+            final int square = Math.min(width, height);
+
+            final Rect cropRect = new Rect((width - square) / 2, (height - square) / 2,
+                    square, square);
+            final RectF circleRect = new RectF(0f, 0f, mSize, mSize);
+
+            final Path fillPath = new Path();
+            fillPath.addArc(circleRect, 0f, 360f);
+
+            canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+
+            // opaque circle
+            mPaint = new Paint();
+            mPaint.setAntiAlias(true);
+            mPaint.setColor(Color.BLACK);
+            mPaint.setStyle(Paint.Style.FILL);
+            canvas.drawPath(fillPath, mPaint);
+
+            // mask in the icon where the bitmap is opaque
+            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
+            canvas.drawBitmap(icon, cropRect, circleRect, mPaint);
+
+            // prepare paint for frame drawing
+            mPaint.setXfermode(null);
+
+            mScale = 1f;
+
+            mSrcRect = new Rect(0, 0, mSize, mSize);
+            mDstRect = new RectF(0, 0, mSize, mSize);
+        }
+
+        @Override
+        public void draw(Canvas canvas) {
+            final float inside = mScale * mSize;
+            final float pad = (mSize - inside) / 2f;
+
+            mDstRect.set(pad, pad, mSize - pad, mSize - pad);
+            canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null);
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+            // Needed to implement abstract method.  Do nothing.
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter colorFilter) {
+            // Needed to implement abstract method.  Do nothing.
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/am/RecentsAnimation.java b/services/core/java/com/android/server/am/RecentsAnimation.java
index b5047ae..a88f408 100644
--- a/services/core/java/com/android/server/am/RecentsAnimation.java
+++ b/services/core/java/com/android/server/am/RecentsAnimation.java
@@ -238,7 +238,9 @@
 
                     final ActivityStack targetStack = mDefaultDisplay.getStack(
                             WINDOWING_MODE_UNDEFINED, mTargetActivityType);
-                    final ActivityRecord targetActivity = targetStack.getTopActivity();
+                    final ActivityRecord targetActivity = targetStack != null
+                            ? targetStack.getTopActivity()
+                            : null;
                     if (DEBUG) Slog.d(TAG, "onAnimationFinished(): targetStack=" + targetStack
                             + " targetActivity=" + targetActivity
                             + " mRestoreTargetBehindStack=" + mRestoreTargetBehindStack);
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
index f427819..ac74598 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
@@ -20,6 +20,7 @@
 import android.net.ConnectivityMetricsEvent;
 import android.net.IIpConnectivityMetrics;
 import android.net.INetdEventCallback;
+import android.net.ip.IpClient;
 import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.IpConnectivityLog;
 import android.os.Binder;
@@ -269,10 +270,12 @@
         // Dump the rolling buffer of metrics event and pretty print events using a human readable
         // format. Also print network dns/connect statistics and default network event time series.
         static final String CMD_LIST = "list";
-        // By default any other argument will fall into the default case which is remapped to the
-        // "list" command. This includes most notably bug reports collected by dumpsys.cpp with
-        // the "-a" argument.
-        static final String CMD_DEFAULT = CMD_LIST;
+        // Dump all IpClient logs ("ipclient").
+        static final String CMD_IPCLIENT = IpClient.DUMP_ARG;
+        // By default any other argument will fall into the default case which is the equivalent
+        // of calling both the "list" and "ipclient" commands. This includes most notably bug
+        // reports collected by dumpsys.cpp with the "-a" argument.
+        static final String CMD_DEFAULT = "";
 
         @Override
         public int logEvent(ConnectivityMetricsEvent event) {
@@ -292,9 +295,20 @@
                 case CMD_PROTO:
                     cmdListAsProto(pw);
                     return;
-                case CMD_LIST: // fallthrough
+                case CMD_IPCLIENT: {
+                    final String[] ipclientArgs = ((args != null) && (args.length > 1))
+                            ? Arrays.copyOfRange(args, 1, args.length)
+                            : null;
+                    IpClient.dumpAllLogs(pw, ipclientArgs);
+                    return;
+                }
+                case CMD_LIST:
+                    cmdList(pw);
+                    return;
                 default:
                     cmdList(pw);
+                    pw.println("");
+                    IpClient.dumpAllLogs(pw, null);
                     return;
             }
         }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index b68ef11..bf17798 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4051,17 +4051,29 @@
         final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
         r.setIsAppImportanceLocked(mRankingHelper.getIsAppImportanceLocked(pkg, callingUid));
 
-        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
-            // opinion otherwise
-            if (TextUtils.isEmpty(channelId)
-                    || NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
-                r.setImportance(IMPORTANCE_LOW, "Bumped for foreground service");
-            } else {
-                channel.setImportance(IMPORTANCE_LOW);
-                mRankingHelper.updateNotificationChannel(pkg, notificationUid, channel, false);
+        if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
+            final boolean fgServiceShown = channel.isFgServiceShown();
+            if (((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0
+                        || !fgServiceShown)
+                    && (r.getImportance() == IMPORTANCE_MIN
+                            || r.getImportance() == IMPORTANCE_NONE)) {
+                // Increase the importance of foreground service notifications unless the user had
+                // an opinion otherwise (and the channel hasn't yet shown a fg service).
+                if (TextUtils.isEmpty(channelId)
+                        || NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
+                    r.setImportance(IMPORTANCE_LOW, "Bumped for foreground service");
+                } else {
+                    channel.setImportance(IMPORTANCE_LOW);
+                    if (!fgServiceShown) {
+                        channel.unlockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+                        channel.setFgServiceShown(true);
+                    }
+                    mRankingHelper.updateNotificationChannel(pkg, notificationUid, channel, false);
+                    r.updateNotificationChannel(channel);
+                }
+            } else if (!fgServiceShown && !TextUtils.isEmpty(channelId)
+                    && !NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
+                channel.setFgServiceShown(true);
                 r.updateNotificationChannel(channel);
             }
         }
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index dbf0940..d0a3757 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -16,6 +16,8 @@
 
 package com.android.server.pm;
 
+import static android.content.Intent.FLAG_ACTIVITY_MATCH_EXTERNAL;
+
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_INSTANT_APP_RESOLUTION_PHASE_ONE;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_INSTANT_APP_RESOLUTION_PHASE_TWO;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INSTANT_APP_LAUNCH_TOKEN;
@@ -366,6 +368,7 @@
         final Intent failureIntent = new Intent(origIntent);
         boolean requiresSecondPhase = false;
         failureIntent.setFlags(failureIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL);
+        failureIntent.setFlags(failureIntent.getFlags() & ~Intent.FLAG_ACTIVITY_MATCH_EXTERNAL);
         failureIntent.setLaunchToken(token);
         ArrayList<AuxiliaryResolveInfo.AuxiliaryFilter> filters = null;
         boolean isWebIntent = origIntent.isWebIntent();
@@ -408,6 +411,10 @@
         if (filters != null && !filters.isEmpty()) {
             return new AuxiliaryResolveInfo(token, requiresSecondPhase, failureIntent, filters);
         }
+        // if the match external flag is set, return an empty resolve info
+        if ((origIntent.getFlags() & FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
+            return new AuxiliaryResolveInfo(token, false, failureIntent, null /* filters */);
+        }
         // Hash or filter mis-match; no instant apps for this domain.
         return null;
     }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index f7a0215..fa934fe 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -17,7 +17,6 @@
 package com.android.server.pm;
 
 import static android.content.pm.PackageManager.INSTALL_FAILED_ABORTED;
-import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_DEX_METADATA;
 import static android.content.pm.PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
@@ -74,6 +73,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.RevocableFileDescriptor;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
 import android.system.ErrnoException;
@@ -111,9 +111,9 @@
 import java.io.FileFilter;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.security.cert.CertificateException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -154,6 +154,8 @@
     private static final String ATTR_NAME = "name";
     private static final String ATTR_INSTALL_REASON = "installRason";
 
+    private static final String PROPERTY_NAME_INHERIT_NATIVE = "pi.inherit_native_on_dont_kill";
+
     // TODO: enforce INSTALL_ALLOW_TEST
     // TODO: enforce INSTALL_ALLOW_DOWNGRADE
 
@@ -255,6 +257,8 @@
     @GuardedBy("mLock")
     private final List<String> mResolvedInstructionSets = new ArrayList<>();
     @GuardedBy("mLock")
+    private final List<String> mResolvedNativeLibPaths = new ArrayList<>();
+    @GuardedBy("mLock")
     private File mInheritedFilesBase;
 
     private static final FileFilter sAddedFilter = new FileFilter() {
@@ -971,6 +975,26 @@
                         final File oatDir = new File(toDir, "oat");
                         createOatDirs(mResolvedInstructionSets, oatDir);
                     }
+                    // pre-create lib dirs for linking if necessary
+                    if (!mResolvedNativeLibPaths.isEmpty()) {
+                        for (String libPath : mResolvedNativeLibPaths) {
+                            // "/lib/arm64" -> ["lib", "arm64"]
+                            final int splitIndex = libPath.lastIndexOf('/');
+                            if (splitIndex < 0 || splitIndex >= libPath.length() - 1) {
+                                Slog.e(TAG, "Skipping native library creation for linking due to "
+                                        + "invalid path: " + libPath);
+                                continue;
+                            }
+                            final String libDirPath = libPath.substring(1, splitIndex);
+                            final File libDir = new File(toDir, libDirPath);
+                            if (!libDir.exists()) {
+                                NativeLibraryHelper.createNativeLibrarySubdir(libDir);
+                            }
+                            final String archDirPath = libPath.substring(splitIndex + 1);
+                            NativeLibraryHelper.createNativeLibrarySubdir(
+                                    new File(libDir, archDirPath));
+                        }
+                    }
                     linkFiles(fromFiles, toDir, mInheritedFilesBase);
                 } else {
                     // TODO: this should delegate to DCS so the system process
@@ -988,7 +1012,7 @@
         computeProgressLocked(true);
 
         // Unpack native libraries
-        extractNativeLibraries(mResolvedStageDir, params.abiOverride);
+        extractNativeLibraries(mResolvedStageDir, params.abiOverride, mayInheritNativeLibs());
 
         // We've reached point of no return; call into PMS to install the stage.
         // Regardless of success or failure we always destroy session.
@@ -1028,6 +1052,17 @@
     }
 
     /**
+     * Returns true if the session should attempt to inherit any existing native libraries already
+     * extracted at the current install location. This is necessary to prevent double loading of
+     * native libraries already loaded by the running app.
+     */
+    private boolean mayInheritNativeLibs() {
+        return SystemProperties.getBoolean(PROPERTY_NAME_INHERIT_NATIVE, true) &&
+                params.mode == SessionParams.MODE_INHERIT_EXISTING &&
+                (params.installFlags & PackageManager.DONT_KILL_APP) != 0;
+    }
+
+    /**
      * Validate install by confirming that all application packages are have
      * consistent package name, version code, and signing certificates.
      * <p>
@@ -1249,6 +1284,38 @@
                     }
                 }
             }
+
+            // Inherit native libraries for DONT_KILL sessions.
+            if (mayInheritNativeLibs() && removeSplitList.isEmpty()) {
+                File[] libDirs = new File[]{
+                        new File(packageInstallDir, NativeLibraryHelper.LIB_DIR_NAME),
+                        new File(packageInstallDir, NativeLibraryHelper.LIB64_DIR_NAME)};
+                for (File libDir : libDirs) {
+                    if (!libDir.exists() || !libDir.isDirectory()) {
+                        continue;
+                    }
+                    final List<File> libDirsToInherit = new LinkedList<>();
+                    for (File archSubDir : libDir.listFiles()) {
+                        if (!archSubDir.isDirectory()) {
+                            continue;
+                        }
+                        String relLibPath;
+                        try {
+                            relLibPath = getRelativePath(archSubDir, packageInstallDir);
+                        } catch (IOException e) {
+                            Slog.e(TAG, "Skipping linking of native library directory!", e);
+                            // shouldn't be possible, but let's avoid inheriting these to be safe
+                            libDirsToInherit.clear();
+                            break;
+                        }
+                        if (!mResolvedNativeLibPaths.contains(relLibPath)) {
+                            mResolvedNativeLibPaths.add(relLibPath);
+                        }
+                        libDirsToInherit.addAll(Arrays.asList(archSubDir.listFiles()));
+                    }
+                    mResolvedInheritedFiles.addAll(libDirsToInherit);
+                }
+            }
         }
     }
 
@@ -1374,11 +1441,13 @@
         Slog.d(TAG, "Copied " + fromFiles.size() + " files into " + toDir);
     }
 
-    private static void extractNativeLibraries(File packageDir, String abiOverride)
+    private static void extractNativeLibraries(File packageDir, String abiOverride, boolean inherit)
             throws PackageManagerException {
-        // Always start from a clean slate
         final File libDir = new File(packageDir, NativeLibraryHelper.LIB_DIR_NAME);
-        NativeLibraryHelper.removeNativeBinariesFromDirLI(libDir, true);
+        if (!inherit) {
+            // Start from a clean slate
+            NativeLibraryHelper.removeNativeBinariesFromDirLI(libDir, true);
+        }
 
         NativeLibraryHelper.Handle handle = null;
         try {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 681b0c9..af5521d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -16403,22 +16403,6 @@
         }
     }
 
-    @Override
-    public List<String> getPreviousCodePaths(String packageName) {
-        final int callingUid = Binder.getCallingUid();
-        final List<String> result = new ArrayList<>();
-        if (getInstantAppPackageName(callingUid) != null) {
-            return result;
-        }
-        final PackageSetting ps = mSettings.mPackages.get(packageName);
-        if (ps != null
-                && ps.oldCodePaths != null
-                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
-            result.addAll(ps.oldCodePaths);
-        }
-        return result;
-    }
-
     private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
             PackageParser.Package pkg, final @ParseFlags int parseFlags,
             final @ScanFlags int scanFlags, UserHandle user, int[] allUsers,
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 898ecf3..f8bf9c4 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -844,7 +844,12 @@
         }
         // If what we are scanning is a system (and possibly privileged) package,
         // then make it so, regardless of whether it was previously installed only
-        // in the data partition.
+        // in the data partition. Reset first.
+        pkgSetting.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
+        pkgSetting.pkgPrivateFlags &= ~(ApplicationInfo.PRIVATE_FLAG_PRIVILEGED
+                | ApplicationInfo.PRIVATE_FLAG_OEM
+                | ApplicationInfo.PRIVATE_FLAG_VENDOR
+                | ApplicationInfo.PRIVATE_FLAG_PRODUCT);
         pkgSetting.pkgFlags |= pkgFlags & ApplicationInfo.FLAG_SYSTEM;
         pkgSetting.pkgPrivateFlags |=
                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java
index 96c102b..045a295 100644
--- a/services/core/java/com/android/server/pm/UserDataPreparer.java
+++ b/services/core/java/com/android/server/pm/UserDataPreparer.java
@@ -24,6 +24,8 @@
 import android.os.FileUtils;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
+import android.os.SystemProperties;
+import android.os.UserHandle;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -96,6 +98,14 @@
             }
 
             mInstaller.createUserData(volumeUuid, userId, userSerial, flags);
+
+            // CE storage is available after they are prepared.
+            if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 &&
+                    (userId == UserHandle.USER_SYSTEM)) {
+                String propertyName = "sys.user." + userId + ".ce_available";
+                Slog.d(TAG, "Setting property: " + propertyName + "=true");
+                SystemProperties.set(propertyName, "true");
+            }
         } catch (Exception e) {
             logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid
                     + " because we failed to prepare: " + e);
@@ -103,7 +113,8 @@
 
             if (allowRecover) {
                 // Try one last time; if we fail again we're really in trouble
-                prepareUserDataLI(volumeUuid, userId, userSerial, flags, false);
+                prepareUserDataLI(volumeUuid, userId, userSerial,
+                    flags | StorageManager.FLAG_STORAGE_DE, false);
             }
         }
     }
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index d1b48480..8214aad 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -426,7 +426,7 @@
                     return;
                 }
                 try {
-                  sStatsd.informDeviceShutdown(true);
+                  sStatsd.informDeviceShutdown();
                 } catch (Exception e) {
                     Slog.w(TAG, "Failed to inform statsd of a shutdown event.", e);
                 }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 38fb30e..9621edd 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -393,6 +393,8 @@
     /** Temporary float array to retrieve 3x3 matrix values. */
     private final float[] mTmpFloats = new float[9];
 
+    private MagnificationSpec mMagnificationSpec;
+
     private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> {
         WindowStateAnimator winAnimator = w.mWinAnimator;
         final AppWindowToken atoken = w.mAppToken;
@@ -3837,10 +3839,22 @@
     }
 
     void applyMagnificationSpec(MagnificationSpec spec) {
+        if (spec.scale != 1.0) {
+            mMagnificationSpec = spec;
+        } else {
+            mMagnificationSpec = null;
+        }
+
         applyMagnificationSpec(getPendingTransaction(), spec);
         getPendingTransaction().apply();
     }
 
+    void reapplyMagnificationSpec() {
+        if (mMagnificationSpec != null) {
+            applyMagnificationSpec(getPendingTransaction(), mMagnificationSpec);
+        }
+    }
+
     @Override
     void onParentSet() {
         // Since we are the top of the SurfaceControl hierarchy here
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 86aed47..0de3c92 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -808,6 +808,8 @@
     void onParentSet() {
         super.onParentSet();
         setDrawnStateEvaluated(false /*evaluated*/);
+
+        getDisplayContent().reapplyMagnificationSpec();
     }
 
     @Override
diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java
index d6999dd..63ae09a 100644
--- a/services/net/java/android/net/ip/IpClient.java
+++ b/services/net/java/android/net/ip/IpClient.java
@@ -54,6 +54,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.R;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.IState;
 import com.android.internal.util.Preconditions;
@@ -74,6 +75,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.StringJoiner;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
@@ -100,6 +102,36 @@
     private static final Class[] sMessageClasses = { IpClient.class, DhcpClient.class };
     private static final SparseArray<String> sWhatToString =
             MessageUtils.findMessageNames(sMessageClasses);
+    // Two static concurrent hashmaps of interface name to logging classes.
+    // One holds StateMachine logs and the other connectivity packet logs.
+    private static final ConcurrentHashMap<String, SharedLog> sSmLogs = new ConcurrentHashMap<>();
+    private static final ConcurrentHashMap<String, LocalLog> sPktLogs = new ConcurrentHashMap<>();
+
+    // If |args| is non-empty, assume it's a list of interface names for which
+    // we should print IpClient logs (filter out all others).
+    public static void dumpAllLogs(PrintWriter writer, String[] args) {
+        for (String ifname : sSmLogs.keySet()) {
+            if (!ArrayUtils.isEmpty(args) && !ArrayUtils.contains(args, ifname)) continue;
+
+            writer.println(String.format("--- BEGIN %s ---", ifname));
+
+            final SharedLog smLog = sSmLogs.get(ifname);
+            if (smLog != null) {
+                writer.println("State machine log:");
+                smLog.dump(null, writer, null);
+            }
+
+            writer.println("");
+
+            final LocalLog pktLog = sPktLogs.get(ifname);
+            if (pktLog != null) {
+                writer.println("Connectivity packet log:");
+                pktLog.readOnlyLocalLog().dump(null, writer, null);
+            }
+
+            writer.println(String.format("--- END %s ---", ifname));
+        }
+    }
 
     /**
      * Callbacks for handling IpClient events.
@@ -680,8 +712,10 @@
         mShutdownLatch = new CountDownLatch(1);
         mNwService = deps.getNMS();
 
-        mLog = new SharedLog(MAX_LOG_RECORDS, mTag);
-        mConnectivityPacketLog = new LocalLog(MAX_PACKET_RECORDS);
+        sSmLogs.putIfAbsent(mInterfaceName, new SharedLog(MAX_LOG_RECORDS, mTag));
+        mLog = sSmLogs.get(mInterfaceName);
+        sPktLogs.putIfAbsent(mInterfaceName, new LocalLog(MAX_PACKET_RECORDS));
+        mConnectivityPacketLog = sPktLogs.get(mInterfaceName);
         mMsgStateLogger = new MessageHandlingLogger();
 
         // TODO: Consider creating, constructing, and passing in some kind of
diff --git a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
index 949c504..b1dad5a 100644
--- a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
+++ b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
@@ -419,7 +419,7 @@
         runTask(task);
 
         verify(mObserver).onResult(PACKAGE_1, BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
-        verify(mObserver).backupFinished(BackupManager.ERROR_TRANSPORT_ABORTED);
+        verify(mObserver).backupFinished(BackupManager.SUCCESS);
     }
 
     @Test
@@ -467,8 +467,7 @@
 
         verify(mObserver).onResult(PACKAGE_1, BackupManager.SUCCESS);
         verify(mObserver).onResult(PACKAGE_2, BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
-        // TODO: Should we return the status of the last?
-        verify(mObserver).backupFinished(BackupManager.ERROR_TRANSPORT_ABORTED);
+        verify(mObserver).backupFinished(BackupManager.SUCCESS);
     }
 
     @Test
@@ -488,7 +487,7 @@
         runTask(task);
 
         verify(mObserver).onResult(PACKAGE_1, BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
-        verify(mObserver).backupFinished(BackupManager.ERROR_TRANSPORT_ABORTED);
+        verify(mObserver).backupFinished(BackupManager.SUCCESS);
         verify(agentMock.agent).onQuotaExceeded(anyLong(), anyLong());
     }
 
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 58f5898..376cc64 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -557,11 +557,34 @@
         assertEquals(IMPORTANCE_NONE,
                 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
 
-        final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
+        StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         waitForIdle();
+        // The first time a foreground service notification is shown, we allow the channel
+        // to be updated to allow it to be seen.
+        assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
+        assertEquals(IMPORTANCE_LOW,
+                mService.getNotificationRecord(sbn.getKey()).getImportance());
+        assertEquals(IMPORTANCE_LOW,
+                mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
+        mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
+        waitForIdle();
+
+        update = new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE);
+        update.setFgServiceShown(true);
+        mBinderService.updateNotificationChannelForPackage(PKG, mUid, update);
+        waitForIdle();
+        assertEquals(IMPORTANCE_NONE,
+                mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
+
+        sbn = generateNotificationRecord(channel).sbn;
+        sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
+        mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+                sbn.getId(), sbn.getNotification(), sbn.getUserId());
+        waitForIdle();
+        // The second time it is shown, we keep the user's preference.
         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
         assertNull(mService.getNotificationRecord(sbn.getKey()));
         assertEquals(IMPORTANCE_NONE,
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 4ca175f..6ce66f0 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -98,7 +98,7 @@
     private static final String LAUNCH_FILE = "applaunch.txt";
     private static final String TRACE_SUB_DIRECTORY = "atrace_logs";
     private static final String DEFAULT_TRACE_CATEGORIES =
-            "sched,freq,gfx,view,dalvik,webview,input,wm,disk,am,wm,binder_driver,hal";
+            "sched,freq,gfx,view,dalvik,webview,input,wm,disk,am,wm,binder_driver,hal,ss";
     private static final String DEFAULT_TRACE_BUFFER_SIZE = "20000";
     private static final String DEFAULT_TRACE_DUMP_INTERVAL = "10";
     private static final String TRIAL_LAUNCH = "TRIAL_LAUNCH";
diff --git a/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java b/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java
index fc46b9c..788924b 100644
--- a/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java
+++ b/tests/net/java/com/android/internal/net/NetworkStatsFactoryTest.java
@@ -116,20 +116,6 @@
     }
 
     @Test
-    public void testNetworkStatsSummary() throws Exception {
-        stageFile(R.raw.net_dev_typical, file("net/dev"));
-
-        final NetworkStats stats = mFactory.readNetworkStatsIfaceDev();
-        assertEquals(6, stats.size());
-        assertStatsEntry(stats, "lo", UID_ALL, SET_ALL, TAG_NONE, 8308L, 8308L);
-        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 1507570L, 489339L);
-        assertStatsEntry(stats, "ifb0", UID_ALL, SET_ALL, TAG_NONE, 52454L, 0L);
-        assertStatsEntry(stats, "ifb1", UID_ALL, SET_ALL, TAG_NONE, 52454L, 0L);
-        assertStatsEntry(stats, "sit0", UID_ALL, SET_ALL, TAG_NONE, 0L, 0L);
-        assertStatsEntry(stats, "ip6tnl0", UID_ALL, SET_ALL, TAG_NONE, 0L, 0L);
-    }
-
-    @Test
     public void testNetworkStatsSingle() throws Exception {
         stageFile(R.raw.xt_qtaguid_iface_typical, file("net/xt_qtaguid/iface_stat_all"));
 
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 19c6c31..7f48544 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -598,10 +598,13 @@
       // If no inner element exists, represent a unique identifier
       out_resource->value = util::make_unique<Id>();
     } else {
-      // If an inner element exists, the inner element must be a reference to
-      // another resource id
       Reference* ref = ValueCast<Reference>(out_resource->value.get());
-      if (!ref || ref->name.value().type != ResourceType::kId) {
+      if (ref && !ref->name && !ref->id) {
+        // A null reference also means there is no inner element when ids are in the form:
+        //    <id name="name"/>
+        out_resource->value = util::make_unique<Id>();
+      } else if (!ref || ref->name.value().type != ResourceType::kId) {
+        // If an inner element exists, the inner element must be a reference to another resource id
         diag_->Error(DiagMessage(out_resource->source)
                          << "<" << parser->element_name()
                          << "> inner element must either be a resource reference or empty");
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index c12b9fa..41b4041 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -944,20 +944,30 @@
   ASSERT_THAT(test::GetValue<Id>(&table_, "id/bar"), NotNull());
   ASSERT_THAT(test::GetValue<Id>(&table_, "id/baz"), NotNull());
 
+  input = R"(
+    <id name="foo2">@id/bar</id>
+    <id name="bar2"/>
+    <id name="baz2"></id>)";
+  ASSERT_TRUE(TestParse(input));
+
+  ASSERT_THAT(test::GetValue<Reference>(&table_, "id/foo2"), NotNull());
+  ASSERT_THAT(test::GetValue<Id>(&table_, "id/bar2"), NotNull());
+  ASSERT_THAT(test::GetValue<Id>(&table_, "id/baz2"), NotNull());
+
   // Reject attribute references
-  input = R"(<item name="foo2" type="id">?attr/bar"</item>)";
+  input = R"(<item name="foo3" type="id">?attr/bar"</item>)";
   ASSERT_FALSE(TestParse(input));
 
   // Reject non-references
-  input = R"(<item name="foo3" type="id">0x7f010001</item>)";
+  input = R"(<item name="foo4" type="id">0x7f010001</item>)";
   ASSERT_FALSE(TestParse(input));
-  input = R"(<item name="foo4" type="id">@drawable/my_image</item>)";
+  input = R"(<item name="foo5" type="id">@drawable/my_image</item>)";
   ASSERT_FALSE(TestParse(input));
-  input = R"(<item name="foo5" type="id"><string name="biz"></string></item>)";
+  input = R"(<item name="foo6" type="id"><string name="biz"></string></item>)";
   ASSERT_FALSE(TestParse(input));
 
   // Ids that reference other resource ids cannot be public
-  input = R"(<public name="foo6" type="id">@id/bar6</item>)";
+  input = R"(<public name="foo7" type="id">@id/bar7</item>)";
   ASSERT_FALSE(TestParse(input));
 }
 
diff --git a/tools/aapt2/format/binary/XmlFlattener.cpp b/tools/aapt2/format/binary/XmlFlattener.cpp
index d897941..2fe2424 100644
--- a/tools/aapt2/format/binary/XmlFlattener.cpp
+++ b/tools/aapt2/format/binary/XmlFlattener.cpp
@@ -79,23 +79,31 @@
   }
 
   void Visit(const xml::Text* node) override {
-    if (util::TrimWhitespace(node->text).empty()) {
-      // Skip whitespace only text nodes.
+    std::string text = util::TrimWhitespace(node->text).to_string();
+
+    // Skip whitespace only text nodes.
+    if (text.empty()) {
       return;
     }
 
+    // Compact leading and trailing whitespace into a single space
+    if (isspace(node->text[0])) {
+      text = ' ' + text;
+    }
+    if (isspace(node->text[node->text.length() - 1])) {
+      text = text + ' ';
+    }
+
     ChunkWriter writer(buffer_);
     ResXMLTree_node* flat_node = writer.StartChunk<ResXMLTree_node>(RES_XML_CDATA_TYPE);
     flat_node->lineNumber = util::HostToDevice32(node->line_number);
     flat_node->comment.index = util::HostToDevice32(-1);
 
-    ResXMLTree_cdataExt* flat_text = writer.NextBlock<ResXMLTree_cdataExt>();
-
     // Process plain strings to make sure they get properly escaped.
-    StringBuilder builder;
-    builder.AppendText(node->text);
-    AddString(builder.to_string(), kLowPriority, &flat_text->data);
+    text = StringBuilder(true /*preserve_spaces*/).AppendText(text).to_string();
 
+    ResXMLTree_cdataExt* flat_text = writer.NextBlock<ResXMLTree_cdataExt>();
+    AddString(text, kLowPriority, &flat_text->data);
     writer.Finish();
   }
 
diff --git a/tools/aapt2/format/binary/XmlFlattener_test.cpp b/tools/aapt2/format/binary/XmlFlattener_test.cpp
index 08243fe..25786b1 100644
--- a/tools/aapt2/format/binary/XmlFlattener_test.cpp
+++ b/tools/aapt2/format/binary/XmlFlattener_test.cpp
@@ -286,6 +286,165 @@
   EXPECT_THAT(tree.getText(&len), StrEq(u"\\d{5}"));
 }
 
+TEST_F(XmlFlattenerTest, ProcessQuotes) {
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(
+      R"(<root>
+          <item>Regular text</item>
+          <item>"Text in double quotes"</item>
+          <item>'Text in single quotes'</item>
+          <item>Text containing "double quotes"</item>
+          <item>Text containing 'single quotes'</item>
+      </root>)");
+
+  size_t len;
+  android::ResXMLTree tree;
+
+  XmlFlattenerOptions options;
+  ASSERT_TRUE(Flatten(doc.get(), &tree, options));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u"Regular text"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u"\"Text in double quotes\""));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementNamespace(&len), IsNull());
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u"'Text in single quotes'"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u"Text containing \"double quotes\""));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u"Text containing 'single quotes'"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_DOCUMENT));
+}
+
+TEST_F(XmlFlattenerTest, ProcessWhitepspace) {
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(
+      R"(<root>
+          <item>   Compact   Spaces   </item>
+          <item>
+                 A
+          </item>
+          <item>B   </item>
+          <item>C </item>
+          <item> D  </item>
+          <item>   E</item>
+          <item> F</item>
+          <item>  G </item>
+          <item> H </item>
+<item>
+I
+</item>
+<item>
+
+   J
+
+</item>
+          <item>
+          </item>
+      </root>)");
+
+  size_t len;
+  android::ResXMLTree tree;
+
+  XmlFlattenerOptions options;
+  ASSERT_TRUE(Flatten(doc.get(), &tree, options));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u" Compact   Spaces "));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u" A "));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u"B "));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u"C "));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u" D "));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u" E"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u" F"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u" G "));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u" H "));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u" I "));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::TEXT));
+  EXPECT_THAT(tree.getText(&len), StrEq(u" J "));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::START_TAG));
+  EXPECT_THAT(tree.getElementName(&len), StrEq(u"item"));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_TAG));
+
+  ASSERT_THAT(tree.next(), Eq(android::ResXMLTree::END_DOCUMENT));
+}
+
 TEST_F(XmlFlattenerTest, FlattenRawValueOnlyMakesCompiledValueToo) {
   std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(<element foo="bar" />)");
 
diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp
index a274a8c..3f9588a 100644
--- a/tools/incident_section_gen/main.cpp
+++ b/tools/incident_section_gen/main.cpp
@@ -413,7 +413,8 @@
             case SECTION_NONE:
                 continue;
             case SECTION_FILE:
-                printf("    new FileSection(%d, \"%s\"),\n", field->number(), s.args().c_str());
+                printf("    new FileSection(%d, \"%s\", %s),\n", field->number(), s.args().c_str(),
+                       s.device_specific() ? "true" : "false");
                 break;
             case SECTION_COMMAND:
                 printf("    new CommandSection(%d,", field->number());