Merge "Status bar icons 15 dp" into pi-dev
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 02003c0..766c2d1 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -83,6 +83,7 @@
       mTimeBaseNs(timeBaseNs),
       mLargestTimestampSeen(0),
       mLastTimestampSeen(0) {
+    mStatsPullerManager.ForceClearPullerCache();
 }
 
 StatsLogProcessor::~StatsLogProcessor() {
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 136fd14..41e55cb 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -414,9 +414,11 @@
                 interval.tainted += 1;
             }
         }
-    } else {    // for pushed events
-        interval.sum += value;
-        interval.hasValue = true;
+    } else {    // for pushed events, only accumulate when condition is true
+        if (mCondition == true || mConditionTrackerIndex < 0) {
+            interval.sum += value;
+            interval.hasValue = true;
+        }
     }
 
     long wholeBucketVal = interval.sum;
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 66afa15..cb6b051 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -169,11 +169,14 @@
     const bool mUseAbsoluteValueOnReset;
 
     FRIEND_TEST(ValueMetricProducerTest, TestNonDimensionalEvents);
+    FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset);
+    FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset);
     FRIEND_TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition);
     FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade);
     FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade);
     FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse);
     FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition);
+    FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithCondition);
     FRIEND_TEST(ValueMetricProducerTest, TestAnomalyDetection);
     FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition);
     FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition);
diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
index 13b3cb1..67acd61 100644
--- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
@@ -84,6 +84,7 @@
             CreateDimensions(android::util::TEMPERATURE, {2 /* sensor name field */});
     valueMetric->set_bucket(FIVE_MINUTES);
     valueMetric->set_min_bucket_size_nanos(minTime);
+    valueMetric->set_use_absolute_value_on_reset(true);
     return config;
 }
 
diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
index 6923e7b..dd28d36 100644
--- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
@@ -48,7 +48,7 @@
     *valueMetric->mutable_dimensions_in_what() =
         CreateDimensions(android::util::TEMPERATURE, {2/* sensor name field */ });
     valueMetric->set_bucket(FIVE_MINUTES);
-
+    valueMetric->set_use_absolute_value_on_reset(true);
     return config;
 }
 
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index 087a612..e3a8a55 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -129,6 +129,153 @@
 }
 
 /*
+ * Tests pulled atoms with no conditions and take absolute value after reset
+ */
+TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
+    ValueMetric metric;
+    metric.set_id(metricId);
+    metric.set_bucket(ONE_MINUTE);
+    metric.mutable_value_field()->set_field(tagId);
+    metric.mutable_value_field()->add_child()->set_field(2);
+    metric.set_use_absolute_value_on_reset(true);
+
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    shared_ptr<MockStatsPullerManager> pullerManager =
+            make_shared<StrictMock<MockStatsPullerManager>>();
+    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+                                      tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+    valueProducer.setBucketSize(60 * NS_PER_SEC);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+    event->write(tagId);
+    event->write(11);
+    event->init();
+    allData.push_back(event);
+
+    valueProducer.onDataPulled(allData);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    valueProducer.setBucketSize(60 * NS_PER_SEC);
+
+    EXPECT_EQ(true, curInterval.startUpdated);
+    EXPECT_EQ(0, curInterval.tainted);
+    EXPECT_EQ(0, curInterval.sum);
+    EXPECT_EQ(11, curInterval.start);
+    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+
+    allData.clear();
+    event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
+    event->write(tagId);
+    event->write(10);
+    event->init();
+    allData.push_back(event);
+    valueProducer.onDataPulled(allData);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    EXPECT_EQ(true, curInterval.startUpdated);
+    EXPECT_EQ(0, curInterval.tainted);
+    EXPECT_EQ(0, curInterval.sum);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+    EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().mValue);
+
+    allData.clear();
+    event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
+    event->write(tagId);
+    event->write(36);
+    event->init();
+    allData.push_back(event);
+    valueProducer.onDataPulled(allData);
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    EXPECT_EQ(true, curInterval.startUpdated);
+    EXPECT_EQ(0, curInterval.tainted);
+    EXPECT_EQ(0, curInterval.sum);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
+    EXPECT_EQ(26, valueProducer.mPastBuckets.begin()->second.back().mValue);
+}
+
+/*
+ * Tests pulled atoms with no conditions and take zero value after reset
+ */
+TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
+    ValueMetric metric;
+    metric.set_id(metricId);
+    metric.set_bucket(ONE_MINUTE);
+    metric.mutable_value_field()->set_field(tagId);
+    metric.mutable_value_field()->add_child()->set_field(2);
+
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    shared_ptr<MockStatsPullerManager> pullerManager =
+            make_shared<StrictMock<MockStatsPullerManager>>();
+    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+
+    ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+                                      tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+    valueProducer.setBucketSize(60 * NS_PER_SEC);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+    event->write(tagId);
+    event->write(11);
+    event->init();
+    allData.push_back(event);
+
+    valueProducer.onDataPulled(allData);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    valueProducer.setBucketSize(60 * NS_PER_SEC);
+
+    EXPECT_EQ(true, curInterval.startUpdated);
+    EXPECT_EQ(0, curInterval.tainted);
+    EXPECT_EQ(0, curInterval.sum);
+    EXPECT_EQ(11, curInterval.start);
+    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+
+    allData.clear();
+    event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
+    event->write(tagId);
+    event->write(10);
+    event->init();
+    allData.push_back(event);
+    valueProducer.onDataPulled(allData);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    EXPECT_EQ(true, curInterval.startUpdated);
+    EXPECT_EQ(0, curInterval.tainted);
+    EXPECT_EQ(0, curInterval.sum);
+    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+
+    allData.clear();
+    event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
+    event->write(tagId);
+    event->write(36);
+    event->init();
+    allData.push_back(event);
+    valueProducer.onDataPulled(allData);
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    EXPECT_EQ(true, curInterval.startUpdated);
+    EXPECT_EQ(0, curInterval.tainted);
+    EXPECT_EQ(0, curInterval.sum);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+    EXPECT_EQ(26, valueProducer.mPastBuckets.begin()->second.back().mValue);
+}
+
+/*
  * Test pulled event with non sliced condition.
  */
 TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
@@ -401,6 +548,72 @@
     EXPECT_EQ(30, valueProducer.mPastBuckets.begin()->second.back().mValue);
 }
 
+TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
+    ValueMetric metric;
+    metric.set_id(metricId);
+    metric.set_bucket(ONE_MINUTE);
+    metric.mutable_value_field()->set_field(tagId);
+    metric.mutable_value_field()->add_child()->set_field(2);
+
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    shared_ptr<MockStatsPullerManager> pullerManager =
+            make_shared<StrictMock<MockStatsPullerManager>>();
+
+    ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, -1, bucketStartTimeNs,
+                                      bucketStartTimeNs, pullerManager);
+    valueProducer.setBucketSize(60 * NS_PER_SEC);
+
+    shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+    event1->write(1);
+    event1->write(10);
+    event1->init();
+    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
+    // has 1 slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    EXPECT_EQ(false, curInterval.hasValue);
+
+    valueProducer.onConditionChangedLocked(true, bucketStartTimeNs + 15);
+    shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
+    event2->write(1);
+    event2->write(20);
+    event2->init();
+    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
+
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    EXPECT_EQ(20, curInterval.sum);
+
+    shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 30);
+    event3->write(1);
+    event3->write(30);
+    event3->init();
+    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
+
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    EXPECT_EQ(50, curInterval.sum);
+
+    valueProducer.onConditionChangedLocked(false, bucketStartTimeNs + 35);
+    shared_ptr<LogEvent> event4 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 40);
+    event4->write(1);
+    event4->write(40);
+    event4->init();
+    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
+
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    EXPECT_EQ(50, curInterval.sum);
+
+    valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+    EXPECT_EQ(50, valueProducer.mPastBuckets.begin()->second.back().mValue);
+}
+
 TEST(ValueMetricProducerTest, TestAnomalyDetection) {
     sp<AlarmMonitor> alarmMonitor;
     Alert alert;
diff --git a/config/hiddenapi-force-blacklist.txt b/config/hiddenapi-force-blacklist.txt
index 0c689e8..3a9e2d1 100644
--- a/config/hiddenapi-force-blacklist.txt
+++ b/config/hiddenapi-force-blacklist.txt
@@ -1,4 +1,5 @@
 Ldalvik/system/VMRuntime;->setHiddenApiExemptions([Ljava/lang/String;)V
+Ljava/lang/invoke/MethodHandles$Lookup;->IMPL_LOOKUP:Ljava/lang/invoke/MethodHandles$Lookup;
 Ljava/lang/invoke/VarHandle;->acquireFence()V
 Ljava/lang/invoke/VarHandle;->compareAndExchange([[Ljava/lang/Object;)Ljava/lang/Object;
 Ljava/lang/invoke/VarHandle;->compareAndExchangeAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 7ecfbe6..96f04ac 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -19,6 +19,8 @@
 Landroid/accounts/AccountManager;->confirmCredentialsAsUser(Landroid/accounts/Account;Landroid/os/Bundle;Landroid/app/Activity;Landroid/accounts/AccountManagerCallback;Landroid/os/Handler;Landroid/os/UserHandle;)Landroid/accounts/AccountManagerFuture;
 Landroid/accounts/AccountManager;->getAccountsByTypeAsUser(Ljava/lang/String;Landroid/os/UserHandle;)[Landroid/accounts/Account;
 Landroid/accounts/AccountManager;->mContext:Landroid/content/Context;
+Landroid/accounts/AuthenticatorDescription;-><init>(Landroid/os/Parcel;)V
+Landroid/accounts/AuthenticatorDescription;-><init>(Ljava/lang/String;)V
 Landroid/accounts/IAccountAuthenticator$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/accounts/IAccountAuthenticator$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/accounts/IAccountAuthenticator$Stub;-><init>()V
@@ -92,12 +94,14 @@
 Landroid/app/Activity;->mTitle:Ljava/lang/CharSequence;
 Landroid/app/Activity;->mToken:Landroid/os/IBinder;
 Landroid/app/Activity;->mVisibleFromClient:Z
+Landroid/app/Activity;->mVoiceInteractor:Landroid/app/VoiceInteractor;
 Landroid/app/Activity;->mWindow:Landroid/view/Window;
 Landroid/app/Activity;->mWindowAdded:Z
 Landroid/app/Activity;->mWindowManager:Landroid/view/WindowManager;
 Landroid/app/Activity;->performCreate(Landroid/os/Bundle;Landroid/os/PersistableBundle;)V
 Landroid/app/Activity;->saveManagedDialogs(Landroid/os/Bundle;)V
 Landroid/app/Activity;->setDisablePreviewScreenshots(Z)V
+Landroid/app/Activity;->setParent(Landroid/app/Activity;)V
 Landroid/app/Activity;->setPersistent(Z)V
 Landroid/app/Activity;->startActivityAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V
 Landroid/app/Activity;->startActivityForResult(Ljava/lang/String;Landroid/content/Intent;ILandroid/os/Bundle;)V
@@ -160,6 +164,7 @@
 Landroid/app/ActivityManager;->PROCESS_STATE_TOP:I
 Landroid/app/ActivityManager;->setPersistentVrThread(I)V
 Landroid/app/ActivityManager;->staticGetMemoryClass()I
+Landroid/app/ActivityManager;->switchUser(I)Z
 Landroid/app/ActivityManagerNative;-><init>()V
 Landroid/app/ActivityManagerNative;->asInterface(Landroid/os/IBinder;)Landroid/app/IActivityManager;
 Landroid/app/ActivityManagerNative;->getDefault()Landroid/app/IActivityManager;
@@ -232,6 +237,8 @@
 Landroid/app/ActivityThread;->getProcessName()Ljava/lang/String;
 Landroid/app/ActivityThread;->getSystemContext()Landroid/app/ContextImpl;
 Landroid/app/ActivityThread;->handleBindApplication(Landroid/app/ActivityThread$AppBindData;)V
+Landroid/app/ActivityThread;->handleCreateService(Landroid/app/ActivityThread$CreateServiceData;)V
+Landroid/app/ActivityThread;->handleReceiver(Landroid/app/ActivityThread$ReceiverData;)V
 Landroid/app/ActivityThread;->handleUnstableProviderDied(Landroid/os/IBinder;Z)V
 Landroid/app/ActivityThread;->installContentProviders(Landroid/content/Context;Ljava/util/List;)V
 Landroid/app/ActivityThread;->installProvider(Landroid/content/Context;Landroid/app/ContentProviderHolder;Landroid/content/pm/ProviderInfo;ZZZ)Landroid/app/ContentProviderHolder;
@@ -443,6 +450,14 @@
 Landroid/app/AppOpsManager;->sOpPerms:[Ljava/lang/String;
 Landroid/app/AppOpsManager;->strOpToOp(Ljava/lang/String;)I
 Landroid/app/AppOpsManager;->_NUM_OP:I
+Landroid/app/assist/AssistContent;-><init>(Landroid/os/Parcel;)V
+Landroid/app/assist/AssistContent;->mClipData:Landroid/content/ClipData;
+Landroid/app/assist/AssistContent;->mExtras:Landroid/os/Bundle;
+Landroid/app/assist/AssistContent;->mIntent:Landroid/content/Intent;
+Landroid/app/assist/AssistContent;->mIsAppProvidedIntent:Z
+Landroid/app/assist/AssistContent;->mStructuredData:Ljava/lang/String;
+Landroid/app/assist/AssistContent;->mUri:Landroid/net/Uri;
+Landroid/app/assist/AssistContent;->writeToParcelInternal(Landroid/os/Parcel;I)V
 Landroid/app/backup/BackupDataInput$EntityHeader;->dataSize:I
 Landroid/app/backup/BackupDataInput$EntityHeader;->key:Ljava/lang/String;
 Landroid/app/backup/BackupDataInputStream;->dataSize:I
@@ -517,8 +532,10 @@
 Landroid/app/Dialog;->mShowing:Z
 Landroid/app/Dialog;->mShowMessage:Landroid/os/Message;
 Landroid/app/Dialog;->mWindow:Landroid/view/Window;
+Landroid/app/DialogFragment;->mBackStackId:I
 Landroid/app/DialogFragment;->mDismissed:Z
 Landroid/app/DialogFragment;->mShownByMe:Z
+Landroid/app/DialogFragment;->mViewDestroyed:Z
 Landroid/app/DialogFragment;->showAllowingStateLoss(Landroid/app/FragmentManager;Ljava/lang/String;)V
 Landroid/app/DownloadManager$Query;->orderBy(Ljava/lang/String;I)Landroid/app/DownloadManager$Query;
 Landroid/app/DownloadManager$Query;->setOnlyIncludeVisibleInDownloadsUi(Z)Landroid/app/DownloadManager$Query;
@@ -556,12 +573,14 @@
 Landroid/app/IActivityManager$Stub$Proxy;->getProcessPss([I)[J
 Landroid/app/IActivityManager$Stub$Proxy;->isAppForeground(I)Z
 Landroid/app/IActivityManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/app/IActivityManager$Stub$Proxy;->setActivityController(Landroid/app/IActivityController;Z)V
 Landroid/app/IActivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IActivityManager;
 Landroid/app/IActivityManager;->bindService(Landroid/app/IApplicationThread;Landroid/os/IBinder;Landroid/content/Intent;Ljava/lang/String;Landroid/app/IServiceConnection;ILjava/lang/String;I)I
 Landroid/app/IActivityManager;->broadcastIntent(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I
 Landroid/app/IActivityManager;->checkPermission(Ljava/lang/String;II)I
 Landroid/app/IActivityManager;->enterSafeMode()V
 Landroid/app/IActivityManager;->finishActivity(Landroid/os/IBinder;ILandroid/content/Intent;I)Z
+Landroid/app/IActivityManager;->finishHeavyWeightApp()V
 Landroid/app/IActivityManager;->finishReceiver(Landroid/os/IBinder;ILjava/lang/String;Landroid/os/Bundle;ZI)V
 Landroid/app/IActivityManager;->forceStopPackage(Ljava/lang/String;I)V
 Landroid/app/IActivityManager;->getAllStackInfos()Ljava/util/List;
@@ -703,6 +722,8 @@
 Landroid/app/ITransientNotification;->hide()V
 Landroid/app/ITransientNotification;->show(Landroid/os/IBinder;)V
 Landroid/app/IUiModeManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/app/IUiModeManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IUiModeManager;
+Landroid/app/IUiModeManager;->disableCarMode(I)V
 Landroid/app/IUserSwitchObserver$Stub;-><init>()V
 Landroid/app/IWallpaperManager$Stub;-><init>()V
 Landroid/app/IWallpaperManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IWallpaperManager;
@@ -740,6 +761,11 @@
 Landroid/app/job/JobParameters;->callback:Landroid/os/IBinder;
 Landroid/app/job/JobParameters;->getCallback()Landroid/app/job/IJobCallback;
 Landroid/app/job/JobParameters;->jobId:I
+Landroid/app/job/JobWorkItem;-><init>(Landroid/os/Parcel;)V
+Landroid/app/job/JobWorkItem;->mDeliveryCount:I
+Landroid/app/job/JobWorkItem;->mGrants:Ljava/lang/Object;
+Landroid/app/job/JobWorkItem;->mIntent:Landroid/content/Intent;
+Landroid/app/job/JobWorkItem;->mWorkId:I
 Landroid/app/KeyguardManager;->isDeviceSecure(I)Z
 Landroid/app/LoadedApk$ReceiverDispatcher;->getIIntentReceiver()Landroid/content/IIntentReceiver;
 Landroid/app/LoadedApk$ReceiverDispatcher;->getIntentReceiver()Landroid/content/BroadcastReceiver;
@@ -750,6 +776,7 @@
 Landroid/app/LoadedApk$ServiceDispatcher;->getIServiceConnection()Landroid/app/IServiceConnection;
 Landroid/app/LoadedApk$ServiceDispatcher;->mConnection:Landroid/content/ServiceConnection;
 Landroid/app/LoadedApk$ServiceDispatcher;->mContext:Landroid/content/Context;
+Landroid/app/LoadedApk;->getAppDir()Ljava/lang/String;
 Landroid/app/LoadedApk;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;
 Landroid/app/LoadedApk;->getAssets()Landroid/content/res/AssetManager;
 Landroid/app/LoadedApk;->getClassLoader()Ljava/lang/ClassLoader;
@@ -822,6 +849,7 @@
 Landroid/app/PendingIntent;->getActivityAsUser(Landroid/content/Context;ILandroid/content/Intent;ILandroid/os/Bundle;Landroid/os/UserHandle;)Landroid/app/PendingIntent;
 Landroid/app/PendingIntent;->getBroadcastAsUser(Landroid/content/Context;ILandroid/content/Intent;ILandroid/os/UserHandle;)Landroid/app/PendingIntent;
 Landroid/app/PendingIntent;->getIntent()Landroid/content/Intent;
+Landroid/app/PendingIntent;->getTag(Ljava/lang/String;)Ljava/lang/String;
 Landroid/app/PendingIntent;->isActivity()Z
 Landroid/app/PendingIntent;->setOnMarshaledListener(Landroid/app/PendingIntent$OnMarshaledListener;)V
 Landroid/app/PictureInPictureArgs;-><init>()V
@@ -869,6 +897,9 @@
 Landroid/app/SearchManager;->launchAssist(Landroid/os/Bundle;)V
 Landroid/app/SearchManager;->mSearchDialog:Landroid/app/SearchDialog;
 Landroid/app/SearchManager;->startSearch(Ljava/lang/String;ZLandroid/content/ComponentName;Landroid/os/Bundle;ZLandroid/graphics/Rect;)V
+Landroid/app/servertransaction/ClientTransaction;->mActivityCallbacks:Ljava/util/List;
+Landroid/app/servertransaction/LaunchActivityItem;->mInfo:Landroid/content/pm/ActivityInfo;
+Landroid/app/servertransaction/LaunchActivityItem;->mIntent:Landroid/content/Intent;
 Landroid/app/Service;->attach(Landroid/content/Context;Landroid/app/ActivityThread;Ljava/lang/String;Landroid/os/IBinder;Landroid/app/Application;Ljava/lang/Object;)V
 Landroid/app/Service;->mActivityManager:Landroid/app/IActivityManager;
 Landroid/app/Service;->mApplication:Landroid/app/Application;
@@ -903,16 +934,42 @@
 Landroid/app/UiAutomation;->disconnect()V
 Landroid/app/UiAutomationConnection;-><init>()V
 Landroid/app/UiModeManager;-><init>()V
+Landroid/app/usage/ConfigurationStats;->mActivationCount:I
+Landroid/app/usage/ConfigurationStats;->mBeginTimeStamp:J
+Landroid/app/usage/ConfigurationStats;->mConfiguration:Landroid/content/res/Configuration;
+Landroid/app/usage/ConfigurationStats;->mEndTimeStamp:J
+Landroid/app/usage/ConfigurationStats;->mLastTimeActive:J
+Landroid/app/usage/ConfigurationStats;->mTotalTimeActive:J
 Landroid/app/usage/IUsageStatsManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/usage/IUsageStatsManager;
 Landroid/app/usage/IUsageStatsManager;->isAppInactive(Ljava/lang/String;I)Z
 Landroid/app/usage/IUsageStatsManager;->queryConfigurationStats(IJJLjava/lang/String;)Landroid/content/pm/ParceledListSlice;
 Landroid/app/usage/IUsageStatsManager;->queryUsageStats(IJJLjava/lang/String;)Landroid/content/pm/ParceledListSlice;
 Landroid/app/usage/IUsageStatsManager;->setAppInactive(Ljava/lang/String;ZI)V
 Landroid/app/usage/NetworkStatsManager;-><init>(Landroid/content/Context;)V
+Landroid/app/usage/UsageEvents$Event;->mClass:Ljava/lang/String;
+Landroid/app/usage/UsageEvents$Event;->mConfiguration:Landroid/content/res/Configuration;
+Landroid/app/usage/UsageEvents$Event;->mEventType:I
+Landroid/app/usage/UsageEvents$Event;->mPackage:Ljava/lang/String;
+Landroid/app/usage/UsageEvents$Event;->mTimeStamp:J
+Landroid/app/usage/UsageEvents;-><init>(Landroid/os/Parcel;)V
+Landroid/app/usage/UsageEvents;->findStringIndex(Ljava/lang/String;)I
+Landroid/app/usage/UsageEvents;->mEventCount:I
+Landroid/app/usage/UsageEvents;->mEventsToWrite:Ljava/util/List;
+Landroid/app/usage/UsageEvents;->mIndex:I
+Landroid/app/usage/UsageEvents;->mParcel:Landroid/os/Parcel;
+Landroid/app/usage/UsageEvents;->mStringPool:[Ljava/lang/String;
+Landroid/app/usage/UsageEvents;->readEventFromParcel(Landroid/os/Parcel;Landroid/app/usage/UsageEvents$Event;)V
+Landroid/app/usage/UsageEvents;->writeEventToParcel(Landroid/app/usage/UsageEvents$Event;Landroid/os/Parcel;I)V
+Landroid/app/usage/UsageStats;->mBeginTimeStamp:J
+Landroid/app/usage/UsageStats;->mEndTimeStamp:J
 Landroid/app/usage/UsageStats;->mLastEvent:I
+Landroid/app/usage/UsageStats;->mLastTimeUsed:J
 Landroid/app/usage/UsageStats;->mLaunchCount:I
+Landroid/app/usage/UsageStats;->mPackageName:Ljava/lang/String;
 Landroid/app/usage/UsageStats;->mTotalTimeInForeground:J
+Landroid/app/usage/UsageStatsManager;->mContext:Landroid/content/Context;
 Landroid/app/usage/UsageStatsManager;->mService:Landroid/app/usage/IUsageStatsManager;
+Landroid/app/usage/UsageStatsManager;->sEmptyResults:Landroid/app/usage/UsageEvents;
 Landroid/app/UserSwitchObserver;-><init>()V
 Landroid/app/Vr2dDisplayProperties$Builder;-><init>()V
 Landroid/app/Vr2dDisplayProperties$Builder;->build()Landroid/app/Vr2dDisplayProperties;
@@ -1276,6 +1333,8 @@
 Landroid/content/CursorEntityIterator;-><init>(Landroid/database/Cursor;)V
 Landroid/content/CursorLoader;->mCancellationSignal:Landroid/os/CancellationSignal;
 Landroid/content/CursorLoader;->mObserver:Landroid/content/Loader$ForceLoadContentObserver;
+Landroid/content/Entity;->mSubValues:Ljava/util/ArrayList;
+Landroid/content/Entity;->mValues:Landroid/content/ContentValues;
 Landroid/content/IClipboard$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/IClipboard$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IClipboard;
 Landroid/content/IContentProvider;->bulkInsert(Ljava/lang/String;Landroid/net/Uri;[Landroid/content/ContentValues;)I
@@ -1354,6 +1413,8 @@
 Landroid/content/pm/ActivityInfo;->isResizeableMode(I)Z
 Landroid/content/pm/ActivityInfo;->resizeMode:I
 Landroid/content/pm/ActivityInfo;->supportsPictureInPicture()Z
+Landroid/content/pm/ApplicationInfo$DisplayNameComparator;->mPM:Landroid/content/pm/PackageManager;
+Landroid/content/pm/ApplicationInfo$DisplayNameComparator;->sCollator:Ljava/text/Collator;
 Landroid/content/pm/ApplicationInfo;->disableCompatibilityMode()V
 Landroid/content/pm/ApplicationInfo;->enabledSetting:I
 Landroid/content/pm/ApplicationInfo;->fullBackupContent:I
@@ -1362,6 +1423,7 @@
 Landroid/content/pm/ApplicationInfo;->hasRtlSupport()Z
 Landroid/content/pm/ApplicationInfo;->installLocation:I
 Landroid/content/pm/ApplicationInfo;->isForwardLocked()Z
+Landroid/content/pm/ApplicationInfo;->isPackageUnavailable(Landroid/content/pm/PackageManager;)Z
 Landroid/content/pm/ApplicationInfo;->nativeLibraryRootDir:Ljava/lang/String;
 Landroid/content/pm/ApplicationInfo;->primaryCpuAbi:Ljava/lang/String;
 Landroid/content/pm/ApplicationInfo;->privateFlags:I
@@ -1475,9 +1537,11 @@
 Landroid/content/pm/LauncherApps;->mPm:Landroid/content/pm/PackageManager;
 Landroid/content/pm/LauncherApps;->mService:Landroid/content/pm/ILauncherApps;
 Landroid/content/pm/LauncherApps;->startShortcut(Ljava/lang/String;Ljava/lang/String;Landroid/graphics/Rect;Landroid/os/Bundle;I)V
+Landroid/content/pm/PackageInfo;-><init>(Landroid/os/Parcel;)V
 Landroid/content/pm/PackageInfo;->coreApp:Z
 Landroid/content/pm/PackageInfo;->INSTALL_LOCATION_UNSPECIFIED:I
 Landroid/content/pm/PackageInfo;->overlayTarget:Ljava/lang/String;
+Landroid/content/pm/PackageInfoLite;->CREATOR:Landroid/os/Parcelable$Creator;
 Landroid/content/pm/PackageInstaller$Session;->addProgress(F)V
 Landroid/content/pm/PackageInstaller$SessionInfo;-><init>()V
 Landroid/content/pm/PackageInstaller$SessionInfo;->active:Z
@@ -1639,6 +1703,7 @@
 Landroid/content/pm/PackageParser;->parsePackageLite(Ljava/io/File;I)Landroid/content/pm/PackageParser$PackageLite;
 Landroid/content/pm/PackageParser;->setCompatibilityModeEnabled(Z)V
 Landroid/content/pm/PackageParser;->setSeparateProcesses([Ljava/lang/String;)V
+Landroid/content/pm/PackageStats;->userHandle:I
 Landroid/content/pm/PackageUserState;-><init>()V
 Landroid/content/pm/ParceledListSlice;-><init>(Ljava/util/List;)V
 Landroid/content/pm/PermissionInfo;->protectionToString(I)Ljava/lang/String;
@@ -1811,13 +1876,18 @@
 Landroid/content/RestrictionsManager;->mService:Landroid/content/IRestrictionsManager;
 Landroid/content/SearchRecentSuggestionsProvider;->mSuggestionProjection:[Ljava/lang/String;
 Landroid/content/SyncAdaptersCache;-><init>(Landroid/content/Context;)V
+Landroid/content/SyncAdapterType;-><init>(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/content/SyncAdapterType;->allowParallelSyncs:Z
 Landroid/content/SyncAdapterType;->isAlwaysSyncable:Z
 Landroid/content/SyncAdapterType;->settingsActivity:Ljava/lang/String;
+Landroid/content/SyncAdapterType;->supportsUploading:Z
+Landroid/content/SyncAdapterType;->userVisible:Z
 Landroid/content/SyncContext;-><init>(Landroid/content/ISyncContext;)V
 Landroid/content/SyncContext;->setStatusText(Ljava/lang/String;)V
 Landroid/content/SyncInfo;-><init>(ILandroid/accounts/Account;Ljava/lang/String;J)V
+Landroid/content/SyncInfo;-><init>(Landroid/os/Parcel;)V
 Landroid/content/SyncInfo;->authorityId:I
+Landroid/content/SyncInfo;->CREATOR:Landroid/os/Parcelable$Creator;
 Landroid/content/SyncRequest;->mAccountToSync:Landroid/accounts/Account;
 Landroid/content/SyncRequest;->mAuthority:Ljava/lang/String;
 Landroid/content/SyncRequest;->mExtras:Landroid/os/Bundle;
@@ -2029,6 +2099,8 @@
 Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->callOnFinished(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V
 Landroid/graphics/drawable/AnimatedVectorDrawable;->forceAnimationOnUI()V
 Landroid/graphics/drawable/AnimatedVectorDrawable;->getOpticalInsets()Landroid/graphics/Insets;
+Landroid/graphics/drawable/AnimatedVectorDrawable;->mAnimatedVectorState:Landroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;
+Landroid/graphics/drawable/AnimatedVectorDrawable;->mAnimatorSet:Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;
 Landroid/graphics/drawable/AnimationDrawable;->mCurFrame:I
 Landroid/graphics/drawable/BitmapDrawable;->getOpticalInsets()Landroid/graphics/Insets;
 Landroid/graphics/drawable/BitmapDrawable;->getTint()Landroid/content/res/ColorStateList;
@@ -2102,6 +2174,7 @@
 Landroid/graphics/drawable/RippleDrawable;->mDensity:I
 Landroid/graphics/drawable/RippleDrawable;->mState:Landroid/graphics/drawable/RippleDrawable$RippleState;
 Landroid/graphics/drawable/RippleDrawable;->setForceSoftware(Z)V
+Landroid/graphics/drawable/RotateDrawable;->mState:Landroid/graphics/drawable/RotateDrawable$RotateState;
 Landroid/graphics/drawable/ScaleDrawable;->mState:Landroid/graphics/drawable/ScaleDrawable$ScaleState;
 Landroid/graphics/drawable/StateListDrawable$StateListState;->addStateSet([ILandroid/graphics/drawable/Drawable;)I
 Landroid/graphics/drawable/StateListDrawable;->extractStateSet(Landroid/util/AttributeSet;)[I
@@ -2135,6 +2208,7 @@
 Landroid/graphics/GraphicBuffer;->CREATOR:Landroid/os/Parcelable$Creator;
 Landroid/graphics/GraphicBuffer;->mNativeObject:J
 Landroid/graphics/ImageDecoder;->postProcessAndRelease(Landroid/graphics/Canvas;)I
+Landroid/graphics/ImageFormat;->Y8:I
 Landroid/graphics/Insets;->bottom:I
 Landroid/graphics/Insets;->left:I
 Landroid/graphics/Insets;->NONE:Landroid/graphics/Insets;
@@ -2158,9 +2232,12 @@
 Landroid/graphics/NinePatch$InsetStruct;-><init>(IIIIIIIIFIF)V
 Landroid/graphics/NinePatch;->mBitmap:Landroid/graphics/Bitmap;
 Landroid/graphics/NinePatch;->mNativeChunk:J
+Landroid/graphics/Outline;->mRect:Landroid/graphics/Rect;
 Landroid/graphics/Paint;->getNativeInstance()J
 Landroid/graphics/Paint;->getTextRunAdvances([CIIIIZ[FI)F
 Landroid/graphics/Paint;->getTextRunCursor([CIIIII)I
+Landroid/graphics/Paint;->mNativePaint:J
+Landroid/graphics/Paint;->mTypeface:Landroid/graphics/Typeface;
 Landroid/graphics/Paint;->setCompatibilityScaling(F)V
 Landroid/graphics/Paint;->setHyphenEdit(I)V
 Landroid/graphics/Path;->isSimplePath:Z
@@ -2190,6 +2267,7 @@
 Landroid/graphics/Region;->scale(F)V
 Landroid/graphics/Shader$TileMode;->nativeInt:I
 Landroid/graphics/SurfaceTexture;->mFrameAvailableListener:J
+Landroid/graphics/SurfaceTexture;->mOnFrameAvailableHandler:Landroid/os/Handler;
 Landroid/graphics/SurfaceTexture;->mProducer:J
 Landroid/graphics/SurfaceTexture;->mSurfaceTexture:J
 Landroid/graphics/SurfaceTexture;->nativeDetachFromGLContext()I
@@ -2207,6 +2285,7 @@
 Landroid/graphics/Typeface;->createFromFamiliesWithDefault([Landroid/graphics/FontFamily;II)Landroid/graphics/Typeface;
 Landroid/graphics/Typeface;->createFromFamiliesWithDefault([Landroid/graphics/FontFamily;Ljava/lang/String;II)Landroid/graphics/Typeface;
 Landroid/graphics/Typeface;->mStyle:I
+Landroid/graphics/Typeface;->nativeCreateFromArray([JII)J
 Landroid/graphics/Typeface;->nativeCreateWeightAlias(JI)J
 Landroid/graphics/Typeface;->native_instance:J
 Landroid/graphics/Typeface;->sDefaults:[Landroid/graphics/Typeface;
@@ -2284,6 +2363,7 @@
 Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Landroid/hardware/camera2/utils/TypeReference;)V
 Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
 Landroid/hardware/camera2/CaptureRequest$Key;->getNativeKey()Landroid/hardware/camera2/impl/CameraMetadataNative$Key;
+Landroid/hardware/camera2/CaptureRequest;->getTargets()Ljava/util/Collection;
 Landroid/hardware/camera2/CaptureRequest;->JPEG_GPS_COORDINATES:Landroid/hardware/camera2/CaptureRequest$Key;
 Landroid/hardware/camera2/CaptureRequest;->JPEG_GPS_PROCESSING_METHOD:Landroid/hardware/camera2/CaptureRequest$Key;
 Landroid/hardware/camera2/CaptureRequest;->JPEG_GPS_TIMESTAMP:Landroid/hardware/camera2/CaptureRequest$Key;
@@ -2319,6 +2399,7 @@
 Landroid/hardware/camera2/CaptureResult;->TONEMAP_CURVE_RED:Landroid/hardware/camera2/CaptureResult$Key;
 Landroid/hardware/camera2/impl/CameraMetadataNative$Key;->getTag()I
 Landroid/hardware/camera2/impl/CameraMetadataNative;->mMetadataPtr:J
+Landroid/hardware/camera2/utils/SurfaceUtils;->getSurfaceSize(Landroid/view/Surface;)Landroid/util/Size;
 Landroid/hardware/camera2/utils/TypeReference;-><init>()V
 Landroid/hardware/camera2/utils/TypeReference;->createSpecializedTypeReference(Ljava/lang/reflect/Type;)Landroid/hardware/camera2/utils/TypeReference;
 Landroid/hardware/Camera;->addCallbackBuffer([BI)V
@@ -2372,6 +2453,7 @@
 Landroid/hardware/display/WifiDisplayStatus;->SCAN_STATE_NOT_SCANNING:I
 Landroid/hardware/fingerprint/Fingerprint;->getFingerId()I
 Landroid/hardware/fingerprint/Fingerprint;->getName()Ljava/lang/CharSequence;
+Landroid/hardware/fingerprint/FingerprintManager$AuthenticationResult;->getFingerprint()Landroid/hardware/fingerprint/Fingerprint;
 Landroid/hardware/fingerprint/FingerprintManager;->getAuthenticatorId()J
 Landroid/hardware/fingerprint/FingerprintManager;->getEnrolledFingerprints()Ljava/util/List;
 Landroid/hardware/fingerprint/FingerprintManager;->getEnrolledFingerprints(I)Ljava/util/List;
@@ -2561,9 +2643,20 @@
 Landroid/location/Location;->mProvider:Ljava/lang/String;
 Landroid/location/LocationManager;->mService:Landroid/location/ILocationManager;
 Landroid/location/LocationManager;->requestLocationUpdates(Landroid/location/LocationRequest;Landroid/location/LocationListener;Landroid/os/Looper;Landroid/app/PendingIntent;)V
+Landroid/location/LocationManager;->sendNiResponse(II)Z
+Landroid/location/LocationRequest;->checkDisplacement(F)V
+Landroid/location/LocationRequest;->checkInterval(J)V
+Landroid/location/LocationRequest;->checkProvider(Ljava/lang/String;)V
+Landroid/location/LocationRequest;->checkQuality(I)V
+Landroid/location/LocationRequest;->mExpireAt:J
+Landroid/location/LocationRequest;->mExplicitFastestInterval:Z
+Landroid/location/LocationRequest;->mFastestInterval:J
 Landroid/location/LocationRequest;->mHideFromAppOps:Z
 Landroid/location/LocationRequest;->mInterval:J
+Landroid/location/LocationRequest;->mNumUpdates:I
 Landroid/location/LocationRequest;->mProvider:Ljava/lang/String;
+Landroid/location/LocationRequest;->mQuality:I
+Landroid/location/LocationRequest;->mSmallestDisplacement:F
 Landroid/location/LocationRequest;->mWorkSource:Landroid/os/WorkSource;
 Landroid/media/AmrInputStream;-><init>(Ljava/io/InputStream;)V
 Landroid/media/AsyncPlayer;->setUsesWakeLock(Landroid/content/Context;)V
@@ -2755,6 +2848,7 @@
 Landroid/media/AudioTrack;->native_release()V
 Landroid/media/AudioTrack;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
 Landroid/media/CamcorderProfile;->native_get_camcorder_profile(II)Landroid/media/CamcorderProfile;
+Landroid/media/CamcorderProfile;->native_init()V
 Landroid/media/DecoderCapabilities$AudioDecoder;->AUDIO_DECODER_WMA:Landroid/media/DecoderCapabilities$AudioDecoder;
 Landroid/media/DecoderCapabilities$VideoDecoder;->VIDEO_DECODER_WMV:Landroid/media/DecoderCapabilities$VideoDecoder;
 Landroid/media/DecoderCapabilities;->getAudioDecoders()Ljava/util/List;
@@ -2765,8 +2859,13 @@
 Landroid/media/EncoderCapabilities$VideoEncoderCap;->mMinFrameHeight:I
 Landroid/media/EncoderCapabilities$VideoEncoderCap;->mMinFrameWidth:I
 Landroid/media/EncoderCapabilities;->getVideoEncoders()Ljava/util/List;
+Landroid/media/ExifInterface;->convertRationalLatLonToFloat(Ljava/lang/String;Ljava/lang/String;)F
 Landroid/media/ExifInterface;->getDateTime()J
+Landroid/media/ExifInterface;->getGpsDateTime()J
 Landroid/media/ExifInterface;->mAttributes:[Ljava/util/HashMap;
+Landroid/media/ExifInterface;->mFilename:Ljava/lang/String;
+Landroid/media/ExifInterface;->mHasThumbnail:Z
+Landroid/media/ExifInterface;->sFormatter:Ljava/text/SimpleDateFormat;
 Landroid/media/IAudioFocusDispatcher;->dispatchAudioFocusChange(ILjava/lang/String;)V
 Landroid/media/IAudioRoutesObserver$Stub;-><init>()V
 Landroid/media/IAudioService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -2793,6 +2892,7 @@
 Landroid/media/MediaCodec;->mNativeContext:J
 Landroid/media/MediaCodec;->releaseOutputBuffer(IZZJ)V
 Landroid/media/MediaCodec;->setParameters([Ljava/lang/String;[Ljava/lang/Object;)V
+Landroid/media/MediaCodecInfo$VideoCapabilities;->create(Landroid/media/MediaFormat;Landroid/media/MediaCodecInfo$CodecCapabilities;)Landroid/media/MediaCodecInfo$VideoCapabilities;
 Landroid/media/MediaFile$MediaFileType;->fileType:I
 Landroid/media/MediaFile$MediaFileType;->mimeType:Ljava/lang/String;
 Landroid/media/MediaFile;-><init>()V
@@ -2829,7 +2929,11 @@
 Landroid/media/MediaHTTPConnection;->readAt(JI)I
 Landroid/media/MediaHTTPService;->createHttpServiceBinderIfNecessary(Ljava/lang/String;)Landroid/os/IBinder;
 Landroid/media/MediaInserter;->flushAll()V
+Landroid/media/MediaMetadata;->getKeyFromMetadataEditorKey(I)Ljava/lang/String;
 Landroid/media/MediaMetadataRetriever;->getEmbeddedPicture(I)[B
+Landroid/media/MediaMetadataRetriever;->native_finalize()V
+Landroid/media/MediaMetadataRetriever;->native_init()V
+Landroid/media/MediaMetadataRetriever;->native_setup()V
 Landroid/media/MediaMuxer;->mCloseGuard:Ldalvik/system/CloseGuard;
 Landroid/media/MediaMuxer;->mNativeObject:J
 Landroid/media/MediaMuxer;->mState:I
@@ -2858,16 +2962,28 @@
 Landroid/media/MediaPlayer;->setParameter(ILandroid/os/Parcel;)Z
 Landroid/media/MediaPlayer;->setRetransmitEndpoint(Ljava/net/InetSocketAddress;)V
 Landroid/media/MediaPlayer;->setSubtitleAnchor(Landroid/media/SubtitleController;Landroid/media/SubtitleController$Anchor;)V
+Landroid/media/MediaRecorder;->mEventHandler:Landroid/media/MediaRecorder$EventHandler;
+Landroid/media/MediaRecorder;->mFd:Ljava/io/FileDescriptor;
+Landroid/media/MediaRecorder;->mOnErrorListener:Landroid/media/MediaRecorder$OnErrorListener;
+Landroid/media/MediaRecorder;->mOnInfoListener:Landroid/media/MediaRecorder$OnInfoListener;
+Landroid/media/MediaRecorder;->mPath:Ljava/lang/String;
+Landroid/media/MediaRecorder;->mSurface:Landroid/view/Surface;
+Landroid/media/MediaRecorder;->native_finalize()V
+Landroid/media/MediaRecorder;->native_init()V
+Landroid/media/MediaRecorder;->native_reset()V
 Landroid/media/MediaRecorder;->native_setup(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V
 Landroid/media/MediaRecorder;->setParameter(Ljava/lang/String;)V
+Landroid/media/MediaRecorder;->_prepare()V
 Landroid/media/MediaRouter$RouteInfo;->getDeviceAddress()Ljava/lang/String;
 Landroid/media/MediaRouter$RouteInfo;->getName(Landroid/content/res/Resources;)Ljava/lang/CharSequence;
 Landroid/media/MediaRouter$RouteInfo;->getStatusCode()I
+Landroid/media/MediaRouter$RouteInfo;->isDefault()Z
 Landroid/media/MediaRouter$RouteInfo;->isSelected()Z
 Landroid/media/MediaRouter$RouteInfo;->matchesTypes(I)Z
 Landroid/media/MediaRouter$RouteInfo;->mNameResId:I
 Landroid/media/MediaRouter$RouteInfo;->select()V
 Landroid/media/MediaRouter$RouteInfo;->STATUS_CONNECTING:I
+Landroid/media/MediaRouter;->getSelectedRoute()Landroid/media/MediaRouter$RouteInfo;
 Landroid/media/MediaRouter;->selectRouteInt(ILandroid/media/MediaRouter$RouteInfo;Z)V
 Landroid/media/MediaScanner$FileEntry;-><init>(JLjava/lang/String;JI)V
 Landroid/media/MediaScanner$FileEntry;->mLastModifiedChanged:Z
@@ -2976,8 +3092,14 @@
 Landroid/media/SubtitleTrack$RenderingWidget;->onDetachedFromWindow()V
 Landroid/media/SubtitleTrack$RenderingWidget;->setOnChangedListener(Landroid/media/SubtitleTrack$RenderingWidget$OnChangedListener;)V
 Landroid/media/SubtitleTrack$RenderingWidget;->setSize(II)V
+Landroid/media/ThumbnailUtils;->closeSilently(Landroid/os/ParcelFileDescriptor;)V
+Landroid/media/ThumbnailUtils;->computeInitialSampleSize(Landroid/graphics/BitmapFactory$Options;II)I
+Landroid/media/ThumbnailUtils;->computeSampleSize(Landroid/graphics/BitmapFactory$Options;II)I
 Landroid/media/ThumbnailUtils;->createImageThumbnail(Ljava/lang/String;I)Landroid/graphics/Bitmap;
+Landroid/media/ThumbnailUtils;->createThumbnailFromEXIF(Ljava/lang/String;IILandroid/media/ThumbnailUtils$SizedThumbnailBitmap;)V
+Landroid/media/ThumbnailUtils;->makeInputStream(Landroid/net/Uri;Landroid/content/ContentResolver;)Landroid/os/ParcelFileDescriptor;
 Landroid/media/ThumbnailUtils;->TARGET_SIZE_MICRO_THUMBNAIL:I
+Landroid/media/ThumbnailUtils;->transform(Landroid/graphics/Matrix;Landroid/graphics/Bitmap;III)Landroid/graphics/Bitmap;
 Landroid/media/TimedText;->getObject(I)Ljava/lang/Object;
 Landroid/media/ToneGenerator;->mNativeContext:J
 Landroid/media/TtmlRenderer;-><init>(Landroid/content/Context;)V
@@ -3124,6 +3246,8 @@
 Landroid/net/http/SslCertificate;->inflateCertificateView(Landroid/content/Context;)Landroid/view/View;
 Landroid/net/http/SslCertificate;->mX509Certificate:Ljava/security/cert/X509Certificate;
 Landroid/net/http/SslError;->mCertificate:Landroid/net/http/SslCertificate;
+Landroid/net/http/SslError;->mErrors:I
+Landroid/net/http/SslError;->mUrl:Ljava/lang/String;
 Landroid/net/IConnectivityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/net/IConnectivityManager$Stub$Proxy;->getActiveLinkProperties()Landroid/net/LinkProperties;
 Landroid/net/IConnectivityManager$Stub$Proxy;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
@@ -3139,11 +3263,13 @@
 Landroid/net/IConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
 Landroid/net/IConnectivityManager;->getAllNetworkInfo()[Landroid/net/NetworkInfo;
 Landroid/net/IConnectivityManager;->getLastTetherError(Ljava/lang/String;)I
+Landroid/net/IConnectivityManager;->getNetworkInfo(I)Landroid/net/NetworkInfo;
 Landroid/net/IConnectivityManager;->getTetherableIfaces()[Ljava/lang/String;
 Landroid/net/IConnectivityManager;->getTetherableUsbRegexs()[Ljava/lang/String;
 Landroid/net/IConnectivityManager;->getTetherableWifiRegexs()[Ljava/lang/String;
 Landroid/net/IConnectivityManager;->getTetheredIfaces()[Ljava/lang/String;
 Landroid/net/IConnectivityManager;->getTetheringErroredIfaces()[Ljava/lang/String;
+Landroid/net/IConnectivityManager;->reportInetCondition(II)V
 Landroid/net/IConnectivityManager;->setAirplaneMode(Z)V
 Landroid/net/IConnectivityManager;->startLegacyVpn(Lcom/android/internal/net/VpnProfile;)V
 Landroid/net/INetworkManagementEventObserver$Stub;-><init>()V
@@ -3174,12 +3300,16 @@
 Landroid/net/IpConfiguration$ProxySettings;->NONE:Landroid/net/IpConfiguration$ProxySettings;
 Landroid/net/IpConfiguration;-><init>(Landroid/net/IpConfiguration$IpAssignment;Landroid/net/IpConfiguration$ProxySettings;Landroid/net/StaticIpConfiguration;Landroid/net/ProxyInfo;)V
 Landroid/net/IpConfiguration;->httpProxy:Landroid/net/ProxyInfo;
+Landroid/net/LinkAddress;->address:Ljava/net/InetAddress;
 Landroid/net/LinkAddress;->getNetworkPrefixLength()I
+Landroid/net/LinkAddress;->prefixLength:I
 Landroid/net/LinkProperties;->addLinkAddress(Landroid/net/LinkAddress;)Z
 Landroid/net/LinkProperties;->getAddresses()Ljava/util/List;
 Landroid/net/LinkProperties;->getAllAddresses()Ljava/util/List;
 Landroid/net/LinkProperties;->getAllLinkAddresses()Ljava/util/List;
+Landroid/net/LinkProperties;->isIdenticalHttpProxy(Landroid/net/LinkProperties;)Z
 Landroid/net/LinkProperties;->isIdenticalInterfaceName(Landroid/net/LinkProperties;)Z
+Landroid/net/LinkProperties;->mIfaceName:Ljava/lang/String;
 Landroid/net/LinkProperties;->setHttpProxy(Landroid/net/ProxyInfo;)V
 Landroid/net/LinkQualityInfo;->setDataSampleDuration(I)V
 Landroid/net/LinkQualityInfo;->setLastDataSampleTime(J)V
@@ -3304,9 +3434,14 @@
 Landroid/net/nsd/INsdManager;->getMessenger()Landroid/os/Messenger;
 Landroid/net/nsd/NsdServiceInfo;->setAttribute(Ljava/lang/String;[B)V
 Landroid/net/Proxy;->getProxy(Landroid/content/Context;Ljava/lang/String;)Ljava/net/Proxy;
+Landroid/net/Proxy;->setHttpProxySystemProperty(Landroid/net/ProxyInfo;)V
 Landroid/net/ProxyInfo;-><init>(Ljava/lang/String;ILjava/lang/String;)V
+Landroid/net/RouteInfo;-><init>(Landroid/net/LinkAddress;Ljava/net/InetAddress;)V
 Landroid/net/RouteInfo;-><init>(Landroid/net/LinkAddress;Ljava/net/InetAddress;Ljava/lang/String;)V
 Landroid/net/RouteInfo;-><init>(Ljava/net/InetAddress;)V
+Landroid/net/RouteInfo;->isHost()Z
+Landroid/net/RouteInfo;->mGateway:Ljava/net/InetAddress;
+Landroid/net/RouteInfo;->mIsHost:Z
 Landroid/net/SntpClient;-><init>()V
 Landroid/net/SSLCertificateSocketFactory;-><init>(ILandroid/net/SSLSessionCache;Z)V
 Landroid/net/SSLCertificateSocketFactory;->castToOpenSSLSocket(Ljava/net/Socket;)Lcom/android/org/conscrypt/OpenSSLSocketImpl;
@@ -3365,6 +3500,12 @@
 Landroid/net/wifi/IWifiScanner$Stub;-><init>()V
 Landroid/net/wifi/IWifiScanner$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiScanner;
 Landroid/net/wifi/p2p/IWifiP2pManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/p2p/IWifiP2pManager;
+Landroid/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo;->createRequest(Ljava/lang/String;II)Ljava/lang/String;
+Landroid/net/wifi/p2p/nsd/WifiP2pServiceInfo;-><init>(Ljava/util/List;)V
+Landroid/net/wifi/p2p/nsd/WifiP2pServiceInfo;->CREATOR:Landroid/os/Parcelable$Creator;
+Landroid/net/wifi/p2p/nsd/WifiP2pServiceInfo;->mQueryList:Ljava/util/List;
+Landroid/net/wifi/p2p/nsd/WifiP2pServiceRequest;-><init>(ILjava/lang/String;)V
+Landroid/net/wifi/p2p/nsd/WifiP2pServiceRequest;->CREATOR:Landroid/os/Parcelable$Creator;
 Landroid/net/wifi/p2p/WifiP2pConfig;-><init>(Ljava/lang/String;)V
 Landroid/net/wifi/p2p/WifiP2pConfig;->MIN_GROUP_OWNER_INTENT:I
 Landroid/net/wifi/p2p/WifiP2pConfig;->netId:I
@@ -3477,6 +3618,7 @@
 Landroid/net/wifi/WifiInfo;->getWifiSsid()Landroid/net/wifi/WifiSsid;
 Landroid/net/wifi/WifiInfo;->INVALID_RSSI:I
 Landroid/net/wifi/WifiInfo;->isEphemeral()Z
+Landroid/net/wifi/WifiInfo;->mBSSID:Ljava/lang/String;
 Landroid/net/wifi/WifiInfo;->mIpAddress:Ljava/net/InetAddress;
 Landroid/net/wifi/WifiInfo;->mMacAddress:Ljava/lang/String;
 Landroid/net/wifi/WifiInfo;->mWifiSsid:Landroid/net/wifi/WifiSsid;
@@ -3493,6 +3635,7 @@
 Landroid/net/wifi/WifiManager;->disable(ILandroid/net/wifi/WifiManager$ActionListener;)V
 Landroid/net/wifi/WifiManager;->enableVerboseLogging(I)V
 Landroid/net/wifi/WifiManager;->forget(ILandroid/net/wifi/WifiManager$ActionListener;)V
+Landroid/net/wifi/WifiManager;->getCountryCode()Ljava/lang/String;
 Landroid/net/wifi/WifiManager;->getCurrentNetwork()Landroid/net/Network;
 Landroid/net/wifi/WifiManager;->getMatchingWifiConfig(Landroid/net/wifi/ScanResult;)Landroid/net/wifi/WifiConfiguration;
 Landroid/net/wifi/WifiManager;->getVerboseLoggingLevel()I
@@ -3584,22 +3727,32 @@
 Landroid/os/BatteryStats$HistoryItem;->batteryPlugType:B
 Landroid/os/BatteryStats$HistoryItem;->batteryStatus:B
 Landroid/os/BatteryStats$HistoryItem;->batteryVoltage:C
+Landroid/os/BatteryStats$HistoryItem;->clear()V
 Landroid/os/BatteryStats$HistoryItem;->CMD_UPDATE:B
+Landroid/os/BatteryStats$HistoryItem;->next:Landroid/os/BatteryStats$HistoryItem;
+Landroid/os/BatteryStats$HistoryItem;->same(Landroid/os/BatteryStats$HistoryItem;)Z
+Landroid/os/BatteryStats$HistoryItem;->setTo(JBLandroid/os/BatteryStats$HistoryItem;)V
+Landroid/os/BatteryStats$HistoryItem;->setTo(Landroid/os/BatteryStats$HistoryItem;)V
 Landroid/os/BatteryStats$HistoryItem;->states2:I
+Landroid/os/BatteryStats$Timer;-><init>()V
 Landroid/os/BatteryStats$Timer;->getTotalTimeLocked(JI)J
 Landroid/os/BatteryStats$Uid$Pkg$Serv;->getLaunches(I)I
 Landroid/os/BatteryStats$Uid$Pkg$Serv;->getStartTime(JI)J
+Landroid/os/BatteryStats$Uid$Pkg;-><init>()V
 Landroid/os/BatteryStats$Uid$Pkg;->getServiceStats()Landroid/util/ArrayMap;
 Landroid/os/BatteryStats$Uid$Pkg;->getWakeupAlarmStats()Landroid/util/ArrayMap;
+Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;-><init>()V
 Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->overTime:J
 Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->type:I
 Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;->usedTime:J
+Landroid/os/BatteryStats$Uid$Proc;-><init>()V
 Landroid/os/BatteryStats$Uid$Proc;->countExcessivePowers()I
 Landroid/os/BatteryStats$Uid$Proc;->getExcessivePower(I)Landroid/os/BatteryStats$Uid$Proc$ExcessivePower;
 Landroid/os/BatteryStats$Uid$Proc;->getForegroundTime(I)J
 Landroid/os/BatteryStats$Uid$Proc;->getStarts(I)I
 Landroid/os/BatteryStats$Uid$Proc;->getSystemTime(I)J
 Landroid/os/BatteryStats$Uid$Proc;->getUserTime(I)J
+Landroid/os/BatteryStats$Uid$Sensor;-><init>()V
 Landroid/os/BatteryStats$Uid$Sensor;->getHandle()I
 Landroid/os/BatteryStats$Uid$Sensor;->getSensorTime()Landroid/os/BatteryStats$Timer;
 Landroid/os/BatteryStats$Uid$Sensor;->GPS:I
@@ -3617,6 +3770,7 @@
 Landroid/os/BatteryStats$Uid;->getWifiBatchedScanTime(IJI)J
 Landroid/os/BatteryStats$Uid;->getWifiMulticastTime(JI)J
 Landroid/os/BatteryStats$Uid;->getWifiScanTime(JI)J
+Landroid/os/BatteryStats;-><init>()V
 Landroid/os/BatteryStats;->computeBatteryTimeRemaining(J)J
 Landroid/os/BatteryStats;->computeBatteryUptime(JI)J
 Landroid/os/BatteryStats;->computeChargeTimeRemaining(J)J
@@ -3642,6 +3796,11 @@
 Landroid/os/Bundle;->putIBinder(Ljava/lang/String;Landroid/os/IBinder;)V
 Landroid/os/Bundle;->putParcelableList(Ljava/lang/String;Ljava/util/List;)V
 Landroid/os/Bundle;->setDefusable(Landroid/os/Bundle;Z)Landroid/os/Bundle;
+Landroid/os/CancellationSignal;->mCancelInProgress:Z
+Landroid/os/CancellationSignal;->mIsCanceled:Z
+Landroid/os/CancellationSignal;->mOnCancelListener:Landroid/os/CancellationSignal$OnCancelListener;
+Landroid/os/CancellationSignal;->mRemote:Landroid/os/ICancellationSignal;
+Landroid/os/CancellationSignal;->waitForCancelFinishedLocked()V
 Landroid/os/Debug$MemoryInfo;->dalvikPrivateClean:I
 Landroid/os/Debug$MemoryInfo;->dalvikRss:I
 Landroid/os/Debug$MemoryInfo;->dalvikSharedClean:I
@@ -3724,6 +3883,7 @@
 Landroid/os/Handler;->getPostMessage(Ljava/lang/Runnable;Ljava/lang/Object;)Landroid/os/Message;
 Landroid/os/Handler;->hasCallbacks(Ljava/lang/Runnable;)Z
 Landroid/os/Handler;->mCallback:Landroid/os/Handler$Callback;
+Landroid/os/Handler;->mLooper:Landroid/os/Looper;
 Landroid/os/Handler;->mMessenger:Landroid/os/IMessenger;
 Landroid/os/health/HealthKeys$Constants;-><init>(Ljava/lang/Class;)V
 Landroid/os/health/HealthStats;-><init>(Landroid/os/Parcel;)V
@@ -3793,6 +3953,7 @@
 Landroid/os/MemoryFile;->getFileDescriptor()Ljava/io/FileDescriptor;
 Landroid/os/MemoryFile;->getSize(Ljava/io/FileDescriptor;)I
 Landroid/os/MemoryFile;->native_get_size(Ljava/io/FileDescriptor;)I
+Landroid/os/MemoryFile;->native_pin(Ljava/io/FileDescriptor;Z)Z
 Landroid/os/Message;->callback:Ljava/lang/Runnable;
 Landroid/os/Message;->flags:I
 Landroid/os/Message;->markInUse()V
@@ -3843,6 +4004,8 @@
 Landroid/os/PerformanceCollector;->endSnapshot()Landroid/os/Bundle;
 Landroid/os/PerformanceCollector;->startTiming(Ljava/lang/String;)V
 Landroid/os/PerformanceCollector;->stopTiming(Ljava/lang/String;)Landroid/os/Bundle;
+Landroid/os/PowerManager$WakeLock;->mFlags:I
+Landroid/os/PowerManager$WakeLock;->mTag:Ljava/lang/String;
 Landroid/os/PowerManager;->ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED:Ljava/lang/String;
 Landroid/os/PowerManager;->ACTION_POWER_SAVE_MODE_CHANGING:Ljava/lang/String;
 Landroid/os/PowerManager;->BRIGHTNESS_ON:I
@@ -3886,6 +4049,7 @@
 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;->ROOT_UID:I
+Landroid/os/Process;->sendSignalQuiet(II)V
 Landroid/os/Process;->setArgV0(Ljava/lang/String;)V
 Landroid/os/Process;->setProcessGroup(II)V
 Landroid/os/Process;->SHELL_UID:I
@@ -3921,6 +4085,7 @@
 Landroid/os/ServiceSpecificException;-><init>(ILjava/lang/String;)V
 Landroid/os/SharedMemory;->getFd()I
 Landroid/os/ShellCommand;->peekNextArg()Ljava/lang/String;
+Landroid/os/StatFs;->mStat:Landroid/system/StructStatVfs;
 Landroid/os/storage/DiskInfo;-><init>(Landroid/os/Parcel;)V
 Landroid/os/storage/DiskInfo;->CREATOR:Landroid/os/Parcelable$Creator;
 Landroid/os/storage/DiskInfo;->flags:I
@@ -3965,6 +4130,7 @@
 Landroid/os/storage/StorageManager;->getVolumeState(Ljava/lang/String;)Ljava/lang/String;
 Landroid/os/storage/StorageManager;->isFileEncryptedNativeOnly()Z
 Landroid/os/storage/StorageManager;->isUsbMassStorageEnabled()Z
+Landroid/os/storage/StorageManager;->partitionPublic(Ljava/lang/String;)V
 Landroid/os/storage/StorageManager;->unmount(Ljava/lang/String;)V
 Landroid/os/storage/StorageVolume;->allowMassStorage()Z
 Landroid/os/storage/StorageVolume;->getFatVolumeId()I
@@ -4026,8 +4192,15 @@
 Landroid/os/SystemClock;->currentTimeMicro()J
 Landroid/os/SystemProperties;-><init>()V
 Landroid/os/SystemProperties;->addChangeCallback(Ljava/lang/Runnable;)V
+Landroid/os/SystemProperties;->native_add_change_callback()V
 Landroid/os/SystemProperties;->native_get(Ljava/lang/String;)Ljava/lang/String;
+Landroid/os/SystemProperties;->native_get(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+Landroid/os/SystemProperties;->native_get_boolean(Ljava/lang/String;Z)Z
+Landroid/os/SystemProperties;->native_get_int(Ljava/lang/String;I)I
+Landroid/os/SystemProperties;->native_get_long(Ljava/lang/String;J)J
+Landroid/os/SystemProperties;->native_set(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/os/SystemProperties;->PROP_NAME_MAX:I
+Landroid/os/SystemProperties;->sChangeCallbacks:Ljava/util/ArrayList;
 Landroid/os/SystemProperties;->set(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/os/SystemVibrator;-><init>(Landroid/content/Context;)V
 Landroid/os/Trace;->asyncTraceBegin(JLjava/lang/String;I)V
@@ -4044,6 +4217,7 @@
 Landroid/os/UEventObserver$UEvent;->get(Ljava/lang/String;)Ljava/lang/String;
 Landroid/os/UEventObserver$UEvent;->get(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 Landroid/os/UEventObserver;-><init>()V
+Landroid/os/UEventObserver;->onUEvent(Landroid/os/UEventObserver$UEvent;)V
 Landroid/os/UEventObserver;->startObserving(Ljava/lang/String;)V
 Landroid/os/UEventObserver;->stopObserving()V
 Landroid/os/UpdateLock;->acquire()V
@@ -4062,12 +4236,14 @@
 Landroid/os/UserHandle;->CURRENT:Landroid/os/UserHandle;
 Landroid/os/UserHandle;->CURRENT_OR_SELF:Landroid/os/UserHandle;
 Landroid/os/UserHandle;->ERR_GID:I
+Landroid/os/UserHandle;->formatUid(Ljava/io/PrintWriter;I)V
 Landroid/os/UserHandle;->getAppIdFromSharedAppGid(I)I
 Landroid/os/UserHandle;->getCallingUserId()I
 Landroid/os/UserHandle;->getUid(II)I
 Landroid/os/UserHandle;->getUserId(I)I
 Landroid/os/UserHandle;->isApp(I)Z
 Landroid/os/UserHandle;->isIsolated(I)Z
+Landroid/os/UserHandle;->mHandle:I
 Landroid/os/UserHandle;->MU_ENABLED:Z
 Landroid/os/UserHandle;->OWNER:Landroid/os/UserHandle;
 Landroid/os/UserHandle;->PER_USER_RANGE:I
@@ -4127,7 +4303,13 @@
 Landroid/os/WorkSource;->mNum:I
 Landroid/os/WorkSource;->mUids:[I
 Landroid/os/WorkSource;->setReturningDiffs(Landroid/os/WorkSource;)[Landroid/os/WorkSource;
+Landroid/os/WorkSource;->sGoneWork:Landroid/os/WorkSource;
 Landroid/os/WorkSource;->size()I
+Landroid/os/WorkSource;->sNewbWork:Landroid/os/WorkSource;
+Landroid/os/WorkSource;->sTmpWorkSource:Landroid/os/WorkSource;
+Landroid/os/WorkSource;->updateLocked(Landroid/os/WorkSource;ZZ)Z
+Landroid/os/ZygoteStartFailedEx;-><init>(Ljava/lang/String;)V
+Landroid/os/ZygoteStartFailedEx;-><init>(Ljava/lang/Throwable;)V
 Landroid/permissionpresenterservice/RuntimePermissionPresenterService;->onRevokeRuntimePermission(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/preference/DialogPreference;->mBuilder:Landroid/app/AlertDialog$Builder;
 Landroid/preference/DialogPreference;->mDialog:Landroid/app/Dialog;
@@ -4264,9 +4446,11 @@
 Landroid/provider/Downloads$Impl;->isStatusSuccess(I)Z
 Landroid/provider/Downloads$Impl;->PUBLICLY_ACCESSIBLE_DOWNLOADS_URI:Landroid/net/Uri;
 Landroid/provider/MediaStore$Files$FileColumns;->FORMAT:Ljava/lang/String;
+Landroid/provider/MediaStore$Files$FileColumns;->STORAGE_ID:Ljava/lang/String;
 Landroid/provider/MediaStore$Files;->getMtpObjectsUri(Ljava/lang/String;)Landroid/net/Uri;
 Landroid/provider/MediaStore$Files;->getMtpObjectsUri(Ljava/lang/String;J)Landroid/net/Uri;
 Landroid/provider/MediaStore$Files;->getMtpReferencesUri(Ljava/lang/String;J)Landroid/net/Uri;
+Landroid/provider/MediaStore$MediaColumns;->IS_DRM:Ljava/lang/String;
 Landroid/provider/Settings$Bookmarks;->add(Landroid/content/ContentResolver;Landroid/content/Intent;Ljava/lang/String;Ljava/lang/String;CI)Landroid/net/Uri;
 Landroid/provider/Settings$Bookmarks;->CONTENT_URI:Landroid/net/Uri;
 Landroid/provider/Settings$ContentProviderHolder;->mContentProvider:Landroid/content/IContentProvider;
@@ -4275,6 +4459,7 @@
 Landroid/provider/Settings$Global;->HEADS_UP_OFF:I
 Landroid/provider/Settings$Global;->HEADS_UP_ON:I
 Landroid/provider/Settings$Global;->MOBILE_DATA:Ljava/lang/String;
+Landroid/provider/Settings$Global;->MULTI_SIM_USER_PREFERRED_SUBS:[Ljava/lang/String;
 Landroid/provider/Settings$Global;->MULTI_SIM_VOICE_PROMPT:Ljava/lang/String;
 Landroid/provider/Settings$Global;->NETWORK_SCORER_APP:Ljava/lang/String;
 Landroid/provider/Settings$Global;->PACKAGE_VERIFIER_ENABLE:Ljava/lang/String;
@@ -4308,6 +4493,7 @@
 Landroid/provider/Settings$Secure;->ENABLED_PRINT_SERVICES:Ljava/lang/String;
 Landroid/provider/Settings$Secure;->getIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;II)I
 Landroid/provider/Settings$Secure;->getLongForUser(Landroid/content/ContentResolver;Ljava/lang/String;JI)J
+Landroid/provider/Settings$Secure;->IMMERSIVE_MODE_CONFIRMATIONS:Ljava/lang/String;
 Landroid/provider/Settings$Secure;->INCALL_POWER_BUTTON_BEHAVIOR:Ljava/lang/String;
 Landroid/provider/Settings$Secure;->LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS:Ljava/lang/String;
 Landroid/provider/Settings$Secure;->LOCK_SCREEN_LOCK_AFTER_TIMEOUT:Ljava/lang/String;
@@ -4355,6 +4541,7 @@
 Landroid/provider/Settings$System;->VIBRATE_IN_SILENT:Ljava/lang/String;
 Landroid/provider/Settings;->ACTION_TRUSTED_CREDENTIALS_USER:Ljava/lang/String;
 Landroid/provider/Settings;->ACTION_USER_DICTIONARY_INSERT:Ljava/lang/String;
+Landroid/provider/Settings;->EXTRA_APP_UID:Ljava/lang/String;
 Landroid/provider/Settings;->isCallingPackageAllowedToDrawOverlays(Landroid/content/Context;ILjava/lang/String;Z)Z
 Landroid/provider/Settings;->isCallingPackageAllowedToPerformAppOpsProtectedOperation(Landroid/content/Context;ILjava/lang/String;ZI[Ljava/lang/String;Z)Z
 Landroid/provider/Settings;->isCallingPackageAllowedToWriteSettings(Landroid/content/Context;ILjava/lang/String;Z)Z
@@ -4373,6 +4560,8 @@
 Landroid/provider/Telephony$Sms;->isOutgoingFolder(I)Z
 Landroid/provider/Telephony$Sms;->moveMessageToFolder(Landroid/content/Context;Landroid/net/Uri;II)Z
 Landroid/provider/Telephony$Sms;->query(Landroid/content/ContentResolver;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
+Landroid/provider/Telephony$Threads;->ID_PROJECTION:[Ljava/lang/String;
+Landroid/provider/Telephony$Threads;->THREAD_ID_CONTENT_URI:Landroid/net/Uri;
 Landroid/R$styleable;->ActionBar:[I
 Landroid/R$styleable;->ActionBar_background:I
 Landroid/R$styleable;->ActionBar_backgroundSplit:I
@@ -4737,6 +4926,7 @@
 Landroid/security/IKeystoreService;->clear_uid(J)I
 Landroid/security/IKeystoreService;->del(Ljava/lang/String;I)I
 Landroid/security/IKeystoreService;->exist(Ljava/lang/String;I)I
+Landroid/security/IKeystoreService;->generateKey(Ljava/lang/String;Landroid/security/keymaster/KeymasterArguments;[BIILandroid/security/keymaster/KeyCharacteristics;)I
 Landroid/security/IKeystoreService;->get(Ljava/lang/String;I)[B
 Landroid/security/IKeystoreService;->getState(I)I
 Landroid/security/IKeystoreService;->get_pubkey(Ljava/lang/String;)[B
@@ -4752,6 +4942,9 @@
 Landroid/security/keymaster/KeyCharacteristics;-><init>()V
 Landroid/security/keymaster/KeyCharacteristics;->readFromParcel(Landroid/os/Parcel;)V
 Landroid/security/keymaster/KeymasterArguments;-><init>()V
+Landroid/security/keymaster/KeymasterArguments;->addEnum(II)V
+Landroid/security/keymaster/KeymasterArguments;->addUnsignedInt(IJ)V
+Landroid/security/keymaster/KeymasterArguments;->addUnsignedLong(ILjava/math/BigInteger;)V
 Landroid/security/keymaster/KeymasterArguments;->CREATOR:Landroid/os/Parcelable$Creator;
 Landroid/security/keymaster/KeymasterArguments;->readFromParcel(Landroid/os/Parcel;)V
 Landroid/security/keymaster/KeymasterBlob;->CREATOR:Landroid/os/Parcelable$Creator;
@@ -4765,6 +4958,7 @@
 Landroid/security/KeyStore;->get(Ljava/lang/String;)[B
 Landroid/security/KeyStore;->getApplicationContext()Landroid/content/Context;
 Landroid/security/KeyStore;->getInstance()Landroid/security/KeyStore;
+Landroid/security/KeyStore;->getKeyStoreException(I)Landroid/security/KeyStoreException;
 Landroid/security/KeyStore;->isEmpty()Z
 Landroid/security/KeyStore;->NO_ERROR:I
 Landroid/security/KeyStore;->reset()Z
@@ -4807,13 +5001,24 @@
 Landroid/service/media/MediaBrowserService;->KEY_MEDIA_ITEM:Ljava/lang/String;
 Landroid/service/notification/INotificationListener$Stub;-><init>()V
 Landroid/service/notification/NotificationListenerService$Ranking;->getVisibilityOverride()I
+Landroid/service/notification/NotificationListenerService;->getNotificationInterface()Landroid/app/INotificationManager;
 Landroid/service/notification/NotificationListenerService;->isBound()Z
 Landroid/service/notification/NotificationListenerService;->mHandler:Landroid/os/Handler;
+Landroid/service/notification/NotificationListenerService;->mNoMan:Landroid/app/INotificationManager;
+Landroid/service/notification/NotificationListenerService;->mWrapper:Landroid/service/notification/NotificationListenerService$NotificationListenerWrapper;
+Landroid/service/notification/NotificationListenerService;->TAG:Ljava/lang/String;
 Landroid/service/notification/StatusBarNotification;->getInitialPid()I
 Landroid/service/notification/StatusBarNotification;->getOpPkg()Ljava/lang/String;
 Landroid/service/notification/StatusBarNotification;->getPackageContext(Landroid/content/Context;)Landroid/content/Context;
 Landroid/service/notification/StatusBarNotification;->getUid()I
+Landroid/service/notification/StatusBarNotification;->id:I
+Landroid/service/notification/StatusBarNotification;->initialPid:I
+Landroid/service/notification/StatusBarNotification;->notification:Landroid/app/Notification;
+Landroid/service/notification/StatusBarNotification;->pkg:Ljava/lang/String;
+Landroid/service/notification/StatusBarNotification;->postTime:J
+Landroid/service/notification/StatusBarNotification;->tag:Ljava/lang/String;
 Landroid/service/notification/StatusBarNotification;->uid:I
+Landroid/service/notification/StatusBarNotification;->user:Landroid/os/UserHandle;
 Landroid/service/notification/ZenModeConfig$ScheduleInfo;->days:[I
 Landroid/service/notification/ZenModeConfig$ScheduleInfo;->endHour:I
 Landroid/service/notification/ZenModeConfig$ScheduleInfo;->endMinute:I
@@ -4919,6 +5124,9 @@
 Landroid/telecom/Connection$VideoProvider;-><init>(Landroid/os/Looper;)V
 Landroid/telecom/Phone;->setProximitySensorOff(Z)V
 Landroid/telecom/Phone;->setProximitySensorOn()V
+Landroid/telecom/PhoneAccountHandle;-><init>(Landroid/os/Parcel;)V
+Landroid/telecom/PhoneAccountHandle;->mComponentName:Landroid/content/ComponentName;
+Landroid/telecom/PhoneAccountHandle;->mId:Ljava/lang/String;
 Landroid/telecom/TelecomManager;->EXTRA_IS_HANDOVER:Ljava/lang/String;
 Landroid/telecom/TelecomManager;->getCallCapablePhoneAccounts(Z)Ljava/util/List;
 Landroid/telecom/TelecomManager;->getCurrentTtyMode()I
@@ -4932,6 +5140,12 @@
 Landroid/telephony/CarrierConfigManager;->KEY_CARRIER_DEFAULT_ACTIONS_ON_REDIRECTION_STRING_ARRAY:Ljava/lang/String;
 Landroid/telephony/CarrierConfigManager;->KEY_DISABLE_VOICE_BARRING_NOTIFICATION_BOOL:Ljava/lang/String;
 Landroid/telephony/CarrierMessagingServiceManager;-><init>()V
+Landroid/telephony/cdma/CdmaCellLocation;->equalsHandlesNulls(Ljava/lang/Object;Ljava/lang/Object;)Z
+Landroid/telephony/cdma/CdmaCellLocation;->mBaseStationId:I
+Landroid/telephony/cdma/CdmaCellLocation;->mBaseStationLatitude:I
+Landroid/telephony/cdma/CdmaCellLocation;->mBaseStationLongitude:I
+Landroid/telephony/cdma/CdmaCellLocation;->mNetworkId:I
+Landroid/telephony/cdma/CdmaCellLocation;->mSystemId:I
 Landroid/telephony/CellBroadcastMessage;-><init>(Landroid/telephony/SmsCbMessage;)V
 Landroid/telephony/CellBroadcastMessage;->createFromCursor(Landroid/database/Cursor;)Landroid/telephony/CellBroadcastMessage;
 Landroid/telephony/CellBroadcastMessage;->getContentValues()Landroid/content/ContentValues;
@@ -4987,6 +5201,11 @@
 Landroid/telephony/DisconnectCause;->toString(I)Ljava/lang/String;
 Landroid/telephony/euicc/EuiccInfo;->osVersion:Ljava/lang/String;
 Landroid/telephony/gsm/GsmCellLocation;->setPsc(I)V
+Landroid/telephony/NeighboringCellInfo;->mCid:I
+Landroid/telephony/NeighboringCellInfo;->mLac:I
+Landroid/telephony/NeighboringCellInfo;->mNetworkType:I
+Landroid/telephony/NeighboringCellInfo;->mPsc:I
+Landroid/telephony/NeighboringCellInfo;->mRssi:I
 Landroid/telephony/PhoneNumberFormattingTextWatcher;->mFormatter:Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;
 Landroid/telephony/PhoneNumberUtils;->cdmaCheckAndProcessPlusCode(Ljava/lang/String;)Ljava/lang/String;
 Landroid/telephony/PhoneNumberUtils;->compare(Ljava/lang/String;Ljava/lang/String;Z)Z
@@ -5033,6 +5252,7 @@
 Landroid/telephony/Rlog;->w(Ljava/lang/String;Ljava/lang/String;)I
 Landroid/telephony/Rlog;->w(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I
 Landroid/telephony/ServiceState;->bearerBitmapHasCdma(I)Z
+Landroid/telephony/ServiceState;->equalsHandlesNulls(Ljava/lang/Object;Ljava/lang/Object;)Z
 Landroid/telephony/ServiceState;->fillInNotifierBundle(Landroid/os/Bundle;)V
 Landroid/telephony/ServiceState;->getCdmaDefaultRoamingIndicator()I
 Landroid/telephony/ServiceState;->getCdmaEriIconIndex()I
@@ -5050,6 +5270,14 @@
 Landroid/telephony/ServiceState;->getVoiceOperatorNumeric()Ljava/lang/String;
 Landroid/telephony/ServiceState;->getVoiceRoaming()Z
 Landroid/telephony/ServiceState;->getVoiceRoamingType()I
+Landroid/telephony/ServiceState;->mCdmaDefaultRoamingIndicator:I
+Landroid/telephony/ServiceState;->mCdmaEriIconIndex:I
+Landroid/telephony/ServiceState;->mCdmaEriIconMode:I
+Landroid/telephony/ServiceState;->mCdmaRoamingIndicator:I
+Landroid/telephony/ServiceState;->mCssIndicator:Z
+Landroid/telephony/ServiceState;->mIsManualNetworkSelection:Z
+Landroid/telephony/ServiceState;->mNetworkId:I
+Landroid/telephony/ServiceState;->mSystemId:I
 Landroid/telephony/ServiceState;->newFromBundle(Landroid/os/Bundle;)Landroid/telephony/ServiceState;
 Landroid/telephony/ServiceState;->RIL_RADIO_TECHNOLOGY_IWLAN:I
 Landroid/telephony/ServiceState;->setCdmaDefaultRoamingIndicator(I)V
@@ -5062,13 +5290,16 @@
 Landroid/telephony/ServiceState;->setDataRoamingFromRegistration(Z)V
 Landroid/telephony/ServiceState;->setDataRoamingType(I)V
 Landroid/telephony/ServiceState;->setEmergencyOnly(Z)V
+Landroid/telephony/ServiceState;->setFromNotifierBundle(Landroid/os/Bundle;)V
 Landroid/telephony/ServiceState;->setOperatorAlphaLong(Ljava/lang/String;)V
 Landroid/telephony/ServiceState;->setVoiceRegState(I)V
 Landroid/telephony/ServiceState;->setVoiceRoaming(Z)V
 Landroid/telephony/ServiceState;->setVoiceRoamingType(I)V
 Landroid/telephony/SignalStrength;-><init>()V
+Landroid/telephony/SignalStrength;-><init>(Landroid/os/Parcel;)V
 Landroid/telephony/SignalStrength;-><init>(Landroid/telephony/SignalStrength;)V
 Landroid/telephony/SignalStrength;-><init>(Z)V
+Landroid/telephony/SignalStrength;->copyFrom(Landroid/telephony/SignalStrength;)V
 Landroid/telephony/SignalStrength;->CREATOR:Landroid/os/Parcelable$Creator;
 Landroid/telephony/SignalStrength;->fillInNotifierBundle(Landroid/os/Bundle;)V
 Landroid/telephony/SignalStrength;->getAsuLevel()I
@@ -5091,6 +5322,11 @@
 Landroid/telephony/SignalStrength;->getTdScdmaAsuLevel()I
 Landroid/telephony/SignalStrength;->getTdScdmaDbm()I
 Landroid/telephony/SignalStrength;->getTdScdmaLevel()I
+Landroid/telephony/SignalStrength;->mCdmaDbm:I
+Landroid/telephony/SignalStrength;->mCdmaEcio:I
+Landroid/telephony/SignalStrength;->mEvdoDbm:I
+Landroid/telephony/SignalStrength;->mEvdoEcio:I
+Landroid/telephony/SignalStrength;->mEvdoSnr:I
 Landroid/telephony/SignalStrength;->mGsmBitErrorRate:I
 Landroid/telephony/SignalStrength;->mGsmSignalStrength:I
 Landroid/telephony/SignalStrength;->mLteCqi:I
@@ -5103,6 +5339,7 @@
 Landroid/telephony/SignalStrength;->mWcdmaRscp:I
 Landroid/telephony/SignalStrength;->newFromBundle(Landroid/os/Bundle;)Landroid/telephony/SignalStrength;
 Landroid/telephony/SignalStrength;->NUM_SIGNAL_STRENGTH_BINS:I
+Landroid/telephony/SignalStrength;->setFromNotifierBundle(Landroid/os/Bundle;)V
 Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_GOOD:I
 Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_GREAT:I
 Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_MODERATE:I
@@ -5115,6 +5352,7 @@
 Landroid/telephony/SmsManager;->enableCellBroadcastRange(III)Z
 Landroid/telephony/SmsManager;->getAllMessagesFromIcc()Ljava/util/ArrayList;
 Landroid/telephony/SmsManager;->isSMSPromptEnabled()Z
+Landroid/telephony/SmsManager;->mSubId:I
 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/SmsManager;->sendTextMessageWithoutPersisting(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;IZI)V
@@ -5271,9 +5509,11 @@
 Landroid/text/Layout;->mPaint:Landroid/text/TextPaint;
 Landroid/text/Layout;->shouldClampCursor(I)Z
 Landroid/text/method/AllCapsTransformationMethod;-><init>(Landroid/content/Context;)V
+Landroid/text/method/HideReturnsTransformationMethod;->sInstance:Landroid/text/method/HideReturnsTransformationMethod;
 Landroid/text/method/LinkMovementMethod;->sInstance:Landroid/text/method/LinkMovementMethod;
 Landroid/text/method/MetaKeyKeyListener;->startSelecting(Landroid/view/View;Landroid/text/Spannable;)V
 Landroid/text/method/MetaKeyKeyListener;->stopSelecting(Landroid/view/View;Landroid/text/Spannable;)V
+Landroid/text/method/PasswordTransformationMethod;->DOT:C
 Landroid/text/method/PasswordTransformationMethod;->sInstance:Landroid/text/method/PasswordTransformationMethod;
 Landroid/text/method/TransformationMethod2;->setLengthChangesAllowed(Z)V
 Landroid/text/method/WordIterator;-><init>(Ljava/util/Locale;)V
@@ -5348,6 +5588,9 @@
 Landroid/text/StaticLayout;->mLineDirections:[Landroid/text/Layout$Directions;
 Landroid/text/StaticLayout;->mLines:[I
 Landroid/text/StaticLayout;->mMaximumVisibleLineCount:I
+Landroid/text/style/BulletSpan;->mColor:I
+Landroid/text/style/BulletSpan;->mGapWidth:I
+Landroid/text/style/BulletSpan;->mWantColor:Z
 Landroid/text/style/DynamicDrawableSpan;->mDrawableRef:Ljava/lang/ref/WeakReference;
 Landroid/text/style/EasyEditSpan;->getPendingIntent()Landroid/app/PendingIntent;
 Landroid/text/style/EasyEditSpan;->isDeleteEnabled()Z
@@ -5379,6 +5622,7 @@
 Landroid/text/TextUtils;->packRangeInLong(II)J
 Landroid/text/TextUtils;->unpackRangeEndFromLong(J)I
 Landroid/text/TextUtils;->unpackRangeStartFromLong(J)I
+Landroid/text/util/Linkify;->gatherTelLinks(Ljava/util/ArrayList;Landroid/text/Spannable;Landroid/content/Context;)V
 Landroid/transition/ChangeBounds;->BOTTOM_RIGHT_ONLY_PROPERTY:Landroid/util/Property;
 Landroid/transition/ChangeBounds;->POSITION_PROPERTY:Landroid/util/Property;
 Landroid/transition/Scene;->mEnterAction:Ljava/lang/Runnable;
@@ -5389,19 +5633,29 @@
 Landroid/transition/TransitionManager;->getRunningTransitions()Landroid/util/ArrayMap;
 Landroid/transition/TransitionManager;->sPendingTransitions:Ljava/util/ArrayList;
 Landroid/transition/TransitionManager;->sRunningTransitions:Ljava/lang/ThreadLocal;
+Landroid/util/ArrayMap;->allocArrays(I)V
 Landroid/util/ArrayMap;->append(Ljava/lang/Object;Ljava/lang/Object;)V
 Landroid/util/ArrayMap;->CACHE_SIZE:I
+Landroid/util/ArrayMap;->EMPTY:Landroid/util/ArrayMap;
+Landroid/util/ArrayMap;->EMPTY_IMMUTABLE_INTS:[I
+Landroid/util/ArrayMap;->freeArrays([I[Ljava/lang/Object;I)V
 Landroid/util/ArrayMap;->indexOf(Ljava/lang/Object;I)I
 Landroid/util/ArrayMap;->indexOfNull()I
 Landroid/util/ArrayMap;->indexOfValue(Ljava/lang/Object;)I
 Landroid/util/ArrayMap;->mArray:[Ljava/lang/Object;
 Landroid/util/ArrayMap;->mBaseCache:[Ljava/lang/Object;
 Landroid/util/ArrayMap;->mBaseCacheSize:I
+Landroid/util/ArrayMap;->mHashes:[I
 Landroid/util/ArrayMap;->mSize:I
 Landroid/util/ArrayMap;->mTwiceBaseCache:[Ljava/lang/Object;
 Landroid/util/ArrayMap;->mTwiceBaseCacheSize:I
 Landroid/util/ArraySet;-><init>(Ljava/util/Collection;)V
+Landroid/util/ArraySet;->allocArrays(I)V
+Landroid/util/ArraySet;->freeArrays([I[Ljava/lang/Object;I)V
+Landroid/util/ArraySet;->indexOf(Ljava/lang/Object;I)I
+Landroid/util/ArraySet;->indexOfNull()I
 Landroid/util/ArraySet;->mArray:[Ljava/lang/Object;
+Landroid/util/ArraySet;->mHashes:[I
 Landroid/util/ArraySet;->mSize:I
 Landroid/util/Base64;-><init>()V
 Landroid/util/Base64OutputStream;-><init>(Ljava/io/OutputStream;IZ)V
@@ -5451,6 +5705,7 @@
 Landroid/util/Slog;->w(Ljava/lang/String;Ljava/lang/String;)I
 Landroid/util/Slog;->w(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I
 Landroid/util/Slog;->wtf(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I
+Landroid/util/Slog;->wtfStack(Ljava/lang/String;Ljava/lang/String;)I
 Landroid/util/SparseArray;->mKeys:[I
 Landroid/util/SparseArray;->mSize:I
 Landroid/util/SparseArray;->mValues:[Ljava/lang/Object;
@@ -5460,6 +5715,8 @@
 Landroid/util/SparseIntArray;->mKeys:[I
 Landroid/util/SparseIntArray;->mSize:I
 Landroid/util/SparseIntArray;->mValues:[I
+Landroid/util/TimeUtils;->formatDuration(JLjava/io/PrintWriter;)V
+Landroid/util/TimeUtils;->formatDuration(JLjava/io/PrintWriter;I)V
 Landroid/util/TimeUtils;->logTimeOfDay(J)Ljava/lang/String;
 Landroid/util/TrustedTime;->currentTimeMillis()J
 Landroid/util/TrustedTime;->forceRefresh()Z
@@ -5605,6 +5862,7 @@
 Landroid/view/InputEventSender;->dispatchInputEventFinished(IZ)V
 Landroid/view/InputFilter;-><init>(Landroid/os/Looper;)V
 Landroid/view/InputFilter;->onInputEvent(Landroid/view/InputEvent;I)V
+Landroid/view/inputmethod/InputMethodInfo;->isDefault(Landroid/content/Context;)Z
 Landroid/view/inputmethod/InputMethodInfo;->mSubtypes:Landroid/view/inputmethod/InputMethodSubtypeArray;
 Landroid/view/inputmethod/InputMethodManager;->checkFocus()V
 Landroid/view/inputmethod/InputMethodManager;->closeCurrentInput()V
@@ -5850,6 +6108,7 @@
 Landroid/view/textclassifier/TextClassifier;->generateLinks(Ljava/lang/CharSequence;Landroid/view/textclassifier/TextLinks$Options;)Landroid/view/textclassifier/TextLinks;
 Landroid/view/textclassifier/TextClassifier;->suggestSelection(Ljava/lang/CharSequence;IILandroid/view/textclassifier/TextSelection$Options;)Landroid/view/textclassifier/TextSelection;
 Landroid/view/textclassifier/TextLinks$Options;-><init>()V
+Landroid/view/textservice/SpellCheckerSession;->mSpellCheckerSessionListener:Landroid/view/textservice/SpellCheckerSession$SpellCheckerSessionListener;
 Landroid/view/textservice/TextServicesManager;->getCurrentSpellChecker()Landroid/view/textservice/SpellCheckerInfo;
 Landroid/view/textservice/TextServicesManager;->getCurrentSpellCheckerSubtype(Z)Landroid/view/textservice/SpellCheckerSubtype;
 Landroid/view/textservice/TextServicesManager;->getEnabledSpellCheckers()[Landroid/view/textservice/SpellCheckerInfo;
@@ -5859,8 +6118,12 @@
 Landroid/view/TextureView;->destroyHardwareResources()V
 Landroid/view/TextureView;->mLayer:Landroid/view/TextureLayer;
 Landroid/view/TextureView;->mNativeWindow:J
+Landroid/view/TextureView;->mOpaque:Z
 Landroid/view/TextureView;->mSurface:Landroid/graphics/SurfaceTexture;
 Landroid/view/TextureView;->mUpdateListener:Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;
+Landroid/view/TextureView;->mUpdateSurface:Z
+Landroid/view/TextureView;->nCreateNativeWindow(Landroid/graphics/SurfaceTexture;)V
+Landroid/view/TextureView;->nDestroyNativeWindow()V
 Landroid/view/TextureView;->onDetachedFromWindowInternal()V
 Landroid/view/ThreadedRenderer;->setupDiskCache(Ljava/io/File;)V
 Landroid/view/TouchDelegate;->mDelegateTargeted:Z
@@ -5919,6 +6182,7 @@
 Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z
 Landroid/view/View;->computeOpaqueFlags()V
 Landroid/view/View;->createSnapshot(Landroid/view/ViewDebug$CanvasProvider;Z)Landroid/graphics/Bitmap;
+Landroid/view/View;->DBG:Z
 Landroid/view/View;->debug()V
 Landroid/view/View;->debug(I)V
 Landroid/view/View;->DEBUG_LAYOUT_PROPERTY:Ljava/lang/String;
@@ -5943,6 +6207,7 @@
 Landroid/view/View;->getLocationOnScreen()[I
 Landroid/view/View;->getRawTextAlignment()I
 Landroid/view/View;->getRawTextDirection()I
+Landroid/view/View;->getScrollCache()Landroid/view/View$ScrollabilityCache;
 Landroid/view/View;->getTransitionAlpha()F
 Landroid/view/View;->getVerticalScrollFactor()F
 Landroid/view/View;->getViewRootImpl()Landroid/view/ViewRootImpl;
@@ -5966,7 +6231,9 @@
 Landroid/view/View;->isVisibleToUser()Z
 Landroid/view/View;->isVisibleToUser(Landroid/graphics/Rect;)Z
 Landroid/view/View;->mAccessibilityDelegate:Landroid/view/View$AccessibilityDelegate;
+Landroid/view/View;->mAccessibilityViewId:I
 Landroid/view/View;->makeOptionalFitsSystemWindows()V
+Landroid/view/View;->mAnimator:Landroid/view/ViewPropertyAnimator;
 Landroid/view/View;->mAttachInfo:Landroid/view/View$AttachInfo;
 Landroid/view/View;->mBackground:Landroid/graphics/drawable/Drawable;
 Landroid/view/View;->mBackgroundResource:I
@@ -6029,6 +6296,7 @@
 Landroid/view/View;->setAlphaNoInvalidation(F)Z
 Landroid/view/View;->setAnimationMatrix(Landroid/graphics/Matrix;)V
 Landroid/view/View;->setAssistBlocked(Z)V
+Landroid/view/View;->setDisabledSystemUiVisibility(I)V
 Landroid/view/View;->setFlags(II)V
 Landroid/view/View;->setFrame(IIII)Z
 Landroid/view/View;->setIsRootNamespace(Z)V
@@ -6047,6 +6315,7 @@
 Landroid/view/ViewConfiguration;->getDeviceGlobalActionKeyTimeout()J
 Landroid/view/ViewConfiguration;->getDoubleTapMinTime()I
 Landroid/view/ViewConfiguration;->getDoubleTapSlop()I
+Landroid/view/ViewConfiguration;->getHoverTapSlop()I
 Landroid/view/ViewConfiguration;->getScaledDoubleTapTouchSlop()I
 Landroid/view/ViewConfiguration;->isFadingMarqueeEnabled()Z
 Landroid/view/ViewConfiguration;->mFadingMarqueeEnabled:Z
@@ -6065,6 +6334,7 @@
 Landroid/view/ViewGroup$TouchTarget;->child:Landroid/view/View;
 Landroid/view/ViewGroup;->addTransientView(Landroid/view/View;I)V
 Landroid/view/ViewGroup;->cancelTouchTarget(Landroid/view/View;)V
+Landroid/view/ViewGroup;->DBG:Z
 Landroid/view/ViewGroup;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V
 Landroid/view/ViewGroup;->dispatchDetachedFromWindow()V
 Landroid/view/ViewGroup;->dispatchGetDisplayList()V
@@ -6081,6 +6351,7 @@
 Landroid/view/ViewGroup;->mChildrenCount:I
 Landroid/view/ViewGroup;->mDisappearingChildren:Ljava/util/ArrayList;
 Landroid/view/ViewGroup;->mFirstTouchTarget:Landroid/view/ViewGroup$TouchTarget;
+Landroid/view/ViewGroup;->mFocused:Landroid/view/View;
 Landroid/view/ViewGroup;->mGroupFlags:I
 Landroid/view/ViewGroup;->mOnHierarchyChangeListener:Landroid/view/ViewGroup$OnHierarchyChangeListener;
 Landroid/view/ViewGroup;->mPersistentDrawingCache:I
@@ -6095,10 +6366,13 @@
 Landroid/view/ViewGroup;->resolvePadding()V
 Landroid/view/ViewGroup;->suppressLayout(Z)V
 Landroid/view/ViewGroup;->transformPointToViewLocal([FLandroid/view/View;)V
+Landroid/view/ViewHierarchyEncoder;->addProperty(Ljava/lang/String;F)V
 Landroid/view/ViewHierarchyEncoder;->addProperty(Ljava/lang/String;I)V
+Landroid/view/ViewHierarchyEncoder;->addProperty(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/view/ViewHierarchyEncoder;->addProperty(Ljava/lang/String;Z)V
 Landroid/view/ViewOverlay;->getOverlayView()Landroid/view/ViewGroup;
 Landroid/view/ViewOverlay;->isEmpty()Z
+Landroid/view/ViewPropertyAnimator;->mRTBackend:Landroid/view/ViewPropertyAnimatorRT;
 Landroid/view/ViewRootImpl$CalledFromWrongThreadException;-><init>(Ljava/lang/String;)V
 Landroid/view/ViewRootImpl;->addConfigCallback(Landroid/view/ViewRootImpl$ConfigChangedCallback;)V
 Landroid/view/ViewRootImpl;->cancelInvalidate(Landroid/view/View;)V
@@ -6164,15 +6438,18 @@
 Landroid/view/Window;->mHardwareAccelerated:Z
 Landroid/view/Window;->mLocalFeatures:I
 Landroid/view/Window;->mWindowAttributes:Landroid/view/WindowManager$LayoutParams;
+Landroid/view/Window;->mWindowManager:Landroid/view/WindowManager;
 Landroid/view/Window;->mWindowStyle:Landroid/content/res/TypedArray;
 Landroid/view/Window;->setCloseOnTouchOutside(Z)V
 Landroid/view/Window;->setCloseOnTouchOutsideIfNotSet(Z)V
 Landroid/view/Window;->setNeedsMenuKey(I)V
+Landroid/view/Window;->shouldCloseOnTouch(Landroid/content/Context;Landroid/view/MotionEvent;)Z
 Landroid/view/WindowAnimationFrameStats;->init(J[J)V
 Landroid/view/WindowContentFrameStats;->init(J[J[J[J)V
 Landroid/view/WindowInsets;-><init>(Landroid/graphics/Rect;)V
 Landroid/view/WindowInsets;->CONSUMED:Landroid/view/WindowInsets;
 Landroid/view/WindowInsets;->getSystemWindowInsets()Landroid/graphics/Rect;
+Landroid/view/WindowInsets;->inset(IIII)Landroid/view/WindowInsets;
 Landroid/view/WindowLeaked;-><init>(Ljava/lang/String;)V
 Landroid/view/WindowManager$LayoutParams;->backup()V
 Landroid/view/WindowManager$LayoutParams;->FLAG_SLIPPERY:I
@@ -6246,6 +6523,10 @@
 Landroid/webkit/CacheManager;->saveCacheFile(Ljava/lang/String;JLandroid/webkit/CacheManager$CacheResult;)V
 Landroid/webkit/CacheManager;->saveCacheFile(Ljava/lang/String;Landroid/webkit/CacheManager$CacheResult;)V
 Landroid/webkit/CacheManager;->startCacheTransaction()Z
+Landroid/webkit/ConsoleMessage;->mLevel:Landroid/webkit/ConsoleMessage$MessageLevel;
+Landroid/webkit/ConsoleMessage;->mLineNumber:I
+Landroid/webkit/ConsoleMessage;->mMessage:Ljava/lang/String;
+Landroid/webkit/ConsoleMessage;->mSourceId:Ljava/lang/String;
 Landroid/webkit/IWebViewUpdateService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/webkit/IWebViewUpdateService$Stub$Proxy;->waitForAndGetProvider()Landroid/webkit/WebViewProviderResponse;
 Landroid/webkit/IWebViewUpdateService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/webkit/IWebViewUpdateService;
@@ -6296,18 +6577,24 @@
 Landroid/webkit/WebViewFactory;->getWebViewContextAndSetProvider()Landroid/content/Context;
 Landroid/webkit/WebViewFactory;->sPackageInfo:Landroid/content/pm/PackageInfo;
 Landroid/webkit/WebViewFactory;->sProviderInstance:Landroid/webkit/WebViewFactoryProvider;
+Landroid/webkit/WebViewProviderInfo;-><init>(Landroid/os/Parcel;)V
 Landroid/webkit/WebViewProviderResponse;->packageInfo:Landroid/content/pm/PackageInfo;
 Landroid/webkit/WebViewUpdateService;-><init>()V
 Landroid/widget/AbsListView$FlingRunnable;->endFling()V
 Landroid/widget/AbsListView$FlingRunnable;->mScroller:Landroid/widget/OverScroller;
 Landroid/widget/AbsListView$FlingRunnable;->start(I)V
+Landroid/widget/AbsListView$LayoutParams;->scrappedFromPosition:I
+Landroid/widget/AbsListView$LayoutParams;->viewType:I
 Landroid/widget/AbsListView$RecycleBin;->clear()V
 Landroid/widget/AbsListView$RecycleBin;->mRecyclerListener:Landroid/widget/AbsListView$RecyclerListener;
 Landroid/widget/AbsListView$SavedState;->firstId:J
 Landroid/widget/AbsListView$SavedState;->viewTop:I
+Landroid/widget/AbsListView;->canScrollDown()Z
+Landroid/widget/AbsListView;->canScrollUp()Z
 Landroid/widget/AbsListView;->findMotionRow(I)I
 Landroid/widget/AbsListView;->invokeOnItemScrollListener()V
 Landroid/widget/AbsListView;->isVerticalScrollBarHidden()Z
+Landroid/widget/AbsListView;->mActivePointerId:I
 Landroid/widget/AbsListView;->mAdapter:Landroid/widget/ListAdapter;
 Landroid/widget/AbsListView;->mChoiceActionMode:Landroid/view/ActionMode;
 Landroid/widget/AbsListView;->mContextMenuInfo:Landroid/view/ContextMenu$ContextMenuInfo;
@@ -6356,7 +6643,14 @@
 Landroid/widget/ActionMenuPresenter;->isOverflowMenuShowing()Z
 Landroid/widget/ActionMenuPresenter;->onRestoreInstanceState(Landroid/os/Parcelable;)V
 Landroid/widget/ActionMenuPresenter;->onSaveInstanceState()Landroid/os/Parcelable;
+Landroid/widget/ActionMenuView$ActionMenuChildView;->needsDividerBefore()Z
+Landroid/widget/ActionMenuView$LayoutParams;->cellsUsed:I
+Landroid/widget/ActionMenuView$LayoutParams;->expandable:Z
+Landroid/widget/ActionMenuView$LayoutParams;->expanded:Z
+Landroid/widget/ActionMenuView$LayoutParams;->extraPixels:I
 Landroid/widget/ActionMenuView$LayoutParams;->isOverflowButton:Z
+Landroid/widget/ActionMenuView$LayoutParams;->preventEdgeOffset:Z
+Landroid/widget/ActionMenuView;->hasDividerBeforeChildAt(I)Z
 Landroid/widget/ActionMenuView;->isOverflowMenuShowPending()Z
 Landroid/widget/ActionMenuView;->isOverflowReserved()Z
 Landroid/widget/ActionMenuView;->peekMenu()Lcom/android/internal/view/menu/MenuBuilder;
@@ -6371,6 +6665,7 @@
 Landroid/widget/ActivityChooserView;->setExpandActivityOverflowButtonDrawable(Landroid/graphics/drawable/Drawable;)V
 Landroid/widget/AdapterView;->mDataChanged:Z
 Landroid/widget/AdapterView;->mFirstPosition:I
+Landroid/widget/AdapterView;->mNeedSync:Z
 Landroid/widget/AdapterView;->mNextSelectedPosition:I
 Landroid/widget/AdapterView;->mNextSelectedRowId:J
 Landroid/widget/AdapterView;->mOldSelectedPosition:I
@@ -6493,6 +6788,8 @@
 Landroid/widget/HorizontalScrollView;->mEdgeGlowRight:Landroid/widget/EdgeEffect;
 Landroid/widget/HorizontalScrollView;->mIsBeingDragged:Z
 Landroid/widget/HorizontalScrollView;->mLastMotionX:I
+Landroid/widget/HorizontalScrollView;->mOverflingDistance:I
+Landroid/widget/HorizontalScrollView;->mOverscrollDistance:I
 Landroid/widget/HorizontalScrollView;->mScroller:Landroid/widget/OverScroller;
 Landroid/widget/HorizontalScrollView;->mVelocityTracker:Landroid/view/VelocityTracker;
 Landroid/widget/HorizontalScrollView;->recycleVelocityTracker()V
@@ -6509,6 +6806,7 @@
 Landroid/widget/ImageView;->mRecycleableBitmapDrawable:Landroid/graphics/drawable/BitmapDrawable;
 Landroid/widget/ImageView;->mResource:I
 Landroid/widget/ImageView;->mUri:Landroid/net/Uri;
+Landroid/widget/ImageView;->resizeFromDrawable()V
 Landroid/widget/ImageView;->resolveUri()V
 Landroid/widget/ImageView;->scaleTypeToScaleToFit(Landroid/widget/ImageView$ScaleType;)Landroid/graphics/Matrix$ScaleToFit;
 Landroid/widget/ImageView;->setImageResourceAsync(I)Ljava/lang/Runnable;
@@ -6529,9 +6827,12 @@
 Landroid/widget/ListPopupWindow;->setForceIgnoreOutsideTouch(Z)V
 Landroid/widget/ListPopupWindow;->setListItemExpandMax(I)V
 Landroid/widget/ListView;->arrowScroll(I)Z
+Landroid/widget/ListView;->correctTooHigh(I)V
+Landroid/widget/ListView;->correctTooLow(I)V
 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;->getHeightForPosition(I)I
 Landroid/widget/ListView;->makeAndAddView(IIZIZ)Landroid/view/View;
 Landroid/widget/ListView;->mAreAllItemsSelectable:Z
 Landroid/widget/ListView;->mDivider:Landroid/graphics/drawable/Drawable;
@@ -6550,8 +6851,10 @@
 Landroid/widget/MediaController;->mEndTime:Landroid/widget/TextView;
 Landroid/widget/MediaController;->mFfwdButton:Landroid/widget/ImageButton;
 Landroid/widget/MediaController;->mFfwdListener:Landroid/view/View$OnClickListener;
+Landroid/widget/MediaController;->mNextButton:Landroid/widget/ImageButton;
 Landroid/widget/MediaController;->mPauseButton:Landroid/widget/ImageButton;
 Landroid/widget/MediaController;->mPlayer:Landroid/widget/MediaController$MediaPlayerControl;
+Landroid/widget/MediaController;->mPrevButton:Landroid/widget/ImageButton;
 Landroid/widget/MediaController;->mProgress:Landroid/widget/ProgressBar;
 Landroid/widget/MediaController;->mRewButton:Landroid/widget/ImageButton;
 Landroid/widget/MediaController;->mRewListener:Landroid/view/View$OnClickListener;
@@ -6575,12 +6878,14 @@
 Landroid/widget/NumberPicker;->mSelectionDividerHeight:I
 Landroid/widget/NumberPicker;->mSelectorIndices:[I
 Landroid/widget/NumberPicker;->mSelectorWheelPaint:Landroid/graphics/Paint;
+Landroid/widget/NumberPicker;->mTextSize:I
 Landroid/widget/NumberPicker;->SELECTOR_MIDDLE_ITEM_INDEX:I
 Landroid/widget/NumberPicker;->SELECTOR_WHEEL_ITEM_COUNT:I
 Landroid/widget/OverScroller$SplineOverScroller;->mCurrVelocity:F
 Landroid/widget/OverScroller;-><init>(Landroid/content/Context;Landroid/view/animation/Interpolator;Z)V
 Landroid/widget/OverScroller;->extendDuration(I)V
 Landroid/widget/OverScroller;->isScrollingInDirection(FF)Z
+Landroid/widget/OverScroller;->mInterpolator:Landroid/view/animation/Interpolator;
 Landroid/widget/OverScroller;->mScrollerY:Landroid/widget/OverScroller$SplineOverScroller;
 Landroid/widget/OverScroller;->setInterpolator(Landroid/view/animation/Interpolator;)V
 Landroid/widget/PopupMenu;->mContext:Landroid/content/Context;
@@ -6628,6 +6933,7 @@
 Landroid/widget/ProgressBar;->mMinWidth:I
 Landroid/widget/ProgressBar;->mMirrorForRtl:Z
 Landroid/widget/ProgressBar;->mOnlyIndeterminate:Z
+Landroid/widget/ProgressBar;->refreshProgress(IIZZ)V
 Landroid/widget/ProgressBar;->setProgressInternal(IZZ)Z
 Landroid/widget/ProgressBar;->startAnimation()V
 Landroid/widget/ProgressBar;->stopAnimation()V
@@ -6721,6 +7027,7 @@
 Landroid/widget/SearchView;->updateViewsVisibility(Z)V
 Landroid/widget/SeekBar;->mOnSeekBarChangeListener:Landroid/widget/SeekBar$OnSeekBarChangeListener;
 Landroid/widget/SeekBar;->onProgressRefresh(FZI)V
+Landroid/widget/SimpleAdapter;->mData:Ljava/util/List;
 Landroid/widget/SimpleCursorAdapter;->mFrom:[I
 Landroid/widget/SimpleCursorAdapter;->mTo:[I
 Landroid/widget/SlidingDrawer;->mTopOffset:I
@@ -6739,6 +7046,7 @@
 Landroid/widget/Switch;->mOnLayout:Landroid/text/Layout;
 Landroid/widget/Switch;->mSwitchHeight:I
 Landroid/widget/Switch;->mSwitchMinWidth:I
+Landroid/widget/Switch;->mSwitchWidth:I
 Landroid/widget/Switch;->mThumbDrawable:Landroid/graphics/drawable/Drawable;
 Landroid/widget/Switch;->mThumbWidth:I
 Landroid/widget/Switch;->mTrackDrawable:Landroid/graphics/drawable/Drawable;
@@ -6781,6 +7089,7 @@
 Landroid/widget/TextView;->mBufferType:Landroid/widget/TextView$BufferType;
 Landroid/widget/TextView;->mChangeWatcher:Landroid/widget/TextView$ChangeWatcher;
 Landroid/widget/TextView;->mCharWrapper:Landroid/widget/TextView$CharWrapper;
+Landroid/widget/TextView;->mCurHintTextColor:I
 Landroid/widget/TextView;->mCursorDrawableRes:I
 Landroid/widget/TextView;->mCurTextColor:I
 Landroid/widget/TextView;->mDesiredHeightAtMeasure:I
@@ -6829,8 +7138,10 @@
 Landroid/widget/TextView;->mUserSetTextScaleX:Z
 Landroid/widget/TextView;->nullLayouts()V
 Landroid/widget/TextView;->setInputType(IZ)V
+Landroid/widget/TextView;->setRawTextSize(FZ)V
 Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;ZI)V
 Landroid/widget/TextView;->startMarquee()V
+Landroid/widget/TextView;->startStopMarquee(Z)V
 Landroid/widget/TextView;->stopTextActionMode()V
 Landroid/widget/TextView;->viewportToContentVerticalOffset()I
 Landroid/widget/TimePicker;->mDelegate:Landroid/widget/TimePicker$TimePickerDelegate;
@@ -7183,6 +7494,8 @@
 Lcom/android/internal/os/BatteryStatsImpl;->getDischargeAmountScreenOn()I
 Lcom/android/internal/os/BatteryStatsImpl;->getGlobalWifiRunningTime(JI)J
 Lcom/android/internal/os/BatteryStatsImpl;->getKernelWakelockStats()Ljava/util/Map;
+Lcom/android/internal/os/BatteryStatsImpl;->getMobileRadioActiveTime(JI)J
+Lcom/android/internal/os/BatteryStatsImpl;->getNetworkActivityBytes(II)J
 Lcom/android/internal/os/BatteryStatsImpl;->getNextHistoryLocked(Landroid/os/BatteryStats$HistoryItem;)Z
 Lcom/android/internal/os/BatteryStatsImpl;->getPackageStatsLocked(ILjava/lang/String;)Lcom/android/internal/os/BatteryStatsImpl$Uid$Pkg;
 Lcom/android/internal/os/BatteryStatsImpl;->getPhoneDataConnectionCount(II)I
@@ -7516,6 +7829,7 @@
 Lcom/android/internal/R$styleable;->CompoundButton_button:I
 Lcom/android/internal/R$styleable;->CompoundButton_checked:I
 Lcom/android/internal/R$styleable;->ContactsDataKind:[I
+Lcom/android/internal/R$styleable;->CycleInterpolator:[I
 Lcom/android/internal/R$styleable;->DatePicker:[I
 Lcom/android/internal/R$styleable;->DialogPreference:[I
 Lcom/android/internal/R$styleable;->DialogPreference_dialogTitle:I
@@ -7535,6 +7849,7 @@
 Lcom/android/internal/R$styleable;->KeyboardView:[I
 Lcom/android/internal/R$styleable;->Keyboard_Key:[I
 Lcom/android/internal/R$styleable;->Keyboard_Row:[I
+Lcom/android/internal/R$styleable;->LinearLayout:[I
 Lcom/android/internal/R$styleable;->ListPreference:[I
 Lcom/android/internal/R$styleable;->ListPreference_entries:I
 Lcom/android/internal/R$styleable;->ListView:[I
@@ -7813,12 +8128,24 @@
 Lcom/android/internal/telephony/ITelephonyRegistry$Stub;-><init>()V
 Lcom/android/internal/telephony/ITelephonyRegistry$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephonyRegistry;
 Lcom/android/internal/telephony/ITelephonyRegistry;->listen(Ljava/lang/String;Lcom/android/internal/telephony/IPhoneStateListener;IZ)V
+Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCallForwardingChanged(Z)V
 Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCallState(ILjava/lang/String;)V
+Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCellInfo(Ljava/util/List;)V
+Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCellLocation(Landroid/os/Bundle;)V
+Lcom/android/internal/telephony/ITelephonyRegistry;->notifyDataActivity(I)V
+Lcom/android/internal/telephony/ITelephonyRegistry;->notifyDataConnectionFailed(Ljava/lang/String;Ljava/lang/String;)V
+Lcom/android/internal/telephony/ITelephonyRegistry;->notifyOtaspChanged(I)V
 Lcom/android/internal/telephony/IWapPushManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IWapPushManager;
 Lcom/android/internal/telephony/IWapPushManager;->addPackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZZ)Z
 Lcom/android/internal/telephony/IWapPushManager;->deletePackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
 Lcom/android/internal/telephony/IWapPushManager;->updatePackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZZ)Z
 Lcom/android/internal/telephony/OperatorInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+Lcom/android/internal/telephony/OperatorInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/android/internal/telephony/OperatorInfo$State;)V
+Lcom/android/internal/telephony/OperatorInfo;->mOperatorAlphaLong:Ljava/lang/String;
+Lcom/android/internal/telephony/OperatorInfo;->mOperatorAlphaShort:Ljava/lang/String;
+Lcom/android/internal/telephony/OperatorInfo;->mOperatorNumeric:Ljava/lang/String;
+Lcom/android/internal/telephony/OperatorInfo;->mState:Lcom/android/internal/telephony/OperatorInfo$State;
+Lcom/android/internal/telephony/OperatorInfo;->rilStateToState(Ljava/lang/String;)Lcom/android/internal/telephony/OperatorInfo$State;
 Lcom/android/internal/telephony/SmsAddress;->origBytes:[B
 Lcom/android/internal/telephony/SmsConstants$MessageClass;->CLASS_0:Lcom/android/internal/telephony/SmsConstants$MessageClass;
 Lcom/android/internal/telephony/SmsConstants$MessageClass;->CLASS_1:Lcom/android/internal/telephony/SmsConstants$MessageClass;
@@ -7849,6 +8176,7 @@
 Lcom/android/internal/telephony/SmsMessageBase;->getProtocolIdentifier()I
 Lcom/android/internal/telephony/SmsMessageBase;->getPseudoSubject()Ljava/lang/String;
 Lcom/android/internal/telephony/SmsMessageBase;->getServiceCenterAddress()Ljava/lang/String;
+Lcom/android/internal/telephony/SmsMessageBase;->getStatus()I
 Lcom/android/internal/telephony/SmsMessageBase;->getTimestampMillis()J
 Lcom/android/internal/telephony/SmsMessageBase;->getUserData()[B
 Lcom/android/internal/telephony/SmsMessageBase;->getUserDataHeader()Lcom/android/internal/telephony/SmsHeader;
@@ -7887,6 +8215,11 @@
 Lcom/android/internal/util/AsyncChannel;->sendMessageSynchronously(Landroid/os/Message;)Landroid/os/Message;
 Lcom/android/internal/util/AsyncChannel;->STATUS_SUCCESSFUL:I
 Lcom/android/internal/util/FastPrintWriter;-><init>(Ljava/io/OutputStream;)V
+Lcom/android/internal/util/JournaledFile;-><init>(Ljava/io/File;Ljava/io/File;)V
+Lcom/android/internal/util/JournaledFile;->chooseForRead()Ljava/io/File;
+Lcom/android/internal/util/JournaledFile;->chooseForWrite()Ljava/io/File;
+Lcom/android/internal/util/JournaledFile;->commit()V
+Lcom/android/internal/util/JournaledFile;->rollback()V
 Lcom/android/internal/util/XmlUtils;->convertValueToBoolean(Ljava/lang/CharSequence;Z)Z
 Lcom/android/internal/util/XmlUtils;->convertValueToInt(Ljava/lang/CharSequence;I)I
 Lcom/android/internal/util/XmlUtils;->readMapXml(Ljava/io/InputStream;)Ljava/util/HashMap;
@@ -7913,6 +8246,7 @@
 Lcom/android/internal/view/IInputMethodSession$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodSession;
 Lcom/android/internal/view/InputBindResult;->CREATOR:Landroid/os/Parcelable$Creator;
 Lcom/android/internal/view/InputBindResult;->method:Lcom/android/internal/view/IInputMethodSession;
+Lcom/android/internal/view/menu/ActionMenuItemView;->hasText()Z
 Lcom/android/internal/view/menu/MenuBuilder$Callback;->onMenuItemSelected(Lcom/android/internal/view/menu/MenuBuilder;Landroid/view/MenuItem;)Z
 Lcom/android/internal/view/menu/MenuBuilder$Callback;->onMenuModeChange(Lcom/android/internal/view/menu/MenuBuilder;)V
 Lcom/android/internal/view/menu/MenuBuilder;-><init>(Landroid/content/Context;)V
@@ -7925,7 +8259,10 @@
 Lcom/android/internal/view/menu/MenuBuilder;->mContext:Landroid/content/Context;
 Lcom/android/internal/view/menu/MenuBuilder;->setCallback(Lcom/android/internal/view/menu/MenuBuilder$Callback;)V
 Lcom/android/internal/view/menu/MenuBuilder;->setCurrentMenuInfo(Landroid/view/ContextMenu$ContextMenuInfo;)V
+Lcom/android/internal/view/menu/MenuBuilder;->setDefaultShowAsAction(I)Lcom/android/internal/view/menu/MenuBuilder;
 Lcom/android/internal/view/menu/MenuBuilder;->setOptionalIconsVisible(Z)V
+Lcom/android/internal/view/menu/MenuBuilder;->startDispatchingItemsChanged()V
+Lcom/android/internal/view/menu/MenuBuilder;->stopDispatchingItemsChanged()V
 Lcom/android/internal/view/menu/MenuItemImpl;->invoke()Z
 Lcom/android/internal/view/menu/MenuItemImpl;->isActionButton()Z
 Lcom/android/internal/view/menu/MenuItemImpl;->mIconResId:I
@@ -7933,6 +8270,7 @@
 Lcom/android/internal/view/menu/MenuItemImpl;->requiresActionButton()Z
 Lcom/android/internal/view/menu/MenuItemImpl;->setActionViewExpanded(Z)V
 Lcom/android/internal/view/menu/MenuItemImpl;->setMenuInfo(Landroid/view/ContextMenu$ContextMenuInfo;)V
+Lcom/android/internal/view/menu/MenuPopupHelper;-><init>(Landroid/content/Context;Lcom/android/internal/view/menu/MenuBuilder;)V
 Lcom/android/internal/view/menu/MenuPopupHelper;-><init>(Landroid/content/Context;Lcom/android/internal/view/menu/MenuBuilder;Landroid/view/View;)V
 Lcom/android/internal/view/menu/MenuPopupHelper;->dismiss()V
 Lcom/android/internal/view/menu/MenuPopupHelper;->mForceShowIcon:Z
@@ -7964,7 +8302,16 @@
 Lcom/android/internal/widget/IRemoteViewsFactory;->hasStableIds()Z
 Lcom/android/internal/widget/IRemoteViewsFactory;->isCreated()Z
 Lcom/android/internal/widget/IRemoteViewsFactory;->onDataSetChanged()V
+Lcom/android/internal/widget/ScrollingTabContainerView;-><init>(Landroid/content/Context;)V
+Lcom/android/internal/widget/ScrollingTabContainerView;->addTab(Landroid/app/ActionBar$Tab;IZ)V
+Lcom/android/internal/widget/ScrollingTabContainerView;->addTab(Landroid/app/ActionBar$Tab;Z)V
+Lcom/android/internal/widget/ScrollingTabContainerView;->animateToTab(I)V
+Lcom/android/internal/widget/ScrollingTabContainerView;->animateToVisibility(I)V
+Lcom/android/internal/widget/ScrollingTabContainerView;->removeAllTabs()V
+Lcom/android/internal/widget/ScrollingTabContainerView;->removeTabAt(I)V
 Lcom/android/internal/widget/ScrollingTabContainerView;->setAllowCollapse(Z)V
+Lcom/android/internal/widget/ScrollingTabContainerView;->setTabSelected(I)V
+Lcom/android/internal/widget/ScrollingTabContainerView;->updateTab(I)V
 Lcom/android/okhttp/Connection;->getSocket()Ljava/net/Socket;
 Lcom/android/okhttp/ConnectionPool;->connections:Ljava/util/Deque;
 Lcom/android/okhttp/ConnectionPool;->keepAliveDurationNs:J
@@ -8072,6 +8419,8 @@
 Ldalvik/system/CloseGuard;->close()V
 Ldalvik/system/CloseGuard;->get()Ldalvik/system/CloseGuard;
 Ldalvik/system/CloseGuard;->open(Ljava/lang/String;)V
+Ldalvik/system/CloseGuard;->setEnabled(Z)V
+Ldalvik/system/CloseGuard;->setReporter(Ldalvik/system/CloseGuard$Reporter;)V
 Ldalvik/system/CloseGuard;->warnIfOpen()V
 Ldalvik/system/DexFile$DFEnum;->mNameList:[Ljava/lang/String;
 Ldalvik/system/DexFile;->getClassNameList(Ljava/lang/Object;)[Ljava/lang/String;
@@ -8148,6 +8497,32 @@
 Ljava/io/FileInputStream;->fd:Ljava/io/FileDescriptor;
 Ljava/io/FileOutputStream;->channel:Ljava/nio/channels/FileChannel;
 Ljava/io/FileOutputStream;->fd:Ljava/io/FileDescriptor;
+Ljava/io/FileSystem;->canonicalize(Ljava/lang/String;)Ljava/lang/String;
+Ljava/io/FileSystem;->checkAccess(Ljava/io/File;I)Z
+Ljava/io/FileSystem;->compare(Ljava/io/File;Ljava/io/File;)I
+Ljava/io/FileSystem;->createDirectory(Ljava/io/File;)Z
+Ljava/io/FileSystem;->createFileExclusively(Ljava/lang/String;)Z
+Ljava/io/FileSystem;->delete(Ljava/io/File;)Z
+Ljava/io/FileSystem;->fromURIPath(Ljava/lang/String;)Ljava/lang/String;
+Ljava/io/FileSystem;->getBooleanAttributes(Ljava/io/File;)I
+Ljava/io/FileSystem;->getDefaultParent()Ljava/lang/String;
+Ljava/io/FileSystem;->getLastModifiedTime(Ljava/io/File;)J
+Ljava/io/FileSystem;->getLength(Ljava/io/File;)J
+Ljava/io/FileSystem;->getPathSeparator()C
+Ljava/io/FileSystem;->getSeparator()C
+Ljava/io/FileSystem;->getSpace(Ljava/io/File;I)J
+Ljava/io/FileSystem;->hashCode(Ljava/io/File;)I
+Ljava/io/FileSystem;->isAbsolute(Ljava/io/File;)Z
+Ljava/io/FileSystem;->list(Ljava/io/File;)[Ljava/lang/String;
+Ljava/io/FileSystem;->listRoots()[Ljava/io/File;
+Ljava/io/FileSystem;->normalize(Ljava/lang/String;)Ljava/lang/String;
+Ljava/io/FileSystem;->prefixLength(Ljava/lang/String;)I
+Ljava/io/FileSystem;->rename(Ljava/io/File;Ljava/io/File;)Z
+Ljava/io/FileSystem;->resolve(Ljava/io/File;)Ljava/lang/String;
+Ljava/io/FileSystem;->resolve(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+Ljava/io/FileSystem;->setLastModifiedTime(Ljava/io/File;J)Z
+Ljava/io/FileSystem;->setPermission(Ljava/io/File;IZZ)Z
+Ljava/io/FileSystem;->setReadOnly(Ljava/io/File;)Z
 Ljava/io/ObjectInputStream;->bin:Ljava/io/ObjectInputStream$BlockDataInputStream;
 Ljava/io/ObjectInputStream;->bytesToDoubles([BI[DII)V
 Ljava/io/ObjectInputStream;->bytesToFloats([BI[FII)V
@@ -8174,6 +8549,7 @@
 Ljava/lang/Class;-><init>()V
 Ljava/lang/Class;->accessFlags:I
 Ljava/lang/Class;->classLoader:Ljava/lang/ClassLoader;
+Ljava/lang/Class;->clinitThreadId:I
 Ljava/lang/Class;->dexCache:Ljava/lang/Object;
 Ljava/lang/Class;->dexClassDefIndex:I
 Ljava/lang/Class;->getDeclaredMethodsUnchecked(Z)[Ljava/lang/reflect/Method;
@@ -8181,6 +8557,7 @@
 Ljava/lang/Class;->ifTable:[Ljava/lang/Object;
 Ljava/lang/Class;->name:Ljava/lang/String;
 Ljava/lang/Class;->objectSize:I
+Ljava/lang/Class;->status:I
 Ljava/lang/ClassLoader;->parent:Ljava/lang/ClassLoader;
 Ljava/lang/Daemons$Daemon;->isRunning()Z
 Ljava/lang/Daemons$Daemon;->start()V
@@ -8195,6 +8572,9 @@
 Ljava/lang/Daemons;->start()V
 Ljava/lang/Daemons;->stop()V
 Ljava/lang/Double;->value:D
+Ljava/lang/Enum;->getSharedConstants(Ljava/lang/Class;)[Ljava/lang/Enum;
+Ljava/lang/Enum;->name:Ljava/lang/String;
+Ljava/lang/Enum;->ordinal:I
 Ljava/lang/Float;->value:F
 Ljava/lang/Integer;->value:I
 Ljava/lang/invoke/MethodHandles$Lookup;-><init>(Ljava/lang/Class;I)V
@@ -8209,6 +8589,7 @@
 Ljava/lang/ref/Reference;->referent:Ljava/lang/Object;
 Ljava/lang/ref/ReferenceQueue;->add(Ljava/lang/ref/Reference;)V
 Ljava/lang/reflect/AccessibleObject;->override:Z
+Ljava/lang/reflect/Constructor;->serializationCopy(Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
 Ljava/lang/reflect/Executable;->artMethod:J
 Ljava/lang/reflect/Field;->accessFlags:I
 Ljava/lang/reflect/Field;->getOffset()I
@@ -8314,6 +8695,7 @@
 Ljava/net/InetSocketAddress;->holder:Ljava/net/InetSocketAddress$InetSocketAddressHolder;
 Ljava/net/InterfaceAddress;-><init>()V
 Ljava/net/Proxy;-><init>()V
+Ljava/net/ServerSocket;->factory:Ljava/net/SocketImplFactory;
 Ljava/net/Socket;->factory:Ljava/net/SocketImplFactory;
 Ljava/net/Socket;->getFileDescriptor$()Ljava/io/FileDescriptor;
 Ljava/net/Socket;->impl:Ljava/net/SocketImpl;
@@ -8397,7 +8779,9 @@
 Ljava/util/concurrent/LinkedBlockingQueue;->putLock:Ljava/util/concurrent/locks/ReentrantLock;
 Ljava/util/concurrent/LinkedBlockingQueue;->takeLock:Ljava/util/concurrent/locks/ReentrantLock;
 Ljava/util/concurrent/locks/ReentrantLock;->sync:Ljava/util/concurrent/locks/ReentrantLock$Sync;
+Ljava/util/concurrent/PriorityBlockingQueue;->dequeue()Ljava/lang/Object;
 Ljava/util/concurrent/PriorityBlockingQueue;->lock:Ljava/util/concurrent/locks/ReentrantLock;
+Ljava/util/concurrent/PriorityBlockingQueue;->notEmpty:Ljava/util/concurrent/locks/Condition;
 Ljava/util/concurrent/ThreadPoolExecutor;->allowCoreThreadTimeOut:Z
 Ljava/util/concurrent/ThreadPoolExecutor;->ctl:Ljava/util/concurrent/atomic/AtomicInteger;
 Ljava/util/concurrent/ThreadPoolExecutor;->defaultHandler:Ljava/util/concurrent/RejectedExecutionHandler;
@@ -8498,6 +8882,7 @@
 Ljava/util/zip/ZipInputStream;->flag:I
 Ljava/util/zip/ZipInputStream;->tmpbuf:[B
 Ljava/util/zip/ZipOutputStream;->method:I
+Ljava/util/zip/ZipOutputStream;->names:Ljava/util/HashSet;
 Ljava/util/zip/ZipOutputStream;->written:J
 Ljavax/microedition/khronos/egl/EGL10;->eglReleaseThread()Z
 Ljavax/net/ssl/SSLServerSocketFactory;->defaultServerSocketFactory:Ljavax/net/ssl/SSLServerSocketFactory;
@@ -8505,20 +8890,105 @@
 Ljavax/net/ssl/SSLSocketFactory;->defaultSocketFactory:Ljavax/net/ssl/SSLSocketFactory;
 Llibcore/util/BasicLruCache;->map:Ljava/util/LinkedHashMap;
 Llibcore/util/ZoneInfo;->mTransitions:[J
+Lorg/apache/http/conn/ssl/AbstractVerifier;->BAD_COUNTRY_2LDS:[Ljava/lang/String;
 Lorg/apache/http/conn/ssl/SSLSocketFactory;-><init>()V
 Lorg/apache/http/conn/ssl/SSLSocketFactory;-><init>(Ljavax/net/ssl/SSLSocketFactory;)V
+Lorg/apache/http/conn/ssl/SSLSocketFactory;->createKeyManagers(Ljava/security/KeyStore;Ljava/lang/String;)[Ljavax/net/ssl/KeyManager;
+Lorg/apache/http/conn/ssl/SSLSocketFactory;->createTrustManagers(Ljava/security/KeyStore;)[Ljavax/net/ssl/TrustManager;
+Lorg/apache/http/conn/ssl/SSLSocketFactory;->hostnameVerifier:Lorg/apache/http/conn/ssl/X509HostnameVerifier;
+Lorg/apache/http/conn/ssl/SSLSocketFactory;->nameResolver:Lorg/apache/http/conn/scheme/HostNameResolver;
+Lorg/apache/http/conn/ssl/SSLSocketFactory;->socketfactory:Ljavax/net/ssl/SSLSocketFactory;
 Lorg/apache/http/conn/ssl/SSLSocketFactory;->sslcontext:Ljavax/net/ssl/SSLContext;
 Lorg/ccil/cowan/tagsoup/AttributesImpl;->data:[Ljava/lang/String;
 Lorg/ccil/cowan/tagsoup/AttributesImpl;->length:I
 Lorg/json/JSONArray;->values:Ljava/util/List;
+Lorg/json/JSONArray;->writeTo(Lorg/json/JSONStringer;)V
 Lorg/json/JSONObject;->append(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
+Lorg/json/JSONObject;->checkName(Ljava/lang/String;)Ljava/lang/String;
 Lorg/json/JSONObject;->keySet()Ljava/util/Set;
 Lorg/json/JSONObject;->nameValuePairs:Ljava/util/LinkedHashMap;
+Lorg/json/JSONObject;->NEGATIVE_ZERO:Ljava/lang/Double;
 Lorg/json/JSONObject;->writeTo(Lorg/json/JSONStringer;)V
+Lorg/json/JSONStringer;-><init>(I)V
+Lorg/json/JSONStringer;->beforeKey()V
+Lorg/json/JSONStringer;->beforeValue()V
+Lorg/json/JSONStringer;->close(Lorg/json/JSONStringer$Scope;Lorg/json/JSONStringer$Scope;Ljava/lang/String;)Lorg/json/JSONStringer;
+Lorg/json/JSONStringer;->indent:Ljava/lang/String;
+Lorg/json/JSONStringer;->newline()V
+Lorg/json/JSONStringer;->open(Lorg/json/JSONStringer$Scope;Ljava/lang/String;)Lorg/json/JSONStringer;
+Lorg/json/JSONStringer;->out:Ljava/lang/StringBuilder;
+Lorg/json/JSONStringer;->peek()Lorg/json/JSONStringer$Scope;
+Lorg/json/JSONStringer;->replaceTop(Lorg/json/JSONStringer$Scope;)V
+Lorg/json/JSONStringer;->stack:Ljava/util/List;
+Lorg/json/JSONStringer;->string(Ljava/lang/String;)V
+Lorg/json/JSONTokener;->in:Ljava/lang/String;
+Lorg/json/JSONTokener;->nextCleanInternal()I
+Lorg/json/JSONTokener;->nextToInternal(Ljava/lang/String;)Ljava/lang/String;
+Lorg/json/JSONTokener;->pos:I
+Lorg/json/JSONTokener;->readArray()Lorg/json/JSONArray;
+Lorg/json/JSONTokener;->readEscapeCharacter()C
+Lorg/json/JSONTokener;->readLiteral()Ljava/lang/Object;
+Lorg/json/JSONTokener;->readObject()Lorg/json/JSONObject;
+Lorg/json/JSONTokener;->skipToEndOfLine()V
 Lorg/w3c/dom/ls/LSSerializerFilter;->getWhatToShow()I
 Lorg/w3c/dom/traversal/NodeFilter;->acceptNode(Lorg/w3c/dom/Node;)S
 Lorg/w3c/dom/traversal/NodeIterator;->detach()V
 Lorg/w3c/dom/traversal/NodeIterator;->nextNode()Lorg/w3c/dom/Node;
+Lorg/xml/sax/helpers/AttributesImpl;->badIndex(I)V
+Lorg/xml/sax/helpers/AttributesImpl;->data:[Ljava/lang/String;
+Lorg/xml/sax/helpers/AttributesImpl;->ensureCapacity(I)V
+Lorg/xml/sax/helpers/AttributesImpl;->length:I
+Lorg/xml/sax/helpers/LocatorImpl;->columnNumber:I
+Lorg/xml/sax/helpers/LocatorImpl;->lineNumber:I
+Lorg/xml/sax/helpers/LocatorImpl;->publicId:Ljava/lang/String;
+Lorg/xml/sax/helpers/LocatorImpl;->systemId:Ljava/lang/String;
+Lorg/xml/sax/helpers/NamespaceSupport;->contextPos:I
+Lorg/xml/sax/helpers/NamespaceSupport;->contexts:[Lorg/xml/sax/helpers/NamespaceSupport$Context;
+Lorg/xml/sax/helpers/NamespaceSupport;->currentContext:Lorg/xml/sax/helpers/NamespaceSupport$Context;
+Lorg/xml/sax/helpers/NamespaceSupport;->EMPTY_ENUMERATION:Ljava/util/Enumeration;
+Lorg/xml/sax/helpers/ParserAdapter;->attAdapter:Lorg/xml/sax/helpers/ParserAdapter$AttributeListAdapter;
+Lorg/xml/sax/helpers/ParserAdapter;->atts:Lorg/xml/sax/helpers/AttributesImpl;
+Lorg/xml/sax/helpers/ParserAdapter;->checkNotParsing(Ljava/lang/String;Ljava/lang/String;)V
+Lorg/xml/sax/helpers/ParserAdapter;->contentHandler:Lorg/xml/sax/ContentHandler;
+Lorg/xml/sax/helpers/ParserAdapter;->dtdHandler:Lorg/xml/sax/DTDHandler;
+Lorg/xml/sax/helpers/ParserAdapter;->entityResolver:Lorg/xml/sax/EntityResolver;
+Lorg/xml/sax/helpers/ParserAdapter;->errorHandler:Lorg/xml/sax/ErrorHandler;
+Lorg/xml/sax/helpers/ParserAdapter;->locator:Lorg/xml/sax/Locator;
+Lorg/xml/sax/helpers/ParserAdapter;->makeException(Ljava/lang/String;)Lorg/xml/sax/SAXParseException;
+Lorg/xml/sax/helpers/ParserAdapter;->nameParts:[Ljava/lang/String;
+Lorg/xml/sax/helpers/ParserAdapter;->namespaces:Z
+Lorg/xml/sax/helpers/ParserAdapter;->nsSupport:Lorg/xml/sax/helpers/NamespaceSupport;
+Lorg/xml/sax/helpers/ParserAdapter;->parser:Lorg/xml/sax/Parser;
+Lorg/xml/sax/helpers/ParserAdapter;->parsing:Z
+Lorg/xml/sax/helpers/ParserAdapter;->prefixes:Z
+Lorg/xml/sax/helpers/ParserAdapter;->processName(Ljava/lang/String;ZZ)[Ljava/lang/String;
+Lorg/xml/sax/helpers/ParserAdapter;->reportError(Ljava/lang/String;)V
+Lorg/xml/sax/helpers/ParserAdapter;->setup(Lorg/xml/sax/Parser;)V
+Lorg/xml/sax/helpers/ParserAdapter;->setupParser()V
+Lorg/xml/sax/helpers/XMLFilterImpl;->contentHandler:Lorg/xml/sax/ContentHandler;
+Lorg/xml/sax/helpers/XMLFilterImpl;->dtdHandler:Lorg/xml/sax/DTDHandler;
+Lorg/xml/sax/helpers/XMLFilterImpl;->entityResolver:Lorg/xml/sax/EntityResolver;
+Lorg/xml/sax/helpers/XMLFilterImpl;->errorHandler:Lorg/xml/sax/ErrorHandler;
+Lorg/xml/sax/helpers/XMLFilterImpl;->locator:Lorg/xml/sax/Locator;
+Lorg/xml/sax/helpers/XMLFilterImpl;->parent:Lorg/xml/sax/XMLReader;
+Lorg/xml/sax/helpers/XMLFilterImpl;->setupParse()V
+Lorg/xml/sax/helpers/XMLReaderAdapter;->documentHandler:Lorg/xml/sax/DocumentHandler;
+Lorg/xml/sax/helpers/XMLReaderAdapter;->qAtts:Lorg/xml/sax/helpers/XMLReaderAdapter$AttributesAdapter;
+Lorg/xml/sax/helpers/XMLReaderAdapter;->setup(Lorg/xml/sax/XMLReader;)V
+Lorg/xml/sax/helpers/XMLReaderAdapter;->setupXMLReader()V
+Lorg/xml/sax/helpers/XMLReaderAdapter;->xmlReader:Lorg/xml/sax/XMLReader;
+Lorg/xml/sax/helpers/XMLReaderFactory;->loadClass(Ljava/lang/ClassLoader;Ljava/lang/String;)Lorg/xml/sax/XMLReader;
+Lorg/xml/sax/InputSource;->byteStream:Ljava/io/InputStream;
+Lorg/xml/sax/InputSource;->characterStream:Ljava/io/Reader;
+Lorg/xml/sax/InputSource;->encoding:Ljava/lang/String;
+Lorg/xml/sax/InputSource;->publicId:Ljava/lang/String;
+Lorg/xml/sax/InputSource;->systemId:Ljava/lang/String;
+Lorg/xml/sax/SAXException;->exception:Ljava/lang/Exception;
+Lorg/xml/sax/SAXParseException;->columnNumber:I
+Lorg/xml/sax/SAXParseException;->init(Ljava/lang/String;Ljava/lang/String;II)V
+Lorg/xml/sax/SAXParseException;->lineNumber:I
+Lorg/xml/sax/SAXParseException;->publicId:Ljava/lang/String;
+Lorg/xml/sax/SAXParseException;->systemId:Ljava/lang/String;
 Lsun/misc/Unsafe;->theUnsafe:Lsun/misc/Unsafe;
 Lsun/misc/Unsafe;->THE_ONE:Lsun/misc/Unsafe;
 Lsun/misc/URLClassPath$JarLoader;->getJarFile()Ljava/util/jar/JarFile;
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 7b383d4..a6d2be0 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5580,6 +5580,9 @@
         if (mParent != null) {
             throw new IllegalStateException("Can only be called on top-level activity");
         }
+        if (Looper.myLooper() != mMainThread.getLooper()) {
+            throw new IllegalStateException("Must be called from main thread");
+        }
         mMainThread.scheduleRelaunchActivity(mToken);
     }
 
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 0ae4b7d..494ea39 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -124,6 +124,7 @@
 import android.util.SparseIntArray;
 import android.util.SuperNotCalledException;
 import android.util.proto.ProtoOutputStream;
+import android.view.Choreographer;
 import android.view.ContextThemeWrapper;
 import android.view.Display;
 import android.view.ThreadedRenderer;
@@ -145,6 +146,7 @@
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastPrintWriter;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.org.conscrypt.OpenSSLSocketImpl;
 import com.android.org.conscrypt.TrustedCertificateStore;
 import com.android.server.am.MemInfoDumpProto;
@@ -1406,7 +1408,15 @@
         }
 
         public void scheduleTrimMemory(int level) {
-            sendMessage(H.TRIM_MEMORY, null, level);
+            final Runnable r = PooledLambda.obtainRunnable(ActivityThread::handleTrimMemory,
+                    ActivityThread.this, level);
+            // Schedule trimming memory after drawing the frame to minimize jank-risk.
+            Choreographer choreographer = Choreographer.getMainThreadInstance();
+            if (choreographer != null) {
+                choreographer.postCallback(Choreographer.CALLBACK_COMMIT, r, null);
+            } else {
+                mH.post(r);
+            }
         }
 
         public void scheduleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
@@ -1561,7 +1571,6 @@
         public static final int SLEEPING                = 137;
         public static final int SET_CORE_SETTINGS       = 138;
         public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
-        public static final int TRIM_MEMORY             = 140;
         public static final int DUMP_PROVIDER           = 141;
         public static final int UNSTABLE_PROVIDER_DIED  = 142;
         public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
@@ -1607,7 +1616,6 @@
                     case SLEEPING: return "SLEEPING";
                     case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
                     case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
-                    case TRIM_MEMORY: return "TRIM_MEMORY";
                     case DUMP_PROVIDER: return "DUMP_PROVIDER";
                     case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
                     case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
@@ -1741,11 +1749,6 @@
                 case UPDATE_PACKAGE_COMPATIBILITY_INFO:
                     handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
                     break;
-                case TRIM_MEMORY:
-                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
-                    handleTrimMemory(msg.arg1);
-                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-                    break;
                 case UNSTABLE_PROVIDER_DIED:
                     handleUnstableProviderDied((IBinder)msg.obj, false);
                     break;
@@ -5409,7 +5412,8 @@
         BinderInternal.forceGc("mem");
     }
 
-    final void handleTrimMemory(int level) {
+    private void handleTrimMemory(int level) {
+        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
         if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
 
         ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
@@ -5420,6 +5424,7 @@
         }
 
         WindowManagerGlobal.getInstance().trimMemory(level);
+        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
     }
 
     private void setupGraphicsSupport(Context context) {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 21a3c07..fcab8c1 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -156,6 +156,12 @@
     public static final int UID_STATE_FOREGROUND_SERVICE = 2;
 
     /**
+     * Last UID state in which we don't restrict what an op can do.
+     * @hide
+     */
+    public static final int UID_STATE_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND_SERVICE;
+
+    /**
      * Metrics about an op when its uid is in the foreground for any other reasons.
      * @hide
      */
@@ -1594,11 +1600,11 @@
         }
 
         public long getLastAccessForegroundTime() {
-            return maxTime(mTimes, UID_STATE_PERSISTENT, UID_STATE_FOREGROUND_SERVICE + 1);
+            return maxTime(mTimes, UID_STATE_PERSISTENT, UID_STATE_LAST_NON_RESTRICTED + 1);
         }
 
         public long getLastAccessBackgroundTime() {
-            return maxTime(mTimes, UID_STATE_FOREGROUND_SERVICE + 1, _NUM_UID_STATE);
+            return maxTime(mTimes, UID_STATE_LAST_NON_RESTRICTED + 1, _NUM_UID_STATE);
         }
 
         public long getLastTimeFor(int uidState) {
@@ -1614,11 +1620,11 @@
         }
 
         public long getLastRejectForegroundTime() {
-            return maxTime(mRejectTimes, UID_STATE_PERSISTENT, UID_STATE_FOREGROUND_SERVICE + 1);
+            return maxTime(mRejectTimes, UID_STATE_PERSISTENT, UID_STATE_LAST_NON_RESTRICTED + 1);
         }
 
         public long getLastRejectBackgroundTime() {
-            return maxTime(mRejectTimes, UID_STATE_FOREGROUND_SERVICE + 1, _NUM_UID_STATE);
+            return maxTime(mRejectTimes, UID_STATE_LAST_NON_RESTRICTED + 1, _NUM_UID_STATE);
         }
 
         public long getLastRejectTimeFor(int uidState) {
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index f771cbd..a591eaf 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -984,6 +984,17 @@
     public static final String EXTRA_SHOW_REMOTE_INPUT_SPINNER = "android.remoteInputSpinner";
 
     /**
+     * {@link #extras} key: boolean as supplied to
+     * {@link Builder#setHideSmartReplies(boolean)}.
+     *
+     * If set to true, then any smart reply buttons will be hidden.
+     *
+     * @see Builder#setHideSmartReplies(boolean)
+     * @hide
+     */
+    public static final String EXTRA_HIDE_SMART_REPLIES = "android.hideSmartReplies";
+
+    /**
      * {@link #extras} key: this is a small piece of additional text as supplied to
      * {@link Builder#setContentInfo(CharSequence)}.
      */
@@ -3595,6 +3606,15 @@
         }
 
         /**
+         * Sets whether smart reply buttons should be hidden.
+         * @hide
+         */
+        public Builder setHideSmartReplies(boolean hideSmartReplies) {
+            mN.extras.putBoolean(EXTRA_HIDE_SMART_REPLIES, hideSmartReplies);
+            return this;
+        }
+
+        /**
          * Sets the number of items this notification represents. May be displayed as a badge count
          * for Launchers that support badging.
          */
@@ -6374,6 +6394,8 @@
 
         /**
          * @hide
+         * Note that we aren't actually comparing the contents of the bitmaps here, so this
+         * is only doing a cursory inspection. Bitmaps of equal size will appear the same.
          */
         @Override
         public boolean areNotificationsVisiblyDifferent(Style other) {
@@ -6381,7 +6403,20 @@
                 return true;
             }
             BigPictureStyle otherS = (BigPictureStyle) other;
-            return !Objects.equals(getBigPicture(), otherS.getBigPicture());
+            return areBitmapsObviouslyDifferent(getBigPicture(), otherS.getBigPicture());
+        }
+
+        private static boolean areBitmapsObviouslyDifferent(Bitmap a, Bitmap b) {
+            if (a == b) {
+                return false;
+            }
+            if (a == null || b == null) {
+                return true;
+            }
+            return a.getWidth() != b.getWidth()
+                    || a.getHeight() != b.getHeight()
+                    || a.getConfig() != b.getConfig()
+                    || a.getGenerationId() != b.getGenerationId();
         }
     }
 
@@ -6526,6 +6561,7 @@
 
         /**
          * @hide
+         * Spans are ignored when comparing text for visual difference.
          */
         @Override
         public boolean areNotificationsVisiblyDifferent(Style other) {
@@ -6533,7 +6569,7 @@
                 return true;
             }
             BigTextStyle newS = (BigTextStyle) other;
-            return !Objects.equals(getBigText(), newS.getBigText());
+            return !Objects.equals(String.valueOf(getBigText()), String.valueOf(newS.getBigText()));
         }
 
         static void applyBigTextContentView(Builder builder,
@@ -6900,6 +6936,7 @@
 
         /**
          * @hide
+         * Spans are ignored when comparing text for visual difference.
          */
         @Override
         public boolean areNotificationsVisiblyDifferent(Style other) {
@@ -6910,10 +6947,7 @@
             List<MessagingStyle.Message> oldMs = getMessages();
             List<MessagingStyle.Message> newMs = newS.getMessages();
 
-            if (oldMs == null) {
-                oldMs = new ArrayList<>();
-            }
-            if (newMs == null) {
+            if (oldMs == null || newMs == null) {
                 newMs = new ArrayList<>();
             }
 
@@ -6924,16 +6958,20 @@
             for (int i = 0; i < n; i++) {
                 MessagingStyle.Message oldM = oldMs.get(i);
                 MessagingStyle.Message newM = newMs.get(i);
-                if (!Objects.equals(oldM.getText(), newM.getText())) {
+                if (!Objects.equals(
+                        String.valueOf(oldM.getText()),
+                        String.valueOf(newM.getText()))) {
                     return true;
                 }
                 if (!Objects.equals(oldM.getDataUri(), newM.getDataUri())) {
                     return true;
                 }
-                CharSequence oldSender = oldM.getSenderPerson() == null ? oldM.getSender()
-                        : oldM.getSenderPerson().getName();
-                CharSequence newSender = newM.getSenderPerson() == null ? newM.getSender()
-                        : newM.getSenderPerson().getName();
+                String oldSender = String.valueOf(oldM.getSenderPerson() == null
+                        ? oldM.getSender()
+                        : oldM.getSenderPerson().getName());
+                String newSender = String.valueOf(newM.getSenderPerson() == null
+                        ? newM.getSender()
+                        : newM.getSenderPerson().getName());
                 if (!Objects.equals(oldSender, newSender)) {
                     return true;
                 }
@@ -7533,7 +7571,22 @@
                 return true;
             }
             InboxStyle newS = (InboxStyle) other;
-            return !Objects.equals(getLines(), newS.getLines());
+
+            final ArrayList<CharSequence> myLines = getLines();
+            final ArrayList<CharSequence> newLines = newS.getLines();
+            final int n = myLines.size();
+            if (n != newLines.size()) {
+                return true;
+            }
+
+            for (int i = 0; i < n; i++) {
+                if (!Objects.equals(
+                        String.valueOf(myLines.get(i)),
+                        String.valueOf(newLines.get(i)))) {
+                    return true;
+                }
+            }
+            return false;
         }
 
         private void handleInboxImageMargin(RemoteViews contentView, int id, boolean first,
diff --git a/core/java/android/app/slice/Slice.java b/core/java/android/app/slice/Slice.java
index aadf904..e54d3b6 100644
--- a/core/java/android/app/slice/Slice.java
+++ b/core/java/android/app/slice/Slice.java
@@ -28,6 +28,7 @@
 import android.os.Parcelable;
 
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.Preconditions;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -427,6 +428,7 @@
          * @see {@link SliceItem#getSubType()}
          */
         public Builder addSubSlice(@NonNull Slice slice, @Nullable @SliceSubtype String subType) {
+            Preconditions.checkNotNull(slice);
             mItems.add(new SliceItem(slice, SliceItem.FORMAT_SLICE, subType,
                     slice.getHints().toArray(new String[slice.getHints().size()])));
             return this;
@@ -439,6 +441,8 @@
          */
         public Slice.Builder addAction(@NonNull PendingIntent action, @NonNull Slice s,
                 @Nullable @SliceSubtype String subType) {
+            Preconditions.checkNotNull(action);
+            Preconditions.checkNotNull(s);
             List<String> hints = s.getHints();
             s.mSpec = null;
             mItems.add(new SliceItem(action, s, SliceItem.FORMAT_ACTION, subType, hints.toArray(
@@ -464,6 +468,7 @@
          */
         public Builder addIcon(Icon icon, @Nullable @SliceSubtype String subType,
                 @SliceHint List<String> hints) {
+            Preconditions.checkNotNull(icon);
             mItems.add(new SliceItem(icon, SliceItem.FORMAT_IMAGE, subType, hints));
             return this;
         }
@@ -476,6 +481,7 @@
         public Slice.Builder addRemoteInput(RemoteInput remoteInput,
                 @Nullable @SliceSubtype String subType,
                 @SliceHint List<String> hints) {
+            Preconditions.checkNotNull(remoteInput);
             mItems.add(new SliceItem(remoteInput, SliceItem.FORMAT_REMOTE_INPUT,
                     subType, hints));
             return this;
@@ -523,6 +529,7 @@
          */
         public Slice.Builder addBundle(Bundle bundle, @Nullable @SliceSubtype String subType,
                 @SliceHint List<String> hints) {
+            Preconditions.checkNotNull(bundle);
             mItems.add(new SliceItem(bundle, SliceItem.FORMAT_BUNDLE, subType,
                     hints));
             return this;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index ea08110..1bc3bc9 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3986,6 +3986,26 @@
      */
     public static final int EXTRA_THERMAL_STATE_EXCEEDED = 2;
 
+    /**
+     * Broadcast Action: Indicates the dock in idle state while device is docked.
+     *
+     * <p class="note">This is a protected intent that can only be sent
+     * by the system.
+     *
+     * @hide
+     */
+    public static final String ACTION_DOCK_IDLE = "android.intent.action.DOCK_IDLE";
+
+    /**
+     * Broadcast Action: Indicates the dock in active state while device is docked.
+     *
+     * <p class="note">This is a protected intent that can only be sent
+     * by the system.
+     *
+     * @hide
+     */
+    public static final String ACTION_DOCK_ACTIVE = "android.intent.action.DOCK_ACTIVE";
+
 
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 80b1c3d..c3b8f39 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -696,7 +696,7 @@
      *
      * @hide
      */
-    public static final String PRIVATE_DNS_DEFAULT_MODE = PRIVATE_DNS_MODE_OPPORTUNISTIC;
+    public static final String PRIVATE_DNS_DEFAULT_MODE_FALLBACK = PRIVATE_DNS_MODE_OPPORTUNISTIC;
 
     private final IConnectivityManager mService;
     /**
diff --git a/core/java/android/os/ConfigUpdate.java b/core/java/android/os/ConfigUpdate.java
index 53b1c51..7858c59 100644
--- a/core/java/android/os/ConfigUpdate.java
+++ b/core/java/android/os/ConfigUpdate.java
@@ -91,7 +91,14 @@
             = "android.intent.action.UPDATE_NETWORK_WATCHLIST";
 
     /**
-     * Update carrier id config file.
+     * Broadcast intent action indicating that the updated carrier id config is available.
+     * <p>Extra: "VERSION" the numeric version of the new data. Devices should only install if the
+     * update version is newer than the current one.
+     * <p>Extra: "REQUIRED_HASH" the hash of the current update data.
+     * <p>Input: {@link android.content.Intent#getData} is URI of downloaded carrier id file.
+     * Devices should pick up the downloaded file and persist to the database
+     * {@link com.android.providers.telephony.CarrierIdProvider}.
+     *
      * @hide
      */
     @SystemApi
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 780f3b9..7bf3af1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6001,6 +6001,23 @@
                 new SettingsValidators.ComponentNameListValidator(":");
 
         /**
+         * Whether the hush gesture has ever been used // TODO: beverlyt
+         * @hide
+         */
+        public static final String HUSH_GESTURE_USED = "hush_gesture_used";
+
+        private static final Validator HUSH_GESTURE_USED_VALIDATOR = BOOLEAN_VALIDATOR;
+
+        /**
+         * Number of times the user has manually clicked the ringer toggle
+         * @hide
+         */
+        public static final String MANUAL_RINGER_TOGGLE_COUNT = "manual_ringer_toggle_count";
+
+        private static final Validator MANUAL_RINGER_TOGGLE_COUNT_VALIDATOR =
+                NON_NEGATIVE_INTEGER_VALIDATOR;
+
+        /**
          * Uri of the slice that's presented on the keyguard.
          * Defaults to a slice with the date and next alarm.
          *
@@ -7983,7 +8000,9 @@
             SCREENSAVER_ACTIVATE_ON_SLEEP,
             LOCKDOWN_IN_POWER_MENU,
             SHOW_FIRST_CRASH_DIALOG_DEV_OPTION,
-            VOLUME_HUSH_GESTURE
+            VOLUME_HUSH_GESTURE,
+            MANUAL_RINGER_TOGGLE_COUNT,
+            HUSH_GESTURE_USED,
         };
 
         /**
@@ -8130,6 +8149,8 @@
                     ENABLED_NOTIFICATION_ASSISTANT_VALIDATOR); //legacy restore setting
             VALIDATORS.put(ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES,
                     ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES_VALIDATOR); //legacy restore setting
+            VALIDATORS.put(HUSH_GESTURE_USED, HUSH_GESTURE_USED_VALIDATOR);
+            VALIDATORS.put(MANUAL_RINGER_TOGGLE_COUNT, MANUAL_RINGER_TOGGLE_COUNT_VALIDATOR);
         }
 
         /**
@@ -8610,6 +8631,14 @@
         private static final Validator CHARGING_SOUNDS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
 
         /**
+         * Whether to vibrate for wireless charging events.
+         * @hide
+         */
+        public static final String CHARGING_VIBRATION_ENABLED = "charging_vibration_enabled";
+
+        private static final Validator CHARGING_VIBRATION_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
+
+        /**
          * Whether we keep the device on while the device is plugged in.
          * Supported values are:
          * <ul>
@@ -9297,7 +9326,7 @@
         * values.
         * Consists of a comma seperated list of strings:
         * "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
-        * note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN"
+        * note that empty fields can be omitted: "name,apn,,,,,,,,,310,260,,DUN"
         * @hide
         */
        public static final String TETHER_DUN_APN = "tether_dun_apn";
@@ -10358,6 +10387,17 @@
 
         private static final Validator PRIVATE_DNS_SPECIFIER_VALIDATOR = ANY_STRING_VALIDATOR;
 
+        /**
+          * Forced override of the default mode (hardcoded as "automatic", nee "opportunistic").
+          * This allows changing the default mode without effectively disabling other modes,
+          * all of which require explicit user action to enable/configure. See also b/79719289.
+          *
+          * Value is a string, suitable for assignment to PRIVATE_DNS_MODE above.
+          *
+          * {@hide}
+          */
+        public static final String PRIVATE_DNS_DEFAULT_MODE = "private_dns_default_mode";
+
         /** {@hide} */
         public static final String
                 BLUETOOTH_HEADSET_PRIORITY_PREFIX = "bluetooth_headset_priority_";
@@ -10447,7 +10487,9 @@
          * The following keys are supported:
          *
          * <pre>
-         * state_settle_time                (long)
+         * top_state_settle_time                (long)
+         * fg_service_state_settle_time         (long)
+         * bg_state_settle_time                 (long)
          * </pre>
          *
          * <p>
@@ -12015,6 +12057,7 @@
             PRIVATE_DNS_SPECIFIER,
             SOFT_AP_TIMEOUT_ENABLED,
             ZEN_DURATION,
+            CHARGING_VIBRATION_ENABLED,
         };
 
         /**
@@ -12058,6 +12101,7 @@
                     WIFI_CARRIER_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR);
             VALIDATORS.put(APP_AUTO_RESTRICTION_ENABLED, APP_AUTO_RESTRICTION_ENABLED_VALIDATOR);
             VALIDATORS.put(ZEN_DURATION, ZEN_DURATION_VALIDATOR);
+            VALIDATORS.put(CHARGING_VIBRATION_ENABLED, CHARGING_VIBRATION_ENABLED_VALIDATOR);
         }
 
         /**
diff --git a/core/java/android/provider/SettingsValidators.java b/core/java/android/provider/SettingsValidators.java
index 5885b6b..c878bba 100644
--- a/core/java/android/provider/SettingsValidators.java
+++ b/core/java/android/provider/SettingsValidators.java
@@ -79,7 +79,7 @@
     public static final Validator COMPONENT_NAME_VALIDATOR = new Validator() {
         @Override
         public boolean validate(String value) {
-            return ComponentName.unflattenFromString(value) != null;
+            return value != null && ComponentName.unflattenFromString(value) != null;
         }
     };
 
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 1caea57..f8cfd0d 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -106,10 +106,16 @@
             if (looper == null) {
                 throw new IllegalStateException("The current thread must have a looper!");
             }
-            return new Choreographer(looper, VSYNC_SOURCE_APP);
+            Choreographer choreographer = new Choreographer(looper, VSYNC_SOURCE_APP);
+            if (looper == Looper.getMainLooper()) {
+                mMainInstance = choreographer;
+            }
+            return choreographer;
         }
     };
 
+    private static volatile Choreographer mMainInstance;
+
     // Thread local storage for the SF choreographer.
     private static final ThreadLocal<Choreographer> sSfThreadInstance =
             new ThreadLocal<Choreographer>() {
@@ -263,6 +269,14 @@
         return sSfThreadInstance.get();
     }
 
+    /**
+     * @return The Choreographer of the main thread, if it exists, or {@code null} otherwise.
+     * @hide
+     */
+    public static Choreographer getMainThreadInstance() {
+        return mMainInstance;
+    }
+
     /** Destroys the calling thread's choreographer
      * @hide
      */
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index 7a10364..a3676ba 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -282,6 +282,9 @@
     public void setAppOpsOnClickListener(OnClickListener l) {
         mAppOpsListener = l;
         mAppOps.setOnClickListener(mAppOpsListener);
+        mCameraIcon.setOnClickListener(mAppOpsListener);
+        mMicIcon.setOnClickListener(mAppOpsListener);
+        mOverlayIcon.setOnClickListener(mAppOpsListener);
         updateTouchListener();
     }
 
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index e03f5fa..d19cc9c 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -790,7 +790,8 @@
      * @param attachInfo AttachInfo tied to the specified view.
      * @param callbacks Callbacks invoked when drawing happens.
      */
-    void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks) {
+    void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks,
+            FrameDrawingCallback frameDrawingCallback) {
         attachInfo.mIgnoreDirtyState = true;
 
         final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;
@@ -815,6 +816,9 @@
         }
 
         final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
+        if (frameDrawingCallback != null) {
+            nSetFrameCallback(mNativeProxy, frameDrawingCallback);
+        }
         int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
         if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
             setEnabled(false);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 049d34f..172e248 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9838,26 +9838,20 @@
     /**
      * @hide Compute the insets that should be consumed by this view and the ones
      * that should propagate to those under it.
+     *
+     * Note: This is used by appcompat's ActionBarOverlayLayout through reflection.
+     *
+     * @param inoutInsets the insets given to this view
+     * @param outLocalInsets the insets that should be applied to this view
+     * @deprecated use {@link #computeSystemWindowInsets}
+     * @return
      */
+    @Deprecated
     protected boolean computeFitSystemWindows(Rect inoutInsets, Rect outLocalInsets) {
-        if ((mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) == 0
-                || mAttachInfo == null
-                || ((mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0
-                        && !mAttachInfo.mOverscanRequested)) {
-            outLocalInsets.set(inoutInsets);
-            inoutInsets.set(0, 0, 0, 0);
-            return true;
-        } else {
-            // The application wants to take care of fitting system window for
-            // the content...  however we still need to take care of any overscan here.
-            final Rect overscan = mAttachInfo.mOverscanInsets;
-            outLocalInsets.set(overscan);
-            inoutInsets.left -= overscan.left;
-            inoutInsets.top -= overscan.top;
-            inoutInsets.right -= overscan.right;
-            inoutInsets.bottom -= overscan.bottom;
-            return false;
-        }
+        WindowInsets innerInsets = computeSystemWindowInsets(new WindowInsets(inoutInsets),
+                outLocalInsets);
+        inoutInsets.set(innerInsets.getSystemWindowInsets());
+        return innerInsets.isSystemWindowInsetsConsumed();
     }
 
     /**
@@ -9873,12 +9867,16 @@
     public WindowInsets computeSystemWindowInsets(WindowInsets in, Rect outLocalInsets) {
         if ((mViewFlags & OPTIONAL_FITS_SYSTEM_WINDOWS) == 0
                 || mAttachInfo == null
-                || (mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0) {
+                || ((mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0
+                && !mAttachInfo.mOverscanRequested)) {
             outLocalInsets.set(in.getSystemWindowInsets());
-            return in.consumeSystemWindowInsets();
+            return in.consumeSystemWindowInsets().inset(outLocalInsets);
         } else {
-            outLocalInsets.set(0, 0, 0, 0);
-            return in;
+            // The application wants to take care of fitting system window for
+            // the content...  however we still need to take care of any overscan here.
+            final Rect overscan = mAttachInfo.mOverscanInsets;
+            outLocalInsets.set(overscan);
+            return in.inset(outLocalInsets);
         }
     }
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 239185e..7c814f4 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -80,6 +80,7 @@
 import android.util.TimeUtils;
 import android.util.TypedValue;
 import android.view.Surface.OutOfResourcesException;
+import android.view.ThreadedRenderer.FrameDrawingCallback;
 import android.view.View.AttachInfo;
 import android.view.View.FocusDirection;
 import android.view.View.MeasureSpec;
@@ -175,6 +176,8 @@
     static final ArrayList<Runnable> sFirstDrawHandlers = new ArrayList();
     static boolean sFirstDrawComplete = false;
 
+    private FrameDrawingCallback mNextRtFrameCallback;
+
     /**
      * Callback for notifying about global configuration changes.
      */
@@ -967,6 +970,17 @@
         }
     }
 
+    /**
+     * Registers a callback to be executed when the next frame is being drawn on RenderThread. This
+     * callback will be executed on a RenderThread worker thread, and only used for the next frame
+     * and thus it will only fire once.
+     *
+     * @param callback The callback to register.
+     */
+    public void registerRtFrameCallback(FrameDrawingCallback callback) {
+        mNextRtFrameCallback = callback;
+    }
+
     private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
         mAttachInfo.mHardwareAccelerated = false;
         mAttachInfo.mHardwareAccelerationRequested = false;
@@ -3260,7 +3274,8 @@
                     requestDrawWindow();
                 }
 
-                mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
+                mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this, mNextRtFrameCallback);
+                mNextRtFrameCallback = null;
             } else {
                 // If we get here with a disabled & requested hardware renderer, something went
                 // wrong (an invalidate posted right before we destroyed the hardware surface
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index e5cbe96..fbd8141 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -20,6 +20,10 @@
 import android.annotation.Nullable;
 import android.graphics.Rect;
 
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
 /**
  * Describes a set of insets for window content.
  *
@@ -27,6 +31,12 @@
  * To adjust insets, use one of the supplied clone methods to obtain a new WindowInsets instance
  * with the adjusted properties.</p>
  *
+ * <p>Note: Before {@link android.os.Build.VERSION_CODES#P P}, WindowInsets instances were only
+ * immutable during a single layout pass (i.e. would return the same values between
+ * {@link View#onApplyWindowInsets} and {@link View#onLayout}, but could return other values
+ * otherwise). Starting with {@link android.os.Build.VERSION_CODES#P P}, WindowInsets are
+ * always immutable and implement equality.
+ *
  * @see View.OnApplyWindowInsetsListener
  * @see View#onApplyWindowInsets(WindowInsets)
  */
@@ -69,13 +79,14 @@
     public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets, Rect stableInsets,
             boolean isRound, boolean alwaysConsumeNavBar, DisplayCutout displayCutout) {
         mSystemWindowInsetsConsumed = systemWindowInsets == null;
-        mSystemWindowInsets = mSystemWindowInsetsConsumed ? EMPTY_RECT : systemWindowInsets;
+        mSystemWindowInsets = mSystemWindowInsetsConsumed
+                ? EMPTY_RECT : new Rect(systemWindowInsets);
 
         mWindowDecorInsetsConsumed = windowDecorInsets == null;
-        mWindowDecorInsets = mWindowDecorInsetsConsumed ? EMPTY_RECT : windowDecorInsets;
+        mWindowDecorInsets = mWindowDecorInsetsConsumed ? EMPTY_RECT : new Rect(windowDecorInsets);
 
         mStableInsetsConsumed = stableInsets == null;
-        mStableInsets = mStableInsetsConsumed ? EMPTY_RECT : stableInsets;
+        mStableInsets = mStableInsetsConsumed ? EMPTY_RECT : new Rect(stableInsets);
 
         mIsRound = isRound;
         mAlwaysConsumeNavBar = alwaysConsumeNavBar;
@@ -535,4 +546,104 @@
                 + (isRound() ? " round" : "")
                 + "}";
     }
+
+    /**
+     * Returns a copy of this instance inset in the given directions.
+     *
+     * @see #inset(int, int, int, int)
+     * @hide
+     */
+    public WindowInsets inset(Rect r) {
+        return inset(r.left, r.top, r.right, r.bottom);
+    }
+
+    /**
+     * Returns a copy of this instance inset in the given directions.
+     *
+     * This is intended for dispatching insets to areas of the window that are smaller than the
+     * current area.
+     *
+     * <p>Example:
+     * <pre>
+     * childView.dispatchApplyWindowInsets(insets.inset(
+     *         childMarginLeft, childMarginTop, childMarginBottom, childMarginRight));
+     * </pre>
+     *
+     * @param left the amount of insets to remove from the left. Must be non-negative.
+     * @param top the amount of insets to remove from the top. Must be non-negative.
+     * @param right the amount of insets to remove from the right. Must be non-negative.
+     * @param bottom the amount of insets to remove from the bottom. Must be non-negative.
+     *
+     * @return the inset insets
+     *
+     * @hide pending API
+     */
+    public WindowInsets inset(int left, int top, int right, int bottom) {
+        Preconditions.checkArgumentNonnegative(left);
+        Preconditions.checkArgumentNonnegative(top);
+        Preconditions.checkArgumentNonnegative(right);
+        Preconditions.checkArgumentNonnegative(bottom);
+
+        WindowInsets result = new WindowInsets(this);
+        if (!result.mSystemWindowInsetsConsumed) {
+            result.mSystemWindowInsets =
+                    insetInsets(result.mSystemWindowInsets, left, top, right, bottom);
+        }
+        if (!result.mWindowDecorInsetsConsumed) {
+            result.mWindowDecorInsets =
+                    insetInsets(result.mWindowDecorInsets, left, top, right, bottom);
+        }
+        if (!result.mStableInsetsConsumed) {
+            result.mStableInsets = insetInsets(result.mStableInsets, left, top, right, bottom);
+        }
+        if (mDisplayCutout != null) {
+            result.mDisplayCutout = result.mDisplayCutout.inset(left, top, right, bottom);
+            if (result.mDisplayCutout.isEmpty()) {
+                result.mDisplayCutout = null;
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || !(o instanceof WindowInsets)) return false;
+        WindowInsets that = (WindowInsets) o;
+        return mIsRound == that.mIsRound
+                && mAlwaysConsumeNavBar == that.mAlwaysConsumeNavBar
+                && mSystemWindowInsetsConsumed == that.mSystemWindowInsetsConsumed
+                && mWindowDecorInsetsConsumed == that.mWindowDecorInsetsConsumed
+                && mStableInsetsConsumed == that.mStableInsetsConsumed
+                && mDisplayCutoutConsumed == that.mDisplayCutoutConsumed
+                && Objects.equals(mSystemWindowInsets, that.mSystemWindowInsets)
+                && Objects.equals(mWindowDecorInsets, that.mWindowDecorInsets)
+                && Objects.equals(mStableInsets, that.mStableInsets)
+                && Objects.equals(mDisplayCutout, that.mDisplayCutout);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mSystemWindowInsets, mWindowDecorInsets, mStableInsets, mIsRound,
+                mDisplayCutout, mAlwaysConsumeNavBar, mSystemWindowInsetsConsumed,
+                mWindowDecorInsetsConsumed, mStableInsetsConsumed, mDisplayCutoutConsumed);
+    }
+
+    private static Rect insetInsets(Rect insets, int left, int top, int right, int bottom) {
+        int newLeft = Math.max(0, insets.left - left);
+        int newTop = Math.max(0, insets.top - top);
+        int newRight = Math.max(0, insets.right - right);
+        int newBottom = Math.max(0, insets.bottom - bottom);
+        if (newLeft == left && newTop == top && newRight == right && newBottom == bottom) {
+            return insets;
+        }
+        return new Rect(newLeft, newTop, newRight, newBottom);
+    }
+
+    /**
+     * @return whether system window insets have been consumed.
+     */
+    boolean isSystemWindowInsetsConsumed() {
+        return mSystemWindowInsetsConsumed;
+    }
 }
diff --git a/core/java/android/view/textclassifier/TextClassification.java b/core/java/android/view/textclassifier/TextClassification.java
index f2643d7..9511a9e 100644
--- a/core/java/android/view/textclassifier/TextClassification.java
+++ b/core/java/android/view/textclassifier/TextClassification.java
@@ -288,11 +288,12 @@
     @Nullable
     public static PendingIntent createPendingIntent(
             @NonNull final Context context, @NonNull final Intent intent, int requestCode) {
+        final int flags = PendingIntent.FLAG_UPDATE_CURRENT;
         switch (getIntentType(intent, context)) {
             case IntentType.ACTIVITY:
-                return PendingIntent.getActivity(context, requestCode, intent, 0);
+                return PendingIntent.getActivity(context, requestCode, intent, flags);
             case IntentType.SERVICE:
-                return PendingIntent.getService(context, requestCode, intent, 0);
+                return PendingIntent.getService(context, requestCode, intent, flags);
             default:
                 return null;
         }
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index 1737861..aee0aa7 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemService;
 import android.content.Context;
+import android.database.ContentObserver;
 import android.os.ServiceManager;
 import android.provider.Settings;
 import android.service.textclassifier.TextClassifierService;
@@ -28,6 +29,8 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
 
+import java.lang.ref.WeakReference;
+
 /**
  * Interface to the text classification service.
  */
@@ -42,23 +45,27 @@
                     classificationContext, getTextClassifier());
 
     private final Context mContext;
-    private final TextClassificationConstants mSettings;
+    private final SettingsObserver mSettingsObserver;
 
     @GuardedBy("mLock")
-    private TextClassifier mTextClassifier;
+    @Nullable
+    private TextClassifier mCustomTextClassifier;
     @GuardedBy("mLock")
+    @Nullable
     private TextClassifier mLocalTextClassifier;
     @GuardedBy("mLock")
+    @Nullable
     private TextClassifier mSystemTextClassifier;
     @GuardedBy("mLock")
     private TextClassificationSessionFactory mSessionFactory;
+    @GuardedBy("mLock")
+    private TextClassificationConstants mSettings;
 
     /** @hide */
     public TextClassificationManager(Context context) {
         mContext = Preconditions.checkNotNull(context);
-        mSettings = TextClassificationConstants.loadFromString(Settings.Global.getString(
-                context.getContentResolver(), Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
         mSessionFactory = mDefaultSessionFactory;
+        mSettingsObserver = new SettingsObserver(this);
     }
 
     /**
@@ -71,14 +78,13 @@
     @NonNull
     public TextClassifier getTextClassifier() {
         synchronized (mLock) {
-            if (mTextClassifier == null) {
-                if (isSystemTextClassifierEnabled()) {
-                    mTextClassifier = getSystemTextClassifier();
-                } else {
-                    mTextClassifier = getLocalTextClassifier();
-                }
+            if (mCustomTextClassifier != null) {
+                return mCustomTextClassifier;
+            } else if (isSystemTextClassifierEnabled()) {
+                return getSystemTextClassifier();
+            } else {
+                return getLocalTextClassifier();
             }
-            return mTextClassifier;
         }
     }
 
@@ -89,7 +95,7 @@
      */
     public void setTextClassifier(@Nullable TextClassifier textClassifier) {
         synchronized (mLock) {
-            mTextClassifier = textClassifier;
+            mCustomTextClassifier = textClassifier;
         }
     }
 
@@ -110,9 +116,15 @@
         }
     }
 
-    /** @hide */
-    public TextClassificationConstants getSettings() {
-        return mSettings;
+    private TextClassificationConstants getSettings() {
+        synchronized (mLock) {
+            if (mSettings == null) {
+                mSettings = TextClassificationConstants.loadFromString(Settings.Global.getString(
+                        mContext.getApplicationContext().getContentResolver(),
+                        Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
+            }
+            return mSettings;
+        }
     }
 
     /**
@@ -170,11 +182,24 @@
         }
     }
 
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            // Note that fields could be null if the constructor threw.
+            if (mContext != null && mSettingsObserver != null) {
+                mContext.getApplicationContext().getContentResolver()
+                        .unregisterContentObserver(mSettingsObserver);
+            }
+        } finally {
+            super.finalize();
+        }
+    }
+
     private TextClassifier getSystemTextClassifier() {
         synchronized (mLock) {
             if (mSystemTextClassifier == null && isSystemTextClassifierEnabled()) {
                 try {
-                    mSystemTextClassifier = new SystemTextClassifier(mContext, mSettings);
+                    mSystemTextClassifier = new SystemTextClassifier(mContext, getSettings());
                     Log.d(LOG_TAG, "Initialized SystemTextClassifier");
                 } catch (ServiceManager.ServiceNotFoundException e) {
                     Log.e(LOG_TAG, "Could not initialize SystemTextClassifier", e);
@@ -190,9 +215,9 @@
     private TextClassifier getLocalTextClassifier() {
         synchronized (mLock) {
             if (mLocalTextClassifier == null) {
-                if (mSettings.isLocalTextClassifierEnabled()) {
+                if (getSettings().isLocalTextClassifierEnabled()) {
                     mLocalTextClassifier =
-                            new TextClassifierImpl(mContext, mSettings, TextClassifier.NO_OP);
+                            new TextClassifierImpl(mContext, getSettings(), TextClassifier.NO_OP);
                 } else {
                     Log.d(LOG_TAG, "Local TextClassifier disabled");
                     mLocalTextClassifier = TextClassifier.NO_OP;
@@ -203,20 +228,51 @@
     }
 
     private boolean isSystemTextClassifierEnabled() {
-        return mSettings.isSystemTextClassifierEnabled()
+        return getSettings().isSystemTextClassifierEnabled()
                 && TextClassifierService.getServiceComponentName(mContext) != null;
     }
 
+    private void invalidate() {
+        synchronized (mLock) {
+            mSettings = null;
+            mLocalTextClassifier = null;
+            mSystemTextClassifier = null;
+        }
+    }
+
     /** @hide */
     public static TextClassificationConstants getSettings(Context context) {
         Preconditions.checkNotNull(context);
         final TextClassificationManager tcm =
                 context.getSystemService(TextClassificationManager.class);
         if (tcm != null) {
-            return tcm.mSettings;
+            return tcm.getSettings();
         } else {
             return TextClassificationConstants.loadFromString(Settings.Global.getString(
-                    context.getContentResolver(), Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
+                    context.getApplicationContext().getContentResolver(),
+                    Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
+        }
+    }
+
+    private static final class SettingsObserver extends ContentObserver {
+
+        private final WeakReference<TextClassificationManager> mTcm;
+
+        SettingsObserver(TextClassificationManager tcm) {
+            super(null);
+            mTcm = new WeakReference<>(tcm);
+            tcm.mContext.getApplicationContext().getContentResolver().registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.TEXT_CLASSIFIER_CONSTANTS),
+                    false /* notifyForDescendants */,
+                    this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            final TextClassificationManager tcm = mTcm.get();
+            if (tcm != null) {
+                tcm.invalidate();
+            }
         }
     }
 }
diff --git a/core/java/android/view/textclassifier/TextSelection.java b/core/java/android/view/textclassifier/TextSelection.java
index 17687c9..a4550af 100644
--- a/core/java/android/view/textclassifier/TextSelection.java
+++ b/core/java/android/view/textclassifier/TextSelection.java
@@ -154,8 +154,8 @@
          * Sets an id for the TextSelection object.
          */
         @NonNull
-        public Builder setId(@NonNull String id) {
-            mId = Preconditions.checkNotNull(id);
+        public Builder setId(@Nullable String id) {
+            mId = id;
             return this;
         }
 
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index 1f2b90a..8f1f1ab 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -70,7 +70,6 @@
     private final Editor mEditor;
     private final TextView mTextView;
     private final TextClassificationHelper mTextClassificationHelper;
-    private final TextClassificationConstants mTextClassificationSettings;
 
     @Nullable private TextClassification mTextClassification;
     private AsyncTask mTextClassificationAsyncTask;
@@ -84,7 +83,6 @@
     SelectionActionModeHelper(@NonNull Editor editor) {
         mEditor = Preconditions.checkNotNull(editor);
         mTextView = mEditor.getTextView();
-        mTextClassificationSettings = TextClassificationManager.getSettings(mTextView.getContext());
         mTextClassificationHelper = new TextClassificationHelper(
                 mTextView.getContext(),
                 mTextView::getTextClassifier,
@@ -92,7 +90,7 @@
                 0, 1, mTextView.getTextLocales());
         mSelectionTracker = new SelectionTracker(mTextView);
 
-        if (mTextClassificationSettings.isSmartSelectionAnimationEnabled()) {
+        if (getTextClassificationSettings().isSmartSelectionAnimationEnabled()) {
             mSmartSelectSprite = new SmartSelectSprite(mTextView.getContext(),
                     editor.getTextView().mHighlightColor, mTextView::invalidate);
         } else {
@@ -105,7 +103,7 @@
      */
     public void startSelectionActionModeAsync(boolean adjustSelection) {
         // Check if the smart selection should run for editable text.
-        adjustSelection &= mTextClassificationSettings.isSmartSelectionEnabled();
+        adjustSelection &= getTextClassificationSettings().isSmartSelectionEnabled();
 
         mSelectionTracker.onOriginalSelection(
                 getText(mTextView),
@@ -212,6 +210,10 @@
         return mSmartSelectSprite != null && mSmartSelectSprite.isAnimationActive();
     }
 
+    private TextClassificationConstants getTextClassificationSettings() {
+        return TextClassificationManager.getSettings(mTextView.getContext());
+    }
+
     private void cancelAsyncTask() {
         if (mTextClassificationAsyncTask != null) {
             mTextClassificationAsyncTask.cancel(true);
@@ -245,7 +247,7 @@
         if (result != null && text instanceof Spannable
                 && (mTextView.isTextSelectable() || mTextView.isTextEditable())) {
             // Do not change the selection if TextClassifier should be dark launched.
-            if (!mTextClassificationSettings.isModelDarkLaunchEnabled()) {
+            if (!getTextClassificationSettings().isModelDarkLaunchEnabled()) {
                 Selection.setSelection((Spannable) text, result.mStart, result.mEnd);
                 mTextView.invalidate();
             }
@@ -906,7 +908,6 @@
         private static final int TRIM_DELTA = 120;  // characters
 
         private final Context mContext;
-        private final boolean mDarkLaunchEnabled;
         private Supplier<TextClassifier> mTextClassifier;
 
         /** The original TextView text. **/
@@ -942,8 +943,6 @@
                 CharSequence text, int selectionStart, int selectionEnd, LocaleList locales) {
             init(textClassifier, text, selectionStart, selectionEnd, locales);
             mContext = Preconditions.checkNotNull(context);
-            mDarkLaunchEnabled = TextClassificationManager.getSettings(mContext)
-                    .isModelDarkLaunchEnabled();
         }
 
         @UiThread
@@ -982,7 +981,7 @@
                         mTrimmedText, mRelativeStart, mRelativeEnd, mDefaultLocales);
             }
             // Do not classify new selection boundaries if TextClassifier should be dark launched.
-            if (!mDarkLaunchEnabled) {
+            if (!isDarkLaunchEnabled()) {
                 mSelectionStart = Math.max(0, selection.getSelectionStartIndex() + mTrimStart);
                 mSelectionEnd = Math.min(
                         mText.length(), selection.getSelectionEndIndex() + mTrimStart);
@@ -1010,6 +1009,10 @@
             }
         }
 
+        private boolean isDarkLaunchEnabled() {
+            return TextClassificationManager.getSettings(mContext).isModelDarkLaunchEnabled();
+        }
+
         private SelectionResult performClassification(@Nullable TextSelection selection) {
             if (!Objects.equals(mText, mLastClassificationText)
                     || mSelectionStart != mLastClassificationSelectionStart
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 2db5739..465957d 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -983,14 +983,14 @@
             if (attrs.height == WindowManager.LayoutParams.WRAP_CONTENT) {
                 mFloatingInsets.top = insets.getSystemWindowInsetTop();
                 mFloatingInsets.bottom = insets.getSystemWindowInsetBottom();
-                insets = insets.replaceSystemWindowInsets(insets.getSystemWindowInsetLeft(), 0,
-                        insets.getSystemWindowInsetRight(), 0);
+                insets = insets.inset(0, insets.getSystemWindowInsetTop(),
+                        0, insets.getSystemWindowInsetBottom());
             }
             if (mWindow.getAttributes().width == WindowManager.LayoutParams.WRAP_CONTENT) {
                 mFloatingInsets.left = insets.getSystemWindowInsetTop();
                 mFloatingInsets.right = insets.getSystemWindowInsetBottom();
-                insets = insets.replaceSystemWindowInsets(0, insets.getSystemWindowInsetTop(),
-                        0, insets.getSystemWindowInsetBottom());
+                insets = insets.inset(insets.getSystemWindowInsetLeft(), 0,
+                        insets.getSystemWindowInsetRight(), 0);
             }
         }
         mFrameOffsets.set(insets.getSystemWindowInsets());
@@ -1158,11 +1158,7 @@
                 }
             }
             if (insets != null) {
-                insets = insets.replaceSystemWindowInsets(
-                        insets.getSystemWindowInsetLeft() - consumedLeft,
-                        insets.getSystemWindowInsetTop() - consumedTop,
-                        insets.getSystemWindowInsetRight() - consumedRight,
-                        insets.getSystemWindowInsetBottom() - consumedBottom);
+                insets = insets.inset(consumedLeft, consumedTop, consumedRight, consumedBottom);
             }
         }
 
@@ -1383,8 +1379,9 @@
                     // screen_simple_overlay_action_mode.xml).
                     final boolean nonOverlay = (mWindow.getLocalFeaturesPrivate()
                             & (1 << Window.FEATURE_ACTION_MODE_OVERLAY)) == 0;
-                    insets = insets.consumeSystemWindowInsets(
-                            false, nonOverlay && showStatusGuard /* top */, false, false);
+                    if (nonOverlay && showStatusGuard) {
+                        insets = insets.inset(0, insets.getSystemWindowInsetTop(), 0, 0);
+                    }
                 } else {
                     // reset top margin
                     if (mlp.topMargin != 0) {
diff --git a/core/java/com/android/internal/statusbar/NotificationVisibility.java b/core/java/com/android/internal/statusbar/NotificationVisibility.java
index 7fe440c..ea0344d 100644
--- a/core/java/com/android/internal/statusbar/NotificationVisibility.java
+++ b/core/java/com/android/internal/statusbar/NotificationVisibility.java
@@ -51,7 +51,7 @@
     @Override
     public String toString() {
         return "NotificationVisibility(id=" + id
-                + "key=" + key
+                + " key=" + key
                 + " rank=" + rank
                 + " count=" + count
                 + (visible?" visible":"")
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index 5d7fa6a..4a1c955 100644
--- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
+++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
@@ -75,10 +75,10 @@
     private final Rect mBaseContentInsets = new Rect();
     private final Rect mLastBaseContentInsets = new Rect();
     private final Rect mContentInsets = new Rect();
-    private final Rect mBaseInnerInsets = new Rect();
-    private final Rect mLastBaseInnerInsets = new Rect();
-    private final Rect mInnerInsets = new Rect();
-    private final Rect mLastInnerInsets = new Rect();
+    private WindowInsets mBaseInnerInsets = WindowInsets.CONSUMED;
+    private WindowInsets mLastBaseInnerInsets = WindowInsets.CONSUMED;
+    private WindowInsets mInnerInsets = WindowInsets.CONSUMED;
+    private WindowInsets mLastInnerInsets = WindowInsets.CONSUMED;
 
     private ActionBarVisibilityCallback mActionBarVisibilityCallback;
 
@@ -322,11 +322,14 @@
             changed |= applyInsets(mActionBarBottom, systemInsets, true, false, true, true);
         }
 
-        mBaseInnerInsets.set(systemInsets);
-        computeFitSystemWindows(mBaseInnerInsets, mBaseContentInsets);
+        // Cannot use the result of computeSystemWindowInsets, because that consumes the
+        // systemWindowInsets. Instead, we do the insetting by the local insets ourselves.
+        computeSystemWindowInsets(insets, mBaseContentInsets);
+        mBaseInnerInsets = insets.inset(mBaseContentInsets);
+
         if (!mLastBaseInnerInsets.equals(mBaseInnerInsets)) {
             changed = true;
-            mLastBaseContentInsets.set(mBaseContentInsets);
+            mLastBaseInnerInsets = mBaseInnerInsets;
         }
         if (!mLastBaseContentInsets.equals(mBaseContentInsets)) {
             changed = true;
@@ -430,22 +433,29 @@
         // will still be covered by the action bar if they have requested it to
         // overlay.
         mContentInsets.set(mBaseContentInsets);
-        mInnerInsets.set(mBaseInnerInsets);
+        mInnerInsets = mBaseInnerInsets;
         if (!mOverlayMode && !stable) {
             mContentInsets.top += topInset;
             mContentInsets.bottom += bottomInset;
+            // Content view has been shrunk, shrink all insets to match.
+            mInnerInsets = mInnerInsets.inset(0 /* left */, topInset, 0 /* right */, bottomInset);
         } else {
-            mInnerInsets.top += topInset;
-            mInnerInsets.bottom += bottomInset;
+            // Add ActionBar to system window inset, but leave other insets untouched.
+            mInnerInsets = mInnerInsets.replaceSystemWindowInsets(
+                    mInnerInsets.getSystemWindowInsetLeft(),
+                    mInnerInsets.getSystemWindowInsetTop() + topInset,
+                    mInnerInsets.getSystemWindowInsetRight(),
+                    mInnerInsets.getSystemWindowInsetBottom() + bottomInset
+            );
         }
         applyInsets(mContent, mContentInsets, true, true, true, true);
 
         if (!mLastInnerInsets.equals(mInnerInsets)) {
             // If the inner insets have changed, we need to dispatch this down to
-            // the app's fitSystemWindows().  We do this before measuring the content
+            // the app's onApplyWindowInsets().  We do this before measuring the content
             // view to keep the same semantics as the normal fitSystemWindows() call.
-            mLastInnerInsets.set(mInnerInsets);
-            mContent.dispatchApplyWindowInsets(new WindowInsets(mInnerInsets));
+            mLastInnerInsets = mInnerInsets;
+            mContent.dispatchApplyWindowInsets(mInnerInsets);
         }
 
         measureChildWithMargins(mContent, widthMeasureSpec, 0, heightMeasureSpec, 0);
diff --git a/core/jni/android/graphics/AnimatedImageDrawable.cpp b/core/jni/android/graphics/AnimatedImageDrawable.cpp
index 7166c75..8dd5f5f 100644
--- a/core/jni/android/graphics/AnimatedImageDrawable.cpp
+++ b/core/jni/android/graphics/AnimatedImageDrawable.cpp
@@ -239,11 +239,6 @@
     return drawable->byteSize();
 }
 
-static void AnimatedImageDrawable_nMarkInvisible(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
-    auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
-    drawable->markInvisible();
-}
-
 static void AnimatedImageDrawable_nSetMirrored(JNIEnv* env, jobject /*clazz*/, jlong nativePtr,
                                                jboolean mirrored) {
     auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
@@ -264,7 +259,6 @@
     { "nSetRepeatCount",     "(JI)V",                                                        (void*) AnimatedImageDrawable_nSetRepeatCount },
     { "nSetOnAnimationEndListener", "(JLandroid/graphics/drawable/AnimatedImageDrawable;)V", (void*) AnimatedImageDrawable_nSetOnAnimationEndListener },
     { "nNativeByteSize",     "(J)J",                                                         (void*) AnimatedImageDrawable_nNativeByteSize },
-    { "nMarkInvisible",      "(J)V",                                                         (void*) AnimatedImageDrawable_nMarkInvisible },
     { "nSetMirrored",        "(JZ)V",                                                        (void*) AnimatedImageDrawable_nSetMirrored },
 };
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 87d8915..e35b631 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -599,6 +599,10 @@
     <protected-broadcast android:name="android.app.action.DATA_SHARING_RESTRICTION_CHANGED" />
     <protected-broadcast android:name="android.app.action.STATSD_STARTED" />
 
+    <!-- For IdleController -->
+    <protected-broadcast android:name="android.intent.action.DOCK_IDLE" />
+    <protected-broadcast android:name="android.intent.action.DOCK_ACTIVE" />
+
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
diff --git a/packages/SystemUI/res/drawable/ic_lock_lockdown.xml b/core/res/res/drawable/ic_lock_lockdown.xml
similarity index 96%
rename from packages/SystemUI/res/drawable/ic_lock_lockdown.xml
rename to core/res/res/drawable/ic_lock_lockdown.xml
index d591aa8..b9685d3 100644
--- a/packages/SystemUI/res/drawable/ic_lock_lockdown.xml
+++ b/core/res/res/drawable/ic_lock_lockdown.xml
@@ -21,6 +21,6 @@
         android:tint="?attr/colorControlNormal">
 
     <path
-        android:fillColor="#000000"
+        android:fillColor="#FF000000"
         android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM12.0,17.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0c1.1,0.0 2.0,0.9 2.0,2.0S13.1,17.0 12.0,17.0zM15.1,8.0L8.9,8.0L8.9,6.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1L15.1,8.0z"/>
 </vector>
diff --git a/core/res/res/layout/autofill_dataset_picker.xml b/core/res/res/layout/autofill_dataset_picker.xml
index a88836e..dca0128 100644
--- a/core/res/res/layout/autofill_dataset_picker.xml
+++ b/core/res/res/layout/autofill_dataset_picker.xml
@@ -18,6 +18,7 @@
     android:id="@+id/autofill_dataset_picker"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
+    android:foreground="?attr/listChoiceBackgroundIndicator"
     style="@style/AutofillDatasetPicker">
 
     <ListView
diff --git a/core/res/res/layout/autofill_dataset_picker_fullscreen.xml b/core/res/res/layout/autofill_dataset_picker_fullscreen.xml
index 1d2b5e5..90435e9 100644
--- a/core/res/res/layout/autofill_dataset_picker_fullscreen.xml
+++ b/core/res/res/layout/autofill_dataset_picker_fullscreen.xml
@@ -60,12 +60,13 @@
 
     </LinearLayout>
 
-    <!-- autofill_container is the common parent for inserting authentication item or
-         autofill_dataset_list, autofill_dataset_foolter-->
+    <!-- autofill_dataset_picker is the common parent for inserting authentication item or
+         autofill_dataset_list, autofill_dataset_footer-->
     <LinearLayout
         android:layout_width="304dp"
         android:layout_height="wrap_content"
         android:id="@+id/autofill_dataset_picker"
+        android:foreground="?attr/listChoiceBackgroundIndicator"
         android:orientation="vertical">
         <ListView
             android:id="@+id/autofill_dataset_list"
@@ -83,4 +84,4 @@
             android:orientation="vertical"/>
     </LinearLayout>
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/core/res/res/layout/autofill_dataset_picker_header_footer.xml b/core/res/res/layout/autofill_dataset_picker_header_footer.xml
index 093f035..4d5f4f0 100644
--- a/core/res/res/layout/autofill_dataset_picker_header_footer.xml
+++ b/core/res/res/layout/autofill_dataset_picker_header_footer.xml
@@ -18,6 +18,7 @@
     android:id="@+id/autofill_dataset_picker"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
+    android:foreground="?attr/listChoiceBackgroundIndicator"
     style="@style/AutofillDatasetPicker">
 
     <LinearLayout
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 0697c97..8b1f28b 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -139,7 +139,6 @@
             android:src="@drawable/ic_camera"
             android:background="?android:selectableItemBackgroundBorderless"
             android:visibility="gone"
-            android:clickable="false"
             android:contentDescription="@string/notification_appops_camera_active"
             />
         <ImageButton
@@ -150,7 +149,6 @@
             android:background="?android:selectableItemBackgroundBorderless"
             android:layout_marginStart="4dp"
             android:visibility="gone"
-            android:clickable="false"
             android:contentDescription="@string/notification_appops_microphone_active"
             />
         <ImageButton
@@ -161,7 +159,6 @@
             android:background="?android:selectableItemBackgroundBorderless"
             android:layout_marginStart="4dp"
             android:visibility="gone"
-            android:clickable="false"
             android:contentDescription="@string/notification_appops_overlay_active"
             />
     </LinearLayout>
diff --git a/core/res/res/values-mcc312-mnc530/config.xml b/core/res/res/values-mcc312-mnc530/config.xml
index f6aed13..413c698 100644
--- a/core/res/res/values-mcc312-mnc530/config.xml
+++ b/core/res/res/values-mcc312-mnc530/config.xml
@@ -25,6 +25,10 @@
     -->
     <integer name="config_mobile_mtu">1422</integer>
 
+    <!-- If this value is true, The mms content-disposition field is supported correctly.
+         If false, Content-disposition fragments are ignored -->
+    <bool name="config_mms_content_disposition_support">false</bool>
+
     <!-- An array of CDMA roaming indicators which means international roaming -->
     <integer-array translatable="false" name="config_cdma_international_roaming_indicators" >
         <item>2</item>
diff --git a/core/res/res/values-w195dp/dimens_material.xml b/core/res/res/values-w195dp/dimens_material.xml
new file mode 100644
index 0000000..7f3ad29
--- /dev/null
+++ b/core/res/res/values-w195dp/dimens_material.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <dimen name="screen_percentage_05">9.75dp</dimen>
+    <dimen name="screen_percentage_10">19.5dp</dimen>
+    <dimen name="screen_percentage_15">29.25dp</dimen>
+</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a353070..b0ecb3e 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -666,10 +666,13 @@
     <!-- Wifi driver supports IEEE80211AC for softap -->
     <bool translatable="false" name="config_wifi_softap_ieee80211ac_supported">false</bool>
 
-    <!-- Flag indicating whether the we should enable the automatic brightness in Settings.
+    <!-- Flag indicating whether we should enable the automatic brightness.
          Software implementation will be used if config_hardware_auto_brightness_available is not set -->
     <bool name="config_automatic_brightness_available">false</bool>
 
+    <!-- Flag indicating whether we should enable smart battery. -->
+    <bool name="config_smart_battery_available">false</bool>
+
     <!-- Fast brightness animation ramp rate in brightness units per second-->
     <integer translatable="false" name="config_brightness_ramp_rate_fast">180</integer>
 
@@ -3424,4 +3427,7 @@
     <!-- Whether or not swipe up gesture is enabled by default -->
     <bool name="config_swipe_up_gesture_default">false</bool>
 
+    <!-- Whether or not swipe up gesture's opt-in setting is available on this device -->
+    <bool name="config_swipe_up_gesture_setting_available">false</bool>
+
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fb275ba..7708911 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1836,6 +1836,7 @@
   <java-symbol type="bool" name="config_useAttentionLight" />
   <java-symbol type="bool" name="config_animateScreenLights" />
   <java-symbol type="bool" name="config_automatic_brightness_available" />
+  <java-symbol type="bool" name="config_smart_battery_available" />
   <java-symbol type="bool" name="config_autoBrightnessResetAmbientLuxAfterWarmUp" />
   <java-symbol type="bool" name="config_notificationHeaderClickableForExpand" />
   <java-symbol type="bool" name="config_enableNightMode" />
@@ -3301,6 +3302,7 @@
   <java-symbol type="string" name="shortcut_restore_unknown_issue" />
 
   <java-symbol type="bool" name="config_swipe_up_gesture_default" />
+  <java-symbol type="bool" name="config_swipe_up_gesture_setting_available" />
 
   <!-- From media projection -->
   <java-symbol type="string" name="config_mediaProjectionPermissionDialogComponent" />
@@ -3380,4 +3382,5 @@
   <java-symbol type="id" name="user_loading" />
 
   <java-symbol type="string" name="battery_saver_description_with_learn_more" />
+  <java-symbol type="drawable" name="ic_lock_lockdown" />
 </resources>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 22aca30..5b7fc6e 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -358,6 +358,7 @@
                     Settings.Global.PREFERRED_NETWORK_MODE,
                     Settings.Global.PRIV_APP_OOB_ENABLED,
                     Settings.Global.PRIV_APP_OOB_LIST,
+                    Settings.Global.PRIVATE_DNS_DEFAULT_MODE,
                     Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS,
                     Settings.Global.RADIO_BLUETOOTH,
                     Settings.Global.RADIO_CELL,
diff --git a/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java b/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java
index e750766..c4d5b0c 100644
--- a/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java
@@ -16,9 +16,9 @@
 
 package android.provider;
 
-import static org.junit.Assert.fail;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.platform.test.annotations.Presubmit;
 import android.provider.SettingsValidators.Validator;
@@ -63,6 +63,11 @@
     }
 
     @Test
+    public void testComponentNameValidator_onNullValue_doesNotThrow() {
+        assertFalse(SettingsValidators.COMPONENT_NAME_VALIDATOR.validate(null));
+    }
+
+    @Test
     public void testLocaleValidator() {
         assertTrue(SettingsValidators.LOCALE_VALIDATOR.validate("en_US"));
         assertTrue(SettingsValidators.LOCALE_VALIDATOR.validate("es"));
diff --git a/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java b/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java
new file mode 100644
index 0000000..cac4e88
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java
@@ -0,0 +1,226 @@
+/*
+ * 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.DisplayCutout.NO_CUTOUT;
+import static android.view.View.MeasureSpec.EXACTLY;
+import static android.view.View.MeasureSpec.makeMeasureSpec;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.DisplayCutout;
+import android.view.View;
+import android.view.View.OnApplyWindowInsetsListener;
+import android.view.ViewGroup;
+import android.view.WindowInsets;
+import android.widget.FrameLayout;
+import android.widget.Toolbar;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ActionBarOverlayLayoutTest {
+
+    private static final Rect TOP_INSET_5 = new Rect(0, 5, 0, 0);
+    private static final Rect TOP_INSET_25 = new Rect(0, 25, 0, 0);
+    private static final Rect ZERO_INSET = new Rect(0, 0, 0, 0);
+    private static final DisplayCutout CONSUMED_CUTOUT = null;
+    private static final DisplayCutout CUTOUT_5 = new DisplayCutout(TOP_INSET_5, Arrays.asList(
+            new Rect(100, 0, 200, 5)));
+    private static final int EXACTLY_1000 = makeMeasureSpec(1000, EXACTLY);
+
+    private Context mContext;
+    private TestActionBarOverlayLayout mLayout;
+
+    private ViewGroup mContent;
+    private ViewGroup mActionBarTop;
+    private Toolbar mToolbar;
+    private FakeOnApplyWindowListener mContentInsetsListener;
+
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+        mLayout = new TestActionBarOverlayLayout(mContext);
+        mLayout.makeOptionalFitsSystemWindows();
+
+        mContent = createViewGroupWithId(com.android.internal.R.id.content);
+        mContent.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+        mLayout.addView(mContent);
+
+        mContentInsetsListener = new FakeOnApplyWindowListener();
+        mContent.setOnApplyWindowInsetsListener(mContentInsetsListener);
+
+        mActionBarTop = new ActionBarContainer(mContext);
+        mActionBarTop.setId(com.android.internal.R.id.action_bar_container);
+        mActionBarTop.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, 20));
+        mLayout.addView(mActionBarTop);
+        mLayout.setActionBarHeight(20);
+
+        mToolbar = new Toolbar(mContext);
+        mToolbar.setId(com.android.internal.R.id.action_bar);
+        mActionBarTop.addView(mToolbar);
+    }
+
+    @Test
+    public void topInset_consumedCutout_stable() {
+        mLayout.setStable(true);
+        mLayout.dispatchApplyWindowInsets(insetsWith(TOP_INSET_5, CONSUMED_CUTOUT));
+
+        assertThat(mContentInsetsListener.captured, nullValue());
+
+        mLayout.measure(EXACTLY_1000, EXACTLY_1000);
+
+        // Action bar height is added to the top inset
+        assertThat(mContentInsetsListener.captured, is(insetsWith(TOP_INSET_25, CONSUMED_CUTOUT)));
+    }
+
+    @Test
+    public void topInset_consumedCutout_notStable() {
+        mLayout.dispatchApplyWindowInsets(insetsWith(TOP_INSET_5, CONSUMED_CUTOUT));
+
+        assertThat(mContentInsetsListener.captured, nullValue());
+
+        mLayout.measure(EXACTLY_1000, EXACTLY_1000);
+
+        assertThat(mContentInsetsListener.captured, is(insetsWith(ZERO_INSET, CONSUMED_CUTOUT)));
+    }
+
+    @Test
+    public void topInset_noCutout_stable() {
+        mLayout.setStable(true);
+        mLayout.dispatchApplyWindowInsets(insetsWith(TOP_INSET_5, NO_CUTOUT));
+
+        assertThat(mContentInsetsListener.captured, nullValue());
+
+        mLayout.measure(EXACTLY_1000, EXACTLY_1000);
+
+        // Action bar height is added to the top inset
+        assertThat(mContentInsetsListener.captured, is(insetsWith(TOP_INSET_25, NO_CUTOUT)));
+    }
+
+    @Test
+    public void topInset_noCutout_notStable() {
+        mLayout.dispatchApplyWindowInsets(insetsWith(TOP_INSET_5, NO_CUTOUT));
+
+        assertThat(mContentInsetsListener.captured, nullValue());
+
+        mLayout.measure(EXACTLY_1000, EXACTLY_1000);
+
+        assertThat(mContentInsetsListener.captured, is(insetsWith(ZERO_INSET, NO_CUTOUT)));
+    }
+
+    @Test
+    public void topInset_cutout_stable() {
+        mLayout.setStable(true);
+        mLayout.dispatchApplyWindowInsets(insetsWith(TOP_INSET_5, CUTOUT_5));
+
+        assertThat(mContentInsetsListener.captured, nullValue());
+
+        mLayout.measure(EXACTLY_1000, EXACTLY_1000);
+
+        // Action bar height is added to the top inset
+        assertThat(mContentInsetsListener.captured, is(insetsWith(TOP_INSET_25, CUTOUT_5)));
+    }
+
+    @Test
+    public void topInset_cutout_notStable() {
+        mLayout.dispatchApplyWindowInsets(insetsWith(TOP_INSET_5, CUTOUT_5));
+
+        assertThat(mContentInsetsListener.captured, nullValue());
+
+        mLayout.measure(EXACTLY_1000, EXACTLY_1000);
+
+        assertThat(mContentInsetsListener.captured, is(insetsWith(ZERO_INSET, NO_CUTOUT)));
+    }
+
+    private WindowInsets insetsWith(Rect content, DisplayCutout cutout) {
+        return new WindowInsets(content, null, null, false, false, cutout);
+    }
+
+    private ViewGroup createViewGroupWithId(int id) {
+        final FrameLayout v = new FrameLayout(mContext);
+        v.setId(id);
+        return v;
+    }
+
+    static class TestActionBarOverlayLayout extends ActionBarOverlayLayout {
+        private boolean mStable;
+
+        public TestActionBarOverlayLayout(Context context) {
+            super(context);
+        }
+
+        @Override
+        public WindowInsets computeSystemWindowInsets(WindowInsets in, Rect outLocalInsets) {
+            if (mStable) {
+                // Emulate the effect of makeOptionalFitsSystemWindows, because we can't do that
+                // without being attached to a window.
+                outLocalInsets.setEmpty();
+                return in;
+            }
+            return super.computeSystemWindowInsets(in, outLocalInsets);
+        }
+
+        void setStable(boolean stable) {
+            mStable = stable;
+            setSystemUiVisibility(stable ? SYSTEM_UI_FLAG_LAYOUT_STABLE : 0);
+        }
+
+        @Override
+        public int getWindowSystemUiVisibility() {
+            return getSystemUiVisibility();
+        }
+
+        void setActionBarHeight(int height) {
+            try {
+                final Field field = ActionBarOverlayLayout.class.getDeclaredField(
+                        "mActionBarHeight");
+                field.setAccessible(true);
+                field.setInt(this, height);
+            } catch (ReflectiveOperationException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    static class FakeOnApplyWindowListener implements OnApplyWindowInsetsListener {
+        WindowInsets captured;
+
+        @Override
+        public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
+            assertNotNull(insets);
+            captured = insets;
+            return v.onApplyWindowInsets(insets);
+        }
+    }
+}
diff --git a/data/keyboards/Vendor_054c_Product_05c4.kl b/data/keyboards/Vendor_054c_Product_05c4.kl
index f465733..a1284a4 100644
--- a/data/keyboards/Vendor_054c_Product_05c4.kl
+++ b/data/keyboards/Vendor_054c_Product_05c4.kl
@@ -62,6 +62,10 @@
 key 0x139    BUTTON_START
 
 # PS key
-key 0x13c    HOME
+key 0x13c    BUTTON_MODE
+
 # Touchpad press
-key 0x13d   BUTTON_MODE
+# The touchpad for this joystick will become a separate input device in future releases
+# and this button will be equivalent to left mouse button
+# Therefore, map it to KEYCODE_BUTTON_1 here to allow apps to still handle this on earlier versions
+key 0x13d   BUTTON_1
diff --git a/data/keyboards/Vendor_054c_Product_09cc.kl b/data/keyboards/Vendor_054c_Product_09cc.kl
index f465733..a1284a4 100644
--- a/data/keyboards/Vendor_054c_Product_09cc.kl
+++ b/data/keyboards/Vendor_054c_Product_09cc.kl
@@ -62,6 +62,10 @@
 key 0x139    BUTTON_START
 
 # PS key
-key 0x13c    HOME
+key 0x13c    BUTTON_MODE
+
 # Touchpad press
-key 0x13d   BUTTON_MODE
+# The touchpad for this joystick will become a separate input device in future releases
+# and this button will be equivalent to left mouse button
+# Therefore, map it to KEYCODE_BUTTON_1 here to allow apps to still handle this on earlier versions
+key 0x13d   BUTTON_1
diff --git a/data/sounds/AudioTv.mk b/data/sounds/AudioTv.mk
index ee37cb9..91265af 100644
--- a/data/sounds/AudioTv.mk
+++ b/data/sounds/AudioTv.mk
@@ -15,111 +15,8 @@
 LOCAL_PATH := frameworks/base/data/sounds
 
 PRODUCT_COPY_FILES += \
-    $(LOCAL_PATH)/Alarm_Beep_01.ogg:system/media/audio/alarms/Alarm_Beep_01.ogg \
-    $(LOCAL_PATH)/Alarm_Beep_02.ogg:system/media/audio/alarms/Alarm_Beep_02.ogg \
-    $(LOCAL_PATH)/Alarm_Beep_03.ogg:system/media/audio/alarms/Alarm_Beep_03.ogg \
-    $(LOCAL_PATH)/Alarm_Buzzer.ogg:system/media/audio/alarms/Alarm_Buzzer.ogg \
-    $(LOCAL_PATH)/Alarm_Classic.ogg:system/media/audio/alarms/Alarm_Classic.ogg \
-    $(LOCAL_PATH)/Alarm_Rooster_02.ogg:system/media/audio/alarms/Alarm_Rooster_02.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Argon.ogg:system/media/audio/alarms/Argon.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Barium.ogg:system/media/audio/alarms/Barium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Cesium.ogg:system/media/audio/alarms/Cesium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Fermium.ogg:system/media/audio/alarms/Fermium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Hassium.ogg:system/media/audio/alarms/Hassium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Helium.ogg:system/media/audio/alarms/Helium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Neon.ogg:system/media/audio/alarms/Neon.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Neptunium.ogg:system/media/audio/alarms/Neptunium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Nobelium.ogg:system/media/audio/alarms/Nobelium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:system/media/audio/alarms/Osmium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:system/media/audio/alarms/Platinum.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Plutonium.ogg:system/media/audio/alarms/Plutonium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Promethium.ogg:system/media/audio/alarms/Promethium.ogg \
-    $(LOCAL_PATH)/alarms/ogg/Scandium.ogg:system/media/audio/alarms/Scandium.ogg \
-    $(LOCAL_PATH)/effects/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \
-    $(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
-    $(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
-    $(LOCAL_PATH)/effects/ogg/Effect_Tick_48k.ogg:system/media/audio/ui/Effect_Tick.ogg \
     $(LOCAL_PATH)/effects/ogg/KeypressDelete_120_48k.ogg:system/media/audio/ui/KeypressDelete.ogg \
     $(LOCAL_PATH)/effects/ogg/KeypressInvalid_120_48k.ogg:system/media/audio/ui/KeypressInvalid.ogg \
     $(LOCAL_PATH)/effects/ogg/KeypressReturn_120_48k.ogg:system/media/audio/ui/KeypressReturn.ogg \
     $(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120_48k.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
-    $(LOCAL_PATH)/effects/ogg/KeypressStandard_120_48k.ogg:system/media/audio/ui/KeypressStandard.ogg \
-    $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
-    $(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
-    $(LOCAL_PATH)/effects/ogg/Trusted_48k.ogg:system/media/audio/ui/Trusted.ogg \
-    $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
-    $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
-    $(LOCAL_PATH)/effects/ogg/VideoRecord_48k.ogg:system/media/audio/ui/VideoRecord.ogg \
-    $(LOCAL_PATH)/effects/ogg/VideoStop_48k.ogg:system/media/audio/ui/VideoStop.ogg \
-    $(LOCAL_PATH)/effects/ogg/WirelessChargingStarted.ogg:system/media/audio/ui/WirelessChargingStarted.ogg \
-    $(LOCAL_PATH)/F1_MissedCall.ogg:system/media/audio/notifications/F1_MissedCall.ogg \
-    $(LOCAL_PATH)/F1_New_MMS.ogg:system/media/audio/notifications/F1_New_MMS.ogg \
-    $(LOCAL_PATH)/F1_New_SMS.ogg:system/media/audio/notifications/F1_New_SMS.ogg \
-    $(LOCAL_PATH)/notifications/Aldebaran.ogg:system/media/audio/notifications/Aldebaran.ogg \
-    $(LOCAL_PATH)/notifications/Altair.ogg:system/media/audio/notifications/Altair.ogg \
-    $(LOCAL_PATH)/notifications/Antares.ogg:system/media/audio/notifications/Antares.ogg \
-    $(LOCAL_PATH)/notifications/arcturus.ogg:system/media/audio/notifications/arcturus.ogg \
-    $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg:system/media/audio/notifications/Beat_Box_Android.ogg \
-    $(LOCAL_PATH)/notifications/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \
-    $(LOCAL_PATH)/notifications/Canopus.ogg:system/media/audio/notifications/Canopus.ogg \
-    $(LOCAL_PATH)/notifications/Castor.ogg:system/media/audio/notifications/Castor.ogg \
-    $(LOCAL_PATH)/notifications/Cricket.ogg:system/media/audio/notifications/Cricket.ogg \
-    $(LOCAL_PATH)/notifications/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \
-    $(LOCAL_PATH)/notifications/Doink.ogg:system/media/audio/notifications/Doink.ogg \
-    $(LOCAL_PATH)/notifications/Drip.ogg:system/media/audio/notifications/Drip.ogg \
-    $(LOCAL_PATH)/notifications/Electra.ogg:system/media/audio/notifications/Electra.ogg \
-    $(LOCAL_PATH)/notifications/Fomalhaut.ogg:system/media/audio/notifications/Fomalhaut.ogg \
-    $(LOCAL_PATH)/notifications/Heaven.ogg:system/media/audio/notifications/Heaven.ogg \
-    $(LOCAL_PATH)/notifications/Merope.ogg:system/media/audio/notifications/Merope.ogg \
-    $(LOCAL_PATH)/notifications/moonbeam.ogg:system/media/audio/notifications/moonbeam.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Antimony.ogg:system/media/audio/notifications/Antimony.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Argon.ogg:system/media/audio/notifications/Argon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:system/media/audio/notifications/Bellatrix.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Beryllium.ogg:system/media/audio/notifications/Beryllium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \
-    $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Cobalt.ogg:system/media/audio/notifications/Cobalt.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Fluorine.ogg:system/media/audio/notifications/Fluorine.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Gallium.ogg:system/media/audio/notifications/Gallium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Helium.ogg:system/media/audio/notifications/Helium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Iridium.ogg:system/media/audio/notifications/Iridium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Krypton.ogg:system/media/audio/notifications/Krypton.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Palladium.ogg:system/media/audio/notifications/Palladium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Radon.ogg:system/media/audio/notifications/Radon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Rubidium.ogg:system/media/audio/notifications/Rubidium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Selenium.ogg:system/media/audio/notifications/Selenium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Strontium.ogg:system/media/audio/notifications/Strontium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Syrma.ogg:system/media/audio/notifications/Syrma.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Talitha.ogg:system/media/audio/notifications/Talitha.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Thallium.ogg:system/media/audio/notifications/Thallium.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Xenon.ogg:system/media/audio/notifications/Xenon.ogg \
-    $(LOCAL_PATH)/notifications/ogg/Zirconium.ogg:system/media/audio/notifications/Zirconium.ogg \
-    $(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \
-    $(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \
-    $(LOCAL_PATH)/notifications/Plastic_Pipe.ogg:system/media/audio/notifications/Plastic_Pipe.ogg \
-    $(LOCAL_PATH)/notifications/regulus.ogg:system/media/audio/notifications/regulus.ogg \
-    $(LOCAL_PATH)/notifications/sirius.ogg:system/media/audio/notifications/sirius.ogg \
-    $(LOCAL_PATH)/notifications/Sirrah.ogg:system/media/audio/notifications/Sirrah.ogg \
-    $(LOCAL_PATH)/notifications/SpaceSeed.ogg:system/media/audio/notifications/SpaceSeed.ogg \
-    $(LOCAL_PATH)/notifications/TaDa.ogg:system/media/audio/notifications/TaDa.ogg \
-    $(LOCAL_PATH)/notifications/Tinkerbell.ogg:system/media/audio/notifications/Tinkerbell.ogg \
-    $(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg \
-    $(LOCAL_PATH)/notifications/vega.ogg:system/media/audio/notifications/vega.ogg
+    $(LOCAL_PATH)/effects/ogg/KeypressStandard_120_48k.ogg:system/media/audio/ui/KeypressStandard.ogg
diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
index 898939e..4f467d9 100644
--- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
@@ -31,6 +31,7 @@
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.TypedValue;
@@ -348,7 +349,7 @@
             if (mRunnable == null) {
                 mRunnable = this::invalidateSelf;
             }
-            scheduleSelf(mRunnable, nextUpdate);
+            scheduleSelf(mRunnable, nextUpdate + SystemClock.uptimeMillis());
         } else if (nextUpdate == FINISHED) {
             // This means the animation was drawn in software mode and ended.
             postOnAnimationEnd();
@@ -430,23 +431,6 @@
         return mState.mAutoMirrored;
     }
 
-    @Override
-    public boolean setVisible(boolean visible, boolean restart) {
-        if (!super.setVisible(visible, restart)) {
-            return false;
-        }
-
-        if (mState.mNativePtr == 0) {
-            throw new IllegalStateException("called setVisible on empty AnimatedImageDrawable");
-        }
-
-        if (!visible) {
-            nMarkInvisible(mState.mNativePtr);
-        }
-
-        return true;
-    }
-
     // Animatable overrides
     /**
      *  Return whether the animation is currently running.
@@ -616,7 +600,5 @@
     @FastNative
     private static native long nNativeByteSize(long nativePtr);
     @FastNative
-    private static native void nMarkInvisible(long nativePtr);
-    @FastNative
     private static native void nSetMirrored(long nativePtr, boolean mirror);
 }
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java
index cc80560..624321c 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java
@@ -48,6 +48,8 @@
     private static final String KEYSTORE_PUBLIC_KEY_CLASS_NAME =
             PACKAGE_NAME + ".AndroidKeyStorePublicKey";
 
+    private static final String DESEDE_SYSTEM_PROPERTY = "ro.hardware.keystore_desede";
+
     AndroidKeyStoreBCWorkaroundProvider() {
         super("AndroidKeyStoreBCWorkaround",
                 1.0,
@@ -93,7 +95,7 @@
         putSymmetricCipherImpl("AES/CTR/NoPadding",
                 PACKAGE_NAME + ".AndroidKeyStoreUnauthenticatedAESCipherSpi$CTR$NoPadding");
 
-        if ("true".equals(System.getProperty("supports3DES"))) {
+        if ("true".equals(android.os.SystemProperties.get(DESEDE_SYSTEM_PROPERTY))) {
             putSymmetricCipherImpl("DESede/CBC/NoPadding",
                 PACKAGE_NAME + ".AndroidKeyStore3DESCipherSpi$CBC$NoPadding");
             putSymmetricCipherImpl("DESede/CBC/PKCS7Padding",
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
index 9b7695d..c048e82 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
@@ -64,10 +64,13 @@
 
     private static final String PACKAGE_NAME = "android.security.keystore";
 
+    private static final String DESEDE_SYSTEM_PROPERTY =
+            "ro.hardware.keystore_desede";
+
     public AndroidKeyStoreProvider() {
         super(PROVIDER_NAME, 1.0, "Android KeyStore security provider");
 
-        boolean supports3DES = "true".equals(System.getProperty("supports3DES"));
+        boolean supports3DES = "true".equals(android.os.SystemProperties.get(DESEDE_SYSTEM_PROPERTY));
 
         // java.security.KeyStore
         put("KeyStore.AndroidKeyStore", PACKAGE_NAME + ".AndroidKeyStoreSpi");
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index 3e9853c..2b5a37b 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -353,6 +353,10 @@
             if (spec.isCriticalToDeviceEncryption()) {
                 flags |= KeyStore.FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
             }
+
+            if (spec.isStrongBoxBacked()) {
+                flags |= KeyStore.FLAG_STRONGBOX;
+            }
         } else {
             throw new KeyStoreException(
                     "Unsupported protection parameter class:" + param.getClass().getName()
@@ -720,6 +724,9 @@
         if (params.isCriticalToDeviceEncryption()) {
             flags |= KeyStore.FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
         }
+        if (params.isStrongBoxBacked()) {
+            flags |= KeyStore.FLAG_STRONGBOX;
+        }
 
         Credentials.deleteAllTypesForAlias(mKeyStore, entryAlias, mUid);
         String keyAliasInKeystore = Credentials.USER_PRIVATE_KEY + entryAlias;
@@ -737,19 +744,76 @@
         }
     }
 
-    private void setWrappedKeyEntry(String alias, byte[] wrappedKeyBytes, String wrappingKeyAlias,
+    private void setWrappedKeyEntry(String alias, WrappedKeyEntry entry,
             java.security.KeyStore.ProtectionParameter param) throws KeyStoreException {
         if (param != null) {
             throw new KeyStoreException("Protection parameters are specified inside wrapped keys");
         }
 
         byte[] maskingKey = new byte[32];
-        KeymasterArguments args = new KeymasterArguments(); // TODO: populate wrapping key args.
+
+
+        KeymasterArguments args = new KeymasterArguments();
+        String[] parts = entry.getTransformation().split("/");
+
+        String algorithm = parts[0];
+        if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(algorithm)) {
+            args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
+        } else if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(algorithm)) {
+            args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
+        }
+
+        if (parts.length > 1) {
+            String mode = parts[1];
+            if (KeyProperties.BLOCK_MODE_ECB.equalsIgnoreCase(mode)) {
+                args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
+            } else if (KeyProperties.BLOCK_MODE_CBC.equalsIgnoreCase(mode)) {
+                args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CBC);
+            } else if (KeyProperties.BLOCK_MODE_CTR.equalsIgnoreCase(mode)) {
+                args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_CTR);
+            } else if (KeyProperties.BLOCK_MODE_GCM.equalsIgnoreCase(mode)) {
+                args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_GCM);
+            }
+        }
+
+        if (parts.length > 2) {
+            String padding = parts[2];
+            if (KeyProperties.ENCRYPTION_PADDING_NONE.equalsIgnoreCase(padding)) {
+                // Noop
+            } else if (KeyProperties.ENCRYPTION_PADDING_PKCS7.equalsIgnoreCase(padding)) {
+                args.addEnums(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_PKCS7);
+            } else if (KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1.equalsIgnoreCase(padding)) {
+                args.addEnums(KeymasterDefs.KM_TAG_PADDING,
+                    KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
+            } else if (KeyProperties.ENCRYPTION_PADDING_RSA_OAEP.equalsIgnoreCase(padding)) {
+                args.addEnums(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_RSA_OAEP);
+            }
+        }
+
+        KeyGenParameterSpec spec = (KeyGenParameterSpec) entry.getAlgorithmParameterSpec();
+        if (spec.isDigestsSpecified()) {
+            String digest = spec.getDigests()[0];
+            if (KeyProperties.DIGEST_NONE.equalsIgnoreCase(digest)) {
+                // Noop
+            } else if (KeyProperties.DIGEST_MD5.equalsIgnoreCase(digest)) {
+                args.addEnums(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_MD5);
+            } else if (KeyProperties.DIGEST_SHA1.equalsIgnoreCase(digest)) {
+                args.addEnums(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA1);
+            } else if (KeyProperties.DIGEST_SHA224.equalsIgnoreCase(digest)) {
+                args.addEnums(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_224);
+            } else if (KeyProperties.DIGEST_SHA256.equalsIgnoreCase(digest)) {
+                args.addEnums(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_256);
+            } else if (KeyProperties.DIGEST_SHA384.equalsIgnoreCase(digest)) {
+                args.addEnums(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_384);
+            } else if (KeyProperties.DIGEST_SHA512.equalsIgnoreCase(digest)) {
+                args.addEnums(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_512);
+            }
+        }
 
         int errorCode = mKeyStore.importWrappedKey(
             Credentials.USER_SECRET_KEY + alias,
-            wrappedKeyBytes,
-            Credentials.USER_PRIVATE_KEY + wrappingKeyAlias,
+            entry.getWrappedKeyBytes(),
+            Credentials.USER_PRIVATE_KEY + entry.getWrappingKeyAlias(),
             maskingKey,
             args,
             GateKeeper.getSecureUserId(),
@@ -996,7 +1060,7 @@
             setSecretKeyEntry(alias, secE.getSecretKey(), param);
         } else if (entry instanceof WrappedKeyEntry) {
             WrappedKeyEntry wke = (WrappedKeyEntry) entry;
-            setWrappedKeyEntry(alias, wke.getWrappedKeyBytes(), wke.getWrappingKeyAlias(), param);
+            setWrappedKeyEntry(alias, wke, param);
         } else {
             throw new KeyStoreException(
                     "Entry must be a PrivateKeyEntry, SecretKeyEntry or TrustedCertificateEntry"
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index fdcad85..081042b 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -232,6 +232,7 @@
     private final boolean mCriticalToDeviceEncryption;
     private final boolean mUserConfirmationRequired;
     private final boolean mUnlockedDeviceRequired;
+    private final boolean mIsStrongBoxBacked;
 
     private KeyProtection(
             Date keyValidityStart,
@@ -251,7 +252,8 @@
             long boundToSecureUserId,
             boolean criticalToDeviceEncryption,
             boolean userConfirmationRequired,
-            boolean unlockedDeviceRequired) {
+            boolean unlockedDeviceRequired,
+            boolean isStrongBoxBacked) {
         mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
         mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
         mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
@@ -272,6 +274,7 @@
         mCriticalToDeviceEncryption = criticalToDeviceEncryption;
         mUserConfirmationRequired = userConfirmationRequired;
         mUnlockedDeviceRequired = unlockedDeviceRequired;
+        mIsStrongBoxBacked = isStrongBoxBacked;
     }
 
     /**
@@ -529,6 +532,14 @@
     }
 
     /**
+     * Returns {@code true} if the key is protected by a Strongbox security chip.
+     * @hide
+     */
+    public boolean isStrongBoxBacked() {
+        return mIsStrongBoxBacked;
+    }
+
+    /**
      * Builder of {@link KeyProtection} instances.
      */
     public final static class Builder {
@@ -552,6 +563,7 @@
 
         private long mBoundToSecureUserId = GateKeeper.INVALID_SECURE_USER_ID;
         private boolean mCriticalToDeviceEncryption = false;
+        private boolean mIsStrongBoxBacked = false;
 
         /**
          * Creates a new instance of the {@code Builder}.
@@ -962,6 +974,16 @@
         }
 
         /**
+         * Sets whether this key should be protected by a StrongBox security chip.
+         * @hide
+         */
+        @NonNull
+        public Builder setIsStrongBoxBacked(boolean isStrongBoxBacked) {
+            mIsStrongBoxBacked = isStrongBoxBacked;
+            return this;
+        }
+
+        /**
          * Builds an instance of {@link KeyProtection}.
          *
          * @throws IllegalArgumentException if a required field is missing
@@ -986,7 +1008,8 @@
                     mBoundToSecureUserId,
                     mCriticalToDeviceEncryption,
                     mUserConfirmationRequired,
-                    mUnlockedDeviceRequired);
+                    mUnlockedDeviceRequired,
+                    mIsStrongBoxBacked);
         }
     }
 }
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index d701269..b37f2cf 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -108,6 +108,12 @@
         // *OR* will post itself for the next vsync automatically, use this
         // only to avoid calling draw()
         bool canDrawThisFrame = true;
+        // Sentinel for animatedImageDelay meaning there is no need to post such
+        // a message.
+        static constexpr nsecs_t kNoAnimatedImageDelay = -1;
+        // This is used to post a message to redraw when it is time to draw the
+        // next frame of an AnimatedImageDrawable.
+        nsecs_t animatedImageDelay = kNoAnimatedImageDelay;
     } out;
 
     // This flag helps to disable projection for receiver nodes that do not have any backward
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.cpp b/libs/hwui/hwui/AnimatedImageDrawable.cpp
index c529f87..007961a 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.cpp
+++ b/libs/hwui/hwui/AnimatedImageDrawable.cpp
@@ -22,13 +22,12 @@
 #include <SkPicture.h>
 #include <SkRefCnt.h>
 #include <SkTLazy.h>
-#include <SkTime.h>
 
 namespace android {
 
 AnimatedImageDrawable::AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage, size_t bytesUsed)
         : mSkAnimatedImage(std::move(animatedImage)), mBytesUsed(bytesUsed) {
-    mTimeToShowNextSnapshot = mSkAnimatedImage->currentFrameDuration();
+    mTimeToShowNextSnapshot = ms2ns(mSkAnimatedImage->currentFrameDuration());
 }
 
 void AnimatedImageDrawable::syncProperties() {
@@ -62,28 +61,42 @@
 }
 
 // Only called on the RenderThread while UI thread is locked.
-bool AnimatedImageDrawable::isDirty() {
-    const double currentTime = SkTime::GetMSecs();
-    const double lastWallTime = mLastWallTime;
+bool AnimatedImageDrawable::isDirty(nsecs_t* outDelay) {
+    *outDelay = 0;
+    const nsecs_t currentTime = systemTime(CLOCK_MONOTONIC);
+    const nsecs_t lastWallTime = mLastWallTime;
 
     mLastWallTime = currentTime;
     if (!mRunning) {
-        mDidDraw = false;
         return false;
     }
 
     std::unique_lock lock{mSwapLock};
-    if (mDidDraw) {
-        mCurrentTime += currentTime - lastWallTime;
-        mDidDraw = false;
-    }
+    mCurrentTime += currentTime - lastWallTime;
 
     if (!mNextSnapshot.valid()) {
         // Need to trigger onDraw in order to start decoding the next frame.
+        *outDelay = mTimeToShowNextSnapshot - mCurrentTime;
         return true;
     }
 
-    return nextSnapshotReady() && mCurrentTime >= mTimeToShowNextSnapshot;
+    if (mTimeToShowNextSnapshot > mCurrentTime) {
+        *outDelay = mTimeToShowNextSnapshot - mCurrentTime;
+    } else if (nextSnapshotReady()) {
+        // We have not yet updated mTimeToShowNextSnapshot. Read frame duration
+        // directly from mSkAnimatedImage.
+        lock.unlock();
+        std::unique_lock imageLock{mImageLock};
+        *outDelay = ms2ns(mSkAnimatedImage->currentFrameDuration());
+        return true;
+    } else {
+        // The next snapshot has not yet been decoded, but we've already passed
+        // time to draw it. There's not a good way to know when decoding will
+        // finish, so request an update immediately.
+        *outDelay = 0;
+    }
+
+    return false;
 }
 
 // Only called on the AnimatedImageThread.
@@ -91,7 +104,7 @@
     Snapshot snap;
     {
         std::unique_lock lock{mImageLock};
-        snap.mDuration = mSkAnimatedImage->decodeNextFrame();
+        snap.mDurationMS = mSkAnimatedImage->decodeNextFrame();
         snap.mPic.reset(mSkAnimatedImage->newPictureSnapshot());
     }
 
@@ -105,7 +118,7 @@
         std::unique_lock lock{mImageLock};
         mSkAnimatedImage->reset();
         snap.mPic.reset(mSkAnimatedImage->newPictureSnapshot());
-        snap.mDuration = mSkAnimatedImage->currentFrameDuration();
+        snap.mDurationMS = mSkAnimatedImage->currentFrameDuration();
     }
 
     return snap;
@@ -127,8 +140,6 @@
         canvas->scale(-1, 1);
     }
 
-    mDidDraw = true;
-
     const bool starting = mStarting;
     mStarting = false;
 
@@ -157,12 +168,12 @@
         std::unique_lock lock{mSwapLock};
         if (mCurrentTime >= mTimeToShowNextSnapshot) {
             mSnapshot = mNextSnapshot.get();
-            const double timeToShowCurrentSnap = mTimeToShowNextSnapshot;
-            if (mSnapshot.mDuration == SkAnimatedImage::kFinished) {
+            const nsecs_t timeToShowCurrentSnap = mTimeToShowNextSnapshot;
+            if (mSnapshot.mDurationMS == SkAnimatedImage::kFinished) {
                 finalFrame = true;
                 mRunning = false;
             } else {
-                mTimeToShowNextSnapshot += mSnapshot.mDuration;
+                mTimeToShowNextSnapshot += ms2ns(mSnapshot.mDurationMS);
                 if (mCurrentTime >= mTimeToShowNextSnapshot) {
                     // This would mean showing the current frame very briefly. It's
                     // possible that not being displayed for a time resulted in
@@ -192,7 +203,7 @@
     }
 }
 
-double AnimatedImageDrawable::drawStaging(SkCanvas* canvas) {
+int AnimatedImageDrawable::drawStaging(SkCanvas* canvas) {
     SkAutoCanvasRestore acr(canvas, false);
     if (mStagingProperties.mAlpha != SK_AlphaOPAQUE || mStagingProperties.mColorFilter.get()) {
         SkPaint paint;
@@ -211,69 +222,69 @@
         // to redraw.
         std::unique_lock lock{mImageLock};
         canvas->drawDrawable(mSkAnimatedImage.get());
-        return 0.0;
+        return 0;
     }
 
     if (mStarting) {
         mStarting = false;
-        double duration = 0.0;
+        int durationMS = 0;
         {
             std::unique_lock lock{mImageLock};
             mSkAnimatedImage->reset();
-            duration = mSkAnimatedImage->currentFrameDuration();
+            durationMS = mSkAnimatedImage->currentFrameDuration();
         }
         {
             std::unique_lock lock{mSwapLock};
-            mLastWallTime = 0.0;
-            mTimeToShowNextSnapshot = duration;
+            mLastWallTime = 0;
+            // The current time will be added later, below.
+            mTimeToShowNextSnapshot = ms2ns(durationMS);
         }
     }
 
     bool update = false;
     {
-        const double currentTime = SkTime::GetMSecs();
+        const nsecs_t currentTime = systemTime(CLOCK_MONOTONIC);
         std::unique_lock lock{mSwapLock};
         // mLastWallTime starts off at 0. If it is still 0, just update it to
         // the current time and avoid updating
-        if (mLastWallTime == 0.0) {
+        if (mLastWallTime == 0) {
             mCurrentTime = currentTime;
             // mTimeToShowNextSnapshot is already set to the duration of the
             // first frame.
             mTimeToShowNextSnapshot += currentTime;
-        } else if (mRunning && mDidDraw) {
+        } else if (mRunning) {
             mCurrentTime += currentTime - mLastWallTime;
             update = mCurrentTime >= mTimeToShowNextSnapshot;
         }
         mLastWallTime = currentTime;
     }
 
-    double duration = 0.0;
+    int durationMS = 0;
     {
         std::unique_lock lock{mImageLock};
         if (update) {
-            duration = mSkAnimatedImage->decodeNextFrame();
+            durationMS = mSkAnimatedImage->decodeNextFrame();
         }
 
         canvas->drawDrawable(mSkAnimatedImage.get());
     }
 
-    mDidDraw = true;
-
     std::unique_lock lock{mSwapLock};
     if (update) {
-        if (duration == SkAnimatedImage::kFinished) {
+        if (durationMS == SkAnimatedImage::kFinished) {
             mRunning = false;
-            return duration;
+            return SkAnimatedImage::kFinished;
         }
 
-        const double timeToShowCurrentSnapshot = mTimeToShowNextSnapshot;
-        mTimeToShowNextSnapshot += duration;
+        const nsecs_t timeToShowCurrentSnapshot = mTimeToShowNextSnapshot;
+        mTimeToShowNextSnapshot += ms2ns(durationMS);
         if (mCurrentTime >= mTimeToShowNextSnapshot) {
             // As in onDraw, prevent speedy catch-up behavior.
             mCurrentTime = timeToShowCurrentSnapshot;
         }
     }
-    return mTimeToShowNextSnapshot;
+
+    return ns2ms(mTimeToShowNextSnapshot - mCurrentTime);
 }
 
 }  // namespace android
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.h b/libs/hwui/hwui/AnimatedImageDrawable.h
index a92b62d..115c45a 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.h
+++ b/libs/hwui/hwui/AnimatedImageDrawable.h
@@ -19,6 +19,7 @@
 #include <cutils/compiler.h>
 #include <utils/Macros.h>
 #include <utils/RefBase.h>
+#include <utils/Timers.h>
 
 #include <SkAnimatedImage.h>
 #include <SkCanvas.h>
@@ -50,12 +51,15 @@
     AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage, size_t bytesUsed);
 
     /**
-     * This updates the internal time and returns true if the animation needs
-     * to be redrawn.
+     * This updates the internal time and returns true if the image needs
+     * to be redrawn this frame.
      *
      * This is called on RenderThread, while the UI thread is locked.
+     *
+     * @param outDelay Nanoseconds in the future when the following frame
+     *      will need to be drawn. 0 if not running.
      */
-    bool isDirty();
+    bool isDirty(nsecs_t* outDelay);
 
     int getStagingAlpha() const { return mStagingProperties.mAlpha; }
     void setStagingAlpha(int alpha) { mStagingProperties.mAlpha = alpha; }
@@ -68,7 +72,9 @@
     virtual SkRect onGetBounds() override { return mSkAnimatedImage->getBounds(); }
 
     // Draw to software canvas, and return time to next draw.
-    double drawStaging(SkCanvas* canvas);
+    // 0 means the animation is not running.
+    // -1 means the animation advanced to the final frame.
+    int drawStaging(SkCanvas* canvas);
 
     // Returns true if the animation was started; false otherwise (e.g. it was
     // already running)
@@ -84,11 +90,9 @@
         mEndListener = std::move(listener);
     }
 
-    void markInvisible() { mDidDraw = false; }
-
     struct Snapshot {
         sk_sp<SkPicture> mPic;
-        int mDuration;
+        int mDurationMS;
 
         Snapshot() = default;
 
@@ -124,16 +128,13 @@
     bool nextSnapshotReady() const;
 
     // When to switch from mSnapshot to mNextSnapshot.
-    double mTimeToShowNextSnapshot = 0.0;
+    nsecs_t mTimeToShowNextSnapshot = 0;
 
     // The current time for the drawable itself.
-    double mCurrentTime = 0.0;
+    nsecs_t mCurrentTime = 0;
 
     // The wall clock of the last time we called isDirty.
-    double mLastWallTime = 0.0;
-
-    // Whether we drew since the last call to isDirty.
-    bool mDidDraw = false;
+    nsecs_t mLastWallTime = 0;
 
     // Locked when assigning snapshots and times. Operations while this is held
     // should be short.
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index aa14699..82179a3 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -93,12 +93,18 @@
 
     bool isDirty = false;
     for (auto& animatedImage : mAnimatedImages) {
+        nsecs_t timeTilNextFrame = TreeInfo::Out::kNoAnimatedImageDelay;
         // If any animated image in the display list needs updated, then damage the node.
-        if (animatedImage->isDirty()) {
+        if (animatedImage->isDirty(&timeTilNextFrame)) {
             isDirty = true;
         }
-        if (animatedImage->isRunning()) {
-            info.out.hasAnimations = true;
+
+        if (animatedImage->isRunning() &&
+            timeTilNextFrame != TreeInfo::Out::kNoAnimatedImageDelay) {
+            auto& delay = info.out.animatedImageDelay;
+            if (delay == TreeInfo::Out::kNoAnimatedImageDelay || timeTilNextFrame < delay) {
+                delay = timeTilNextFrame;
+            }
         }
     }
 
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f4d8051..2ddf55b 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -140,6 +140,7 @@
                              IContextFactory* contextFactory,
                              std::unique_ptr<IRenderPipeline> renderPipeline)
         : mRenderThread(thread)
+        , mGenerationID(0)
         , mOpaque(!translucent)
         , mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord()))
         , mJankTracker(&thread.globalProfileData(), thread.mainDisplayInfo())
@@ -196,6 +197,7 @@
         mSwapHistory.clear();
     } else {
         mRenderThread.removeFrameCallback(this);
+        mGenerationID++;
     }
 }
 
@@ -204,6 +206,7 @@
 }
 
 bool CanvasContext::pauseSurface() {
+    mGenerationID++;
     return mRenderThread.removeFrameCallback(this);
 }
 
@@ -211,6 +214,7 @@
     if (mStopped != stopped) {
         mStopped = stopped;
         if (mStopped) {
+            mGenerationID++;
             mRenderThread.removeFrameCallback(this);
             mRenderPipeline->onStop();
         } else if (mIsDirty && hasSurface()) {
@@ -383,6 +387,7 @@
         mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
     }
 
+    bool postedFrameCallback = false;
     if (info.out.hasAnimations || !info.out.canDrawThisFrame) {
         if (CC_UNLIKELY(!Properties::enableRTAnimations)) {
             info.out.requiresUiRedraw = true;
@@ -391,6 +396,24 @@
             // If animationsNeedsRedraw is set don't bother posting for an RT anim
             // as we will just end up fighting the UI thread.
             mRenderThread.postFrameCallback(this);
+            postedFrameCallback = true;
+        }
+    }
+
+    if (!postedFrameCallback &&
+        info.out.animatedImageDelay != TreeInfo::Out::kNoAnimatedImageDelay) {
+        // Subtract the time of one frame so it can be displayed on time.
+        const nsecs_t kFrameTime = mRenderThread.timeLord().frameIntervalNanos();
+        if (info.out.animatedImageDelay <= kFrameTime) {
+            mRenderThread.postFrameCallback(this);
+        } else {
+            const auto delay = info.out.animatedImageDelay - kFrameTime;
+            int genId = mGenerationID;
+            mRenderThread.queue().postDelayed(delay, [this, genId]() {
+                if (mGenerationID == genId) {
+                    mRenderThread.postFrameCallback(this);
+                }
+            });
         }
     }
 }
@@ -398,6 +421,7 @@
 void CanvasContext::stopDrawing() {
     mRenderThread.removeFrameCallback(this);
     mAnimationContext->pauseAnimators();
+    mGenerationID++;
 }
 
 void CanvasContext::notifyFramePending() {
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index c2cc72a..e52b644 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -213,6 +213,9 @@
     // stopped indicates the CanvasContext will reject actual redraw operations,
     // and defer repaint until it is un-stopped
     bool mStopped = false;
+    // Incremented each time the CanvasContext is stopped. Used to ignore
+    // delayed messages that are triggered after stopping.
+    int mGenerationID;
     // CanvasContext is dirty if it has received an update that it has not
     // painted onto its surface.
     bool mIsDirty = false;
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 778e768..60df514 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -95,6 +95,7 @@
     // Grab a copy of everything we need
     CanvasContext* context = mContext;
     std::function<void(int64_t)> callback = std::move(mFrameCallback);
+    mFrameCallback = nullptr;
 
     // From this point on anything in "this" is *UNSAFE TO ACCESS*
     if (canUnblockUiThread) {
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 1f00c78..02bf4e3 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -1584,6 +1584,20 @@
      */
     public static final int BUFFER_FLAG_PARTIAL_FRAME = 8;
 
+    /**
+     * This indicates that the buffer contains non-media data for the
+     * muxer to process.
+     *
+     * All muxer data should start with a FOURCC header that determines the type of data.
+     *
+     * For example, when it contains Exif data sent to a MediaMuxer track of
+     * {@link MediaFormat#MIMETYPE_IMAGE_ANDROID_HEIC} type, the data must start with
+     * Exif header ("Exif\0\0"), followed by the TIFF header (See JEITA CP-3451C Section 4.5.2.)
+     *
+     * @hide
+     */
+    public static final int BUFFER_FLAG_MUXER_DATA = 16;
+
     /** @hide */
     @IntDef(
         flag = true,
@@ -1593,6 +1607,7 @@
             BUFFER_FLAG_CODEC_CONFIG,
             BUFFER_FLAG_END_OF_STREAM,
             BUFFER_FLAG_PARTIAL_FRAME,
+            BUFFER_FLAG_MUXER_DATA,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface BufferFlag {}
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 384326f..7c68b55 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -87,7 +87,7 @@
  * <tr><td>{@link #KEY_AAC_DRC_ATTENUATION_FACTOR}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the DRC attenuation factor.</td></tr>
  * <tr><td>{@link #KEY_AAC_DRC_HEAVY_COMPRESSION}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies whether to use heavy compression.</td></tr>
  * <tr><td>{@link #KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the maximum number of channels the decoder outputs.</td></tr>
- * <tr><td>{@link #KEY_AAC_DRC_EFFECT_TYPE}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the DRC effect type to use.</td></tr>
+ * <tr><td>{@link #KEY_AAC_DRC_EFFECT_TYPE}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the MPEG-D DRC effect type to use.</td></tr>
  * <tr><td>{@link #KEY_CHANNEL_MASK}</td><td>Integer</td><td>optional, a mask of audio channel assignments</td></tr>
  * <tr><td>{@link #KEY_FLAC_COMPRESSION_LEVEL}</td><td>Integer</td><td><b>encoder-only</b>, optional, if content is FLAC audio, specifies the desired compression level.</td></tr>
  * </table>
@@ -515,9 +515,12 @@
      * The gain is derived as the difference between the Target Reference Level and the
      * Program Reference Level. The latter can be given in the bitstream and indicates the actual
      * loudness value of the program item.
+     * <p>The Target Reference Level controls loudness normalization for both MPEG-4 DRC and
+     * MPEG-D DRC.
      * <p>The value is given as an integer value between
-     * 0 and 127, and is calculated as -0.25 * Target Reference Level in dBFS.
-     * Therefore, it represents the range of Full Scale (0 dBFS) to -31.75 dBFS.
+     * 40 and 127, and is calculated as -4 * Target Reference Level in LKFS.
+     * Therefore, it represents the range of -10 to -31.75 LKFS.
+     * <p>The default value on mobile devices is 64 (-16 LKFS).
      * <p>This key is only used during decoding.
      */
     public static final String KEY_AAC_DRC_TARGET_REFERENCE_LEVEL = "aac-target-ref-level";
@@ -542,19 +545,18 @@
      * clipping<br>
      * The value 6 (General compression) can be used for enabling MPEG-D DRC without particular
      * DRC effect type request.<br>
-     * The default is DRC effect type "None".
+     * The default DRC effect type is 3 ("Limited playback range") on mobile devices.
      * <p>This key is only used during decoding.
      */
     public static final String KEY_AAC_DRC_EFFECT_TYPE = "aac-drc-effect-type";
 
     /**
      * A key describing the target reference level that was assumed at the encoder for
-     * calculation of attenuation gains for clipping prevention. This information can be provided
-     * if it is known, otherwise a worst-case assumption is used.
-     * <p>The value is given as an integer value between
-     * 0 and 127, and is calculated as -0.25 * Target Reference Level in dBFS.
-     * Therefore, it represents the range of Full Scale (0 dBFS) to -31.75 dBFS.
-     * The default value is the worst-case assumption of 127.
+     * calculation of attenuation gains for clipping prevention.
+     * <p>If it is known, this information can be provided as an integer value between
+     * 0 and 127, which is calculated as -4 * Encoded Target Level in LKFS.
+     * If the Encoded Target Level is unknown, the value can be set to -1.
+     * <p>The default value is -1 (unknown).
      * <p>The value is ignored when heavy compression is used (see
      * {@link #KEY_AAC_DRC_HEAVY_COMPRESSION}).
      * <p>This key is only used during decoding.
@@ -576,11 +578,12 @@
      * factor is used to enable the negative gains, to prevent loud signal from surprising
      * the listener. In applications which generally need a low dynamic range, both the boost factor
      * and the attenuation factor are used in order to enable all DRC gains.
-     * <p>In order to prevent clipping, it is also recommended to apply the attenuation factors
+     * <p>In order to prevent clipping, it is also recommended to apply the attenuation gains
      * in case of a downmix and/or loudness normalization to high target reference levels.
      * <p>Both the boost and the attenuation factor parameters are given as integer values
      * between 0 and 127, representing the range of the factor of 0 (i.e. don't apply)
-     * to 1 (i.e. fully apply boost/attenuation factors respectively).
+     * to 1 (i.e. fully apply boost/attenuation gains respectively).
+     * <p>The default value is 127 (fully apply boost DRC gains).
      * <p>This key is only used during decoding.
      */
     public static final String KEY_AAC_DRC_BOOST_FACTOR = "aac-drc-boost-level";
@@ -590,6 +593,7 @@
      * actual listening requirements.
      * See {@link #KEY_AAC_DRC_BOOST_FACTOR} for a description of the role of this attenuation
      * factor and the value range.
+     * <p>The default value is 127 (fully apply attenuation DRC gains).
      * <p>This key is only used during decoding.
      */
     public static final String KEY_AAC_DRC_ATTENUATION_FACTOR = "aac-drc-cut-level";
@@ -609,7 +613,7 @@
      * Light compression usually contains clipping prevention for stereo downmixing while heavy
      * compression, if additionally provided in the bitstream, is usually stronger, and contains
      * clipping prevention for stereo and mono downmixing.
-     * <p>The default is light compression.
+     * <p>The default is 1 (heavy compression).
      * <p>This key is only used during decoding.
      */
     public static final String KEY_AAC_DRC_HEAVY_COMPRESSION = "aac-drc-heavy-compression";
diff --git a/packages/SettingsLib/res/drawable/ic_landscape_from_auto_rotate.xml b/packages/SettingsLib/res/drawable/ic_landscape_from_auto_rotate.xml
index 061f9fe..44b1866 100644
--- a/packages/SettingsLib/res/drawable/ic_landscape_from_auto_rotate.xml
+++ b/packages/SettingsLib/res/drawable/ic_landscape_from_auto_rotate.xml
@@ -17,50 +17,12 @@
 <vector
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:name="ic_rotate_to_landscape"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportHeight="24.0"
+    android:viewportWidth="24.0"
     android:tint="?android:attr/colorControlNormal" >
-    <group
-        android:name="device"
-        android:translateX="24"
-        android:translateY="24" >
-        <group
-            android:name="device_pivot"
-            android:translateX="-24.15"
-            android:translateY="-24.25" >
-            <group
-                android:name="landscape"
-                android:translateX="24"
-                android:translateY="24"
-                android:scaleX="0.909"
-                android:scaleY="0.909"
-                android:rotation="45" >
-                <path
-                    android:name="device_merged"
-                    android:pathData="M -21.9799957275,-10.0 c 0.0,0.0 -0.0200042724609,20.0 -0.0200042724609,20.0 c 0.0,2.19999694824 1.80000305176,4.0 4.0,4.0 c 0.0,0.0 36.0,0.0 36.0,0.0 c 2.19999694824,0.0 4.0,-1.80000305176 4.0,-4.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,-2.19999694824 -1.80000305176,-4.0 -4.0,-4.0 c 0.0,0.0 -36.0,0.0 -36.0,0.0 c -2.19999694824,0.0 -3.97999572754,1.80000305176 -3.97999572754,4.0 Z M 14.0,10.0 c 0.0,0.0 -28.0,0.0 -28.0,0.0 c 0.0,0.0 0.0,-20.0 0.0,-20.0 c 0.0,0.0 28.0,0.0 28.0,0.0 c 0.0,0.0 0.0,20.0 0.0,20.0 Z"
-                    android:fillColor="#FFFFFFFF" />
-            </group>
-        </group>
-    </group>
-    <group
-        android:name="arrows"
-        android:translateX="24"
-        android:translateY="24" >
-        <group
-            android:name="arrows_pivot"
-            android:translateX="-24.0798"
-            android:translateY="-24.23" >
-            <group
-                android:name="arrows_0"
-                android:translateX="12.2505"
-                android:translateY="37.2145" >
-                <path
-                    android:name="bottom_merged"
-                    android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z"
-                    android:fillColor="#FFFFFFFF" />
-            </group>
-        </group>
-    </group>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12.72,23H11C5.49,23 1,18.51 1,13h2c0,3.78 2.63,6.95 6.15,7.79L8.13,19L9.87,18L12.72,23zM13,1h-1.72l2.85,5L15.87,5l-1.02,-1.79C18.37,4.05 21,7.22 21,11h2C23,5.49 18.51,1 13,1zM10.23,6L18,13.76L13.77,18L6,10.24L10.23,6C10.23,6 10.23,6 10.23,6M10.23,4C9.72,4 9.21,4.2 8.82,4.59L4.59,8.82c-0.78,0.78 -0.78,2.04 0,2.82l7.77,7.77c0.39,0.39 0.9,0.59 1.41,0.59c0.51,0 1.02,-0.2 1.41,-0.59l4.24,-4.24c0.78,-0.78 0.78,-2.04 0,-2.82l-7.77,-7.77C11.26,4.2 10.75,4 10.23,4L10.23,4z"/>
 </vector>
diff --git a/packages/SettingsLib/res/drawable/ic_settings_print.xml b/packages/SettingsLib/res/drawable/ic_settings_print.xml
index 0eab402..68b627c 100644
--- a/packages/SettingsLib/res/drawable/ic_settings_print.xml
+++ b/packages/SettingsLib/res/drawable/ic_settings_print.xml
@@ -14,15 +14,12 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
-        android:height="24.0dp"
+        android:width="24dp"
+        android:height="24dp"
         android:viewportWidth="24.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M19,8H5c-1.66,0-3,1.34-3,3v5c0,0.55,0.45,1,1,1h3v3c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1v-3h3c0.55,0,1-0.45,1-1v-5
-C22,9.34,20.66,8,19,8z M16,19H8v-5h8V19z
-M19,12c-0.55,0-1-0.45-1-1s0.45-1,1-1s1,0.45,1,1S19.55,12,19,12z M17,3H7
-C6.45,3,6,3.45,6,4v3h12V4C18,3.45,17.55,3,17,3z"/>
+        android:fillColor="#FF000000"
+        android:pathData="M19,8h-1V3H6v5H5c-1.66,0 -3,1.34 -3,3v6h4v4h12v-4h4v-6C22,9.34 20.66,8 19,8zM16,19H8v-4h8V19zM16,8H8V5h8V8zM18,12.5c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1s1,0.45 1,1S18.55,12.5 18,12.5z"/>
 </vector>
diff --git a/packages/SettingsLib/res/layout/zen_mode_radio_button.xml b/packages/SettingsLib/res/layout/zen_mode_radio_button.xml
index 4c0faed..9ded283 100644
--- a/packages/SettingsLib/res/layout/zen_mode_radio_button.xml
+++ b/packages/SettingsLib/res/layout/zen_mode_radio_button.xml
@@ -17,10 +17,10 @@
 <RadioButton
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@android:id/checkbox"
-    android:layout_width="40dp"
+    android:layout_height="48dp"
+    android:layout_width="48dp"
     android:layout_marginStart="7dp"
     android:layout_marginEnd="4dp"
-    android:layout_height="48dp"
     android:layout_alignParentStart="true"
     android:gravity="center"
     android:paddingTop="10dp"
diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml
index 229367a..04917cd 100644
--- a/packages/SettingsLib/res/values-af/arrays.xml
+++ b/packages/SettingsLib/res/values-af/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Geoptimeer vir verbindinggehalte"</item>
     <item msgid="364670732877872677">"Beste poging (Aanpasbare bistempo)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktief"</item>
+    <item msgid="8962366465966010158">", aktief (media)"</item>
+    <item msgid="4046665544396189228">", aktief (foon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Af"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml
index 9e8749b..d7866da 100644
--- a/packages/SettingsLib/res/values-am/arrays.xml
+++ b/packages/SettingsLib/res/values-am/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"ለግንኙነት ጥራት ተብቷል"</item>
     <item msgid="364670732877872677">"የተሻለው ጥረት (ተለማማጅ የቢት ፍጥነት)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">"፣ ገቢር"</item>
+    <item msgid="8962366465966010158">"፣ ገቢር (ሚዲያ)"</item>
+    <item msgid="4046665544396189228">"፣ ገቢር (ስልክ)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"ጠፍቷል"</item>
     <item msgid="1593289376502312923">"64 ኪባ"</item>
diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml
index 1dd2320..f17c74c 100644
--- a/packages/SettingsLib/res/values-ar/arrays.xml
+++ b/packages/SettingsLib/res/values-ar/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"تحسين جودة الاتصال"</item>
     <item msgid="364670732877872677">"أفضل جهد (معدل سرعة المعلومات التكيُّفي)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">"، مُفعَّل"</item>
+    <item msgid="8962366465966010158">"، مُفعَّل (وسائط)"</item>
+    <item msgid="4046665544396189228">"، مُفعَّل (هاتف)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"إيقاف"</item>
     <item msgid="1593289376502312923">"٦٤ كيلوبايت"</item>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index c05f90d..6d01891 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -373,10 +373,10 @@
     <string name="power_remaining_duration_only_enhanced" msgid="4189311599812296592">"يتبقى <xliff:g id="TIME_REMAINING">%1$s</xliff:g> تقريبًا، بناءً على استخدامك"</string>
     <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"يتبقى <xliff:g id="TIME_REMAINING">%1$s</xliff:g> تقريبًا، بناءً على استخدامك (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <string name="power_remaining_duration_only_short" msgid="3463575350656389957">"الوقت المتبقي: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
-    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"من المفترض أن يستمر شحن البطارية حوالي <xliff:g id="TIME">%1$s</xliff:g> حسب استخدامك (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
-    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"من المفترض أن يستمر شحن البطارية حوالي <xliff:g id="TIME">%1$s</xliff:g> حسب استخدامك."</string>
-    <string name="power_discharge_by" msgid="6453537733650125582">"من المفترض أن يستمر شحن البطارية حوالي <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
-    <string name="power_discharge_by_only" msgid="107616694963545745">"من المفترض أن يستمر شحن البطارية حوالي <xliff:g id="TIME">%1$s</xliff:g>."</string>
+    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"من المفترض أن يستمر شحن البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> حسب استخدامك (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
+    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"من المفترض أن يستمر شحن البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> حسب استخدامك."</string>
+    <string name="power_discharge_by" msgid="6453537733650125582">"من المفترض أن يستمر شحن البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
+    <string name="power_discharge_by_only" msgid="107616694963545745">"من المفترض أن يستمر شحن البطارية حتى حوالي الساعة <xliff:g id="TIME">%1$s</xliff:g>."</string>
     <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"يتبقى أقل من <xliff:g id="THRESHOLD">%1$s</xliff:g>."</string>
     <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"يتبقى أقل من <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
     <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"يتبقى أكثر من <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
@@ -449,8 +449,8 @@
     <string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"مطلقًا"</string>
     <string name="zen_interruption_level_priority" msgid="2078370238113347720">"الأولوية فقط"</string>
     <string name="zen_mode_and_condition" msgid="4927230238450354412">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="zen_alarm_warning_indef" msgid="3007988140196673193">"لن تسمع المنبه القادم في <xliff:g id="WHEN">%1$s</xliff:g> إلا إذا أوقفت هذا قبل الموعد."</string>
-    <string name="zen_alarm_warning" msgid="6236690803924413088">"لن تسمع المنبه القادم في <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+    <string name="zen_alarm_warning_indef" msgid="3007988140196673193">"لن تسمع المنبّه القادم في <xliff:g id="WHEN">%1$s</xliff:g> إلا إذا أوقفت هذا قبل الموعد."</string>
+    <string name="zen_alarm_warning" msgid="6236690803924413088">"لن تسمع المنبّه القادم في <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template" msgid="4996153414057676512">"الساعة <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="3779172822607461675">"يوم <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="zen_mode_duration_settings_title" msgid="229547412251222757">"المدة"</string>
diff --git a/packages/SettingsLib/res/values-as/arrays.xml b/packages/SettingsLib/res/values-as/arrays.xml
index d4d4405..d0973f0 100644
--- a/packages/SettingsLib/res/values-as/arrays.xml
+++ b/packages/SettingsLib/res/values-as/arrays.xml
@@ -138,6 +138,9 @@
     <item msgid="4681409244565426925">"সংযোগৰ ক্ষমতা অনুযায়ী সৰ্বোত্তম"</item>
     <item msgid="364670732877872677">"উত্তম প্ৰচেষ্টা (অভিযোজিত বিট ৰেইট)"</item>
   </string-array>
+    <!-- no translation found for bluetooth_audio_active_device_summaries:1 (6481691720774549651) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:2 (8962366465966010158) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:3 (4046665544396189228) -->
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"অফ কৰক"</item>
     <item msgid="1593289376502312923">"৬৪কে."</item>
diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml
index b4ee3cc..52006ad 100644
--- a/packages/SettingsLib/res/values-az/arrays.xml
+++ b/packages/SettingsLib/res/values-az/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Bağlantı Keyfiyyəti üçün optimallaşdırıldı"</item>
     <item msgid="364670732877872677">"Yüksək Cəhd (Adaptiv Bit Ölçüsü)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktiv"</item>
+    <item msgid="8962366465966010158">", aktiv (media)"</item>
+    <item msgid="4046665544396189228">", aktiv (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Deaktiv"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
index f2f34c1..1d5713c 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimizovano za kvalitet veze"</item>
     <item msgid="364670732877872677">"Najbolje moguće (prilagodljiva brzina prenosa)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktivan"</item>
+    <item msgid="8962366465966010158">", aktivan (medijski)"</item>
+    <item msgid="4046665544396189228">", aktivan (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Isključeno"</item>
     <item msgid="1593289376502312923">"64 kB"</item>
diff --git a/packages/SettingsLib/res/values-be/arrays.xml b/packages/SettingsLib/res/values-be/arrays.xml
index fb2e13e..3891b7a 100644
--- a/packages/SettingsLib/res/values-be/arrays.xml
+++ b/packages/SettingsLib/res/values-be/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Аптымізавана якасць падключэння"</item>
     <item msgid="364670732877872677">"Лепшая якасць (адаптыўны бітрэйт)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", уключана"</item>
+    <item msgid="8962366465966010158">", уключана (мультымедыя)"</item>
+    <item msgid="4046665544396189228">", уключана (тэлефон)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Выкл."</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-bg/arrays.xml b/packages/SettingsLib/res/values-bg/arrays.xml
index a5aa98e..d6e79cb 100644
--- a/packages/SettingsLib/res/values-bg/arrays.xml
+++ b/packages/SettingsLib/res/values-bg/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Оптимизирано за качество на връзката"</item>
     <item msgid="364670732877872677">"Възможно най-добро качество (адаптивна скорост на предаване)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">"– активно"</item>
+    <item msgid="8962366465966010158">"– активно (мултимедия)"</item>
+    <item msgid="4046665544396189228">"– активно (телефон)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Изключено"</item>
     <item msgid="1593289376502312923">"64 КБ"</item>
diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml
index 4390197..e186bb4 100644
--- a/packages/SettingsLib/res/values-bn/arrays.xml
+++ b/packages/SettingsLib/res/values-bn/arrays.xml
@@ -138,6 +138,9 @@
     <item msgid="4681409244565426925">"সংযোগের গুণমানের জন্য অপটিমাইজ করা হয়েছে"</item>
     <item msgid="364670732877872677">"সেরা প্রচেষ্টা (অ্যাডাপ্টিভ বিট রেট)"</item>
   </string-array>
+    <!-- no translation found for bluetooth_audio_active_device_summaries:1 (6481691720774549651) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:2 (8962366465966010158) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:3 (4046665544396189228) -->
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"বন্ধ আছে"</item>
     <item msgid="1593289376502312923">"৬৪K"</item>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index 04cb9e9..8577779 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimizirano za kvalitet veze"</item>
     <item msgid="364670732877872677">"Maksimalan napor (Prilagodljiva brzina prijenosa)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktivan"</item>
+    <item msgid="8962366465966010158">", aktivan (mediji)"</item>
+    <item msgid="4046665544396189228">", aktivan (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Isključeno"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index c207772..d26afb5 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimitzat per a la qualitat de la connexió"</item>
     <item msgid="364670732877872677">"Millor qualitat (taxa de bits automàtica)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", actiu"</item>
+    <item msgid="8962366465966010158">", actiu (contingut multimèdia)"</item>
+    <item msgid="4046665544396189228">", actiu (telèfon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"No"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml
index 7e7bbe1..1555720 100644
--- a/packages/SettingsLib/res/values-cs/arrays.xml
+++ b/packages/SettingsLib/res/values-cs/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimalizováno pro kvalitu připojení"</item>
     <item msgid="364670732877872677">"Nejlepší možná kvalita (adaptivní datový tok)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktivní"</item>
+    <item msgid="8962366465966010158">", aktivní (média)"</item>
+    <item msgid="4046665544396189228">", aktivní (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Vypnuto"</item>
     <item msgid="1593289376502312923">"64 kB"</item>
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index 6d651d5..01ae8d2 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimeret til forbindelseskvalitet"</item>
     <item msgid="364670732877872677">"Bedste resultat (tilpasset bithastighed)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktiv"</item>
+    <item msgid="8962366465966010158">", aktiv (medier)"</item>
+    <item msgid="4046665544396189228">", aktiv (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Fra"</item>
     <item msgid="1593289376502312923">"64 kB"</item>
diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml
index 6f18183..6722410 100644
--- a/packages/SettingsLib/res/values-de/arrays.xml
+++ b/packages/SettingsLib/res/values-de/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Für Verbindungsqualität optimiert"</item>
     <item msgid="364670732877872677">"Bestmöglich (adaptive Bitrate)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktiv"</item>
+    <item msgid="8962366465966010158">", aktiv (Medien)"</item>
+    <item msgid="4046665544396189228">", aktiv (Telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Aus"</item>
     <item msgid="1593289376502312923">"64.000"</item>
diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml
index 8d3e3fa..9bf9f9b 100644
--- a/packages/SettingsLib/res/values-el/arrays.xml
+++ b/packages/SettingsLib/res/values-el/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Βελτιστοποιημένο για ποιότητα σύνδεσης"</item>
     <item msgid="364670732877872677">"Βέλτιστη προσπάθεια (ρυθμός δεδομένων με δυνατότητα προσαρμογής)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", ενεργή"</item>
+    <item msgid="8962366465966010158">", ενεργή (μέσα)"</item>
+    <item msgid="4046665544396189228">", ενεργή (τηλέφωνο)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Ανενεργό"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-en-rAU/arrays.xml b/packages/SettingsLib/res/values-en-rAU/arrays.xml
index 19ef58c..bd1a78c 100644
--- a/packages/SettingsLib/res/values-en-rAU/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rAU/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimised for Connection Quality"</item>
     <item msgid="364670732877872677">"Best effort (adaptive bit rate)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", active"</item>
+    <item msgid="8962366465966010158">", active (media)"</item>
+    <item msgid="4046665544396189228">", active (phone)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Off"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-en-rCA/arrays.xml b/packages/SettingsLib/res/values-en-rCA/arrays.xml
index 19ef58c..bd1a78c 100644
--- a/packages/SettingsLib/res/values-en-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rCA/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimised for Connection Quality"</item>
     <item msgid="364670732877872677">"Best effort (adaptive bit rate)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", active"</item>
+    <item msgid="8962366465966010158">", active (media)"</item>
+    <item msgid="4046665544396189228">", active (phone)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Off"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-en-rGB/arrays.xml b/packages/SettingsLib/res/values-en-rGB/arrays.xml
index 19ef58c..bd1a78c 100644
--- a/packages/SettingsLib/res/values-en-rGB/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rGB/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimised for Connection Quality"</item>
     <item msgid="364670732877872677">"Best effort (adaptive bit rate)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", active"</item>
+    <item msgid="8962366465966010158">", active (media)"</item>
+    <item msgid="4046665544396189228">", active (phone)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Off"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-en-rIN/arrays.xml b/packages/SettingsLib/res/values-en-rIN/arrays.xml
index 19ef58c..bd1a78c 100644
--- a/packages/SettingsLib/res/values-en-rIN/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rIN/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimised for Connection Quality"</item>
     <item msgid="364670732877872677">"Best effort (adaptive bit rate)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", active"</item>
+    <item msgid="8962366465966010158">", active (media)"</item>
+    <item msgid="4046665544396189228">", active (phone)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Off"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-en-rXC/arrays.xml b/packages/SettingsLib/res/values-en-rXC/arrays.xml
index b66ace9..1f66235 100644
--- a/packages/SettingsLib/res/values-en-rXC/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rXC/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‏‎Optimized for Connection Quality‎‏‎‎‏‎"</item>
     <item msgid="364670732877872677">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‏‎‏‎‏‏‏‏‏‎‎‎‏‎‎‏‎‏‎Best Effort (Adaptive Bit Rate)‎‏‎‎‏‎"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‏‎, active‎‏‎‎‏‎"</item>
+    <item msgid="8962366465966010158">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‎‎, active (media)‎‏‎‎‏‎"</item>
+    <item msgid="4046665544396189228">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‎‏‎‏‎‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎, active (phone)‎‏‎‎‏‎"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‎‎‏‎‏‎Off‎‏‎‎‏‎"</item>
     <item msgid="1593289376502312923">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‏‎‏‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‎64K‎‏‎‎‏‎"</item>
diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml
index b46024f..38342e3 100644
--- a/packages/SettingsLib/res/values-es-rUS/arrays.xml
+++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimizado para calidad de conexión"</item>
     <item msgid="364670732877872677">"Mejores resultados (tasa de bits ajustable)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", activo"</item>
+    <item msgid="8962366465966010158">", activo (contenido multimedia)"</item>
+    <item msgid="4046665544396189228">", activo (teléfono)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Desactivado"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index a109831..db62655 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Se ha optimizado para la calidad de la conexión"</item>
     <item msgid="364670732877872677">"Mejor esfuerzo (tasa de bits flexible)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", activo"</item>
+    <item msgid="8962366465966010158">", activo (contenido multimedia)"</item>
+    <item msgid="4046665544396189228">", activo (teléfono)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Desactivado"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-et/arrays.xml b/packages/SettingsLib/res/values-et/arrays.xml
index 65801eb..9c7873f 100644
--- a/packages/SettingsLib/res/values-et/arrays.xml
+++ b/packages/SettingsLib/res/values-et/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Ühenduskvaliteedi jaoks optimeeritud"</item>
     <item msgid="364670732877872677">"Parim võimalik (kohanduv bitikiirus)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktiivne"</item>
+    <item msgid="8962366465966010158">", aktiivne (meedia)"</item>
+    <item msgid="4046665544396189228">", aktiivne (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Väljas"</item>
     <item msgid="1593289376502312923">"64 000"</item>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index d573ab8..4b76d59 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Konexioaren kalitatea areagotzeko optimizatua"</item>
     <item msgid="364670732877872677">"Emaitzarik onenak (bit-abiadura doigarria)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktibo"</item>
+    <item msgid="8962366465966010158">", aktibo (multimedia-edukia)"</item>
+    <item msgid="4046665544396189228">", aktibo (telefonoa)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Desaktibatuta"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml
index 2baa632..1e4d47f 100644
--- a/packages/SettingsLib/res/values-fa/arrays.xml
+++ b/packages/SettingsLib/res/values-fa/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"بهینه‌شده برای کیفیت اتصال"</item>
     <item msgid="364670732877872677">"بهترین حالت (نرخ بیت تطبیقی)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">"، فعال"</item>
+    <item msgid="8962366465966010158">"، فعال (رسانه)"</item>
+    <item msgid="4046665544396189228">"، فعال (تلفن)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"خاموش"</item>
     <item msgid="1593289376502312923">"۶۴ هزار"</item>
diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml
index 64d85b3..6bbddb2 100644
--- a/packages/SettingsLib/res/values-fi/arrays.xml
+++ b/packages/SettingsLib/res/values-fi/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimoi yhteyden laatu"</item>
     <item msgid="364670732877872677">"Paras mahdollinen (mukautuva siirtonopeus)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktiivinen"</item>
+    <item msgid="8962366465966010158">", aktiivinen (media)"</item>
+    <item msgid="4046665544396189228">", aktiivinen (puhelin)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Ei käytössä"</item>
     <item msgid="1593289376502312923">"64 kt"</item>
diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
index a6afcf8..2e7f2b2 100644
--- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimisé pour la qualité de connexion"</item>
     <item msgid="364670732877872677">"Meilleur effort (débit adaptatif)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", actif"</item>
+    <item msgid="8962366465966010158">", actif (média)"</item>
+    <item msgid="4046665544396189228">", actif (téléphone)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Désactivé"</item>
     <item msgid="1593289376502312923">"64 ko"</item>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index e88d1b5..b14cf54 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimisée pour la qualité de la connexion"</item>
     <item msgid="364670732877872677">"Qualité de lecture optimale (débit adaptatif)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", actif"</item>
+    <item msgid="8962366465966010158">", actif (son des médias)"</item>
+    <item msgid="4046665544396189228">", actif (téléphone)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Désactivé"</item>
     <item msgid="1593289376502312923">"64 Ko"</item>
diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml
index 1d186f9..a25d136 100644
--- a/packages/SettingsLib/res/values-gl/arrays.xml
+++ b/packages/SettingsLib/res/values-gl/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimizado para a calidade da conexión"</item>
     <item msgid="364670732877872677">"Máxima (taxa de bits adaptable)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", activo"</item>
+    <item msgid="8962366465966010158">", activo (contido multimedia)"</item>
+    <item msgid="4046665544396189228">", activo (teléfono)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Desactivado"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-gu/arrays.xml b/packages/SettingsLib/res/values-gu/arrays.xml
index ecdf9347..30a9339 100644
--- a/packages/SettingsLib/res/values-gu/arrays.xml
+++ b/packages/SettingsLib/res/values-gu/arrays.xml
@@ -138,6 +138,9 @@
     <item msgid="4681409244565426925">"કનેક્શનની ગુણવત્તા માટે ઓપ્ટિમાઇઝ કર્યું"</item>
     <item msgid="364670732877872677">"ઉત્તમ પ્રયાસ (અનુકૂલનશીલ બિટ રેટ)"</item>
   </string-array>
+    <!-- no translation found for bluetooth_audio_active_device_summaries:1 (6481691720774549651) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:2 (8962366465966010158) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:3 (4046665544396189228) -->
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"બંધ"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index 1cc1b55..0e34b77 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"कनेक्शन की गुणवत्ता के लिए अनुकूलित किया गया"</item>
     <item msgid="364670732877872677">"सबसे अच्छी क्वालिटी में चलाएं (अनुकूल बिट रेट)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">"चालू है"</item>
+    <item msgid="8962366465966010158">"चालू है (सिर्फ़ मीडिया के लिए)"</item>
+    <item msgid="4046665544396189228">"चालू है (सिर्फ़ फ़ोन के लिए)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"बंद"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index cdbbccc..d7ee655 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -224,8 +224,7 @@
     <string name="bluetooth_select_a2dp_codec_channel_mode" msgid="884855779449390540">"ब्लूटूथ ऑडियो चैनल मोड"</string>
     <string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="7234956835280563341">"ब्लूटूथ ऑडियो कोडेक का\nयह विकल्प चालू करें: चैनल मोड"</string>
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3619694372407843405">"ब्लूटूथ ऑडियो LDAC कोडेक: प्लेबैक क्वालिटी"</string>
-    <!-- no translation found for bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title (6893955536658137179) -->
-    <skip />
+    <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="6893955536658137179">"ब्लूटूथ से चलने वाले ऑडियो के लिए LDAC कोडेक का\nविकल्प चुनें: ऑडियो की क्वालिटी"</string>
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="5347862512596240506">"चलाया जा रहा है: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="select_private_dns_configuration_title" msgid="3700456559305263922">"निजी डीएनएस"</string>
     <string name="select_private_dns_configuration_dialog_title" msgid="9221994415765826811">"निजी डीएनएस मोड चुनें"</string>
diff --git a/packages/SettingsLib/res/values-hr/arrays.xml b/packages/SettingsLib/res/values-hr/arrays.xml
index e25cd9c..893a0c1 100644
--- a/packages/SettingsLib/res/values-hr/arrays.xml
+++ b/packages/SettingsLib/res/values-hr/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimizirano za kvalitetu veze"</item>
     <item msgid="364670732877872677">"Najbolji rezultat (prilagodljiva brzina prijenosa)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktivno"</item>
+    <item msgid="8962366465966010158">", aktivno (mediji)"</item>
+    <item msgid="4046665544396189228">", aktivno (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Isključeno"</item>
     <item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-hu/arrays.xml b/packages/SettingsLib/res/values-hu/arrays.xml
index 129944f..bfd70e9 100644
--- a/packages/SettingsLib/res/values-hu/arrays.xml
+++ b/packages/SettingsLib/res/values-hu/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimális kapcsolatminőség"</item>
     <item msgid="364670732877872677">"A legjobb eredmény (adaptív bitsebesség)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktív"</item>
+    <item msgid="8962366465966010158">", aktív (média)"</item>
+    <item msgid="4046665544396189228">", aktív (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Ki"</item>
     <item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml
index e632cdb..08c871c 100644
--- a/packages/SettingsLib/res/values-hy/arrays.xml
+++ b/packages/SettingsLib/res/values-hy/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Օպտիմալացված կապի որակի համար"</item>
     <item msgid="364670732877872677">"Հնարավորներից լավագույնը (բիթերի փոխանցման հարմարեցվող արագություն)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", ակտիվ է"</item>
+    <item msgid="8962366465966010158">", ակտիվ է (մեդիա)"</item>
+    <item msgid="4046665544396189228">", ակտիվ է (հեռախոս)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Անջատված է"</item>
     <item msgid="1593289376502312923">"64ԿԲ"</item>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index 724cb54..8b8057b 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Dioptimalkan untuk Kualitas Sambungan"</item>
     <item msgid="364670732877872677">"Best Effort (Kecepatan Bit Adaptif)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktif"</item>
+    <item msgid="8962366465966010158">", aktif (media)"</item>
+    <item msgid="4046665544396189228">", aktif (ponsel)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Nonaktif"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-is/arrays.xml b/packages/SettingsLib/res/values-is/arrays.xml
index 08d49aa..3aef4ce 100644
--- a/packages/SettingsLib/res/values-is/arrays.xml
+++ b/packages/SettingsLib/res/values-is/arrays.xml
@@ -138,6 +138,9 @@
     <item msgid="4681409244565426925">"Fínstillt fyrir gæði tengingar"</item>
     <item msgid="364670732877872677">"Bestu mögulegu gæði (breytilegur bitahraði)"</item>
   </string-array>
+    <!-- no translation found for bluetooth_audio_active_device_summaries:1 (6481691720774549651) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:2 (8962366465966010158) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:3 (4046665544396189228) -->
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Slökkt"</item>
     <item msgid="1593289376502312923">"64 k"</item>
diff --git a/packages/SettingsLib/res/values-it/arrays.xml b/packages/SettingsLib/res/values-it/arrays.xml
index 0e606ff..6e9628c 100644
--- a/packages/SettingsLib/res/values-it/arrays.xml
+++ b/packages/SettingsLib/res/values-it/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Ottimizzato per qualità di connessione"</item>
     <item msgid="364670732877872677">"Qualità migliore possibile (velocità in bit adattiva)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", attivo"</item>
+    <item msgid="8962366465966010158">", attivo (contenuti multimediali)"</item>
+    <item msgid="4046665544396189228">", attivo (telefono)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Off"</item>
     <item msgid="1593289376502312923">"64 kB"</item>
diff --git a/packages/SettingsLib/res/values-iw/arrays.xml b/packages/SettingsLib/res/values-iw/arrays.xml
index d758ed9..037c23f 100644
--- a/packages/SettingsLib/res/values-iw/arrays.xml
+++ b/packages/SettingsLib/res/values-iw/arrays.xml
@@ -138,6 +138,9 @@
     <item msgid="4681409244565426925">"אופטימיזציה להשגת איכות חיבור מרבית"</item>
     <item msgid="364670732877872677">"האיכות הטובה ביותר (קצב העברת נתונים מותאם)"</item>
   </string-array>
+    <!-- no translation found for bluetooth_audio_active_device_summaries:1 (6481691720774549651) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:2 (8962366465966010158) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:3 (4046665544396189228) -->
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"כבוי"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index d024f01..e860b42 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"接続の品質重視で最適化"</item>
     <item msgid="364670732877872677">"ベスト エフォート(アダプティブ ビットレート)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">"、有効"</item>
+    <item msgid="8962366465966010158">"、有効(メディア)"</item>
+    <item msgid="4046665544396189228">"、有効(スマートフォン)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"OFF"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-ka/arrays.xml b/packages/SettingsLib/res/values-ka/arrays.xml
index 6e6d19c..a92ecef 100644
--- a/packages/SettingsLib/res/values-ka/arrays.xml
+++ b/packages/SettingsLib/res/values-ka/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"კავშირის ხარისხისთვის ოპტიმიზებული"</item>
     <item msgid="364670732877872677">"შეძლებისდაგვარად მაღალი (ადაპტირებადი ბიტური სიხშირე)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", აქტიური"</item>
+    <item msgid="8962366465966010158">", აქტიური (მედია)"</item>
+    <item msgid="4046665544396189228">", აქტიური (ტელეფონი)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"გამორთული"</item>
     <item msgid="1593289376502312923">"64 კბაიტი"</item>
diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml
index 38fcb42..ae9a679 100644
--- a/packages/SettingsLib/res/values-kk/arrays.xml
+++ b/packages/SettingsLib/res/values-kk/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Байланыс сапасы бойынша оңтайландырылды"</item>
     <item msgid="364670732877872677">"Максималды күш (шартты жіберу жылдамдығы)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", қосулы"</item>
+    <item msgid="8962366465966010158">", қосулы (медиамазмұн)"</item>
+    <item msgid="4046665544396189228">", қосулы (телефон)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Өшірулі"</item>
     <item msgid="1593289376502312923">"64 КБ"</item>
diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml
index 3997c59..beb3147 100644
--- a/packages/SettingsLib/res/values-km/arrays.xml
+++ b/packages/SettingsLib/res/values-km/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"បាន​បង្កើន​ប្រសិទ្ធភាព​​សម្រាប់គុណភាព​នៃ​ការ​ត​ភ្ជាប់"</item>
     <item msgid="364670732877872677">"កម្រិតល្អបំផុត (កម្រិតប៊ីតដែលអាចប្រែប្រួល)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">"សកម្ម"</item>
+    <item msgid="8962366465966010158">"សកម្ម (មេឌៀ)"</item>
+    <item msgid="4046665544396189228">"សកម្ម (ទូរសព្ទ)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"បិទ"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml
index e1cc086..a66af95 100644
--- a/packages/SettingsLib/res/values-kn/arrays.xml
+++ b/packages/SettingsLib/res/values-kn/arrays.xml
@@ -138,6 +138,9 @@
     <item msgid="4681409244565426925">"ಸಂಪರ್ಕ ಗುಣಮಟ್ಟಕ್ಕಾಗಿ ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ"</item>
     <item msgid="364670732877872677">"ಅತ್ಯುತ್ತಮ ಪ್ರಯತ್ನ (ಹೊಂದಿಸಬಹುದಾದ ಬಿಟ್ ಪ್ರಮಾಣ)"</item>
   </string-array>
+    <!-- no translation found for bluetooth_audio_active_device_summaries:1 (6481691720774549651) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:2 (8962366465966010158) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:3 (4046665544396189228) -->
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"ಆಫ್"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml
index 27c4c8c..d784858 100644
--- a/packages/SettingsLib/res/values-ko/arrays.xml
+++ b/packages/SettingsLib/res/values-ko/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"연결 품질에 최적화됨"</item>
     <item msgid="364670732877872677">"최선의 결과(비트 전송률 자동 조절)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", 활성"</item>
+    <item msgid="8962366465966010158">", 활성(미디어)"</item>
+    <item msgid="4046665544396189228">", 활성(휴대전화)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"사용 안함"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-ky/arrays.xml b/packages/SettingsLib/res/values-ky/arrays.xml
index e4af2d5..73b24b1 100644
--- a/packages/SettingsLib/res/values-ky/arrays.xml
+++ b/packages/SettingsLib/res/values-ky/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Туташуунун сапатын оптималдаштыруу"</item>
     <item msgid="364670732877872677">"Мүмкүн болгон эң мыкты натыйжа (адаптивдүү битрейт)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", жандырылган"</item>
+    <item msgid="8962366465966010158">", жандырылган (аудио)"</item>
+    <item msgid="4046665544396189228">", жандырылган (телефон)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Өчүк"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml
index 3842cf4..9d602e8 100644
--- a/packages/SettingsLib/res/values-lo/arrays.xml
+++ b/packages/SettingsLib/res/values-lo/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"ປັບແຕ່ງສຳລັບຄຸນນະພາບການເຊື່ອມຕໍ່"</item>
     <item msgid="364670732877872677">"ພະຍາຍາມເຕັມທີ່ (ປັບອັດຕາບິດເຣດອັດຕະໂນມັດ)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", ອອນລາຍ"</item>
+    <item msgid="8962366465966010158">", ອອນລາຍ (ມີເດຍ)"</item>
+    <item msgid="4046665544396189228">", ອອນລາຍ (ໂທລະສັບ)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"ປິດ"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-lt/arrays.xml b/packages/SettingsLib/res/values-lt/arrays.xml
index 012ab35..7576ab3 100644
--- a/packages/SettingsLib/res/values-lt/arrays.xml
+++ b/packages/SettingsLib/res/values-lt/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimizuota ryšio kokybė"</item>
     <item msgid="364670732877872677">"Geriausias rezultatas (adaptyvusis pralaidumas)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktyvus"</item>
+    <item msgid="8962366465966010158">", aktyvus (medija)"</item>
+    <item msgid="4046665544396189228">", aktyvus (telefonas)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Išjungta"</item>
     <item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-lv/arrays.xml b/packages/SettingsLib/res/values-lv/arrays.xml
index 1286770..3d7f77a 100644
--- a/packages/SettingsLib/res/values-lv/arrays.xml
+++ b/packages/SettingsLib/res/values-lv/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Savienojuma kvalitātes optimizēšana"</item>
     <item msgid="364670732877872677">"Labākais rezultāts (adaptīvs bitu pārraides ātrums)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktīva"</item>
+    <item msgid="8962366465966010158">", aktīva (multivide)"</item>
+    <item msgid="4046665544396189228">", aktīva (tālrunis)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Izslēgts"</item>
     <item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml
index 8963f03..e2dbc7e 100644
--- a/packages/SettingsLib/res/values-mk/arrays.xml
+++ b/packages/SettingsLib/res/values-mk/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Оптимизирано за квалитет на врската"</item>
     <item msgid="364670732877872677">"Најдобар напор (приспособлива стапка на битови)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", активен"</item>
+    <item msgid="8962366465966010158">", активен (аудиосодржини)"</item>
+    <item msgid="4046665544396189228">", активен (телефон)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Исклучено"</item>
     <item msgid="1593289376502312923">"64.000"</item>
diff --git a/packages/SettingsLib/res/values-ml/arrays.xml b/packages/SettingsLib/res/values-ml/arrays.xml
index 615a020..74689e3 100644
--- a/packages/SettingsLib/res/values-ml/arrays.xml
+++ b/packages/SettingsLib/res/values-ml/arrays.xml
@@ -138,6 +138,9 @@
     <item msgid="4681409244565426925">"കണക്ഷൻ നിലവാരമുയർത്താൻ ഒപ്‌റ്റിമൈസ് ചെയ്‌തു"</item>
     <item msgid="364670732877872677">"മികച്ച സംവിധാനം (അനുയോജ്യമായ ബിറ്റ് റേറ്റ്)"</item>
   </string-array>
+    <!-- no translation found for bluetooth_audio_active_device_summaries:1 (6481691720774549651) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:2 (8962366465966010158) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:3 (4046665544396189228) -->
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"ഓഫ്"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml
index e0f5ac6..9b057fb 100644
--- a/packages/SettingsLib/res/values-mn/arrays.xml
+++ b/packages/SettingsLib/res/values-mn/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Холболтын чанарт тааруулсан"</item>
     <item msgid="364670732877872677">"Шилдэг оролдлого (Тохируулж болох битийн хурд)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", идэвхтэй"</item>
+    <item msgid="8962366465966010158">", идэвхтэй (медиа)"</item>
+    <item msgid="4046665544396189228">", идэвхтэй (утас)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Идэвхгүй"</item>
     <item msgid="1593289376502312923">"64000"</item>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index 5ab1f90..841e564 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -138,6 +138,9 @@
     <item msgid="4681409244565426925">"कनेक्शन गुणवत्तेसाठी ऑप्टिमाइझ केले"</item>
     <item msgid="364670732877872677">"सर्वोत्तम प्रयत्न (अनुकूल बिट रेट)"</item>
   </string-array>
+    <!-- no translation found for bluetooth_audio_active_device_summaries:1 (6481691720774549651) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:2 (8962366465966010158) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:3 (4046665544396189228) -->
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"बंद"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-ms/arrays.xml b/packages/SettingsLib/res/values-ms/arrays.xml
index a804ea2..ad12a77 100644
--- a/packages/SettingsLib/res/values-ms/arrays.xml
+++ b/packages/SettingsLib/res/values-ms/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Dioptimumkan untuk Kualiti Sambungan"</item>
     <item msgid="364670732877872677">"Usaha Terbaik (Kadar Bit Mudah Suai)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktif"</item>
+    <item msgid="8962366465966010158">", aktif (media)"</item>
+    <item msgid="4046665544396189228">", aktif (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Mati"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml
index f62a667..62b3cc5 100644
--- a/packages/SettingsLib/res/values-my/arrays.xml
+++ b/packages/SettingsLib/res/values-my/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"ချိတ်ဆက်မှု အရည်အသွေးကို ပိုကောင်းအောင် ပြုလုပ်ထားသည်"</item>
     <item msgid="364670732877872677">"အကောင်းဆုံးကြိုးပမ်းမှု (ပေးပို့နှုန်း အလိုက်)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">"၊ ဖွင့်ထားသည်"</item>
+    <item msgid="8962366465966010158">"၊ ဖွင့်ထားသည် (မီဒီယာ)"</item>
+    <item msgid="4046665544396189228">"၊ ဖွင့်ထားသည် (ဖုန်း)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"ပိတ်ရန်"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml
index 9c304b8..68e864a 100644
--- a/packages/SettingsLib/res/values-nb/arrays.xml
+++ b/packages/SettingsLib/res/values-nb/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimalisert for tilkoblingskvalitet"</item>
     <item msgid="364670732877872677">"Beste forsøk (tilpasset bithastighet)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktiv"</item>
+    <item msgid="8962366465966010158">", aktiv (media)"</item>
+    <item msgid="4046665544396189228">", aktiv (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Av"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index cd016e0..95a26d2 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -138,6 +138,9 @@
     <item msgid="4681409244565426925">"जडानको गुणस्तर सुधार्न अनुकूलन गरिएको"</item>
     <item msgid="364670732877872677">"उत्कृष्ट प्रयास (अनुकूलनीय बिट दर)"</item>
   </string-array>
+    <!-- no translation found for bluetooth_audio_active_device_summaries:1 (6481691720774549651) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:2 (8962366465966010158) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:3 (4046665544396189228) -->
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"निष्क्रिय गर्नुहोस्"</item>
     <item msgid="1593289376502312923">"६४के"</item>
diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml
index 6fcdfd2..621e3065 100644
--- a/packages/SettingsLib/res/values-nl/arrays.xml
+++ b/packages/SettingsLib/res/values-nl/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Geoptimaliseerd voor verbindingskwaliteit"</item>
     <item msgid="364670732877872677">"Beste mogelijkheid (aanpasbare bitsnelheid)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", actief"</item>
+    <item msgid="8962366465966010158">", actief (media)"</item>
+    <item msgid="4046665544396189228">", actief (telefoon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Uit"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-or/arrays.xml b/packages/SettingsLib/res/values-or/arrays.xml
index 422fab46..9da5d6e 100644
--- a/packages/SettingsLib/res/values-or/arrays.xml
+++ b/packages/SettingsLib/res/values-or/arrays.xml
@@ -138,6 +138,9 @@
     <item msgid="4681409244565426925">"ସଂଯୋଗର ଗୁଣବତ୍ତା ପାଇଁ ଅନୁକୂଳିତ"</item>
     <item msgid="364670732877872677">"ସର୍ବୋତ୍ତମ ପ୍ରୟାସ (ଅନୁକୂଳ ବିଟ୍‌ ରେଟ୍‌)"</item>
   </string-array>
+    <!-- no translation found for bluetooth_audio_active_device_summaries:1 (6481691720774549651) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:2 (8962366465966010158) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:3 (4046665544396189228) -->
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"ଅଫ୍"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index 489100a..047dcb1 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"ਕਨੈਕਸ਼ਨ ਗੁਣਵੱਤਾ ਲਈ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ"</item>
     <item msgid="364670732877872677">"ਸਰਵੋਤਮ ਕੋਸ਼ਿਸ਼ (ਅਨੁਕੂਲਨਕਾਰੀ ਬਿਟ ਰੇਟ)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", ਕਿਰਿਆਸ਼ੀਲ"</item>
+    <item msgid="8962366465966010158">", ਕਿਰਿਆਸ਼ੀਲ (ਮੀਡੀਆ)"</item>
+    <item msgid="4046665544396189228">", ਕਿਰਿਆਸ਼ੀਲ (ਫ਼ੋਨ)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"ਬੰਦ"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index 3141219..03afdb6 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optymalizacja pod kątem jakości połączenia"</item>
     <item msgid="364670732877872677">"Optymalna (adaptacyjna szybkość transmisji bitów)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktywne"</item>
+    <item msgid="8962366465966010158">", aktywne (multimedia)"</item>
+    <item msgid="4046665544396189228">", aktywne (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Wył."</item>
     <item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
index aa5aed0..dfdc09c 100644
--- a/packages/SettingsLib/res/values-pt-rBR/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Otimizado para qualidade de conexão"</item>
     <item msgid="364670732877872677">"Melhor resultado (Taxa de bits adaptável)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", ativo"</item>
+    <item msgid="8962366465966010158">", ativo (mídia)"</item>
+    <item msgid="4046665544396189228">", ativo (telefone)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Desativado"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
index 384d9f5..7edad9b 100644
--- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Otimizado para a qualidade da ligação"</item>
     <item msgid="364670732877872677">"Resultado possível (taxa de bits adaptável)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", ativo"</item>
+    <item msgid="8962366465966010158">", ativo (multimédia)"</item>
+    <item msgid="4046665544396189228">", ativo (telemóvel)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Desativado"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml
index aa5aed0..dfdc09c 100644
--- a/packages/SettingsLib/res/values-pt/arrays.xml
+++ b/packages/SettingsLib/res/values-pt/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Otimizado para qualidade de conexão"</item>
     <item msgid="364670732877872677">"Melhor resultado (Taxa de bits adaptável)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", ativo"</item>
+    <item msgid="8962366465966010158">", ativo (mídia)"</item>
+    <item msgid="4046665544396189228">", ativo (telefone)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Desativado"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index 842d81d..e4a341a 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimizat pentru calitatea conexiunii"</item>
     <item msgid="364670732877872677">"Cel mai bun rezultat (rată de biți adaptivă)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", activ"</item>
+    <item msgid="8962366465966010158">", activ (media)"</item>
+    <item msgid="4046665544396189228">", activ (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Dezactivată"</item>
     <item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-ru/arrays.xml b/packages/SettingsLib/res/values-ru/arrays.xml
index 7965f19..7603a0e 100644
--- a/packages/SettingsLib/res/values-ru/arrays.xml
+++ b/packages/SettingsLib/res/values-ru/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Оптимизировать скорость подключения"</item>
     <item msgid="364670732877872677">"Лучший возможный результат (адаптивный битрейт)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", активно"</item>
+    <item msgid="8962366465966010158">", активно (A2DP)"</item>
+    <item msgid="4046665544396189228">", активно (HSP/HFP)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Отключено"</item>
     <item msgid="1593289376502312923">"64 КБ"</item>
diff --git a/packages/SettingsLib/res/values-si/arrays.xml b/packages/SettingsLib/res/values-si/arrays.xml
index b056a9c..00beb00 100644
--- a/packages/SettingsLib/res/values-si/arrays.xml
+++ b/packages/SettingsLib/res/values-si/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"සබැඳුම් ගුණත්වය සඳහා ප්‍රශස්ත කරන ලදී"</item>
     <item msgid="364670732877872677">"හොඳම වෑයම (අනුවර්තී බිට් අනුපාතය)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", ක්‍රියාකාරී"</item>
+    <item msgid="8962366465966010158">", ක්‍රියාකාරී (මාධ්‍ය)"</item>
+    <item msgid="4046665544396189228">", ක්‍රියාකාරී (දුරකථන)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"ක්‍රියාවිරහිතය"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-sk/arrays.xml b/packages/SettingsLib/res/values-sk/arrays.xml
index 20d7e24..8e1dec0 100644
--- a/packages/SettingsLib/res/values-sk/arrays.xml
+++ b/packages/SettingsLib/res/values-sk/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimalizovaná kvalita pripojenia"</item>
     <item msgid="364670732877872677">"Najvyšši kvalita (adaptívna prenosová rýchlosť)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktívne"</item>
+    <item msgid="8962366465966010158">", aktívne (médiá)"</item>
+    <item msgid="4046665544396189228">", aktívne (telefón)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Vypnuté"</item>
     <item msgid="1593289376502312923">"64 kB"</item>
diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml
index 2d1cb55..11f99c5 100644
--- a/packages/SettingsLib/res/values-sl/arrays.xml
+++ b/packages/SettingsLib/res/values-sl/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimizirano za kakovost povezave"</item>
     <item msgid="364670732877872677">"Najboljše možno (prilagodljiva bitna hitrost)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktivno"</item>
+    <item msgid="8962366465966010158">", aktivno (predstavnost)"</item>
+    <item msgid="4046665544396189228">", aktivno (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Izklopljeno"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-sq/arrays.xml b/packages/SettingsLib/res/values-sq/arrays.xml
index 5bd5b1d..70786e7 100644
--- a/packages/SettingsLib/res/values-sq/arrays.xml
+++ b/packages/SettingsLib/res/values-sq/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimizuar për cilësi lidhjeje"</item>
     <item msgid="364670732877872677">"Përpjekja më e mirë (shpejtësia me përshtatje e bitëve)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktiv"</item>
+    <item msgid="8962366465966010158">", aktiv (media)"</item>
+    <item msgid="4046665544396189228">", aktiv (telefoni)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Joaktiv"</item>
     <item msgid="1593289376502312923">"64 mijë"</item>
diff --git a/packages/SettingsLib/res/values-sr/arrays.xml b/packages/SettingsLib/res/values-sr/arrays.xml
index 8767185..190f502 100644
--- a/packages/SettingsLib/res/values-sr/arrays.xml
+++ b/packages/SettingsLib/res/values-sr/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Оптимизовано за квалитет везе"</item>
     <item msgid="364670732877872677">"Најбоље могуће (прилагодљива брзина преноса)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", активан"</item>
+    <item msgid="8962366465966010158">", активан (медијски)"</item>
+    <item msgid="4046665544396189228">", активан (телефон)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Искључено"</item>
     <item msgid="1593289376502312923">"64 kB"</item>
diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml
index b359aab..b5464a2 100644
--- a/packages/SettingsLib/res/values-sv/arrays.xml
+++ b/packages/SettingsLib/res/values-sv/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Optimerad för anslutningskvalitet"</item>
     <item msgid="364670732877872677">"Bästa möjliga kvalitet (anpassad bithastighet)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktiv"</item>
+    <item msgid="8962366465966010158">", aktiv (media)"</item>
+    <item msgid="4046665544396189228">", aktiv (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Av"</item>
     <item msgid="1593289376502312923">"64 kB"</item>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index 77de1d7..d77c92d 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Imeimarishwa kwa ajili ya Ubora wa Muunganisho"</item>
     <item msgid="364670732877872677">"Kazi Bora Zaidi (Kasi Maalum ya Biti)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", inatumika"</item>
+    <item msgid="8962366465966010158">", inatumika (maudhui)"</item>
+    <item msgid="4046665544396189228">", inatumika (simu)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Imezimwa"</item>
     <item msgid="1593289376502312923">"K64"</item>
diff --git a/packages/SettingsLib/res/values-ta/arrays.xml b/packages/SettingsLib/res/values-ta/arrays.xml
index aa24fde..7b69c78 100644
--- a/packages/SettingsLib/res/values-ta/arrays.xml
+++ b/packages/SettingsLib/res/values-ta/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"இணைப்புத் தரத்திற்காக மேம்படுத்தியது"</item>
     <item msgid="364670732877872677">"சிறந்த முறை (அடாப்டிவ் பிட் வீதம்)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", செயலில் உள்ளது"</item>
+    <item msgid="8962366465966010158">", செயலில் உள்ளது (மீடியா)"</item>
+    <item msgid="4046665544396189228">", செயலில் உள்ளது (மொபைல்)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"ஆஃப்"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index ce99f63..2b3b919 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -138,6 +138,9 @@
     <item msgid="4681409244565426925">"కనెక్షన్ నాణ్యత కోసం అనుకూలీకరించబడింది"</item>
     <item msgid="364670732877872677">"ఉత్తమ కృషి (అనుకూల బిట్ రేట్)"</item>
   </string-array>
+    <!-- no translation found for bluetooth_audio_active_device_summaries:1 (6481691720774549651) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:2 (8962366465966010158) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:3 (4046665544396189228) -->
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"ఆఫ్"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index 29ccc6e..a5b3d2c 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"เพิ่มประสิทธิภาพสำหรับคุณภาพการเชื่อมต่อ"</item>
     <item msgid="364670732877872677">"ดีที่สุดเท่าที่ทำได้ (ปรับอัตราบิตอัตโนมัติ)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">"ใช้งานอยู่"</item>
+    <item msgid="8962366465966010158">"ใช้งานอยู่ (สื่อ)"</item>
+    <item msgid="4046665544396189228">"ใช้งานอยู่ (โทรศัพท์)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"ปิด"</item>
     <item msgid="1593289376502312923">"64 K"</item>
diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml
index e9e7fff..bfe358b 100644
--- a/packages/SettingsLib/res/values-tl/arrays.xml
+++ b/packages/SettingsLib/res/values-tl/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Naka-optimize para sa Kalidad ng Koneksyon"</item>
     <item msgid="364670732877872677">"Pinakamahusay na Pagsisikap (Adaptive Bit Rate)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", aktibo"</item>
+    <item msgid="8962366465966010158">", aktibo (media)"</item>
+    <item msgid="4046665544396189228">", aktibo (telepono)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"I-off"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml
index acf0051..141b4e2 100644
--- a/packages/SettingsLib/res/values-tr/arrays.xml
+++ b/packages/SettingsLib/res/values-tr/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Bağlantı Kalitesi için optimize edildi"</item>
     <item msgid="364670732877872677">"En İyi Sonuç (Uyarlanabilir Bit Hızı)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", etkin"</item>
+    <item msgid="8962366465966010158">", etkin (medya)"</item>
+    <item msgid="4046665544396189228">", etkin (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Kapalı"</item>
     <item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml
index 4a1c626..88a2aca 100644
--- a/packages/SettingsLib/res/values-uk/arrays.xml
+++ b/packages/SettingsLib/res/values-uk/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Оптимізовано для кращої якості з’єднання"</item>
     <item msgid="364670732877872677">"Найкраща якість (адаптивна швидкість передавання)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", активний"</item>
+    <item msgid="8962366465966010158">", активний (лише для медіа)"</item>
+    <item msgid="4046665544396189228">", активний (лише для телефона)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Вимкнено"</item>
     <item msgid="1593289376502312923">"64 КБ"</item>
diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml
index 5efc872..6e2f904 100644
--- a/packages/SettingsLib/res/values-ur/arrays.xml
+++ b/packages/SettingsLib/res/values-ur/arrays.xml
@@ -138,6 +138,9 @@
     <item msgid="4681409244565426925">"کنکشن کے معیار کیلئے بہتر بنایا گيا"</item>
     <item msgid="364670732877872677">"بہترین کوشش (اڈاپٹیو بٹ ریٹ)"</item>
   </string-array>
+    <!-- no translation found for bluetooth_audio_active_device_summaries:1 (6481691720774549651) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:2 (8962366465966010158) -->
+    <!-- no translation found for bluetooth_audio_active_device_summaries:3 (4046665544396189228) -->
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"آف"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml
index 95aa775..b3e4619 100644
--- a/packages/SettingsLib/res/values-uz/arrays.xml
+++ b/packages/SettingsLib/res/values-uz/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Ulanish tezligini optimallashtirish"</item>
     <item msgid="364670732877872677">"Yuqori sifat (moslashuvchan bitreyt)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", faol"</item>
+    <item msgid="8962366465966010158">", faol (media)"</item>
+    <item msgid="4046665544396189228">", faol (telefon)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"O‘chiq"</item>
     <item msgid="1593289376502312923">"64 KB"</item>
diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml
index e30bb8d..ccc6cee 100644
--- a/packages/SettingsLib/res/values-vi/arrays.xml
+++ b/packages/SettingsLib/res/values-vi/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Được tối ưu hóa cho chất lượng kết nối"</item>
     <item msgid="364670732877872677">"Nỗ lực cao nhất (Tốc độ bit thích ứng)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", đang hoạt động"</item>
+    <item msgid="8962366465966010158">", đang hoạt động (nội dung phương tiện)"</item>
+    <item msgid="4046665544396189228">", đang hoạt động (điện thoại)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Tắt"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
index 7b451ae..4ee055b 100644
--- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"偏重连接质量"</item>
     <item msgid="364670732877872677">"尽可能提供更佳音质(自适应比特率)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">",使用中"</item>
+    <item msgid="8962366465966010158">",使用中(媒体)"</item>
+    <item msgid="4046665544396189228">",使用中(手机)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"关闭"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 18e11cf..fd6e6ef 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -310,7 +310,7 @@
     <string name="enable_gpu_debug_layers_summary" msgid="8009136940671194940">"允许为调试应用加载 GPU 调试层"</string>
     <string name="window_animation_scale_title" msgid="6162587588166114700">"窗口动画缩放"</string>
     <string name="transition_animation_scale_title" msgid="387527540523595875">"过渡动画缩放"</string>
-    <string name="animator_duration_scale_title" msgid="3406722410819934083">"动画程序时长缩放"</string>
+    <string name="animator_duration_scale_title" msgid="3406722410819934083">"Animator 时长缩放"</string>
     <string name="overlay_display_devices_title" msgid="5364176287998398539">"模拟辅助显示设备"</string>
     <string name="debug_applications_category" msgid="4206913653849771549">"应用"</string>
     <string name="immediately_destroy_activities" msgid="1579659389568133959">"不保留活动"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/arrays.xml b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
index 6115976..a49a91d 100644
--- a/packages/SettingsLib/res/values-zh-rHK/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"已優化連線品質"</item>
     <item msgid="364670732877872677">"盡力傳送 (自動調整位元率)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">",使用中"</item>
+    <item msgid="8962366465966010158">",使用中 (媒體)"</item>
+    <item msgid="4046665544396189228">",使用中 (手機)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"關閉"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
index 9295b35..da4c886 100644
--- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"連線品質最佳化"</item>
     <item msgid="364670732877872677">"最佳效果 (自動調整位元率)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">",使用中"</item>
+    <item msgid="8962366465966010158">",使用中 (媒體)"</item>
+    <item msgid="4046665544396189228">",使用中 (手機)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"關閉"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/res/values-zu/arrays.xml b/packages/SettingsLib/res/values-zu/arrays.xml
index 6361dc1..93397c6 100644
--- a/packages/SettingsLib/res/values-zu/arrays.xml
+++ b/packages/SettingsLib/res/values-zu/arrays.xml
@@ -138,6 +138,12 @@
     <item msgid="4681409244565426925">"Kuthuthukiselwe ikhwalithi yoxhumo"</item>
     <item msgid="364670732877872677">"Amandla amahle (Adaptive Bit Rate)"</item>
   </string-array>
+  <string-array name="bluetooth_audio_active_device_summaries">
+    <item msgid="4862957058729193940"></item>
+    <item msgid="6481691720774549651">", iyasebenza"</item>
+    <item msgid="8962366465966010158">", iyasebenza (imidiya)"</item>
+    <item msgid="4046665544396189228">", iyasebenza (ifoni)"</item>
+  </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"Valiwe"</item>
     <item msgid="1593289376502312923">"64K"</item>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
index a0dfb5d..4c21e61 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
@@ -110,7 +110,7 @@
     }
 
     public boolean isConnectable() {
-        return true;
+        return false;
     }
 
     public boolean isAutoConnectable() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
index 660521e..573504a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
@@ -37,6 +37,13 @@
      * Updates the current status of preference (summary, switch state, etc)
      */
     public void updateState(Preference preference) {
+        refreshSummary(preference);
+    }
+
+    /**
+     * Refresh preference summary with getSummary()
+     */
+    protected void refreshSummary(Preference preference) {
         if (preference == null) {
             return;
         }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 7b76fce..85bbd59 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2935,7 +2935,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 166;
+            private static final int SETTINGS_VERSION = 167;
 
             private final int mUserId;
 
@@ -3522,14 +3522,7 @@
                 }
 
                 if (currentVersion == 150) {
-                    // Version 151: Reset rotate locked setting for upgrading users
-                    final SettingsState systemSettings = getSystemSettingsLocked(userId);
-                    systemSettings.insertSettingLocked(
-                            Settings.System.ACCELEROMETER_ROTATION,
-                            getContext().getResources().getBoolean(
-                                    R.bool.def_accelerometer_rotation) ? "1" : "0",
-                            null, true, SettingsState.SYSTEM_PACKAGE_NAME);
-
+                    // Version 151: Removed.
                     currentVersion = 151;
                 }
 
@@ -3777,6 +3770,28 @@
                     currentVersion = 166;
                 }
 
+                if (currentVersion == 166) {
+                    // Version 166: add default values for hush gesture used and manual ringer
+                    // toggle
+                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
+                    Setting currentHushUsedSetting = secureSettings.getSettingLocked(
+                            Secure.HUSH_GESTURE_USED);
+                    if (currentHushUsedSetting.isNull()) {
+                        secureSettings.insertSettingLocked(
+                                Settings.Secure.HUSH_GESTURE_USED, "0", null, true,
+                                SettingsState.SYSTEM_PACKAGE_NAME);
+                    }
+
+                    Setting currentRingerToggleCountSetting = secureSettings.getSettingLocked(
+                            Secure.MANUAL_RINGER_TOGGLE_COUNT);
+                    if (currentRingerToggleCountSetting.isNull()) {
+                        secureSettings.insertSettingLocked(
+                                Settings.Secure.MANUAL_RINGER_TOGGLE_COUNT, "0", null, true,
+                                SettingsState.SYSTEM_PACKAGE_NAME);
+                    }
+                    currentVersion = 167;
+                }
+
                 // vXXX: Add new settings above this point.
 
                 if (currentVersion != newVersion) {
diff --git a/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml b/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml
deleted file mode 100644
index 11a3bdd..0000000
--- a/packages/SystemUI/res/drawable/stat_sys_dnd_total_silence.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2017, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
-    android:insetLeft="2.5dp"
-    android:insetRight="2.5dp" >
-    <vector
-        android:width="16dp"
-        android:height="16dp"
-        android:viewportWidth="16.6"
-        android:viewportHeight="16.6">
-        <group
-            android:translateX="-0.2"
-            android:translateY="-0.2">
-            <path
-                android:pathData="M8.5,3.72c-2.62,0 -4.78,2.16 -4.78,4.78s2.16,4.78 4.78,4.78 4.78,-2.16 4.78,-4.78 -2.07,-4.78 -4.78,-4.78zM10.09,9.56L6.91,9.56c-0.59,0 -1.06,-0.48 -1.06,-1.06s0.48,-1.06 1.06,-1.06h3.19c0.59,0 1.06,0.48 1.06,1.06s-0.48,1.06 -1.07,1.06z"
-                android:fillColor="#FFF"/>
-            <path
-                android:pathData="M8.5,0.53C4.11,0.53 0.53,4.11 0.53,8.5s3.58,7.97 7.97,7.97 7.97,-3.58 7.97,-7.97S12.89,0.53 8.5,0.53zM8.5,15.28c-3.75,0 -6.78,-3.03 -6.78,-6.78S4.75,1.72 8.5,1.72s6.78,3.03 6.78,6.78 -3.03,6.78 -6.78,6.78z"
-                android:fillColor="#FFF"/>
-        </group>
-    </vector>
-</inset>
diff --git a/packages/SystemUI/res/layout/recents_onboarding.xml b/packages/SystemUI/res/layout/recents_onboarding.xml
index 6764eee..093a7ce1 100644
--- a/packages/SystemUI/res/layout/recents_onboarding.xml
+++ b/packages/SystemUI/res/layout/recents_onboarding.xml
@@ -48,7 +48,8 @@
             android:layout_marginEnd="2dp"
             android:alpha="0.7"
             android:src="@drawable/ic_close_white"
-            android:background="?android:attr/selectableItemBackgroundBorderless"/>
+            android:background="?android:attr/selectableItemBackgroundBorderless"
+            android:contentDescription="@string/accessibility_desc_close"/>
     </LinearLayout>
 
     <View
diff --git a/packages/SystemUI/res/layout/status_bar_notification_footer.xml b/packages/SystemUI/res/layout/status_bar_notification_footer.xml
index b4c2ba8..6c5cebc 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_footer.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_footer.xml
@@ -22,7 +22,7 @@
         android:paddingStart="4dp"
         android:paddingEnd="4dp"
         android:visibility="gone">
-    <FrameLayout
+    <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
         android:id="@+id/content"
         android:layout_width="match_parent"
         android:layout_height="wrap_content" >
@@ -46,5 +46,5 @@
             android:contentDescription="@string/accessibility_clear_all"
             android:text="@string/clear_all_notifications_text"
             android:textColor="?attr/wallpaperTextColor"/>
-    </FrameLayout>
+    </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
 </com.android.systemui.statusbar.FooterView>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 24d662b..cd8ffa8 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -61,6 +61,7 @@
     <item type="id" name="notification_temperature"/>
     <item type="id" name="notification_plugin"/>
     <item type="id" name="transformation_start_x_tag"/>
+    <item type="id" name="doze_intensity_tag"/>
     <item type="id" name="transformation_start_y_tag"/>
     <item type="id" name="transformation_start_actual_width"/>
     <item type="id" name="transformation_start_actual_height"/>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 654f407..edf56af 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1069,7 +1069,7 @@
     <string name="manage_notifications_text">Manage notifications</string>
 
     <!-- The text to show in the notifications shade when dnd is suppressing notifications. [CHAR LIMIT=100] -->
-    <string name="dnd_suppressing_shade_text">Do Not Disturb is hiding notifications</string>
+    <string name="dnd_suppressing_shade_text">Notifications paused by Do Not Disturb</string>
 
     <!-- Media projection permission dialog action text. [CHAR LIMIT=60] -->
     <string name="media_projection_action_text">Start now</string>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
index 3ecf89c..ebfadd8 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
@@ -54,4 +54,10 @@
      * Get the secondary split screen app's rectangle when not minimized.
      */
     Rect getNonMinimizedSplitScreenSecondaryBounds() = 7;
+
+    /**
+     * Control the {@param alpha} of the back button in the navigation bar and {@param animate} if
+     * needed from current value
+     */
+    void setBackButtonAlpha(float alpha, boolean animate) = 8;
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityCompat.java
index 0d8ce58..12699d5 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityCompat.java
@@ -17,6 +17,10 @@
 package com.android.systemui.shared.system;
 
 import android.app.Activity;
+import android.view.View;
+import android.view.ViewHierarchyEncoder;
+
+import java.io.ByteArrayOutputStream;
 
 public class ActivityCompat {
     private final Activity mWrapped;
@@ -31,4 +35,27 @@
     public void registerRemoteAnimations(RemoteAnimationDefinitionCompat definition) {
         mWrapped.registerRemoteAnimations(definition.getWrapped());
     }
+
+    /**
+     * @see android.view.ViewDebug#dumpv2(View, ByteArrayOutputStream)
+     */
+    public boolean encodeViewHierarchy(ByteArrayOutputStream out) {
+        View view = null;
+        if (mWrapped.getWindow() != null &&
+                mWrapped.getWindow().peekDecorView() != null &&
+                mWrapped.getWindow().peekDecorView().getViewRootImpl() != null) {
+            view = mWrapped.getWindow().peekDecorView().getViewRootImpl().getView();
+        }
+        if (view == null) {
+            return false;
+        }
+
+        final ViewHierarchyEncoder encoder = new ViewHierarchyEncoder(out);
+        int[] location = view.getLocationOnScreen();
+        encoder.addProperty("window:left", location[0]);
+        encoder.addProperty("window:top", location[1]);
+        view.encode(encoder);
+        encoder.endStream();
+        return true;
+    }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
index cc536a5..96ec232 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
@@ -62,8 +62,7 @@
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({FLAG_DISABLE_SWIPE_UP,
             FLAG_DISABLE_QUICK_SCRUB,
-            FLAG_SHOW_OVERVIEW_BUTTON,
-            FLAG_HIDE_BACK_BUTTON
+            FLAG_SHOW_OVERVIEW_BUTTON
     })
     public @interface InteractionType {}
 
@@ -82,11 +81,6 @@
      */
     public static final int FLAG_SHOW_OVERVIEW_BUTTON = 0x4;
 
-    /**
-     * Interaction type: show/hide the back button while this service is connected to launcher
-     */
-    public static final int FLAG_HIDE_BACK_BUTTON = 0x8;
-
     private static int convertDpToPixel(float dp){
         return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
     }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplier.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplier.java
new file mode 100644
index 0000000..9f7d0b2
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplier.java
@@ -0,0 +1,104 @@
+/*
+ * 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.graphics.Matrix;
+import android.graphics.Rect;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.view.View;
+import android.view.ViewRootImpl;
+
+import java.util.ArrayList;
+
+/**
+ * Helper class to apply surface transactions in sync with RenderThread.
+ */
+public class SyncRtSurfaceTransactionApplier {
+
+    private final Surface mTargetSurface;
+    private final ViewRootImpl mTargetViewRootImpl;
+    private final float[] mTmpFloat9 = new float[9];
+
+    /**
+     * @param targetView The view in the surface that acts as synchronization anchor.
+     */
+    public SyncRtSurfaceTransactionApplier(View targetView) {
+        mTargetViewRootImpl = targetView != null ? targetView.getViewRootImpl() : null;
+        mTargetSurface = mTargetViewRootImpl != null ? mTargetViewRootImpl.mSurface : null;
+    }
+
+    /**
+     * Schedules applying surface parameters on the next frame.
+     *
+     * @param params The surface parameters to apply. DO NOT MODIFY the list after passing into
+     *               this method to avoid synchronization issues.
+     */
+    public void scheduleApply(SurfaceParams... params) {
+        if (mTargetViewRootImpl == null) {
+            return;
+        }
+        mTargetViewRootImpl.registerRtFrameCallback(frame -> {
+                if (mTargetSurface == null || !mTargetSurface.isValid()) {
+                    return;
+                }
+                SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+                for (int i = params.length - 1; i >= 0; i--) {
+                    SurfaceParams surfaceParams = params[i];
+                    SurfaceControl surface = surfaceParams.surface;
+                    t.deferTransactionUntilSurface(surface, mTargetSurface, frame);
+                    t.setMatrix(surface, surfaceParams.matrix, mTmpFloat9);
+                    t.setWindowCrop(surface, surfaceParams.windowCrop);
+                    t.setAlpha(surface, surfaceParams.alpha);
+                    t.setLayer(surface, surfaceParams.layer);
+                    t.show(surface);
+                }
+                t.setEarlyWakeup();
+                t.apply();
+        });
+
+        // Make sure a frame gets scheduled.
+        mTargetViewRootImpl.getView().invalidate();
+    }
+
+    public static class SurfaceParams {
+
+        /**
+         * Constructs surface parameters to be applied when the current view state gets pushed to
+         * RenderThread.
+         *
+         * @param surface The surface to modify.
+         * @param alpha Alpha to apply.
+         * @param matrix Matrix to apply.
+         * @param windowCrop Crop to apply.
+         */
+        public SurfaceParams(SurfaceControlCompat surface, float alpha, Matrix matrix,
+                Rect windowCrop, int layer) {
+            this.surface = surface.mSurfaceControl;
+            this.alpha = alpha;
+            this.matrix = new Matrix(matrix);
+            this.windowCrop = new Rect(windowCrop);
+            this.layer = layer;
+        }
+
+        final SurfaceControl surface;
+        final float alpha;
+        final Matrix matrix;
+        final Rect windowCrop;
+        final int layer;
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
index 7db3ac6..f9aa8da 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
@@ -17,6 +17,7 @@
 package com.android.systemui.shared.system;
 
 import android.app.ActivityManager.TaskSnapshot;
+import android.content.ComponentName;
 import android.os.UserHandle;
 import android.util.Log;
 
@@ -43,6 +44,7 @@
     public void onActivityDismissingDockedStack() { }
     public void onActivityLaunchOnSecondaryDisplayFailed() { }
     public void onTaskProfileLocked(int taskId, int userId) { }
+    public void onTaskCreated(int taskId, ComponentName componentName) { }
     public void onTaskRemoved(int taskId) { }
     public void onTaskMovedToFront(int taskId) { }
     public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation) { }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
index 857e0ea..5e293c6 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
@@ -19,6 +19,7 @@
 import android.app.ActivityManager.TaskSnapshot;
 import android.app.IActivityManager;
 import android.app.TaskStackListener;
+import android.content.ComponentName;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -140,12 +141,16 @@
     }
 
     @Override
-    public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot)
-            throws RemoteException {
+    public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) throws RemoteException {
         mHandler.obtainMessage(H.ON_TASK_SNAPSHOT_CHANGED, taskId, 0, snapshot).sendToTarget();
     }
 
     @Override
+    public void onTaskCreated(int taskId, ComponentName componentName) throws RemoteException {
+        mHandler.obtainMessage(H.ON_TASK_CREATED, taskId, 0, componentName).sendToTarget();
+    }
+
+    @Override
     public void onTaskRemoved(int taskId) throws RemoteException {
         mHandler.obtainMessage(H.ON_TASK_REMOVED, taskId, 0).sendToTarget();
     }
@@ -174,9 +179,10 @@
         private static final int ON_PINNED_STACK_ANIMATION_STARTED = 9;
         private static final int ON_ACTIVITY_UNPINNED = 10;
         private static final int ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED = 11;
-        private static final int ON_TASK_REMOVED = 12;
-        private static final int ON_TASK_MOVED_TO_FRONT = 13;
-        private static final int ON_ACTIVITY_REQUESTED_ORIENTATION_CHANGE = 14;
+        private static final int ON_TASK_CREATED = 12;
+        private static final int ON_TASK_REMOVED = 13;
+        private static final int ON_TASK_MOVED_TO_FRONT = 14;
+        private static final int ON_ACTIVITY_REQUESTED_ORIENTATION_CHANGE = 15;
 
 
         public H(Looper looper) {
@@ -262,6 +268,13 @@
                         }
                         break;
                     }
+                    case ON_TASK_CREATED: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onTaskCreated(msg.arg1,
+                                    (ComponentName) msg.obj);
+                        }
+                        break;
+                    }
                     case ON_TASK_REMOVED: {
                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                             mTaskStackListeners.get(i).onTaskRemoved(msg.arg1);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index 174dcab..f399667 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -373,7 +373,6 @@
 
     @Override
     public void onResume(int reason) {
-        reset();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 9f382b00..62cd13b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -708,6 +708,11 @@
         return mStrongAuthTracker.isUnlockingWithFingerprintAllowed();
     }
 
+    public boolean isUserInLockdown(int userId) {
+        return mStrongAuthTracker.getStrongAuthForUser(userId)
+                == LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
+    }
+
     public boolean needsSlowUnlockTransition() {
         return mNeedsSlowUnlockTransition;
     }
@@ -750,7 +755,7 @@
     private DisplayClientState mDisplayClientState = new DisplayClientState();
 
     @VisibleForTesting
-    final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+    protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
 
         @Override
         public void onReceive(Context context, Intent intent) {
diff --git a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
index 9307c22..42bd66a 100644
--- a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
@@ -161,6 +161,19 @@
                 Binder.restoreCallingIdentity(token);
             }
         }
+
+        public void setBackButtonAlpha(float alpha, boolean animate) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mHandler.post(() -> {
+                    for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
+                        mConnectionCallbacks.get(i).onBackButtonAlphaChanged(alpha, animate);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
     };
 
     private final Runnable mDeferredConnectionCallback = () -> {
@@ -389,5 +402,6 @@
         default void onInteractionFlagsChanged(@InteractionType int flags) {}
         default void onOverviewShown(boolean fromHome) {}
         default void onQuickScrubStarted() {}
+        default void onBackButtonAlphaChanged(float alpha, boolean animate) {}
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 8d32e4d..139215a0 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -554,7 +554,18 @@
                 return null;
             }
 
-            return mInfo.displayCutout.getBounds();
+            View rootView = getRootView();
+            Region cutoutBounds = mInfo.displayCutout.getBounds();
+
+            // Transform to window's coordinate space
+            rootView.getLocationOnScreen(mLocation);
+            cutoutBounds.translate(-mLocation[0], -mLocation[1]);
+
+            // Intersect with window's frame
+            cutoutBounds.op(rootView.getLeft(), rootView.getTop(), rootView.getRight(),
+                    rootView.getBottom(), Region.Op.INTERSECT);
+
+            return cutoutBounds;
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java b/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java
deleted file mode 100644
index 2c96e31..0000000
--- a/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2014 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;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Paint;
-import android.view.View;
-
-import java.util.ArrayList;
-
-/**
- * Helper to invert the colors of views and fade between the states.
- */
-public class ViewInvertHelper {
-
-    private final Paint mDarkPaint = new Paint();
-    private final ColorMatrix mMatrix = new ColorMatrix();
-    private final ColorMatrix mGrayscaleMatrix = new ColorMatrix();
-    private final long mFadeDuration;
-    private final ArrayList<View> mTargets = new ArrayList<>();
-
-    public ViewInvertHelper(View v, long fadeDuration) {
-        this(v.getContext(), fadeDuration);
-        addTarget(v);
-    }
-    public ViewInvertHelper(Context context, long fadeDuration) {
-        mFadeDuration = fadeDuration;
-    }
-
-    private static ArrayList<View> constructArray(View target) {
-        final ArrayList<View> views = new ArrayList<>();
-        views.add(target);
-        return views;
-    }
-
-    public void clearTargets() {
-        mTargets.clear();
-    }
-
-    public void addTarget(View target) {
-        mTargets.add(target);
-    }
-
-    public void fade(final boolean invert, long delay) {
-        float startIntensity = invert ? 0f : 1f;
-        float endIntensity = invert ? 1f : 0f;
-        ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
-        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                updateInvertPaint((Float) animation.getAnimatedValue());
-                for (int i = 0; i < mTargets.size(); i++) {
-                    mTargets.get(i).setLayerType(View.LAYER_TYPE_HARDWARE, mDarkPaint);
-                }
-            }
-        });
-        animator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (!invert) {
-                    for (int i = 0; i < mTargets.size(); i++) {
-                        mTargets.get(i).setLayerType(View.LAYER_TYPE_NONE, null);
-                    }
-                }
-            }
-        });
-        animator.setDuration(mFadeDuration);
-        animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
-        animator.setStartDelay(delay);
-        animator.start();
-    }
-
-    public void update(boolean invert) {
-        if (invert) {
-            updateInvertPaint(1f);
-            for (int i = 0; i < mTargets.size(); i++) {
-                mTargets.get(i).setLayerType(View.LAYER_TYPE_HARDWARE, mDarkPaint);
-            }
-        } else {
-            for (int i = 0; i < mTargets.size(); i++) {
-                mTargets.get(i).setLayerType(View.LAYER_TYPE_NONE, null);
-            }
-        }
-    }
-
-    private void updateInvertPaint(float intensity) {
-        float components = 1 - 2 * intensity;
-        final float[] invert = {
-                components, 0f,         0f,         0f, 255f * intensity,
-                0f,         components, 0f,         0f, 255f * intensity,
-                0f,         0f,         components, 0f, 255f * intensity,
-                0f,         0f,         0f,         1f, 0f
-        };
-        mMatrix.set(invert);
-        mGrayscaleMatrix.setSaturation(1 - intensity);
-        mMatrix.preConcat(mGrayscaleMatrix);
-        mDarkPaint.setColorFilter(new ColorMatrixColorFilter(mMatrix));
-    }
-
-    public void setInverted(boolean invert, boolean fade, long delay) {
-        if (fade) {
-            fade(invert, delay);
-        } else {
-            update(invert);
-        }
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
index 9a8512d..f9bf4f5 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
@@ -23,14 +23,18 @@
 import android.view.View;
 
 import com.android.systemui.ConfigurationChangedReceiver;
+import com.android.systemui.Dumpable;
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIApplication;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
 /**
  * Holds a map of root views to FragmentHostStates and generates them as needed.
  * Also dispatches the configuration changes to all current FragmentHostStates.
  */
-public class FragmentService implements ConfigurationChangedReceiver {
+public class FragmentService implements ConfigurationChangedReceiver, Dumpable {
 
     private static final String TAG = "FragmentService";
 
@@ -65,6 +69,14 @@
         }
     }
 
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("Dumping fragments:");
+        for (FragmentHostState state : mHosts.values()) {
+            state.mFragmentHostManager.getFragmentManager().dump("  ", fd, pw, args);
+        }
+    }
+
     private class FragmentHostState {
         private final View mView;
 
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 4b65288..d232108 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -690,7 +690,7 @@
     }
 
     private Action getLockdownAction() {
-        return new SinglePressAction(com.android.systemui.R.drawable.ic_lock_lockdown,
+        return new SinglePressAction(R.drawable.ic_lock_lockdown,
                 R.string.global_action_lockdown) {
 
             @Override
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
index b2a80f4..4a67868 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.media;
 
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.DialogInterface;
@@ -36,6 +38,7 @@
 import android.text.TextUtils;
 import android.text.style.StyleSpan;
 import android.util.Log;
+import android.view.Window;
 import android.view.WindowManager;
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
@@ -146,7 +149,9 @@
         mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setFilterTouchesWhenObscured(true);
 
         ((CheckBox) mDialog.findViewById(R.id.remember)).setOnCheckedChangeListener(this);
-        mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+        final Window w = mDialog.getWindow();
+        w.setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+        w.addPrivateFlags(PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
 
         mDialog.show();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
index 69b0f31..ff0c11d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
@@ -33,6 +33,7 @@
 import android.annotation.TargetApi;
 import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -46,6 +47,7 @@
 import android.os.SystemProperties;
 import android.os.UserManager;
 import android.os.RemoteException;
+import android.util.Log;
 import android.util.TypedValue;
 import android.view.Gravity;
 import android.view.LayoutInflater;
@@ -63,8 +65,8 @@
 import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.LauncherEventUtil;
 
+import java.io.PrintWriter;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
@@ -110,8 +112,19 @@
     private int mOverviewOpenedCountSinceQuickScrubTipDismiss;
 
     private final SysUiTaskStackChangeListener mTaskListener = new SysUiTaskStackChangeListener() {
+        private String mLastPackageName;
+
         @Override
-        public void onTaskStackChanged() {
+        public void onTaskCreated(int taskId, ComponentName componentName) {
+            onAppLaunch();
+        }
+
+        @Override
+        public void onTaskMovedToFront(int taskId) {
+            onAppLaunch();
+        }
+
+        private void onAppLaunch() {
             ActivityManager.RunningTaskInfo info = ActivityManagerWrapper.getInstance()
                     .getRunningTask(ACTIVITY_TYPE_UNDEFINED /* ignoreActivityType */);
             if (info == null) {
@@ -121,6 +134,10 @@
                 hide(true);
                 return;
             }
+            if (info.baseActivity.getPackageName().equals(mLastPackageName)) {
+                return;
+            }
+            mLastPackageName = info.baseActivity.getPackageName();
             int activityType = info.configuration.windowConfiguration.getActivityType();
             if (activityType == ACTIVITY_TYPE_STANDARD) {
                 boolean alreadySeenSwipeUpOnboarding = hasSeenSwipeUpOnboarding();
@@ -208,12 +225,15 @@
             = new View.OnAttachStateChangeListener() {
         @Override
         public void onViewAttachedToWindow(View view) {
+            Log.d(TAG, "View attached");
             if (view == mLayout) {
                 mContext.registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
                 mLayoutAttachedToWindow = true;
                 if (view.getTag().equals(R.string.recents_swipe_up_onboarding)) {
+                    Log.d(TAG, "recents_swipe_up_onboarding tip attached");
                     mHasDismissedSwipeUpTip = false;
                 } else {
+                    Log.d(TAG, "recents_quick_scrub_onboarding tip attached");
                     mHasDismissedQuickScrubTip = false;
                 }
             }
@@ -221,9 +241,11 @@
 
         @Override
         public void onViewDetachedFromWindow(View view) {
+            Log.d(TAG, "View detached");
             if (view == mLayout) {
                 mLayoutAttachedToWindow = false;
                 if (view.getTag().equals(R.string.recents_quick_scrub_onboarding)) {
+                    Log.d(TAG, "recents_quick_scrub_onboarding tip detached");
                     mHasDismissedQuickScrubTip = true;
                     if (hasDismissedQuickScrubOnboardingOnce()) {
                         // If user dismisses the quick scrub tip twice, we consider user has seen it
@@ -306,22 +328,29 @@
             return;
         }
 
+        Log.d(TAG, "Connecting to launcher");
         if (!mOverviewProxyListenerRegistered) {
+            Log.d(TAG, "Registering mOverviewProxyListener");
             mOverviewProxyService.addCallback(mOverviewProxyListener);
             mOverviewProxyListenerRegistered = true;
         }
         if (!mTaskListenerRegistered) {
+            Log.d(TAG, "Registering mTaskListener");
             ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskListener);
             mTaskListenerRegistered = true;
         }
     }
 
     public void onDisconnectedFromLauncher() {
+        Log.d(TAG, "Disconnecting to launcher");
+
         if (mOverviewProxyListenerRegistered) {
+            Log.d(TAG, "Unregistering mOverviewProxyListener");
             mOverviewProxyService.removeCallback(mOverviewProxyListener);
             mOverviewProxyListenerRegistered = false;
         }
         if (mTaskListenerRegistered) {
+            Log.d(TAG, "Unregistering mTaskListener");
             ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskListener);
             mTaskListenerRegistered = false;
         }
@@ -349,6 +378,8 @@
         // Only show in portrait.
         int orientation = mContext.getResources().getConfiguration().orientation;
         if (!mLayoutAttachedToWindow && orientation == Configuration.ORIENTATION_PORTRAIT) {
+            Log.d(TAG, "Show " + (stringRes == R.string.recents_swipe_up_onboarding
+                    ? "recents_swipe_up_onboarding" : "recents_quick_scrub_onboarding") + " tip");
             mLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
 
             mWindowManager.addView(mLayout, getWindowLayoutParams());
@@ -377,6 +408,7 @@
 
     public void hide(boolean animate) {
         if (mLayoutAttachedToWindow) {
+            Log.d(TAG, "Hide tip, animated: " + animate);
             if (animate) {
                 mLayout.animate()
                         .alpha(0f)
@@ -397,6 +429,24 @@
         mNavBarHeight = navBarHeight;
     }
 
+    public void dump(PrintWriter pw) {
+        pw.println("RecentsOnboarding {");
+        pw.println("      mTaskListenerRegistered: " + mTaskListenerRegistered);
+        pw.println("      mOverviewProxyListenerRegistered: " + mOverviewProxyListenerRegistered);
+        pw.println("      mLayoutAttachedToWindow: " + mLayoutAttachedToWindow);
+        pw.println("      mHasDismissedSwipeUpTip: " + mHasDismissedSwipeUpTip);
+        pw.println("      mHasDismissedQuickScrubTip: " + mHasDismissedQuickScrubTip);
+        pw.println("      mNumAppsLaunchedSinceSwipeUpTipDismiss: "
+                + mNumAppsLaunchedSinceSwipeUpTipDismiss);
+        pw.println("      hasSeenSwipeUpOnboarding: " + hasSeenSwipeUpOnboarding());
+        pw.println("      hasSeenQuickScrubOnboarding: " + hasSeenQuickScrubOnboarding());
+        pw.println("      hasDismissedQuickScrubOnboardingOnce: "
+                + hasDismissedQuickScrubOnboardingOnce());
+        pw.println("      getOpenedOverviewCount: " + getOpenedOverviewCount());
+        pw.println("      getOpenedOverviewFromHomeCount: " + getOpenedOverviewFromHomeCount());
+        pw.println("    }");
+    }
+
     private WindowManager.LayoutParams getWindowLayoutParams() {
         int flags = WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -418,6 +468,7 @@
     }
 
     private void setHasSeenSwipeUpOnboarding(boolean hasSeenSwipeUpOnboarding) {
+        Log.d(TAG, "setHasSeenSwipeUpOnboarding: " + hasSeenSwipeUpOnboarding);
         Prefs.putBoolean(mContext, HAS_SEEN_RECENTS_SWIPE_UP_ONBOARDING, hasSeenSwipeUpOnboarding);
         if (hasSeenSwipeUpOnboarding && hasSeenQuickScrubOnboarding()) {
             onDisconnectedFromLauncher();
@@ -429,6 +480,7 @@
     }
 
     private void setHasSeenQuickScrubOnboarding(boolean hasSeenQuickScrubOnboarding) {
+        Log.d(TAG, "setHasSeenQuickScrubOnboarding: " + hasSeenQuickScrubOnboarding);
         Prefs.putBoolean(mContext, HAS_SEEN_RECENTS_QUICK_SCRUB_ONBOARDING,
                 hasSeenQuickScrubOnboarding);
         if (hasSeenQuickScrubOnboarding && hasSeenSwipeUpOnboarding()) {
@@ -442,6 +494,8 @@
 
     private void setHasDismissedQuickScrubOnboardingOnce(
             boolean hasDismissedQuickScrubOnboardingOnce) {
+        Log.d(TAG,
+                "setHasDismissedQuickScrubOnboardingOnce: " + hasDismissedQuickScrubOnboardingOnce);
         Prefs.putBoolean(mContext, HAS_DISMISSED_RECENTS_QUICK_SCRUB_ONBOARDING_ONCE,
                 hasDismissedQuickScrubOnboardingOnce);
     }
@@ -451,6 +505,7 @@
     }
 
     private void setOpenedOverviewFromHomeCount(int openedOverviewFromHomeCount) {
+        Log.d(TAG, "setOpenedOverviewFromHomeCount: " + openedOverviewFromHomeCount);
         Prefs.putInt(mContext, OVERVIEW_OPENED_FROM_HOME_COUNT, openedOverviewFromHomeCount);
     }
 
@@ -459,6 +514,7 @@
     }
 
     private void setOpenedOverviewCount(int openedOverviewCount) {
+        Log.d(TAG, "setOpenedOverviewCount: " + openedOverviewCount);
         Prefs.putInt(mContext, OVERVIEW_OPENED_COUNT, openedOverviewCount);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 8d89314..3eb3160 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -778,10 +778,19 @@
             mHandle.setAlpha(minimized ? 0f : 1f);
             mDockedStackMinimized = minimized;
         } else if (mDockedStackMinimized != minimized) {
-            mMinimizedSnapAlgorithm = null;
             mDockedStackMinimized = minimized;
-            initializeSnapAlgorithm();
-            if (mIsInMinimizeInteraction != minimized) {
+            if (mDisplayRotation != mDefaultDisplay.getRotation()) {
+                // Splitscreen to minimize is about to starts after rotating landscape to seascape,
+                // update insets, display info and snap algorithm targets
+                SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
+                repositionSnapTargetBeforeMinimized();
+                updateDisplayInfo();
+            } else {
+                mMinimizedSnapAlgorithm = null;
+                initializeSnapAlgorithm();
+            }
+            if (mIsInMinimizeInteraction != minimized || mCurrentAnimator != null) {
+                cancelFlingAnimation();
                 if (minimized) {
                     // Relayout to recalculate the divider shadow when minimizing
                     requestLayout();
@@ -1017,7 +1026,6 @@
             if (mDockSide == DOCKED_RIGHT) {
                 mDockedTaskRect.offset(Math.max(position, mStableInsets.left - mDividerSize)
                         - mDockedTaskRect.left + mDividerSize, 0);
-                mOtherTaskRect.offset(mStableInsets.left, 0);
             }
             mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedTaskRect,
                     mOtherTaskRect, null);
@@ -1031,7 +1039,6 @@
             if (mDockSide == DOCKED_RIGHT) {
                 mDockedTaskRect.offset(Math.max(position, mStableInsets.left - mDividerSize)
                         - mDockedTaskRect.left + mDividerSize, 0);
-                mOtherTaskRect.offset(mStableInsets.left, 0);
             }
             calculateBoundsForPosition(taskPosition, DockedDividerUtils.invertDockSide(mDockSide),
                     mOtherTaskRect);
@@ -1048,7 +1055,6 @@
             // Move a right-docked-app to line up with the divider while dragging it
             if (mDockSide == DOCKED_RIGHT) {
                 mDockedTaskRect.offset(position - mStableInsets.left + mDividerSize, 0);
-                mOtherTaskRect.offset(mStableInsets.left, 0);
             }
             mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedInsetRect,
                     mOtherTaskRect, mOtherInsetRect);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AppOpsInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/AppOpsInfo.java
index cfc4da4..7999a6c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AppOpsInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AppOpsInfo.java
@@ -186,6 +186,11 @@
     }
 
     @Override
+    public boolean shouldBeSaved() {
+        return false;
+    }
+
+    @Override
     public View getContentView() {
         return this;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
index 011be88..4da1558 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
@@ -84,8 +84,7 @@
             if (view instanceof EmptyShadeView) {
                 EmptyShadeView emptyShadeView = (EmptyShadeView) view;
                 boolean visible = this.clipTopAmount <= mEmptyText.getPaddingTop() * 0.6f;
-                emptyShadeView.performVisibilityAnimation(
-                        visible && !emptyShadeView.willBeGone());
+                emptyShadeView.setContentVisible(visible && emptyShadeView.isVisible());
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index b010199..d03da8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -2286,6 +2286,11 @@
     @Override
     public void setHideSensitive(boolean hideSensitive, boolean animated, long delay,
             long duration) {
+        if (getVisibility() == GONE) {
+            // If we are GONE, the hideSensitive parameter will not be calculated and always be
+            // false, which is incorrect, let's wait until a real call comes in later.
+            return;
+        }
         boolean oldShowingPublic = mShowingPublic;
         mShowingPublic = mSensitive && hideSensitive;
         if (mShowingPublicInitialized && mShowingPublic == oldShowingPublic) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/FooterView.java
index 0f4b621..dc5bb9a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FooterView.java
@@ -98,7 +98,7 @@
             if (view instanceof FooterView) {
                 FooterView footerView = (FooterView) view;
                 boolean visible = this.clipTopAmount < mClearAllTopPadding;
-                footerView.performVisibilityAnimation(visible && !footerView.willBeGone());
+                footerView.setContentVisible(visible && footerView.isVisible());
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 08d530b..952c961 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -422,7 +422,6 @@
         mContractedChild = child;
         mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child,
                 mContainingNotification);
-        mContractedWrapper.setDark(mDark, false /* animate */, 0 /* delay */);
     }
 
     private NotificationViewWrapper getWrapperForView(View child) {
@@ -1106,18 +1105,6 @@
             return;
         }
         mDark = dark;
-        if (mVisibleType == VISIBLE_TYPE_CONTRACTED || !dark) {
-            mContractedWrapper.setDark(dark, fade, delay);
-        }
-        if (mVisibleType == VISIBLE_TYPE_EXPANDED || (mExpandedChild != null && !dark)) {
-            mExpandedWrapper.setDark(dark, fade, delay);
-        }
-        if (mVisibleType == VISIBLE_TYPE_HEADSUP || (mHeadsUpChild != null && !dark)) {
-            mHeadsUpWrapper.setDark(dark, fade, delay);
-        }
-        if (mSingleLineView != null && (mVisibleType == VISIBLE_TYPE_SINGLELINE || !dark)) {
-            mSingleLineView.setDark(dark, fade, delay);
-        }
         selectLayout(!dark && fade /* animate */, false /* force */);
     }
 
@@ -1397,6 +1384,13 @@
             smartReplyContainer.setVisibility(View.GONE);
             return null;
         }
+        // If we are keeping the notification around while sending we don't want to add the buttons.
+        boolean hideSmartReplies = entry.notification.getNotification()
+                .extras.getBoolean(Notification.EXTRA_HIDE_SMART_REPLIES, false);
+        if (hideSmartReplies) {
+            smartReplyContainer.setVisibility(View.GONE);
+            return null;
+        }
         SmartReplyView smartReplyView = null;
         if (smartReplyContainer.getChildCount() == 0) {
             smartReplyView = SmartReplyView.inflate(mContext, smartReplyContainer);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
index f14ca71..30fa0c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
@@ -113,6 +113,8 @@
             Dependency.get(ForegroundServiceController.class);
     protected final NotificationListener mNotificationListener =
             Dependency.get(NotificationListener.class);
+    private final SmartReplyController mSmartReplyController =
+            Dependency.get(SmartReplyController.class);
 
     protected IStatusBarService mBarService;
     protected NotificationPresenter mPresenter;
@@ -127,6 +129,13 @@
     protected boolean mDisableNotificationAlerts;
     protected NotificationListContainer mListContainer;
     private ExpandableNotificationRow.OnAppOpsClickListener mOnAppOpsClickListener;
+    /**
+     * Notifications with keys in this set are not actually around anymore. We kept them around
+     * when they were canceled in response to a remote input interaction. This allows us to show
+     * what you replied and allows you to continue typing into it.
+     */
+    private final ArraySet<String> mKeysKeptForRemoteInput = new ArraySet<>();
+
 
     private final class NotificationClicker implements View.OnClickListener {
 
@@ -220,6 +229,8 @@
         }
         pw.print("  mUseHeadsUp=");
         pw.println(mUseHeadsUp);
+        pw.print("  mKeysKeptForRemoteInput: ");
+        pw.println(mKeysKeptForRemoteInput);
     }
 
     public NotificationEntryManager(Context context) {
@@ -374,6 +385,12 @@
         final NotificationVisibility nv = NotificationVisibility.obtain(n.getKey(), rank, count,
                 true);
         NotificationData.Entry entry = mNotificationData.get(n.getKey());
+
+        if (FORCE_REMOTE_INPUT_HISTORY
+                && mKeysKeptForRemoteInput.contains(n.getKey())) {
+            mKeysKeptForRemoteInput.remove(n.getKey());
+        }
+
         mRemoteInputManager.onPerformRemoveNotification(n, entry);
         final String pkg = n.getPackageName();
         final String tag = n.getTag();
@@ -491,10 +508,35 @@
             }
             if (updated) {
                 Log.w(TAG, "Keeping notification around after sending remote input "+ entry.key);
-                mRemoteInputManager.getKeysKeptForRemoteInput().add(entry.key);
+                addKeyKeptForRemoteInput(entry.key);
                 return;
             }
         }
+
+        if (FORCE_REMOTE_INPUT_HISTORY
+                && shouldKeepForSmartReply(entry)
+                && entry.row != null && !entry.row.isDismissed()) {
+            // Turn off the spinner and hide buttons when an app cancels the notification.
+            StatusBarNotification newSbn = rebuildNotificationForCanceledSmartReplies(entry);
+            boolean updated = false;
+            try {
+                updateNotificationInternal(newSbn, null);
+                updated = true;
+            } catch (InflationException e) {
+                // Ignore just don't keep the notification around.
+            }
+            // Treat the reply as longer sending.
+            mSmartReplyController.stopSending(entry);
+            if (updated) {
+                Log.w(TAG, "Keeping notification around after sending smart reply " + entry.key);
+                addKeyKeptForRemoteInput(entry.key);
+                return;
+            }
+        }
+
+        // Actually removing notification so smart reply controller can forget about it.
+        mSmartReplyController.stopSending(entry);
+
         if (deferRemoval) {
             mLatestRankingMap = ranking;
             mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key));
@@ -536,18 +578,21 @@
 
         Notification.Builder b = Notification.Builder
                 .recoverBuilder(mContext, sbn.getNotification().clone());
-        CharSequence[] oldHistory = sbn.getNotification().extras
-                .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
-        CharSequence[] newHistory;
-        if (oldHistory == null) {
-            newHistory = new CharSequence[1];
-        } else {
-            newHistory = new CharSequence[oldHistory.length + 1];
-            System.arraycopy(oldHistory, 0, newHistory, 1, oldHistory.length);
+        if (remoteInputText != null) {
+            CharSequence[] oldHistory = sbn.getNotification().extras
+                    .getCharSequenceArray(Notification.EXTRA_REMOTE_INPUT_HISTORY);
+            CharSequence[] newHistory;
+            if (oldHistory == null) {
+                newHistory = new CharSequence[1];
+            } else {
+                newHistory = new CharSequence[oldHistory.length + 1];
+                System.arraycopy(oldHistory, 0, newHistory, 1, oldHistory.length);
+            }
+            newHistory[0] = String.valueOf(remoteInputText);
+            b.setRemoteInputHistory(newHistory);
         }
-        newHistory[0] = String.valueOf(remoteInputText);
-        b.setRemoteInputHistory(newHistory);
         b.setShowRemoteInputSpinner(showSpinner);
+        b.setHideSmartReplies(true);
 
         Notification newNotification = b.build();
 
@@ -563,6 +608,17 @@
         return newSbn;
     }
 
+    @VisibleForTesting
+    StatusBarNotification rebuildNotificationForCanceledSmartReplies(
+            NotificationData.Entry entry) {
+        return rebuildNotificationWithRemoteInput(entry, null /* remoteInputTest */,
+                false /* showSpinner */);
+    }
+
+    private boolean shouldKeepForSmartReply(NotificationData.Entry entry) {
+        return entry != null && mSmartReplyController.isSendingSmartReply(entry.key);
+    }
+
     private boolean shouldKeepForRemoteInput(NotificationData.Entry entry) {
         if (entry == null) {
             return false;
@@ -792,6 +848,7 @@
         }
         mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
         mRemoteInputManager.onUpdateNotification(entry);
+        mSmartReplyController.stopSending(entry);
 
         if (key.equals(mGutsManager.getKeyToRemoveOnGutsClosed())) {
             mGutsManager.setKeyToRemoveOnGutsClosed(null);
@@ -955,6 +1012,20 @@
         return mHeadsUpManager.isHeadsUp(key);
     }
 
+    public boolean isNotificationKeptForRemoteInput(String key) {
+        return mKeysKeptForRemoteInput.contains(key);
+    }
+
+    public void removeKeyKeptForRemoteInput(String key) {
+        mKeysKeptForRemoteInput.remove(key);
+    }
+
+    public void addKeyKeptForRemoteInput(String key) {
+        if (FORCE_REMOTE_INPUT_HISTORY) {
+            mKeysKeptForRemoteInput.add(key);
+        }
+    }
+
     /**
      * Callback for NotificationEntryManager.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index eb46fba..cfd5d83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -63,12 +63,12 @@
         public void setGutsParent(NotificationGuts listener);
 
         /**
-         * @return the view to be shown in the notification guts.
+         * Return the view to be shown in the notification guts.
          */
         public View getContentView();
 
         /**
-         * @return the actual height of the content.
+         * Return the actual height of the content.
          */
         public int getActualHeight();
 
@@ -83,16 +83,21 @@
         public boolean handleCloseControls(boolean save, boolean force);
 
         /**
-         * @return whether the notification associated with these guts is set to be removed.
+         * Return whether the notification associated with these guts is set to be removed.
          */
         public boolean willBeRemoved();
 
         /**
-         * @return whether these guts are a leavebehind (e.g. {@link NotificationSnooze}).
+         * Return whether these guts are a leavebehind (e.g. {@link NotificationSnooze}).
          */
         public default boolean isLeavebehind() {
             return false;
         }
+
+        /**
+         * Return whether something changed and needs to be saved, possibly requiring a bouncer.
+         */
+        boolean shouldBeSaved();
     }
 
     public interface OnGutsClosedListener {
@@ -201,12 +206,19 @@
         setExposed(true /* exposed */, needsFalsingProtection);
     }
 
+    /**
+     * Hide controls if they are visible
+     * @param leavebehinds true if leavebehinds should be closed
+     * @param controls true if controls should be closed
+     * @param x x coordinate to animate the close circular reveal with
+     * @param y y coordinate to animate the close circular reveal with
+     * @param force whether the guts should be force-closed regardless of state.
+     */
     public void closeControls(boolean leavebehinds, boolean controls, int x, int y, boolean force) {
         if (mGutsContent != null) {
-            if (mGutsContent.isLeavebehind() && leavebehinds) {
-                closeControls(x, y, true /* save */, force);
-            } else if (!mGutsContent.isLeavebehind() && controls) {
-                closeControls(x, y, true /* save */, force);
+            if ((mGutsContent.isLeavebehind() && leavebehinds)
+                    || (!mGutsContent.isLeavebehind() && controls)) {
+                closeControls(x, y, mGutsContent.shouldBeSaved(), force);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 98e9268..2b7ab10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -486,6 +486,11 @@
     }
 
     @Override
+    public boolean shouldBeSaved() {
+        return hasImportanceChanged();
+    }
+
+    @Override
     public View getContentView() {
         return this;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index 0144f42..a2d0c2b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -75,7 +75,7 @@
             mPresenter.getHandler().post(() -> {
                 processForRemoteInput(sbn.getNotification(), mContext);
                 String key = sbn.getKey();
-                mRemoteInputManager.getKeysKeptForRemoteInput().remove(key);
+                mEntryManager.removeKeyKeptForRemoteInput(key);
                 boolean isUpdate =
                         mEntryManager.getNotificationData().get(key) != null;
                 // In case we don't allow child notifications, we ignore children of
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
index c4cc494..1287ced 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
@@ -39,7 +39,7 @@
 
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.NotificationVisibility;
-import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
 import com.android.systemui.OverviewProxyService;
@@ -68,7 +68,6 @@
             Dependency.get(DeviceProvisionedController.class);
     private final UserManager mUserManager;
     private final IStatusBarService mBarService;
-    private final LockPatternUtils mLockPatternUtils;
 
     private boolean mShowLockscreenNotifications;
     private boolean mAllowLockscreenRemoteInput;
@@ -162,7 +161,6 @@
         mCurrentUserId = ActivityManager.getCurrentUser();
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
-        mLockPatternUtils = new LockPatternUtils(mContext);
     }
 
     public void setUpWithPresenter(NotificationPresenter presenter,
@@ -274,7 +272,7 @@
         if (userId == UserHandle.USER_ALL) {
             userId = mCurrentUserId;
         }
-        return mLockPatternUtils.isUserInLockdown(userId);
+        return KeyguardUpdateMonitor.getInstance(mContext).isUserInLockdown(userId);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLogger.java
index 01ec461..8e8e718 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLogger.java
@@ -176,10 +176,9 @@
         if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) {
             return;
         }
-        NotificationVisibility[] newlyVisibleAr =
-                newlyVisible.toArray(new NotificationVisibility[newlyVisible.size()]);
-        NotificationVisibility[] noLongerVisibleAr =
-                noLongerVisible.toArray(new NotificationVisibility[noLongerVisible.size()]);
+        final NotificationVisibility[] newlyVisibleAr = cloneVisibilitiesAsArr(newlyVisible);
+        final NotificationVisibility[] noLongerVisibleAr = cloneVisibilitiesAsArr(noLongerVisible);
+
         mUiOffloadThread.submit(() -> {
             try {
                 mBarService.onNotificationVisibilityChanged(newlyVisibleAr, noLongerVisibleAr);
@@ -202,6 +201,8 @@
                     Log.d(TAG, "failed setNotificationsShown: ", e);
                 }
             }
+            recycleAllVisibilityObjects(newlyVisibleAr);
+            recycleAllVisibilityObjects(noLongerVisibleAr);
         });
     }
 
@@ -213,6 +214,28 @@
         array.clear();
     }
 
+    private void recycleAllVisibilityObjects(NotificationVisibility[] array) {
+        final int N = array.length;
+        for (int i = 0 ; i < N; i++) {
+            if (array[i] != null) {
+                array[i].recycle();
+            }
+        }
+    }
+
+    private NotificationVisibility[] cloneVisibilitiesAsArr(Collection<NotificationVisibility> c) {
+
+        final NotificationVisibility[] array = new NotificationVisibility[c.size()];
+        int i = 0;
+        for(NotificationVisibility nv: c) {
+            if (nv != null) {
+                array[i] = nv.clone();
+            }
+            i++;
+        }
+        return array;
+    }
+
     @VisibleForTesting
     public Runnable getVisibilityReporter() {
         return mVisibilityReporter;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index a333654..9e87a0b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -77,12 +77,6 @@
     protected final NotificationLockscreenUserManager mLockscreenUserManager =
             Dependency.get(NotificationLockscreenUserManager.class);
 
-    /**
-     * Notifications with keys in this set are not actually around anymore. We kept them around
-     * when they were canceled in response to a remote input interaction. This allows us to show
-     * what you replied and allows you to continue typing into it.
-     */
-    protected final ArraySet<String> mKeysKeptForRemoteInput = new ArraySet<>();
     protected final Context mContext;
     private final UserManager mUserManager;
 
@@ -290,7 +284,8 @@
         mRemoteInputController.addCallback(new RemoteInputController.Callback() {
             @Override
             public void onRemoteInputSent(NotificationData.Entry entry) {
-                if (FORCE_REMOTE_INPUT_HISTORY && mKeysKeptForRemoteInput.contains(entry.key)) {
+                if (FORCE_REMOTE_INPUT_HISTORY
+                        && mEntryManager.isNotificationKeptForRemoteInput(entry.key)) {
                     mEntryManager.removeNotification(entry.key, null);
                 } else if (mRemoteInputEntriesToRemoveOnCollapse.contains(entry)) {
                     // We're currently holding onto this notification, but from the apps point of
@@ -340,10 +335,6 @@
         if (mRemoteInputController.isRemoteInputActive(entry)) {
             mRemoteInputController.removeRemoteInput(entry, null);
         }
-        if (FORCE_REMOTE_INPUT_HISTORY
-                && mKeysKeptForRemoteInput.contains(n.getKey())) {
-            mKeysKeptForRemoteInput.remove(n.getKey());
-        }
     }
 
     public void removeRemoteInputEntriesKeptUntilCollapsed() {
@@ -368,8 +359,6 @@
         pw.println("NotificationRemoteInputManager state:");
         pw.print("  mRemoteInputEntriesToRemoveOnCollapse: ");
         pw.println(mRemoteInputEntriesToRemoveOnCollapse);
-        pw.print("  mKeysKeptForRemoteInput: ");
-        pw.println(mKeysKeptForRemoteInput);
     }
 
     public void bindRow(ExpandableNotificationRow row) {
@@ -377,10 +366,6 @@
         row.setRemoteViewClickHandler(mOnClickHandler);
     }
 
-    public Set<String> getKeysKeptForRemoteInput() {
-        return mKeysKeptForRemoteInput;
-    }
-
     @VisibleForTesting
     public Set<NotificationData.Entry> getRemoteInputEntriesToRemoveOnCollapse() {
         return mRemoteInputEntriesToRemoveOnCollapse;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index d3caf03..3063199 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -33,10 +33,8 @@
 
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.ViewInvertHelper;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.phone.NotificationIconContainer;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
 import com.android.systemui.statusbar.stack.AmbientState;
 import com.android.systemui.statusbar.stack.AnimationProperties;
 import com.android.systemui.statusbar.stack.ExpandableViewState;
@@ -60,7 +58,6 @@
     private static final String TAG = "NotificationShelf";
     private static final long SHELF_IN_TRANSLATION_DURATION = 200;
 
-    private ViewInvertHelper mViewInvertHelper;
     private boolean mDark;
     private NotificationIconContainer mShelfIcons;
     private ShelfState mShelfState;
@@ -105,8 +102,6 @@
         setClipChildren(false);
         setClipToPadding(false);
         mShelfIcons.setIsStaticLayout(false);
-        mViewInvertHelper = new ViewInvertHelper(mShelfIcons,
-                NotificationPanelView.DOZE_ANIMATION_DURATION);
         mShelfState = new ShelfState();
         setBottomRoundness(1.0f, false /* animate */);
         initDimens();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
index aea0127..d84d3dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
@@ -431,6 +431,11 @@
         return true;
     }
 
+    @Override
+    public boolean shouldBeSaved() {
+        return true;
+    }
+
     public class NotificationSnoozeOption implements SnoozeOption {
         private SnoozeCriterion mCriterion;
         private int mMinutesToSnoozeFor;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 1637849..341c692 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.os.Trace;
 import android.service.notification.NotificationListenerService;
 import android.util.Log;
 import android.view.View;
@@ -283,6 +284,7 @@
      * Updates expanded, dimmed and locked states of notification rows.
      */
     public void updateRowStates() {
+        Trace.beginSection("NotificationViewHierarchyManager#updateRowStates");
         final int N = mListContainer.getContainerChildCount();
 
         int visibleNotifications = 0;
@@ -352,6 +354,9 @@
             row.showAppOpsIcons(entry.mActiveAppOps);
         }
 
+        Trace.beginSection("NotificationPresenter#onUpdateRowStates");
         mPresenter.onUpdateRowStates();
+        Trace.endSection();
+        Trace.endSection();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
index 67da68c..5ba75de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
@@ -17,10 +17,12 @@
 
 import android.os.RemoteException;
 import android.service.notification.StatusBarNotification;
+import android.util.ArraySet;
 
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.Dependency;
 
+import java.util.Set;
 
 /**
  * Handles when smart replies are added to a notification
@@ -28,18 +30,20 @@
  */
 public class SmartReplyController {
     private IStatusBarService mBarService;
-    private NotificationEntryManager mNotificationEntryManager;
+    private Set<String> mSendingKeys = new ArraySet<>();
 
     public SmartReplyController() {
         mBarService = Dependency.get(IStatusBarService.class);
-        mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
     }
 
     public void smartReplySent(NotificationData.Entry entry, int replyIndex, CharSequence reply) {
+        NotificationEntryManager notificationEntryManager
+                = Dependency.get(NotificationEntryManager.class);
         StatusBarNotification newSbn =
-                mNotificationEntryManager.rebuildNotificationWithRemoteInput(entry, reply,
+                notificationEntryManager.rebuildNotificationWithRemoteInput(entry, reply,
                         true /* showSpinner */);
-        mNotificationEntryManager.updateNotification(newSbn, null /* ranking */);
+        notificationEntryManager.updateNotification(newSbn, null /* ranking */);
+        mSendingKeys.add(entry.key);
 
         try {
             mBarService.onNotificationSmartReplySent(entry.notification.getKey(),
@@ -49,6 +53,14 @@
         }
     }
 
+    /**
+     * Have we posted an intent to an app about sending a smart reply from the
+     * notification with this key.
+     */
+    public boolean isSendingSmartReply(String key) {
+        return mSendingKeys.contains(key);
+    }
+
     public void smartRepliesAdded(final NotificationData.Entry entry, int replyCount) {
         try {
             mBarService.onNotificationSmartRepliesAdded(entry.notification.getKey(),
@@ -57,4 +69,10 @@
             // Nothing to do, system going down
         }
     }
+
+    public void stopSending(final NotificationData.Entry entry) {
+        if (entry != null) {
+            mSendingKeys.remove(entry.notification.getKey());
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
index b2eb18e..c5b3560 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
@@ -16,13 +16,13 @@
 
 package com.android.systemui.statusbar;
 
-import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.animation.Interpolator;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.Interpolators;
 
 /**
@@ -33,11 +33,19 @@
 
     protected View mContent;
     protected View mSecondaryView;
-    private boolean mIsVisible;
-    private boolean mIsSecondaryVisible;
-    private boolean mAnimating;
-    private boolean mSecondaryAnimating;
+    private boolean mIsVisible = true;
+    private boolean mContentVisible = true;
+    private boolean mIsSecondaryVisible = true;
     private int mDuration = 260;
+    private boolean mContentAnimating;
+    private final Runnable mContentVisibilityEndRunnable = () -> {
+        mContentAnimating = false;
+        if (getVisibility() != View.GONE && !mIsVisible) {
+            setVisibility(GONE);
+            setWillBeGone(false);
+            notifyHeightChanged(false /* needsAnimation */);
+        }
+    };
 
     public StackScrollerDecorView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -48,7 +56,8 @@
         super.onFinishInflate();
         mContent = findContentView();
         mSecondaryView = findSecondaryView();
-        setInvisible();
+        setVisible(false /* nowVisible */, false /* animate */);
+        setSecondaryVisible(false /* nowVisible */, false /* animate */);
     }
 
     @Override
@@ -62,72 +71,86 @@
         return true;
     }
 
-    public void performVisibilityAnimation(boolean nowVisible) {
-        performVisibilityAnimation(nowVisible, null /* onFinishedRunnable */);
-    }
-
-    public void performVisibilityAnimation(boolean nowVisible, Runnable onFinishedRunnable) {
-        boolean oldVisible = isVisible();
-        animateText(mContent, nowVisible, oldVisible, new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    mAnimating = true;
-                }
-
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    mAnimating = false;
-                    mIsVisible = nowVisible;
-                    if (onFinishedRunnable != null) {
-                        onFinishedRunnable.run();
-                    }
-                }
-            });
-    }
-
-    public void performSecondaryVisibilityAnimation(boolean nowVisible) {
-        performSecondaryVisibilityAnimation(nowVisible, null /* onFinishedRunnable */);
-    }
-
-    public void performSecondaryVisibilityAnimation(boolean nowVisible,
-            Runnable onFinishedRunnable) {
-        boolean oldVisible = isSecondaryVisible();
-        animateText(mSecondaryView, nowVisible, oldVisible, new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    mSecondaryAnimating = true;
-                }
-
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    mSecondaryAnimating = false;
-                    mIsSecondaryVisible = nowVisible;
-                    if (onFinishedRunnable != null) {
-                        onFinishedRunnable.run();
-                    }
-                }
-            });
-    }
-
     /**
-     * Check whether the secondary view is visible or not.<p/>
+     * Set the content of this view to be visible in an animated way.
      *
-     * @see #isVisible()
+     * @param contentVisible True if the content should be visible or false if it should be hidden.
      */
-    public boolean isSecondaryVisible() {
-        return mSecondaryView != null && (mIsSecondaryVisible ^ mSecondaryAnimating);
+    public void setContentVisible(boolean contentVisible) {
+        setContentVisible(contentVisible, true /* animate */);
+    }
+    /**
+     * Set the content of this view to be visible.
+     * @param contentVisible True if the content should be visible or false if it should be hidden.
+     * @param animate Should an animation be performed.
+     */
+    private void setContentVisible(boolean contentVisible, boolean animate) {
+        if (mContentVisible != contentVisible) {
+            mContentAnimating = animate;
+            setViewVisible(mContent, contentVisible, animate, mContentVisibilityEndRunnable);
+            mContentVisible = contentVisible;
+        } if (!mContentAnimating) {
+            mContentVisibilityEndRunnable.run();
+        }
+    }
+
+    public boolean isContentVisible() {
+        return mContentVisible;
     }
 
     /**
-     * Check whether the whole view is visible or not.<p/>
-     * The view is considered visible if it matches one of following:
-     * <ul>
-     *   <li> It's visible and there is no ongoing animation. </li>
-     *   <li> It's not visible but is animating, thus being eventually visible. </li>
-     * </ul>
+     * Make this view visible. If {@code false} is passed, the view will fade out it's content
+     * and set the view Visibility to GONE. If only the content should be changed
+     * {@link #setContentVisible(boolean)} can be used.
+     *
+     * @param nowVisible should the view be visible
+     * @param animate should the change be animated.
+     */
+    public void setVisible(boolean nowVisible, boolean animate) {
+        if (mIsVisible != nowVisible) {
+            mIsVisible = nowVisible;
+            if (animate) {
+                if (nowVisible) {
+                    setVisibility(VISIBLE);
+                    setWillBeGone(false);
+                    notifyHeightChanged(false /* needsAnimation */);
+                } else {
+                    setWillBeGone(true);
+                }
+                setContentVisible(nowVisible, true /* animate */);
+            } else {
+                setVisibility(nowVisible ? VISIBLE : GONE);
+                setContentVisible(nowVisible, false /* animate */);
+                setWillBeGone(false);
+                notifyHeightChanged(false /* needsAnimation */);
+            }
+        }
+    }
+
+    /**
+     * Set the secondary view of this layout to visible.
+     *
+     * @param nowVisible should the secondary view be visible
+     * @param animate should the change be animated
+     */
+    public void setSecondaryVisible(boolean nowVisible, boolean animate) {
+        if (mIsSecondaryVisible != nowVisible) {
+            setViewVisible(mSecondaryView, nowVisible, animate, null /* endRunnable */);
+            mIsSecondaryVisible = nowVisible;
+        }
+    }
+
+    @VisibleForTesting
+    boolean isSecondaryVisible() {
+        return mIsSecondaryVisible;
+    }
+
+    /**
+     * Is this view visible. If a view is currently animating to gone, it will
+     * return {@code false}.
      */
     public boolean isVisible() {
-        return mIsVisible ^ mAnimating;
+        return mIsVisible;
     }
 
     void setDuration(int duration) {
@@ -135,43 +158,35 @@
     }
 
     /**
-     * Animate the text to a new visibility.
-     *
-     * @param view Target view, maybe content view or dissmiss view
-     * @param nowVisible Should it now be visible
-     * @param oldVisible Is it visible currently
-     * @param listener A listener that doing flag settings or other actions
+     * Animate a view to a new visibility.
+     * @param view Target view, maybe content view or dismiss view.
+     * @param nowVisible Should it now be visible.
+     * @param animate Should this be done in an animated way.
+     * @param endRunnable A runnable that is run when the animation is done.
      */
-    private void animateText(View view, boolean nowVisible, boolean oldVisible,
-        AnimatorListenerAdapter listener) {
+    private void setViewVisible(View view, boolean nowVisible,
+            boolean animate, Runnable endRunnable) {
         if (view == null) {
             return;
         }
-
-        if (nowVisible != oldVisible) {
-            // Animate text
-            float endValue = nowVisible ? 1.0f : 0.0f;
-            Interpolator interpolator;
-            if (nowVisible) {
-                interpolator = Interpolators.ALPHA_IN;
-            } else {
-                interpolator = Interpolators.ALPHA_OUT;
+        // cancel any previous animations
+        view.animate().cancel();
+        float endValue = nowVisible ? 1.0f : 0.0f;
+        if (!animate) {
+            view.setAlpha(endValue);
+            if (endRunnable != null) {
+                endRunnable.run();
             }
-            view.animate()
-                    .alpha(endValue)
-                    .setInterpolator(interpolator)
-                    .setDuration(mDuration)
-                    .setListener(listener);
+            return;
         }
-    }
 
-    public void setInvisible() {
-        mContent.setAlpha(0.0f);
-        if (mSecondaryView != null) {
-            mSecondaryView.setAlpha(0.0f);
-        }
-        mIsVisible = false;
-        mIsSecondaryVisible = false;
+        // Animate the view alpha
+        Interpolator interpolator = nowVisible ? Interpolators.ALPHA_IN : Interpolators.ALPHA_OUT;
+        view.animate()
+                .alpha(endValue)
+                .setInterpolator(interpolator)
+                .setDuration(mDuration)
+                .withEndAction(endRunnable);
     }
 
     @Override
@@ -180,13 +195,13 @@
             Runnable onFinishedRunnable,
             AnimatorListenerAdapter animationListener) {
         // TODO: Use duration
-        performVisibilityAnimation(false);
+        setContentVisible(false);
     }
 
     @Override
     public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear) {
         // TODO: use delay and duration
-        performVisibilityAnimation(true);
+        setContentVisible(true);
     }
 
     @Override
@@ -194,13 +209,6 @@
         return false;
     }
 
-    public void cancelAnimation() {
-        mContent.animate().cancel();
-        if (mSecondaryView != null) {
-            mSecondaryView.animate().cancel();
-        }
-    }
-
     protected abstract View findContentView();
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 8d2c934..ebeea58 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -818,7 +818,7 @@
             updateDecorColor();
             updateIconColor();
             updateAllowAnimation();
-        }, dark, fade, delay);
+        }, dark, fade, delay, this);
     }
 
     private void updateAllowAnimation() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index cfbb4d9..a68d75a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -28,11 +28,11 @@
 import android.view.IRemoteAnimationRunner;
 import android.view.RemoteAnimationAdapter;
 import android.view.RemoteAnimationTarget;
-import android.view.Surface;
-import android.view.SurfaceControl;
-import android.view.ViewRootImpl;
 
 import com.android.systemui.Interpolators;
+import com.android.systemui.shared.system.SurfaceControlCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier.SurfaceParams;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.NotificationListContainer;
 import com.android.systemui.statusbar.StatusBarState;
@@ -41,6 +41,8 @@
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarWindowView;
 
+import java.util.ArrayList;
+
 /**
  * A class that allows activities to be launched in a seamless way where the notification
  * transforms nicely into the starting window.
@@ -81,7 +83,7 @@
         }
         AnimationRunner animationRunner = new AnimationRunner(sourceNotification);
         return new RemoteAnimationAdapter(animationRunner, ANIMATION_DURATION,
-                0 /* statusBarTransitionDelay */);
+                ANIMATION_DURATION - 150 /* statusBarTransitionDelay */);
     }
 
     public boolean isAnimationPending() {
@@ -109,12 +111,13 @@
         private final ExpandableNotificationRow mSourceNotification;
         private final ExpandAnimationParameters mParams;
         private final Rect mWindowCrop = new Rect();
-        private boolean mLeashShown;
         private boolean mInstantCollapsePanel = true;
+        private final SyncRtSurfaceTransactionApplier mSyncRtTransactionApplier;
 
         public AnimationRunner(ExpandableNotificationRow sourceNofitication) {
             mSourceNotification = sourceNofitication;
             mParams = new ExpandAnimationParameters();
+            mSyncRtTransactionApplier = new SyncRtSurfaceTransactionApplier(mSourceNotification);
         }
 
         @Override
@@ -240,24 +243,12 @@
         }
 
         private void applyParamsToWindow(RemoteAnimationTarget app) {
-            SurfaceControl.Transaction t = new SurfaceControl.Transaction();
-            if (!mLeashShown) {
-                t.show(app.leash);
-                mLeashShown = true;
-            }
             Matrix m = new Matrix();
             m.postTranslate(0, (float) (mParams.top - app.position.y));
-            t.setMatrix(app.leash, m, new float[9]);
             mWindowCrop.set(mParams.left, 0, mParams.right, mParams.getHeight());
-            t.setWindowCrop(app.leash, mWindowCrop);
-            ViewRootImpl viewRootImpl = mSourceNotification.getViewRootImpl();
-            if (viewRootImpl != null) {
-                Surface systemUiSurface = viewRootImpl.mSurface;
-                t.deferTransactionUntilSurface(app.leash, systemUiSurface,
-                        systemUiSurface.getNextFrameNumber());
-            }
-            t.setEarlyWakeup();
-            t.apply();
+            SurfaceParams params = new SurfaceParams(new SurfaceControlCompat(app.leash),
+                    1f /* alpha */, m, mWindowCrop, app.prefixOrderIndex);
+            mSyncRtTransactionApplier.scheduleApply(params);
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridGroupManager.java
index a096508..ec94df1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridGroupManager.java
@@ -166,7 +166,7 @@
         mDozer.setIntensityDark((f)->{
             mDarkAmount = f;
             updateOverFlowNumberColor(view);
-        }, dark, fade, delay);
+        }, dark, fade, delay, view);
         view.setTextSize(TypedValue.COMPLEX_UNIT_PX,
                 dark ? mOverflowNumberSizeDark : mOverflowNumberSize);
         int paddingEnd = dark ? mOverflowNumberPaddingDark : mOverflowNumberPadding;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java
index 0a1795f..85f2a63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java
@@ -25,11 +25,9 @@
 
 import com.android.keyguard.AlphaOptimizedLinearLayout;
 import com.android.systemui.R;
-import com.android.systemui.ViewInvertHelper;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.ViewTransformationHelper;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 /**
  * A hybrid view which may contain information about one ore more notifications.
@@ -41,7 +39,6 @@
 
     protected TextView mTitleView;
     protected TextView mTextView;
-    private ViewInvertHelper mInvertHelper;
 
     public HybridNotificationView(Context context) {
         this(context, null);
@@ -73,7 +70,6 @@
         super.onFinishInflate();
         mTitleView = (TextView) findViewById(R.id.notification_title);
         mTextView = (TextView) findViewById(R.id.notification_text);
-        mInvertHelper = new ViewInvertHelper(this, NotificationPanelView.DOZE_ANIMATION_DURATION);
         mTransformationHelper = new ViewTransformationHelper();
         mTransformationHelper.setCustomTransformation(
                 new ViewTransformationHelper.CustomTransformation() {
@@ -126,10 +122,6 @@
         requestLayout();
     }
 
-    public void setDark(boolean dark, boolean fade, long delay) {
-        mInvertHelper.setInverted(dark, fade, delay);
-    }
-
     @Override
     public TransformState getCurrentState(int fadingView) {
         return mTransformationHelper.getCurrentState(fadingView);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
index adc0914..7a51fe1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
@@ -16,82 +16,26 @@
 
 package com.android.systemui.statusbar.notification;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.content.Context;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Paint;
 import android.view.View;
 
 import com.android.systemui.R;
-import com.android.systemui.ViewInvertHelper;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 /**
  * Wraps a notification containing a custom view.
  */
 public class NotificationCustomViewWrapper extends NotificationViewWrapper {
 
-    private final ViewInvertHelper mInvertHelper;
-    private final Paint mGreyPaint = new Paint();
     private boolean mIsLegacy;
     private int mLegacyColor;
 
     protected NotificationCustomViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
         super(ctx, view, row);
-        mInvertHelper = new ViewInvertHelper(view, NotificationPanelView.DOZE_ANIMATION_DURATION);
         mLegacyColor = row.getContext().getColor(R.color.notification_legacy_background_color);
     }
 
     @Override
-    public void setDark(boolean dark, boolean fade, long delay) {
-        if (dark == mDark && mDarkInitialized) {
-            return;
-        }
-        super.setDark(dark, fade, delay);
-        if (!mIsLegacy && mShouldInvertDark) {
-            if (fade) {
-                mInvertHelper.fade(dark, delay);
-            } else {
-                mInvertHelper.update(dark);
-            }
-        } else {
-            mView.setLayerType(dark ? View.LAYER_TYPE_HARDWARE : View.LAYER_TYPE_NONE, null);
-            if (fade) {
-                fadeGrayscale(dark, delay);
-            } else {
-                updateGrayscale(dark);
-            }
-        }
-    }
-
-    protected void fadeGrayscale(final boolean dark, long delay) {
-        getDozer().startIntensityAnimation(animation -> {
-            getDozer().updateGrayscaleMatrix((float) animation.getAnimatedValue());
-            mGreyPaint.setColorFilter(
-                    new ColorMatrixColorFilter(getDozer().getGrayscaleColorMatrix()));
-            mView.setLayerPaint(mGreyPaint);
-        }, dark, delay, new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (!dark) {
-                    mView.setLayerType(View.LAYER_TYPE_NONE, null);
-                }
-            }
-        });
-    }
-
-    protected void updateGrayscale(boolean dark) {
-        if (dark) {
-            getDozer().updateGrayscaleMatrix(1f);
-            mGreyPaint.setColorFilter(
-                    new ColorMatrixColorFilter(getDozer().getGrayscaleColorMatrix()));
-            mView.setLayerPaint(mGreyPaint);
-        }
-    }
-
-    @Override
     public void setVisible(boolean visible) {
         super.setVisible(visible);
         mView.setAlpha(visible ? 1.0f : 0.0f);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
index 0b3b3cb..fb362c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
@@ -21,14 +21,17 @@
 import android.animation.ValueAnimator;
 import android.graphics.ColorMatrix;
 import android.graphics.ColorMatrixColorFilter;
+import android.view.View;
 import android.widget.ImageView;
 
 import com.android.systemui.Interpolators;
+import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 import java.util.function.Consumer;
 
 public class NotificationDozeHelper {
+    private static final int DOZE_ANIMATOR_TAG = R.id.doze_intensity_tag;
     private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix();
 
     public void fadeGrayscale(final ImageView target, final boolean dark, long delay) {
@@ -76,11 +79,26 @@
     }
 
     public void setIntensityDark(Consumer<Float> listener, boolean dark,
-            boolean animate, long delay) {
+            boolean animate, long delay, View view) {
         if (animate) {
             startIntensityAnimation(a -> listener.accept((Float) a.getAnimatedValue()), dark, delay,
-                    null /* listener */);
+                    new AnimatorListenerAdapter() {
+
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            view.setTag(DOZE_ANIMATOR_TAG, null);
+                        }
+
+                        @Override
+                        public void onAnimationStart(Animator animation) {
+                            view.setTag(DOZE_ANIMATOR_TAG, animation);
+                        }
+                    } /* listener */);
         } else {
+            Animator animator = (Animator) view.getTag(DOZE_ANIMATOR_TAG);
+            if (animator != null) {
+                animator.cancel();
+            }
             listener.accept(dark ? 1f : 0f);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
index 78df77f..2fc2cdb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -16,10 +16,10 @@
 
 package com.android.systemui.statusbar.notification;
 
+import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y;
+
 import android.app.Notification;
 import android.content.Context;
-import android.graphics.ColorFilter;
-import android.graphics.PorterDuffColorFilter;
 import android.util.ArraySet;
 import android.view.NotificationHeaderView;
 import android.view.View;
@@ -32,16 +32,12 @@
 import com.android.internal.widget.NotificationExpandButton;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.ViewInvertHelper;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.ViewTransformationHelper;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 import java.util.Stack;
 
-import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y;
-
 /**
  * Wraps a notification header view.
  */
@@ -50,7 +46,6 @@
     private static final Interpolator LOW_PRIORITY_HEADER_CLOSE
             = new PathInterpolator(0.4f, 0f, 0.7f, 1f);
 
-    protected final ViewInvertHelper mInvertHelper;
     protected final ViewTransformationHelper mTransformationHelper;
     private final int mTranslationForHeader;
 
@@ -70,7 +65,6 @@
         super(ctx, view, row);
         mShowExpandButtonAtEnd = ctx.getResources().getBoolean(
                 R.bool.config_showNotificationExpandButtonAtEnd);
-        mInvertHelper = new ViewInvertHelper(ctx, NotificationPanelView.DOZE_ANIMATION_DURATION);
         mTransformationHelper = new ViewTransformationHelper();
 
         // we want to avoid that the header clashes with the other text when transforming
@@ -99,7 +93,6 @@
                     }
                 }, TRANSFORMING_VIEW_TITLE);
         resolveHeaderViews();
-        updateInvertHelper();
         addAppOpsOnClickListener(row);
         mTranslationForHeader = ctx.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.notification_content_margin)
@@ -107,16 +100,6 @@
                         com.android.internal.R.dimen.notification_content_margin_top);
     }
 
-    @Override
-    protected NotificationDozeHelper createDozer(Context ctx) {
-        return new NotificationIconDozeHelper(ctx);
-    }
-
-    @Override
-    protected NotificationIconDozeHelper getDozer() {
-        return (NotificationIconDozeHelper) super.getDozer();
-    }
-
     protected void resolveHeaderViews() {
         mIcon = mView.findViewById(com.android.internal.R.id.icon);
         mHeaderText = mView.findViewById(com.android.internal.R.id.header_text);
@@ -125,7 +108,6 @@
         mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header);
         mNotificationHeader.setShowExpandButtonAtEnd(mShowExpandButtonAtEnd);
         mColor = mNotificationHeader.getOriginalIconColor();
-        getDozer().setColor(mColor);
     }
 
     private void addAppOpsOnClickListener(ExpandableNotificationRow row) {
@@ -141,7 +123,6 @@
 
         // Reinspect the notification.
         resolveHeaderViews();
-        updateInvertHelper();
         updateTransformedTypes();
         addRemainingTransformTypes();
         updateCropToPaddingForImageViews();
@@ -192,16 +173,6 @@
         }
     }
 
-    protected void updateInvertHelper() {
-        mInvertHelper.clearTargets();
-        for (int i = 0; i < mNotificationHeader.getChildCount(); i++) {
-            View child = mNotificationHeader.getChildAt(i);
-            if (child != mIcon) {
-                mInvertHelper.addTarget(child);
-            }
-        }
-    }
-
     protected void updateTransformedTypes() {
         mTransformationHelper.reset();
         mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_ICON, mIcon);
@@ -212,27 +183,6 @@
     }
 
     @Override
-    public void setDark(boolean dark, boolean fade, long delay) {
-        if (dark == mDark && mDarkInitialized) {
-            return;
-        }
-        super.setDark(dark, fade, delay);
-        if (fade) {
-            mInvertHelper.fade(dark, delay);
-        } else {
-            mInvertHelper.update(dark);
-        }
-        if (mIcon != null && !mRow.isChildInGroup()) {
-            // We don't update the color for children views / their icon is invisible anyway.
-            // It also may lead to bugs where the icon isn't correctly greyed out.
-            boolean hadColorFilter = mNotificationHeader.getOriginalIconColor()
-                    != NotificationHeaderView.NO_COLOR;
-
-            getDozer().setImageDark(mIcon, dark, fade, delay, !hadColorFilter);
-        }
-    }
-
-    @Override
     public void updateExpandability(boolean expandable, View.OnClickListener onClickListener) {
         mExpandButton.setVisibility(expandable ? View.VISIBLE : View.GONE);
         mNotificationHeader.setOnClickListener(expandable ? onClickListener : null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
index 0143d01..1303057 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
@@ -137,9 +137,15 @@
             return;
         }
         StatusBarNotification sbn = mRow.getEntry().notification;
-        new AsyncInflationTask(sbn, reInflateFlags, mRow, mIsLowPriority,
+        AsyncInflationTask task = new AsyncInflationTask(sbn, reInflateFlags, mRow,
+                mIsLowPriority,
                 mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, mRedactAmbient,
-                mCallback, mRemoteViewClickHandler).execute();
+                mCallback, mRemoteViewClickHandler);
+        if (mCallback != null && mCallback.doInflateSynchronous()) {
+            task.onPostExecute(task.doInBackground());
+        } else {
+            task.execute();
+        }
     }
 
     @VisibleForTesting
@@ -331,6 +337,30 @@
             final HashMap<Integer, CancellationSignal> runningInflations,
             ApplyCallback applyCallback) {
         RemoteViews newContentView = applyCallback.getRemoteView();
+        if (callback != null && callback.doInflateSynchronous()) {
+            try {
+                if (isNewView) {
+                    View v = newContentView.apply(
+                            result.packageContext,
+                            parentLayout,
+                            remoteViewClickHandler);
+                    v.setIsRootNamespace(true);
+                    applyCallback.setResultView(v);
+                } else {
+                    newContentView.reapply(
+                            result.packageContext,
+                            existingView,
+                            remoteViewClickHandler);
+                    existingWrapper.onReinflated();
+                }
+            } catch (Exception e) {
+                handleInflationError(runningInflations, e, entry.notification, callback);
+                // Add a running inflation to make sure we don't trigger callbacks.
+                // Safe to do because only happens in tests.
+                runningInflations.put(inflationId, new CancellationSignal());
+            }
+            return;
+        }
         RemoteViews.OnViewAppliedListener listener
                 = new RemoteViews.OnViewAppliedListener() {
 
@@ -515,6 +545,13 @@
     public interface InflationCallback {
         void handleInflationException(StatusBarNotification notification, Exception e);
         void onAsyncInflationFinished(NotificationData.Entry entry);
+
+        /**
+         * Used to disable async-ness for tests. Should only be used for tests.
+         */
+        default boolean doInflateSynchronous() {
+            return false;
+        }
     }
 
     public void onDensityOrFontScaleChanged() {
@@ -646,6 +683,11 @@
             mRow.onNotificationUpdated();
             mCallback.onAsyncInflationFinished(mRow.getEntry());
         }
+
+        @Override
+        public boolean doInflateSynchronous() {
+            return mCallback != null && mCallback.doInflateSynchronous();
+        }
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
index 2a47fe0..2d983c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -45,8 +45,6 @@
  */
 public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapper {
 
-    private static final int mDarkProgressTint = 0xffffffff;
-
     protected ImageView mPicture;
     private ProgressBar mProgressBar;
     private TextView mTitle;
@@ -275,15 +273,6 @@
     }
 
     @Override
-    protected void updateInvertHelper() {
-        super.updateInvertHelper();
-        View mainColumn = mView.findViewById(com.android.internal.R.id.notification_main_column);
-        if (mainColumn != null) {
-            mInvertHelper.addTarget(mainColumn);
-        }
-    }
-
-    @Override
     protected void updateTransformedTypes() {
         // This also clears the existing types
         super.updateTransformedTypes();
@@ -306,65 +295,6 @@
     }
 
     @Override
-    public void setDark(boolean dark, boolean fade, long delay) {
-        if (dark == mDark && mDarkInitialized) {
-            return;
-        }
-        super.setDark(dark, fade, delay);
-        setPictureDark(dark, fade, delay);
-        setProgressBarDark(dark, fade, delay);
-    }
-
-    private void setProgressBarDark(boolean dark, boolean fade, long delay) {
-        if (mProgressBar != null) {
-            if (fade) {
-                fadeProgressDark(mProgressBar, dark, delay);
-            } else {
-                updateProgressDark(mProgressBar, dark);
-            }
-        }
-    }
-
-    private void fadeProgressDark(final ProgressBar target, final boolean dark, long delay) {
-        getDozer().startIntensityAnimation(animation -> {
-            float t = (float) animation.getAnimatedValue();
-            updateProgressDark(target, t);
-        }, dark, delay, null /* listener */);
-    }
-
-    private void updateProgressDark(ProgressBar target, float intensity) {
-        int color = interpolateColor(mColor, mDarkProgressTint, intensity);
-        target.getIndeterminateDrawable().mutate().setTint(color);
-        target.getProgressDrawable().mutate().setTint(color);
-    }
-
-    private void updateProgressDark(ProgressBar target, boolean dark) {
-        updateProgressDark(target, dark ? 1f : 0f);
-    }
-
-    private void setPictureDark(boolean dark, boolean fade, long delay) {
-        if (mPicture != null) {
-            getDozer().setImageDark(mPicture, dark, fade, delay, true /* useGrayscale */);
-        }
-    }
-
-    private static int interpolateColor(int source, int target, float t) {
-        int aSource = Color.alpha(source);
-        int rSource = Color.red(source);
-        int gSource = Color.green(source);
-        int bSource = Color.blue(source);
-        int aTarget = Color.alpha(target);
-        int rTarget = Color.red(target);
-        int gTarget = Color.green(target);
-        int bTarget = Color.blue(target);
-        return Color.argb(
-                (int) (aSource * (1f - t) + aTarget * t),
-                (int) (rSource * (1f - t) + rTarget * t),
-                (int) (gSource * (1f - t) + gTarget * t),
-                (int) (bSource * (1f - t) + bTarget * t));
-    }
-
-    @Override
     public void setContentHeight(int contentHeight, int minHeightHint) {
         super.setContentHeight(contentHeight, minHeightHint);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
index 93a9947..93058b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -17,10 +17,8 @@
 package com.android.systemui.statusbar.notification;
 
 import android.content.Context;
-import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.support.v4.graphics.ColorUtils;
 import android.view.NotificationHeaderView;
 import android.view.View;
 
@@ -36,12 +34,8 @@
 
     protected final View mView;
     protected final ExpandableNotificationRow mRow;
-    private final NotificationDozeHelper mDozer;
 
-    protected boolean mDark;
     private int mBackgroundColor = 0;
-    protected boolean mShouldInvertDark;
-    protected boolean mDarkInitialized = false;
 
     public static NotificationViewWrapper wrap(Context ctx, View v, ExpandableNotificationRow row) {
         if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) {
@@ -65,36 +59,14 @@
     protected NotificationViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
         mView = view;
         mRow = row;
-        mDozer = createDozer(ctx);
         onReinflated();
     }
 
-    protected NotificationDozeHelper createDozer(Context ctx) {
-        return new NotificationDozeHelper();
-    }
-
-    protected NotificationDozeHelper getDozer() {
-        return mDozer;
-    }
-
-    /**
-     * In dark mode, we draw as little as possible, assuming a black background.
-     *
-     * @param dark whether we should display ourselves in dark mode
-     * @param fade whether to animate the transition if the mode changes
-     * @param delay if fading, the delay of the animation
-     */
-    public void setDark(boolean dark, boolean fade, long delay) {
-        mDark = dark;
-        mDarkInitialized = true;
-    }
-
     /**
      * Notifies this wrapper that the content of the view might have changed.
      * @param row the row this wrapper is attached to
      */
     public void onContentUpdated(ExpandableNotificationRow row) {
-        mDarkInitialized = false;
     }
 
     public void onReinflated() {
@@ -106,18 +78,12 @@
             mBackgroundColor = ((ColorDrawable) background).getColor();
             mView.setBackground(null);
         }
-        mShouldInvertDark = mBackgroundColor == 0 || isColorLight(mBackgroundColor);
     }
 
     protected boolean shouldClearBackgroundOnReapply() {
         return true;
     }
 
-    private boolean isColorLight(int backgroundColor) {
-        return Color.alpha(backgroundColor) == 0
-                || ColorUtils.calculateLuminance(backgroundColor) > 0.5;
-    }
-
     /**
      * Update the appearance of the expand button.
      *
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java
index 178c813..c1ffc22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java
@@ -35,9 +35,7 @@
     @Override
     public void initFrom(View view, TransformInfo transformInfo) {
         super.initFrom(view, transformInfo);
-        if (view instanceof TextView) {
-            mText = (TextView) view;
-        }
+        mText = (TextView) view;
     }
 
     @Override
@@ -94,6 +92,9 @@
             return false;
         }
         TextViewTransformState otherTvs = (TextViewTransformState) otherState;
+        if (!TextUtils.equals(mText.getText(), otherTvs.mText.getText())) {
+            return false;
+        }
         int lineCount = mText.getLineCount();
         return lineCount == 1 && lineCount == otherTvs.mText.getLineCount()
                 && getEllipsisCount() == otherTvs.getEllipsisCount()
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 fb94756..3c0b226 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
@@ -14,13 +14,15 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.android.systemui.Interpolators.ALPHA_IN;
+import static com.android.systemui.Interpolators.ALPHA_OUT;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.view.View;
 
 import android.view.View.AccessibilityDelegate;
-import com.android.systemui.Interpolators;
 import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider.ButtonInterface;
 import com.android.systemui.statusbar.policy.KeyButtonDrawable;
 
@@ -150,10 +152,27 @@
     }
 
     public void setAlpha(float alpha) {
-        mAlpha = alpha;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            mViews.get(i).setAlpha(alpha);
+        setAlpha(alpha, false /* animate */);
+    }
+
+    public void setAlpha(float alpha, boolean animate) {
+        if (animate) {
+            if (mFadeAnimator != null) {
+                mFadeAnimator.cancel();
+            }
+            mFadeAnimator = ValueAnimator.ofFloat(getAlpha(), alpha);
+            mFadeAnimator.setDuration(getAlpha() < alpha? FADE_DURATION_IN : FADE_DURATION_OUT);
+            mFadeAnimator.setInterpolator(getAlpha() < alpha ? ALPHA_IN : ALPHA_OUT);
+            mFadeAnimator.addListener(mFadeListener);
+            mFadeAnimator.addUpdateListener(mAlphaListener);
+            mFadeAnimator.start();
+            setVisibility(View.VISIBLE);
+        } else {
+            mAlpha = alpha;
+            final int N = mViews.size();
+            for (int i = 0; i < N; i++) {
+                mViews.get(i).setAlpha(alpha);
+            }
         }
     }
 
@@ -233,19 +252,6 @@
         }
     }
 
-    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/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index ee83250..f7b7eeb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -165,7 +165,9 @@
                 showNotificationIconArea(animate);
             }
         }
-        if ((diff1 & DISABLE_CLOCK) != 0) {
+        // The clock may have already been hidden, but we might want to shift its
+        // visibility to GONE from INVISIBLE or vice versa
+        if ((diff1 & DISABLE_CLOCK) != 0 || mClockView.getVisibility() != clockHiddenMode()) {
             if ((state1 & DISABLE_CLOCK) != 0) {
                 hideClock(animate);
             } else {
@@ -212,13 +214,24 @@
     }
 
     public void hideClock(boolean animate) {
-        animateHiddenState(mClockView, View.GONE, animate);
+        animateHiddenState(mClockView, clockHiddenMode(), animate);
     }
 
     public void showClock(boolean animate) {
         animateShow(mClockView, animate);
     }
 
+    /**
+     * If panel is expanded/expanding it usually means QS shade is opening, so
+     * don't set the clock GONE otherwise it'll mess up the animation.
+     */
+    private int clockHiddenMode() {
+        if (!mStatusBar.isClosed() && !mKeyguardMonitor.isShowing()) {
+            return View.INVISIBLE;
+        }
+        return View.GONE;
+    }
+
     public void hideNotificationIconArea(boolean animate) {
         animateHide(mNotificationIconAreaInner, animate);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 48eb3e8..c74d09d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -54,8 +54,8 @@
 
     private static final String TAG = "KeyguardBouncer";
     static final float ALPHA_EXPANSION_THRESHOLD = 0.95f;
-    private static final float EXPANSION_HIDDEN = 1f;
-    private static final float EXPANSION_VISIBLE = 0f;
+    static final float EXPANSION_HIDDEN = 1f;
+    static final float EXPANSION_VISIBLE = 0f;
 
     protected final Context mContext;
     protected final ViewMediatorCallback mCallback;
@@ -86,6 +86,7 @@
     private boolean mShowingSoon;
     private int mBouncerPromptReason;
     private boolean mIsAnimatingAway;
+    private boolean mIsScrimmed;
 
     public KeyguardBouncer(Context context, ViewMediatorCallback callback,
             LockPatternUtils lockPatternUtils, ViewGroup container,
@@ -103,17 +104,17 @@
     }
 
     public void show(boolean resetSecuritySelection) {
-        show(resetSecuritySelection, true /* animated */);
+        show(resetSecuritySelection, true /* scrimmed */);
     }
 
     /**
      * Shows the bouncer.
      *
      * @param resetSecuritySelection Cleans keyguard view
-     * @param animated true when the bouncer show show animated, false when the user will be
-     *                 dragging it and animation should be deferred.
+     * @param isScrimmed true when the bouncer show show scrimmed, false when the user will be
+     *                 dragging it and translation should be deferred.
      */
-    public void show(boolean resetSecuritySelection, boolean animated) {
+    public void show(boolean resetSecuritySelection, boolean isScrimmed) {
         final int keyguardUserId = KeyguardUpdateMonitor.getCurrentUser();
         if (keyguardUserId == UserHandle.USER_SYSTEM && UserManager.isSplitSystemUser()) {
             // In split system user mode, we never unlock system user.
@@ -126,9 +127,10 @@
         // are valid.
         // Later, at the end of the animation, when the bouncer is at the top of the screen,
         // onFullyShown() will be called and FalsingManager will stop recording touches.
-        if (animated) {
+        if (isScrimmed) {
             setExpansion(EXPANSION_VISIBLE);
         }
+        mIsScrimmed = isScrimmed;
 
         if (resetSecuritySelection) {
             // showPrimarySecurityScreen() updates the current security method. This is needed in
@@ -164,6 +166,10 @@
         mCallback.onBouncerVisiblityChanged(true /* shown */);
     }
 
+    public boolean isShowingScrimmed() {
+        return isShowing() && mIsScrimmed;
+    }
+
     /**
      * This method must be called at the end of the bouncer animation when
      * the translation is performed manually by the user, otherwise FalsingManager
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 2ddae74..2a37845 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -186,6 +186,13 @@
             mNavigationBarView.updateStates();
             updateScreenPinningGestures();
         }
+
+        @Override
+        public void onBackButtonAlphaChanged(float alpha, boolean animate) {
+            final ButtonDispatcher backButton = mNavigationBarView.getBackButton();
+            backButton.setVisibility(alpha > 0 ? View.VISIBLE : View.INVISIBLE);
+            backButton.setAlpha(alpha, animate);
+        }
     };
 
     // ----- Fragment Lifecycle Callbacks -----
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 98f9f1a..98672b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -85,7 +85,6 @@
 import java.util.function.Consumer;
 
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB;
-import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_HIDE_BACK_BUTTON;
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
 import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW;
 import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ROTATION;
@@ -655,8 +654,6 @@
             disableRecent |= (flags & FLAG_SHOW_OVERVIEW_BUTTON) == 0;
             if (pinningActive) {
                 disableBack = disableHome = false;
-            } else {
-                disableBack |= (flags & FLAG_HIDE_BACK_BUTTON) != 0;
             }
         } else if (pinningActive) {
             disableBack = disableRecent = false;
@@ -863,7 +860,7 @@
     public boolean isRotateButtonVisible() { return mShowRotateButton; }
 
     public void setMenuContainerVisibility(boolean visible) {
-        getMenuContainer().animateFade(visible);
+        getMenuContainer().setAlpha(visible ? 1 : 0, true /* animate */);
     }
 
     @Override
@@ -1177,6 +1174,8 @@
         dumpButton(pw, "menu", getMenuButton());
         dumpButton(pw, "a11y", getAccessibilityButton());
 
+        mRecentsOnboarding.dump(pw);
+
         pw.println("    }");
     }
 
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 a3905b7..2f18aad9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -2199,7 +2199,7 @@
 
     @Override
     protected boolean isClearAllVisible() {
-        return mNotificationStackScroller.isFooterViewVisible();
+        return mNotificationStackScroller.isFooterViewContentVisible();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 347a4b0..e4eeec1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -252,7 +252,8 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent event) {
-        if (mInstantExpanding || mTouchDisabled
+        if (mInstantExpanding
+                || (mTouchDisabled && event.getActionMasked() != MotionEvent.ACTION_CANCEL)
                 || (mMotionAborted && event.getActionMasked() != MotionEvent.ACTION_DOWN)) {
             return false;
         }
@@ -947,17 +948,6 @@
         return mClosing || mLaunchingNotification;
     }
 
-    /**
-     * Bouncer might need a scrim when you double tap on notifications or edit QS.
-     * On other cases, when you drag up the bouncer with the finger or just fling,
-     * the scrim should be hidden to avoid occluding the clock.
-     *
-     * @return true when we need a scrim to show content on top of the notification panel.
-     */
-    public boolean needsScrimming() {
-        return !isTracking() && !isCollapsing() && !isFullyCollapsed();
-    }
-
     public boolean isTracking() {
         return mTracking;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 420c517..e9c0f5d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -52,6 +52,7 @@
 import android.service.notification.StatusBarNotification;
 import android.service.notification.ZenModeConfig;
 import android.telecom.TelecomManager;
+import android.text.format.DateFormat;
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.Pair;
@@ -89,6 +90,7 @@
 import com.android.systemui.util.NotificationChannels;
 
 import java.util.List;
+import java.util.Locale;
 
 /**
  * This class contains all of the policy about which icons are installed in the status
@@ -121,7 +123,7 @@
     private final Handler mHandler = new Handler();
     private final CastController mCast;
     private final HotspotController mHotspot;
-    private final NextAlarmController mNextAlarm;
+    private final NextAlarmController mNextAlarmController;
     private final AlarmManager mAlarmManager;
     private final UserInfoController mUserInfoController;
     private final UserManager mUserManager;
@@ -147,6 +149,7 @@
     private boolean mManagedProfileIconVisible = false;
 
     private BluetoothController mBluetooth;
+    private AlarmManager.AlarmClockInfo mNextAlarm;
 
     public PhoneStatusBarPolicy(Context context, StatusBarIconController iconController) {
         mContext = context;
@@ -154,7 +157,7 @@
         mCast = Dependency.get(CastController.class);
         mHotspot = Dependency.get(HotspotController.class);
         mBluetooth = Dependency.get(BluetoothController.class);
-        mNextAlarm = Dependency.get(NextAlarmController.class);
+        mNextAlarmController = Dependency.get(NextAlarmController.class);
         mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         mUserInfoController = Dependency.get(UserInfoController.class);
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
@@ -242,7 +245,7 @@
         mZenController.addCallback(this);
         mCast.addCallback(mCastCallback);
         mHotspot.addCallback(mHotspotCallback);
-        mNextAlarm.addCallback(mNextAlarmCallback);
+        mNextAlarmController.addCallback(mNextAlarmCallback);
         mDataSaver.addCallback(this);
         mKeyguardMonitor.addCallback(this);
         mLocationController.addCallback(this);
@@ -270,7 +273,7 @@
         mZenController.removeCallback(this);
         mCast.removeCallback(mCastCallback);
         mHotspot.removeCallback(mHotspotCallback);
-        mNextAlarm.removeCallback(mNextAlarmCallback);
+        mNextAlarmController.removeCallback(mNextAlarmCallback);
         mDataSaver.removeCallback(this);
         mKeyguardMonitor.removeCallback(this);
         mLocationController.removeCallback(this);
@@ -313,10 +316,29 @@
         int zen = mZenController.getZen();
         final boolean zenNone = zen == Global.ZEN_MODE_NO_INTERRUPTIONS;
         mIconController.setIcon(mSlotAlarmClock, zenNone ? R.drawable.stat_sys_alarm_dim
-                : R.drawable.stat_sys_alarm, null);
+                : R.drawable.stat_sys_alarm, buildAlarmContentDescription());
         mIconController.setIconVisibility(mSlotAlarmClock, mCurrentUserSetup && hasAlarm);
     }
 
+    private String buildAlarmContentDescription() {
+        if (mNextAlarm == null) {
+            return mContext.getString(R.string.status_bar_alarm);
+        }
+        return formatNextAlarm(mNextAlarm, mContext);
+    }
+
+    private static String formatNextAlarm(AlarmManager.AlarmClockInfo info, Context context) {
+        if (info == null) {
+            return "";
+        }
+        String skeleton = DateFormat.is24HourFormat(
+                context, ActivityManager.getCurrentUser()) ? "EHm" : "Ehma";
+        String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
+        String dateString = DateFormat.format(pattern, info.getTriggerTime()).toString();
+
+        return context.getString(R.string.accessibility_quick_settings_alarm, dateString);
+    }
+
     private final void updateSimState(Intent intent) {
         String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
         if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
@@ -356,8 +378,7 @@
 
         if (DndTile.isVisible(mContext) || DndTile.isCombinedIcon(mContext)) {
             zenVisible = zen != Global.ZEN_MODE_OFF;
-            zenIconId = zen == Global.ZEN_MODE_NO_INTERRUPTIONS
-                    ? R.drawable.stat_sys_dnd_total_silence : R.drawable.stat_sys_dnd;
+            zenIconId = R.drawable.stat_sys_dnd;
             zenDescription = mContext.getString(R.string.quick_settings_dnd_label);
         } else if (zen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
             zenVisible = true;
@@ -688,6 +709,7 @@
             new NextAlarmController.NextAlarmChangeCallback() {
                 @Override
                 public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
+                    mNextAlarm = nextAlarm;
                     updateAlarm();
                 }
             };
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 9eeb4d2..b0d72c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -45,6 +45,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.AlarmManager;
+import android.app.IWallpaperManager;
 import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -747,6 +748,14 @@
             Slog.e(TAG, "Failed to register VR mode state listener: " + e);
         }
 
+        IWallpaperManager wallpaperManager = IWallpaperManager.Stub.asInterface(
+                ServiceManager.getService(Context.WALLPAPER_SERVICE));
+        try {
+            wallpaperManager.setInAmbientMode(false /* ambientMode */, false /* animated */);
+        } catch (RemoteException e) {
+            // Just pass, nothing critical.
+        }
+
         // end old BaseStatusBar.start().
 
         // Lastly, call to the icon policy to install/update all the icons.
@@ -1453,11 +1462,11 @@
 
     @VisibleForTesting
     protected void updateFooter() {
-        boolean showFooterView = mState != StatusBarState.KEYGUARD
-                && mEntryManager.getNotificationData().getActiveNotifications().size() != 0
+        boolean showDismissView = mClearAllEnabled && hasActiveClearableNotifications();
+        boolean showFooterView = (showDismissView ||
+                        mEntryManager.getNotificationData().getActiveNotifications().size() != 0)
+                && mState != StatusBarState.KEYGUARD
                 && !mRemoteInputManager.getController().isRemoteInputActive();
-        boolean showDismissView = mClearAllEnabled && mState != StatusBarState.KEYGUARD
-                && hasActiveClearableNotifications();
 
         mStackScroller.updateFooterView(showFooterView, showDismissView);
     }
@@ -2081,7 +2090,7 @@
      * @param animate should the change of the icons be animated.
      */
     private void updateHideIconsForBouncer(boolean animate) {
-        boolean hideBecauseApp = mTopHidesStatusBar && mIsOccluded;
+        boolean hideBecauseApp = mTopHidesStatusBar && mIsOccluded && mStatusBarWindowHidden;
         boolean hideBecauseKeyguard = !mPanelExpanded && !mIsOccluded && mBouncerShowing;
         boolean shouldHideIconsForBouncer = hideBecauseApp || hideBecauseKeyguard;
         if (mHideIconsForBouncer != shouldHideIconsForBouncer) {
@@ -3888,7 +3897,6 @@
         mKeyguardIndicationController.setDozing(mDozing);
         mNotificationPanel.setDozing(mDozing, animate);
         updateQsExpansionEnabled();
-        mViewHierarchyManager.updateRowStates();
         Trace.endSection();
     }
 
@@ -3977,12 +3985,12 @@
     private void showBouncerIfKeyguard() {
         if ((mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)
                 && !mKeyguardViewMediator.isHiding()) {
-            showBouncer(true /* animated */);
+            showBouncer(true /* scrimmed */);
         }
     }
 
-    protected void showBouncer(boolean animated) {
-        mStatusBarKeyguardViewManager.showBouncer(animated);
+    protected void showBouncer(boolean scrimmed) {
+        mStatusBarKeyguardViewManager.showBouncer(scrimmed);
     }
 
     private void instantExpandNotificationsPanel() {
@@ -4096,7 +4104,7 @@
     public void onTrackingStopped(boolean expand) {
         if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
             if (!expand && !mUnlockMethodCache.canSkipBouncer()) {
-                showBouncer(false /* animated */);
+                showBouncer(false /* scrimmed */);
             }
         }
     }
@@ -4235,7 +4243,7 @@
     @Override
     public void onLockedRemoteInput(ExpandableNotificationRow row, View clicked) {
         mLeaveOpenOnKeyguardHide = true;
-        showBouncer(true /* animated */);
+        showBouncer(true /* scrimmed */);
         mPendingRemoteInputView = clicked;
     }
 
@@ -4676,16 +4684,18 @@
                 FingerprintUnlockController.MODE_WAKE_AND_UNLOCK) {
             dozing = false;
         }
-        mDozing = dozing;
-        mKeyguardViewMediator.setAodShowing(mDozing && alwaysOn);
-        mStatusBarWindowManager.setDozing(mDozing);
-        mStatusBarKeyguardViewManager.setDozing(mDozing);
-        if (mAmbientIndicationContainer instanceof DozeReceiver) {
-            ((DozeReceiver) mAmbientIndicationContainer).setDozing(mDozing);
+        if (mDozing != dozing) {
+            mDozing = dozing;
+            mKeyguardViewMediator.setAodShowing(mDozing && alwaysOn);
+            mStatusBarWindowManager.setDozing(mDozing);
+            mStatusBarKeyguardViewManager.setDozing(mDozing);
+            if (mAmbientIndicationContainer instanceof DozeReceiver) {
+                ((DozeReceiver) mAmbientIndicationContainer).setDozing(mDozing);
+            }
+            mEntryManager.updateNotifications();
+            updateDozingState();
+            updateReportRejectedTouchVisibility();
         }
-        mEntryManager.updateNotifications();
-        updateDozingState();
-        updateReportRejectedTouchVisibility();
         Trace.endSection();
     }
 
@@ -4705,7 +4715,7 @@
             // Bouncer needs the front scrim when it's on top of an activity,
             // tapping on a notification, editing QS or being dismissed by
             // FLAG_DISMISS_KEYGUARD_ACTIVITY.
-            ScrimState state = mIsOccluded || mNotificationPanel.needsScrimming()
+            ScrimState state = mStatusBarKeyguardViewManager.bouncerNeedsScrimming()
                     || mStatusBarKeyguardViewManager.willDismissWithAction()
                     || mStatusBarKeyguardViewManager.isFullscreenBouncer() ?
                     ScrimState.BOUNCER_SCRIMMED : ScrimState.BOUNCER;
@@ -5160,7 +5170,8 @@
                 if (parentToCancelFinal != null) {
                     removeNotification(parentToCancelFinal);
                 }
-                if (shouldAutoCancel(sbn)) {
+                if (shouldAutoCancel(sbn)
+                        || mEntryManager.isNotificationKeptForRemoteInput(notificationKey)) {
                     // Automatically remove all notifications that we may have kept around longer
                     removeNotification(sbn);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index b517d11..6a6a7dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -31,6 +31,7 @@
 import android.view.ViewRootImpl;
 import android.view.WindowManagerGlobal;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
@@ -158,7 +159,8 @@
         mNotificationPanelView.setBouncerTop(mBouncer.getTop());
     }
 
-    private void onPanelExpansionChanged(float expansion, boolean tracking) {
+    @VisibleForTesting
+    void onPanelExpansionChanged(float expansion, boolean tracking) {
         // We don't want to translate the bounce when:
         // • Keyguard is occluded, because we're in a FLAG_SHOW_WHEN_LOCKED activity and need to
         //   conserve the original animation.
@@ -166,13 +168,14 @@
         // • Keyguard will be dismissed by an action. a.k.a: FLAG_DISMISS_KEYGUARD_ACTIVITY
         // • Full-screen user switcher is displayed.
         if (mNotificationPanelView.isUnlockHintRunning()) {
-            mBouncer.setExpansion(1);
-        } else if (mOccluded || mBouncer.willDismissWithAction()
+            mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
+        } else if (mBouncer.willDismissWithAction() || mBouncer.isShowingScrimmed()
                 || mStatusBar.isFullScreenUserSwitcherState()) {
-            mBouncer.setExpansion(0);
+            mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
         } else if (mShowing && !mDozing) {
             mBouncer.setExpansion(expansion);
-            if (expansion != 1 && tracking && mStatusBar.isKeyguardCurrentlySecure()
+            if (expansion != KeyguardBouncer.EXPANSION_HIDDEN && tracking
+                    && mStatusBar.isKeyguardCurrentlySecure()
                     && !mBouncer.isShowing() && !mBouncer.isAnimatingAway()) {
                 mBouncer.show(false /* resetSecuritySelection */, false /* animated */);
             }
@@ -215,9 +218,9 @@
         cancelPendingWakeupAction();
     }
 
-    public void showBouncer(boolean animated) {
-        if (mShowing) {
-            mBouncer.show(false /* resetSecuritySelection */, animated);
+    public void showBouncer(boolean scrimmed) {
+        if (mShowing && !mBouncer.isShowing()) {
+            mBouncer.show(false /* resetSecuritySelection */, scrimmed);
         }
         updateStates();
     }
@@ -725,6 +728,10 @@
         return mBouncer.willDismissWithAction();
     }
 
+    public boolean bouncerNeedsScrimming() {
+        return mBouncer.isShowingScrimmed();
+    }
+
     public void dump(PrintWriter pw) {
         pw.println("StatusBarKeyguardViewManager:");
         pw.println("  mShowing: " + mShowing);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 4c100cd..25261c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -23,6 +23,7 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
+import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.wifi.WifiManager;
 import android.os.AsyncTask;
@@ -219,6 +220,38 @@
                         deviceProvisionedController.getCurrentUser()));
             }
         });
+
+        ConnectivityManager.NetworkCallback callback = new ConnectivityManager.NetworkCallback(){
+            private Network mLastNetwork;
+            private NetworkCapabilities mLastNetworkCapabilities;
+
+            @Override
+            public void onCapabilitiesChanged(
+                Network network, NetworkCapabilities networkCapabilities) {
+                boolean lastValidated = (mLastNetworkCapabilities != null) &&
+                    mLastNetworkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED);
+                boolean validated =
+                    networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED);
+
+                // This callback is invoked a lot (i.e. when RSSI changes), so avoid updating
+                // icons when connectivity state has remained the same.
+                if (network.equals(mLastNetwork) &&
+                    networkCapabilities.equalsTransportTypes(mLastNetworkCapabilities) &&
+                    validated == lastValidated) {
+                    return;
+                }
+                mLastNetwork = network;
+                mLastNetworkCapabilities = networkCapabilities;
+                updateConnectivity();
+            }
+        };
+        // Even though this callback runs on the receiver handler thread which also processes the
+        // CONNECTIVITY_ACTION broadcasts, the broadcast and callback might come in at different
+        // times. This is safe since updateConnectivity() builds the list of transports from
+        // scratch.
+        // TODO: Move off of the deprecated CONNECTIVITY_ACTION broadcast and rely on callbacks
+        // exclusively for status bar icons.
+        mConnectivityManager.registerDefaultNetworkCallback(callback, mReceiverHandler);
     }
 
     public DataSaverController getDataSaverController() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index cc802a8..585787e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -207,6 +207,7 @@
         b.setText(choice);
 
         OnDismissAction action = () -> {
+            smartReplyController.smartReplySent(entry, replyIndex, b.getText());
             Bundle results = new Bundle();
             results.putString(remoteInput.getResultKey(), choice.toString());
             Intent intent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
@@ -217,7 +218,6 @@
             } catch (PendingIntent.CanceledException e) {
                 Log.w(TAG, "Unable to send smart reply", e);
             }
-            smartReplyController.smartReplySent(entry, replyIndex, b.getText());
             mSmartReplyContainer.setVisibility(View.GONE);
             return false; // do not defer
         };
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index 45fa44c..2dd3d4e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -1168,7 +1168,6 @@
         if (mOverflowNumber != null) {
             mHybridGroupManager.setOverflowNumberDark(mOverflowNumber, dark, fade, delay);
         }
-        mNotificationHeaderWrapper.setDark(dark, fade, delay);
     }
 
     public void reInflateViews(OnClickListener listener, StatusBarNotification notification) {
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 ee70019..bd56d79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -3922,10 +3922,6 @@
     }
 
     public void goToFullShade(long delay) {
-        if (mFooterView != null) {
-            mFooterView.setInvisible();
-        }
-        mEmptyShadeView.setInvisible();
         mGoToFullShadeNeedsAnimation = true;
         mGoToFullShadeDelay = delay;
         mNeedsAnimation = true;
@@ -4073,17 +4069,7 @@
     }
 
     public void updateEmptyShadeView(boolean visible) {
-        int oldVisibility = mEmptyShadeView.willBeGone() ? GONE : mEmptyShadeView.getVisibility();
-        int newVisibility = visible ? VISIBLE : GONE;
-
-        boolean changedVisibility = oldVisibility != newVisibility;
-        if (changedVisibility) {
-            if (newVisibility != GONE) {
-                showFooterView(mEmptyShadeView);
-            } else {
-                hideFooterView(mEmptyShadeView, true);
-            }
-        }
+        mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled);
 
         int oldTextRes = mEmptyShadeView.getTextResource();
         int newTextRes = mStatusBar.areNotificationsHidden()
@@ -4097,48 +4083,9 @@
         if (mFooterView == null) {
             return;
         }
-        int oldVisibility = mFooterView.willBeGone() ? GONE : mFooterView.getVisibility();
-        int newVisibility = visible ? VISIBLE : GONE;
-        if (oldVisibility != newVisibility) {
-            if (newVisibility != GONE) {
-                showFooterView(mFooterView);
-            } else {
-                hideFooterView(mFooterView, mFooterView.isButtonVisible());
-            }
-        }
-        if (mFooterView.isSecondaryVisible() != showDismissView) {
-            mFooterView.performSecondaryVisibilityAnimation(showDismissView);
-        }
-    }
-
-    private void showFooterView(StackScrollerDecorView footerView) {
-        if (footerView.willBeGone()) {
-            footerView.cancelAnimation();
-        } else {
-            footerView.setInvisible();
-        }
-        footerView.setVisibility(VISIBLE);
-        footerView.setWillBeGone(false);
-        updateContentHeight();
-        notifyHeightChangeListener(footerView);
-    }
-
-    private void hideFooterView(StackScrollerDecorView footerView, boolean isButtonVisible) {
-        Runnable onHideFinishRunnable = new Runnable() {
-            @Override
-            public void run() {
-                footerView.setVisibility(GONE);
-                footerView.setWillBeGone(false);
-                updateContentHeight();
-                notifyHeightChangeListener(footerView);
-            }
-        };
-        if (isButtonVisible && mIsExpanded && mAnimationsEnabled) {
-            footerView.setWillBeGone(true);
-            footerView.performVisibilityAnimation(false, onHideFinishRunnable);
-        } else {
-            onHideFinishRunnable.run();
-        }
+        boolean animate = mIsExpanded && mAnimationsEnabled;
+        mFooterView.setVisible(visible, animate);
+        mFooterView.setSecondaryVisible(showDismissView, animate);
     }
 
     public void setDismissAllInProgress(boolean dismissAllInProgress) {
@@ -4170,8 +4117,8 @@
                 && !mFooterView.willBeGone();
     }
 
-    public boolean isFooterViewVisible() {
-        return mFooterView != null && mFooterView.isVisible();
+    public boolean isFooterViewContentVisible() {
+        return mFooterView != null && mFooterView.isContentVisible();
     }
 
     public int getFooterViewHeight() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index 4e8fcac..a75d40f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -364,7 +364,7 @@
                 // This item is added, initialize it's properties.
                 ExpandableViewState viewState = finalState
                         .getViewStateForView(changingView);
-                if (viewState == null) {
+                if (viewState == null || viewState.gone) {
                     // The position for this child was never generated, let's continue.
                     continue;
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 6b322c7..d76b7f0 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -36,6 +36,7 @@
 import android.annotation.SuppressLint;
 import android.app.Dialog;
 import android.app.KeyguardManager;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -445,6 +446,7 @@
                 }
             }
             Events.writeEvent(mContext, Events.EVENT_RINGER_TOGGLE, newRingerMode);
+            incrementManualToggleCount();
             updateRingerH();
             provideTouchFeedbackH(newRingerMode);
             mController.setRingerMode(newRingerMode, false);
@@ -453,6 +455,11 @@
         updateRingerH();
     }
 
+    private void incrementManualToggleCount() {
+        ContentResolver cr = mContext.getContentResolver();
+        int ringerCount = Settings.Secure.getInt(cr, Settings.Secure.MANUAL_RINGER_TOGGLE_COUNT, 0);
+        Settings.Secure.putInt(cr, Settings.Secure.MANUAL_RINGER_TOGGLE_COUNT, ringerCount + 1);
+    }
 
     private void provideTouchFeedbackH(int newRingerMode) {
         VibrationEffect effect = null;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaTest.java
index f3be945..f8ca262 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaTest.java
@@ -20,10 +20,9 @@
 
 import static org.mockito.Mockito.mock;
 
-import android.os.Handler;
-import android.os.Looper;
-import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
 
 import com.android.systemui.SysuiTestCase;
 
@@ -32,33 +31,25 @@
 import org.junit.runner.RunWith;
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
 public class KeyguardMessageAreaTest extends SysuiTestCase {
-    private Handler mHandler = new Handler(Looper.getMainLooper());
     private KeyguardMessageArea mMessageArea;
 
     @Before
     public void setUp() throws Exception {
         KeyguardUpdateMonitor monitor = mock(KeyguardUpdateMonitor.class);
-        mHandler.post(()-> mMessageArea = new KeyguardMessageArea(mContext, null, monitor));
+        mMessageArea = new KeyguardMessageArea(mContext, null, monitor);
         waitForIdleSync();
     }
 
     @Test
     public void clearFollowedByMessage_keepsMessage() {
-        mHandler.post(()-> {
-            mMessageArea.setMessage("");
-            mMessageArea.setMessage("test");
-        });
-
-        waitForIdleSync();
+        mMessageArea.setMessage("");
+        mMessageArea.setMessage("test");
 
         CharSequence[] messageText = new CharSequence[1];
-        mHandler.post(()-> {
-            messageText[0] = mMessageArea.getText();
-        });
-
-        waitForIdleSync();
+        messageText[0] = mMessageArea.getText();
 
         assertEquals("test", messageText[0]);
     }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 21483aa..d46a974 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -16,6 +16,7 @@
 
 package com.android.keyguard;
 
+import android.content.Context;
 import android.content.Intent;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -35,7 +36,12 @@
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
-@RunWithLooper
+// We must run on the main looper because KeyguardUpdateMonitor#mHandler is initialized with
+// new Handler(Looper.getMainLooper()).
+//
+// Using the main looper should be avoided whenever possible, please don't copy this over to
+// new tests.
+@RunWithLooper(setAsMainLooper = true)
 public class KeyguardUpdateMonitorTest extends SysuiTestCase {
 
     private TestableLooper mTestableLooper;
@@ -49,24 +55,39 @@
     public void testIgnoresSimStateCallback_rebroadcast() {
         Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
 
-        AtomicBoolean simStateChanged = new AtomicBoolean(false);
-        KeyguardUpdateMonitor keyguardUpdateMonitor = new KeyguardUpdateMonitor(getContext()) {
-            @Override
-            protected void handleSimStateChange(int subId, int slotId,
-                    IccCardConstants.State state) {
-                simStateChanged.set(true);
-                super.handleSimStateChange(subId, slotId, state);
-            }
-        };
+        TestableKeyguardUpdateMonitor keyguardUpdateMonitor =
+                new TestableKeyguardUpdateMonitor(getContext());
 
         keyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), intent);
         mTestableLooper.processAllMessages();
-        Assert.assertTrue("onSimStateChanged not called", simStateChanged.get());
+        Assert.assertTrue("onSimStateChanged not called",
+                keyguardUpdateMonitor.hasSimStateJustChanged());
 
         intent.putExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, true);
-        simStateChanged.set(false);
         keyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext(), intent);
         mTestableLooper.processAllMessages();
-        Assert.assertFalse("onSimStateChanged should have been skipped", simStateChanged.get());
+        Assert.assertFalse("onSimStateChanged should have been skipped",
+                keyguardUpdateMonitor.hasSimStateJustChanged());
+    }
+
+    private class TestableKeyguardUpdateMonitor extends KeyguardUpdateMonitor {
+        AtomicBoolean mSimStateChanged = new AtomicBoolean(false);
+
+        protected TestableKeyguardUpdateMonitor(Context context) {
+            super(context);
+            // Avoid race condition when unexpected broadcast could be received.
+            context.unregisterReceiver(mBroadcastReceiver);
+        }
+
+        public boolean hasSimStateJustChanged() {
+            return mSimStateChanged.getAndSet(false);
+        }
+
+        @Override
+        protected void handleSimStateChange(int subId, int slotId,
+                IccCardConstants.State state) {
+            mSimStateChanged.set(true);
+            super.handleSimStateChange(subId, slotId, state);
+        }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java
index aa840989..08c4235 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java
@@ -22,6 +22,8 @@
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
 
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.NotificationTestHelper;
@@ -35,7 +37,8 @@
 import static org.mockito.Mockito.when;
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
 public class ExpandHelperTest extends SysuiTestCase {
 
     private ExpandableNotificationRow mRow;
@@ -47,9 +50,7 @@
         Context context = getContext();
         mRow = new NotificationTestHelper(context).createRow();
         mCallback = mock(ExpandHelper.Callback.class);
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(
-                () -> mExpandHelper = new ExpandHelper(context, mCallback, 10, 100));
-
+        mExpandHelper = new ExpandHelper(context, mCallback, 10, 100);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index a8ea1c0..c2da7f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -29,7 +29,8 @@
 import android.os.Looper;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
 
 import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.systemui.SysuiTestCase;
@@ -46,7 +47,8 @@
 
 @SmallTest
 @Ignore("failing")
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
 public class DozeTriggersTest extends SysuiTestCase {
     private DozeTriggers mTriggers;
     private DozeMachine mMachine;
@@ -54,7 +56,6 @@
     private AmbientDisplayConfiguration mConfig;
     private DozeParameters mParameters;
     private FakeSensorManager mSensors;
-    private Handler mHandler;
     private WakeLock mWakeLock;
     private Instrumentation mInstrumentation;
     private AlarmManager mAlarmManager;
@@ -74,40 +75,29 @@
         mConfig = DozeConfigurationUtil.createMockConfig();
         mParameters = DozeConfigurationUtil.createMockParameters();
         mSensors = new FakeSensorManager(mContext);
-        mHandler = new Handler(Looper.getMainLooper());
         mWakeLock = new WakeLockFake();
 
-        mInstrumentation.runOnMainSync(() -> {
-            mTriggers = new DozeTriggers(mContext, mMachine, mHost, mAlarmManager,
-                    mConfig, mParameters, mSensors, mHandler, mWakeLock, true);
-        });
+        mTriggers = new DozeTriggers(mContext, mMachine, mHost, mAlarmManager, mConfig, mParameters,
+                mSensors, Handler.createAsync(Looper.myLooper()), mWakeLock, true);
     }
 
     @Test
     public void testOnNotification_stillWorksAfterOneFailedProxCheck() throws Exception {
         when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE);
 
-        mInstrumentation.runOnMainSync(()->{
-            mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
-            mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
+        mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
+        mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
 
-            mHost.callback.onNotificationHeadsUp();
-        });
+        mHost.callback.onNotificationHeadsUp();
 
-        mInstrumentation.runOnMainSync(() -> {
-            mSensors.getMockProximitySensor().sendProximityResult(false); /* Near */
-        });
+        mSensors.getMockProximitySensor().sendProximityResult(false); /* Near */
 
         verify(mMachine, never()).requestState(any());
         verify(mMachine, never()).requestPulse(anyInt());
 
-        mInstrumentation.runOnMainSync(()->{
-            mHost.callback.onNotificationHeadsUp();
-        });
+        mHost.callback.onNotificationHeadsUp();
 
-        mInstrumentation.runOnMainSync(() -> {
-            mSensors.getMockProximitySensor().sendProximityResult(true); /* Far */
-        });
+        mSensors.getMockProximitySensor().sendProximityResult(true); /* Far */
 
         verify(mMachine).requestPulse(anyInt());
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchStateTest.java
index b8c946d..b7c1e8e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchStateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchStateTest.java
@@ -24,43 +24,36 @@
 import static org.junit.Assert.assertTrue;
 
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.SystemClock;
 import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
 import android.view.MotionEvent;
 import android.view.ViewConfiguration;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.pip.phone.PipTouchState;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
 @SmallTest
+@RunWithLooper
 public class PipTouchStateTest extends SysuiTestCase {
 
-    private Handler mHandler;
-    private HandlerThread mHandlerThread;
     private PipTouchState mTouchState;
     private CountDownLatch mDoubleTapCallbackTriggeredLatch;
 
     @Before
     public void setUp() throws Exception {
-        mHandlerThread = new HandlerThread("PipTouchStateTestThread");
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
-
         mDoubleTapCallbackTriggeredLatch = new CountDownLatch(1);
         mTouchState = new PipTouchState(ViewConfiguration.get(getContext()),
-                mHandler, () -> {
+                Handler.createAsync(Looper.myLooper()), () -> {
             mDoubleTapCallbackTriggeredLatch.countDown();
         });
         assertFalse(mTouchState.isDoubleTap());
@@ -91,7 +84,10 @@
 
         assertTrue(mTouchState.getDoubleTapTimeoutCallbackDelay() == 10);
         mTouchState.scheduleDoubleTapTimeoutCallback();
-        mDoubleTapCallbackTriggeredLatch.await(1, TimeUnit.SECONDS);
+
+        // TODO: Remove this sleep. Its only being added because it speeds up this test a bit.
+        Thread.sleep(15);
+        TestableLooper.get(this).processAllMessages();
         assertTrue(mDoubleTapCallbackTriggeredLatch.getCount() == 0);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
index 4f98836..33b347a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -22,12 +22,15 @@
 
 import android.content.Context;
 import android.content.pm.UserInfo;
-import android.os.Handler;
 import android.os.Looper;
 import android.os.UserManager;
 import android.provider.Settings;
-import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.LayoutInflaterBuilder;
+import android.testing.TestableImageView;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
 import android.text.SpannableStringBuilder;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -38,8 +41,6 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.policy.SecurityController;
-import android.testing.LayoutInflaterBuilder;
-import android.testing.TestableImageView;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -56,7 +57,8 @@
 */
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
 public class QSSecurityFooterTest extends SysuiTestCase {
 
     private final String MANAGING_ORGANIZATION = "organization";
@@ -81,12 +83,10 @@
                         .build());
         mUserManager = Mockito.mock(UserManager.class);
         mContext.addMockSystemService(Context.USER_SERVICE, mUserManager);
-        Handler h = new Handler(Looper.getMainLooper());
-        h.post(() -> mFooter = new QSSecurityFooter(null, mContext));
-        waitForIdleSync(h);
+        mFooter = new QSSecurityFooter(null, mContext);
         mRootView = (ViewGroup) mFooter.getView();
-        mFooterText = (TextView) mRootView.findViewById(R.id.footer_text);
-        mFooterIcon = (TestableImageView) mRootView.findViewById(R.id.footer_icon);
+        mFooterText = mRootView.findViewById(R.id.footer_text);
+        mFooterIcon = mRootView.findViewById(R.id.footer_icon);
         mFooter.setHostEnvironment(null);
     }
 
@@ -95,7 +95,7 @@
         when(mSecurityController.isDeviceManaged()).thenReturn(false);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(View.GONE, mRootView.getVisibility());
     }
 
@@ -105,7 +105,7 @@
         when(mSecurityController.getDeviceOwnerOrganizationName()).thenReturn(null);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_management),
                      mFooterText.getText());
         assertEquals(View.VISIBLE, mRootView.getVisibility());
@@ -121,7 +121,7 @@
                 .thenReturn(MANAGING_ORGANIZATION);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_named_management,
                                         MANAGING_ORGANIZATION),
                 mFooterText.getText());
@@ -142,7 +142,7 @@
 
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(View.GONE, mRootView.getVisibility());
     }
 
@@ -152,7 +152,7 @@
         when(mSecurityController.isNetworkLoggingEnabled()).thenReturn(true);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_monitoring),
                 mFooterText.getText());
         assertEquals(View.VISIBLE, mFooterIcon.getVisibility());
@@ -164,7 +164,7 @@
                 .thenReturn(MANAGING_ORGANIZATION);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(mContext.getString(
                              R.string.quick_settings_disclosure_named_management_monitoring,
                              MANAGING_ORGANIZATION),
@@ -177,7 +177,7 @@
         when(mSecurityController.hasCACertInCurrentUser()).thenReturn(true);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_monitoring),
                 mFooterText.getText());
     }
@@ -189,7 +189,7 @@
         when(mSecurityController.getPrimaryVpnName()).thenReturn(VPN_PACKAGE);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_named_vpn,
                                         VPN_PACKAGE),
                      mFooterText.getText());
@@ -201,7 +201,7 @@
                 .thenReturn(MANAGING_ORGANIZATION);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(mContext.getString(
                               R.string.quick_settings_disclosure_named_management_named_vpn,
                               MANAGING_ORGANIZATION, VPN_PACKAGE),
@@ -216,7 +216,7 @@
         when(mSecurityController.getWorkProfileVpnName()).thenReturn(VPN_PACKAGE_2);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_vpns),
                      mFooterText.getText());
         assertEquals(View.VISIBLE, mFooterIcon.getVisibility());
@@ -227,7 +227,7 @@
                 .thenReturn(MANAGING_ORGANIZATION);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_named_management_vpns,
                                         MANAGING_ORGANIZATION),
                      mFooterText.getText());
@@ -241,7 +241,7 @@
         when(mSecurityController.getPrimaryVpnName()).thenReturn("VPN Test App");
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(View.VISIBLE, mFooterIcon.getVisibility());
         assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource());
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_monitoring),
@@ -254,7 +254,7 @@
         when(mSecurityController.hasCACertInWorkProfile()).thenReturn(true);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         // -1 == never set.
         assertEquals(-1, mFooterIcon.getLastImageResource());
         assertEquals(mContext.getString(
@@ -266,7 +266,7 @@
                 .thenReturn(MANAGING_ORGANIZATION);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(mContext.getString(
                              R.string.quick_settings_disclosure_named_managed_profile_monitoring,
                              MANAGING_ORGANIZATION),
@@ -279,7 +279,7 @@
         when(mSecurityController.hasCACertInCurrentUser()).thenReturn(true);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         // -1 == never set.
         assertEquals(-1, mFooterIcon.getLastImageResource());
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_monitoring),
@@ -293,7 +293,7 @@
         when(mSecurityController.getWorkProfileVpnName()).thenReturn(VPN_PACKAGE_2);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource());
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_vpns),
                      mFooterText.getText());
@@ -305,7 +305,7 @@
         when(mSecurityController.getWorkProfileVpnName()).thenReturn(VPN_PACKAGE_2);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource());
         assertEquals(mContext.getString(
                              R.string.quick_settings_disclosure_managed_profile_named_vpn,
@@ -319,7 +319,7 @@
         when(mSecurityController.getPrimaryVpnName()).thenReturn(VPN_PACKAGE);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource());
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_named_vpn,
                                         VPN_PACKAGE),
@@ -328,7 +328,7 @@
         when(mSecurityController.hasWorkProfile()).thenReturn(true);
         mFooter.refreshState();
 
-        waitForIdleSync(mFooter.mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertEquals(mContext.getString(
                              R.string.quick_settings_disclosure_personal_profile_named_vpn,
                              VPN_PACKAGE),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
index 66ec7dd..e5e8ae3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
@@ -81,7 +81,7 @@
         mUser = new UserHandle(UserHandle.myUserId());
         mThread = new HandlerThread("TestThread");
         mThread.start();
-        mHandler = new Handler(mThread.getLooper());
+        mHandler = Handler.createAsync(mThread.getLooper());
         mStateManager = new TileLifecycleManager(mHandler, mContext,
                 Mockito.mock(IQSService.class), new Tile(),
                 mTileServiceIntent,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java
index c2237c9..cc743245 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java
@@ -46,7 +46,7 @@
     public void setUp() throws Exception {
         mThread = new HandlerThread("TestThread");
         mThread.start();
-        mHandler = new Handler(mThread.getLooper());
+        mHandler = Handler.createAsync(mThread.getLooper());
         mTileServices = Mockito.mock(TileServices.class);
         Mockito.when(mTileServices.getContext()).thenReturn(mContext);
         mTileLifecycle = Mockito.mock(TileLifecycleManager.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java
index dc0e2b0..0feaa5a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.statusbar;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -53,7 +51,6 @@
     @Mock private ForegroundServiceController mFsc;
 
     private AppOpsListener mListener;
-    private Handler mHandler;
 
     @Before
     public void setUp() {
@@ -61,8 +58,7 @@
         mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
         mDependency.injectTestDependency(ForegroundServiceController.class, mFsc);
         getContext().addMockSystemService(AppOpsManager.class, mAppOpsManager);
-        mHandler = new Handler(Looper.getMainLooper());
-        when(mPresenter.getHandler()).thenReturn(mHandler);
+        when(mPresenter.getHandler()).thenReturn(Handler.createAsync(Looper.myLooper()));
 
         mListener = new AppOpsListener(mContext);
     }
@@ -85,7 +81,7 @@
         mListener.setUpWithPresenter(mPresenter, mEntryManager);
         mListener.onOpActiveChanged(
                 AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
-        waitForIdleSync(mHandler);
+        TestableLooper.get(this).processAllMessages();
         verify(mEntryManager, times(1)).updateNotificationsForAppOp(
                 AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
     }
@@ -95,7 +91,7 @@
         mListener.setUpWithPresenter(mPresenter, mEntryManager);
         mListener.onOpActiveChanged(
                 AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
-        waitForIdleSync(mHandler);
+        TestableLooper.get(this).processAllMessages();
         verify(mFsc, times(1)).onAppOpChanged(
                 AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
     }
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 2a4a5ad..ff12c53 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar;
 
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -33,7 +34,8 @@
 import android.app.AppOpsManager;
 import android.app.NotificationChannel;
 import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
 import android.util.ArraySet;
 import android.view.NotificationHeaderView;
 import android.view.View;
@@ -49,15 +51,14 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.Spy;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
 import java.util.List;
-import java.util.function.Consumer;
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
 public class ExpandableNotificationRowTest extends SysuiTestCase {
 
     private ExpandableNotificationRow mGroupRow;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/FooterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/FooterViewTest.java
index 96b0255..e6fdfa4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/FooterViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/FooterViewTest.java
@@ -23,39 +23,22 @@
 import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
 
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.graphics.Color;
-import android.graphics.drawable.Icon;
-import android.os.UserHandle;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
-import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
 
-import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.util.NotificationColorUtil;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.ExpectedException;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatcher;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -90,34 +73,18 @@
 
     @Test
     public void testPerformVisibilityAnimation() {
-        mView.setInvisible();
+        mView.setVisible(false /* visible */, false /* animate */);
         assertFalse(mView.isVisible());
 
-        Runnable test = new Runnable() {
-            @Override
-            public void run() {
-                assertEquals(1.0f, mView.findContentView().getAlpha());
-                assertEquals(0.0f, mView.findSecondaryView().getAlpha());
-                assertTrue(mView.isVisible());
-            }
-        };
-        mView.performVisibilityAnimation(true, test);
+        mView.setVisible(true /* visible */, true /* animate */);
     }
 
     @Test
     public void testPerformSecondaryVisibilityAnimation() {
-        mView.setInvisible();
+        mView.setSecondaryVisible(false /* visible */, false /* animate */);
         assertFalse(mView.isSecondaryVisible());
 
-        Runnable test = new Runnable() {
-            @Override
-            public void run() {
-                assertEquals(0.0f, mView.findContentView().getAlpha());
-                assertEquals(1.0f, mView.findSecondaryView().getAlpha());
-                assertTrue(mView.isSecondaryVisible());
-            }
-        };
-        mView.performSecondaryVisibilityAnimation(true, test);
+        mView.setSecondaryVisible(true /* visible */, true /* animate */);
     }
 }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
index 1204dda..2af0c3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
@@ -55,13 +55,10 @@
     @Mock private NotificationGutsManager.OnSettingsClickListener mOnClickListener;
     @Mock private NotificationRemoteInputManager.Callback mRemoteInputManagerCallback;
 
-    private Handler mHandler;
-
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mHandler = new Handler(Looper.getMainLooper());
-        when(mPresenter.getHandler()).thenReturn(mHandler);
+        when(mPresenter.getHandler()).thenReturn(Handler.createAsync(Looper.myLooper()));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationBlockingHelperManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationBlockingHelperManagerTest.java
index a6d87af..9638541 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationBlockingHelperManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationBlockingHelperManagerTest.java
@@ -52,7 +52,7 @@
 @SmallTest
 @FlakyTest
 @org.junit.runner.RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class NotificationBlockingHelperManagerTest extends SysuiTestCase {
 
     private NotificationBlockingHelperManager mBlockingHelperManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
index 2ff86c3..a34588d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
@@ -16,9 +16,9 @@
 
 package com.android.systemui.statusbar;
 
-import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
 import android.view.View;
 import android.widget.RemoteViews;
 
@@ -33,7 +33,8 @@
 import org.junit.runner.RunWith;
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
 public class NotificationCustomViewWrapperTest extends SysuiTestCase {
 
     private ExpandableNotificationRow mRow;
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 8bdaff9..609e032 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
@@ -47,6 +47,8 @@
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
 import android.util.ArraySet;
 
 import com.android.systemui.ForegroundServiceController;
@@ -61,7 +63,8 @@
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
 public class NotificationDataTest extends SysuiTestCase {
 
     private static final int UID_NORMAL = 123;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
index 8172626..afe16cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
@@ -19,6 +19,7 @@
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.assertFalse;
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
@@ -97,10 +98,10 @@
     @Mock private DeviceProvisionedController mDeviceProvisionedController;
     @Mock private VisualStabilityManager mVisualStabilityManager;
     @Mock private MetricsLogger mMetricsLogger;
+    @Mock private SmartReplyController mSmartReplyController;
 
     private NotificationData.Entry mEntry;
     private StatusBarNotification mSbn;
-    private Handler mHandler;
     private TestableNotificationEntryManager mEntryManager;
     private CountDownLatch mCountDownLatch;
 
@@ -159,11 +160,11 @@
                 mDeviceProvisionedController);
         mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
         mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
+        mDependency.injectTestDependency(SmartReplyController.class, mSmartReplyController);
 
-        mHandler = new Handler(Looper.getMainLooper());
         mCountDownLatch = new CountDownLatch(1);
 
-        when(mPresenter.getHandler()).thenReturn(mHandler);
+        when(mPresenter.getHandler()).thenReturn(Handler.createAsync(Looper.myLooper()));
         when(mPresenter.getNotificationLockscreenUserManager()).thenReturn(mLockscreenUserManager);
         when(mPresenter.getGroupManager()).thenReturn(mGroupManager);
         when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
@@ -188,6 +189,7 @@
     @Test
     public void testAddNotification() throws Exception {
         com.android.systemui.util.Assert.isNotMainThread();
+        TestableLooper.get(this).processAllMessages();
 
         doAnswer(invocation -> {
             mCountDownLatch.countDown();
@@ -196,12 +198,10 @@
 
         // Post on main thread, otherwise we will be stuck waiting here for the inflation finished
         // callback forever, since it won't execute until the tests ends.
-        mHandler.post(() -> {
-            mEntryManager.addNotification(mSbn, mRankingMap);
-        });
-        assertTrue(mCountDownLatch.await(1, TimeUnit.MINUTES));
-        assertTrue(mEntryManager.getCountDownLatch().await(1, TimeUnit.MINUTES));
-        waitForIdleSync(mHandler);
+        mEntryManager.addNotification(mSbn, mRankingMap);
+        TestableLooper.get(this).processMessages(1);
+        assertTrue(mCountDownLatch.await(10, TimeUnit.SECONDS));
+        assertTrue(mEntryManager.getCountDownLatch().await(10, TimeUnit.SECONDS));
 
         // Check that no inflation error occurred.
         verify(mBarService, never()).onNotificationError(any(), any(), anyInt(), anyInt(), anyInt(),
@@ -228,17 +228,16 @@
     @Test
     public void testUpdateNotification() throws Exception {
         com.android.systemui.util.Assert.isNotMainThread();
+        TestableLooper.get(this).processAllMessages();
 
         mEntryManager.getNotificationData().add(mEntry);
 
         setUserSentiment(mEntry.key, NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
 
-        mHandler.post(() -> {
-            mEntryManager.updateNotification(mSbn, mRankingMap);
-        });
+        mEntryManager.updateNotification(mSbn, mRankingMap);
+        TestableLooper.get(this).processMessages(1);
         // Wait for content update.
-        mEntryManager.getCountDownLatch().await(1, TimeUnit.MINUTES);
-        waitForIdleSync(mHandler);
+        assertTrue(mEntryManager.getCountDownLatch().await(10, TimeUnit.SECONDS));
 
         verify(mBarService, never()).onNotificationError(any(), any(), anyInt(), anyInt(), anyInt(),
                 any(), anyInt());
@@ -259,16 +258,14 @@
         mEntry.row = mRow;
         mEntryManager.getNotificationData().add(mEntry);
 
-        mHandler.post(() -> {
-            mEntryManager.removeNotification(mSbn.getKey(), mRankingMap);
-        });
-        waitForIdleSync(mHandler);
+        mEntryManager.removeNotification(mSbn.getKey(), mRankingMap);
 
         verify(mBarService, never()).onNotificationError(any(), any(), anyInt(), anyInt(), anyInt(),
                 any(), anyInt());
 
         verify(mMediaManager).onNotificationRemoved(mSbn.getKey());
         verify(mRemoteInputManager).onRemoveNotification(mEntry);
+        verify(mSmartReplyController).stopSending(mEntry);
         verify(mForegroundServiceController).removeNotification(mSbn);
         verify(mListContainer).cleanUpViewState(mRow);
         verify(mPresenter).updateNotificationViews();
@@ -279,6 +276,20 @@
     }
 
     @Test
+    public void testRemoveNotification_blockedBySendingSmartReply() throws Exception {
+        com.android.systemui.util.Assert.isNotMainThread();
+
+        mEntry.row = mRow;
+        mEntryManager.getNotificationData().add(mEntry);
+        when(mSmartReplyController.isSendingSmartReply(mEntry.key)).thenReturn(true);
+
+        mEntryManager.removeNotification(mSbn.getKey(), mRankingMap);
+
+        assertNotNull(mEntryManager.getNotificationData().get(mSbn.getKey()));
+        assertTrue(mEntryManager.isNotificationKeptForRemoteInput(mEntry.key));
+    }
+
+    @Test
     public void testUpdateAppOps_foregroundNoti() {
         com.android.systemui.util.Assert.isNotMainThread();
 
@@ -287,12 +298,9 @@
         mEntry.row = mRow;
         mEntryManager.getNotificationData().add(mEntry);
 
-        mHandler.post(() -> {
-            mEntryManager.updateNotificationsForAppOp(
-                    AppOpsManager.OP_CAMERA, mEntry.notification.getUid(),
-                    mEntry.notification.getPackageName(), true);
-        });
-        waitForIdleSync(mHandler);
+        mEntryManager.updateNotificationsForAppOp(
+                AppOpsManager.OP_CAMERA, mEntry.notification.getUid(),
+                mEntry.notification.getPackageName(), true);
 
         verify(mPresenter, times(1)).updateNotificationViews();
         assertTrue(mEntryManager.getNotificationData().get(mEntry.key).mActiveAppOps.contains(
@@ -305,10 +313,7 @@
 
         when(mForegroundServiceController.getStandardLayoutKey(anyInt(), anyString()))
                 .thenReturn(null);
-        mHandler.post(() -> {
-            mEntryManager.updateNotificationsForAppOp(AppOpsManager.OP_CAMERA, 1000, "pkg", true);
-        });
-        waitForIdleSync(mHandler);
+        mEntryManager.updateNotificationsForAppOp(AppOpsManager.OP_CAMERA, 1000, "pkg", true);
 
         verify(mPresenter, never()).updateNotificationViews();
     }
@@ -378,6 +383,8 @@
         Assert.assertEquals("A Reply", messages[0]);
         Assert.assertFalse(newSbn.getNotification().extras
                 .getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false));
+        Assert.assertTrue(newSbn.getNotification().extras
+                .getBoolean(Notification.EXTRA_HIDE_SMART_REPLIES, false));
     }
 
     @Test
@@ -390,6 +397,8 @@
         Assert.assertEquals("A Reply", messages[0]);
         Assert.assertTrue(newSbn.getNotification().extras
                 .getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false));
+        Assert.assertTrue(newSbn.getNotification().extras
+                .getBoolean(Notification.EXTRA_HIDE_SMART_REPLIES, false));
     }
 
     @Test
@@ -407,4 +416,15 @@
         Assert.assertEquals("Reply 2", messages[0]);
         Assert.assertEquals("A Reply", messages[1]);
     }
+
+    @Test
+    public void testRebuildNotificationForCanceledSmartReplies() {
+        // Try rebuilding to remove spinner and hide buttons.
+        StatusBarNotification newSbn =
+                mEntryManager.rebuildNotificationForCanceledSmartReplies(mEntry);
+        Assert.assertFalse(newSbn.getNotification().extras
+                .getBoolean(Notification.EXTRA_SHOW_REMOTE_INPUT_SPINNER, false));
+        Assert.assertTrue(newSbn.getNotification().extras
+                .getBoolean(Notification.EXTRA_HIDE_SMART_REPLIES, false));
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsManagerTest.java
index 0ef2d051..cba1b54 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsManagerTest.java
@@ -74,7 +74,7 @@
  */
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class NotificationGutsManagerTest extends SysuiTestCase {
     private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
 
@@ -95,7 +95,7 @@
     @Before
     public void setUp() {
         mTestableLooper = TestableLooper.get(this);
-        mHandler = new Handler(mTestableLooper.getLooper());
+        mHandler = Handler.createAsync(mTestableLooper.getLooper());
 
         mHelper = new NotificationTestHelper(mContext);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
index ef5f071..26f91b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
@@ -59,9 +59,7 @@
     @Mock private NotificationRemoteInputManager mRemoteInputManager;
 
     private NotificationListener mListener;
-    private Handler mHandler;
     private StatusBarNotification mSbn;
-    private Set<String> mKeysKeptForRemoteInput;
 
     @Before
     public void setUp() {
@@ -70,12 +68,8 @@
         mDependency.injectTestDependency(NotificationRemoteInputManager.class,
                 mRemoteInputManager);
 
-        mHandler = new Handler(Looper.getMainLooper());
-        mKeysKeptForRemoteInput = new HashSet<>();
-
-        when(mPresenter.getHandler()).thenReturn(mHandler);
+        when(mPresenter.getHandler()).thenReturn(Handler.createAsync(Looper.myLooper()));
         when(mEntryManager.getNotificationData()).thenReturn(mNotificationData);
-        when(mRemoteInputManager.getKeysKeptForRemoteInput()).thenReturn(mKeysKeptForRemoteInput);
 
         mListener = new NotificationListener(mContext);
         mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
@@ -87,37 +81,36 @@
     @Test
     public void testNotificationAddCallsAddNotification() {
         mListener.onNotificationPosted(mSbn, mRanking);
-        waitForIdleSync(mHandler);
+        TestableLooper.get(this).processAllMessages();
         verify(mEntryManager).addNotification(mSbn, mRanking);
     }
 
     @Test
     public void testPostNotificationRemovesKeyKeptForRemoteInput() {
-        mKeysKeptForRemoteInput.add(mSbn.getKey());
         mListener.onNotificationPosted(mSbn, mRanking);
-        waitForIdleSync(mHandler);
-        assertTrue(mKeysKeptForRemoteInput.isEmpty());
+        TestableLooper.get(this).processAllMessages();
+        verify(mEntryManager).removeKeyKeptForRemoteInput(mSbn.getKey());
     }
 
     @Test
     public void testNotificationUpdateCallsUpdateNotification() {
         when(mNotificationData.get(mSbn.getKey())).thenReturn(new NotificationData.Entry(mSbn));
         mListener.onNotificationPosted(mSbn, mRanking);
-        waitForIdleSync(mHandler);
+        TestableLooper.get(this).processAllMessages();
         verify(mEntryManager).updateNotification(mSbn, mRanking);
     }
 
     @Test
     public void testNotificationRemovalCallsRemoveNotification() {
         mListener.onNotificationRemoved(mSbn, mRanking);
-        waitForIdleSync(mHandler);
+        TestableLooper.get(this).processAllMessages();
         verify(mEntryManager).removeNotification(mSbn.getKey(), mRanking);
     }
 
     @Test
     public void testRankingUpdateCallsNotificationRankingUpdate() {
         mListener.onNotificationRankingUpdate(mRanking);
-        waitForIdleSync(mHandler);
+        TestableLooper.get(this).processAllMessages();
         // RankingMap may be modified by plugins.
         verify(mEntryManager).updateNotificationRanking(any());
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index cb8f7ce..2401519 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -63,7 +63,6 @@
     @Mock private DeviceProvisionedController mDeviceProvisionedController;
 
     private int mCurrentUserId;
-    private Handler mHandler;
     private TestNotificationLockscreenUserManager mLockscreenUserManager;
 
     @Before
@@ -73,13 +72,12 @@
         mDependency.injectTestDependency(DeviceProvisionedController.class,
                 mDeviceProvisionedController);
 
-        mHandler = new Handler(Looper.getMainLooper());
         mContext.addMockSystemService(UserManager.class, mUserManager);
         mCurrentUserId = ActivityManager.getCurrentUser();
 
         when(mUserManager.getProfiles(mCurrentUserId)).thenReturn(Lists.newArrayList(
                 new UserInfo(mCurrentUserId, "", 0), new UserInfo(mCurrentUserId + 1, "", 0)));
-        when(mPresenter.getHandler()).thenReturn(mHandler);
+        when(mPresenter.getHandler()).thenReturn(Handler.createAsync(Looper.myLooper()));
 
         mLockscreenUserManager = new TestNotificationLockscreenUserManager(mContext);
         mLockscreenUserManager.setUpWithPresenter(mPresenter, mEntryManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLoggerTest.java
index 14fada5..42bf290 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLoggerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLoggerTest.java
@@ -16,7 +16,9 @@
 
 package com.android.systemui.statusbar;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -25,8 +27,8 @@
 import android.app.Notification;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.RemoteException;
 import android.os.UserHandle;
-import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -35,7 +37,6 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.UiOffloadThread;
 
 import com.google.android.collect.Lists;
 
@@ -45,10 +46,13 @@
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class NotificationLoggerTest extends SysuiTestCase {
     private static final String TEST_PACKAGE_NAME = "test";
     private static final int TEST_UID = 0;
@@ -66,9 +70,10 @@
     private NotificationData.Entry mEntry;
     private StatusBarNotification mSbn;
     private TestableNotificationLogger mLogger;
+    private ConcurrentLinkedQueue<AssertionError> mErrorQueue = new ConcurrentLinkedQueue<>();
 
     @Before
-    public void setUp() {
+    public void setUp() throws RemoteException {
         MockitoAnnotations.initMocks(this);
         mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
         mDependency.injectTestDependency(NotificationListener.class, mListener);
@@ -86,22 +91,38 @@
 
     @Test
     public void testOnChildLocationsChangedReportsVisibilityChanged() throws Exception {
-        when(mListContainer.isInVisibleLocation(any())).thenReturn(true);
-        when(mNotificationData.getActiveNotifications()).thenReturn(Lists.newArrayList(mEntry));
-        mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged();
-        waitForIdleSync(mLogger.getHandlerForTest());
-        waitForUiOffloadThread();
-
         NotificationVisibility[] newlyVisibleKeys = {
                 NotificationVisibility.obtain(mEntry.key, 0, 1, true)
         };
         NotificationVisibility[] noLongerVisibleKeys = {};
-        verify(mBarService).onNotificationVisibilityChanged(newlyVisibleKeys, noLongerVisibleKeys);
+        doAnswer((Answer) invocation -> {
+                    try {
+                        assertArrayEquals(newlyVisibleKeys,
+                                (NotificationVisibility[]) invocation.getArguments()[0]);
+                        assertArrayEquals(noLongerVisibleKeys,
+                                (NotificationVisibility[]) invocation.getArguments()[1]);
+                    } catch (AssertionError error) {
+                        mErrorQueue.offer(error);
+                    }
+                    return null;
+                }
+        ).when(mBarService).onNotificationVisibilityChanged(any(NotificationVisibility[].class),
+                any(NotificationVisibility[].class));
+
+        when(mListContainer.isInVisibleLocation(any())).thenReturn(true);
+        when(mNotificationData.getActiveNotifications()).thenReturn(Lists.newArrayList(mEntry));
+        mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged();
+        TestableLooper.get(this).processAllMessages();
+        waitForUiOffloadThread();
+
+        if(!mErrorQueue.isEmpty()) {
+            throw mErrorQueue.poll();
+        }
 
         // |mEntry| won't change visibility, so it shouldn't be reported again:
         Mockito.reset(mBarService);
         mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged();
-        waitForIdleSync(mLogger.getHandlerForTest());
+        TestableLooper.get(this).processAllMessages();
         waitForUiOffloadThread();
 
         verify(mBarService, never()).onNotificationVisibilityChanged(any(), any());
@@ -113,7 +134,7 @@
         when(mListContainer.isInVisibleLocation(any())).thenReturn(true);
         when(mNotificationData.getActiveNotifications()).thenReturn(Lists.newArrayList(mEntry));
         mLogger.getChildLocationsChangedListenerForTest().onChildLocationsChanged();
-        waitForIdleSync(mLogger.getHandlerForTest());
+        TestableLooper.get(this).processAllMessages();
         waitForUiOffloadThread();
         Mockito.reset(mBarService);
 
@@ -128,8 +149,8 @@
 
         public TestableNotificationLogger(IStatusBarService barService) {
             mBarService = barService;
-            // Make this on the main thread so we can wait for it during tests.
-            mHandler = new Handler(Looper.getMainLooper());
+            // Make this on the current thread so we can wait for it during tests.
+            mHandler = Handler.createAsync(Looper.myLooper());
         }
 
         public OnChildLocationsChangedListener
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
index 4829cb2..7a2cb3a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
@@ -45,7 +45,6 @@
     @Mock private NotificationEntryManager mEntryManager;
     @Mock private NotificationLockscreenUserManager mLockscreenUserManager;
 
-    private Handler mHandler;
     private TestableNotificationRemoteInputManager mRemoteInputManager;
     private StatusBarNotification mSbn;
     private NotificationData.Entry mEntry;
@@ -56,9 +55,8 @@
         mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
         mDependency.injectTestDependency(NotificationLockscreenUserManager.class,
                 mLockscreenUserManager);
-        mHandler = new Handler(Looper.getMainLooper());
 
-        when(mPresenter.getHandler()).thenReturn(mHandler);
+        when(mPresenter.getHandler()).thenReturn(Handler.createAsync(Looper.myLooper()));
         when(mEntryManager.getLatestRankingMap()).thenReturn(mRanking);
 
         mRemoteInputManager = new TestableNotificationRemoteInputManager(mContext);
@@ -88,11 +86,9 @@
     @Test
     public void testPerformOnRemoveNotification() {
         when(mController.isRemoteInputActive(mEntry)).thenReturn(true);
-        mRemoteInputManager.getKeysKeptForRemoteInput().add(mEntry.key);
         mRemoteInputManager.onPerformRemoveNotification(mSbn, mEntry);
 
         verify(mController).removeRemoteInput(mEntry, null);
-        assertTrue(mRemoteInputManager.getKeysKeptForRemoteInput().isEmpty());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index de2e6bf..2b0c6bf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -143,12 +143,10 @@
             throws Exception {
         LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
                 mContext.LAYOUT_INFLATER_SERVICE);
-        mInstrumentation.runOnMainSync(() ->
-                mRow = (ExpandableNotificationRow) inflater.inflate(
-                        R.layout.status_bar_notification_row,
-                        null /* root */,
-                        false /* attachToRoot */)
-        );
+        mRow = (ExpandableNotificationRow) inflater.inflate(
+                R.layout.status_bar_notification_row,
+                null /* root */,
+                false /* attachToRoot */);
         ExpandableNotificationRow row = mRow;
         row.setGroupManager(mGroupManager);
         row.setHeadsUpManager(mHeadsUpManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index 76ed452..0d0d1f86 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -50,7 +50,7 @@
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class NotificationViewHierarchyManagerTest extends SysuiTestCase {
     @Mock private NotificationPresenter mPresenter;
     @Mock private NotificationData mNotificationData;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
index 84dceae..e91530d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
@@ -14,6 +14,8 @@
 
 package com.android.systemui.statusbar;
 
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
@@ -74,7 +76,7 @@
     }
 
     @Test
-    public void testSendSmartReply_updatesRemoteInput() throws RemoteException {
+    public void testSendSmartReply_updatesRemoteInput() {
         StatusBarNotification sbn = mock(StatusBarNotification.class);
         when(sbn.getKey()).thenReturn(TEST_NOTIFICATION_KEY);
         when(mNotificationEntryManager.rebuildNotificationWithRemoteInput(
@@ -118,4 +120,21 @@
         verify(mIStatusBarService).onNotificationSmartRepliesAdded(TEST_NOTIFICATION_KEY,
                 TEST_CHOICE_COUNT);
     }
+
+    @Test
+    public void testSendSmartReply_reportsSending() {
+        SmartReplyController controller = new SmartReplyController();
+        controller.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT);
+
+        assertTrue(controller.isSendingSmartReply(TEST_NOTIFICATION_KEY));
+    }
+
+    @Test
+    public void testSendingSmartReply_afterRemove_shouldReturnFalse() {
+        SmartReplyController controller = new SmartReplyController();
+        controller.isSendingSmartReply(TEST_NOTIFICATION_KEY);
+        controller.stopSending(mEntry);
+
+        assertFalse(controller.isSendingSmartReply(TEST_NOTIFICATION_KEY));
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java
index 1ee9b32..00e9995 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java
@@ -21,6 +21,8 @@
 
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
 import android.widget.FrameLayout;
 
 import com.android.systemui.SysuiTestCase;
@@ -33,7 +35,8 @@
 import org.junit.runner.RunWith;
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
 public class AboveShelfObserverTest extends SysuiTestCase {
 
     private AboveShelfObserver mObserver;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java
index 83a2883..aa8a08c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java
@@ -18,6 +18,7 @@
 
 import static com.android.systemui.statusbar.notification.NotificationInflater.FLAG_REINFLATE_ALL;
 
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -28,10 +29,9 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.service.notification.StatusBarNotification;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.FlakyTest;
 import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.RemoteViews;
@@ -52,9 +52,11 @@
 import java.util.HashMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
 public class NotificationInflaterTest extends SysuiTestCase {
 
     private NotificationInflater mNotificationInflater;
@@ -85,7 +87,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testIncreasedHeadsUpBeingUsed() {
         mNotificationInflater.setUsesIncreasedHeadsUpHeight(true);
         Notification.Builder builder = spy(mBuilder);
@@ -94,7 +95,6 @@
     }
 
     @Test
-    @UiThreadTest
     public void testIncreasedHeightBeingUsed() {
         mNotificationInflater.setUsesIncreasedHeight(true);
         Notification.Builder builder = spy(mBuilder);
@@ -115,8 +115,8 @@
         mRow.getEntry().cachedBigContentView = null;
         runThenWaitForInflation(() -> mNotificationInflater.inflateNotificationViews(
                 NotificationInflater.FLAG_REINFLATE_EXPANDED_VIEW), mNotificationInflater);
-        Assert.assertTrue(mRow.getPrivateLayout().getChildCount() == 1);
-        Assert.assertTrue(mRow.getPrivateLayout().getChildAt(0)
+        assertTrue(mRow.getPrivateLayout().getChildCount() == 1);
+        assertTrue(mRow.getPrivateLayout().getChildAt(0)
                 == mRow.getPrivateLayout().getExpandedChild());
         verify(mRow).onNotificationUpdated();
     }
@@ -128,7 +128,7 @@
                 = new RemoteViews(mContext.getPackageName(), R.layout.status_bar);
         runThenWaitForInflation(() -> mNotificationInflater.inflateNotificationViews(),
                 true /* expectingException */, mNotificationInflater);
-        Assert.assertTrue(mRow.getPrivateLayout().getChildCount() == 0);
+        assertTrue(mRow.getPrivateLayout().getChildCount() == 0);
         verify(mRow, times(0)).onNotificationUpdated();
     }
 
@@ -181,12 +181,11 @@
                                 R.layout.custom_view_dark);
                     }
                 });
-        countDownLatch.await();
+        assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS));
     }
 
     /* Cancelling requires us to be on the UI thread otherwise we might have a race */
     @Test
-    @UiThreadTest
     public void testSupersedesExistingTask() throws Exception {
         mNotificationInflater.inflateNotificationViews();
         mNotificationInflater.setIsLowPriority(true);
@@ -219,7 +218,6 @@
 
     private static void runThenWaitForInflation(Runnable block, boolean expectingException,
             NotificationInflater inflater) throws Exception {
-        com.android.systemui.util.Assert.isNotMainThread();
         CountDownLatch countDownLatch = new CountDownLatch(1);
         final ExceptionHolder exceptionHolder = new ExceptionHolder();
         inflater.setInflationCallback(new NotificationInflater.InflationCallback() {
@@ -240,9 +238,14 @@
                 }
                 countDownLatch.countDown();
             }
+
+            @Override
+            public boolean doInflateSynchronous() {
+                return true;
+            }
         });
         block.run();
-        countDownLatch.await();
+        assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS));
         if (exceptionHolder.mException != null) {
             throw exceptionHolder.mException;
         }
@@ -257,7 +260,7 @@
     }
 
     private class AsyncFailRemoteView extends RemoteViews {
-        Handler mHandler = new Handler(Looper.getMainLooper());
+        Handler mHandler = Handler.createAsync(Looper.getMainLooper());
 
         public AsyncFailRemoteView(String packageName, int layoutId) {
             super(packageName, layoutId);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java
index 9da28a0..7e2e505 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java
@@ -20,6 +20,8 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
 import android.view.View;
 
 import com.android.systemui.SysuiTestCase;
@@ -30,8 +32,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
 @SmallTest
+@RunWithLooper(setAsMainLooper = true)
 public class NotificationViewWrapperTest extends SysuiTestCase {
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 36fd499..23365a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -51,7 +51,7 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         mAutoTileManager = new AutoTileManager(mContext, mAutoAddTracker, mQsTileHost,
-                new Handler(TestableLooper.get(this).getLooper()));
+                Handler.createAsync(TestableLooper.get(this).getLooper()));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index 7a61bfe..537bfd4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -26,6 +26,8 @@
 
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
 import android.view.View;
 import android.widget.TextView;
 
@@ -47,7 +49,8 @@
 import java.util.HashSet;
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
 public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
 
     private final NotificationStackScrollLayout mStackScroller =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
index 73f05c4..12b14c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
@@ -326,6 +328,14 @@
     }
 
     @Test
+    public void testIsShowingScrimmed() {
+        mBouncer.show(false /* resetSecuritySelection */, true /* animate */);
+        assertThat(mBouncer.isShowingScrimmed()).isTrue();
+        mBouncer.show(false /* resetSecuritySelection */, false /* animate */);
+        assertThat(mBouncer.isShowingScrimmed()).isFalse();
+    }
+
+    @Test
     public void testWillDismissWithAction() {
         mBouncer.ensureView();
         Assert.assertFalse("Action not set yet", mBouncer.willDismissWithAction());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
new file mode 100644
index 0000000..e2e5b32
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -0,0 +1,183 @@
+/*
+ * 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 static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.ViewGroup;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardHostView;
+import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
+
+    @Mock
+    private ViewMediatorCallback mViewMediatorCallback;
+    @Mock
+    private LockPatternUtils mLockPatternUtils;
+    @Mock
+    private KeyguardBouncer mBouncer;
+    @Mock
+    private StatusBar mStatusBar;
+    @Mock
+    private ViewGroup mContainer;
+    @Mock
+    private NotificationPanelView mNotificationPanelView;
+    @Mock
+    private FingerprintUnlockController mFingerprintUnlockController;
+    @Mock
+    private DismissCallbackRegistry mDismissCallbackRegistry;
+    private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mDependency.injectMockDependency(StatusBarWindowManager.class);
+        mStatusBarKeyguardViewManager = new TestableStatusBarKeyguardViewManager(getContext(),
+                mViewMediatorCallback, mLockPatternUtils);
+        mStatusBarKeyguardViewManager.registerStatusBar(mStatusBar, mContainer,
+                mNotificationPanelView, mFingerprintUnlockController, mDismissCallbackRegistry);
+        mStatusBarKeyguardViewManager.show(null);
+    }
+
+    @Test
+    public void dismissWithAction_AfterKeyguardGoneSetToFalse() {
+        KeyguardHostView.OnDismissAction action = () -> false;
+        Runnable cancelAction = () -> {};
+        mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
+                false /* afterKeyguardGone */);
+        verify(mBouncer).showWithDismissAction(eq(action), eq(cancelAction));
+    }
+
+    @Test
+    public void showBouncer_onlyWhenShowing() {
+        mStatusBarKeyguardViewManager.hide(0 /* startTime */, 0 /* fadeoutDuration */);
+        mStatusBar.showBouncer(true /* scrimmed */);
+        verify(mBouncer, never()).show(anyBoolean(), anyBoolean());
+        verify(mBouncer, never()).show(anyBoolean());
+    }
+
+    @Test
+    public void showBouncer_notWhenBouncerAlreadyShowing() {
+        mStatusBarKeyguardViewManager.hide(0 /* startTime */, 0 /* fadeoutDuration */);
+        when(mBouncer.isSecure()).thenReturn(true);
+        mStatusBar.showBouncer(true /* scrimmed */);
+        verify(mBouncer, never()).show(anyBoolean(), anyBoolean());
+        verify(mBouncer, never()).show(anyBoolean());
+    }
+
+    @Test
+    public void showBouncer_showsTheBouncer() {
+        mStatusBarKeyguardViewManager.showBouncer(true /* scrimmed */);
+        verify(mBouncer).show(anyBoolean(), eq(true));
+    }
+
+    @Test
+    public void onPanelExpansionChanged_neverHidesFullscreenBouncer() {
+        // TODO: StatusBar should not be here, mBouncer.isFullscreenBouncer() should do the same.
+        when(mStatusBar.isFullScreenUserSwitcherState()).thenReturn(true);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */,
+                true /* tracking */);
+        verify(mBouncer).setExpansion(eq(KeyguardBouncer.EXPANSION_VISIBLE));
+    }
+
+    @Test
+    public void onPanelExpansionChanged_neverHidesScrimmedBouncer() {
+        when(mBouncer.isShowingScrimmed()).thenReturn(true);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */,
+                true /* tracking */);
+        verify(mBouncer).setExpansion(eq(KeyguardBouncer.EXPANSION_VISIBLE));
+    }
+
+    @Test
+    public void onPanelExpansionChanged_neverShowsDuringHintAnimation() {
+        when(mNotificationPanelView.isUnlockHintRunning()).thenReturn(true);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */,
+                true /* tracking */);
+        verify(mBouncer).setExpansion(eq(KeyguardBouncer.EXPANSION_HIDDEN));
+    }
+
+    @Test
+    public void onPanelExpansionChanged_propagatesToBouncer() {
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */,
+                true /* tracking */);
+        verify(mBouncer).setExpansion(eq(0.5f));
+    }
+
+    @Test
+    public void onPanelExpansionChanged_showsBouncerWhenSwiping() {
+        when(mStatusBar.isKeyguardCurrentlySecure()).thenReturn(true);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */,
+                true /* tracking */);
+        verify(mBouncer).show(eq(false), eq(false));
+
+        // But not when it's already visible
+        reset(mBouncer);
+        when(mBouncer.isShowing()).thenReturn(true);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */, true /* tracking */);
+        verify(mBouncer, never()).show(eq(false), eq(false));
+
+        // Or animating away
+        reset(mBouncer);
+        when(mBouncer.isAnimatingAway()).thenReturn(true);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */, true /* tracking */);
+        verify(mBouncer, never()).show(eq(false), eq(false));
+    }
+
+    private class TestableStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager {
+
+        public TestableStatusBarKeyguardViewManager(Context context,
+                ViewMediatorCallback callback,
+                LockPatternUtils lockPatternUtils) {
+            super(context, callback, lockPatternUtils);
+        }
+
+        @Override
+        public void registerStatusBar(StatusBar statusBar, ViewGroup container,
+                NotificationPanelView notificationPanelView,
+                FingerprintUnlockController fingerprintUnlockController,
+                DismissCallbackRegistry dismissCallbackRegistry) {
+            super.registerStatusBar(statusBar, container, notificationPanelView,
+                    fingerprintUnlockController, dismissCallbackRegistry);
+            mBouncer = StatusBarKeyguardViewManagerTest.this.mBouncer;
+        }
+    }
+}
\ No newline at end of file
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 37e0005..0a412b9 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
@@ -48,6 +48,7 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IPowerManager;
+import android.os.Looper;
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -173,10 +174,8 @@
         mNotificationLogger = new NotificationLogger();
 
         IPowerManager powerManagerService = mock(IPowerManager.class);
-        HandlerThread handlerThread = new HandlerThread("TestThread");
-        handlerThread.start();
         mPowerManager = new PowerManager(mContext, powerManagerService,
-                new Handler(handlerThread.getLooper()));
+                Handler.createAsync(Looper.myLooper()));
 
         CommandQueue commandQueue = mock(CommandQueue.class);
         when(commandQueue.asBinder()).thenReturn(new Binder());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 714ad1f..35f0dba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -17,20 +17,25 @@
 package com.android.systemui.statusbar.policy;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isA;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.content.Intent;
 import android.net.ConnectivityManager;
+import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.wifi.WifiManager;
+import android.os.Handler;
 import android.provider.Settings;
 import android.provider.Settings.Global;
 import android.telephony.PhoneStateListener;
@@ -90,6 +95,7 @@
     protected int mSubId;
 
     private NetworkCapabilities mNetCapabilities;
+    private ConnectivityManager.NetworkCallback mNetworkCallback;
 
     @Rule
     public TestWatcher failWatcher = new TestWatcher() {
@@ -154,6 +160,13 @@
         setSubscriptions(mSubId);
         mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
         mPhoneStateListener = mMobileSignalController.mPhoneStateListener;
+
+        ArgumentCaptor<ConnectivityManager.NetworkCallback> callbackArg =
+            ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
+        Mockito.verify(mMockCm, atLeastOnce())
+            .registerDefaultNetworkCallback(callbackArg.capture(), isA(Handler.class));
+        mNetworkCallback = callbackArg.getValue();
+        assertNotNull(mNetworkCallback);
     }
 
     protected void setDefaultSubId(int subId) {
@@ -195,24 +208,37 @@
         setLevel(DEFAULT_LEVEL);
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
                 TelephonyManager.NETWORK_TYPE_UMTS);
-        setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, true, true);
+        setConnectivityViaBroadcast(
+            NetworkCapabilities.TRANSPORT_CELLULAR, true, true);
     }
 
-    public void setConnectivity(int networkType, boolean inetCondition, boolean isConnected) {
+    public void setConnectivityViaBroadcast(
+        int networkType, boolean validated, boolean isConnected) {
+        setConnectivityCommon(networkType, validated, isConnected);
         Intent i = new Intent(ConnectivityManager.INET_CONDITION_ACTION);
+        mNetworkController.onReceive(mContext, i);
+    }
+
+    public void setConnectivityViaCallback(
+        int networkType, boolean validated, boolean isConnected){
+        setConnectivityCommon(networkType, validated, isConnected);
+        mNetworkCallback.onCapabilitiesChanged(
+            mock(Network.class), new NetworkCapabilities(mNetCapabilities));
+    }
+
+    private void setConnectivityCommon(
+        int networkType, boolean validated, boolean isConnected){
         // TODO: Separate out into several NetworkCapabilities.
         if (isConnected) {
             mNetCapabilities.addTransportType(networkType);
         } else {
             mNetCapabilities.removeTransportType(networkType);
         }
-        if (inetCondition) {
+        if (validated) {
             mNetCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
         } else {
             mNetCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
         }
-
-        mNetworkController.onReceive(mContext, i);
     }
 
     public void setGsmRoaming(boolean isRoaming) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 365a9b2..d42940a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -118,7 +118,7 @@
         when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0);
-        setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
+        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
 
         // Verify that a SignalDrawable with a cut out is used to display data disabled.
         verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, 0,
@@ -132,7 +132,7 @@
         when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
-        setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
+        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
 
         // Verify that a SignalDrawable with a cut out is used to display data disabled.
         verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, 0,
@@ -146,7 +146,7 @@
         when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
-        setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
+        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
         when(mMockProvisionController.isUserSetup(anyInt())).thenReturn(false);
         mUserCallback.onUserSetupChanged();
         TestableLooper.get(this).processAllMessages();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java
index d2d7347..eefdeee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java
@@ -38,7 +38,7 @@
     }
 
     protected void setEthernetState(boolean connected, boolean validated) {
-        setConnectivity(NetworkCapabilities.TRANSPORT_ETHERNET, validated, connected);
+        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_ETHERNET, validated, connected);
     }
 
     protected void verifyLastEthernetIcon(boolean visible, int icon) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 33aa417..c24336d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -143,7 +143,7 @@
                     testStrength, DEFAULT_ICON);
 
             // Verify low inet number indexing.
-            setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, true);
+            setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, true);
             verifyLastMobileDataIndicators(true,
                     testStrength, DEFAULT_ICON, false, false);
         }
@@ -230,8 +230,8 @@
     @Test
     public void testNoBangWithWifi() {
         setupDefaultSignal();
-        setConnectivity(mMobileSignalController.mTransportType, false, false);
-        setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+        setConnectivityViaBroadcast(mMobileSignalController.mTransportType, false, false);
+        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
 
         verifyLastMobileDataIndicators(true, DEFAULT_LEVEL, 0);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
index 6591715..dff0665 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -18,9 +18,9 @@
 
 import static junit.framework.Assert.assertEquals;
 
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 @SmallTest
@@ -44,9 +44,9 @@
         for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
             setWifiLevel(testLevel);
 
-            setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+            setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
             verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
-            setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, false, true);
+            setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, false, true);
             verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[0][testLevel]);
         }
     }
@@ -65,10 +65,10 @@
         for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
             setWifiLevel(testLevel);
 
-            setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+            setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
             verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[1][testLevel],
                     testSsid);
-            setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, false, true);
+            setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, false, true);
             verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[0][testLevel],
                     testSsid);
         }
@@ -82,7 +82,7 @@
         setWifiEnabled(true);
         setWifiState(true, testSsid);
         setWifiLevel(testLevel);
-        setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
         verifyLastQsWifiIcon(true, true,
                 WifiIcons.QS_WIFI_SIGNAL_STRENGTH[1][testLevel], testSsid);
 
@@ -107,19 +107,68 @@
         setWifiEnabled(true);
         setWifiState(true, testSsid);
         setWifiLevel(testLevel);
-        setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
         verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
 
         setupDefaultSignal();
         setGsmRoaming(true);
         // Still be on wifi though.
-        setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true);
-        setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
+        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
         verifyLastMobileDataIndicators(true,
                 DEFAULT_LEVEL,
                 0, true);
     }
 
+    @Test
+    public void testWifiIconInvalidatedViaCallback() {
+        // Setup normal connection
+        String testSsid = "Test SSID";
+        int testLevel = 2;
+        setWifiEnabled(true);
+        setWifiState(true, testSsid);
+        setWifiLevel(testLevel);
+        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+        verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
+
+        setConnectivityViaCallback(NetworkCapabilities.TRANSPORT_WIFI, false, true);
+        verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[0][testLevel]);
+    }
+
+    @Test
+    public void testWifiIconDisconnectedViaCallback(){
+        // Setup normal connection
+        String testSsid = "Test SSID";
+        int testLevel = 2;
+        setWifiEnabled(true);
+        setWifiState(true, testSsid);
+        setWifiLevel(testLevel);
+        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+        verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
+
+        setWifiState(false, testSsid);
+        setConnectivityViaCallback(NetworkCapabilities.TRANSPORT_WIFI, false, false);
+        verifyLastWifiIcon(false, WifiIcons.WIFI_NO_NETWORK);
+    }
+
+    @Test
+    public void testVpnWithUnderlyingWifi(){
+        String testSsid = "Test SSID";
+        int testLevel = 2;
+        setWifiEnabled(true);
+        verifyLastWifiIcon(false, WifiIcons.WIFI_NO_NETWORK);
+
+        setConnectivityViaCallback(NetworkCapabilities.TRANSPORT_VPN, false, true);
+        setConnectivityViaCallback(NetworkCapabilities.TRANSPORT_VPN, true, true);
+        verifyLastWifiIcon(false, WifiIcons.WIFI_NO_NETWORK);
+
+        // Mock calling setUnderlyingNetworks.
+        setWifiState(true, testSsid);
+        setWifiLevel(testLevel);
+        setConnectivityViaCallback(NetworkCapabilities.TRANSPORT_WIFI, true, true);
+        verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
+    }
+
     protected void setWifiActivity(int activity) {
         // TODO: Not this, because this variable probably isn't sticking around.
         mNetworkController.mWifiSignalController.setActivity(activity);
@@ -143,10 +192,10 @@
 
     protected void setWifiState(boolean connected, String ssid) {
         Intent i = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        NetworkInfo networkInfo = Mockito.mock(NetworkInfo.class);
+        NetworkInfo networkInfo = mock(NetworkInfo.class);
         when(networkInfo.isConnected()).thenReturn(connected);
 
-        WifiInfo wifiInfo = Mockito.mock(WifiInfo.class);
+        WifiInfo wifiInfo = mock(WifiInfo.class);
         when(wifiInfo.getSSID()).thenReturn(ssid);
         when(mMockWm.getConnectionInfo()).thenReturn(wifiInfo);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
index 7e1aba5..938dfca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ShortcutManager;
+import android.os.Handler;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -28,6 +29,7 @@
 import android.widget.EditText;
 import android.widget.ImageButton;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -42,7 +44,7 @@
 import org.mockito.MockitoAnnotations;
 
 @RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class RemoteInputViewTest extends SysuiTestCase {
 
@@ -60,7 +62,8 @@
         MockitoAnnotations.initMocks(this);
 
         mReceiver = new BlockingQueueIntentReceiver();
-        mContext.registerReceiver(mReceiver, new IntentFilter(TEST_ACTION));
+        mContext.registerReceiver(mReceiver, new IntentFilter(TEST_ACTION), null,
+                Handler.createAsync(Dependency.get(Dependency.BG_LOOPER)));
 
         // Avoid SecurityException RemoteInputView#sendRemoteInput().
         mContext.addMockSystemService(ShortcutManager.class, mShortcutManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
index aca7c9c..2266b47 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
@@ -51,7 +51,7 @@
         resources.addOverride(R.bool.config_smart_replies_in_notifications_enabled, true);
         resources.addOverride(
                 R.integer.config_smart_replies_in_notifications_max_squeeze_remeasure_attempts, 7);
-        mConstants = new SmartReplyConstants(new Handler(Looper.getMainLooper()), mContext);
+        mConstants = new SmartReplyConstants(Handler.createAsync(Looper.myLooper()), mContext);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
index ff65587..7437e834 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
@@ -24,6 +24,7 @@
 
 import android.app.NotificationManager;
 import android.os.Handler;
+import android.os.Looper;
 import android.provider.Settings;
 import android.service.notification.ZenModeConfig;
 import android.support.test.filters.SmallTest;
@@ -58,7 +59,7 @@
         mContext.addMockSystemService(NotificationManager.class, mNm);
         when(mNm.getZenModeConfig()).thenReturn(mConfig);
 
-        mController = new ZenModeControllerImpl(mContext, new Handler());
+        mController = new ZenModeControllerImpl(mContext, Handler.createAsync(Looper.myLooper()));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
index 5ac965c..8a74019 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
@@ -18,6 +18,8 @@
 
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
 import android.view.NotificationHeaderView;
 import android.view.View;
 
@@ -31,7 +33,8 @@
 import org.junit.runner.RunWith;
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
 public class NotificationChildrenContainerTest extends SysuiTestCase {
 
     private ExpandableNotificationRow mGroup;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationRoundnessManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationRoundnessManagerTest.java
index 28d1aff..16e69f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationRoundnessManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationRoundnessManagerTest.java
@@ -16,29 +16,18 @@
 
 package com.android.systemui.statusbar.stack;
 
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyFloat;
-import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
 
-import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
 import android.view.View;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.NotificationTestHelper;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.phone.ScrimController;
-import com.android.systemui.statusbar.phone.StatusBar;
 
 import org.junit.Assert;
 import org.junit.Before;
@@ -46,10 +35,10 @@
 import org.junit.runner.RunWith;
 
 import java.util.HashSet;
-import java.util.function.Consumer;
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
 public class NotificationRoundnessManagerTest extends SysuiTestCase {
 
     private NotificationRoundnessManager mRoundnessManager = new NotificationRoundnessManager();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
index eeb4209..5400e3b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
@@ -18,6 +18,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
@@ -28,12 +29,10 @@
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
-import android.view.View;
 
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.TestableDependency;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.FooterView;
 import com.android.systemui.statusbar.NotificationBlockingHelperManager;
@@ -169,12 +168,11 @@
         FooterView view = mock(FooterView.class);
         mStackScroller.setFooterView(view);
         when(view.willBeGone()).thenReturn(true);
-        when(view.isSecondaryVisible()).thenReturn(true);
 
         mStackScroller.updateFooterView(true, false);
 
-        verify(view).setVisibility(View.VISIBLE);
-        verify(view).performSecondaryVisibilityAnimation(false);
+        verify(view).setVisible(eq(true), anyBoolean());
+        verify(view).setSecondaryVisible(eq(false), anyBoolean());
     }
 
     @Test
@@ -182,11 +180,10 @@
         FooterView view = mock(FooterView.class);
         mStackScroller.setFooterView(view);
         when(view.willBeGone()).thenReturn(true);
-        when(view.isSecondaryVisible()).thenReturn(false);
 
         mStackScroller.updateFooterView(true, true);
 
-        verify(view).setVisibility(View.VISIBLE);
-        verify(view).performSecondaryVisibilityAnimation(true);
+        verify(view).setVisible(eq(true), anyBoolean());
+        verify(view).setSecondaryVisible(eq(true), anyBoolean());
     }
 }
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index c22dac8..686ab53 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -5969,6 +5969,17 @@
     // OS: P
     FIELD_BATTERY_CHARGE_CYCLES = 1439;
 
+    // ACTION: Hush gesture - volume up + power button
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: P
+    ACTION_HUSH_GESTURE = 1440;
+
+    // OPEN: Settings -> Developer Options -> Disable Bluetooth A2DP hardware
+    // offload
+    // CATEGORY: SETTINGS
+    // OS: P
+    DIALOG_BLUETOOTH_DISABLE_A2DP_HW_OFFLOAD = 1441;
+
     // ---- End P Constants, all P constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index 8fa6b3e..9ff8e7d 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -450,6 +450,9 @@
 
   // Number of radio mode changes to DBS (Dual band simultaneous).
   optional int32 num_radio_mode_change_to_dbs = 115;
+
+  // Number of times the firmware picked a SoftAp channel not satisfying user band preference.
+  optional int32 num_soft_ap_user_band_preference_unsatisfied = 116;
 }
 
 // Information that gets logged for every WiFi connection.
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index 1aeb3b9..8119054 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -228,8 +228,8 @@
                 mWindow = null;
                 return;
             }
-            decor.setFocusable(true);
-            decor.setOnClickListener(v -> mCallback.onResponsePicked(response));
+            container.setFocusable(true);
+            container.setOnClickListener(v -> mCallback.onResponsePicked(response));
 
             if (!mFullScreen) {
                 final Point maxSize = mTempPoint;
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 4c914c2..3beebcb 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -95,11 +95,12 @@
 import java.util.List;
 import java.util.Map;
 
+import static android.app.AppOpsManager._NUM_UID_STATE;
 import static android.app.AppOpsManager.UID_STATE_BACKGROUND;
 import static android.app.AppOpsManager.UID_STATE_CACHED;
 import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
 import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
-import static android.app.AppOpsManager._NUM_UID_STATE;
+import static android.app.AppOpsManager.UID_STATE_LAST_NON_RESTRICTED;
 import static android.app.AppOpsManager.UID_STATE_PERSISTENT;
 import static android.app.AppOpsManager.UID_STATE_TOP;
 
@@ -213,15 +214,31 @@
      */
     private final class Constants extends ContentObserver {
         // Key names stored in the settings value.
-        private static final String KEY_STATE_SETTLE_TIME = "state_settle_time";
+        private static final String KEY_TOP_STATE_SETTLE_TIME = "top_state_settle_time";
+        private static final String KEY_FG_SERVICE_STATE_SETTLE_TIME
+                = "fg_service_state_settle_time";
+        private static final String KEY_BG_STATE_SETTLE_TIME = "bg_state_settle_time";
 
         /**
-         * How long we want for a drop in uid state to settle before applying it.
+         * How long we want for a drop in uid state from top to settle before applying it.
          * @see Settings.Global#APP_OPS_CONSTANTS
-         * @see #KEY_STATE_SETTLE_TIME
+         * @see #KEY_TOP_STATE_SETTLE_TIME
          */
-        public long STATE_SETTLE_TIME;
+        public long TOP_STATE_SETTLE_TIME;
 
+        /**
+         * How long we want for a drop in uid state from foreground to settle before applying it.
+         * @see Settings.Global#APP_OPS_CONSTANTS
+         * @see #KEY_FG_SERVICE_STATE_SETTLE_TIME
+         */
+        public long FG_SERVICE_STATE_SETTLE_TIME;
+
+        /**
+         * How long we want for a drop in uid state from background to settle before applying it.
+         * @see Settings.Global#APP_OPS_CONSTANTS
+         * @see #KEY_BG_STATE_SETTLE_TIME
+         */
+        public long BG_STATE_SETTLE_TIME;
 
         private final KeyValueListParser mParser = new KeyValueListParser(',');
         private ContentResolver mResolver;
@@ -256,16 +273,26 @@
                     // with defaults.
                     Slog.e(TAG, "Bad app ops settings", e);
                 }
-                STATE_SETTLE_TIME = mParser.getDurationMillis(
-                        KEY_STATE_SETTLE_TIME, 10 * 1000L);
+                TOP_STATE_SETTLE_TIME = mParser.getDurationMillis(
+                        KEY_TOP_STATE_SETTLE_TIME, 30 * 1000L);
+                FG_SERVICE_STATE_SETTLE_TIME = mParser.getDurationMillis(
+                        KEY_FG_SERVICE_STATE_SETTLE_TIME, 10 * 1000L);
+                BG_STATE_SETTLE_TIME = mParser.getDurationMillis(
+                        KEY_BG_STATE_SETTLE_TIME, 1 * 1000L);
             }
         }
 
         void dump(PrintWriter pw) {
             pw.println("  Settings:");
 
-            pw.print("    "); pw.print(KEY_STATE_SETTLE_TIME); pw.print("=");
-            TimeUtils.formatDuration(STATE_SETTLE_TIME, pw);
+            pw.print("    "); pw.print(KEY_TOP_STATE_SETTLE_TIME); pw.print("=");
+            TimeUtils.formatDuration(TOP_STATE_SETTLE_TIME, pw);
+            pw.println();
+            pw.print("    "); pw.print(KEY_FG_SERVICE_STATE_SETTLE_TIME); pw.print("=");
+            TimeUtils.formatDuration(FG_SERVICE_STATE_SETTLE_TIME, pw);
+            pw.println();
+            pw.print("    "); pw.print(KEY_BG_STATE_SETTLE_TIME); pw.print("=");
+            TimeUtils.formatDuration(BG_STATE_SETTLE_TIME, pw);
             pw.println();
         }
     }
@@ -304,7 +331,7 @@
 
         int evalMode(int mode) {
             if (mode == AppOpsManager.MODE_FOREGROUND) {
-                return state <= UID_STATE_FOREGROUND_SERVICE
+                return state <= UID_STATE_LAST_NON_RESTRICTED
                         ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
             }
             return mode;
@@ -728,14 +755,22 @@
             if (uidState != null && uidState.pendingState != newState) {
                 final int oldPendingState = uidState.pendingState;
                 uidState.pendingState = newState;
-                if (newState < uidState.state) {
-                    // We are moving to a more important state, always do it immediately.
+                if (newState < uidState.state || newState <= UID_STATE_LAST_NON_RESTRICTED) {
+                    // We are moving to a more important state, or the new state is in the
+                    // foreground, then always do it immediately.
                     commitUidPendingStateLocked(uidState);
                 } else if (uidState.pendingStateCommitTime == 0) {
                     // We are moving to a less important state for the first time,
                     // delay the application for a bit.
-                    uidState.pendingStateCommitTime = SystemClock.uptimeMillis() +
-                            mConstants.STATE_SETTLE_TIME;
+                    final long settleTime;
+                    if (uidState.state <= UID_STATE_TOP) {
+                        settleTime = mConstants.TOP_STATE_SETTLE_TIME;
+                    } else if (uidState.state <= UID_STATE_FOREGROUND_SERVICE) {
+                        settleTime = mConstants.FG_SERVICE_STATE_SETTLE_TIME;
+                    } else {
+                        settleTime = mConstants.BG_STATE_SETTLE_TIME;
+                    }
+                    uidState.pendingStateCommitTime = SystemClock.uptimeMillis() + settleTime;
                 }
                 if (uidState.startNesting != 0) {
                     // There is some actively running operation...  need to find it
@@ -1858,9 +1893,11 @@
     }
 
     private void commitUidPendingStateLocked(UidState uidState) {
+        final boolean lastForeground = uidState.state <= UID_STATE_LAST_NON_RESTRICTED;
+        final boolean nowForeground = uidState.pendingState <= UID_STATE_LAST_NON_RESTRICTED;
         uidState.state = uidState.pendingState;
         uidState.pendingStateCommitTime = 0;
-        if (uidState.hasForegroundWatchers) {
+        if (uidState.hasForegroundWatchers && lastForeground != nowForeground) {
             for (int fgi = uidState.foregroundOps.size() - 1; fgi >= 0; fgi--) {
                 if (!uidState.foregroundOps.valueAt(fgi)) {
                     continue;
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index b32ece7..4c2a940 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -64,6 +64,7 @@
 import com.android.internal.util.FastPrintWriter;
 import com.android.server.AppStateTracker;
 import com.android.server.LocalServices;
+import com.android.server.SystemService;
 import com.android.server.am.ActivityManagerService.ItemMatcher;
 import com.android.server.am.ActivityManagerService.NeededUriGrants;
 
@@ -476,12 +477,23 @@
                 Slog.w(TAG, "Background start not allowed: service "
                         + service + " to " + r.name.flattenToShortString()
                         + " from pid=" + callingPid + " uid=" + callingUid
-                        + " pkg=" + callingPackage);
+                        + " pkg=" + callingPackage + " startFg?=" + fgRequired);
                 if (allowed == ActivityManager.APP_START_MODE_DELAYED || forceSilentAbort) {
                     // In this case we are silently disabling the app, to disrupt as
                     // little as possible existing apps.
                     return null;
                 }
+                if (forcedStandby) {
+                    // This is an O+ app, but we might be here because the user has placed
+                    // it under strict background restrictions.  Don't punish the app if it's
+                    // trying to do the right thing but we're denying it for that reason.
+                    if (fgRequired) {
+                        if (DEBUG_BACKGROUND_CHECK) {
+                            Slog.v(TAG, "Silently dropping foreground service launch due to FAS");
+                        }
+                        return null;
+                    }
+                }
                 // This app knows it is in the new model where this operation is not
                 // allowed, so tell it what has happened.
                 UidRecord uidRec = mAm.mActiveUids.get(r.appInfo.uid);
@@ -2001,6 +2013,25 @@
                 + why + " of " + r + " in app " + r.app);
         else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING, ">>> EXECUTING "
                 + why + " of " + r.shortName);
+
+        // For b/34123235: Services within the system server won't start until SystemServer
+        // does Looper.loop(), so we shouldn't try to start/bind to them too early in the boot
+        // process. However, since there's a little point of showing the ANR dialog in that case,
+        // let's suppress the timeout until PHASE_THIRD_PARTY_APPS_CAN_START.
+        //
+        // (Note there are multiple services start at PHASE_THIRD_PARTY_APPS_CAN_START too,
+        // which technically could also trigger this timeout if there's a system server
+        // that takes a long time to handle PHASE_THIRD_PARTY_APPS_CAN_START, but that shouldn't
+        // happen.)
+        boolean timeoutNeeded = true;
+        if ((mAm.mBootPhase < SystemService.PHASE_THIRD_PARTY_APPS_CAN_START)
+                && (r.app != null) && (r.app.pid == android.os.Process.myPid())) {
+
+            Slog.w(TAG, "Too early to start/bind service in system_server: Phase=" + mAm.mBootPhase
+                    + " " + r.getComponentName());
+            timeoutNeeded = false;
+        }
+
         long now = SystemClock.uptimeMillis();
         if (r.executeNesting == 0) {
             r.executeFg = fg;
@@ -2011,13 +2042,15 @@
             if (r.app != null) {
                 r.app.executingServices.add(r);
                 r.app.execServicesFg |= fg;
-                if (r.app.executingServices.size() == 1) {
+                if (timeoutNeeded && r.app.executingServices.size() == 1) {
                     scheduleServiceTimeoutLocked(r.app);
                 }
             }
         } else if (r.app != null && fg && !r.app.execServicesFg) {
             r.app.execServicesFg = true;
-            scheduleServiceTimeoutLocked(r.app);
+            if (timeoutNeeded) {
+                scheduleServiceTimeoutLocked(r.app);
+            }
         }
         r.executeFg |= fg;
         r.executeNesting++;
@@ -3592,6 +3625,21 @@
         }
     }
 
+    public void updateServiceApplicationInfoLocked(ApplicationInfo applicationInfo) {
+        final int userId = UserHandle.getUserId(applicationInfo.uid);
+        ServiceMap serviceMap = mServiceMap.get(userId);
+        if (serviceMap != null) {
+            ArrayMap<ComponentName, ServiceRecord> servicesByName = serviceMap.mServicesByName;
+            for (int j = servicesByName.size() - 1; j >= 0; j--) {
+                ServiceRecord serviceRecord = servicesByName.valueAt(j);
+                if (applicationInfo.packageName.equals(serviceRecord.appInfo.packageName)) {
+                    serviceRecord.appInfo = applicationInfo;
+                    serviceRecord.serviceInfo.applicationInfo = applicationInfo;
+                }
+            }
+        }
+    }
+
     void serviceForegroundCrash(ProcessRecord app, CharSequence serviceRecord) {
         mAm.crashApplication(app.uid, app.pid, app.info.packageName, app.userId,
                 "Context.startForegroundService() did not then call Service.startForeground(): "
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index cddda58..113f452 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1850,6 +1850,11 @@
      */
     boolean mBooted = false;
 
+    /**
+     * Current boot phase.
+     */
+    int mBootPhase;
+
     WindowManagerService mWindowManager;
     final ActivityThread mSystemThread;
 
@@ -2881,6 +2886,7 @@
 
         @Override
         public void onBootPhase(int phase) {
+            mService.mBootPhase = phase;
             if (phase == PHASE_SYSTEM_SERVICES_READY) {
                 mService.mBatteryStatsService.systemServicesReady();
                 mService.mServices.systemServicesReady();
@@ -21455,6 +21461,7 @@
                             return ActivityManager.BROADCAST_SUCCESS;
                         }
                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
+                        mServices.updateServiceApplicationInfoLocked(aInfo);
                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
                                 new String[] {ssp}, userId);
                     }
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index e73f42f..73710d3 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1927,11 +1927,12 @@
         if (displayStartTime != 0) {
             reportLaunchTimeLocked(curTime);
         }
-        final ActivityStack stack = getStack();
-        if (fullyDrawnStartTime != 0 && stack != null) {
+        final LaunchTimeTracker.Entry entry = mStackSupervisor.getLaunchTimeTracker().getEntry(
+                getWindowingMode());
+        if (fullyDrawnStartTime != 0 && entry != null) {
             final long thisTime = curTime - fullyDrawnStartTime;
-            final long totalTime = stack.mFullyDrawnStartTime != 0
-                    ? (curTime - stack.mFullyDrawnStartTime) : thisTime;
+            final long totalTime = entry.mFullyDrawnStartTime != 0
+                    ? (curTime - entry.mFullyDrawnStartTime) : thisTime;
             if (SHOW_ACTIVITY_START_TIME) {
                 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
                 EventLog.writeEvent(AM_ACTIVITY_FULLY_DRAWN_TIME,
@@ -1953,7 +1954,7 @@
             if (totalTime > 0) {
                 //service.mUsageStatsService.noteFullyDrawnTime(realActivity, (int) totalTime);
             }
-            stack.mFullyDrawnStartTime = 0;
+            entry.mFullyDrawnStartTime = 0;
         }
         mStackSupervisor.getActivityMetricsLogger().logAppTransitionReportedDrawn(this,
                 restoredFromBundle);
@@ -1961,13 +1962,14 @@
     }
 
     private void reportLaunchTimeLocked(final long curTime) {
-        final ActivityStack stack = getStack();
-        if (stack == null) {
+        final LaunchTimeTracker.Entry entry = mStackSupervisor.getLaunchTimeTracker().getEntry(
+                getWindowingMode());
+        if (entry == null) {
             return;
         }
         final long thisTime = curTime - displayStartTime;
-        final long totalTime = stack.mLaunchStartTime != 0
-                ? (curTime - stack.mLaunchStartTime) : thisTime;
+        final long totalTime = entry.mLaunchStartTime != 0
+                ? (curTime - entry.mLaunchStartTime) : thisTime;
         if (SHOW_ACTIVITY_START_TIME) {
             Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
             EventLog.writeEvent(AM_ACTIVITY_LAUNCH_TIME,
@@ -1991,7 +1993,7 @@
             //service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
         }
         displayStartTime = 0;
-        stack.mLaunchStartTime = 0;
+        entry.mLaunchStartTime = 0;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index c182502..aaa5161 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -339,9 +340,6 @@
     private final Rect mDeferredTaskBounds = new Rect();
     private final Rect mDeferredTaskInsetBounds = new Rect();
 
-    long mLaunchStartTime = 0;
-    long mFullyDrawnStartTime = 0;
-
     int mCurrentUser;
 
     final int mStackId;
@@ -1257,39 +1255,11 @@
                 + " callers=" + Debug.getCallers(5));
         r.setState(RESUMED, "minimalResumeActivityLocked");
         r.completeResumeLocked();
-        setLaunchTime(r);
+        mStackSupervisor.getLaunchTimeTracker().setLaunchTime(r);
         if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
                 "Launch completed; removing icicle of " + r.icicle);
     }
 
-    private void startLaunchTraces(String packageName) {
-        if (mFullyDrawnStartTime != 0)  {
-            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
-        }
-        Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
-        Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
-    }
-
-    private void stopFullyDrawnTraceIfNeeded() {
-        if (mFullyDrawnStartTime != 0 && mLaunchStartTime == 0) {
-            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
-            mFullyDrawnStartTime = 0;
-        }
-    }
-
-    void setLaunchTime(ActivityRecord r) {
-        if (r.displayStartTime == 0) {
-            r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis();
-            if (mLaunchStartTime == 0) {
-                startLaunchTraces(r.packageName);
-                mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime;
-            }
-        } else if (mLaunchStartTime == 0) {
-            startLaunchTraces(r.packageName);
-            mLaunchStartTime = mFullyDrawnStartTime = SystemClock.uptimeMillis();
-        }
-    }
-
     private void clearLaunchTime(ActivityRecord r) {
         // Make sure that there is no activity waiting for this to launch.
         if (mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
@@ -1477,9 +1447,8 @@
         prev.setState(PAUSING, "startPausingLocked");
         prev.getTask().touchActiveTime();
         clearLaunchTime(prev);
-        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
 
-        stopFullyDrawnTraceIfNeeded();
+        mStackSupervisor.getLaunchTimeTracker().stopFullyDrawnTraceIfNeeded(getWindowingMode());
 
         mService.updateCpuStats();
 
@@ -1791,10 +1760,16 @@
                 // In this case the home stack isn't resizeable even though we are in split-screen
                 // mode. We still want the primary splitscreen stack to be visible as there will be
                 // a slight hint of it in the status bar area above the non-resizeable home
-                // activity.
-                if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
-                        && other.getActivityType() == ACTIVITY_TYPE_HOME) {
-                    return true;
+                // activity. In addition, if the fullscreen assistant is over primary splitscreen
+                // stack, the stack should still be visible in the background as long as the recents
+                // animation is running.
+                final int activityType = other.getActivityType();
+                if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+                    if (activityType == ACTIVITY_TYPE_HOME
+                            || (activityType == ACTIVITY_TYPE_ASSISTANT
+                                    && mWindowManager.getRecentsAnimationController() != null)) {
+                       return true;
+                    }
                 }
                 if (other.isStackTranslucent(starting)) {
                     // Can be visible behind a translucent fullscreen stack.
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index df1ee55..afad0b1 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -445,6 +445,7 @@
     private boolean mTaskLayersChanged = true;
 
     private ActivityMetricsLogger mActivityMetricsLogger;
+    private LaunchTimeTracker mLaunchTimeTracker = new LaunchTimeTracker();
 
     private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>();
 
@@ -629,6 +630,10 @@
         return mActivityMetricsLogger;
     }
 
+    LaunchTimeTracker getLaunchTimeTracker() {
+        return mLaunchTimeTracker;
+    }
+
     public KeyguardController getKeyguardController() {
         return mKeyguardController;
     }
@@ -1646,7 +1651,7 @@
         ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                 r.info.applicationInfo.uid, true);
 
-        r.getStack().setLaunchTime(r);
+        getLaunchTimeTracker().setLaunchTime(r);
 
         if (app != null && app.thread != null) {
             try {
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 0104980..ad434b4 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1587,6 +1587,7 @@
                     }
                 }
             } else if (mOptions.getAvoidMoveToFront()) {
+                mDoResume = false;
                 mAvoidMoveToFront = true;
             }
         }
@@ -1929,7 +1930,7 @@
         // Need to update mTargetStack because if task was moved out of it, the original stack may
         // be destroyed.
         mTargetStack = intentActivity.getStack();
-        if (!mAvoidMoveToFront && !mMovedToFront && mDoResume) {
+        if (!mMovedToFront && mDoResume) {
             if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
                     + " from " + intentActivity);
             mTargetStack.moveToFront("intentActivityFound");
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index 5764382..ddf9552 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -132,6 +132,8 @@
         if (showingChanged) {
             dismissDockedStackIfNeeded();
             setKeyguardGoingAway(false);
+            mWindowManager.setKeyguardOrAodShowingOnDefaultDisplay(
+                    isKeyguardOrAodShowing(DEFAULT_DISPLAY));
             if (keyguardShowing) {
                 mDismissalRequested = false;
             }
diff --git a/services/core/java/com/android/server/am/LaunchTimeTracker.java b/services/core/java/com/android/server/am/LaunchTimeTracker.java
new file mode 100644
index 0000000..ee86969
--- /dev/null
+++ b/services/core/java/com/android/server/am/LaunchTimeTracker.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+import android.app.WaitResult;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.util.SparseArray;
+
+/**
+ * Tracks launch time of apps to be reported by {@link WaitResult}. Note that this is slightly
+ * different from {@link ActivityMetricsLogger}, but should eventually merged with it.
+ */
+class LaunchTimeTracker {
+
+    private final SparseArray<Entry> mWindowingModeLaunchTime = new SparseArray<>();
+
+    void setLaunchTime(ActivityRecord r) {
+        Entry entry = mWindowingModeLaunchTime.get(r.getWindowingMode());
+        if (entry == null){
+            entry = new Entry();
+            mWindowingModeLaunchTime.append(r.getWindowingMode(), entry);
+        }
+        entry.setLaunchTime(r);
+    }
+
+    void stopFullyDrawnTraceIfNeeded(int windowingMode) {
+        final Entry entry = mWindowingModeLaunchTime.get(windowingMode);
+        if (entry == null) {
+            return;
+        }
+        entry.stopFullyDrawnTraceIfNeeded();
+    }
+
+    Entry getEntry(int windowingMode) {
+        return mWindowingModeLaunchTime.get(windowingMode);
+    }
+
+    static class Entry {
+
+        long mLaunchStartTime;
+        long mFullyDrawnStartTime;
+
+        void setLaunchTime(ActivityRecord r) {
+            if (r.displayStartTime == 0) {
+                r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis();
+                if (mLaunchStartTime == 0) {
+                    startLaunchTraces(r.packageName);
+                    mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime;
+                }
+            } else if (mLaunchStartTime == 0) {
+                startLaunchTraces(r.packageName);
+                mLaunchStartTime = mFullyDrawnStartTime = SystemClock.uptimeMillis();
+            }
+        }
+
+        private void startLaunchTraces(String packageName) {
+            if (mFullyDrawnStartTime != 0)  {
+                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
+            }
+            Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
+            Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
+        }
+
+        private void stopFullyDrawnTraceIfNeeded() {
+            if (mFullyDrawnStartTime != 0 && mLaunchStartTime == 0) {
+                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
+                mFullyDrawnStartTime = 0;
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/am/RecentsAnimation.java b/services/core/java/com/android/server/am/RecentsAnimation.java
index a3d2173..bd49bd1 100644
--- a/services/core/java/com/android/server/am/RecentsAnimation.java
+++ b/services/core/java/com/android/server/am/RecentsAnimation.java
@@ -52,8 +52,7 @@
 class RecentsAnimation implements RecentsAnimationCallbacks,
         ActivityDisplay.OnStackOrderChangedListener {
     private static final String TAG = RecentsAnimation.class.getSimpleName();
-    // TODO (b/73188263): Reset debugging flags
-    private static final boolean DEBUG = true;
+    private static final boolean DEBUG = false;
 
     private final ActivityManagerService mService;
     private final ActivityStackSupervisor mStackSupervisor;
@@ -169,6 +168,7 @@
                         .setMayWait(mUserController.getCurrentUserId())
                         .execute();
                 mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
+                mWindowManager.executeAppTransition();
 
                 targetActivity = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
                         mTargetActivityType).getTopActivity();
diff --git a/services/core/java/com/android/server/am/SafeActivityOptions.java b/services/core/java/com/android/server/am/SafeActivityOptions.java
index 0fb69e7..55d17a9 100644
--- a/services/core/java/com/android/server/am/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/am/SafeActivityOptions.java
@@ -79,9 +79,6 @@
         mOriginalCallingPid = Binder.getCallingPid();
         mOriginalCallingUid = Binder.getCallingUid();
         mOriginalOptions = options;
-        if (mOriginalCallingPid == Process.myPid()) {
-            Slog.wtf(TAG, "Safe activity options constructed after clearing calling id");
-        }
     }
 
     /**
@@ -93,9 +90,6 @@
         mRealCallingPid = Binder.getCallingPid();
         mRealCallingUid = Binder.getCallingUid();
         mCallerOptions = options;
-        if (mRealCallingPid == Process.myPid()) {
-            Slog.wtf(TAG, "setCallerOptions called after clearing calling id");
-        }
     }
 
     /**
@@ -128,20 +122,28 @@
         if (mOriginalOptions != null) {
             checkPermissions(intent, aInfo, callerApp, supervisor, mOriginalOptions,
                     mOriginalCallingPid, mOriginalCallingUid);
-            if (mOriginalOptions.getRemoteAnimationAdapter() != null) {
-                mOriginalOptions.getRemoteAnimationAdapter().setCallingPid(mOriginalCallingPid);
-            }
+            setCallingPidForRemoteAnimationAdapter(mOriginalOptions, mOriginalCallingPid);
         }
         if (mCallerOptions != null) {
             checkPermissions(intent, aInfo, callerApp, supervisor, mCallerOptions,
                     mRealCallingPid, mRealCallingUid);
-            if (mCallerOptions.getRemoteAnimationAdapter() != null) {
-                mCallerOptions.getRemoteAnimationAdapter().setCallingPid(mRealCallingPid);
-            }
+            setCallingPidForRemoteAnimationAdapter(mCallerOptions, mRealCallingPid);
         }
         return mergeActivityOptions(mOriginalOptions, mCallerOptions);
     }
 
+    private void setCallingPidForRemoteAnimationAdapter(ActivityOptions options, int callingPid) {
+        final RemoteAnimationAdapter adapter = options.getRemoteAnimationAdapter();
+        if (adapter == null) {
+            return;
+        }
+        if (callingPid == Process.myPid()) {
+            Slog.wtf(TAG, "Safe activity options constructed after clearing calling id");
+            return;
+        }
+        adapter.setCallingPid(callingPid);
+    }
+
     /**
      * @see ActivityOptions#popAppVerificationBundle
      */
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 32887e4..4d89d01 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -73,7 +73,7 @@
                             // original intent used to find service.
     final ServiceInfo serviceInfo;
                             // all information about the service.
-    final ApplicationInfo appInfo;
+    ApplicationInfo appInfo;
                             // information about service's app.
     final int userId;       // user that this service is running as
     final String packageName; // the package implementing intent's component
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 2843a2f..7c9a3ae 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1320,6 +1320,11 @@
         }
         String enabledSurroundFormats = Settings.Global.getString(
                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
+        if (enabledSurroundFormats == null) {
+            // Never allow enabledSurroundFormats as a null, which could happen when
+            // ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS is not appear in settings DB.
+            enabledSurroundFormats = "";
+        }
         if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) {
             // Update enabled surround formats to AudioPolicyManager only when forceUpdate
             // is true or enabled surround formats changed.
@@ -3713,26 +3718,35 @@
         }
         String address = btDevice.getAddress();
         BluetoothClass btClass = btDevice.getBluetoothClass();
-        int outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
         int inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+        int[] outDeviceTypes = {
+            AudioSystem.DEVICE_OUT_BLUETOOTH_SCO,
+            AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
+            AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT
+        };
         if (btClass != null) {
             switch (btClass.getDeviceClass()) {
                 case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
                 case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
-                    outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
+                    outDeviceTypes = new int[] { AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET };
                     break;
                 case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
-                    outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
+                    outDeviceTypes = new int[] { AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT };
                     break;
             }
         }
-
         if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             address = "";
         }
-
         String btDeviceName =  btDevice.getName();
-        boolean result = handleDeviceConnection(isActive, outDevice, address, btDeviceName);
+        boolean result = false;
+        if (isActive) {
+            result |= handleDeviceConnection(isActive, outDeviceTypes[0], address, btDeviceName);
+        } else {
+            for (int outDeviceType : outDeviceTypes) {
+                result |= handleDeviceConnection(isActive, outDeviceType, address, btDeviceName);
+            }
+        }
         // handleDeviceConnection() && result to make sure the method get executed
         result = handleDeviceConnection(isActive, inDevice, address, btDeviceName) && result;
         return result;
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index d51a196..c0beb37 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -16,7 +16,7 @@
 
 package com.android.server.connectivity;
 
-import static android.net.ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE;
+import static android.net.ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE_FALLBACK;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
@@ -24,6 +24,7 @@
 import static android.provider.Settings.Global.DNS_RESOLVER_MAX_SAMPLES;
 import static android.provider.Settings.Global.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS;
 import static android.provider.Settings.Global.DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT;
+import static android.provider.Settings.Global.PRIVATE_DNS_DEFAULT_MODE;
 import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
 
@@ -184,6 +185,7 @@
 
     public static Uri[] getPrivateDnsSettingsUris() {
         return new Uri[]{
+            Settings.Global.getUriFor(PRIVATE_DNS_DEFAULT_MODE),
             Settings.Global.getUriFor(PRIVATE_DNS_MODE),
             Settings.Global.getUriFor(PRIVATE_DNS_SPECIFIER),
         };
@@ -485,8 +487,10 @@
     }
 
     private static String getPrivateDnsMode(ContentResolver cr) {
-        final String mode = getStringSetting(cr, PRIVATE_DNS_MODE);
-        return !TextUtils.isEmpty(mode) ? mode : PRIVATE_DNS_DEFAULT_MODE;
+        String mode = getStringSetting(cr, PRIVATE_DNS_MODE);
+        if (TextUtils.isEmpty(mode)) mode = getStringSetting(cr, PRIVATE_DNS_DEFAULT_MODE);
+        if (TextUtils.isEmpty(mode)) mode = PRIVATE_DNS_DEFAULT_MODE_FALLBACK;
+        return mode;
     }
 
     private static String getStringSetting(ContentResolver cr, String which) {
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index c9f92d2..2a6f7c8 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -21,7 +21,7 @@
 import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT;
 import static android.Manifest.permission.USE_BIOMETRIC;
 import static android.Manifest.permission.USE_FINGERPRINT;
-import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
 
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningAppProcessInfo;
@@ -772,7 +772,7 @@
             for (int i = 0; i < N; i++) {
                 RunningAppProcessInfo proc = procs.get(i);
                 if (proc.pid == pid && proc.uid == uid
-                        && proc.importance == IMPORTANCE_FOREGROUND) {
+                        && proc.importance <= IMPORTANCE_FOREGROUND_SERVICE) {
                     return true;
                 }
             }
@@ -1499,8 +1499,10 @@
             try {
                 userId = getUserOrWorkProfileId(clientPackage, userId);
                 if (userId != mCurrentUserId) {
+                    int firstSdkInt = Build.VERSION.FIRST_SDK_INT;
+                    if (firstSdkInt == 0) firstSdkInt = Build.VERSION.SDK_INT;
                     File baseDir;
-                    if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O_MR1) {
+                    if (firstSdkInt <= Build.VERSION_CODES.O_MR1) {
                         baseDir = Environment.getUserSystemDirectory(userId);
                     } else {
                         baseDir = Environment.getDataVendorDeDirectory(userId);
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index b441baf..0b7c5b9 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -2961,6 +2961,18 @@
         return 0;
     }
 
+    void triggerDockState(boolean idleState) {
+        final Intent dockIntent;
+        if (idleState) {
+            dockIntent = new Intent(Intent.ACTION_DOCK_IDLE);
+        } else {
+            dockIntent = new Intent(Intent.ACTION_DOCK_ACTIVE);
+        }
+        dockIntent.setPackage("android");
+        dockIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
+        getContext().sendBroadcastAsUser(dockIntent, UserHandle.ALL);
+    }
+
     private String printContextIdToJobMap(JobStatus[] map, String initial) {
         StringBuilder s = new StringBuilder(initial + ": ");
         for (int i=0; i<map.length; i++) {
diff --git a/services/core/java/com/android/server/job/JobSchedulerShellCommand.java b/services/core/java/com/android/server/job/JobSchedulerShellCommand.java
index 63225f3..e361441 100644
--- a/services/core/java/com/android/server/job/JobSchedulerShellCommand.java
+++ b/services/core/java/com/android/server/job/JobSchedulerShellCommand.java
@@ -66,6 +66,8 @@
                     return getJobState(pw);
                 case "heartbeat":
                     return doHeartbeat(pw);
+                case "trigger-dock-state":
+                    return triggerDockState(pw);
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -349,6 +351,29 @@
         }
     }
 
+    private int triggerDockState(PrintWriter pw) throws Exception {
+        checkPermission("trigger wireless charging dock state");
+
+        final String opt = getNextArgRequired();
+        boolean idleState;
+        if ("idle".equals(opt)) {
+            idleState = true;
+        } else if ("active".equals(opt)) {
+            idleState = false;
+        } else {
+            getErrPrintWriter().println("Error: unknown option " + opt);
+            return 1;
+        }
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            mInternal.triggerDockState(idleState);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+        return 0;
+    }
+
     @Override
     public void onHelp() {
         final PrintWriter pw = getOutPrintWriter();
@@ -403,6 +428,8 @@
         pw.println("    Options:");
         pw.println("      -u or --user: specify which user's job is to be run; the default is");
         pw.println("         the primary or system user");
+        pw.println("  trigger-dock-state [idle|active]");
+        pw.println("    Trigger wireless charging dock state.  Active by default.");
         pw.println();
     }
 
diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
index 40d2a3a..644f2c4 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -42,7 +42,7 @@
             || Log.isLoggable(TAG, Log.DEBUG);
 
     // Policy: we decide that we're "idle" if the device has been unused /
-    // screen off or dreaming for at least this long
+    // screen off or dreaming or wireless charging dock idle for at least this long
     private long mInactivityIdleThreshold;
     private long mIdleWindowSlop;
     final ArraySet<JobStatus> mTrackedTasks = new ArraySet<>();
@@ -105,6 +105,7 @@
         // on the main looper thread, either in onReceive() or in an alarm callback.
         private boolean mIdle;
         private boolean mScreenOn;
+        private boolean mDockIdle;
 
         private AlarmManager.OnAlarmListener mIdleAlarmListener = () -> {
             handleIdleTrigger();
@@ -117,6 +118,7 @@
             // device in some meaningful way.
             mIdle = false;
             mScreenOn = true;
+            mDockIdle = false;
         }
 
         public boolean isIdle() {
@@ -137,6 +139,10 @@
             // Debugging/instrumentation
             filter.addAction(ActivityManagerService.ACTION_TRIGGER_IDLE);
 
+            // Wireless charging dock state
+            filter.addAction(Intent.ACTION_DOCK_IDLE);
+            filter.addAction(Intent.ACTION_DOCK_ACTIVE);
+
             mContext.registerReceiver(this, filter);
         }
 
@@ -144,11 +150,22 @@
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
             if (action.equals(Intent.ACTION_SCREEN_ON)
-                    || action.equals(Intent.ACTION_DREAMING_STOPPED)) {
+                    || action.equals(Intent.ACTION_DREAMING_STOPPED)
+                    || action.equals(Intent.ACTION_DOCK_ACTIVE)) {
+                if (action.equals(Intent.ACTION_DOCK_ACTIVE)) {
+                    if (!mScreenOn) {
+                        // Ignore this intent during screen off
+                        return;
+                    } else {
+                        mDockIdle = false;
+                    }
+                } else {
+                    mScreenOn = true;
+                    mDockIdle = false;
+                }
                 if (DEBUG) {
                     Slog.v(TAG,"exiting idle : " + action);
                 }
-                mScreenOn = true;
                 //cancel the alarm
                 mAlarm.cancel(mIdleAlarmListener);
                 if (mIdle) {
@@ -157,17 +174,28 @@
                     reportNewIdleState(mIdle);
                 }
             } else if (action.equals(Intent.ACTION_SCREEN_OFF)
-                    || action.equals(Intent.ACTION_DREAMING_STARTED)) {
-                // when the screen goes off or dreaming starts, we schedule the
-                // alarm that will tell us when we have decided the device is
+                    || action.equals(Intent.ACTION_DREAMING_STARTED)
+                    || action.equals(Intent.ACTION_DOCK_IDLE)) {
+                // when the screen goes off or dreaming starts or wireless charging dock in idle,
+                // we schedule the alarm that will tell us when we have decided the device is
                 // truly idle.
+                if (action.equals(Intent.ACTION_DOCK_IDLE)) {
+                    if (!mScreenOn) {
+                        // Ignore this intent during screen off
+                        return;
+                    } else {
+                        mDockIdle = true;
+                    }
+                } else {
+                    mScreenOn = false;
+                    mDockIdle = false;
+                }
                 final long nowElapsed = sElapsedRealtimeClock.millis();
                 final long when = nowElapsed + mInactivityIdleThreshold;
                 if (DEBUG) {
                     Slog.v(TAG, "Scheduling idle : " + action + " now:" + nowElapsed + " when="
                             + when);
                 }
-                mScreenOn = false;
                 mAlarm.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                         when, mIdleWindowSlop, "JS idleness", mIdleAlarmListener, null);
             } else if (action.equals(ActivityManagerService.ACTION_TRIGGER_IDLE)) {
@@ -177,7 +205,7 @@
 
         private void handleIdleTrigger() {
             // idle time starts now. Do not set mIdle if screen is on.
-            if (!mIdle && !mScreenOn) {
+            if (!mIdle && (!mScreenOn || mDockIdle)) {
                 if (DEBUG) {
                     Slog.v(TAG, "Idle trigger fired @ " + sElapsedRealtimeClock.millis());
                 }
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
index 5d71cc7..f1951b1 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
@@ -33,6 +33,7 @@
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDb;
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverySnapshotStorage;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.charset.StandardCharsets;
@@ -176,7 +177,11 @@
 
         List<Integer> recoveryAgents = mRecoverableKeyStoreDb.getRecoveryAgents(mUserId);
         for (int uid : recoveryAgents) {
-            syncKeysForAgent(uid);
+            try {
+              syncKeysForAgent(uid);
+            } catch (IOException e) {
+                Log.e(TAG, "IOException during sync for agent " + uid, e);
+            }
         }
         if (recoveryAgents.isEmpty()) {
             Log.w(TAG, "No recovery agent initialized for user " + mUserId);
@@ -189,13 +194,13 @@
             && mCredentialType != LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
     }
 
-    private void syncKeysForAgent(int recoveryAgentUid) {
-        boolean recreateCurrentVersion = false;
+    private void syncKeysForAgent(int recoveryAgentUid) throws IOException {
+        boolean shouldRecreateCurrentVersion = false;
         if (!shouldCreateSnapshot(recoveryAgentUid)) {
-            recreateCurrentVersion =
+            shouldRecreateCurrentVersion =
                     (mRecoverableKeyStoreDb.getSnapshotVersion(mUserId, recoveryAgentUid) != null)
                     && (mRecoverySnapshotStorage.get(recoveryAgentUid) == null);
-            if (recreateCurrentVersion) {
+            if (shouldRecreateCurrentVersion) {
                 Log.d(TAG, "Recreating most recent snapshot");
             } else {
                 Log.d(TAG, "Key sync not needed.");
@@ -203,12 +208,12 @@
             }
         }
 
-        PublicKey publicKey;
         String rootCertAlias =
                 mRecoverableKeyStoreDb.getActiveRootOfTrust(mUserId, recoveryAgentUid);
         rootCertAlias = mTestOnlyInsecureCertificateHelper
                 .getDefaultCertificateAliasIfEmpty(rootCertAlias);
 
+        PublicKey publicKey;
         CertPath certPath = mRecoverableKeyStoreDb.getRecoveryServiceCertPath(mUserId,
                 recoveryAgentUid, rootCertAlias);
         if (certPath != null) {
@@ -260,19 +265,22 @@
             Log.e(TAG, "Failed to load recoverable keys for sync", e);
             return;
         } catch (InsecureUserException e) {
-            Log.wtf(TAG, "A screen unlock triggered the key sync flow, so user must have "
+            Log.e(TAG, "A screen unlock triggered the key sync flow, so user must have "
                     + "lock screen. This should be impossible.", e);
             return;
         } catch (BadPlatformKeyException e) {
-            Log.wtf(TAG, "Loaded keys for same generation ID as platform key, so "
+            Log.e(TAG, "Loaded keys for same generation ID as platform key, so "
                     + "BadPlatformKeyException should be impossible.", e);
             return;
+        } catch (IOException e) {
+            Log.e(TAG, "Local database error.", e);
+            return;
         }
-
         // Only include insecure key material for test
         if (mTestOnlyInsecureCertificateHelper.isTestOnlyCertificateAlias(rootCertAlias)) {
             rawKeys = mTestOnlyInsecureCertificateHelper.keepOnlyWhitelistedInsecureKeys(rawKeys);
         }
+
         SecretKey recoveryKey;
         try {
             recoveryKey = generateRecoveryKey();
@@ -323,6 +331,7 @@
             Log.e(TAG,"Could not encrypt with recovery key", e);
             return;
         }
+
         KeyDerivationParams keyDerivationParams;
         if (useScryptToHashCredential) {
             keyDerivationParams = KeyDerivationParams.createScryptParams(
@@ -330,7 +339,7 @@
         } else {
             keyDerivationParams = KeyDerivationParams.createSha256Params(salt);
         }
-        KeyChainProtectionParams metadata = new KeyChainProtectionParams.Builder()
+        KeyChainProtectionParams keyChainProtectionParams = new KeyChainProtectionParams.Builder()
                 .setUserSecretType(TYPE_LOCKSCREEN)
                 .setLockScreenUiFormat(getUiFormat(mCredentialType, mCredential))
                 .setKeyDerivationParams(keyDerivationParams)
@@ -338,13 +347,11 @@
                 .build();
 
         ArrayList<KeyChainProtectionParams> metadataList = new ArrayList<>();
-        metadataList.add(metadata);
-
-        // If application keys are not updated, snapshot will not be created on next unlock.
-        mRecoverableKeyStoreDb.setShouldCreateSnapshot(mUserId, recoveryAgentUid, false);
+        metadataList.add(keyChainProtectionParams);
 
         KeyChainSnapshot.Builder keyChainSnapshotBuilder = new KeyChainSnapshot.Builder()
-                .setSnapshotVersion(getSnapshotVersion(recoveryAgentUid, recreateCurrentVersion))
+                .setSnapshotVersion(
+                        getSnapshotVersion(recoveryAgentUid, shouldRecreateCurrentVersion))
                 .setMaxAttempts(TRUSTED_HARDWARE_MAX_ATTEMPTS)
                 .setCounterId(counterId)
                 .setServerParams(vaultHandle)
@@ -360,25 +367,38 @@
         }
         mRecoverySnapshotStorage.put(recoveryAgentUid, keyChainSnapshotBuilder.build());
         mSnapshotListenersStorage.recoverySnapshotAvailable(recoveryAgentUid);
+
+        mRecoverableKeyStoreDb.setShouldCreateSnapshot(mUserId, recoveryAgentUid, false);
     }
 
     @VisibleForTesting
-    int getSnapshotVersion(int recoveryAgentUid, boolean recreateCurrentVersion) {
+    int getSnapshotVersion(int recoveryAgentUid, boolean shouldRecreateCurrentVersion)
+            throws IOException {
         Long snapshotVersion = mRecoverableKeyStoreDb.getSnapshotVersion(mUserId, recoveryAgentUid);
-        if (recreateCurrentVersion) {
+        if (shouldRecreateCurrentVersion) {
             // version shouldn't be null at this moment.
             snapshotVersion = snapshotVersion == null ? 1 : snapshotVersion;
         } else {
             snapshotVersion = snapshotVersion == null ? 1 : snapshotVersion + 1;
         }
-        mRecoverableKeyStoreDb.setSnapshotVersion(mUserId, recoveryAgentUid, snapshotVersion);
+
+        long updatedRows = mRecoverableKeyStoreDb.setSnapshotVersion(mUserId, recoveryAgentUid,
+                snapshotVersion);
+        if (updatedRows < 0) {
+            Log.e(TAG, "Failed to set the snapshot version in the local DB.");
+            throw new IOException("Failed to set the snapshot version in the local DB.");
+        }
 
         return snapshotVersion.intValue();
     }
 
-    private long generateAndStoreCounterId(int recoveryAgentUid) {
+    private long generateAndStoreCounterId(int recoveryAgentUid) throws IOException {
         long counter = new SecureRandom().nextLong();
-        mRecoverableKeyStoreDb.setCounterId(mUserId, recoveryAgentUid, counter);
+        long updatedRows = mRecoverableKeyStoreDb.setCounterId(mUserId, recoveryAgentUid, counter);
+        if (updatedRows < 0) {
+            Log.e(TAG, "Failed to set the snapshot version in the local DB.");
+            throw new IOException("Failed to set counterId in the local DB.");
+        }
         return counter;
     }
 
@@ -388,7 +408,7 @@
     private Map<String, SecretKey> getKeysToSync(int recoveryAgentUid)
             throws InsecureUserException, KeyStoreException, UnrecoverableKeyException,
             NoSuchAlgorithmException, NoSuchPaddingException, BadPlatformKeyException,
-            InvalidKeyException, InvalidAlgorithmParameterException {
+            InvalidKeyException, InvalidAlgorithmParameterException, IOException {
         PlatformDecryptionKey decryptKey = mPlatformKeyManager.getDecryptKey(mUserId);;
         Map<String, WrappedKey> wrappedKeys = mRecoverableKeyStoreDb.getAllKeys(
                 mUserId, recoveryAgentUid, decryptKey.getGenerationId());
@@ -440,7 +460,7 @@
      *
      * @return The salt.
      */
-    private byte[] generateSalt() {
+    private static byte[] generateSalt() {
         byte[] salt = new byte[SALT_LENGTH_BYTES];
         new SecureRandom().nextBytes(salt);
         return salt;
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java
index 57fb74d..8e6f9cb 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncUtils.java
@@ -37,7 +37,7 @@
 import javax.crypto.SecretKey;
 
 /**
- * Utility functions for the flow where the RecoveryManager syncs keys with remote storage.
+ * Utility functions for the flow where the RecoveryController syncs keys with remote storage.
  *
  * @hide
  */
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
index 52394d2..9ca052b 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
@@ -157,11 +157,13 @@
      * @throws NoSuchAlgorithmException if AES is unavailable - should never happen.
      * @throws KeyStoreException if there is an error in AndroidKeyStore.
      * @throws InsecureUserException if the user does not have a lock screen set.
+     * @throws IOException if there was an issue with local database update.
      *
      * @hide
      */
-    public void regenerate(int userId)
-            throws NoSuchAlgorithmException, KeyStoreException, InsecureUserException {
+    @VisibleForTesting
+    void regenerate(int userId)
+            throws NoSuchAlgorithmException, KeyStoreException, InsecureUserException, IOException {
         if (!isAvailable(userId)) {
             throw new InsecureUserException(String.format(
                     Locale.US, "%d does not have a lock screen set.", userId));
@@ -187,11 +189,12 @@
      * @throws UnrecoverableKeyException if the key could not be recovered.
      * @throws NoSuchAlgorithmException if AES is unavailable - should never occur.
      * @throws InsecureUserException if the user does not have a lock screen set.
+     * @throws IOException if there was an issue with local database update.
      *
      * @hide
      */
     public PlatformEncryptionKey getEncryptKey(int userId) throws KeyStoreException,
-           UnrecoverableKeyException, NoSuchAlgorithmException, InsecureUserException {
+           UnrecoverableKeyException, NoSuchAlgorithmException, InsecureUserException, IOException {
         init(userId);
         try {
             // Try to see if the decryption key is still accessible before using the encryption key.
@@ -239,11 +242,12 @@
      * @throws UnrecoverableKeyException if the key could not be recovered.
      * @throws NoSuchAlgorithmException if AES is unavailable - should never occur.
      * @throws InsecureUserException if the user does not have a lock screen set.
+     * @throws IOException if there was an issue with local database update.
      *
      * @hide
      */
     public PlatformDecryptionKey getDecryptKey(int userId) throws KeyStoreException,
-           UnrecoverableKeyException, NoSuchAlgorithmException, InsecureUserException {
+           UnrecoverableKeyException, NoSuchAlgorithmException, InsecureUserException, IOException {
         init(userId);
         try {
             return getDecryptKeyInternal(userId);
@@ -286,11 +290,12 @@
      * @param userId The ID of the user to whose lock screen the platform key must be bound.
      * @throws KeyStoreException if there was an error in AndroidKeyStore.
      * @throws NoSuchAlgorithmException if AES is unavailable - should never happen.
+     * @throws IOException if there was an issue with local database update.
      *
      * @hide
      */
     void init(int userId)
-            throws KeyStoreException, NoSuchAlgorithmException, InsecureUserException {
+            throws KeyStoreException, NoSuchAlgorithmException, InsecureUserException, IOException {
         if (!isAvailable(userId)) {
             throw new InsecureUserException(String.format(
                     Locale.US, "%d does not have a lock screen set.", userId));
@@ -347,9 +352,13 @@
 
     /**
      * Sets the current generation ID to {@code generationId}.
+     * @throws IOException if there was an issue with local database update.
      */
-    private void setGenerationId(int userId, int generationId) {
-        mDatabase.setPlatformKeyGenerationId(userId, generationId);
+    private void setGenerationId(int userId, int generationId) throws IOException {
+        long updatedRows = mDatabase.setPlatformKeyGenerationId(userId, generationId);
+        if (updatedRows < 0) {
+            throw new IOException("Failed to set the platform key in the local DB.");
+        }
     }
 
     /**
@@ -370,9 +379,10 @@
      * @throws NoSuchAlgorithmException if AES is unavailable. This should never happen, as it is
      *     available since API version 1.
      * @throws KeyStoreException if there was an issue loading the keys into AndroidKeyStore.
+     * @throws IOException if there was an issue with local database update.
      */
     private void generateAndLoadKey(int userId, int generationId)
-            throws NoSuchAlgorithmException, KeyStoreException {
+            throws NoSuchAlgorithmException, KeyStoreException, IOException {
         String encryptAlias = getEncryptAlias(userId, generationId);
         String decryptAlias = getDecryptAlias(userId, generationId);
         // SecretKey implementation doesn't provide reliable way to destroy the secret
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGenerator.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGenerator.java
index 396862d..c249468 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGenerator.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGenerator.java
@@ -24,6 +24,7 @@
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.util.Locale;
+import android.util.Log;
 
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
@@ -40,6 +41,7 @@
  */
 public class RecoverableKeyGenerator {
 
+    private static final String TAG = "PlatformKeyGen";
     private static final int RESULT_CANNOT_INSERT_ROW = -1;
     private static final String SECRET_KEY_ALGORITHM = "AES";
 
@@ -104,7 +106,11 @@
                             Locale.US, "Failed writing (%d, %s) to database.", uid, alias));
         }
 
-        mDatabase.setShouldCreateSnapshot(userId, uid, true);
+        long updatedRows = mDatabase.setShouldCreateSnapshot(userId, uid, true);
+        if (updatedRows < 0) {
+            Log.e(TAG, "Failed to set the shoudCreateSnapshot flag in the local DB.");
+        }
+
         return key.getEncoded();
     }
 
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
index 09906e4..fc5184d 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
@@ -57,6 +57,7 @@
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverySessionStorage;
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverySnapshotStorage;
 
+import java.io.IOException;
 import java.security.InvalidKeyException;
 import java.security.KeyFactory;
 import java.security.KeyStoreException;
@@ -189,11 +190,14 @@
         if (activeRootAlias == null) {
             Log.d(TAG, "Root of trust for recovery agent + " + uid
                 + " is assigned for the first time to " + rootCertificateAlias);
-            mDatabase.setActiveRootOfTrust(userId, uid, rootCertificateAlias);
         } else if (!activeRootAlias.equals(rootCertificateAlias)) {
             Log.i(TAG, "Root of trust for recovery agent " + uid + " is changed to "
                     + rootCertificateAlias + " from  " + activeRootAlias);
-            mDatabase.setActiveRootOfTrust(userId, uid, rootCertificateAlias);
+        }
+        long updatedRows = mDatabase.setActiveRootOfTrust(userId, uid, rootCertificateAlias);
+        if (updatedRows < 0) {
+            throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR,
+                    "Failed to set the root of trust in the local DB.");
         }
 
         CertXml certXml;
@@ -236,17 +240,32 @@
         // Save the chosen and validated certificate into database
         try {
             Log.d(TAG, "Saving the randomly chosen endpoint certificate to database");
-            if (mDatabase.setRecoveryServiceCertPath(userId, uid, rootCertificateAlias,
-                    certPath) > 0) {
-                mDatabase.setRecoveryServiceCertSerial(userId, uid, rootCertificateAlias,
-                        newSerial);
+            long updatedCertPathRows = mDatabase.setRecoveryServiceCertPath(userId, uid,
+                    rootCertificateAlias, certPath);
+            if (updatedCertPathRows > 0) {
+                long updatedCertSerialRows = mDatabase.setRecoveryServiceCertSerial(userId, uid,
+                        rootCertificateAlias, newSerial);
+                if (updatedCertSerialRows < 0) {
+                    // Ideally CertPath and CertSerial should be updated together in single
+                    // transaction, but since their mismatch doesn't create many problems
+                    // extra complexity is unnecessary.
+                    throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR,
+                        "Failed to set the certificate serial number in the local DB.");
+                }
                 if (mDatabase.getSnapshotVersion(userId, uid) != null) {
                     mDatabase.setShouldCreateSnapshot(userId, uid, true);
                     Log.i(TAG, "This is a certificate change. Snapshot must be updated");
                 } else {
                     Log.i(TAG, "This is a certificate change. Snapshot didn't exist");
                 }
-                mDatabase.setCounterId(userId, uid, new SecureRandom().nextLong());
+                long updatedCounterIdRows =
+                        mDatabase.setCounterId(userId, uid, new SecureRandom().nextLong());
+                if (updatedCounterIdRows < 0) {
+                    Log.e(TAG, "Failed to set the counter id in the local DB.");
+                }
+            } else if (updatedCertPathRows < 0) {
+                throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR,
+                        "Failed to set the certificate path in the local DB.");
             }
         } catch (CertificateEncodingException e) {
             Log.e(TAG, "Failed to encode CertPath", e);
@@ -340,7 +359,7 @@
         }
 
         long updatedRows = mDatabase.setServerParams(userId, uid, serverParams);
-        if (updatedRows < 1) {
+        if (updatedRows < 0) {
             throw new ServiceSpecificException(
                     ERROR_SERVICE_INTERNAL_ERROR, "Database failure trying to set server params.");
         }
@@ -364,7 +383,12 @@
     public void setRecoveryStatus(@NonNull String alias, int status) throws RemoteException {
         checkRecoverKeyStorePermission();
         Preconditions.checkNotNull(alias, "alias is null");
-        mDatabase.setRecoveryStatus(Binder.getCallingUid(), alias, status);
+        long updatedRows = mDatabase.setRecoveryStatus(Binder.getCallingUid(), alias, status);
+        if (updatedRows < 0) {
+            throw new ServiceSpecificException(
+                    ERROR_SERVICE_INTERNAL_ERROR,
+                    "Failed to set the key recovery status in the local DB.");
+        }
     }
 
     /**
@@ -400,7 +424,7 @@
         }
 
         long updatedRows = mDatabase.setRecoverySecretTypes(userId, uid, secretTypes);
-        if (updatedRows < 1) {
+        if (updatedRows < 0) {
             throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR,
                     "Database error trying to set secret types.");
         }
@@ -664,7 +688,7 @@
         } catch (NoSuchAlgorithmException e) {
             // Impossible: all algorithms must be supported by AOSP
             throw new RuntimeException(e);
-        } catch (KeyStoreException | UnrecoverableKeyException e) {
+        } catch (KeyStoreException | UnrecoverableKeyException | IOException e) {
             throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
         } catch (InsecureUserException e) {
             throw new ServiceSpecificException(ERROR_INSECURE_USER, e.getMessage());
@@ -713,7 +737,7 @@
         } catch (NoSuchAlgorithmException e) {
             // Impossible: all algorithms must be supported by AOSP
             throw new RuntimeException(e);
-        } catch (KeyStoreException | UnrecoverableKeyException e) {
+        } catch (KeyStoreException | UnrecoverableKeyException | IOException e) {
             throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
         } catch (InsecureUserException e) {
             throw new ServiceSpecificException(ERROR_INSECURE_USER, e.getMessage());
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbContract.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbContract.java
index 7ee809a..22e77cc 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbContract.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbContract.java
@@ -64,7 +64,7 @@
         static final String COLUMN_NAME_LAST_SYNCED_AT = "last_synced_at";
 
         /**
-         * Status of the key sync {@code RecoveryManager#setRecoveryStatus}
+         * Status of the key sync {@code RecoveryController#setRecoveryStatus}
          */
         static final String COLUMN_NAME_RECOVERY_STATUS = "recovery_status";
     }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index bf17798..e2e6f6d 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -243,6 +243,9 @@
     public static final boolean ENABLE_CHILD_NOTIFICATIONS
             = SystemProperties.getBoolean("debug.child_notifs", true);
 
+    static final boolean DEBUG_INTERRUPTIVENESS = SystemProperties.getBoolean(
+            "debug.notification.interruptiveness", false);
+
     static final int MAX_PACKAGE_NOTIFICATIONS = 50;
     static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 5f;
 
@@ -4437,7 +4440,7 @@
                     if (index < 0) {
                         mNotificationList.add(r);
                         mUsageStats.registerPostedByApp(r);
-                        r.setInterruptive(true);
+                        r.setInterruptive(isVisuallyInterruptive(null, r));
                     } else {
                         old = mNotificationList.get(index);
                         mNotificationList.set(index, r);
@@ -4516,31 +4519,75 @@
     @GuardedBy("mNotificationLock")
     @VisibleForTesting
     protected boolean isVisuallyInterruptive(NotificationRecord old, NotificationRecord r) {
+        if (old == null) {
+            if (DEBUG_INTERRUPTIVENESS) {
+                Log.v(TAG, "INTERRUPTIVENESS: "
+                        +  r.getKey() + " is interruptive: new notification");
+            }
+            return true;
+        }
+
         Notification oldN = old.sbn.getNotification();
         Notification newN = r.sbn.getNotification();
+
         if (oldN.extras == null || newN.extras == null) {
+            if (DEBUG_INTERRUPTIVENESS) {
+                Log.v(TAG, "INTERRUPTIVENESS: "
+                        +  r.getKey() + " is not interruptive: no extras");
+            }
             return false;
         }
 
         // Ignore visual interruptions from foreground services because users
         // consider them one 'session'. Count them for everything else.
         if (r != null && (r.sbn.getNotification().flags & FLAG_FOREGROUND_SERVICE) != 0) {
+            if (DEBUG_INTERRUPTIVENESS) {
+                Log.v(TAG, "INTERRUPTIVENESS: "
+                        +  r.getKey() + " is not interruptive: foreground service");
+            }
             return false;
         }
 
-        if (!Objects.equals(oldN.extras.get(Notification.EXTRA_TITLE),
-                newN.extras.get(Notification.EXTRA_TITLE))) {
+        final String oldTitle = String.valueOf(oldN.extras.get(Notification.EXTRA_TITLE));
+        final String newTitle = String.valueOf(newN.extras.get(Notification.EXTRA_TITLE));
+        if (!Objects.equals(oldTitle, newTitle)) {
+            if (DEBUG_INTERRUPTIVENESS) {
+                Log.v(TAG, "INTERRUPTIVENESS: "
+                        +  r.getKey() + " is interruptive: changed title");
+                Log.v(TAG, "INTERRUPTIVENESS: " + String.format("   old title: %s (%s@0x%08x)",
+                        oldTitle, oldTitle.getClass(), oldTitle.hashCode()));
+                Log.v(TAG, "INTERRUPTIVENESS: " + String.format("   new title: %s (%s@0x%08x)",
+                        newTitle, newTitle.getClass(), newTitle.hashCode()));
+            }
             return true;
         }
-        if (!Objects.equals(oldN.extras.get(Notification.EXTRA_TEXT),
-                newN.extras.get(Notification.EXTRA_TEXT))) {
+        // Do not compare Spannables (will always return false); compare unstyled Strings
+        final String oldText = String.valueOf(oldN.extras.get(Notification.EXTRA_TEXT));
+        final String newText = String.valueOf(newN.extras.get(Notification.EXTRA_TEXT));
+        if (!Objects.equals(oldText, newText)) {
+            if (DEBUG_INTERRUPTIVENESS) {
+                Log.v(TAG, "INTERRUPTIVENESS: "
+                        + r.getKey() + " is interruptive: changed text");
+                Log.v(TAG, "INTERRUPTIVENESS: " + String.format("   old text: %s (%s@0x%08x)",
+                        oldText, oldText.getClass(), oldText.hashCode()));
+                Log.v(TAG, "INTERRUPTIVENESS: " + String.format("   new text: %s (%s@0x%08x)",
+                        newText, newText.getClass(), newText.hashCode()));
+            }
             return true;
         }
-        if (oldN.extras.containsKey(Notification.EXTRA_PROGRESS) && newN.hasCompletedProgress()) {
+        if (oldN.hasCompletedProgress() != newN.hasCompletedProgress()) {
+            if (DEBUG_INTERRUPTIVENESS) {
+                Log.v(TAG, "INTERRUPTIVENESS: "
+                    +  r.getKey() + " is interruptive: completed progress");
+            }
             return true;
         }
         // Actions
         if (Notification.areActionsVisiblyDifferent(oldN, newN)) {
+            if (DEBUG_INTERRUPTIVENESS) {
+                Log.v(TAG, "INTERRUPTIVENESS: "
+                        +  r.getKey() + " is interruptive: changed actions");
+            }
             return true;
         }
 
@@ -4550,16 +4597,25 @@
 
             // Style based comparisons
             if (Notification.areStyledNotificationsVisiblyDifferent(oldB, newB)) {
+                if (DEBUG_INTERRUPTIVENESS) {
+                    Log.v(TAG, "INTERRUPTIVENESS: "
+                            +  r.getKey() + " is interruptive: styles differ");
+                }
                 return true;
             }
 
             // Remote views
             if (Notification.areRemoteViewsChanged(oldB, newB)) {
+                if (DEBUG_INTERRUPTIVENESS) {
+                    Log.v(TAG, "INTERRUPTIVENESS: "
+                            +  r.getKey() + " is interruptive: remoteviews differ");
+                }
                 return true;
             }
         } catch (Exception e) {
             Slog.w(TAG, "error recovering builder", e);
         }
+
         return false;
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 01f84c4..cd9efdc 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -78,6 +78,8 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageManager;
+import android.system.ErrnoException;
+import android.system.Os;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.ArraySet;
@@ -1373,7 +1375,9 @@
             try (OutputStream outStream = new FileOutputStream(outputProfilePath)) {
                 Streams.copy(inStream, outStream);
             }
-        } catch (IOException e) {
+            // Give read permissions to the other group.
+            Os.chmod(outputProfilePath, /*mode*/ 0644 );
+        } catch (IOException | ErrnoException e) {
             pw.println("Error when reading the profile fd: " + e.getMessage());
             e.printStackTrace(pw);
             return -1;
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index c9aa1ef..1ae59cb 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -833,11 +833,11 @@
                     getSystemPackage(textClassifierPackageName);
             if (textClassifierPackage != null
                     && doesPackageSupportRuntimePermissions(textClassifierPackage)) {
-                grantRuntimePermissions(textClassifierPackage, PHONE_PERMISSIONS, true, userId);
-                grantRuntimePermissions(textClassifierPackage, SMS_PERMISSIONS, true, userId);
-                grantRuntimePermissions(textClassifierPackage, CALENDAR_PERMISSIONS, true, userId);
-                grantRuntimePermissions(textClassifierPackage, LOCATION_PERMISSIONS, true, userId);
-                grantRuntimePermissions(textClassifierPackage, CONTACTS_PERMISSIONS, true, userId);
+                grantRuntimePermissions(textClassifierPackage, PHONE_PERMISSIONS, false, userId);
+                grantRuntimePermissions(textClassifierPackage, SMS_PERMISSIONS, false, userId);
+                grantRuntimePermissions(textClassifierPackage, CALENDAR_PERMISSIONS, false, userId);
+                grantRuntimePermissions(textClassifierPackage, LOCATION_PERMISSIONS, false, userId);
+                grantRuntimePermissions(textClassifierPackage, CONTACTS_PERMISSIONS, false, userId);
             }
         }
 
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 16440c8..d911761 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -267,6 +267,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.policy.IShortcutService;
 import com.android.internal.policy.KeyguardDismissCallback;
@@ -621,6 +622,7 @@
     boolean mUseTvRouting;
     int mVeryLongPressTimeout;
     boolean mAllowStartActivityForLongPressOnPowerDuringSetup;
+    MetricsLogger mLogger;
 
     private boolean mHandleVolumeKeysInWM;
 
@@ -929,7 +931,7 @@
                     accessibilityShortcutActivated();
                     break;
                 case MSG_BUGREPORT_TV:
-                    takeBugreport();
+                    requestFullBugreport();
                     break;
                 case MSG_ACCESSIBILITY_TV:
                     if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(false)) {
@@ -1136,6 +1138,8 @@
         }
         getAudioManagerInternal();
         mAudioManagerInternal.silenceRingerModeInternal("volume_hush");
+        Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.HUSH_GESTURE_USED, 1);
+        mLogger.action(MetricsProto.MetricsEvent.ACTION_HUSH_GESTURE, mRingerToggleChord);
     }
 
     IStatusBarService getStatusBarService() {
@@ -2003,6 +2007,7 @@
         mHasFeatureLeanback = mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK);
         mAccessibilityShortcutController =
                 new AccessibilityShortcutController(mContext, new Handler(), mCurrentUserId);
+        mLogger = new MetricsLogger();
         // Init display burn-in protection
         boolean burnInProtectionEnabled = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_enableBurnInProtection);
@@ -4104,13 +4109,13 @@
         return mAccessibilityTvScheduled;
     }
 
-    private void takeBugreport() {
+    private void requestFullBugreport() {
         if ("1".equals(SystemProperties.get("ro.debuggable"))
                 || Settings.Global.getInt(mContext.getContentResolver(),
                         Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) == 1) {
             try {
                 ActivityManager.getService()
-                        .requestBugReport(ActivityManager.BUGREPORT_OPTION_INTERACTIVE);
+                        .requestBugReport(ActivityManager.BUGREPORT_OPTION_FULL);
             } catch (RemoteException e) {
                 Slog.e(TAG, "Error taking bugreport", e);
             }
@@ -5078,7 +5083,7 @@
         final int fl = PolicyControl.getWindowFlags(win, attrs);
         final int pfl = attrs.privateFlags;
         final int sim = attrs.softInputMode;
-        final int requestedSysUiFl = PolicyControl.getSystemUiVisibility(win, null);
+        final int requestedSysUiFl = PolicyControl.getSystemUiVisibility(null, attrs);
         final int sysUiFl = requestedSysUiFl | getImpliedSysUiFlagsForLayout(attrs);
 
         final Rect pf = mTmpParentFrame;
diff --git a/services/core/java/com/android/server/policy/PolicyControl.java b/services/core/java/com/android/server/policy/PolicyControl.java
index 3f26d86..48e72bc 100644
--- a/services/core/java/com/android/server/policy/PolicyControl.java
+++ b/services/core/java/com/android/server/policy/PolicyControl.java
@@ -65,7 +65,8 @@
 
     public static int getSystemUiVisibility(WindowState win, LayoutParams attrs) {
         attrs = attrs != null ? attrs : win.getAttrs();
-        int vis = win != null ? win.getSystemUiVisibility() : attrs.systemUiVisibility;
+        int vis = win != null ? win.getSystemUiVisibility()
+                : (attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility);
         if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
             vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                     | View.SYSTEM_UI_FLAG_FULLSCREEN
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index a492672..eecf17a 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -25,6 +25,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.hardware.input.InputManagerInternal;
+import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.Ringtone;
 import android.media.RingtoneManager;
@@ -40,20 +41,21 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
 import android.os.WorkSource;
 import android.provider.Settings;
 import android.util.EventLog;
 import android.util.Slog;
 import android.view.inputmethod.InputMethodManagerInternal;
 
-import com.android.internal.app.IAppOpsService;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.server.EventLogTags;
 import com.android.server.LocalServices;
-import com.android.server.statusbar.StatusBarManagerInternal;
 import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.statusbar.StatusBarManagerInternal;
 
 /**
  * Sends broadcasts about important power state changes.
@@ -88,6 +90,21 @@
     private static final int MSG_PROFILE_TIMED_OUT = 5;
     private static final int MSG_WIRED_CHARGING_STARTED = 6;
 
+    private static final long[] WIRELESS_VIBRATION_TIME = {
+            40, 40, 40, 40, 40, 40, 40, 40, 40, // ramp-up sampling rate = 40ms
+            40, 40, 40, 40, 40, 40, 40 // ramp-down sampling rate = 40ms
+    };
+    private static final int[] WIRELESS_VIBRATION_AMPLITUDE = {
+            1, 4, 11, 25, 44, 67, 91, 114, 123, // ramp-up amplitude (from 0 to 50%)
+            103, 79, 55, 34, 17, 7, 2 // ramp-up amplitude
+    };
+    private static final VibrationEffect WIRELESS_CHARGING_VIBRATION_EFFECT =
+            VibrationEffect.createWaveform(WIRELESS_VIBRATION_TIME, WIRELESS_VIBRATION_AMPLITUDE,
+                    -1);
+    private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
+            .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+            .build();
+
     private final Object mLock = new Object();
 
     private final Context mContext;
@@ -100,6 +117,7 @@
     private final InputMethodManagerInternal mInputMethodManagerInternal;
     @Nullable private final StatusBarManagerInternal mStatusBarManagerInternal;
     private final TrustManager mTrustManager;
+    private final Vibrator mVibrator;
 
     private final NotifierHandler mHandler;
     private final Intent mScreenOnIntent;
@@ -146,6 +164,7 @@
         mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
         mStatusBarManagerInternal = LocalServices.getService(StatusBarManagerInternal.class);
         mTrustManager = mContext.getSystemService(TrustManager.class);
+        mVibrator = mContext.getSystemService(Vibrator.class);
 
         mHandler = new NotifierHandler(looper);
         mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
@@ -719,14 +738,9 @@
      * Plays the wireless charging sound for both wireless and non-wireless charging
      */
     private void playChargingStartedSound() {
-        final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.CHARGING_SOUNDS_ENABLED, 1) != 0;
-        final boolean dndOff = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
-                == Settings.Global.ZEN_MODE_OFF;
         final String soundPath = Settings.Global.getString(mContext.getContentResolver(),
                 Settings.Global.CHARGING_STARTED_SOUND);
-        if (enabled && dndOff && soundPath != null) {
+        if (isChargingFeedbackEnabled() && soundPath != null) {
             final Uri soundUri = Uri.parse("file://" + soundPath);
             if (soundUri != null) {
                 final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
@@ -739,6 +753,7 @@
     }
 
     private void showWirelessChargingStarted(int batteryLevel) {
+        playWirelessChargingVibration();
         playChargingStartedSound();
         if (mStatusBarManagerInternal != null) {
             mStatusBarManagerInternal.showChargingAnimation(batteryLevel);
@@ -755,6 +770,23 @@
         mTrustManager.setDeviceLockedForUser(userId, true /*locked*/);
     }
 
+    private void playWirelessChargingVibration() {
+        final boolean vibrateEnabled = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.CHARGING_VIBRATION_ENABLED, 0) != 0;
+        if (vibrateEnabled && isChargingFeedbackEnabled()) {
+            mVibrator.vibrate(WIRELESS_CHARGING_VIBRATION_EFFECT, VIBRATION_ATTRIBUTES);
+        }
+    }
+
+    private boolean isChargingFeedbackEnabled() {
+        final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.CHARGING_SOUNDS_ENABLED, 1) != 0;
+        final boolean dndOff = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
+                == Settings.Global.ZEN_MODE_OFF;
+        return enabled && dndOff;
+    }
+
     private final class NotifierHandler extends Handler {
 
         public NotifierHandler(Looper looper) {
@@ -780,6 +812,7 @@
                     break;
                 case MSG_WIRED_CHARGING_STARTED:
                     showWiredChargingStarted();
+                    break;
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index f5f994a..a6ec3cf 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -674,6 +674,7 @@
                 mTempLayer = 0;
                 dc.forAllWindows((w) -> {
                     if (w.isOnScreen() && w.isVisibleLw()
+                            && (w.mAttrs.alpha != 0)
                             && !w.mWinAnimator.mEnterAnimationPending) {
                         mTempLayer++;
                         outWindows.put(mTempLayer, w);
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 39a3629..cd8d677 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -692,7 +692,7 @@
 
         // Do not minimize when dock is already minimized while keyguard is showing and not
         // occluded such as unlocking the screen
-        if (mMinimizedDock && mService.mPolicy.isKeyguardShowingAndNotOccluded()) {
+        if (mMinimizedDock && mService.mKeyguardOrAodShowingOnDefaultDisplay) {
             return;
         }
         final TaskStack topSecondaryStack = mDisplayContent.getTopStackInWindowingMode(
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 891ee2e..2fbb846 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -800,34 +800,7 @@
     }
 
     private void updateBoundsForWindowModeChange() {
-        Rect bounds = null;
-        final boolean inSplitScreenPrimary = inSplitScreenPrimaryWindowingMode();
-        final TaskStack splitScreenStack =
-                mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
-        if (inSplitScreenPrimary || (splitScreenStack != null
-                && inSplitScreenSecondaryWindowingMode() && !splitScreenStack.fillsParent())) {
-            // The existence of a docked stack affects the size of other static stack created since
-            // the docked stack occupies a dedicated region on screen, but only if the dock stack is
-            // not fullscreen. If it's fullscreen, it means that we are in the transition of
-            // dismissing it, so we must not resize this stack.
-            bounds = new Rect();
-            mDisplayContent.getBounds(mTmpRect);
-            mTmpRect2.setEmpty();
-            if (splitScreenStack != null) {
-                splitScreenStack.getRawBounds(mTmpRect2);
-            }
-            final boolean dockedOnTopOrLeft = mService.mDockedStackCreateMode
-                    == SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
-            getStackDockedModeBounds(mTmpRect, bounds, mTmpRect2,
-                    mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
-        } else if (inPinnedWindowingMode()) {
-            // Update the bounds based on any changes to the display info
-            getAnimationOrCurrentBounds(mTmpRect2);
-            if (mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(
-                    mTmpRect2, mTmpRect3)) {
-                bounds = new Rect(mTmpRect3);
-            }
-        }
+        final Rect bounds = calculateBoundsForWindowModeChange();
 
         if (inSplitScreenSecondaryWindowingMode()) {
             // When the stack is resized due to entering split screen secondary, offset the
@@ -841,6 +814,49 @@
         updateSurfaceBounds();
     }
 
+    private Rect calculateBoundsForWindowModeChange() {
+        final boolean inSplitScreenPrimary = inSplitScreenPrimaryWindowingMode();
+        final TaskStack splitScreenStack =
+                mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
+        if (inSplitScreenPrimary || (splitScreenStack != null
+                && inSplitScreenSecondaryWindowingMode() && !splitScreenStack.fillsParent())) {
+            // The existence of a docked stack affects the size of other static stack created since
+            // the docked stack occupies a dedicated region on screen, but only if the dock stack is
+            // not fullscreen. If it's fullscreen, it means that we are in the transition of
+            // dismissing it, so we must not resize this stack.
+            final Rect bounds = new Rect();
+            mDisplayContent.getBounds(mTmpRect);
+            mTmpRect2.setEmpty();
+            if (splitScreenStack != null) {
+                if (inSplitScreenSecondaryWindowingMode()
+                        && mDisplayContent.mDividerControllerLocked.isMinimizedDock()
+                        && splitScreenStack.getTopChild() != null) {
+                    // If the primary split screen stack is currently minimized, then don't use the
+                    // stack bounds of the minimized stack, instead, use the temporary task bounds
+                    // to calculate the appropriate uniminized size of any secondary split stack
+                    // TODO: Find a cleaner way for computing new stack bounds while minimized that
+                    //       doesn't assume the primary stack's task bounds as the temp task bounds
+                    splitScreenStack.getTopChild().getBounds(mTmpRect2);
+                } else {
+                    splitScreenStack.getRawBounds(mTmpRect2);
+                }
+            }
+            final boolean dockedOnTopOrLeft = mService.mDockedStackCreateMode
+                    == SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
+            getStackDockedModeBounds(mTmpRect, bounds, mTmpRect2,
+                    mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
+            return bounds;
+        } else if (inPinnedWindowingMode()) {
+            // Update the bounds based on any changes to the display info
+            getAnimationOrCurrentBounds(mTmpRect2);
+            if (mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(
+                    mTmpRect2, mTmpRect3)) {
+                return new Rect(mTmpRect3);
+            }
+        }
+        return null;
+    }
+
     /**
      * Determines the stack and task bounds of the other stack when in docked mode. The current task
      * bounds is passed in but depending on the stack, the task and stack must match. Only in
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index 990eb97..c366e4d 100644
--- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
@@ -74,9 +74,8 @@
     static final boolean SHOW_STACK_CRAWLS = false;
     static final boolean DEBUG_WINDOW_CROP = false;
     static final boolean DEBUG_UNKNOWN_APP_VISIBILITY = false;
-    // TODO (b/73188263): Reset debugging flags
-    static final boolean DEBUG_RECENTS_ANIMATIONS = true;
-    static final boolean DEBUG_REMOTE_ANIMATIONS = DEBUG_APP_TRANSITIONS || true;
+    static final boolean DEBUG_RECENTS_ANIMATIONS = false;
+    static final boolean DEBUG_REMOTE_ANIMATIONS = DEBUG_APP_TRANSITIONS || false;
 
     static final String TAG_KEEP_SCREEN_ON = "DebugKeepScreenOn";
     static final boolean DEBUG_KEEP_SCREEN_ON = false;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 16399008..cb64142 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -369,7 +369,10 @@
     final WindowTracing mWindowTracing;
 
     final private KeyguardDisableHandler mKeyguardDisableHandler;
+    // TODO: eventually unify all keyguard state in a common place instead of having it spread over
+    // AM's KeyguardController and the policy's KeyguardServiceDelegate.
     boolean mKeyguardGoingAway;
+    boolean mKeyguardOrAodShowingOnDefaultDisplay;
     // VR Vr2d Display Id.
     int mVr2dDisplayId = INVALID_DISPLAY;
 
@@ -2909,6 +2912,12 @@
         }
     }
 
+    public void setKeyguardOrAodShowingOnDefaultDisplay(boolean showing) {
+        synchronized (mWindowMap) {
+            mKeyguardOrAodShowingOnDefaultDisplay = showing;
+        }
+    }
+
     // -------------------------------------------------------------
     // Misc IWindowSession methods
     // -------------------------------------------------------------
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 91c449b..dac85b3 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -409,7 +409,7 @@
 
     final Rect mContainingFrame = new Rect();
 
-    private final Rect mParentFrame = new Rect();
+    final Rect mParentFrame = new Rect();
 
     /** Whether the parent frame would have been different if there was no display cutout. */
     private boolean mParentFrameWasClippedByDisplayCutout;
@@ -931,6 +931,17 @@
                     mContainingFrame.set(contentFrame);
                 }
             }
+
+            final TaskStack stack = getStack();
+            if (inPinnedWindowingMode() && stack != null
+                    && stack.lastAnimatingBoundsWasToFullscreen()) {
+                // PIP edge case: When going from pinned to fullscreen, we apply a
+                // tempInsetFrame for the full task - but we're still at the start of the animation.
+                // To prevent a jump if there's a letterbox, restrict to the parent frame.
+                mInsetFrame.intersectUnchecked(parentFrame);
+                mContainingFrame.intersectUnchecked(parentFrame);
+            }
+
             mDisplayFrame.set(mContainingFrame);
             layoutXDiff = !mInsetFrame.isEmpty() ? mInsetFrame.left - mContainingFrame.left : 0;
             layoutYDiff = !mInsetFrame.isEmpty() ? mInsetFrame.top - mContainingFrame.top : 0;
@@ -4404,14 +4415,6 @@
 
         result |= (!wasVisible || !isDrawnLw()) ? RELAYOUT_RES_FIRST_TIME : 0;
 
-        if (mWinAnimator.mChildrenDetached) {
-            // If there are detached children hanging around we need to force
-            // the client receiving a new Surface.
-            mWinAnimator.preserveSurfaceLocked();
-            result |= RELAYOUT_RES_SURFACE_CHANGED
-                    | RELAYOUT_RES_FIRST_TIME;
-        }
-
         if (mAnimatingExit) {
             Slog.d(TAG, "relayoutVisibleWindow: " + this + " mAnimatingExit=true, mRemoveOnExit="
                     + mRemoveOnExit + ", mDestroying=" + mDestroying);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 4a6587b..3eef125 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -927,6 +927,13 @@
                 mTmpSourceBounds.inset(mWin.mLastRelayoutContentInsets);
                 allowStretching = true;
             }
+
+            // Make sure that what we're animating to and from is actually the right size in case
+            // the window cannot take up the full screen.
+            mTmpStackBounds.intersectUnchecked(w.mParentFrame);
+            mTmpSourceBounds.intersectUnchecked(w.mParentFrame);
+            mTmpAnimatingBounds.intersectUnchecked(w.mParentFrame);
+
             if (!mTmpSourceBounds.isEmpty()) {
                 // Get the final target stack bounds, if we are not animating, this is just the
                 // current stack bounds
@@ -1291,6 +1298,7 @@
         // if we are transparent.
         if (mPendingDestroySurface != null && mDestroyPreservedSurfaceUponRedraw) {
             mPendingDestroySurface.mSurfaceControl.hide();
+            mPendingDestroySurface.reparentChildrenInTransaction(mSurfaceController);
         }
 
         return true;
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 22bec44..2ac9df9 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -52,6 +52,7 @@
     <uses-permission android:name="android.permission.DELETE_PACKAGES" />
     <uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
     <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
+    <uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES"/>
     <uses-permission android:name="android.permission.DEVICE_POWER" />
     <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES" />
     <uses-permission android:name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST" />
diff --git a/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java b/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
index 24d925f..a2ccee4 100644
--- a/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
@@ -159,7 +159,12 @@
 
         updateWindow(decorWindow, TOP, MATCH_PARENT, mDecorThickness,
                 0, PRIVATE_FLAG_IS_SCREEN_DECOR);
-        assertTopInsetEquals(mTestActivity, initialInsets.getSystemWindowInsetTop());
+
+        // TODO: fix test and re-enable assertion.
+        // initialInsets was not actually immutable and just updated to the current insets,
+        // meaning this assertion never actually tested anything. Now that WindowInsets actually is
+        // immutable, it turns out the test was broken.
+        // assertTopInsetEquals(mTestActivity, initialInsets.getSystemWindowInsetTop());
 
         updateWindow(decorWindow, TOP, MATCH_PARENT, mDecorThickness,
                 PRIVATE_FLAG_IS_SCREEN_DECOR, PRIVATE_FLAG_IS_SCREEN_DECOR);
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 376cc64..3dde7f1 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -104,6 +104,7 @@
 import android.testing.TestableContext;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
+import android.text.Html;
 import android.util.ArrayMap;
 import android.util.AtomicFile;
 
@@ -2731,6 +2732,56 @@
     }
 
     @Test
+    public void testVisualDifference_inboxStyle() {
+        Notification.Builder nb1 = new Notification.Builder(mContext, "")
+                .setStyle(new Notification.InboxStyle()
+                    .addLine("line1").addLine("line2"));
+        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb1.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r1 =
+                new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
+
+        Notification.Builder nb2 = new Notification.Builder(mContext, "")
+                .setStyle(new Notification.InboxStyle()
+                        .addLine("line1").addLine("line2_changed"));
+        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb2.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r2 =
+                new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
+
+        assertTrue(mService.isVisuallyInterruptive(r1, r2)); // line 2 changed unnoticed
+
+        Notification.Builder nb3 = new Notification.Builder(mContext, "")
+                .setStyle(new Notification.InboxStyle()
+                        .addLine("line1"));
+        StatusBarNotification sbn3 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb3.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r3 =
+                new NotificationRecord(mContext, sbn3, mock(NotificationChannel.class));
+
+        assertTrue(mService.isVisuallyInterruptive(r1, r3)); // line 2 removed unnoticed
+
+        Notification.Builder nb4 = new Notification.Builder(mContext, "")
+                .setStyle(new Notification.InboxStyle()
+                        .addLine("line1").addLine("line2").addLine("line3"));
+        StatusBarNotification sbn4 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb4.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r4 =
+                new NotificationRecord(mContext, sbn4, mock(NotificationChannel.class));
+
+        assertTrue(mService.isVisuallyInterruptive(r1, r4)); // line 3 added unnoticed
+
+        Notification.Builder nb5 = new Notification.Builder(mContext, "")
+            .setContentText("not an inbox");
+        StatusBarNotification sbn5 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb5.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r5 =
+                new NotificationRecord(mContext, sbn5, mock(NotificationChannel.class));
+
+        assertTrue(mService.isVisuallyInterruptive(r1, r5)); // changed Styles, went unnoticed
+    }
+
+    @Test
     public void testVisualDifference_diffText() {
         Notification.Builder nb1 = new Notification.Builder(mContext, "")
                 .setContentText("foo");
@@ -2750,6 +2801,63 @@
     }
 
     @Test
+    public void testVisualDifference_sameText() {
+        Notification.Builder nb1 = new Notification.Builder(mContext, "")
+                .setContentText("foo");
+        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb1.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r1 =
+                new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
+
+        Notification.Builder nb2 = new Notification.Builder(mContext, "")
+                .setContentText("foo");
+        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb2.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r2 =
+                new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
+
+        assertFalse(mService.isVisuallyInterruptive(r1, r2));
+    }
+
+    @Test
+    public void testVisualDifference_sameTextButStyled() {
+        Notification.Builder nb1 = new Notification.Builder(mContext, "")
+                .setContentText(Html.fromHtml("<b>foo</b>"));
+        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb1.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r1 =
+                new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
+
+        Notification.Builder nb2 = new Notification.Builder(mContext, "")
+                .setContentText(Html.fromHtml("<b>foo</b>"));
+        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb2.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r2 =
+                new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
+
+        assertFalse(mService.isVisuallyInterruptive(r1, r2));
+    }
+
+    @Test
+    public void testVisualDifference_diffTextButStyled() {
+        Notification.Builder nb1 = new Notification.Builder(mContext, "")
+                .setContentText(Html.fromHtml("<b>foo</b>"));
+        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb1.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r1 =
+                new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
+
+        Notification.Builder nb2 = new Notification.Builder(mContext, "")
+                .setContentText(Html.fromHtml("<b>bar</b>"));
+        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb2.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r2 =
+                new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
+
+        assertTrue(mService.isVisuallyInterruptive(r1, r2));
+    }
+
+    @Test
     public void testVisualDifference_diffProgress() {
         Notification.Builder nb1 = new Notification.Builder(mContext, "")
                 .setProgress(100, 90, false);
@@ -2788,6 +2896,25 @@
     }
 
     @Test
+    public void testVisualDifference_sameProgressStillDone() {
+        Notification.Builder nb1 = new Notification.Builder(mContext, "")
+                .setProgress(100, 100, false);
+        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb1.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r1 =
+                new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
+
+        Notification.Builder nb2 = new Notification.Builder(mContext, "")
+                .setProgress(100, 100, false);
+        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+                nb2.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord r2 =
+                new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
+
+        assertFalse(mService.isVisuallyInterruptive(r1, r2));
+    }
+
+    @Test
     public void testHideAndUnhideNotificationsOnSuspendedPackageBroadcast() {
         // post 2 notification from this package
         final NotificationRecord notif1 = generateNotificationRecord(
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java
index 36ec221..975fbcc 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java
@@ -221,10 +221,15 @@
 
     @Test
     public void testBigPictureChange() {
+        Bitmap bitA = mock(Bitmap.class);
+        when(bitA.getGenerationId()).thenReturn(100);
+        Bitmap bitB = mock(Bitmap.class);
+        when(bitB.getGenerationId()).thenReturn(200);
+
         Notification.Builder nBigPic1 = new Notification.Builder(mContext, "test")
-                .setStyle(new Notification.BigPictureStyle().bigPicture(mock(Bitmap.class)));
+                .setStyle(new Notification.BigPictureStyle().bigPicture(bitA));
         Notification.Builder nBigPic2 = new Notification.Builder(mContext, "test")
-                .setStyle(new Notification.BigPictureStyle().bigPicture(mock(Bitmap.class)));
+                .setStyle(new Notification.BigPictureStyle().bigPicture(bitB));
 
         assertTrue(Notification.areStyledNotificationsVisiblyDifferent(nBigPic1, nBigPic2));
     }
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 243718a..71f9bb3 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -585,6 +585,9 @@
                         flushToDiskLocked();
                         pw.println("Flushed stats to disk");
                         return;
+                    } else if ("is-app-standby-enabled".equals(arg)) {
+                        pw.println(mAppStandby.mAppIdleEnabled);
+                        return;
                     } else if (arg != null && !arg.startsWith("-")) {
                         // Anything else that doesn't start with '-' is a pkg to filter
                         pkg = arg;
diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java
index ce444dd..d2001ae 100644
--- a/telephony/java/android/telephony/PhysicalChannelConfig.java
+++ b/telephony/java/android/telephony/PhysicalChannelConfig.java
@@ -99,6 +99,20 @@
         return mCellConnectionStatus;
     }
 
+    /** @return String representation of the connection status */
+    private String getConnectionStatusString() {
+        switch(mCellConnectionStatus) {
+            case CONNECTION_PRIMARY_SERVING:
+                return "PrimaryServing";
+            case CONNECTION_SECONDARY_SERVING:
+                return "SecondaryServing";
+            case CONNECTION_UNKNOWN:
+                return "Unknown";
+            default:
+                return "Invalid(" + mCellConnectionStatus + ")";
+        }
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) {
@@ -129,4 +143,15 @@
                 return new PhysicalChannelConfig[size];
             }
         };
+
+    @Override
+    public String toString() {
+        return new StringBuilder()
+            .append("{mConnectionStatus=")
+            .append(getConnectionStatusString())
+            .append(",mCellBandwidthDownlinkKhz=")
+            .append(mCellBandwidthDownlinkKhz)
+            .append("}")
+            .toString();
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index d25fd3f..49fbd8f 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -477,4 +477,5 @@
     int RIL_UNSOL_NETWORK_SCAN_RESULT = 1049;
     int RIL_UNSOL_ICC_SLOT_STATUS = 1050;
     int RIL_UNSOL_KEEPALIVE_STATUS = 1051;
+    int RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG = 1052;
 }
diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
index 1ec4eec..01b468a 100644
--- a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
@@ -19,6 +19,9 @@
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+import static android.provider.Settings.Global.PRIVATE_DNS_DEFAULT_MODE;
+import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
+import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -40,6 +43,7 @@
 import android.test.mock.MockContentResolver;
 
 import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.server.connectivity.DnsManager.PrivateDnsConfig;
 import com.android.server.connectivity.MockableSystemProperties;
 
 import java.net.InetAddress;
@@ -84,10 +88,9 @@
         mDnsManager = new DnsManager(mCtx, mNMService, mSystemProperties);
 
         // Clear the private DNS settings
-        Settings.Global.putString(mContentResolver,
-                Settings.Global.PRIVATE_DNS_MODE, "");
-        Settings.Global.putString(mContentResolver,
-                Settings.Global.PRIVATE_DNS_SPECIFIER, "");
+        Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, "");
+        Settings.Global.putString(mContentResolver, PRIVATE_DNS_MODE, "");
+        Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "");
     }
 
     @Test
@@ -127,9 +130,8 @@
                 TEST_IFACENAME));
 
         Settings.Global.putString(mContentResolver,
-                Settings.Global.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
-        Settings.Global.putString(mContentResolver,
-                Settings.Global.PRIVATE_DNS_SPECIFIER, "strictmode.com");
+                PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+        Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "strictmode.com");
         mDnsManager.updatePrivateDns(new Network(TEST_NETID),
                 new DnsManager.PrivateDnsConfig("strictmode.com", new InetAddress[] {
                     InetAddress.parseNumericAddress("6.6.6.6"),
@@ -222,8 +224,7 @@
         assertNull(lp.getPrivateDnsServerName());
 
         // Turn private DNS mode off
-        Settings.Global.putString(mContentResolver,
-                Settings.Global.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OFF);
+        Settings.Global.putString(mContentResolver, PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OFF);
         mDnsManager.updatePrivateDns(new Network(TEST_NETID),
                 mDnsManager.getPrivateDnsConfig());
         mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
@@ -234,4 +235,29 @@
         assertFalse(lp.isPrivateDnsActive());
         assertNull(lp.getPrivateDnsServerName());
     }
+
+    @Test
+    public void testOverrideDefaultMode() throws Exception {
+        // Hard-coded default is opportunistic mode.
+        final PrivateDnsConfig cfgAuto = DnsManager.getPrivateDnsConfig(mContentResolver);
+        assertTrue(cfgAuto.useTls);
+        assertEquals("", cfgAuto.hostname);
+        assertEquals(new InetAddress[0], cfgAuto.ips);
+
+        // Pretend a gservices push sets the default to "off".
+        Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, "off");
+        final PrivateDnsConfig cfgOff = DnsManager.getPrivateDnsConfig(mContentResolver);
+        assertFalse(cfgOff.useTls);
+        assertEquals("", cfgOff.hostname);
+        assertEquals(new InetAddress[0], cfgOff.ips);
+
+        // Strict mode still works.
+        Settings.Global.putString(
+                mContentResolver, PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+        Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "strictmode.com");
+        final PrivateDnsConfig cfgStrict = DnsManager.getPrivateDnsConfig(mContentResolver);
+        assertTrue(cfgStrict.useTls);
+        assertEquals("strictmode.com", cfgStrict.hostname);
+        assertEquals(new InetAddress[0], cfgStrict.ips);
+    }
 }
diff --git a/tests/testables/src/android/testing/TestableInstrumentation.java b/tests/testables/src/android/testing/TestableInstrumentation.java
index 93fed85..3207b48 100644
--- a/tests/testables/src/android/testing/TestableInstrumentation.java
+++ b/tests/testables/src/android/testing/TestableInstrumentation.java
@@ -77,7 +77,7 @@
         private TestLooperManager mManager;
 
         public MainLooperManager() {
-            mMainHandler = new Handler(Looper.getMainLooper());
+            mMainHandler = Handler.createAsync(Looper.getMainLooper());
             startManaging();
         }
 
diff --git a/tests/testables/src/android/testing/TestableLooper.java b/tests/testables/src/android/testing/TestableLooper.java
index f1a7092..f8d223a 100644
--- a/tests/testables/src/android/testing/TestableLooper.java
+++ b/tests/testables/src/android/testing/TestableLooper.java
@@ -51,12 +51,12 @@
         this(acquireLooperManager(l), l);
     }
 
-    private TestableLooper(TestLooperManager wrapper, Looper l) throws Exception {
+    private TestableLooper(TestLooperManager wrapper, Looper l) {
         mQueueWrapper = wrapper;
         setupQueue(l);
     }
 
-    private TestableLooper(Looper looper, boolean b) throws Exception {
+    private TestableLooper(Looper looper, boolean b) {
         setupQueue(looper);
     }
 
@@ -64,7 +64,7 @@
         return mLooper;
     }
 
-    private void setupQueue(Looper l) throws Exception {
+    private void setupQueue(Looper l) {
         mLooper = l;
         mQueue = mLooper.getQueue();
         mHandler = new Handler(mLooper);
@@ -75,7 +75,7 @@
      * the looper will not be available for any subsequent tests. This is
      * automatically handled for tests using {@link RunWithLooper}.
      */
-    public void destroy() throws NoSuchFieldException, IllegalAccessException {
+    public void destroy() {
         mQueueWrapper.release();
         if (mLooper == Looper.getMainLooper()) {
             TestableInstrumentation.releaseMain();
@@ -133,7 +133,7 @@
 
                 if (mMessageHandler != null) {
                     if (mMessageHandler.onMessageHandled(result)) {
-                        result.getTarget().dispatchMessage(result);
+                        mQueueWrapper.execute(result);
                         mQueueWrapper.recycle(result);
                     } else {
                         mQueueWrapper.recycle(result);
@@ -141,7 +141,7 @@
                         return false;
                     }
                 } else {
-                    result.getTarget().dispatchMessage(result);
+                    mQueueWrapper.execute(result);
                     mQueueWrapper.recycle(result);
                 }
             } else {
@@ -238,7 +238,7 @@
             super(base.getMethod());
             mLooper = other.mLooper;
             mTestableLooper = other;
-            mHandler = new Handler(mLooper);
+            mHandler = Handler.createAsync(mLooper);
         }
 
         public static FrameworkMethod get(FrameworkMethod base, boolean setAsMain, Object test) {
diff --git a/tests/testables/tests/src/android/testing/TestableLooperTest.java b/tests/testables/tests/src/android/testing/TestableLooperTest.java
index 13e72ba..25f6a488 100644
--- a/tests/testables/tests/src/android/testing/TestableLooperTest.java
+++ b/tests/testables/tests/src/android/testing/TestableLooperTest.java
@@ -16,6 +16,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
@@ -158,4 +159,22 @@
     public void testMainLooperAnnotation() {
         assertEquals(Looper.myLooper(), Looper.getMainLooper());
     }
+
+    @Test
+    public void testCorrectLooperExecution() throws Exception {
+        boolean[] hasRun = new boolean[] { false };
+        Runnable r = () -> {
+            assertEquals("Should run on main looper", Looper.getMainLooper(), Looper.myLooper());
+            hasRun[0] = true;
+        };
+        TestableLooper testableLooper = new TestableLooper(Looper.getMainLooper());
+        try {
+            new Handler(Looper.getMainLooper()).post(r);
+            testableLooper.processAllMessages();
+
+            assertTrue(hasRun[0]);
+        } finally {
+            testableLooper.destroy();
+        }
+    }
 }
diff --git a/tools/fonts/fontchain_linter.py b/tools/fonts/fontchain_linter.py
index ffca466..a8411aa 100755
--- a/tools/fonts/fontchain_linter.py
+++ b/tools/fonts/fontchain_linter.py
@@ -486,12 +486,8 @@
     return tuple(0x1F1E6 + ord(ch) - ord('A') for ch in territory_code)
 
 UNSUPPORTED_FLAGS = frozenset({
-    flag_sequence('BL'), flag_sequence('BQ'), flag_sequence('DG'),
-    flag_sequence('EA'), flag_sequence('EH'), flag_sequence('FK'),
-    flag_sequence('GF'), flag_sequence('GP'), flag_sequence('GS'),
-    flag_sequence('MF'), flag_sequence('MQ'), flag_sequence('NC'),
-    flag_sequence('PM'), flag_sequence('RE'), flag_sequence('TF'),
-    flag_sequence('WF'), flag_sequence('XK'), flag_sequence('YT'),
+    flag_sequence('BL'), flag_sequence('BQ'), flag_sequence('MQ'),
+    flag_sequence('RE'), flag_sequence('TF'),
 })
 
 EQUIVALENT_FLAGS = {
@@ -531,10 +527,17 @@
 ZWJ_IDENTICALS = {
     # KISS
     (0x1F469, 0x200D, 0x2764, 0x200D, 0x1F48B, 0x200D, 0x1F468): 0x1F48F,
-    # FAMILY
-    (0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F466): 0x1F46A,
 }
 
+SAME_FLAG_MAPPINGS = [
+    # Diego Garcia and British Indian Ocean Territory
+    ((0x1F1EE, 0x1F1F4), (0x1F1E9, 0x1F1EC)),
+    # St. Martin and France
+    ((0x1F1F2, 0x1F1EB), (0x1F1EB, 0x1F1F7)),
+    # Spain and Ceuta & Melilla
+    ((0x1F1EA, 0x1F1F8), (0x1F1EA, 0x1F1E6)),
+]
+
 ZWJ = 0x200D
 FEMALE_SIGN = 0x2640
 MALE_SIGN = 0x2642
@@ -636,6 +639,9 @@
         all_sequences.add(reversed_seq)
         equivalent_emoji[reversed_seq] = sequence
 
+    for first, second in SAME_FLAG_MAPPINGS:
+        equivalent_emoji[first] = second
+
     # Remove unsupported flags
     all_sequences.difference_update(UNSUPPORTED_FLAGS)
 
diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java
index 50c4b5e..9ab374a 100644
--- a/wifi/java/android/net/wifi/RttManager.java
+++ b/wifi/java/android/net/wifi/RttManager.java
@@ -995,6 +995,10 @@
                                     result.getDistanceStdDevMm() / 10;
                             legacyResults[i].rssi = result.getRssi() * -2;
                             legacyResults[i].ts = result.getRangingTimestampMillis() * 1000;
+                            legacyResults[i].measurementFrameNumber =
+                                    result.getNumAttemptedMeasurements();
+                            legacyResults[i].successMeasurementFrameNumber =
+                                    result.getNumSuccessfulMeasurements();
                         } else {
                             // just in case legacy API needed some relatively real timestamp
                             legacyResults[i].ts = SystemClock.elapsedRealtime() * 1000;