Merge "Fixes docked stack from being invisible from assistant stack over" into pi-dev
diff --git a/api/test-current.txt b/api/test-current.txt
index 5cffd0e..f1c6120 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -564,6 +564,11 @@
     field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
   }
 
+  public final class NetworkCapabilities implements android.os.Parcelable {
+    method public int[] getCapabilities();
+    method public int[] getTransportTypes();
+  }
+
   public class TrafficStats {
     method public static long getLoopbackRxBytes();
     method public static long getLoopbackRxPackets();
@@ -897,6 +902,14 @@
 
 }
 
+package android.telecom {
+
+  public final class CallAudioState implements android.os.Parcelable {
+    ctor public CallAudioState(boolean, int, int, android.bluetooth.BluetoothDevice, java.util.Collection<android.bluetooth.BluetoothDevice>);
+  }
+
+}
+
 package android.telephony {
 
   public class MbmsDownloadSession implements java.lang.AutoCloseable {
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index df8763c..136fd14 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -87,7 +87,8 @@
       mDimensionHardLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
                                           StatsdStats::kAtomDimensionKeySizeLimitMap.end()
                                   ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).second
-                                  : StatsdStats::kDimensionKeySizeHardLimit) {
+                                  : StatsdStats::kDimensionKeySizeHardLimit),
+      mUseAbsoluteValueOnReset(metric.use_absolute_value_on_reset()) {
     // TODO: valuemetric for pushed events may need unlimited bucket length
     int64_t bucketSizeMills = 0;
     if (metric.has_bucket()) {
@@ -393,15 +394,20 @@
             }
         } else {
             // Generally we expect value to be monotonically increasing.
-            // If not, there was a reset event. We take the absolute value as
-            // diff in this case.
+            // If not, take absolute value or drop it, based on config.
             if (interval.startUpdated) {
                 if (value >= interval.start) {
                     interval.sum += (value - interval.start);
+                    interval.hasValue = true;
                 } else {
-                    interval.sum += value;
+                    if (mUseAbsoluteValueOnReset) {
+                        interval.sum += value;
+                        interval.hasValue = true;
+                    } else {
+                        VLOG("Dropping data for atom %d, prev: %lld, now: %lld", mPullTagId,
+                             (long long)interval.start, (long long)value);
+                    }
                 }
-                interval.hasValue = true;
                 interval.startUpdated = false;
             } else {
                 VLOG("No start for matching end %lld", (long long)value);
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 113be4b..66afa15 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -51,7 +51,7 @@
                           const int64_t version) override {
         std::lock_guard<std::mutex> lock(mMutex);
 
-        if (mPullTagId != -1) {
+        if (mPullTagId != -1 && (mCondition == true || mConditionTrackerIndex < 0) ) {
             vector<shared_ptr<LogEvent>> allData;
             mStatsPullerManager->Pull(mPullTagId, eventTimeNs, &allData);
             if (allData.size() == 0) {
@@ -73,7 +73,9 @@
                 data->setElapsedTimestampNs(eventTimeNs);
                 onMatchedLogEventLocked(0, *data);
             }
-        } else {  // For pushed value metric, we simply flush and reset the current bucket start.
+        } else {
+            // For pushed value metric or pulled metric where condition is not true,
+            // we simply flush and reset the current bucket start.
             flushCurrentBucketLocked(eventTimeNs);
             mCurrentBucketStartTimeNs = eventTimeNs;
         }
@@ -164,10 +166,13 @@
 
     const size_t mDimensionHardLimit;
 
+    const bool mUseAbsoluteValueOnReset;
+
     FRIEND_TEST(ValueMetricProducerTest, TestNonDimensionalEvents);
     FRIEND_TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition);
     FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade);
     FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade);
+    FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse);
     FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition);
     FRIEND_TEST(ValueMetricProducerTest, TestAnomalyDetection);
     FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition);
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index 849d5f6..eb77299 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -265,6 +265,8 @@
   optional AggregationType aggregation_type = 8 [default = SUM];
 
   optional int64 min_bucket_size_nanos = 10;
+
+  optional bool use_absolute_value_on_reset = 11 [default = false];
 }
 
 message Alert {
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index 81d8892..087a612 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -308,6 +308,57 @@
     EXPECT_EQ(30L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mValue);
 }
 
+TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
+    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_condition(StringToId("SCREEN_ON"));
+
+    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());
+    EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+            .WillOnce(Invoke([](int tagId, int64_t timeNs,
+                                vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+                event->write(tagId);
+                event->write(100);
+                event->init();
+                data->push_back(event);
+                return true;
+            }))
+            .WillOnce(Invoke([](int tagId, int64_t timeNs,
+                                vector<std::shared_ptr<LogEvent>>* data) {
+                data->clear();
+                shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+                event->write(tagId);
+                event->write(120);
+                event->init();
+                data->push_back(event);
+                return true;
+            }));
+    ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
+                                      bucketStartTimeNs, pullerManager);
+    valueProducer.setBucketSize(60 * NS_PER_SEC);
+    valueProducer.onConditionChanged(true, bucketStartTimeNs + 1);
+
+    valueProducer.onConditionChanged(false, bucket2StartTimeNs-100);
+    EXPECT_FALSE(valueProducer.mCondition);
+
+    valueProducer.notifyAppUpgrade(bucket2StartTimeNs-50, "ANY.APP", 1, 1);
+    // Expect one full buckets already done and starting a partial bucket.
+    EXPECT_EQ(bucket2StartTimeNs-50, valueProducer.mCurrentBucketStartTimeNs);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    EXPECT_EQ(bucketStartTimeNs, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
+    EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mValue);
+    EXPECT_FALSE(valueProducer.mCondition);
+}
+
 TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
     ValueMetric metric;
     metric.set_id(metricId);
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 9e3a1ca..0a667cc 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
@@ -232,6 +236,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 +449,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 +531,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;
@@ -562,6 +578,7 @@
 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 +720,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 +759,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 +774,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 +847,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
@@ -903,16 +929,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 +1328,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 +1408,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 +1418,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 +1532,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 +1698,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 +1871,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 +2094,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 +2169,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
@@ -2158,9 +2226,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 +2261,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 +2279,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 +2357,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 +2393,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 +2447,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 +2637,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 +2842,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 +2853,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 +2886,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 +2923,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 +2956,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 +3086,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 +3240,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 +3257,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 +3294,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
@@ -3208,8 +3332,6 @@
 Landroid/net/NetworkCapabilities;-><init>()V
 Landroid/net/NetworkCapabilities;->addCapability(I)Landroid/net/NetworkCapabilities;
 Landroid/net/NetworkCapabilities;->addTransportType(I)Landroid/net/NetworkCapabilities;
-Landroid/net/NetworkCapabilities;->getCapabilities()[I
-Landroid/net/NetworkCapabilities;->getTransportTypes()[I
 Landroid/net/NetworkCapabilities;->mNetworkCapabilities:J
 Landroid/net/NetworkCapabilities;->mSignalStrength:I
 Landroid/net/NetworkCapabilities;->removeCapability(I)Landroid/net/NetworkCapabilities;
@@ -3306,9 +3428,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;
@@ -3367,6 +3494,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
@@ -3479,6 +3612,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;
@@ -3495,6 +3629,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
@@ -3586,22 +3721,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
@@ -3619,6 +3764,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
@@ -3644,6 +3790,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
@@ -3726,6 +3877,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
@@ -3795,6 +3947,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
@@ -3845,6 +3998,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
@@ -3888,6 +4043,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
@@ -3923,6 +4079,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
@@ -3967,6 +4124,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
@@ -4028,8 +4186,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
@@ -4064,12 +4229,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
@@ -4129,7 +4296,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;
@@ -4277,6 +4450,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;
@@ -4357,6 +4531,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
@@ -4375,6 +4550,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
@@ -4739,6 +4916,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
@@ -4754,6 +4932,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;
@@ -4767,6 +4948,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
@@ -4809,13 +4991,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
@@ -4921,6 +5114,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
@@ -4934,6 +5130,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;
@@ -4989,6 +5191,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
@@ -5035,6 +5242,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
@@ -5052,6 +5260,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
@@ -5064,13 +5280,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
@@ -5093,6 +5312,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
@@ -5105,6 +5329,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
@@ -5117,6 +5342,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
@@ -5273,9 +5499,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
@@ -5350,6 +5578,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
@@ -5381,6 +5612,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;
@@ -5391,19 +5623,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
@@ -5453,6 +5695,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;
@@ -5462,6 +5705,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
@@ -5607,6 +5852,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
@@ -5852,6 +6098,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;
@@ -5861,8 +6108,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
@@ -5921,6 +6172,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;
@@ -5945,6 +6197,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;
@@ -5968,7 +6221,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
@@ -6031,6 +6286,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
@@ -6049,6 +6305,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
@@ -6067,6 +6324,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
@@ -6083,6 +6341,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
@@ -6097,10 +6356,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
@@ -6166,10 +6428,12 @@
 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
@@ -6248,6 +6512,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;
@@ -6298,18 +6566,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;
@@ -6358,7 +6632,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;
@@ -6373,6 +6654,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
@@ -6495,6 +6777,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
@@ -6511,6 +6795,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;
@@ -6531,9 +6816,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;
@@ -6552,8 +6840,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;
@@ -6577,12 +6867,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;
@@ -6630,6 +6922,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
@@ -6664,6 +6957,7 @@
 Landroid/widget/RemoteViews;->mergeRemoteViews(Landroid/widget/RemoteViews;)V
 Landroid/widget/RemoteViews;->mLayoutId:I
 Landroid/widget/RemoteViews;->mPortrait:Landroid/widget/RemoteViews;
+Landroid/widget/RemoteViews;->setIsWidgetCollectionChild(Z)V
 Landroid/widget/RemoteViews;->setRemoteAdapter(ILjava/util/ArrayList;I)V
 Landroid/widget/RemoteViewsAdapter;->getRemoteViewsServiceIntent()Landroid/content/Intent;
 Landroid/widget/RemoteViewsAdapter;->isDataReady()Z
@@ -6722,6 +7016,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
@@ -6740,6 +7035,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;
@@ -6782,6 +7078,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
@@ -6830,8 +7127,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;
@@ -7184,6 +7483,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
@@ -7517,6 +7818,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
@@ -7536,6 +7838,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
@@ -7814,12 +8117,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;
@@ -7850,6 +8165,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;
@@ -7888,6 +8204,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;
@@ -7914,6 +8235,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
@@ -7926,7 +8248,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
@@ -7934,6 +8259,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
@@ -7965,7 +8291,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
@@ -8059,6 +8394,7 @@
 Lcom/android/org/conscrypt/TrustedCertificateStore;->getCertificateChain(Ljava/security/cert/X509Certificate;)Ljava/util/List;
 Lcom/android/org/conscrypt/TrustManagerImpl;-><init>(Ljava/security/KeyStore;)V
 Lcom/android/org/conscrypt/TrustManagerImpl;->checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List;
+Ldalvik/system/BaseDexClassLoader;-><init>(Ljava/lang/String;Ljava/io/File;Ljava/lang/String;Ljava/lang/ClassLoader;Z)V
 Ldalvik/system/BaseDexClassLoader;->addDexPath(Ljava/lang/String;)V
 Ldalvik/system/BaseDexClassLoader;->addDexPath(Ljava/lang/String;Z)V
 Ldalvik/system/BaseDexClassLoader;->getLdLibraryPath()Ljava/lang/String;
@@ -8072,6 +8408,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 +8486,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 +8538,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 +8546,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 +8561,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 +8578,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 +8684,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 +8768,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 +8871,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 +8879,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 3b62bd7..a6d2be0 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -979,7 +979,9 @@
     @Override
     protected void attachBaseContext(Context newBase) {
         super.attachBaseContext(newBase);
-        newBase.setAutofillClient(this);
+        if (newBase != null) {
+            newBase.setAutofillClient(this);
+        }
     }
 
     /** @hide */
@@ -5578,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/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/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java
new file mode 100644
index 0000000..24c5d23
--- /dev/null
+++ b/core/java/android/app/AppOpsManagerInternal.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.util.SparseIntArray;
+
+/**
+ * App ops service local interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class AppOpsManagerInternal {
+    /**
+     * Set the currently configured device and profile owners.  Specifies the package uid (value)
+     * that has been configured for each user (key) that has one.  These will be allowed privileged
+     * access to app ops for their user.
+     */
+    public abstract void setDeviceAndProfileOwners(SparseIntArray owners);
+}
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index ca3257f..9db642b 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -700,7 +700,7 @@
                         librarySearchPath, libraryPermittedPath, mBaseClassLoader,
                         null /* classLoaderName */);
                 StrictMode.setThreadPolicy(oldPolicy);
-                mAppComponentFactory = createAppFactory(mApplicationInfo, mClassLoader);
+                mAppComponentFactory = AppComponentFactory.DEFAULT;
             }
 
             return;
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index f771cbd..526888d 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6374,6 +6374,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 +6383,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 +6541,7 @@
 
         /**
          * @hide
+         * Spans are ignored when comparing text for visual difference.
          */
         @Override
         public boolean areNotificationsVisiblyDifferent(Style other) {
@@ -6533,7 +6549,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 +6916,7 @@
 
         /**
          * @hide
+         * Spans are ignored when comparing text for visual difference.
          */
         @Override
         public boolean areNotificationsVisiblyDifferent(Style other) {
@@ -6910,10 +6927,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 +6938,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 +7551,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/RemoteInput.java b/core/java/android/app/RemoteInput.java
index 6feb38e..85fe99d 100644
--- a/core/java/android/app/RemoteInput.java
+++ b/core/java/android/app/RemoteInput.java
@@ -17,6 +17,8 @@
 package android.app;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.ClipData;
 import android.content.ClipDescription;
 import android.content.Intent;
@@ -178,17 +180,18 @@
      */
     public static final class Builder {
         private final String mResultKey;
+        private final ArraySet<String> mAllowedDataTypes = new ArraySet<>();
+        private final Bundle mExtras = new Bundle();
         private CharSequence mLabel;
         private CharSequence[] mChoices;
         private int mFlags = DEFAULT_FLAGS;
-        private Bundle mExtras = new Bundle();
-        private final ArraySet<String> mAllowedDataTypes = new ArraySet<>();
 
         /**
          * Create a builder object for {@link RemoteInput} objects.
+         *
          * @param resultKey the Bundle key that refers to this input when collected from the user
          */
-        public Builder(String resultKey) {
+        public Builder(@NonNull String resultKey) {
             if (resultKey == null) {
                 throw new IllegalArgumentException("Result key can't be null");
             }
@@ -197,22 +200,30 @@
 
         /**
          * Set a label to be displayed to the user when collecting this input.
-         * @param label The label to show to users when they input a response.
+         *
+         * @param label The label to show to users when they input a response
          * @return this object for method chaining
          */
-        public Builder setLabel(CharSequence label) {
+        @NonNull
+        public Builder setLabel(@Nullable CharSequence label) {
             mLabel = Notification.safeCharSequence(label);
             return this;
         }
 
         /**
          * Specifies choices available to the user to satisfy this input.
+         *
+         * <p>Note: Starting in Android P, these choices will always be shown on phones if the app's
+         * target SDK is >= P. However, these choices may also be rendered on other types of devices
+         * regardless of target SDK.
+         *
          * @param choices an array of pre-defined choices for users input.
          *        You must provide a non-null and non-empty array if
-         *        you disabled free form input using {@link #setAllowFreeFormInput}.
+         *        you disabled free form input using {@link #setAllowFreeFormInput}
          * @return this object for method chaining
          */
-        public Builder setChoices(CharSequence[] choices) {
+        @NonNull
+        public Builder setChoices(@Nullable CharSequence[] choices) {
             if (choices == null) {
                 mChoices = null;
             } else {
@@ -232,11 +243,12 @@
          * @param mimeType A mime type that results are allowed to come in.
          *         Be aware that text results (see {@link #setAllowFreeFormInput}
          *         are allowed by default. If you do not want text results you will have to
-         *         pass false to {@code setAllowFreeFormInput}.
-         * @param doAllow Whether the mime type should be allowed or not.
+         *         pass false to {@code setAllowFreeFormInput}
+         * @param doAllow Whether the mime type should be allowed or not
          * @return this object for method chaining
          */
-        public Builder setAllowDataType(String mimeType, boolean doAllow) {
+        @NonNull
+        public Builder setAllowDataType(@NonNull String mimeType, boolean doAllow) {
             if (doAllow) {
                 mAllowedDataTypes.add(mimeType);
             } else {
@@ -252,9 +264,10 @@
          *         If you specify {@code false}, you must either provide a non-null
          *         and non-empty array to {@link #setChoices}, or enable a data result
          *         in {@code setAllowDataType}. Otherwise an
-         *         {@link IllegalArgumentException} is thrown.
+         *         {@link IllegalArgumentException} is thrown
          * @return this object for method chaining
          */
+        @NonNull
         public Builder setAllowFreeFormInput(boolean allowFreeFormTextInput) {
             setFlag(mFlags, allowFreeFormTextInput);
             return this;
@@ -267,7 +280,8 @@
          *
          * @see RemoteInput#getExtras
          */
-        public Builder addExtras(Bundle extras) {
+        @NonNull
+        public Builder addExtras(@NonNull Bundle extras) {
             if (extras != null) {
                 mExtras.putAll(extras);
             }
@@ -279,6 +293,7 @@
          *
          * <p>The returned Bundle is shared with this Builder.
          */
+        @NonNull
         public Bundle getExtras() {
             return mExtras;
         }
@@ -295,6 +310,7 @@
          * Combine all of the options that have been set and return a new {@link RemoteInput}
          * object.
          */
+        @NonNull
         public RemoteInput build() {
             return new RemoteInput(
                     mResultKey, mLabel, mChoices, mFlags, mExtras, mAllowedDataTypes);
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/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java
index 6c57d81..5e75841 100644
--- a/core/java/android/app/slice/SliceProvider.java
+++ b/core/java/android/app/slice/SliceProvider.java
@@ -130,6 +130,10 @@
     /**
      * @hide
      */
+    public static final String METHOD_GET_PERMISSIONS = "get_permissions";
+    /**
+     * @hide
+     */
     public static final String EXTRA_INTENT = "slice_intent";
     /**
      * @hide
@@ -147,6 +151,10 @@
      * @hide
      */
     public static final String EXTRA_PROVIDER_PKG = "provider_pkg";
+    /**
+     * @hide
+     */
+    public static final String EXTRA_RESULT = "result";
 
     private static final boolean DEBUG = false;
 
@@ -392,6 +400,13 @@
             b.putParcelableArrayList(EXTRA_SLICE_DESCENDANTS,
                     new ArrayList<>(handleGetDescendants(uri)));
             return b;
+        } else if (method.equals(METHOD_GET_PERMISSIONS)) {
+            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+                throw new SecurityException("Only the system can get permissions");
+            }
+            Bundle b = new Bundle();
+            b.putStringArray(EXTRA_RESULT, mAutoGrantPermissions);
+            return b;
         }
         return super.call(method, arg, extras);
     }
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 1b05402..1b07784 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -513,7 +513,7 @@
         try {
             mService.setAppStandbyBucket(packageName, bucket, mContext.getUserId());
         } catch (RemoteException e) {
-            // Nothing to do
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -539,8 +539,8 @@
             }
             return bucketMap;
         } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
-        return Collections.EMPTY_MAP;
     }
 
     /**
@@ -563,6 +563,7 @@
         try {
             mService.setAppStandbyBuckets(slice, mContext.getUserId());
         } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -596,6 +597,7 @@
             mService.registerAppUsageObserver(observerId, packages, timeUnit.toMillis(timeLimit),
                     callbackIntent, mContext.getOpPackageName());
         } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -614,6 +616,7 @@
         try {
             mService.unregisterAppUsageObserver(observerId, mContext.getOpPackageName());
         } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -698,6 +701,7 @@
         try {
             mService.whitelistAppTemporarily(packageName, duration, user.getIdentifier());
         } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
         }
     }
 
@@ -709,6 +713,7 @@
         try {
             mService.onCarrierPrivilegedAppsChanged();
         } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
         }
     }
 
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/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 65dfb13..a808c64 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -427,6 +428,7 @@
      * @return an array of capability values for this instance.
      * @hide
      */
+    @TestApi
     public @NetCapability int[] getCapabilities() {
         return BitUtils.unpackBits(mNetworkCapabilities);
     }
@@ -690,6 +692,7 @@
      * @return an array of transport type values for this instance.
      * @hide
      */
+    @TestApi
     public @Transport int[] getTransportTypes() {
         return BitUtils.unpackBits(mTransportTypes);
     }
diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java
index 839a8bf..fd5a22a 100644
--- a/core/java/android/os/storage/StorageVolume.java
+++ b/core/java/android/os/storage/StorageVolume.java
@@ -78,6 +78,7 @@
 
     private final String mId;
     private final File mPath;
+    private final File mInternalPath;
     private final String mDescription;
     private final boolean mPrimary;
     private final boolean mRemovable;
@@ -118,11 +119,12 @@
     public static final int STORAGE_ID_PRIMARY = 0x00010001;
 
     /** {@hide} */
-    public StorageVolume(String id, File path, String description, boolean primary,
-            boolean removable, boolean emulated, boolean allowMassStorage,
+    public StorageVolume(String id, File path, File internalPath, String description,
+            boolean primary, boolean removable, boolean emulated, boolean allowMassStorage,
             long maxFileSize, UserHandle owner, String fsUuid, String state) {
         mId = Preconditions.checkNotNull(id);
         mPath = Preconditions.checkNotNull(path);
+        mInternalPath = Preconditions.checkNotNull(internalPath);
         mDescription = Preconditions.checkNotNull(description);
         mPrimary = primary;
         mRemovable = removable;
@@ -137,6 +139,7 @@
     private StorageVolume(Parcel in) {
         mId = in.readString();
         mPath = new File(in.readString());
+        mInternalPath = new File(in.readString());
         mDescription = in.readString();
         mPrimary = in.readInt() != 0;
         mRemovable = in.readInt() != 0;
@@ -163,6 +166,16 @@
         return mPath.toString();
     }
 
+    /**
+     * Returns the path of the underlying filesystem.
+     *
+     * @return the internal path
+     * @hide
+     */
+    public String getInternalPath() {
+        return mInternalPath.toString();
+    }
+
     /** {@hide} */
     public File getPathFile() {
         return mPath;
@@ -351,6 +364,7 @@
         pw.increaseIndent();
         pw.printPair("mId", mId);
         pw.printPair("mPath", mPath);
+        pw.printPair("mInternalPath", mInternalPath);
         pw.printPair("mDescription", mDescription);
         pw.printPair("mPrimary", mPrimary);
         pw.printPair("mRemovable", mRemovable);
@@ -384,6 +398,7 @@
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeString(mId);
         parcel.writeString(mPath.toString());
+        parcel.writeString(mInternalPath.toString());
         parcel.writeString(mDescription);
         parcel.writeInt(mPrimary ? 1 : 0);
         parcel.writeInt(mRemovable ? 1 : 0);
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index 5c99f6c..576ea52 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -333,6 +333,10 @@
         if (userPath == null) {
             userPath = new File("/dev/null");
         }
+        File internalPath = getInternalPathForUser(userId);
+        if (internalPath == null) {
+            internalPath = new File("/dev/null");
+        }
 
         String description = null;
         String derivedFsUuid = fsUuid;
@@ -371,7 +375,7 @@
             description = context.getString(android.R.string.unknownName);
         }
 
-        return new StorageVolume(id, userPath, description, isPrimary(), removable,
+        return new StorageVolume(id, userPath, internalPath, description, isPrimary(), removable,
                 emulated, allowMassStorage, maxFileSize, new UserHandle(userId),
                 derivedFsUuid, envState);
     }
diff --git a/core/java/android/print/IPrintManager.aidl b/core/java/android/print/IPrintManager.aidl
index d7c267b..d3d3874 100644
--- a/core/java/android/print/IPrintManager.aidl
+++ b/core/java/android/print/IPrintManager.aidl
@@ -143,4 +143,21 @@
     void stopPrinterStateTracking(in PrinterId printerId, int userId);
     void destroyPrinterDiscoverySession(in IPrinterDiscoveryObserver observer,
             int userId);
+
+    /**
+     * Check if the system will bind to print services in intant app.
+     *
+     * @param userId the Id of the user the behavior should be checked for
+     *
+     * @return {@code true} iff the system will bind to print services in instant apps.
+     */
+    boolean getBindInstantServiceAllowed(int userId);
+
+    /**
+     * Set if the system will bind to print services in intant app.
+     *
+     * @param userId the Id of the user the behavior should be changed for
+     * @param allows iff {@code true} the system will bind to print services in instant apps
+     */
+    void setBindInstantServiceAllowed(int userId, boolean allowed);
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 29bbddc..27f446a 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -58,6 +58,7 @@
 import android.database.Cursor;
 import android.database.SQLException;
 import android.location.LocationManager;
+import android.media.AudioFormat;
 import android.net.ConnectivityManager;
 import android.net.NetworkScoreManager;
 import android.net.Uri;
@@ -4186,6 +4187,7 @@
             PUBLIC_SETTINGS.add(DIM_SCREEN);
             PUBLIC_SETTINGS.add(SCREEN_OFF_TIMEOUT);
             PUBLIC_SETTINGS.add(SCREEN_BRIGHTNESS);
+            PUBLIC_SETTINGS.add(SCREEN_BRIGHTNESS_FOR_VR);
             PUBLIC_SETTINGS.add(SCREEN_BRIGHTNESS_MODE);
             PUBLIC_SETTINGS.add(MODE_RINGER_STREAMS_AFFECTED);
             PUBLIC_SETTINGS.add(MUTE_STREAMS_AFFECTED);
@@ -10445,7 +10447,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>
@@ -10921,21 +10925,13 @@
                 = "forced_app_standby_for_small_battery_enabled";
 
         /**
-         * Whether or not to enable the Off Body, Radios Off feature on small battery devices.
+         * Whether or not to enable the User Absent, Radios Off feature on small battery devices.
          * Type: int (0 for false, 1 for true)
          * Default: 0
          * @hide
          */
-        public static final String OFF_BODY_RADIOS_OFF_FOR_SMALL_BATTERY_ENABLED
-                = "off_body_radios_off_for_small_battery_enabled";
-
-        /**
-         * How long after the device goes off body to disable radios, in milliseconds.
-         * Type: long
-         * Default: 10 minutes
-         * @hide
-         */
-        public static final String OFF_BODY_RADIOS_OFF_DELAY_MS = "off_body_radios_off_delay_ms";
+        public static final String USER_ABSENT_RADIOS_OFF_FOR_SMALL_BATTERY_ENABLED
+                = "user_absent_radios_off_for_small_battery_enabled";
 
         /**
          * Whether or not to turn on Wifi when proxy is disconnected.
@@ -11308,15 +11304,66 @@
          public static final int ENCODED_SURROUND_OUTPUT_ALWAYS = 2;
 
         /**
+         * Surround sound formats are available according to the choice
+         * of user, even if they are not detected by the hardware. Those
+         * formats will be reported as part of the HDMI output capability.
+         * Applications are then free to use either PCM or encoded output.
+         *
+         * An example use case would be an AVR that doesn't report a surround
+         * format while the user knows the AVR does support it.
+         * @hide
+         */
+        public static final int ENCODED_SURROUND_OUTPUT_MANUAL = 3;
+
+        /**
          * Set to ENCODED_SURROUND_OUTPUT_AUTO,
-         * ENCODED_SURROUND_OUTPUT_NEVER or
-         * ENCODED_SURROUND_OUTPUT_ALWAYS
+         * ENCODED_SURROUND_OUTPUT_NEVER,
+         * ENCODED_SURROUND_OUTPUT_ALWAYS or
+         * ENCODED_SURROUND_OUTPUT_MANUAL
          * @hide
          */
         public static final String ENCODED_SURROUND_OUTPUT = "encoded_surround_output";
 
         private static final Validator ENCODED_SURROUND_OUTPUT_VALIDATOR =
-                new SettingsValidators.DiscreteValueValidator(new String[] {"0", "1", "2"});
+                new SettingsValidators.DiscreteValueValidator(new String[] {"0", "1", "2", "3"});
+
+        /**
+         * Surround sounds formats that are enabled when ENCODED_SURROUND_OUTPUT is set to
+         * ENCODED_SURROUND_OUTPUT_MANUAL. Encoded as comma separated list. Allowed values
+         * are the format constants defined in AudioFormat.java. Ex:
+         *
+         * "5,6"
+         *
+         * @hide
+         */
+        public static final String ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS =
+                "encoded_surround_output_enabled_formats";
+
+        private static final Validator ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS_VALIDATOR =
+                new Validator() {
+            @Override
+            public boolean validate(String value) {
+                try {
+                    String[] surroundFormats = TextUtils.split(value, ",");
+                    for (String format : surroundFormats) {
+                        int audioFormat = Integer.valueOf(format);
+                        boolean isSurroundFormat = false;
+                        for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) {
+                            if (sf == audioFormat) {
+                                isSurroundFormat = true;
+                                break;
+                            }
+                        }
+                        if (!isSurroundFormat) {
+                            return false;
+                        }
+                    }
+                    return true;
+                } catch (NumberFormatException e) {
+                    return false;
+                }
+            }
+        };
 
         /**
          * Persisted safe headphone volume management state by AudioService
@@ -11963,6 +12010,7 @@
             CALL_AUTO_RETRY,
             DOCK_AUDIO_MEDIA_ENABLED,
             ENCODED_SURROUND_OUTPUT,
+            ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
             LOW_POWER_MODE_TRIGGER_LEVEL,
             BLUETOOTH_ON,
             PRIVATE_DNS_MODE,
@@ -11999,6 +12047,8 @@
             VALIDATORS.put(CALL_AUTO_RETRY, CALL_AUTO_RETRY_VALIDATOR);
             VALIDATORS.put(DOCK_AUDIO_MEDIA_ENABLED, DOCK_AUDIO_MEDIA_ENABLED_VALIDATOR);
             VALIDATORS.put(ENCODED_SURROUND_OUTPUT, ENCODED_SURROUND_OUTPUT_VALIDATOR);
+            VALIDATORS.put(ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
+                    ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS_VALIDATOR);
             VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL, LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR);
             VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL_MAX,
                     LOW_POWER_MODE_TRIGGER_LEVEL_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/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
index d51a13f..f1e937e 100644
--- a/core/java/android/util/ArrayMap.java
+++ b/core/java/android/util/ArrayMap.java
@@ -644,9 +644,11 @@
         if (osize <= 1) {
             // Now empty.
             if (DEBUG) Log.d(TAG, "remove: shrink from " + mHashes.length + " to 0");
-            freeArrays(mHashes, mArray, osize);
+            final int[] ohashes = mHashes;
+            final Object[] oarray = mArray;
             mHashes = EmptyArray.INT;
             mArray = EmptyArray.OBJECT;
+            freeArrays(ohashes, oarray, osize);
             nsize = 0;
         } else {
             nsize = osize - 1;
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/View.java b/core/java/android/view/View.java
index 3807079..049d34f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -15049,8 +15049,7 @@
     public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {
         ensureTransformationInfo();
         if (mTransformationInfo.mAlpha != alpha) {
-            float oldAlpha = mTransformationInfo.mAlpha;
-            mTransformationInfo.mAlpha = alpha;
+            setAlphaInternal(alpha);
             if (onSetAlpha((int) (alpha * 255))) {
                 mPrivateFlags |= PFLAG_ALPHA_SET;
                 // subclass is handling alpha - don't optimize rendering cache invalidation
@@ -15061,10 +15060,6 @@
                 invalidateViewProperty(true, false);
                 mRenderNode.setAlpha(getFinalAlpha());
             }
-            // Report visibility changes, which can affect children, to accessibility
-            if ((alpha == 0) ^ (oldAlpha == 0)) {
-                notifySubtreeAccessibilityStateChangedIfNeeded();
-            }
         }
     }
 
@@ -15081,7 +15076,7 @@
     boolean setAlphaNoInvalidation(float alpha) {
         ensureTransformationInfo();
         if (mTransformationInfo.mAlpha != alpha) {
-            mTransformationInfo.mAlpha = alpha;
+            setAlphaInternal(alpha);
             boolean subclassHandlesAlpha = onSetAlpha((int) (alpha * 255));
             if (subclassHandlesAlpha) {
                 mPrivateFlags |= PFLAG_ALPHA_SET;
@@ -15094,6 +15089,15 @@
         return false;
     }
 
+    private void setAlphaInternal(float alpha) {
+        float oldAlpha = mTransformationInfo.mAlpha;
+        mTransformationInfo.mAlpha = alpha;
+        // Report visibility changes, which can affect children, to accessibility
+        if ((alpha == 0) ^ (oldAlpha == 0)) {
+            notifySubtreeAccessibilityStateChangedIfNeeded();
+        }
+    }
+
     /**
      * This property is hidden and intended only for use by the Fade transition, which
      * animates it to produce a visual translucency that does not side-effect (or get
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 2ec42c0..65a6125 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -8574,6 +8574,8 @@
 
         private final Rect mLocation = new Rect();
 
+        private ViewGroup mRoot;
+
         public View mView;
 
         private int mLayoutDirection;
@@ -8603,47 +8605,100 @@
                 return 1;
             }
 
+            int boundsResult = compareBoundsOfTree(this, another);
+            if (boundsResult != 0) {
+                return boundsResult;
+            }
+
+            // Just break the tie somehow. The accessibility ids are unique
+            // and stable, hence this is deterministic tie breaking.
+            return mView.getAccessibilityViewId() - another.mView.getAccessibilityViewId();
+        }
+
+        /**
+         * Compare two views based on their bounds. Use the bounds of their children to break ties.
+         *
+         * @param holder1 Holder of first view to compare
+         * @param holder2 Holder of second view to compare. Must have the same root at holder1.
+         * @return The compare result, with equality if no good comparison was found.
+         */
+        private static int compareBoundsOfTree(
+                ViewLocationHolder holder1, ViewLocationHolder holder2) {
             if (sComparisonStrategy == COMPARISON_STRATEGY_STRIPE) {
                 // First is above second.
-                if (mLocation.bottom - another.mLocation.top <= 0) {
+                if (holder1.mLocation.bottom - holder2.mLocation.top <= 0) {
                     return -1;
                 }
                 // First is below second.
-                if (mLocation.top - another.mLocation.bottom >= 0) {
+                if (holder1.mLocation.top - holder2.mLocation.bottom >= 0) {
                     return 1;
                 }
             }
 
             // We are ordering left-to-right, top-to-bottom.
-            if (mLayoutDirection == LAYOUT_DIRECTION_LTR) {
-                final int leftDifference = mLocation.left - another.mLocation.left;
+            if (holder1.mLayoutDirection == LAYOUT_DIRECTION_LTR) {
+                final int leftDifference = holder1.mLocation.left - holder2.mLocation.left;
                 if (leftDifference != 0) {
                     return leftDifference;
                 }
             } else { // RTL
-                final int rightDifference = mLocation.right - another.mLocation.right;
+                final int rightDifference = holder1.mLocation.right - holder2.mLocation.right;
                 if (rightDifference != 0) {
                     return -rightDifference;
                 }
             }
             // We are ordering left-to-right, top-to-bottom.
-            final int topDifference = mLocation.top - another.mLocation.top;
+            final int topDifference = holder1.mLocation.top - holder2.mLocation.top;
             if (topDifference != 0) {
                 return topDifference;
             }
             // Break tie by height.
-            final int heightDiference = mLocation.height() - another.mLocation.height();
+            final int heightDiference = holder1.mLocation.height() - holder2.mLocation.height();
             if (heightDiference != 0) {
                 return -heightDiference;
             }
             // Break tie by width.
-            final int widthDiference = mLocation.width() - another.mLocation.width();
-            if (widthDiference != 0) {
-                return -widthDiference;
+            final int widthDifference = holder1.mLocation.width() - holder2.mLocation.width();
+            if (widthDifference != 0) {
+                return -widthDifference;
             }
-            // Just break the tie somehow. The accessibliity ids are unique
-            // and stable, hence this is deterministic tie breaking.
-            return mView.getAccessibilityViewId() - another.mView.getAccessibilityViewId();
+
+            // Find a child of each view with different screen bounds.
+            final Rect view1Bounds = new Rect();
+            final Rect view2Bounds = new Rect();
+            final Rect tempRect = new Rect();
+            holder1.mView.getBoundsOnScreen(view1Bounds, true);
+            holder2.mView.getBoundsOnScreen(view2Bounds, true);
+            final View child1 = holder1.mView.findViewByPredicateTraversal((view) -> {
+                view.getBoundsOnScreen(tempRect, true);
+                return !tempRect.equals(view1Bounds);
+            }, null);
+            final View child2 = holder2.mView.findViewByPredicateTraversal((view) -> {
+                view.getBoundsOnScreen(tempRect, true);
+                return !tempRect.equals(view2Bounds);
+            }, null);
+
+
+            // Compare the children recursively
+            if ((child1 != null) && (child2 != null)) {
+                final ViewLocationHolder childHolder1 =
+                        ViewLocationHolder.obtain(holder1.mRoot, child1);
+                final ViewLocationHolder childHolder2 =
+                        ViewLocationHolder.obtain(holder1.mRoot, child2);
+                return compareBoundsOfTree(childHolder1, childHolder2);
+            }
+
+            // If only one has a child, use that one
+            if (child1 != null) {
+                return 1;
+            }
+
+            if (child2 != null) {
+                return -1;
+            }
+
+            // Give up
+            return 0;
         }
 
         private void init(ViewGroup root, View view) {
@@ -8651,6 +8706,7 @@
             view.getDrawingRect(viewLocation);
             root.offsetDescendantRectToMyCoords(view, viewLocation);
             mView = view;
+            mRoot = root;
             mLayoutDirection = root.getLayoutDirection();
         }
 
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 4104728..7e6af49 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -53,6 +53,7 @@
 import android.view.View;
 import android.view.ViewRootImpl;
 import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
+import android.view.autofill.AutofillManager;
 
 import com.android.internal.inputmethod.IInputContentUriToken;
 import com.android.internal.os.SomeArgs;
@@ -406,6 +407,17 @@
     static final int MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER = 9;
     static final int MSG_REPORT_FULLSCREEN_MODE = 10;
 
+    private static boolean isAutofillUIShowing(View servedView) {
+        AutofillManager afm = servedView.getContext().getSystemService(AutofillManager.class);
+        return afm != null && afm.isAutofillUiShowing();
+    }
+
+    private static boolean canStartInput(View servedView) {
+        // We can start input ether the servedView has window focus
+        // or the activity is showing autofill ui.
+        return servedView.hasWindowFocus() || isAutofillUIShowing(servedView);
+    }
+
     class H extends Handler {
         H(Looper looper) {
             super(looper, null, true);
@@ -506,7 +518,7 @@
                         }
                         // Check focus again in case that "onWindowFocus" is called before
                         // handling this message.
-                        if (mServedView != null && mServedView.hasWindowFocus()) {
+                        if (mServedView != null && canStartInput(mServedView)) {
                             if (checkFocusNoStartInput(mRestartOnNextWindowFocus)) {
                                 final int reason = active ?
                                         InputMethodClient.START_INPUT_REASON_ACTIVATED_BY_IMMS :
@@ -1435,7 +1447,7 @@
                 // at times when we don't really want it to.  For now it
                 // seems better to just turn it all off.
                 // TODO: Check view.isTemporarilyDetached() when re-enable the following code.
-                if (false && view.hasWindowFocus()) {
+                if (false && canStartInput(view)) {
                     mNextServedView = null;
                     scheduleCheckFocusLocked(view);
                 }
@@ -2572,6 +2584,7 @@
         sb.append(view);
         sb.append(",focus=" + view.hasFocus());
         sb.append(",windowFocus=" + view.hasWindowFocus());
+        sb.append(",autofillUiShowing=" + isAutofillUIShowing(view));
         sb.append(",window=" + view.getWindowToken());
         sb.append(",temporaryDetach=" + view.isTemporarilyDetached());
         return sb.toString();
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/app/SuspendedAppActivity.java b/core/java/com/android/internal/app/SuspendedAppActivity.java
index 25af355..f42a195 100644
--- a/core/java/com/android/internal/app/SuspendedAppActivity.java
+++ b/core/java/com/android/internal/app/SuspendedAppActivity.java
@@ -16,10 +16,12 @@
 
 package com.android.internal.app;
 
+import android.Manifest;
 import android.app.AlertDialog;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.util.Slog;
@@ -30,35 +32,47 @@
 public class SuspendedAppActivity extends AlertActivity
         implements DialogInterface.OnClickListener {
     private static final String TAG = "SuspendedAppActivity";
-
     public static final String EXTRA_SUSPENDED_PACKAGE =
             "SuspendedAppActivity.extra.SUSPENDED_PACKAGE";
     public static final String EXTRA_SUSPENDING_PACKAGE =
             "SuspendedAppActivity.extra.SUSPENDING_PACKAGE";
     public static final String EXTRA_DIALOG_MESSAGE = "SuspendedAppActivity.extra.DIALOG_MESSAGE";
-    public static final String EXTRA_MORE_DETAILS_INTENT =
-            "SuspendedAppActivity.extra.MORE_DETAILS_INTENT";
 
     private Intent mMoreDetailsIntent;
     private int mUserId;
+    private PackageManager mPm;
 
     private CharSequence getAppLabel(String packageName) {
-        final PackageManager pm = getPackageManager();
         try {
-            return pm.getApplicationInfoAsUser(packageName, 0, mUserId).loadLabel(pm);
+            return mPm.getApplicationInfoAsUser(packageName, 0, mUserId).loadLabel(mPm);
         } catch (PackageManager.NameNotFoundException ne) {
             Slog.e(TAG, "Package " + packageName + " not found", ne);
         }
         return packageName;
     }
 
+    private Intent getMoreDetailsActivity(String suspendingPackage, String suspendedPackage,
+            int userId) {
+        final Intent moreDetailsIntent = new Intent(Intent.ACTION_SHOW_SUSPENDED_APP_DETAILS)
+                .setPackage(suspendingPackage);
+        final String requiredPermission = Manifest.permission.SEND_SHOW_SUSPENDED_APP_DETAILS;
+        final ResolveInfo resolvedInfo = mPm.resolveActivityAsUser(moreDetailsIntent, 0, userId);
+        if (resolvedInfo != null && resolvedInfo.activityInfo != null
+                && requiredPermission.equals(resolvedInfo.activityInfo.permission)) {
+            moreDetailsIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, suspendedPackage)
+                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            return moreDetailsIntent;
+        }
+        return null;
+    }
+
     @Override
     public void onCreate(Bundle icicle) {
-        getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
         super.onCreate(icicle);
+        mPm = getPackageManager();
+        getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
 
         final Intent intent = getIntent();
-        mMoreDetailsIntent = intent.getParcelableExtra(EXTRA_MORE_DETAILS_INTENT);
         mUserId = intent.getIntExtra(Intent.EXTRA_USER_ID, -1);
         if (mUserId < 0) {
             Slog.wtf(TAG, "Invalid user: " + mUserId);
@@ -66,13 +80,13 @@
             return;
         }
         final String suppliedMessage = intent.getStringExtra(EXTRA_DIALOG_MESSAGE);
-        final CharSequence suspendedAppLabel = getAppLabel(
-                intent.getStringExtra(EXTRA_SUSPENDED_PACKAGE));
+        final String suspendedPackage = intent.getStringExtra(EXTRA_SUSPENDED_PACKAGE);
+        final String suspendingPackage = intent.getStringExtra(EXTRA_SUSPENDING_PACKAGE);
+        final CharSequence suspendedAppLabel = getAppLabel(suspendedPackage);
         final CharSequence dialogMessage;
         if (suppliedMessage == null) {
-            dialogMessage = getString(R.string.app_suspended_default_message,
-                    suspendedAppLabel,
-                    getAppLabel(intent.getStringExtra(EXTRA_SUSPENDING_PACKAGE)));
+            dialogMessage = getString(R.string.app_suspended_default_message, suspendedAppLabel,
+                    getAppLabel(suspendingPackage));
         } else {
             dialogMessage = String.format(getResources().getConfiguration().getLocales().get(0),
                     suppliedMessage, suspendedAppLabel);
@@ -82,6 +96,7 @@
         ap.mTitle = getString(R.string.app_suspended_title);
         ap.mMessage = dialogMessage;
         ap.mPositiveButtonText = getString(android.R.string.ok);
+        mMoreDetailsIntent = getMoreDetailsActivity(suspendingPackage, suspendedPackage, mUserId);
         if (mMoreDetailsIntent != null) {
             ap.mNeutralButtonText = getString(R.string.app_suspended_more_details);
         }
@@ -99,4 +114,16 @@
         }
         finish();
     }
+
+    public static Intent createSuspendedAppInterceptIntent(String suspendedPackage,
+            String suspendingPackage, String dialogMessage, int userId) {
+        return new Intent()
+                .setClassName("android", SuspendedAppActivity.class.getName())
+                .putExtra(EXTRA_SUSPENDED_PACKAGE, suspendedPackage)
+                .putExtra(EXTRA_DIALOG_MESSAGE, dialogMessage)
+                .putExtra(EXTRA_SUSPENDING_PACKAGE, suspendingPackage)
+                .putExtra(Intent.EXTRA_USER_ID, userId)
+                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+    }
 }
diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java
index 79576bd..d468ce3 100644
--- a/core/java/com/android/internal/widget/MessagingLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLayout.java
@@ -50,6 +50,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Consumer;
+import java.util.regex.Pattern;
 
 /**
  * A custom-built layout for the Notification.MessagingStyle allows dynamic addition and removal
@@ -59,6 +60,8 @@
 public class MessagingLayout extends FrameLayout {
 
     private static final float COLOR_SHIFT_AMOUNT = 60;
+    private static final Pattern SPECIAL_CHAR_PATTERN
+            = Pattern.compile ("[!@#$%&*()_+=|<>?{}\\[\\]~-]");
     private static final Consumer<MessagingMessage> REMOVE_MESSAGE
             = MessagingMessage::removeMessage;
     public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f);
@@ -259,18 +262,26 @@
     }
 
     public Icon createAvatarSymbol(CharSequence senderName, String symbol, int layoutColor) {
-        Bitmap bitmap = Bitmap.createBitmap(mAvatarSize, mAvatarSize, Bitmap.Config.ARGB_8888);
-        Canvas canvas = new Canvas(bitmap);
-        float radius = mAvatarSize / 2.0f;
-        int color = findColor(senderName, layoutColor);
-        mPaint.setColor(color);
-        canvas.drawCircle(radius, radius, radius, mPaint);
-        boolean needDarkText  = ColorUtils.calculateLuminance(color) > 0.5f;
-        mTextPaint.setColor(needDarkText ? Color.BLACK : Color.WHITE);
-        mTextPaint.setTextSize(symbol.length() == 1 ? mAvatarSize * 0.5f : mAvatarSize * 0.3f);
-        int yPos = (int) (radius - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)) ;
-        canvas.drawText(symbol, radius, yPos, mTextPaint);
-        return Icon.createWithBitmap(bitmap);
+        if (symbol.isEmpty() || TextUtils.isDigitsOnly(symbol) ||
+                SPECIAL_CHAR_PATTERN.matcher(symbol).find()) {
+            Icon avatarIcon = Icon.createWithResource(getContext(),
+                    com.android.internal.R.drawable.messaging_user);
+            avatarIcon.setTint(findColor(senderName, layoutColor));
+            return avatarIcon;
+        } else {
+            Bitmap bitmap = Bitmap.createBitmap(mAvatarSize, mAvatarSize, Bitmap.Config.ARGB_8888);
+            Canvas canvas = new Canvas(bitmap);
+            float radius = mAvatarSize / 2.0f;
+            int color = findColor(senderName, layoutColor);
+            mPaint.setColor(color);
+            canvas.drawCircle(radius, radius, radius, mPaint);
+            boolean needDarkText = ColorUtils.calculateLuminance(color) > 0.5f;
+            mTextPaint.setColor(needDarkText ? Color.BLACK : Color.WHITE);
+            mTextPaint.setTextSize(symbol.length() == 1 ? mAvatarSize * 0.5f : mAvatarSize * 0.3f);
+            int yPos = (int) (radius - ((mTextPaint.descent() + mTextPaint.ascent()) / 2));
+            canvas.drawText(symbol, radius, yPos, mTextPaint);
+            return Icon.createWithBitmap(bitmap);
+        }
     }
 
     private int findColor(CharSequence senderName, int layoutColor) {
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/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index adaff1f..04918ba 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -48,6 +48,15 @@
     jmethodID    toArray;
 } gArrayListMethods;
 
+static jclass gBooleanClass;
+static jmethodID gBooleanCstor;
+
+static jclass gIntegerClass;
+static jmethodID gIntegerCstor;
+
+static jclass gMapClass;
+static jmethodID gMapPut;
+
 static jclass gAudioHandleClass;
 static jmethodID gAudioHandleCstor;
 static struct {
@@ -1829,6 +1838,72 @@
     return jStatus;
 }
 
+static jint
+android_media_AudioSystem_getSurroundFormats(JNIEnv *env, jobject thiz,
+                                             jobject jSurroundFormats, jboolean reported)
+{
+    ALOGV("getSurroundFormats");
+
+    if (jSurroundFormats == NULL) {
+        ALOGE("jSurroundFormats is NULL");
+        return (jint)AUDIO_JAVA_BAD_VALUE;
+    }
+    if (!env->IsInstanceOf(jSurroundFormats, gMapClass)) {
+        ALOGE("getSurroundFormats not a map");
+        return (jint)AUDIO_JAVA_BAD_VALUE;
+    }
+
+    jint jStatus;
+    unsigned int numSurroundFormats = 0;
+    audio_format_t *surroundFormats = NULL;
+    bool *surroundFormatsEnabled = NULL;
+    status_t status = AudioSystem::getSurroundFormats(
+            &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
+    if (status != NO_ERROR) {
+        ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
+        jStatus = nativeToJavaStatus(status);
+        goto exit;
+    }
+    if (numSurroundFormats == 0) {
+        jStatus = (jint)AUDIO_JAVA_SUCCESS;
+        goto exit;
+    }
+    surroundFormats = (audio_format_t *)calloc(numSurroundFormats, sizeof(audio_format_t));
+    surroundFormatsEnabled = (bool *)calloc(numSurroundFormats, sizeof(bool));
+    status = AudioSystem::getSurroundFormats(
+            &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
+    jStatus = nativeToJavaStatus(status);
+    if (status != NO_ERROR) {
+        ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
+        goto exit;
+    }
+    for (size_t i = 0; i < numSurroundFormats; i++) {
+        jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor,
+                                                audioFormatFromNative(surroundFormats[i]));
+        jobject enabled = env->NewObject(gBooleanClass, gBooleanCstor, surroundFormatsEnabled[i]);
+        env->CallObjectMethod(jSurroundFormats, gMapPut, surroundFormat, enabled);
+        env->DeleteLocalRef(surroundFormat);
+        env->DeleteLocalRef(enabled);
+    }
+
+exit:
+    free(surroundFormats);
+    free(surroundFormatsEnabled);
+    return jStatus;
+}
+
+static jint
+android_media_AudioSystem_setSurroundFormatEnabled(JNIEnv *env, jobject thiz,
+                                                   jint audioFormat, jboolean enabled)
+{
+    status_t status = AudioSystem::setSurroundFormatEnabled(audioFormatToNative(audioFormat),
+                                                            (bool)enabled);
+    if (status != NO_ERROR) {
+        ALOGE_IF(status != NO_ERROR, "AudioSystem::setSurroundFormatEnabled error %d", status);
+    }
+    return (jint)nativeToJavaStatus(status);
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gMethods[] = {
@@ -1884,6 +1959,8 @@
     {"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB},
     {"native_is_offload_supported", "(IIII)Z", (void *)android_media_AudioSystem_isOffloadSupported},
     {"getMicrophones", "(Ljava/util/ArrayList;)I", (void *)android_media_AudioSystem_getMicrophones},
+    {"getSurroundFormats", "(Ljava/util/Map;Z)I", (void *)android_media_AudioSystem_getSurroundFormats},
+    {"setSurroundFormatEnabled", "(IZ)I", (void *)android_media_AudioSystem_setSurroundFormatEnabled},
 };
 
 
@@ -1903,6 +1980,18 @@
     gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
     gArrayListMethods.toArray = GetMethodIDOrDie(env, arrayListClass, "toArray", "()[Ljava/lang/Object;");
 
+    jclass booleanClass = FindClassOrDie(env, "java/lang/Boolean");
+    gBooleanClass = MakeGlobalRefOrDie(env, booleanClass);
+    gBooleanCstor = GetMethodIDOrDie(env, booleanClass, "<init>", "(Z)V");
+
+    jclass integerClass = FindClassOrDie(env, "java/lang/Integer");
+    gIntegerClass = MakeGlobalRefOrDie(env, integerClass);
+    gIntegerCstor = GetMethodIDOrDie(env, integerClass, "<init>", "(I)V");
+
+    jclass mapClass = FindClassOrDie(env, "java/util/Map");
+    gMapClass = MakeGlobalRefOrDie(env, mapClass);
+    gMapPut = GetMethodIDOrDie(env, mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+
     jclass audioHandleClass = FindClassOrDie(env, "android/media/AudioHandle");
     gAudioHandleClass = MakeGlobalRefOrDie(env, audioHandleClass);
     gAudioHandleCstor = GetMethodIDOrDie(env, audioHandleClass, "<init>", "(I)V");
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index 0765faa..99f3034 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -600,16 +600,14 @@
     }
     optional Ntp ntp = 84;
 
-    // Details about the Off Body, Radios Off feature.
-    message OffBodyRadiosOff {
+    // Details about the User Absent, Radios Off feature.
+    message UserAbsentRadiosOff {
         option (android.msg_privacy).dest = DEST_EXPLICIT;
 
-        // Whether or not to enable the Off Body, Radios Off feature on small battery devices.
+        // Whether or not to enable the User Absent, Radios Off feature on small battery devices.
         optional SettingProto enabled_for_small_battery = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
-        // How long after the device goes off body to disable radios, in milliseconds.
-        optional SettingProto delay_ms = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
     }
-    optional OffBodyRadiosOff off_body_radios_off = 85;
+    optional UserAbsentRadiosOff user_absent_radios_off = 85;
 
     // Whether to disable the automatic scheduling of system updates.
     optional SettingProto ota_disable_automatic_update = 86 [ (android.privacy).dest = DEST_AUTOMATIC ];
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/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/config.xml b/core/res/res/values/config.xml
index bc43d91..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>
 
@@ -1285,9 +1288,6 @@
          adapt to the environment.  This mode may be better suited for watches. -->
     <bool name="config_autoBrightnessResetAmbientLuxAfterWarmUp">true</bool>
 
-    <!-- Period of time in which to consider light samples in milliseconds. -->
-    <integer name="config_autoBrightnessAmbientLightHorizon">10000</integer>
-
     <!-- Screen brightness used to dim the screen when the user activity
          timeout expires.  May be less than the minimum allowed brightness setting
          that can be set by the user. -->
@@ -3427,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 db2aa8e..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" />
@@ -1905,7 +1906,6 @@
   <java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
   <java-symbol type="bool" name="config_allowPriorityVibrationsInLowPowerMode" />
   <java-symbol type="fraction" name="config_autoBrightnessAdjustmentMaxGamma" />
-  <java-symbol type="integer" name="config_autoBrightnessAmbientLightHorizon"/>
   <java-symbol type="integer" name="config_autoBrightnessBrighteningLightDebounce"/>
   <java-symbol type="integer" name="config_autoBrightnessDarkeningLightDebounce"/>
   <java-symbol type="integer" name="config_autoBrightnessInitialLightSensorRate"/>
@@ -3302,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" />
@@ -3381,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 ab9fc13..22aca30 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -339,8 +339,7 @@
                     Settings.Global.NTP_SERVER,
                     Settings.Global.NTP_TIMEOUT,
                     Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE,
-                    Settings.Global.OFF_BODY_RADIOS_OFF_FOR_SMALL_BATTERY_ENABLED,
-                    Settings.Global.OFF_BODY_RADIOS_OFF_DELAY_MS,
+                    Settings.Global.USER_ABSENT_RADIOS_OFF_FOR_SMALL_BATTERY_ENABLED,
                     Settings.Global.OVERLAY_DISPLAY_DEVICES,
                     Settings.Global.PAC_CHANGE_DELAY,
                     Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
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/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/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/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index b2903c4..5563cce 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -218,8 +218,7 @@
     }
 
     /**
-     * Reports whether {@link #getCarrierFrequencyHz(int satIndex)} is available (i.e. carrier
-     * frequency is available for the satellite at the specified index).
+     * Reports whether a valid {@link #getCarrierFrequencyHz(int satIndex)} is available.
      *
      * @param satIndex the index of the satellite in the list.
      */
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index d0a2c98..e245425 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -1074,4 +1074,58 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface Encoding {}
 
+    /** @hide */
+    public static final int[] SURROUND_SOUND_ENCODING = {
+            ENCODING_AC3,
+            ENCODING_E_AC3,
+            ENCODING_DTS,
+            ENCODING_DTS_HD,
+            ENCODING_AAC_LC,
+            ENCODING_DOLBY_TRUEHD,
+            ENCODING_E_AC3_JOC,
+    };
+
+    /** @hide */
+    @IntDef(flag = false, prefix = "ENCODING", value = {
+            ENCODING_AC3,
+            ENCODING_E_AC3,
+            ENCODING_DTS,
+            ENCODING_DTS_HD,
+            ENCODING_AAC_LC,
+            ENCODING_DOLBY_TRUEHD,
+            ENCODING_E_AC3_JOC }
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SurroundSoundEncoding {}
+
+    /**
+     * @hide
+     *
+     * Return default name for a surround format. This is not an International name.
+     * It is just a default to use if an international name is not available.
+     *
+     * @param audioFormat a surround format
+     * @return short default name for the format, eg. “AC3” for ENCODING_AC3.
+     */
+    public static String toDisplayName(@SurroundSoundEncoding int audioFormat) {
+        switch (audioFormat) {
+            case ENCODING_AC3:
+                return "Dolby Digital (AC3)";
+            case ENCODING_E_AC3:
+                return "Dolby Digital Plus (E_AC3)";
+            case ENCODING_DTS:
+                return "DTS";
+            case ENCODING_DTS_HD:
+                return "DTS HD";
+            case ENCODING_AAC_LC:
+                return "AAC";
+            case ENCODING_DOLBY_TRUEHD:
+                return "Dolby TrueHD";
+            case ENCODING_E_AC3_JOC:
+                return "Dolby Atmos";
+            default:
+                return "Unknown surround sound format";
+        }
+    }
+
 }
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 566db94..3057501 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -66,6 +66,7 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 
@@ -5014,6 +5015,66 @@
         }
     }
 
+    /**
+     * @hide
+     * Returns all surround formats.
+     * @return a map where the key is a surround format and
+     * the value indicates the surround format is enabled or not
+     */
+    public Map<Integer, Boolean> getSurroundFormats() {
+        Map<Integer, Boolean> surroundFormats = new HashMap<>();
+        int status = AudioSystem.getSurroundFormats(surroundFormats, false);
+        if (status != AudioManager.SUCCESS) {
+            // fail and bail!
+            Log.e(TAG, "getSurroundFormats failed:" + status);
+            return new HashMap<Integer, Boolean>(); // Always return a map.
+        }
+        return surroundFormats;
+    }
+
+    /**
+     * @hide
+     * Set a certain surround format as enabled or not.
+     * @param audioFormat a surround format, the value is one of
+     *        {@link AudioFormat#ENCODING_AC3}, {@link AudioFormat#ENCODING_E_AC3},
+     *        {@link AudioFormat#ENCODING_DTS}, {@link AudioFormat#ENCODING_DTS_HD},
+     *        {@link AudioFormat#ENCODING_AAC_LC}, {@link AudioFormat#ENCODING_DOLBY_TRUEHD},
+     *        {@link AudioFormat#ENCODING_E_AC3_JOC}. Once {@link AudioFormat#ENCODING_AAC_LC} is
+     *        set as enabled, {@link AudioFormat#ENCODING_AAC_LC},
+     *        {@link AudioFormat#ENCODING_AAC_HE_V1}, {@link AudioFormat#ENCODING_AAC_HE_V2},
+     *        {@link AudioFormat#ENCODING_AAC_ELD}, {@link AudioFormat#ENCODING_AAC_XHE} are
+     *        all enabled.
+     * @param enabled the required surround format state, true for enabled, false for disabled
+     * @return true if successful, otherwise false
+     */
+    public boolean setSurroundFormatEnabled(
+            @AudioFormat.SurroundSoundEncoding int audioFormat, boolean enabled) {
+        int status = AudioSystem.setSurroundFormatEnabled(audioFormat, enabled);
+        return status == AudioManager.SUCCESS;
+    }
+
+    /**
+     * @hide
+     * Returns all surround formats that are reported by the connected HDMI device.
+     * The keys are not affected by calling setSurroundFormatEnabled(), and the values
+     * are not affected by calling setSurroundFormatEnabled() when in AUTO mode.
+     * This information can used to show the AUTO setting for SurroundSound.
+     *
+     * @return a map where the key is a surround format and
+     * the value indicates the surround format is enabled or not
+     */
+    public Map<Integer, Boolean> getReportedSurroundFormats() {
+        Map<Integer, Boolean> reportedSurroundFormats = new HashMap<>();
+        int status = AudioSystem.getSurroundFormats(reportedSurroundFormats, true);
+        if (status != AudioManager.SUCCESS) {
+            // fail and bail!
+            Log.e(TAG, "getReportedSurroundFormats failed:" + status);
+            return new HashMap<Integer, Boolean>(); // Always return a map.
+        }
+        return reportedSurroundFormats;
+    }
+
+
     //---------------------------------------------------------
     // Inner classes
     //--------------------
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index aaba1e3..7c893d0 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -23,6 +23,7 @@
 import android.util.Log;
 
 import java.util.ArrayList;
+import java.util.Map;
 
 /* IF YOU CHANGE ANY OF THE CONSTANTS IN THIS FILE, DO NOT FORGET
  * TO UPDATE THE CORRESPONDING NATIVE GLUE AND AudioManager.java.
@@ -715,7 +716,8 @@
     public static final int FORCE_HDMI_SYSTEM_AUDIO_ENFORCED = 12;
     public static final int FORCE_ENCODED_SURROUND_NEVER = 13;
     public static final int FORCE_ENCODED_SURROUND_ALWAYS = 14;
-    public static final int NUM_FORCE_CONFIG = 15;
+    public static final int FORCE_ENCODED_SURROUND_MANUAL = 15;
+    public static final int NUM_FORCE_CONFIG = 16;
     public static final int FORCE_DEFAULT = FORCE_NONE;
 
     public static String forceUseConfigToString(int config) {
@@ -735,6 +737,7 @@
             case FORCE_HDMI_SYSTEM_AUDIO_ENFORCED: return "FORCE_HDMI_SYSTEM_AUDIO_ENFORCED";
             case FORCE_ENCODED_SURROUND_NEVER: return "FORCE_ENCODED_SURROUND_NEVER";
             case FORCE_ENCODED_SURROUND_ALWAYS: return "FORCE_ENCODED_SURROUND_ALWAYS";
+            case FORCE_ENCODED_SURROUND_MANUAL: return "FORCE_ENCODED_SURROUND_MANUAL";
             default: return "unknown config (" + config + ")" ;
         }
     }
@@ -836,6 +839,11 @@
 
     public static native int getMicrophones(ArrayList<MicrophoneInfo> microphonesInfo);
 
+    public static native int getSurroundFormats(Map<Integer, Boolean> surroundFormats,
+                                                boolean reported);
+
+    public static native int setSurroundFormatEnabled(int audioFormat, boolean enabled);
+
     // Items shared with audio service
 
     /**
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 7976f67..e568ef7 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -35,6 +35,9 @@
 import android.provider.MediaStore.Audio;
 import android.provider.MediaStore.Files;
 import android.provider.MediaStore.MediaColumns;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
 import android.util.Log;
 import android.view.Display;
 import android.view.WindowManager;
@@ -560,6 +563,13 @@
             return MtpConstants.RESPONSE_GENERAL_ERROR;
         Path newPath = obj.getPath();
         boolean success = oldPath.toFile().renameTo(newPath.toFile());
+        try {
+            Os.access(oldPath.toString(), OsConstants.F_OK);
+            Os.access(newPath.toString(), OsConstants.F_OK);
+        } catch (ErrnoException e) {
+            // Ignore. Could fail if the metadata was already updated.
+        }
+
         if (!mManager.endRenameObject(obj, oldPath.getFileName().toString(), success)) {
             Log.e(TAG, "Failed to end rename object");
         }
diff --git a/media/java/android/mtp/MtpStorage.java b/media/java/android/mtp/MtpStorage.java
index c72b827..2625e0c 100644
--- a/media/java/android/mtp/MtpStorage.java
+++ b/media/java/android/mtp/MtpStorage.java
@@ -16,7 +16,6 @@
 
 package android.mtp;
 
-import android.content.Context;
 import android.os.storage.StorageVolume;
 
 /**
@@ -36,7 +35,7 @@
 
     public MtpStorage(StorageVolume volume, int storageId) {
         mStorageId = storageId;
-        mPath = volume.getPath();
+        mPath = volume.getInternalPath();
         mDescription = volume.getDescription(null);
         mRemovable = volume.isRemovable();
         mMaxFileSize = volume.getMaxFileSize();
diff --git a/media/java/android/mtp/MtpStorageManager.java b/media/java/android/mtp/MtpStorageManager.java
index bdc8741..a36d88d 100644
--- a/media/java/android/mtp/MtpStorageManager.java
+++ b/media/java/android/mtp/MtpStorageManager.java
@@ -399,8 +399,8 @@
      */
     public synchronized MtpStorage addMtpStorage(StorageVolume volume) {
         int storageId = ((getNextStorageId() & 0x0000FFFF) << 16) + 1;
-        MtpObject root = new MtpObject(volume.getPath(), storageId, null, true);
         MtpStorage storage = new MtpStorage(volume, storageId);
+        MtpObject root = new MtpObject(storage.getPath(), storageId, null, true);
         mRoots.put(storageId, root);
         return storage;
     }
diff --git a/media/tests/MtpTests/src/android/mtp/MtpStorageManagerTest.java b/media/tests/MtpTests/src/android/mtp/MtpStorageManagerTest.java
index 0d7f3fe..b05242d 100644
--- a/media/tests/MtpTests/src/android/mtp/MtpStorageManagerTest.java
+++ b/media/tests/MtpTests/src/android/mtp/MtpStorageManagerTest.java
@@ -104,10 +104,10 @@
         mainStorageDir = createNewDir(TEMP_DIR_FILE);
         secondaryStorageDir = createNewDir(TEMP_DIR_FILE);
 
-        StorageVolume mainStorage = new StorageVolume("1", mainStorageDir, "", true, false, true,
-                false, -1, UserHandle.CURRENT, "", "");
-        StorageVolume secondaryStorage = new StorageVolume("2", secondaryStorageDir, "", false,
-                false, true, false, -1, UserHandle.CURRENT, "", "");
+        StorageVolume mainStorage = new StorageVolume("1", mainStorageDir, mainStorageDir,
+                "", true, false, true, false, -1, UserHandle.CURRENT, "", "");
+        StorageVolume secondaryStorage = new StorageVolume("2", secondaryStorageDir,
+                secondaryStorageDir, "", false, false, true, false, -1, UserHandle.CURRENT, "", "");
 
         objectsAdded = new ArrayList<>();
         objectsRemoved = new ArrayList<>();
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 83d7e16..06fbf9f 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -811,6 +811,8 @@
         List<ResolveInfo> resolvedActivities = getPackageManager()
                 .queryIntentActivities(intent, 0);
         if (resolvedActivities.isEmpty()) {
+            Log.w(LOG_TAG, "Advanced options activity " + mAdvancedPrintOptionsActivity + " could "
+                    + "not be found");
             return;
         }
 
diff --git a/packages/SettingsLib/res/drawable/home.xml b/packages/SettingsLib/res/drawable/home.xml
deleted file mode 100644
index 8d379b3..0000000
--- a/packages/SettingsLib/res/drawable/home.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-    Copyright (C) 2016 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0"
-        android:tint="?android:attr/colorAccent">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M10.0,20.0l0.0,-6.0l4.0,0.0l0.0,6.0l5.0,0.0l0.0,-8.0l3.0,0.0L12.0,3.0 2.0,12.0l3.0,0.0l0.0,8.0z"/>
-</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_mode_edit.xml b/packages/SettingsLib/res/drawable/ic_mode_edit.xml
index c1d2378..319e7eb 100644
--- a/packages/SettingsLib/res/drawable/ic_mode_edit.xml
+++ b/packages/SettingsLib/res/drawable/ic_mode_edit.xml
@@ -1,25 +1,26 @@
 <!--
-    Copyright (C) 2017 The Android Open Source Project
+  Copyright (C) 2018 The Android Open Source Project
 
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
+  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
+       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.
--->
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="20.0dp"
-        android:height="20.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:fillColor="#FFFFFF"
         android:pathData="M20.41,4.94l-1.35,-1.35c-0.78,-0.78 -2.05,-0.78 -2.83,0l0,0L3,16.82V21h4.18L20.41,7.77C21.2,6.99 21.2,5.72 20.41,4.94zM6.41,19.06L5,19v-1.36l9.82,-9.82l1.41,1.41L6.41,19.06z"/>
 </vector>
diff --git a/packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml b/packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml
index 8801f5d..35907cc 100644
--- a/packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml
+++ b/packages/SettingsLib/res/drawable/ic_qs_night_display_on.xml
@@ -18,7 +18,10 @@
     android:height="64dp"
     android:viewportWidth="24.0"
     android:viewportHeight="24.0">
-    <path
-        android:pathData="M13,12c0,-3.57 2.2,-6.62 5.31,-7.87 0.89,-0.36 0.75,-1.69 -0.19,-1.9 -1.1,-0.24 -2.27,-0.3 -3.48,-0.14 -4.51,0.6 -8.12,4.31 -8.59,8.83C5.43,16.93 10.12,22 16,22c0.73,0 1.43,-0.08 2.12,-0.23 0.95,-0.21 1.1,-1.53 0.2,-1.9A8.471,8.471 0,0 1,13 12z"
-        android:fillColor="#FFF"/>
+    <group
+        android:translateX="-1.0">
+        <path
+            android:pathData="M13,12c0,-3.57 2.2,-6.62 5.31,-7.87 0.89,-0.36 0.75,-1.69 -0.19,-1.9 -1.1,-0.24 -2.27,-0.3 -3.48,-0.14 -4.51,0.6 -8.12,4.31 -8.59,8.83C5.43,16.93 10.12,22 16,22c0.73,0 1.43,-0.08 2.12,-0.23 0.95,-0.21 1.1,-1.53 0.2,-1.9A8.471,8.471 0,0 1,13 12z"
+            android:fillColor="#FFF"/>
+    </group>
 </vector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index c926e1f..09fa284 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -250,6 +250,18 @@
         <item>Best Effort (Adaptive Bit Rate)</item>
     </string-array>
 
+    <!-- Summaries for Android Auto Bluetooth Audio Active Device status. [CHAR LIMIT=50]-->
+    <string-array name="bluetooth_audio_active_device_summaries" >
+        <!-- Status message when the device is not Active. -->
+        <item></item>
+        <!-- Status message when the device is Active for Media and Phone. -->
+        <item>, active</item>
+        <!-- Status message when the device is Active for Media only. -->
+        <item>, active (media)</item>
+        <!-- Status message when the device is Active for Phone only. -->
+        <item>, active (phone)</item>
+    </string-array>
+
     <!-- Titles for logd limit size selection preference. [CHAR LIMIT=14] -->
     <string-array name="select_logd_size_titles">
         <item>Off</item>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index ce4aef3..bb8fbe2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -1076,6 +1076,116 @@
     }
 
     /**
+     * @return resource for android auto string that describes the connection state of this device.
+     */
+    public String getCarConnectionSummary() {
+        boolean profileConnected = false;       // at least one profile is connected
+        boolean a2dpNotConnected = false;       // A2DP is preferred but not connected
+        boolean hfpNotConnected = false;        // HFP is preferred but not connected
+        boolean hearingAidNotConnected = false; // Hearing Aid is preferred but not connected
+
+        for (LocalBluetoothProfile profile : getProfiles()) {
+            int connectionStatus = getProfileConnectionState(profile);
+
+            switch (connectionStatus) {
+                case BluetoothProfile.STATE_CONNECTING:
+                case BluetoothProfile.STATE_DISCONNECTING:
+                    return mContext.getString(Utils.getConnectionStateSummary(connectionStatus));
+
+                case BluetoothProfile.STATE_CONNECTED:
+                    profileConnected = true;
+                    break;
+
+                case BluetoothProfile.STATE_DISCONNECTED:
+                    if (profile.isProfileReady()) {
+                        if ((profile instanceof A2dpProfile) ||
+                                (profile instanceof A2dpSinkProfile)){
+                            a2dpNotConnected = true;
+                        } else if ((profile instanceof HeadsetProfile) ||
+                                (profile instanceof HfpClientProfile)) {
+                            hfpNotConnected = true;
+                        } else if (profile instanceof  HearingAidProfile) {
+                            hearingAidNotConnected = true;
+                        }
+                    }
+                    break;
+            }
+        }
+
+        String batteryLevelPercentageString = null;
+        // Android framework should only set mBatteryLevel to valid range [0-100] or
+        // BluetoothDevice.BATTERY_LEVEL_UNKNOWN, any other value should be a framework bug.
+        // Thus assume here that if value is not BluetoothDevice.BATTERY_LEVEL_UNKNOWN, it must
+        // be valid
+        final int batteryLevel = getBatteryLevel();
+        if (batteryLevel != BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
+            // TODO: name com.android.settingslib.bluetooth.Utils something different
+            batteryLevelPercentageString =
+                    com.android.settingslib.Utils.formatPercentage(batteryLevel);
+        }
+
+        // Prepare the string for the Active Device summary
+        String[] activeDeviceStringsArray = mContext.getResources().getStringArray(
+                R.array.bluetooth_audio_active_device_summaries);
+        String activeDeviceString = activeDeviceStringsArray[0];  // Default value: not active
+        if (mIsActiveDeviceA2dp && mIsActiveDeviceHeadset) {
+            activeDeviceString = activeDeviceStringsArray[1];     // Active for Media and Phone
+        } else {
+            if (mIsActiveDeviceA2dp) {
+                activeDeviceString = activeDeviceStringsArray[2]; // Active for Media only
+            }
+            if (mIsActiveDeviceHeadset) {
+                activeDeviceString = activeDeviceStringsArray[3]; // Active for Phone only
+            }
+        }
+        if (!hearingAidNotConnected && mIsActiveDeviceHearingAid) {
+            activeDeviceString = activeDeviceStringsArray[1];
+            return mContext.getString(R.string.bluetooth_connected, activeDeviceString);
+        }
+
+        if (profileConnected) {
+            if (a2dpNotConnected && hfpNotConnected) {
+                if (batteryLevelPercentageString != null) {
+                    return mContext.getString(
+                            R.string.bluetooth_connected_no_headset_no_a2dp_battery_level,
+                            batteryLevelPercentageString, activeDeviceString);
+                } else {
+                    return mContext.getString(R.string.bluetooth_connected_no_headset_no_a2dp,
+                            activeDeviceString);
+                }
+
+            } else if (a2dpNotConnected) {
+                if (batteryLevelPercentageString != null) {
+                    return mContext.getString(R.string.bluetooth_connected_no_a2dp_battery_level,
+                            batteryLevelPercentageString, activeDeviceString);
+                } else {
+                    return mContext.getString(R.string.bluetooth_connected_no_a2dp,
+                            activeDeviceString);
+                }
+
+            } else if (hfpNotConnected) {
+                if (batteryLevelPercentageString != null) {
+                    return mContext.getString(R.string.bluetooth_connected_no_headset_battery_level,
+                            batteryLevelPercentageString, activeDeviceString);
+                } else {
+                    return mContext.getString(R.string.bluetooth_connected_no_headset,
+                            activeDeviceString);
+                }
+            } else {
+                if (batteryLevelPercentageString != null) {
+                    return mContext.getString(R.string.bluetooth_connected_battery_level,
+                            batteryLevelPercentageString, activeDeviceString);
+                } else {
+                    return mContext.getString(R.string.bluetooth_connected, activeDeviceString);
+                }
+            }
+        }
+
+        return getBondState() == BluetoothDevice.BOND_BONDING ?
+                mContext.getString(R.string.bluetooth_pairing) : null;
+    }
+
+    /**
      * @return {@code true} if {@code cachedBluetoothDevice} is a2dp device
      */
     public boolean isA2dpDevice() {
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/SettingsLib/tests/integ/src/com/android/settingslib/drawable/UserIconDrawableTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawable/UserIconDrawableTest.java
index 508107c..143a6cf 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawable/UserIconDrawableTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawable/UserIconDrawableTest.java
@@ -37,7 +37,7 @@
     public void getConstantState_shouldNotBeNull() {
         final Bitmap b = BitmapFactory.decodeResource(
                 InstrumentationRegistry.getTargetContext().getResources(),
-                R.drawable.home);
+                R.drawable.ic_mode_edit);
         mDrawable = new UserIconDrawable(100 /* size */).setIcon(b).bake();
 
         assertThat(mDrawable.getConstantState()).isNotNull();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 5853dca..927a94f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -16,6 +16,7 @@
 package com.android.settingslib.bluetooth;
 
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doAnswer;
@@ -159,7 +160,7 @@
 
         // Test with battery level
         mBatteryLevel = 10;
-       assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                 "Active, 10% battery");
 
         // Set A2DP profile to be disconnected and test connection state summary
@@ -193,7 +194,7 @@
 
         // Test with battery level
         mBatteryLevel = 10;
-       assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
+        assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
                 "Active, 10% battery");
 
         // Set HFP profile to be disconnected and test connection state summary
@@ -278,6 +279,200 @@
     }
 
     @Test
+    public void getCarConnectionSummary_singleProfileConnectDisconnect() {
+        // Test without battery level
+        // Set PAN profile to be connected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected");
+
+        // Set PAN profile to be disconnected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
+
+        // Test with battery level
+        mBatteryLevel = 10;
+        // Set PAN profile to be connected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected, battery 10%");
+
+        // Set PAN profile to be disconnected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
+
+        // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
+        mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+
+        // Set PAN profile to be connected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected");
+
+        // Set PAN profile to be disconnected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
+    }
+
+    @Test
+    public void getCarConnectionSummary_multipleProfileConnectDisconnect() {
+        mBatteryLevel = 10;
+
+        // Set HFP, A2DP and PAN profile to be connected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected, battery 10%");
+
+        // Disconnect HFP only and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo(
+                "Connected (no phone), battery 10%");
+
+        // Disconnect A2DP only and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo(
+                "Connected (no media), battery 10%");
+
+        // Disconnect both HFP and A2DP and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo(
+                "Connected (no phone or media), battery 10%");
+
+        // Disconnect all profiles and test connection state summary
+        mCachedDevice.onProfileStateChanged(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
+    }
+
+    @Test
+    public void getCarConnectionSummary_singleProfileActiveDeviceA2dp() {
+        // Test without battery level
+        // Set A2DP profile to be connected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected");
+
+        // Set device as Active for A2DP and test connection state summary
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected, active (media)");
+
+        // Test with battery level
+        mBatteryLevel = 10;
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo(
+                "Connected, battery 10%, active (media)");
+
+        // Set A2DP profile to be disconnected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
+
+        // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
+        mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+        // Set A2DP profile to be connected, Active and test connection state summary
+        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected, active (media)");
+
+        // Set A2DP profile to be disconnected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
+    }
+
+    @Test
+    public void getCarConnectionSummary_singleProfileActiveDeviceHfp() {
+        // Test without battery level
+        // Set HFP profile to be connected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected");
+
+        // Set device as Active for HFP and test connection state summary
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected, active (phone)");
+
+        // Test with battery level
+        mBatteryLevel = 10;
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo(
+                "Connected, battery 10%, active (phone)");
+
+        // Set HFP profile to be disconnected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
+
+        // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
+        mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+        // Set HFP profile to be connected, Active and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected, active (phone)");
+
+        // Set HFP profile to be disconnected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
+    }
+
+    @Test
+    public void getCarConnectionSummary_singleProfileActiveDeviceHearingAid() {
+        // Test without battery level
+        // Set Hearing Aid profile to be connected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected");
+
+        // Set device as Active for Hearing Aid and test connection state summary
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected, active");
+
+        // Set Hearing Aid profile to be disconnected and test connection state summary
+        mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEARING_AID);
+        mCachedDevice.onProfileStateChanged(mHearingAidProfile,
+                BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
+    }
+
+    @Test
+    public void getCarConnectionSummary_multipleProfilesActiveDevice() {
+        // Test without battery level
+        // Set A2DP and HFP profiles to be connected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected");
+
+        // Set device as Active for A2DP and HFP and test connection state summary
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected, active");
+
+        // Test with battery level
+        mBatteryLevel = 10;
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo(
+                "Connected, battery 10%, active");
+
+        // Disconnect A2DP only and test connection state summary
+        mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.A2DP);
+        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo(
+                "Connected (no media), battery 10%, active (phone)");
+
+        // Disconnect HFP only and test connection state summary
+        mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEADSET);
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo(
+                "Connected (no phone), battery 10%, active (media)");
+
+        // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
+        mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+        // Set A2DP and HFP profiles to be connected, Active and test connection state summary
+        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+        mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isEqualTo("Connected, active");
+
+        // Set A2DP and HFP profiles to be disconnected and test connection state summary
+        mCachedDevice.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        mCachedDevice.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+        assertThat(mCachedDevice.getCarConnectionSummary()).isNull();
+    }
+
+
+    @Test
     public void testDeviceName_testAliasNameAvailable() {
         when(mDevice.getAliasName()).thenReturn(DEVICE_ALIAS);
         when(mDevice.getName()).thenReturn(DEVICE_NAME);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 4530f80..e853399 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2300,6 +2300,9 @@
             loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
                     R.integer.def_screen_brightness);
 
+            loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_FOR_VR,
+                    com.android.internal.R.integer.config_screenBrightnessForVrSettingDefault);
+
             loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
                     R.bool.def_screen_brightness_automatic_mode);
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 3a2d1ce..d5efcb5 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -963,14 +963,11 @@
                 GlobalSettingsProto.Ntp.TIMEOUT_MS);
         p.end(ntpToken);
 
-        final long obroToken = p.start(GlobalSettingsProto.OFF_BODY_RADIOS_OFF);
+        final long uaroToken = p.start(GlobalSettingsProto.USER_ABSENT_RADIOS_OFF);
         dumpSetting(s, p,
-                Settings.Global.OFF_BODY_RADIOS_OFF_FOR_SMALL_BATTERY_ENABLED,
-                GlobalSettingsProto.OffBodyRadiosOff.ENABLED_FOR_SMALL_BATTERY);
-        dumpSetting(s, p,
-                Settings.Global.OFF_BODY_RADIOS_OFF_DELAY_MS,
-                GlobalSettingsProto.OffBodyRadiosOff.DELAY_MS);
-        p.end(obroToken);
+                Settings.Global.USER_ABSENT_RADIOS_OFF_FOR_SMALL_BATTERY_ENABLED,
+                GlobalSettingsProto.UserAbsentRadiosOff.ENABLED_FOR_SMALL_BATTERY);
+        p.end(uaroToken);
 
         dumpSetting(s, p,
                 Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 7b76fce..15df0a8 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -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;
                 }
 
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
index 299e337..680f14b 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
@@ -38,7 +38,7 @@
 public interface NotificationMenuRowPlugin extends Plugin {
 
     public static final String ACTION = "com.android.systemui.action.PLUGIN_NOTIFICATION_MENU_ROW";
-    public static final int VERSION = 3;
+    public static final int VERSION = 4;
 
     @ProvidesInterface(version = OnMenuEventListener.VERSION)
     public interface OnMenuEventListener {
@@ -75,6 +75,11 @@
      */
     public MenuItem getAppOpsMenuItem(Context context);
 
+    /**
+     * @return the {@link MenuItem} to display when snooze item is pressed.
+     */
+    public MenuItem getSnoozeMenuItem(Context context);
+
     public void setMenuItems(ArrayList<MenuItem> items);
 
     public void setMenuClickListener(OnMenuEventListener listener);
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors.xml b/packages/SystemUI/res/drawable/ic_invert_colors.xml
index f7a86a4..77d4918 100644
--- a/packages/SystemUI/res/drawable/ic_invert_colors.xml
+++ b/packages/SystemUI/res/drawable/ic_invert_colors.xml
@@ -19,10 +19,7 @@
     android:height="48dp"
     android:viewportWidth="24.0"
     android:viewportHeight="24.0">
-    <group
-        android:translateX="-0.61">
-        <path
-            android:pathData="M17.44,7.71L12.7,2.97a0.996,0.996 0,0 0,-1.41 0L6.56,7.71c-3,3 -3.4,7.89 -0.62,11.1 1.6,1.85 3.83,2.77 6.06,2.77s4.46,-0.92 6.06,-2.77c2.78,-3.21 2.38,-8.1 -0.62,-11.1zM12,19.59c-1.6,0 -3.11,-0.62 -4.24,-1.76C6.62,16.69 6,15.19 6,13.59s0.62,-3.11 1.76,-4.24L12,5.1v14.49z"
-            android:fillColor="#FFFFFFFF"/>
-    </group>
+    <path
+        android:pathData="M17.44,7.71L12.7,2.97a0.996,0.996 0,0 0,-1.41 0L6.56,7.71c-3,3 -3.4,7.89 -0.62,11.1 1.6,1.85 3.83,2.77 6.06,2.77s4.46,-0.92 6.06,-2.77c2.78,-3.21 2.38,-8.1 -0.62,-11.1zM12,19.59c-1.6,0 -3.11,-0.62 -4.24,-1.76C6.62,16.69 6,15.19 6,13.59s0.62,-3.11 1.76,-4.24L12,5.1v14.49z"
+        android:fillColor="#FFFFFFFF"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml
index 95345b8..30024dd 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="56dp"
-    android:height="56dp"
-    android:viewportWidth="25.0"
-    android:viewportHeight="23.5"
+    android:width="32dp"
+    android:height="29.5dp"
+    android:viewportWidth="25.6"
+    android:viewportHeight="23.6"
     android:alpha="0.14"
     android:tint="?android:attr/colorForeground" >
     <group
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
index ea02ba7..a72e9b8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
@@ -20,7 +20,7 @@
     android:viewportHeight="23.6">
     <group
         android:translateX="0.8"
-        android:translateY="1.1">
+        android:translateY="-1.1">
         <path
             android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
             android:fillColor="#FFFFFFFF"/>
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/quick_status_bar_header_system_icons.xml b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
index d40534e..680112c 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
@@ -31,6 +31,7 @@
         android:id="@+id/clock"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
+        android:minWidth="48dp"
         android:gravity="center_vertical|start"
         android:paddingStart="@dimen/status_bar_left_clock_starting_padding"
         android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
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/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 75403b9..0cc3c9e 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -56,8 +56,6 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content" />
 
-    <include layout="@layout/brightness_mirror" />
-
     <ViewStub android:id="@+id/fullscreen_user_switcher_stub"
               android:layout="@layout/car_fullscreen_user_switcher"
               android:layout_width="match_parent"
@@ -68,6 +66,8 @@
         android:layout_height="match_parent"
         android:visibility="invisible" />
 
+    <include layout="@layout/brightness_mirror" />
+
     <com.android.systemui.statusbar.ScrimView
         android:id="@+id/scrim_in_front"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 458e133d7..cd8ffa8 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -61,12 +61,16 @@
     <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"/>
     <item type="id" name="transformation_start_scale_x_tag"/>
     <item type="id" name="transformation_start_scale_y_tag"/>
     <item type="id" name="continuous_clipping_tag"/>
+    <item type="id" name="panel_alpha_animator_tag"/>
+    <item type="id" name="panel_alpha_animator_start_tag"/>
+    <item type="id" name="panel_alpha_animator_end_tag"/>
 
     <!-- Whether the icon is from a notification for which targetSdk < L -->
     <item type="id" name="icon_is_pre_L"/>
@@ -99,6 +103,7 @@
     <item type="id" name="action_snooze_long"/>
     <item type="id" name="action_snooze_longer"/>
     <item type="id" name="action_snooze_assistant_suggestion_1"/>
+    <item type="id" name="action_snooze"/>
 
     <!-- For StatusBarIconContainer to tag its icon views -->
     <item type="id" name="status_bar_view_state_tag" />
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
index 939a868..2ff98ba 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
@@ -85,4 +85,9 @@
      * cancel (long) press.
      */
     void onQuickStep(in MotionEvent event);
+
+    /**
+     * Sent when there was an action on one of the onboarding tips view.
+     */
+    void onTip(int actionType, int viewType);
 }
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/LauncherEventUtil.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/LauncherEventUtil.java
new file mode 100644
index 0000000..eed9580
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/LauncherEventUtil.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+public class LauncherEventUtil {
+
+    // Constants for the Action
+    public static final int VISIBLE = 0;
+    public static final int DISMISS = 1;
+
+    // Constants for the Target (View)
+    public static final int RECENTS_SWIPE_UP_ONBOARDING_TIP = 0;
+    public static final int RECENTS_QUICK_SCRUB_ONBOARDING_TIP = 1;
+
+}
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..31fd47f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -750,7 +750,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/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/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/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index ad2efbd..a9bfa45 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -179,9 +179,10 @@
 
         mBatteryMeterView = findViewById(R.id.battery);
         mBatteryMeterView.setForceShowPercent(true);
+        mBatteryMeterView.setOnClickListener(this);
         mClockView = findViewById(R.id.clock);
+        mClockView.setOnClickListener(this);
         mDateView = findViewById(R.id.date);
-        mDateView.setOnClickListener(this);
     }
 
     private void updateStatusText() {
@@ -413,9 +414,12 @@
 
     @Override
     public void onClick(View v) {
-        if(v == mDateView){
+        if (v == mClockView) {
             Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(new Intent(
                     AlarmClock.ACTION_SHOW_ALARMS),0);
+        } else if (v == mBatteryMeterView) {
+            Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(new Intent(
+                    Intent.ACTION_POWER_USAGE_SUMMARY),0);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index d6182c4..fb4fcd4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -123,7 +123,6 @@
             mDataController.setMobileDataEnabled(false);
             return;
         }
-        mHost.collapsePanels();
         String carrierName = mController.getMobileDataNetworkName();
         if (TextUtils.isEmpty(carrierName)) {
             carrierName = mContext.getString(R.string.mobile_data_disable_message_default_carrier);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
index d16e1b1..368fa67 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
@@ -24,11 +24,19 @@
 import static com.android.systemui.Prefs.Key.HAS_SEEN_RECENTS_SWIPE_UP_ONBOARDING;
 import static com.android.systemui.Prefs.Key.OVERVIEW_OPENED_COUNT;
 import static com.android.systemui.Prefs.Key.OVERVIEW_OPENED_FROM_HOME_COUNT;
+import static com.android.systemui.shared.system.LauncherEventUtil.VISIBLE;
+import static com.android.systemui.shared.system.LauncherEventUtil.DISMISS;
+import static com.android.systemui.shared.system.LauncherEventUtil.RECENTS_QUICK_SCRUB_ONBOARDING_TIP;
+import static com.android.systemui.shared.system.LauncherEventUtil.RECENTS_SWIPE_UP_ONBOARDING_TIP;
 
 import android.annotation.StringRes;
 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;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.CornerPathEffect;
@@ -38,6 +46,7 @@
 import android.os.Build;
 import android.os.SystemProperties;
 import android.os.UserManager;
+import android.os.RemoteException;
 import android.util.TypedValue;
 import android.view.Gravity;
 import android.view.LayoutInflater;
@@ -53,6 +62,7 @@
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
+import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 
 import java.util.Collections;
@@ -100,8 +110,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) {
@@ -111,6 +132,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();
@@ -120,6 +145,7 @@
                     return;
                 }
 
+                boolean shouldLog = false;
                 if (!alreadySeenSwipeUpOnboarding) {
                     if (getOpenedOverviewFromHomeCount()
                             >= SWIPE_UP_SHOW_ON_OVERVIEW_OPENED_FROM_HOME_COUNT) {
@@ -128,10 +154,13 @@
                             if (mNumAppsLaunchedSinceSwipeUpTipDismiss
                                     == SWIPE_UP_SHOW_ON_APP_LAUNCH_AFTER_DISMISS) {
                                 mNumAppsLaunchedSinceSwipeUpTipDismiss = 0;
-                                show(R.string.recents_swipe_up_onboarding);
+                                shouldLog = show(R.string.recents_swipe_up_onboarding);
                             }
                         } else {
-                            show(R.string.recents_swipe_up_onboarding);
+                            shouldLog = show(R.string.recents_swipe_up_onboarding);
+                        }
+                        if (shouldLog) {
+                            notifyOnTip(VISIBLE, RECENTS_SWIPE_UP_ONBOARDING_TIP);
                         }
                     }
                 } else {
@@ -140,12 +169,16 @@
                             if (mOverviewOpenedCountSinceQuickScrubTipDismiss
                                     == QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) {
                                 mOverviewOpenedCountSinceQuickScrubTipDismiss = 0;
-                                show(R.string.recents_quick_scrub_onboarding);
+                                shouldLog = show(R.string.recents_quick_scrub_onboarding);
                             }
                         } else {
-                            show(R.string.recents_quick_scrub_onboarding);
+                            shouldLog = show(R.string.recents_quick_scrub_onboarding);
+                        }
+                        if (shouldLog) {
+                            notifyOnTip(VISIBLE, RECENTS_QUICK_SCRUB_ONBOARDING_TIP);
                         }
                     }
+
                 }
             } else {
                 hide(false);
@@ -191,6 +224,7 @@
         @Override
         public void onViewAttachedToWindow(View view) {
             if (view == mLayout) {
+                mContext.registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
                 mLayoutAttachedToWindow = true;
                 if (view.getTag().equals(R.string.recents_swipe_up_onboarding)) {
                     mHasDismissedSwipeUpTip = false;
@@ -215,6 +249,7 @@
                     }
                     mOverviewOpenedCountSinceQuickScrubTipDismiss = 0;
                 }
+                mContext.unregisterReceiver(mReceiver);
             }
         }
     };
@@ -244,6 +279,9 @@
             if (v.getTag().equals(R.string.recents_swipe_up_onboarding)) {
                 mHasDismissedSwipeUpTip = true;
                 mNumAppsLaunchedSinceSwipeUpTipDismiss = 0;
+                notifyOnTip(DISMISS, RECENTS_SWIPE_UP_ONBOARDING_TIP);
+            } else {
+                notifyOnTip(DISMISS, RECENTS_QUICK_SCRUB_ONBOARDING_TIP);
             }
         });
 
@@ -265,6 +303,15 @@
         }
     }
 
+    private void notifyOnTip(int action, int target) {
+        try {
+            IOverviewProxy overviewProxy = mOverviewProxyService.getProxy();
+            if(overviewProxy != null) {
+                overviewProxy.onTip(action, target);
+            }
+        } catch (RemoteException e) {}
+    }
+
     public void onConnectedToLauncher() {
         if (!ONBOARDING_ENABLED) {
             return;
@@ -307,9 +354,9 @@
         }
     }
 
-    public void show(@StringRes int stringRes) {
+    public boolean show(@StringRes int stringRes) {
         if (!shouldShow()) {
-            return;
+            return false;
         }
         mDismissView.setTag(stringRes);
         mLayout.setTag(stringRes);
@@ -328,7 +375,9 @@
                     .setDuration(SHOW_DURATION_MS)
                     .setInterpolator(new DecelerateInterpolator())
                     .start();
+            return true;
         }
+        return false;
     }
 
     /**
@@ -370,7 +419,7 @@
                 ViewGroup.LayoutParams.MATCH_PARENT,
                 ViewGroup.LayoutParams.WRAP_CONTENT,
                 0, -mNavBarHeight / 2,
-                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
+                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
                 flags,
                 PixelFormat.TRANSLUCENT);
         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
@@ -427,4 +476,13 @@
     private void setOpenedOverviewCount(int openedOverviewCount) {
         Prefs.putInt(mContext, OVERVIEW_OPENED_COUNT, openedOverviewCount);
     }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
+                hide(false);
+            }
+        }
+    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 82cf93e..b010199 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -54,6 +54,7 @@
 import android.view.ViewStub;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.widget.Chronometer;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
@@ -1599,6 +1600,10 @@
     public void doLongClickCallback(int x, int y) {
         createMenu();
         MenuItem menuItem = getProvider().getLongpressMenuItem(mContext);
+        doLongClickCallback(x, y, menuItem);
+    }
+
+    private void doLongClickCallback(int x, int y, MenuItem menuItem) {
         if (mLongPressListener != null && menuItem != null) {
             mLongPressListener.onLongPress(this, x, y, menuItem);
         }
@@ -2707,6 +2712,16 @@
                 info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
             }
         }
+        NotificationMenuRowPlugin provider = getProvider();
+        if (provider != null) {
+            MenuItem snoozeMenu = provider.getSnoozeMenuItem(getContext());
+            if (snoozeMenu != null) {
+                AccessibilityAction action = new AccessibilityAction(R.id.action_snooze,
+                    getContext().getResources()
+                        .getString(R.string.notification_menu_snooze_action));
+                info.addAction(action);
+            }
+        }
     }
 
     @Override
@@ -2725,6 +2740,16 @@
             case AccessibilityNodeInfo.ACTION_LONG_CLICK:
                 doLongClickCallback();
                 return true;
+            case R.id.action_snooze:
+                NotificationMenuRowPlugin provider = getProvider();
+                if (provider == null) {
+                    provider = createMenu();
+                }
+                MenuItem snoozeMenu = provider.getSnoozeMenuItem(getContext());
+                if (snoozeMenu != null) {
+                    doLongClickCallback(getWidth() / 2, getHeight() / 2, snoozeMenu);
+                }
+                return true;
         }
         return false;
     }
@@ -2743,6 +2768,10 @@
         return mNotificationViewState;
     }
 
+    public NotificationViewState getViewState() {
+        return mNotificationViewState;
+    }
+
     @Override
     public boolean isAboveShelf() {
         return !isOnKeyguard()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 8fa1b67..724bd22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -178,7 +178,7 @@
         int heightMode = MeasureSpec.getMode(heightMeasureSpec);
         boolean hasFixedHeight = heightMode == MeasureSpec.EXACTLY;
         boolean isHeightLimited = heightMode == MeasureSpec.AT_MOST;
-        int maxSize = Integer.MAX_VALUE;
+        int maxSize = Integer.MAX_VALUE / 2;
         int width = MeasureSpec.getSize(widthMeasureSpec);
         if (hasFixedHeight || isHeightLimited) {
             maxSize = MeasureSpec.getSize(heightMeasureSpec);
@@ -189,17 +189,15 @@
             if (mExpandedSmartReplyView != null) {
                 notificationMaxHeight += mExpandedSmartReplyView.getHeightUpperLimit();
             }
-            int size = Math.min(maxSize, notificationMaxHeight);
+            int size = notificationMaxHeight;
             ViewGroup.LayoutParams layoutParams = mExpandedChild.getLayoutParams();
             boolean useExactly = false;
             if (layoutParams.height >= 0) {
                 // An actual height is set
-                size = Math.min(maxSize, layoutParams.height);
+                size = Math.min(size, layoutParams.height);
                 useExactly = true;
             }
-            int spec = size == Integer.MAX_VALUE
-                    ? MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
-                    : MeasureSpec.makeMeasureSpec(size, useExactly
+            int spec = MeasureSpec.makeMeasureSpec(size, useExactly
                             ? MeasureSpec.EXACTLY
                             : MeasureSpec.AT_MOST);
             measureChildWithMargins(mExpandedChild, widthMeasureSpec, 0, spec, 0);
@@ -207,7 +205,7 @@
         }
         if (mContractedChild != null) {
             int heightSpec;
-            int size = Math.min(maxSize, mSmallHeight);
+            int size = mSmallHeight;
             ViewGroup.LayoutParams layoutParams = mContractedChild.getLayoutParams();
             boolean useExactly = false;
             if (layoutParams.height >= 0) {
@@ -241,7 +239,7 @@
         if (mHeadsUpChild != null) {
             int maxHeight = mHeadsUpHeight;
             maxHeight += mHeadsUpWrapper.getExtraMeasureHeight();
-            int size = Math.min(maxSize, maxHeight);
+            int size = maxHeight;
             ViewGroup.LayoutParams layoutParams = mHeadsUpChild.getLayoutParams();
             boolean useExactly = false;
             if (layoutParams.height >= 0) {
@@ -263,11 +261,11 @@
                         MeasureSpec.EXACTLY);
             }
             mSingleLineView.measure(singleLineWidthSpec,
-                    MeasureSpec.makeMeasureSpec(maxSize, MeasureSpec.AT_MOST));
+                    MeasureSpec.makeMeasureSpec(mNotificationMaxHeight, MeasureSpec.AT_MOST));
             maxChildHeight = Math.max(maxChildHeight, mSingleLineView.getMeasuredHeight());
         }
         if (mAmbientChild != null) {
-            int size = Math.min(maxSize, mNotificationAmbientHeight);
+            int size = mNotificationAmbientHeight;
             ViewGroup.LayoutParams layoutParams = mAmbientChild.getLayoutParams();
             boolean useExactly = false;
             if (layoutParams.height >= 0) {
@@ -281,7 +279,7 @@
             maxChildHeight = Math.max(maxChildHeight, mAmbientChild.getMeasuredHeight());
         }
         if (mAmbientSingleLineChild != null) {
-            int size = Math.min(maxSize, mNotificationAmbientHeight);
+            int size = mNotificationAmbientHeight;
             ViewGroup.LayoutParams layoutParams = mAmbientSingleLineChild.getLayoutParams();
             boolean useExactly = false;
             if (layoutParams.height >= 0) {
@@ -424,7 +422,6 @@
         mContractedChild = child;
         mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child,
                 mContainingNotification);
-        mContractedWrapper.setDark(mDark, false /* animate */, 0 /* delay */);
     }
 
     private NotificationViewWrapper getWrapperForView(View child) {
@@ -1108,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 */);
     }
 
@@ -1201,8 +1186,13 @@
     }
     private void updateSingleLineView() {
         if (mIsChildInGroup) {
+            boolean isNewView = mSingleLineView == null;
             mSingleLineView = mHybridGroupManager.bindFromNotification(
                     mSingleLineView, mStatusBarNotification.getNotification());
+            if (isNewView) {
+                updateViewVisibility(mVisibleType, VISIBLE_TYPE_SINGLELINE,
+                        mSingleLineView, mSingleLineView);
+            }
         } else if (mSingleLineView != null) {
             removeView(mSingleLineView);
             mSingleLineView = null;
@@ -1211,8 +1201,13 @@
 
     private void updateAmbientSingleLineView() {
         if (mIsChildInGroup) {
+            boolean isNewView = mAmbientSingleLineChild == null;
             mAmbientSingleLineChild = mHybridGroupManager.bindAmbientFromNotification(
                     mAmbientSingleLineChild, mStatusBarNotification.getNotification());
+            if (isNewView) {
+                updateViewVisibility(mVisibleType, VISIBLE_TYPE_AMBIENT_SINGLELINE,
+                        mAmbientSingleLineChild, mAmbientSingleLineChild);
+            }
         } else if (mAmbientSingleLineChild != null) {
             removeView(mAmbientSingleLineChild);
             mAmbientSingleLineChild = null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
index 7681530..f14ca71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
@@ -229,6 +229,7 @@
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
         mMessagingUtil = new NotificationMessagingUtil(context);
         mSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
+        mGroupManager.setPendingEntries(mPendingNotifications);
     }
 
     public void setUpWithPresenter(NotificationPresenter presenter,
@@ -739,6 +740,7 @@
                 mNotificationData.getImportance(key));
 
         mPendingNotifications.put(key, shadeEntry);
+        mGroupManager.onPendingEntryAdded(shadeEntry);
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 0cc6137..eb46fba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -25,6 +25,7 @@
 import android.os.Handler;
 import android.support.annotation.Nullable;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.View;
 import android.view.ViewAnimationUtils;
 import android.view.accessibility.AccessibilityEvent;
@@ -247,25 +248,29 @@
     /** Animates in the guts view via either a fade or a circular reveal. */
     private void animateOpen(
             boolean shouldDoCircularReveal, int x, int y, @Nullable Runnable onAnimationEnd) {
-        if (shouldDoCircularReveal) {
-            double horz = Math.max(getWidth() - x, x);
-            double vert = Math.max(getHeight() - y, y);
-            float r = (float) Math.hypot(horz, vert);
-            // Circular reveal originating at (x, y)
-            Animator a = ViewAnimationUtils.createCircularReveal(this, x, y, 0, r);
-            a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
-            a.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
-            a.addListener(new AnimateOpenListener(onAnimationEnd));
-            a.start();
+        if (isAttachedToWindow()) {
+            if (shouldDoCircularReveal) {
+                double horz = Math.max(getWidth() - x, x);
+                double vert = Math.max(getHeight() - y, y);
+                float r = (float) Math.hypot(horz, vert);
+                // Circular reveal originating at (x, y)
+                Animator a = ViewAnimationUtils.createCircularReveal(this, x, y, 0, r);
+                a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+                a.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
+                a.addListener(new AnimateOpenListener(onAnimationEnd));
+                a.start();
+            } else {
+                // Fade in content
+                this.setAlpha(0f);
+                this.animate()
+                        .alpha(1f)
+                        .setDuration(StackStateAnimator.ANIMATION_DURATION_BLOCKING_HELPER_FADE)
+                        .setInterpolator(Interpolators.ALPHA_IN)
+                        .setListener(new AnimateOpenListener(onAnimationEnd))
+                        .start();
+            }
         } else {
-            // Fade in content
-            this.setAlpha(0f);
-            this.animate()
-                    .alpha(1f)
-                    .setDuration(StackStateAnimator.ANIMATION_DURATION_BLOCKING_HELPER_FADE)
-                    .setInterpolator(Interpolators.ALPHA_IN)
-                    .setListener(new AnimateOpenListener(onAnimationEnd))
-                    .start();
+            Log.w(TAG, "Failed to animate guts open");
         }
     }
 
@@ -273,29 +278,33 @@
     /** Animates out the guts view via either a fade or a circular reveal. */
     @VisibleForTesting
     void animateClose(int x, int y, boolean shouldDoCircularReveal) {
-        if (shouldDoCircularReveal) {
-            // Circular reveal originating at (x, y)
-            if (x == -1 || y == -1) {
-                x = (getLeft() + getRight()) / 2;
-                y = (getTop() + getHeight() / 2);
+        if (isAttachedToWindow()) {
+            if (shouldDoCircularReveal) {
+                // Circular reveal originating at (x, y)
+                if (x == -1 || y == -1) {
+                    x = (getLeft() + getRight()) / 2;
+                    y = (getTop() + getHeight() / 2);
+                }
+                double horz = Math.max(getWidth() - x, x);
+                double vert = Math.max(getHeight() - y, y);
+                float r = (float) Math.hypot(horz, vert);
+                Animator a = ViewAnimationUtils.createCircularReveal(this,
+                        x, y, r, 0);
+                a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+                a.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
+                a.addListener(new AnimateCloseListener(this /* view */));
+                a.start();
+            } else {
+                // Fade in the blocking helper.
+                this.animate()
+                        .alpha(0f)
+                        .setDuration(StackStateAnimator.ANIMATION_DURATION_BLOCKING_HELPER_FADE)
+                        .setInterpolator(Interpolators.ALPHA_OUT)
+                        .setListener(new AnimateCloseListener(this /* view */))
+                        .start();
             }
-            double horz = Math.max(getWidth() - x, x);
-            double vert = Math.max(getHeight() - y, y);
-            float r = (float) Math.hypot(horz, vert);
-            Animator a = ViewAnimationUtils.createCircularReveal(this,
-                    x, y, r, 0);
-            a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
-            a.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
-            a.addListener(new AnimateCloseListener(this /* view */));
-            a.start();
         } else {
-            // Fade in the blocking helper.
-            this.animate()
-                    .alpha(0f)
-                    .setDuration(StackStateAnimator.ANIMATION_DURATION_BLOCKING_HELPER_FADE)
-                    .setInterpolator(Interpolators.ALPHA_OUT)
-                    .setListener(new AnimateCloseListener(this /* view */))
-                    .start();
+            Log.w(TAG, "Failed to animate guts close");
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index 0eb6bd4e..ada1a17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -70,6 +70,7 @@
     private FrameLayout mMenuContainer;
     private MenuItem mInfoItem;
     private MenuItem mAppOpsItem;
+    private MenuItem mSnoozeItem;
     private ArrayList<MenuItem> mMenuItems;
     private OnMenuEventListener mMenuListener;
 
@@ -128,6 +129,11 @@
     }
 
     @Override
+    public MenuItem getSnoozeMenuItem(Context context) {
+        return mSnoozeItem;
+    }
+
+    @Override
     public void setSwipeActionHelper(NotificationSwipeActionHelper helper) {
         mSwipeHelper = helper;
     }
@@ -190,7 +196,8 @@
             boolean isForeground = (flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
             if (!isForeground) {
                 // Only show snooze for non-foreground notifications
-                mMenuItems.add(createSnoozeItem(mContext));
+                mSnoozeItem = createSnoozeItem(mContext);
+                mMenuItems.add(mSnoozeItem);
             }
         }
         mInfoItem = createInfoItem(mContext);
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/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 4fc18ad..0b941c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -806,7 +806,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 20ab64c..cfbb4d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -20,7 +20,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.app.ActivityManager;
-import android.app.ActivityOptions;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.os.RemoteException;
@@ -76,8 +75,8 @@
     }
 
     public RemoteAnimationAdapter getLaunchAnimation(
-            ExpandableNotificationRow sourceNotification) {
-        if (mStatusBar.getBarState() != StatusBarState.SHADE) {
+            ExpandableNotificationRow sourceNotification, boolean occluded) {
+        if (mStatusBar.getBarState() != StatusBarState.SHADE || occluded) {
             return null;
         }
         AnimationRunner animationRunner = new AnimationRunner(sourceNotification);
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/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index 85fac16..8f552e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -38,6 +38,8 @@
 public class DozeParameters implements TunerService.Tunable {
     private static final int MAX_DURATION = 60 * 1000;
     public static final String DOZE_SENSORS_WAKE_UP_FULLY = "doze_sensors_wake_up_fully";
+    public static final boolean FORCE_NO_BLANKING =
+            SystemProperties.getBoolean("debug.force_no_blanking", false);
 
     private static IntInOutMatcher sPickupSubtypePerformsProxMatcher;
     private static DozeParameters sInstance;
@@ -181,7 +183,7 @@
      * @return {@code true} if screen needs to be completely black before a power transition.
      */
     public boolean getDisplayNeedsBlanking() {
-        return mContext.getResources().getBoolean(
+        return !FORCE_NO_BLANKING && mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_displayBlanksAfterDoze);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
index c4a7814..76860e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -266,7 +266,9 @@
     }
 
     private void showBouncer() {
-        mStatusBarKeyguardViewManager.showBouncer(false);
+        if (calculateMode() == MODE_SHOW_BOUNCER) {
+            mStatusBarKeyguardViewManager.showBouncer(false);
+        }
         mStatusBarKeyguardViewManager.animateCollapsePanels(
                 FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR);
         mPendingShowBouncer = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index 9ec5609..06f3c50 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -36,7 +36,7 @@
 /**
  * Controls the appearance of heads up notifications in the icon area and the header itself.
  */
-class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
+public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
         DarkIconDispatcher.DarkReceiver {
     public static final int CONTENT_FADE_DURATION = 110;
     public static final int CONTENT_FADE_DELAY = 100;
@@ -92,6 +92,7 @@
         panelView.setHeadsUpAppearanceController(this);
         mStackScroller.addOnExpandedHeightListener(mSetExpandedHeight);
         mStackScroller.addOnLayoutChangeListener(mStackScrollLayoutChangeListener);
+        mStackScroller.setHeadsUpAppearanceController(this);
         mClockView = clockView;
         mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
         mDarkIconDispatcher.addDarkReceiver(this);
@@ -226,10 +227,10 @@
         });
     }
 
-    private void updateHeader(NotificationData.Entry entry) {
+    public void updateHeader(NotificationData.Entry entry) {
         ExpandableNotificationRow row = entry.row;
         float headerVisibleAmount = 1.0f;
-        if (row.isPinned() || row == mTrackedChild) {
+        if (row.isPinned() || row.isHeadsUpAnimatingAway() || row == mTrackedChild) {
             headerVisibleAmount = mExpandFraction;
         }
         row.setHeaderVisibleAmount(headerVisibleAmount);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index ca65965..55ffb3e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.app.Notification;
+import android.os.SystemClock;
 import android.service.notification.StatusBarNotification;
 import android.support.annotation.Nullable;
 import android.util.Log;
@@ -29,9 +31,11 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Objects;
 
 /**
  * A class to handle notifications and their corresponding groups.
@@ -39,12 +43,14 @@
 public class NotificationGroupManager implements OnHeadsUpChangedListener {
 
     private static final String TAG = "NotificationGroupManager";
+    private static final long HEADS_UP_TRANSFER_TIMEOUT = 300;
     private final HashMap<String, NotificationGroup> mGroupMap = new HashMap<>();
     private OnGroupChangeListener mListener;
     private int mBarState = -1;
     private HashMap<String, StatusBarNotification> mIsolatedEntries = new HashMap<>();
     private HeadsUpManager mHeadsUpManager;
     private boolean mIsUpdatingUnchangedGroup;
+    private HashMap<String, NotificationData.Entry> mPendingNotifications;
 
     public void setOnGroupChangeListener(OnGroupChangeListener listener) {
         mListener = listener;
@@ -147,6 +153,103 @@
                 mListener.onGroupCreatedFromChildren(group);
             }
         }
+        cleanUpHeadsUpStatesOnAdd(group, false /* addIsPending */);
+    }
+
+    public void onPendingEntryAdded(NotificationData.Entry shadeEntry) {
+        String groupKey = getGroupKey(shadeEntry.notification);
+        NotificationGroup group = mGroupMap.get(groupKey);
+        if (group != null) {
+            cleanUpHeadsUpStatesOnAdd(group, true /* addIsPending */);
+        }
+    }
+
+    /**
+     * Clean up the heads up states when a new child was added.
+     * @param group The group where a view was added or will be added.
+     * @param addIsPending True if is the addition still pending or false has it already been added.
+     */
+    private void cleanUpHeadsUpStatesOnAdd(NotificationGroup group, boolean addIsPending) {
+        if (!addIsPending && group.hunSummaryOnNextAddition) {
+            if (!mHeadsUpManager.isHeadsUp(group.summary.key)) {
+                mHeadsUpManager.showNotification(group.summary);
+            }
+            group.hunSummaryOnNextAddition = false;
+        }
+        // Because notification groups are not delivered as a whole unit, it may happen that a
+        // group child gets added quite a bit after the summary got posted. Our guidance is, that
+        // apps should always post the group summary as well and we'll hide it for them if the child
+        // is the only child in a group. Because of this, we also have to transfer heads up to the
+        // child, otherwise the invisible summary would be heads-upped.
+        // This transfer to the child is not always correct in case the app has just posted another
+        // child in addition to the existing one, but it hasn't arrived in systemUI yet. In such
+        // a scenario we would transfer the heads up to the old child and the wrong notification
+        // would be heads-upped. In oder to avoid this, we'll recover from this issue and hun the
+        // summary again instead of the old child if it's within a certain timeout.
+        if (SystemClock.elapsedRealtime() - group.lastHeadsUpTransfer < HEADS_UP_TRANSFER_TIMEOUT) {
+            if (!onlySummaryAlerts(group.summary)) {
+                return;
+            }
+            int numChildren = group.children.size();
+            NotificationData.Entry isolatedChild = getIsolatedChild(getGroupKey(
+                    group.summary.notification));
+            int numPendingChildren = getPendingChildrenNotAlerting(group);
+            numChildren += numPendingChildren;
+            if (isolatedChild != null) {
+                numChildren++;
+            }
+            if (numChildren <= 1) {
+                return;
+            }
+            boolean releasedChild = false;
+            ArrayList<NotificationData.Entry> children = new ArrayList<>(group.children.values());
+            int size = children.size();
+            for (int i = 0; i < size; i++) {
+                NotificationData.Entry entry = children.get(i);
+                if (onlySummaryAlerts(entry) && entry.row.isHeadsUp()) {
+                    releasedChild = true;
+                    mHeadsUpManager.releaseImmediately(entry.key);
+                }
+            }
+            if (isolatedChild != null && onlySummaryAlerts(isolatedChild)
+                    && isolatedChild.row.isHeadsUp()) {
+                releasedChild = true;
+                mHeadsUpManager.releaseImmediately(isolatedChild.key);
+            }
+            if (releasedChild && !mHeadsUpManager.isHeadsUp(group.summary.key)) {
+                boolean notifyImmediately = (numChildren - numPendingChildren) > 1;
+                if (notifyImmediately) {
+                    mHeadsUpManager.showNotification(group.summary);
+                } else {
+                    group.hunSummaryOnNextAddition = true;
+                }
+                group.lastHeadsUpTransfer = 0;
+            }
+        }
+    }
+
+    private int getPendingChildrenNotAlerting(NotificationGroup group) {
+        if (mPendingNotifications == null) {
+            return 0;
+        }
+        int number = 0;
+        String groupKey = getGroupKey(group.summary.notification);
+        Collection<NotificationData.Entry> values = mPendingNotifications.values();
+        for (NotificationData.Entry entry : values) {
+            if (!isGroupChild(entry.notification)) {
+                continue;
+            }
+            if (!Objects.equals(getGroupKey(entry.notification), groupKey)) {
+                continue;
+            }
+            if (group.children.containsKey(entry.key)) {
+                continue;
+            }
+            if (onlySummaryAlerts(entry)) {
+                number++;
+            }
+        }
+        return number;
     }
 
     private void onEntryBecomingChild(NotificationData.Entry entry) {
@@ -421,8 +524,16 @@
                 || !entry.row.isHeadsUp()) {
             return;
         }
+
         // The parent of a suppressed group got huned, lets hun the child!
         NotificationGroup notificationGroup = mGroupMap.get(sbn.getGroupKey());
+
+        if (pendingInflationsWillAddChildren(notificationGroup)) {
+            // New children will actually be added to this group, let's not transfer the heads
+            // up
+            return;
+        }
+
         if (notificationGroup != null) {
             Iterator<NotificationData.Entry> iterator
                     = notificationGroup.children.values().iterator();
@@ -438,6 +549,9 @@
                 if (mHeadsUpManager.isHeadsUp(child.key)) {
                     mHeadsUpManager.updateNotification(child, true);
                 } else {
+                    if (onlySummaryAlerts(entry)) {
+                        notificationGroup.lastHeadsUpTransfer = SystemClock.elapsedRealtime();
+                    }
                     mHeadsUpManager.showNotification(child);
                 }
             }
@@ -445,6 +559,35 @@
         mHeadsUpManager.releaseImmediately(entry.key);
     }
 
+    private boolean onlySummaryAlerts(NotificationData.Entry entry) {
+        return entry.notification.getNotification().getGroupAlertBehavior()
+                == Notification.GROUP_ALERT_SUMMARY;
+    }
+
+    /**
+     * Check if the pending inflations will add children to this group.
+     * @param group The group to check.
+     */
+    private boolean pendingInflationsWillAddChildren(NotificationGroup group) {
+        if (mPendingNotifications == null) {
+            return false;
+        }
+        Collection<NotificationData.Entry> values = mPendingNotifications.values();
+        String groupKey = getGroupKey(group.summary.notification);
+        for (NotificationData.Entry entry : values) {
+            if (!isGroupChild(entry.notification)) {
+                continue;
+            }
+            if (!Objects.equals(getGroupKey(entry.notification), groupKey)) {
+                continue;
+            }
+            if (!group.children.containsKey(entry.key)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private boolean shouldIsolate(StatusBarNotification sbn) {
         NotificationGroup notificationGroup = mGroupMap.get(sbn.getGroupKey());
         return (sbn.isGroup() && !sbn.getNotification().isGroupSummary())
@@ -477,6 +620,10 @@
         }
     }
 
+    public void setPendingEntries(HashMap<String, NotificationData.Entry> pendingNotifications) {
+        mPendingNotifications = pendingNotifications;
+    }
+
     public static class NotificationGroup {
         public final HashMap<String, NotificationData.Entry> children = new HashMap<>();
         public NotificationData.Entry summary;
@@ -485,6 +632,12 @@
          * Is this notification group suppressed, i.e its summary is hidden
          */
         public boolean suppressed;
+        /**
+         * The time when the last heads transfer from group to child happened, while the summary
+         * has the flags to heads up on its own.
+         */
+        public long lastHeadsUpTransfer;
+        public boolean hunSummaryOnNextAddition;
 
         @Override
         public String toString() {
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 b475b64..a3905b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -32,6 +32,8 @@
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.os.PowerManager;
 import android.util.AttributeSet;
@@ -250,6 +252,33 @@
     private ArrayList<Runnable> mVerticalTranslationListener = new ArrayList<>();
     private HeadsUpAppearanceController mHeadsUpAppearanceController;
 
+    private int mPanelAlpha;
+    private int mCurrentPanelAlpha;
+    private final Paint mAlphaPaint = new Paint();
+    private Runnable mPanelAlphaEndAction;
+    private AnimatorListenerAdapter mAnimatorListenerAdapter = new AnimatorListenerAdapter() {
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            if (mPanelAlphaEndAction != null) {
+                mPanelAlphaEndAction.run();
+            }
+        }
+    };
+    private final AnimatableProperty PANEL_ALPHA = AnimatableProperty.from(
+            "panelAlpha",
+            NotificationPanelView::setPanelAlphaInternal,
+            NotificationPanelView::getCurrentPanelAlpha,
+            R.id.panel_alpha_animator_tag,
+            R.id.panel_alpha_animator_start_tag,
+            R.id.panel_alpha_animator_end_tag);
+    private final AnimationProperties PANEL_ALPHA_OUT_PROPERTIES = new AnimationProperties()
+            .setDuration(150)
+            .setCustomInterpolator(PANEL_ALPHA.getProperty(), Interpolators.ALPHA_OUT);
+    private final AnimationProperties PANEL_ALPHA_IN_PROPERTIES = new AnimationProperties()
+            .setDuration(200)
+            .setAnimationFinishListener(mAnimatorListenerAdapter)
+            .setCustomInterpolator(PANEL_ALPHA.getProperty(), Interpolators.ALPHA_IN);
+
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
         setWillNotDraw(!DEBUG);
@@ -257,6 +286,8 @@
         mPowerManager = context.getSystemService(PowerManager.class);
         mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
         setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
+        mAlphaPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
+        setPanelAlpha(255, false /* animate */);
     }
 
     public void setStatusBar(StatusBar bar) {
@@ -2303,6 +2334,38 @@
     }
 
     @Override
+    protected void dispatchDraw(Canvas canvas) {
+        super.dispatchDraw(canvas);
+        if (mCurrentPanelAlpha != 255) {
+            canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), mAlphaPaint);
+        }
+    }
+
+    public float getCurrentPanelAlpha() {
+        return mCurrentPanelAlpha;
+    }
+
+    public boolean setPanelAlpha(int alpha, boolean animate) {
+        if (mPanelAlpha != alpha) {
+            mPanelAlpha = alpha;
+            PropertyAnimator.setProperty(this, PANEL_ALPHA, alpha,
+                    alpha == 255 ? PANEL_ALPHA_IN_PROPERTIES : PANEL_ALPHA_OUT_PROPERTIES, animate);
+            return true;
+        }
+        return false;
+    }
+
+    public void setPanelAlphaInternal(float alpha) {
+        mCurrentPanelAlpha = (int) alpha;
+        mAlphaPaint.setARGB(mCurrentPanelAlpha, 255, 255, 255);
+        invalidate();
+    }
+
+    public void setPanelAlphaEndAction(Runnable r) {
+        mPanelAlphaEndAction = r;
+    }
+
+    @Override
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
 
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..bef6944 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;
         }
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 65cb56c..5c14015 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -2081,7 +2081,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) {
@@ -5058,6 +5058,7 @@
         final boolean afterKeyguardGone = intent.isActivity()
                 && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
                 mLockscreenUserManager.getCurrentUserId());
+        final boolean wasOccluded = mIsOccluded;
         dismissKeyguardThenExecute(() -> {
             // TODO: Some of this code may be able to move to NotificationEntryManager.
             if (mHeadsUpManager != null && mHeadsUpManager.isHeadsUp(notificationKey)) {
@@ -5121,7 +5122,7 @@
                                 remoteInputText.toString());
                     }
                     RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation(
-                            row);
+                            row, wasOccluded);
                     try {
                         if (adapter != null) {
                             ActivityManager.getService()
@@ -5159,7 +5160,9 @@
                 if (parentToCancelFinal != null) {
                     removeNotification(parentToCancelFinal);
                 }
-                if (shouldAutoCancel(sbn)) {
+                if (shouldAutoCancel(sbn)
+                        || mRemoteInputManager.getKeysKeptForRemoteInput().contains(
+                                notificationKey)) {
                     // Automatically remove all notifications that we may have kept around longer
                     removeNotification(sbn);
                 }
@@ -5168,6 +5171,7 @@
             if (mStatusBarKeyguardViewManager.isShowing()
                     && mStatusBarKeyguardViewManager.isOccluded()) {
                 mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
+                collapsePanel(true /* animate */);
             } else {
                 new Thread(runnable).start();
             }
@@ -5252,7 +5256,7 @@
                 int launchResult = TaskStackBuilder.create(mContext)
                         .addNextIntentWithParentStack(intent)
                         .startActivities(getActivityOptions(
-                                mActivityLaunchAnimator.getLaunchAnimation(row)),
+                                mActivityLaunchAnimator.getLaunchAnimation(row, mIsOccluded)),
                                 new UserHandle(UserHandle.getUserId(appUid)));
                 mActivityLaunchAnimator.setLaunchResult(launchResult);
                 if (shouldCollapse()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index 06a56ff..e9bdc68 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -22,14 +22,12 @@
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewPropertyAnimator;
 import android.widget.FrameLayout;
 
 import com.android.internal.util.Preconditions;
-import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.NotificationPanelView;
 import com.android.systemui.statusbar.phone.StatusBarWindowView;
-import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 import java.util.function.Consumer;
 
@@ -39,13 +37,9 @@
 public class BrightnessMirrorController
         implements CallbackController<BrightnessMirrorController.BrightnessMirrorListener> {
 
-    private final static long TRANSITION_DURATION_OUT = 150;
-    private final static long TRANSITION_DURATION_IN = 200;
-
     private final StatusBarWindowView mStatusBarWindow;
-    private final NotificationStackScrollLayout mStackScroller;
     private final Consumer<Boolean> mVisibilityCallback;
-    private final View mNotificationPanel;
+    private final NotificationPanelView mNotificationPanel;
     private final ArraySet<BrightnessMirrorListener> mBrightnessMirrorListeners = new ArraySet<>();
     private final int[] mInt2Cache = new int[2];
     private View mBrightnessMirror;
@@ -55,38 +49,21 @@
         mStatusBarWindow = statusBarWindow;
         mBrightnessMirror = statusBarWindow.findViewById(R.id.brightness_mirror);
         mNotificationPanel = statusBarWindow.findViewById(R.id.notification_panel);
-        mStackScroller = statusBarWindow.findViewById(R.id.notification_stack_scroller);
+        mNotificationPanel.setPanelAlphaEndAction(() -> {
+            mBrightnessMirror.setVisibility(View.INVISIBLE);
+        });
         mVisibilityCallback = visibilityCallback;
     }
 
     public void showMirror() {
         mBrightnessMirror.setVisibility(View.VISIBLE);
-        mStackScroller.setFadingOut(true);
         mVisibilityCallback.accept(true);
-        outAnimation(mNotificationPanel.animate())
-                .withLayer();
+        mNotificationPanel.setPanelAlpha(0, true /* animate */);
     }
 
     public void hideMirror() {
         mVisibilityCallback.accept(false);
-        inAnimation(mNotificationPanel.animate())
-                .withLayer()
-                .withEndAction(() -> {
-                    mBrightnessMirror.setVisibility(View.INVISIBLE);
-                    mStackScroller.setFadingOut(false);
-                });
-    }
-
-    private ViewPropertyAnimator outAnimation(ViewPropertyAnimator a) {
-        return a.alpha(0.0f)
-                .setDuration(TRANSITION_DURATION_OUT)
-                .setInterpolator(Interpolators.ALPHA_OUT)
-                .withEndAction(null);
-    }
-    private ViewPropertyAnimator inAnimation(ViewPropertyAnimator a) {
-        return a.alpha(1.0f)
-                .setDuration(TRANSITION_DURATION_IN)
-                .setInterpolator(Interpolators.ALPHA_IN);
+        mNotificationPanel.setPanelAlpha(255, true /* animate */);
     }
 
     public void setLocation(View original) {
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/stack/AnimationProperties.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationProperties.java
index 2f6e658..47df226 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationProperties.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationProperties.java
@@ -31,6 +31,7 @@
     public long duration;
     public long delay;
     private ArrayMap<Property, Interpolator> mInterpolatorMap;
+    private AnimatorListenerAdapter mAnimatorListenerAdapter;
 
     /**
      * @return an animation filter for this animation.
@@ -48,7 +49,12 @@
      * @return a listener that should be run whenever any property finished its animation
      */
     public AnimatorListenerAdapter getAnimationFinishListener() {
-        return null;
+        return mAnimatorListenerAdapter;
+    }
+
+    public AnimationProperties setAnimationFinishListener(AnimatorListenerAdapter listener) {
+        mAnimatorListenerAdapter = listener;
+        return this;
     }
 
     public boolean wasAdded(View view) {
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 55ec142..2dd3d4e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -269,6 +269,12 @@
 
         updateGroupOverflow();
         row.setContentTransformationAmount(0, false /* isLastChild */);
+        // It doesn't make sense to keep old animations around, lets cancel them!
+        ExpandableNotificationRow.NotificationViewState viewState = row.getViewState();
+        if (viewState != null) {
+            viewState.cancelAnimations(row);
+            row.cancelAppearDrawing();
+        }
     }
 
     public void removeNotification(ExpandableNotificationRow row) {
@@ -1162,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 236ead0..ee70019 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -98,6 +98,7 @@
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.VisibilityLocationProvider;
 import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.ScrimController;
@@ -292,7 +293,7 @@
     private int[] mTempInt2 = new int[2];
     private boolean mGenerateChildOrderChangedEvent;
     private HashSet<Runnable> mAnimationFinishedRunnables = new HashSet<>();
-    private HashSet<View> mClearOverlayViewsWhenFinished = new HashSet<>();
+    private HashSet<ExpandableView> mClearTransientViewsWhenFinished = new HashSet<>();
     private HashSet<Pair<ExpandableNotificationRow, Boolean>> mHeadsUpChangeAnimations
             = new HashSet<>();
     private HeadsUpManagerPhone mHeadsUpManager;
@@ -413,6 +414,7 @@
     private int mAntiBurnInOffsetX;
     private ArrayList<BiConsumer<Float, Float>> mExpandedHeightListeners = new ArrayList<>();
     private int mHeadsUpInset;
+    private HeadsUpAppearanceController mHeadsUpAppearanceController;
 
     public NotificationStackScrollLayout(Context context) {
         this(context, null);
@@ -727,7 +729,7 @@
     }
 
     private void updateAlgorithmLayoutMinHeight() {
-        mAmbientState.setLayoutMinHeight(mQsExpanded && !onKeyguard() || isHeadsUpTransition()
+        mAmbientState.setLayoutMinHeight(mQsExpanded || isHeadsUpTransition()
                 ? getLayoutMinHeight() : 0);
     }
 
@@ -2451,7 +2453,6 @@
             }
             int finalHeight = ExpandableViewState.getFinalActualHeight(lastView);
             int finalBottom = finalTranslationY + finalHeight - lastView.getClipBottomAmount();
-            finalBottom = Math.min(finalBottom, getHeight());
             if (mAnimateNextBackgroundBottom
                     || mBottomAnimator == null && mCurrentBounds.bottom == finalBottom
                     || mBottomAnimator != null && mEndAnimationRect.bottom == finalBottom) {
@@ -2460,7 +2461,6 @@
             } else {
                 bottom = (int) (lastView.getTranslationY() + lastView.getActualHeight()
                         - lastView.getClipBottomAmount());
-                bottom = Math.min(bottom, getHeight());
             }
         } else {
             top = mTopPadding;
@@ -2473,7 +2473,7 @@
             top = Math.max(0, top);
         }
         mBackgroundBounds.top = top;
-        mBackgroundBounds.bottom = Math.min(getHeight(), Math.max(bottom, top));
+        mBackgroundBounds.bottom = Math.max(bottom, top);
     }
 
     private ActivatableNotificationView getFirstPinnedHeadsUp() {
@@ -2831,8 +2831,8 @@
             return false;
         }
         if (isClickedHeadsUp(child)) {
-            // An animation is already running, add it to the Overlay
-            mClearOverlayViewsWhenFinished.add(child);
+            // An animation is already running, add it transiently
+            mClearTransientViewsWhenFinished.add((ExpandableView) child);
             return true;
         }
         if (mIsExpanded && mAnimationsEnabled && !isChildInInvisibleGroup(child)) {
@@ -3079,8 +3079,10 @@
 
     @Override
     public void bindRow(ExpandableNotificationRow row) {
-        row.setHeadsUpAnimatingAwayListener(animatingAway
-                -> mRoundnessManager.onHeadsupAnimatingAwayChanged(row, animatingAway));
+        row.setHeadsUpAnimatingAwayListener(animatingAway -> {
+            mRoundnessManager.onHeadsupAnimatingAwayChanged(row, animatingAway);
+            mHeadsUpAppearanceController.updateHeader(row.getEntry());
+        });
     }
 
     @Override
@@ -3202,6 +3204,7 @@
                 if (row.isChildInGroup()) {
                     // We can otherwise get stuck in there if it was just isolated
                     row.setHeadsUpAnimatingAway(false);
+                    continue;
                 }
             } else {
                 ExpandableViewState viewState = mCurrentStackScrollState.getViewStateForView(row);
@@ -3622,7 +3625,7 @@
     }
 
     private void clearTemporaryViews() {
-        // lets make sure nothing is in the overlay / transient anymore
+        // lets make sure nothing is transient anymore
         clearTemporaryViewsInGroup(this);
         for (int i = 0; i < getChildCount(); i++) {
             ExpandableView child = (ExpandableView) getChildAt(i);
@@ -3637,9 +3640,6 @@
         while (viewGroup != null && viewGroup.getTransientViewCount() != 0) {
             viewGroup.removeTransientView(viewGroup.getTransientView(0));
         }
-        if (viewGroup != null) {
-            viewGroup.getOverlay().clear();
-        }
     }
 
     public void onPanelTrackingStarted() {
@@ -3747,7 +3747,7 @@
         setAnimationRunning(false);
         requestChildrenUpdate();
         runAnimationFinishedRunnables();
-        clearViewOverlays();
+        clearTransient();
         clearHeadsUpDisappearRunning();
     }
 
@@ -3766,11 +3766,11 @@
         }
     }
 
-    private void clearViewOverlays() {
-        for (View view : mClearOverlayViewsWhenFinished) {
-            StackStateAnimator.removeFromOverlay(view);
+    private void clearTransient() {
+        for (ExpandableView view : mClearTransientViewsWhenFinished) {
+            StackStateAnimator.removeTransientView(view);
         }
-        mClearOverlayViewsWhenFinished.clear();
+        mClearTransientViewsWhenFinished.clear();
     }
 
     private void runAnimationFinishedRunnables() {
@@ -4638,6 +4638,11 @@
         mExpandedHeightListeners.remove(listener);
     }
 
+    public void setHeadsUpAppearanceController(
+            HeadsUpAppearanceController headsUpAppearanceController) {
+        mHeadsUpAppearanceController = headsUpAppearanceController;
+    }
+
     /**
      * A listener that is notified when the empty space below the notifications is clicked on
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index f4d7f8d..85f33d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -478,6 +478,22 @@
                 childState.hidden = false;
             }
         }
+        // Let's hide all the views if we are not expanded. the views might otherwise be visible
+        // in the headsup area if a view was swiped away
+        if (!mIsExpanded) {
+            for (int i = 0; i < childCount; i++) {
+                boolean visible = false;
+                View child = algorithmState.visibleChildren.get(i);
+                if (child instanceof ExpandableNotificationRow) {
+                    ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+                    visible = row.isHeadsUp() || row.isHeadsUpAnimatingAway();
+                }
+                if (!visible) {
+                    ExpandableViewState childState = resultState.getViewStateForView(child);
+                    childState.hidden = true;
+                }
+            }
+        }
     }
 
     private void clampHunToTop(AmbientState ambientState, ExpandableNotificationRow row,
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 d01db14..4e8fcac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -419,9 +419,6 @@
                 }, null);
             } else if (event.animationType ==
                 NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT) {
-                // A race condition can trigger the view to be added to the overlay even though
-                // it was fully swiped out. So let's remove it
-                mHostLayout.getOverlay().remove(changingView);
                 if (Math.abs(changingView.getTranslation()) == changingView.getWidth()
                         && changingView.getTransientContainer() != null) {
                     changingView.getTransientContainer().removeTransientView(changingView);
@@ -469,8 +466,9 @@
                         ? ANIMATION_DELAY_HEADS_UP_CLICKED
                         : 0;
                 if (changingView.getParent() == null) {
-                    // This notification was actually removed, so we need to add it to the overlay
-                    mHostLayout.getOverlay().add(changingView);
+                    // This notification was actually removed, so we need to add it transiently
+                    mHostLayout.addTransientView(changingView, 0);
+                    changingView.setTransientContainer(mHostLayout);
                     mTmpState.initFrom(changingView);
                     mTmpState.yTranslation = 0;
                     // We temporarily enable Y animations, the real filter will be combined
@@ -479,10 +477,7 @@
                     mAnimationProperties.delay = extraDelay + ANIMATION_DELAY_HEADS_UP;
                     mAnimationProperties.duration = ANIMATION_DURATION_HEADS_UP_DISAPPEAR;
                     mTmpState.animateTo(changingView, mAnimationProperties);
-                    endRunnable = () -> {
-                        // remove the temporary overlay
-                        removeFromOverlay(changingView);
-                    };
+                    endRunnable = () -> removeTransientView(changingView);
                 }
                 float targetLocation = 0;
                 boolean needsAnimation = true;
@@ -517,19 +512,12 @@
         }
     }
 
-    private static void removeTransientView(ExpandableView viewToRemove) {
+    public static void removeTransientView(ExpandableView viewToRemove) {
         if (viewToRemove.getTransientContainer() != null) {
             viewToRemove.getTransientContainer().removeTransientView(viewToRemove);
         }
     }
 
-    public static void removeFromOverlay(View changingView) {
-        ViewGroup parent = (ViewGroup) changingView.getParent();
-        if (parent != null) {
-            parent.removeView(changingView);
-        }
-    }
-
     public void animateOverScrollToAmount(float targetAmount, final boolean onTop,
             final boolean isRubberbanded) {
         final float startOverScrollAmount = mHostLayout.getCurrentOverScrollAmount(onTop);
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index 611d4eb..1bdb7ad 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -54,6 +54,7 @@
     // shouldn't be reset with tuner settings.
     private static final String[] RESET_BLACKLIST = new String[] {
             QSTileHost.TILES_SETTING,
+            Settings.Secure.DOZE_ALWAYS_ON
     };
 
     private final Observer mObserver = new Observer();
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/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..f05cf6b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
@@ -100,7 +100,6 @@
 
     private NotificationData.Entry mEntry;
     private StatusBarNotification mSbn;
-    private Handler mHandler;
     private TestableNotificationEntryManager mEntryManager;
     private CountDownLatch mCountDownLatch;
 
@@ -160,10 +159,9 @@
         mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
         mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
 
-        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 +186,7 @@
     @Test
     public void testAddNotification() throws Exception {
         com.android.systemui.util.Assert.isNotMainThread();
+        TestableLooper.get(this).processAllMessages();
 
         doAnswer(invocation -> {
             mCountDownLatch.countDown();
@@ -196,12 +195,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 +225,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,10 +255,7 @@
         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());
@@ -287,12 +280,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 +295,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();
     }
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..c6397e6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
@@ -59,7 +59,6 @@
     @Mock private NotificationRemoteInputManager mRemoteInputManager;
 
     private NotificationListener mListener;
-    private Handler mHandler;
     private StatusBarNotification mSbn;
     private Set<String> mKeysKeptForRemoteInput;
 
@@ -70,10 +69,9 @@
         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);
 
@@ -87,7 +85,7 @@
     @Test
     public void testNotificationAddCallsAddNotification() {
         mListener.onNotificationPosted(mSbn, mRanking);
-        waitForIdleSync(mHandler);
+        TestableLooper.get(this).processAllMessages();
         verify(mEntryManager).addNotification(mSbn, mRanking);
     }
 
@@ -95,7 +93,7 @@
     public void testPostNotificationRemovesKeyKeptForRemoteInput() {
         mKeysKeptForRemoteInput.add(mSbn.getKey());
         mListener.onNotificationPosted(mSbn, mRanking);
-        waitForIdleSync(mHandler);
+        TestableLooper.get(this).processAllMessages();
         assertTrue(mKeysKeptForRemoteInput.isEmpty());
     }
 
@@ -103,21 +101,21 @@
     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..bbb03d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLoggerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLoggerTest.java
@@ -26,7 +26,6 @@
 import android.os.Handler;
 import android.os.Looper;
 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 +34,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;
 
@@ -48,7 +46,7 @@
 
 @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;
@@ -89,7 +87,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();
 
         NotificationVisibility[] newlyVisibleKeys = {
@@ -101,7 +99,7 @@
         // |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 +111,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 +126,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..8b2f6cd 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);
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/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/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/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 95dc3ab..083598d 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -188,6 +188,23 @@
     ACCESS_METHOD_LINKING = 3; // never logged, included for completeness
   }
 
+  enum HardwareType {
+        HARDWARE_UNKNOWN = 0;
+        HARDWARE_MICROPHONE = 1;
+        HARDWARE_CODEC = 2;
+        HARDWARE_SPEAKER = 3;
+        HARDWARE_FINGERPRINT = 4;
+    }
+
+    enum HardwareFailureCode {
+        HARDWARE_FAILURE_UNKNOWN = 0;
+        HARDWARE_FAILURE_COMPLETE = 1;
+        HARDWARE_FAILURE_SPEAKER_HIGH_Z = 2;
+        HARDWARE_FAILURE_SPEAKER_SHORT = 3;
+        HARDWARE_FAILURE_FINGERPRINT_SENSOR_BROKEN = 4;
+        HARDWARE_FAILURE_FINGERPRINT_TOO_MANY_DEAD_PIXELS = 5;
+    }
+
   // Known visual elements: views or controls.
   enum View {
     // Unknown view
@@ -5296,11 +5313,11 @@
     // OS: P
     FIELD_DURATION_MILLIS = 1304;
 
-    // Battery level in uA (0 - ~3,000,000 depending on device) when the current "mode" started.
+    // Battery level in uAh (0 - ~3,000,000 depending on device) when the current "mode" started.
     // OS: P
     FIELD_START_BATTERY_UA = 1305;
 
-    // Battery level in uA (0 - ~3,000,000 depending on device) when this event was created.
+    // Battery level in uAh (0 - ~3,000,000 depending on device) when this event was created.
     // OS: P
     FIELD_END_BATTERY_UA = 1306;
 
@@ -5329,7 +5346,6 @@
     // OS: P
     FIELD_QS_MODE = 1311;
 
-
     // OPEN: Settings->Developer Options->Default USB
     // CATEGORY: SETTINGS
     // OS: P
@@ -5733,8 +5749,8 @@
     // OS: P
     FIELD_HIDDEN_API_SIGNATURE = 1394;
 
-    // This value should never appear in log outputs - it is reserved for
-    // internal platform metrics use.
+    // The number of items in the shade when this notification event was logged.
+    // OS: P
     NOTIFICATION_SHADE_COUNT = 1395;
 
     // ACTION: DND Settings > What to block
@@ -5852,6 +5868,112 @@
     // 3 = Wireless
     FIELD_PLUG_TYPE = 1421;
 
+    // ACTION: USB-C Connector connected.
+    // CATEGORY: OTHER
+    // OS: P
+    ACTION_USB_CONNECTOR_CONNECTED = 1422;
+
+    // ACTION: USB-C Connector disconnected.
+    // CATEGORY: OTHER
+    // OS: P
+    // uses FIELD_DURATION_MILLIS for connected duration
+    ACTION_USB_CONNECTOR_DISCONNECTED = 1423;
+
+    // ACTION: USB-C Audio device connected
+    // CATEGORY: OTHER
+    // OS: P
+    ACTION_USB_AUDIO_CONNECTED = 1424;
+
+    // FIELD: VIDPID of connected USB Audio device
+    // CATEGORY: OTHER
+    // OS: P
+    FIELD_USB_AUDIO_VIDPID = 1425;
+
+    // ACTION: USB-C Audio device disconnected
+    // CATEGORY: OTHER
+    // OS: P
+    // use FIELD_DURATION_MILLIS for time
+    ACTION_USB_AUDIO_DISCONNECTED = 1426;
+
+    // ACTION: Hardware failure event
+    // CATEGORY: OTHER
+    // OS: P
+    ACTION_HARDWARE_FAILED = 1427;
+
+    // FIELD: Hardware failure category
+    // CATEGORY: OTHER
+    // OS: P
+    // Uses enum HardwareType
+    FIELD_HARDWARE_TYPE = 1428;
+
+    // FIELD: Hardware failure category
+    // CATEGORY: OTHER
+    // OS: P
+    // Uses enum HardwareFailureCode
+    FIELD_HARDWARE_FAILURE_CODE = 1429;
+
+    // ACTION: Physical drop event
+    // CATEGORY: OTHER
+    // OS: P
+    // use FIELD_DURATION_MILLIS for time
+    ACTION_PHYSICAL_DROP = 1430;
+
+    // FIELD: Confidence in detection of drop, in integer percentage.
+    // CATEGORY: OTHER
+    // OS: P
+    FIELD_CONFIDENCE_PERCENT = 1431;
+
+    // FIELD: Detected bounce acceleration, in 1/1000th of a G.
+    // CATEGORY: OTHER
+    // OS: P
+    FIELD_ACCEL_MILLI_G = 1432;
+
+    // ACTION: Battery health snapshot
+    // CATEGORY: OTHER
+    // OS: P
+    // uses FIELD_END_BATTERY_PERCENT for batt %
+    // uses FIELD_END_BATTERY_UA for instantaneous current load
+    ACTION_BATTERY_HEALTH = 1433;
+
+    // FIELD: Battery health snapshot type - min daily voltage, resistance, etc.
+    // CATEGORY: OTHER
+    // OS: P
+    FIELD_BATTERY_HEALTH_SNAPSHOT_TYPE = 1434;
+
+    // FIELD: Battery temperature at snapshop.
+    // CATEGORY: OTHER
+    // OS: P
+    FIELD_BATTERY_TEMPERATURE = 1435;
+
+    // FIELD: Battery voltage at snapshot.
+    // CATEGORY: OTHER
+    // OS: P
+    FIELD_BATTERY_VOLTAGE = 1436;
+
+    // FIELD: Battery open circuit voltage at snapshot.
+    // CATEGORY: OTHER
+    // OS: P
+    FIELD_BATTERY_OPEN_CIRCUIT_VOLTAGE = 1437;
+
+    // ACTION: Battery charge cycles
+    //         Number of times the battery has charged beyond a
+    //         fractional threshold of full capacity.
+    // CATEGORY: OTHER
+    // OS: P
+    ACTION_BATTERY_CHARGE_CYCLES = 1438;
+
+    // FIELD: Battery charge cycles
+    //        Number of times the battery has charged beyond a
+    //        fractional threshold of full capacity.
+    // CATEGORY: OTHER
+    // OS: P
+    FIELD_BATTERY_CHARGE_CYCLES = 1439;
+
+    // ACTION: Hush gesture - volume up + power button
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: P
+    ACTION_HUSH_GESTURE = 1440;
+
     // ---- 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/system_messages.proto b/proto/src/system_messages.proto
index f9af31c..a9a14ca 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -184,19 +184,19 @@
     NOTE_USB_AUDIO_ACCESSORY_NOT_SUPPORTED = 41;
 
     // Inform the user that a wrong password was detected while attempting to connect
-    // to a Wi-Fi network
+    // to a wifi network
     NOTE_WIFI_WRONG_PASSWORD = 42;
 
     // Inform the user that Wifi Wake will re-enable wifi when possible
     NOTE_WIFI_WAKE_ONBOARD = 43;
 
-    // Inform the user that Wifi Wake has automatically re-enabled Wifi
+    // Inform the user that Wifi Wake has automatically re-enabled wifi
     NOTE_WIFI_WAKE_TURNED_BACK_ON = 44;
 
     // Inform the user that unexpectedly rapid network usage is happening
     NOTE_NET_RAPID = 45;
 
-    // Notify the user that carrier Wi-Fi networks are available.
+    // Notify the user that carrier wifi networks are available.
     // Package: android
     NOTE_CARRIER_NETWORK_AVAILABLE = 46;
 
@@ -248,10 +248,10 @@
     // Package: com.android.systemui
     NOTE_TV_PIP = 1100;
 
-    // Extreme battery saver notifiaction.
+    // Extreme battery saver notification.
     NOTE_BATTERY_SAVER_WARNING = 1200;
 
-    // Notify the user that open Wi-Fi networks are available.
+    // Notify the user that open wifi networks are available.
     // Package: android
     NOTE_NETWORK_AVAILABLE = 17303299;
 
@@ -261,7 +261,6 @@
 
     // Notify the user about public volume state changes..
     // Package: com.android.systemui
-
     NOTE_STORAGE_PUBLIC = 0x53505542;  // 1397773634
 
     // Notify the user about private volume state changes.
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index f992049..db8ad12 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -20,6 +20,8 @@
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 
+import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
+
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.AlarmManager;
@@ -50,6 +52,7 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
@@ -96,13 +99,13 @@
 import android.widget.RemoteViews;
 
 import com.android.internal.R;
+import com.android.internal.app.SuspendedAppActivity;
 import com.android.internal.app.UnlaunchableAppActivity;
 import com.android.internal.appwidget.IAppWidgetHost;
 import com.android.internal.appwidget.IAppWidgetService;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.widget.IRemoteViewsFactory;
@@ -110,7 +113,6 @@
 import com.android.server.WidgetBackupProvider;
 import com.android.server.policy.IconUtilities;
 
-import libcore.util.EmptyArray;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -228,6 +230,7 @@
     private AppOpsManager mAppOpsManager;
     private KeyguardManager mKeyguardManager;
     private DevicePolicyManagerInternal mDevicePolicyManagerInternal;
+    private PackageManagerInternal mPackageManagerInternal;
 
     private SecurityPolicy mSecurityPolicy;
 
@@ -254,6 +257,7 @@
         mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
         mKeyguardManager = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE);
         mDevicePolicyManagerInternal = LocalServices.getService(DevicePolicyManagerInternal.class);
+        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
         mSaveStateHandler = BackgroundThread.getHandler();
         mCallbackHandler = new CallbackHandler(mContext.getMainLooper());
         mBackupRestoreController = new BackupRestoreController();
@@ -620,8 +624,17 @@
             if (provider.maskedBySuspendedPackage) {
                 UserInfo userInfo = mUserManager.getUserInfo(providerUserId);
                 showBadge = userInfo.isManagedProfile();
-                onClickIntent = mDevicePolicyManagerInternal.createShowAdminSupportIntent(
-                        providerUserId, true);
+                final String suspendingPackage = mPackageManagerInternal.getSuspendingPackage(
+                        providerPackage, providerUserId);
+                if (PLATFORM_PACKAGE_NAME.equals(suspendingPackage)) {
+                    onClickIntent = mDevicePolicyManagerInternal.createShowAdminSupportIntent(
+                            providerUserId, true);
+                } else {
+                    final String dialogMessage = mPackageManagerInternal.getSuspendedDialogMessage(
+                            providerPackage, providerUserId);
+                    onClickIntent = SuspendedAppActivity.createSuspendedAppInterceptIntent(
+                            providerPackage, suspendingPackage, dialogMessage, providerUserId);
+                }
             } else if (provider.maskedByQuietProfile) {
                 showBadge = true;
                 onClickIntent = UnlaunchableAppActivity.createInQuietModeDialogIntent(
@@ -824,6 +837,12 @@
         mSecurityPolicy.enforceCallFromPackage(callingPackage);
 
         synchronized (mLock) {
+            // Instant apps cannot host app widgets.
+            if (mSecurityPolicy.isInstantAppLocked(callingPackage, userId)) {
+                Slog.w(TAG, "Instant package " + callingPackage + " cannot host app widgets");
+                return ParceledListSlice.emptyList();
+            }
+
             ensureGroupStateLoadedLocked(userId);
 
             // NOTE: The lookup is enforcing security across users by making
@@ -890,6 +909,12 @@
         mSecurityPolicy.enforceCallFromPackage(callingPackage);
 
         synchronized (mLock) {
+            // Instant apps cannot host app widgets.
+            if (mSecurityPolicy.isInstantAppLocked(callingPackage, userId)) {
+                Slog.w(TAG, "Instant package " + callingPackage + " cannot host app widgets");
+                return AppWidgetManager.INVALID_APPWIDGET_ID;
+            }
+
             ensureGroupStateLoadedLocked(userId);
 
             if (mNextAppWidgetIds.indexOfKey(userId) < 0) {
@@ -1621,6 +1646,13 @@
 
     @Override
     public boolean isRequestPinAppWidgetSupported() {
+        synchronized (mLock) {
+            if (mSecurityPolicy.isCallerInstantAppLocked()) {
+                Slog.w(TAG, "Instant uid " + Binder.getCallingUid()
+                        + " query information about app widgets");
+                return false;
+            }
+        }
         return LocalServices.getService(ShortcutServiceInternal.class)
                 .isRequestPinItemSupported(UserHandle.getCallingUserId(),
                         LauncherApps.PinItemRequest.REQUEST_TYPE_APPWIDGET);
@@ -1671,6 +1703,12 @@
         }
 
         synchronized (mLock) {
+            if (mSecurityPolicy.isCallerInstantAppLocked()) {
+                Slog.w(TAG, "Instant uid " + Binder.getCallingUid()
+                        + " cannot access widget providers");
+                return ParceledListSlice.emptyList();
+            }
+
             ensureGroupStateLoadedLocked(userId);
 
             ArrayList<AppWidgetProviderInfo> result = new ArrayList<AppWidgetProviderInfo>();
@@ -3652,6 +3690,35 @@
                     "hasBindAppWidgetPermission packageName=" + packageName);
         }
 
+        public boolean isCallerInstantAppLocked() {
+            final int callingUid =  Binder.getCallingUid();
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                final String[] uidPackages = mPackageManager.getPackagesForUid(callingUid);
+                if (!ArrayUtils.isEmpty(uidPackages)) {
+                    return mPackageManager.isInstantApp(uidPackages[0],
+                            UserHandle.getCallingUserId());
+                }
+            } catch (RemoteException e) {
+                /* ignore - same process */
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+            return false;
+        }
+
+        public boolean isInstantAppLocked(String packageName, int userId) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                return mPackageManager.isInstantApp(packageName, userId);
+            } catch (RemoteException e) {
+                /* ignore - same process */
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+            return false;
+        }
+
         public void enforceCallFromPackage(String packageName) {
             mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
         }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 9b833f7..21398e3 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -588,7 +588,7 @@
 
     private void addCompatibilityModeRequestsLocked(@NonNull AutofillManagerServiceImpl service
             , int userId) {
-        mAutofillCompatState.reset();
+        mAutofillCompatState.reset(userId);
         final ArrayMap<String, Long> compatPackages =
                 service.getCompatibilityPackagesLocked();
         if (compatPackages == null || compatPackages.isEmpty()) {
@@ -721,6 +721,9 @@
     static final class AutofillCompatState {
         private final Object mLock = new Object();
 
+        /**
+         * Map of app->compat_state per user.
+         */
         @GuardedBy("mLock")
         private SparseArray<ArrayMap<String, PackageCompatState>> mUserSpecs;
 
@@ -787,11 +790,17 @@
             }
         }
 
-        void reset() {
+        void reset(int userId) {
             synchronized (mLock) {
                 if (mUserSpecs != null) {
-                    mUserSpecs.clear();
-                    mUserSpecs = null;
+                    mUserSpecs.delete(userId);
+                    final int newSize = mUserSpecs.size();
+                    if (newSize == 0) {
+                        if (sVerbose) Slog.v(TAG, "reseting mUserSpecs");
+                        mUserSpecs = null;
+                    } else {
+                        if (sVerbose) Slog.v(TAG, "mUserSpecs down to " + newSize);
+                    }
                 }
             }
         }
@@ -806,7 +815,7 @@
              for (int i = 0; i < mUserSpecs.size(); i++) {
                  final int user = mUserSpecs.keyAt(i);
                  pw.print(prefix); pw.print("User: "); pw.println(user);
-                 final ArrayMap<String,PackageCompatState> perUser = mUserSpecs.get(i);
+                 final ArrayMap<String, PackageCompatState> perUser = mUserSpecs.valueAt(i);
                  for (int j = 0; j < perUser.size(); j++) {
                      final String packageName = perUser.keyAt(j);
                      final PackageCompatState state = perUser.valueAt(j);
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 169f2a8..3beebcb 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -21,6 +21,7 @@
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
+import android.app.AppOpsManagerInternal;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -94,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;
 
@@ -172,6 +174,9 @@
     final AtomicFile mFile;
     final Handler mHandler;
 
+    private final AppOpsManagerInternalImpl mAppOpsManagerInternal
+            = new AppOpsManagerInternalImpl();
+
     boolean mWriteScheduled;
     boolean mFastWriteScheduled;
     final Runnable mWriteRunner = new Runnable() {
@@ -200,6 +205,8 @@
      */
     private final ArrayMap<IBinder, ClientRestrictionState> mOpUserRestrictions = new ArrayMap<>();
 
+    SparseIntArray mProfileOwners;
+
     /**
      * All times are in milliseconds. These constants are kept synchronized with the system
      * global Settings. Any access to this class or its fields should be done while
@@ -207,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;
@@ -250,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();
         }
     }
@@ -298,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;
@@ -551,6 +584,7 @@
     public void publish(Context context) {
         mContext = context;
         ServiceManager.addService(Context.APP_OPS_SERVICE, asBinder());
+        LocalServices.addService(AppOpsManagerInternal.class, mAppOpsManagerInternal);
     }
 
     public void systemReady() {
@@ -721,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
@@ -921,12 +963,27 @@
         }
     }
 
+    void enforceManageAppOpsModes(int callingPid, int callingUid, int targetUid) {
+        if (callingPid == Process.myPid()) {
+            return;
+        }
+        final int callingUser = UserHandle.getUserId(callingUid);
+        synchronized (this) {
+            if (mProfileOwners != null && mProfileOwners.get(callingUser, -1) == callingUid) {
+                if (targetUid >= 0 && callingUser == UserHandle.getUserId(targetUid)) {
+                    // Profile owners are allowed to change modes but only for apps
+                    // within their user.
+                    return;
+                }
+            }
+        }
+        mContext.enforcePermission(android.Manifest.permission.MANAGE_APP_OPS_MODES,
+                Binder.getCallingPid(), Binder.getCallingUid(), null);
+    }
+
     @Override
     public void setUidMode(int code, int uid, int mode) {
-        if (Binder.getCallingPid() != Process.myPid()) {
-            mContext.enforcePermission(android.Manifest.permission.MANAGE_APP_OPS_MODES,
-                    Binder.getCallingPid(), Binder.getCallingUid(), null);
-        }
+        enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid);
         verifyIncomingOp(code);
         code = AppOpsManager.opToSwitch(code);
 
@@ -1029,10 +1086,7 @@
 
     @Override
     public void setMode(int code, int uid, String packageName, int mode) {
-        if (Binder.getCallingPid() != Process.myPid()) {
-            mContext.enforcePermission(android.Manifest.permission.MANAGE_APP_OPS_MODES,
-                    Binder.getCallingPid(), Binder.getCallingUid(), null);
-        }
+        enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid);
         verifyIncomingOp(code);
         ArraySet<ModeCallback> repCbs = null;
         code = AppOpsManager.opToSwitch(code);
@@ -1151,8 +1205,6 @@
     public void resetAllModes(int reqUserId, String reqPackageName) {
         final int callingPid = Binder.getCallingPid();
         final int callingUid = Binder.getCallingUid();
-        mContext.enforcePermission(android.Manifest.permission.MANAGE_APP_OPS_MODES,
-                callingPid, callingUid, null);
         reqUserId = ActivityManager.handleIncomingUser(callingPid, callingUid, reqUserId,
                 true, true, "resetAllModes", null);
 
@@ -1166,6 +1218,8 @@
             }
         }
 
+        enforceManageAppOpsModes(callingPid, callingUid, reqUid);
+
         HashMap<ModeCallback, ArrayList<ChangeRec>> callbacks = null;
         synchronized (this) {
             boolean changed = false;
@@ -1428,10 +1482,9 @@
     @Override
     public void setAudioRestriction(int code, int usage, int uid, int mode,
             String[] exceptionPackages) {
+        enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid);
         verifyIncomingUid(uid);
         verifyIncomingOp(code);
-        mContext.enforcePermission(android.Manifest.permission.MANAGE_APP_OPS_MODES,
-                Binder.getCallingPid(), Binder.getCallingUid(), null);
         synchronized (this) {
             SparseArray<Restriction> usageRestrictions = mAudioRestrictions.get(code);
             if (usageRestrictions == null) {
@@ -1840,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;
@@ -2809,9 +2864,8 @@
                     return 0;
                 }
                 case "write-settings": {
-                    shell.mInternal.mContext.enforcePermission(
-                            android.Manifest.permission.MANAGE_APP_OPS_MODES,
-                            Binder.getCallingPid(), Binder.getCallingUid(), null);
+                    shell.mInternal.enforceManageAppOpsModes(Binder.getCallingPid(),
+                            Binder.getCallingUid(), -1);
                     long token = Binder.clearCallingIdentity();
                     try {
                         synchronized (shell.mInternal) {
@@ -2825,9 +2879,8 @@
                     return 0;
                 }
                 case "read-settings": {
-                    shell.mInternal.mContext.enforcePermission(
-                            android.Manifest.permission.MANAGE_APP_OPS_MODES,
-                            Binder.getCallingPid(), Binder.getCallingUid(), null);
+                    shell.mInternal.enforceManageAppOpsModes(Binder.getCallingPid(),
+                            Binder.getCallingUid(), -1);
                     long token = Binder.clearCallingIdentity();
                     try {
                         shell.mInternal.readState();
@@ -2989,6 +3042,17 @@
             final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
             final Date date = new Date();
             boolean needSep = false;
+            if (dumpOp < 0 && dumpMode < 0 && dumpPackage == null && mProfileOwners != null) {
+                pw.println("  Profile owners:");
+                for (int poi = 0; poi < mProfileOwners.size(); poi++) {
+                    pw.print("    User #");
+                    pw.print(mProfileOwners.keyAt(poi));
+                    pw.print(": ");
+                    UserHandle.formatUid(pw, mProfileOwners.valueAt(poi));
+                    pw.println();
+                }
+                pw.println();
+            }
             if (mOpModeWatchers.size() > 0) {
                 boolean printedHeader = false;
                 for (int i=0; i<mOpModeWatchers.size(); i++) {
@@ -3702,4 +3766,12 @@
             return true;
         }
     }
+
+    private final class AppOpsManagerInternalImpl extends AppOpsManagerInternal {
+        @Override public void setDeviceAndProfileOwners(SparseIntArray owners) {
+            synchronized (AppOpsService.this) {
+                mProfileOwners = owners;
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 00302b2..183be9b 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -2795,7 +2795,7 @@
             final String uuid = null;
             final String state = Environment.MEDIA_REMOVED;
 
-            res.add(0, new StorageVolume(id, path,
+            res.add(0, new StorageVolume(id, path, path,
                     description, primary, removable, emulated,
                     allowMassStorage, maxFileSize, owner, uuid, state));
         }
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index b32ece7..6f572df 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -476,12 +476,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);
@@ -3592,6 +3603,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/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index 27eae57..698b6f7 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -800,6 +800,20 @@
         }
     }
 
+    /**
+     * See {@link DisplayWindowController#deferUpdateImeTarget()}
+     */
+    public void deferUpdateImeTarget() {
+        mWindowContainerController.deferUpdateImeTarget();
+    }
+
+    /**
+     * See {@link DisplayWindowController#deferUpdateImeTarget()}
+     */
+    public void continueUpdateImeTarget() {
+        mWindowContainerController.continueUpdateImeTarget();
+    }
+
     public void dump(PrintWriter pw, String prefix) {
         pw.println(prefix + "displayId=" + mDisplayId + " stacks=" + mStacks.size());
         final String myPrefix = prefix + " ";
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f83d9e6..70648c6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -21455,6 +21455,7 @@
                             return ActivityManager.BROADCAST_SUCCESS;
                         }
                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
+                        mServices.updateServiceApplicationInfoLocked(aInfo);
                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
                                 new String[] {ssp}, userId);
                     }
@@ -22011,12 +22012,13 @@
                     doNext = r.queue.finishReceiverLocked(r, resultCode,
                         resultData, resultExtras, resultAbort, true);
                 }
+                if (doNext) {
+                    r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
+                }
+                // updateOomAdjLocked() will be done here
+                trimApplicationsLocked();
             }
 
-            if (doNext) {
-                r.queue.processNextBroadcast(false);
-            }
-            trimApplications();
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
@@ -25747,40 +25749,43 @@
 
     final void trimApplications() {
         synchronized (this) {
-            int i;
+            trimApplicationsLocked();
+        }
+    }
 
-            // First remove any unused application processes whose package
-            // has been removed.
-            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
-                final ProcessRecord app = mRemovedProcesses.get(i);
-                if (app.activities.size() == 0 && app.recentTasks.size() == 0
-                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
-                    Slog.i(
-                        TAG, "Exiting empty application process "
-                        + app.toShortString() + " ("
-                        + (app.thread != null ? app.thread.asBinder() : null)
-                        + ")\n");
-                    if (app.pid > 0 && app.pid != MY_PID) {
-                        app.kill("empty", false);
-                    } else if (app.thread != null) {
-                        try {
-                            app.thread.scheduleExit();
-                        } catch (Exception e) {
-                            // Ignore exceptions.
-                        }
-                    }
-                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
-                    mRemovedProcesses.remove(i);
-
-                    if (app.persistent) {
-                        addAppLocked(app.info, null, false, null /* ABI override */);
+    final void trimApplicationsLocked() {
+        // First remove any unused application processes whose package
+        // has been removed.
+        for (int i=mRemovedProcesses.size()-1; i>=0; i--) {
+            final ProcessRecord app = mRemovedProcesses.get(i);
+            if (app.activities.size() == 0 && app.recentTasks.size() == 0
+                    && app.curReceivers.isEmpty() && app.services.size() == 0) {
+                Slog.i(
+                    TAG, "Exiting empty application process "
+                    + app.toShortString() + " ("
+                    + (app.thread != null ? app.thread.asBinder() : null)
+                    + ")\n");
+                if (app.pid > 0 && app.pid != MY_PID) {
+                    app.kill("empty", false);
+                } else if (app.thread != null) {
+                    try {
+                        app.thread.scheduleExit();
+                    } catch (Exception e) {
+                        // Ignore exceptions.
                     }
                 }
-            }
+                cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
+                mRemovedProcesses.remove(i);
 
-            // Now update the oom adj for all processes.
-            updateOomAdjLocked();
+                if (app.persistent) {
+                    addAppLocked(app.info, null, false, null /* ABI override */);
+                }
+            }
         }
+
+        // Now update the oom adj for all processes. Don't skip this, since other callers
+        // might be depending on it.
+        updateOomAdjLocked();
     }
 
     /** This method sends the specified signal to each of the persistent apps */
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 8af9078..aaa5161 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -340,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;
@@ -1258,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()) {
@@ -1478,9 +1447,8 @@
         prev.setState(PAUSING, "startPausingLocked");
         prev.getTask().touchActiveTime();
         clearLaunchTime(prev);
-        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
 
-        stopFullyDrawnTraceIfNeeded();
+        mStackSupervisor.getLaunchTimeTracker().stopFullyDrawnTraceIfNeeded(getWindowingMode());
 
         mService.updateCpuStats();
 
@@ -4602,46 +4570,58 @@
             }
         }
 
-        // Shift all activities with this task up to the top
-        // of the stack, keeping them in the same internal order.
-        insertTaskAtTop(tr, null);
+        try {
+            // Defer updating the IME target since the new IME target will try to get computed
+            // before updating all closing and opening apps, which can cause the ime target to
+            // get calculated incorrectly.
+            getDisplay().deferUpdateImeTarget();
 
-        // Don't refocus if invisible to current user
-        final ActivityRecord top = tr.getTopActivity();
-        if (top == null || !top.okToShowLocked()) {
-            if (top != null) {
-                mStackSupervisor.mRecentTasks.add(top.getTask());
+            // Shift all activities with this task up to the top
+            // of the stack, keeping them in the same internal order.
+            insertTaskAtTop(tr, null);
+
+            // Don't refocus if invisible to current user
+            final ActivityRecord top = tr.getTopActivity();
+            if (top == null || !top.okToShowLocked()) {
+                if (top != null) {
+                    mStackSupervisor.mRecentTasks.add(top.getTask());
+                }
+                ActivityOptions.abort(options);
+                return;
             }
-            ActivityOptions.abort(options);
-            return;
-        }
 
-        // Set focus to the top running activity of this stack.
-        final ActivityRecord r = topRunningActivityLocked();
-        mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, reason);
+            // Set focus to the top running activity of this stack.
+            final ActivityRecord r = topRunningActivityLocked();
+            mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, reason);
 
-        if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
-        if (noAnimation) {
-            mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
-            if (r != null) {
-                mStackSupervisor.mNoAnimActivities.add(r);
+            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
+            if (noAnimation) {
+                mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
+                if (r != null) {
+                    mStackSupervisor.mNoAnimActivities.add(r);
+                }
+                ActivityOptions.abort(options);
+            } else {
+                updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
             }
-            ActivityOptions.abort(options);
-        } else {
-            updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
-        }
-        // If a new task is moved to the front, then mark the existing top activity as supporting
-        // picture-in-picture while paused only if the task would not be considered an oerlay on top
-        // of the current activity (eg. not fullscreen, or the assistant)
-        if (canEnterPipOnTaskSwitch(topActivity, tr, null /* toFrontActivity */,
-                options)) {
-            topActivity.supportsEnterPipOnTaskSwitch = true;
-        }
+            // If a new task is moved to the front, then mark the existing top activity as
+            // supporting
 
-        mStackSupervisor.resumeFocusedStackTopActivityLocked();
-        EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
+            // picture-in-picture while paused only if the task would not be considered an oerlay
+            // on top
+            // of the current activity (eg. not fullscreen, or the assistant)
+            if (canEnterPipOnTaskSwitch(topActivity, tr, null /* toFrontActivity */,
+                    options)) {
+                topActivity.supportsEnterPipOnTaskSwitch = true;
+            }
 
-        mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId);
+            mStackSupervisor.resumeFocusedStackTopActivityLocked();
+            EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
+
+            mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId);
+        } finally {
+            getDisplay().continueUpdateImeTarget();
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index d194db3..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 {
@@ -1702,11 +1707,16 @@
 
     boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo,
             String resultWho, int requestCode, int callingPid, int callingUid,
-            String callingPackage, boolean ignoreTargetSecurity, ProcessRecord callerApp,
-            ActivityRecord resultRecord, ActivityStack resultStack) {
+            String callingPackage, boolean ignoreTargetSecurity, boolean launchingInTask,
+            ProcessRecord callerApp, ActivityRecord resultRecord, ActivityStack resultStack) {
+        final boolean isCallerRecents = mService.getRecentTasks() != null &&
+                mService.getRecentTasks().isCallerRecents(callingUid);
         final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid,
                 callingUid);
-        if (startAnyPerm == PERMISSION_GRANTED) {
+        if (startAnyPerm == PERMISSION_GRANTED || (isCallerRecents && launchingInTask)) {
+            // If the caller has START_ANY_ACTIVITY, ignore all checks below. In addition, if the
+            // caller is the recents component and we are specifically starting an activity in an
+            // existing task, then also allow the activity to be fully relaunched.
             return true;
         }
         final int componentRestriction = getComponentRestrictionForCallingPackage(
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
index 8c3ff34..ff97db8 100644
--- a/services/core/java/com/android/server/am/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -34,7 +34,6 @@
 
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
 
-import android.Manifest;
 import android.app.ActivityOptions;
 import android.app.KeyguardManager;
 import android.app.admin.DevicePolicyManagerInternal;
@@ -233,31 +232,6 @@
         return true;
     }
 
-    private Intent createSuspendedAppInterceptIntent(String suspendedPackage,
-            String suspendingPackage, String dialogMessage, int userId) {
-        final Intent interceptIntent = new Intent(mServiceContext, SuspendedAppActivity.class)
-                .putExtra(SuspendedAppActivity.EXTRA_SUSPENDED_PACKAGE, suspendedPackage)
-                .putExtra(SuspendedAppActivity.EXTRA_DIALOG_MESSAGE, dialogMessage)
-                .putExtra(SuspendedAppActivity.EXTRA_SUSPENDING_PACKAGE, suspendingPackage)
-                .putExtra(Intent.EXTRA_USER_ID, userId)
-                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-
-        final Intent moreDetailsIntent = new Intent(Intent.ACTION_SHOW_SUSPENDED_APP_DETAILS)
-                .setPackage(suspendingPackage);
-        final String requiredPermission = Manifest.permission.SEND_SHOW_SUSPENDED_APP_DETAILS;
-        final ResolveInfo resolvedInfo = mSupervisor.resolveIntent(moreDetailsIntent, null, userId,
-                0, mRealCallingUid);
-        if (resolvedInfo != null && resolvedInfo.activityInfo != null
-                && requiredPermission.equals(resolvedInfo.activityInfo.permission)) {
-            moreDetailsIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, suspendedPackage)
-                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            interceptIntent.putExtra(SuspendedAppActivity.EXTRA_MORE_DETAILS_INTENT,
-                    moreDetailsIntent);
-        }
-        return interceptIntent;
-    }
-
     private boolean interceptSuspendedPackageIfNeeded() {
         // Do not intercept if the package is not suspended
         if (mAInfo == null || mAInfo.applicationInfo == null ||
@@ -274,8 +248,8 @@
             return interceptSuspendedByAdminPackage();
         }
         final String dialogMessage = pmi.getSuspendedDialogMessage(suspendedPackage, mUserId);
-        mIntent = createSuspendedAppInterceptIntent(suspendedPackage, suspendingPackage,
-                dialogMessage, mUserId);
+        mIntent = SuspendedAppActivity.createSuspendedAppInterceptIntent(suspendedPackage,
+                suspendingPackage, dialogMessage, mUserId);
         mCallingPid = mRealCallingPid;
         mCallingUid = mRealCallingUid;
         mResolvedType = null;
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index bbf6e6c..ad434b4 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -713,7 +713,7 @@
 
         boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
                 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
-                callerApp, resultRecord, resultStack);
+                inTask != null, callerApp, resultRecord, resultStack);
         abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                 callingPid, resolvedType, aInfo.applicationInfo);
 
@@ -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/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index cc3a887..c9a26cb 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -271,7 +271,7 @@
     }
 
     private final void processCurBroadcastLocked(BroadcastRecord r,
-            ProcessRecord app) throws RemoteException {
+            ProcessRecord app, boolean skipOomAdj) throws RemoteException {
         if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                 "Process cur broadcast " + r + " for app " + app);
         if (app.thread == null) {
@@ -287,7 +287,9 @@
         app.curReceivers.add(r);
         app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
         mService.updateLruProcessLocked(app, false, null);
-        mService.updateOomAdjLocked();
+        if (!skipOomAdj) {
+            mService.updateOomAdjLocked();
+        }
 
         // Tell the application to launch this receiver.
         r.intent.setComponent(r.curComponent);
@@ -328,7 +330,7 @@
             }
             try {
                 mPendingBroadcast = null;
-                processCurBroadcastLocked(br, app);
+                processCurBroadcastLocked(br, app, false);
                 didSomething = true;
             } catch (Exception e) {
                 Slog.w(TAG, "Exception in new application when starting receiver "
@@ -819,577 +821,581 @@
     }
 
     final void processNextBroadcast(boolean fromMsg) {
-        synchronized(mService) {
-            BroadcastRecord r;
+        synchronized (mService) {
+            processNextBroadcastLocked(fromMsg, false);
+        }
+    }
 
-            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast ["
-                    + mQueueName + "]: "
-                    + mParallelBroadcasts.size() + " parallel broadcasts, "
-                    + mOrderedBroadcasts.size() + " ordered broadcasts");
+    final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
+        BroadcastRecord r;
 
-            mService.updateCpuStats();
+        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast ["
+                + mQueueName + "]: "
+                + mParallelBroadcasts.size() + " parallel broadcasts, "
+                + mOrderedBroadcasts.size() + " ordered broadcasts");
 
-            if (fromMsg) {
-                mBroadcastsScheduled = false;
+        mService.updateCpuStats();
+
+        if (fromMsg) {
+            mBroadcastsScheduled = false;
+        }
+
+        // First, deliver any non-serialized broadcasts right away.
+        while (mParallelBroadcasts.size() > 0) {
+            r = mParallelBroadcasts.remove(0);
+            r.dispatchTime = SystemClock.uptimeMillis();
+            r.dispatchClockTime = System.currentTimeMillis();
+
+            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
+                    System.identityHashCode(r));
+                Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
+                    System.identityHashCode(r));
             }
 
-            // First, deliver any non-serialized broadcasts right away.
-            while (mParallelBroadcasts.size() > 0) {
-                r = mParallelBroadcasts.remove(0);
-                r.dispatchTime = SystemClock.uptimeMillis();
-                r.dispatchClockTime = System.currentTimeMillis();
-
-                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
-                    Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
-                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
-                        System.identityHashCode(r));
-                    Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
-                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
-                        System.identityHashCode(r));
-                }
-
-                final int N = r.receivers.size();
-                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
-                        + mQueueName + "] " + r);
-                for (int i=0; i<N; i++) {
-                    Object target = r.receivers.get(i);
-                    if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
-                            "Delivering non-ordered on [" + mQueueName + "] to registered "
-                            + target + ": " + r);
-                    deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
-                }
-                addBroadcastToHistoryLocked(r);
-                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
-                        + mQueueName + "] " + r);
-            }
-
-            // Now take care of the next serialized one...
-
-            // If we are waiting for a process to come up to handle the next
-            // broadcast, then do nothing at this point.  Just in case, we
-            // check that the process we're waiting for still exists.
-            if (mPendingBroadcast != null) {
-                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
-                        "processNextBroadcast [" + mQueueName + "]: waiting for "
-                        + mPendingBroadcast.curApp);
-
-                boolean isDead;
-                if (mPendingBroadcast.curApp.pid > 0) {
-                    synchronized (mService.mPidsSelfLocked) {
-                        ProcessRecord proc = mService.mPidsSelfLocked.get(
-                                mPendingBroadcast.curApp.pid);
-                        isDead = proc == null || proc.crashing;
-                    }
-                } else {
-                    final ProcessRecord proc = mService.mProcessNames.get(
-                            mPendingBroadcast.curApp.processName, mPendingBroadcast.curApp.uid);
-                    isDead = proc == null || !proc.pendingStart;
-                }
-                if (!isDead) {
-                    // It's still alive, so keep waiting
-                    return;
-                } else {
-                    Slog.w(TAG, "pending app  ["
-                            + mQueueName + "]" + mPendingBroadcast.curApp
-                            + " died before responding to broadcast");
-                    mPendingBroadcast.state = BroadcastRecord.IDLE;
-                    mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
-                    mPendingBroadcast = null;
-                }
-            }
-
-            boolean looped = false;
-            
-            do {
-                if (mOrderedBroadcasts.size() == 0) {
-                    // No more broadcasts pending, so all done!
-                    mService.scheduleAppGcsLocked();
-                    if (looped) {
-                        // If we had finished the last ordered broadcast, then
-                        // make sure all processes have correct oom and sched
-                        // adjustments.
-                        mService.updateOomAdjLocked();
-                    }
-                    return;
-                }
-                r = mOrderedBroadcasts.get(0);
-                boolean forceReceive = false;
-
-                // Ensure that even if something goes awry with the timeout
-                // detection, we catch "hung" broadcasts here, discard them,
-                // and continue to make progress.
-                //
-                // This is only done if the system is ready so that PRE_BOOT_COMPLETED
-                // receivers don't get executed with timeouts. They're intended for
-                // one time heavy lifting after system upgrades and can take
-                // significant amounts of time.
-                int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
-                if (mService.mProcessesReady && r.dispatchTime > 0) {
-                    long now = SystemClock.uptimeMillis();
-                    if ((numReceivers > 0) &&
-                            (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
-                        Slog.w(TAG, "Hung broadcast ["
-                                + mQueueName + "] discarded after timeout failure:"
-                                + " now=" + now
-                                + " dispatchTime=" + r.dispatchTime
-                                + " startTime=" + r.receiverTime
-                                + " intent=" + r.intent
-                                + " numReceivers=" + numReceivers
-                                + " nextReceiver=" + r.nextReceiver
-                                + " state=" + r.state);
-                        broadcastTimeoutLocked(false); // forcibly finish this broadcast
-                        forceReceive = true;
-                        r.state = BroadcastRecord.IDLE;
-                    }
-                }
-
-                if (r.state != BroadcastRecord.IDLE) {
-                    if (DEBUG_BROADCAST) Slog.d(TAG_BROADCAST,
-                            "processNextBroadcast("
-                            + mQueueName + ") called when not idle (state="
-                            + r.state + ")");
-                    return;
-                }
-
-                if (r.receivers == null || r.nextReceiver >= numReceivers
-                        || r.resultAbort || forceReceive) {
-                    // No more receivers for this broadcast!  Send the final
-                    // result if requested...
-                    if (r.resultTo != null) {
-                        try {
-                            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
-                                    "Finishing broadcast [" + mQueueName + "] "
-                                    + r.intent.getAction() + " app=" + r.callerApp);
-                            performReceiveLocked(r.callerApp, r.resultTo,
-                                new Intent(r.intent), r.resultCode,
-                                r.resultData, r.resultExtras, false, false, r.userId);
-                            // Set this to null so that the reference
-                            // (local and remote) isn't kept in the mBroadcastHistory.
-                            r.resultTo = null;
-                        } catch (RemoteException e) {
-                            r.resultTo = null;
-                            Slog.w(TAG, "Failure ["
-                                    + mQueueName + "] sending broadcast result of "
-                                    + r.intent, e);
-
-                        }
-                    }
-
-                    if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Cancelling BROADCAST_TIMEOUT_MSG");
-                    cancelBroadcastTimeoutLocked();
-
-                    if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
-                            "Finished with ordered broadcast " + r);
-
-                    // ... and on to the next...
-                    addBroadcastToHistoryLocked(r);
-                    if (r.intent.getComponent() == null && r.intent.getPackage() == null
-                            && (r.intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
-                        // This was an implicit broadcast... let's record it for posterity.
-                        mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
-                                r.manifestCount, r.manifestSkipCount, r.finishTime-r.dispatchTime);
-                    }
-                    mOrderedBroadcasts.remove(0);
-                    r = null;
-                    looped = true;
-                    continue;
-                }
-            } while (r == null);
-
-            // Get the next receiver...
-            int recIdx = r.nextReceiver++;
-
-            // Keep track of when this receiver started, and make sure there
-            // is a timeout message pending to kill it if need be.
-            r.receiverTime = SystemClock.uptimeMillis();
-            if (recIdx == 0) {
-                r.dispatchTime = r.receiverTime;
-                r.dispatchClockTime = System.currentTimeMillis();
-                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
-                    Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
-                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
-                        System.identityHashCode(r));
-                    Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
-                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
-                        System.identityHashCode(r));
-                }
-                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing ordered broadcast ["
-                        + mQueueName + "] " + r);
-            }
-            if (! mPendingBroadcastTimeoutMessage) {
-                long timeoutTime = r.receiverTime + mTimeoutPeriod;
-                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
-                        "Submitting BROADCAST_TIMEOUT_MSG ["
-                        + mQueueName + "] for " + r + " at " + timeoutTime);
-                setBroadcastTimeoutLocked(timeoutTime);
-            }
-
-            final BroadcastOptions brOptions = r.options;
-            final Object nextReceiver = r.receivers.get(recIdx);
-
-            if (nextReceiver instanceof BroadcastFilter) {
-                // Simple case: this is a registered receiver who gets
-                // a direct call.
-                BroadcastFilter filter = (BroadcastFilter)nextReceiver;
+            final int N = r.receivers.size();
+            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
+                    + mQueueName + "] " + r);
+            for (int i=0; i<N; i++) {
+                Object target = r.receivers.get(i);
                 if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
-                        "Delivering ordered ["
-                        + mQueueName + "] to registered "
-                        + filter + ": " + r);
-                deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
-                if (r.receiver == null || !r.ordered) {
-                    // The receiver has already finished, so schedule to
-                    // process the next one.
-                    if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Quick finishing ["
-                            + mQueueName + "]: ordered="
-                            + r.ordered + " receiver=" + r.receiver);
-                    r.state = BroadcastRecord.IDLE;
-                    scheduleBroadcastsLocked();
-                } else {
-                    if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
-                        scheduleTempWhitelistLocked(filter.owningUid,
-                                brOptions.getTemporaryAppWhitelistDuration(), r);
-                    }
+                        "Delivering non-ordered on [" + mQueueName + "] to registered "
+                        + target + ": " + r);
+                deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
+            }
+            addBroadcastToHistoryLocked(r);
+            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
+                    + mQueueName + "] " + r);
+        }
+
+        // Now take care of the next serialized one...
+
+        // If we are waiting for a process to come up to handle the next
+        // broadcast, then do nothing at this point.  Just in case, we
+        // check that the process we're waiting for still exists.
+        if (mPendingBroadcast != null) {
+            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
+                    "processNextBroadcast [" + mQueueName + "]: waiting for "
+                    + mPendingBroadcast.curApp);
+
+            boolean isDead;
+            if (mPendingBroadcast.curApp.pid > 0) {
+                synchronized (mService.mPidsSelfLocked) {
+                    ProcessRecord proc = mService.mPidsSelfLocked.get(
+                            mPendingBroadcast.curApp.pid);
+                    isDead = proc == null || proc.crashing;
+                }
+            } else {
+                final ProcessRecord proc = mService.mProcessNames.get(
+                        mPendingBroadcast.curApp.processName, mPendingBroadcast.curApp.uid);
+                isDead = proc == null || !proc.pendingStart;
+            }
+            if (!isDead) {
+                // It's still alive, so keep waiting
+                return;
+            } else {
+                Slog.w(TAG, "pending app  ["
+                        + mQueueName + "]" + mPendingBroadcast.curApp
+                        + " died before responding to broadcast");
+                mPendingBroadcast.state = BroadcastRecord.IDLE;
+                mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
+                mPendingBroadcast = null;
+            }
+        }
+
+        boolean looped = false;
+
+        do {
+            if (mOrderedBroadcasts.size() == 0) {
+                // No more broadcasts pending, so all done!
+                mService.scheduleAppGcsLocked();
+                if (looped) {
+                    // If we had finished the last ordered broadcast, then
+                    // make sure all processes have correct oom and sched
+                    // adjustments.
+                    mService.updateOomAdjLocked();
                 }
                 return;
             }
+            r = mOrderedBroadcasts.get(0);
+            boolean forceReceive = false;
 
-            // Hard case: need to instantiate the receiver, possibly
-            // starting its application process to host it.
+            // Ensure that even if something goes awry with the timeout
+            // detection, we catch "hung" broadcasts here, discard them,
+            // and continue to make progress.
+            //
+            // This is only done if the system is ready so that PRE_BOOT_COMPLETED
+            // receivers don't get executed with timeouts. They're intended for
+            // one time heavy lifting after system upgrades and can take
+            // significant amounts of time.
+            int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
+            if (mService.mProcessesReady && r.dispatchTime > 0) {
+                long now = SystemClock.uptimeMillis();
+                if ((numReceivers > 0) &&
+                        (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
+                    Slog.w(TAG, "Hung broadcast ["
+                            + mQueueName + "] discarded after timeout failure:"
+                            + " now=" + now
+                            + " dispatchTime=" + r.dispatchTime
+                            + " startTime=" + r.receiverTime
+                            + " intent=" + r.intent
+                            + " numReceivers=" + numReceivers
+                            + " nextReceiver=" + r.nextReceiver
+                            + " state=" + r.state);
+                    broadcastTimeoutLocked(false); // forcibly finish this broadcast
+                    forceReceive = true;
+                    r.state = BroadcastRecord.IDLE;
+                }
+            }
 
-            ResolveInfo info =
-                (ResolveInfo)nextReceiver;
-            ComponentName component = new ComponentName(
-                    info.activityInfo.applicationInfo.packageName,
-                    info.activityInfo.name);
+            if (r.state != BroadcastRecord.IDLE) {
+                if (DEBUG_BROADCAST) Slog.d(TAG_BROADCAST,
+                        "processNextBroadcast("
+                        + mQueueName + ") called when not idle (state="
+                        + r.state + ")");
+                return;
+            }
 
-            boolean skip = false;
-            if (brOptions != null &&
-                    (info.activityInfo.applicationInfo.targetSdkVersion
-                            < brOptions.getMinManifestReceiverApiLevel() ||
-                    info.activityInfo.applicationInfo.targetSdkVersion
-                            > brOptions.getMaxManifestReceiverApiLevel())) {
+            if (r.receivers == null || r.nextReceiver >= numReceivers
+                    || r.resultAbort || forceReceive) {
+                // No more receivers for this broadcast!  Send the final
+                // result if requested...
+                if (r.resultTo != null) {
+                    try {
+                        if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
+                                "Finishing broadcast [" + mQueueName + "] "
+                                + r.intent.getAction() + " app=" + r.callerApp);
+                        performReceiveLocked(r.callerApp, r.resultTo,
+                            new Intent(r.intent), r.resultCode,
+                            r.resultData, r.resultExtras, false, false, r.userId);
+                        // Set this to null so that the reference
+                        // (local and remote) isn't kept in the mBroadcastHistory.
+                        r.resultTo = null;
+                    } catch (RemoteException e) {
+                        r.resultTo = null;
+                        Slog.w(TAG, "Failure ["
+                                + mQueueName + "] sending broadcast result of "
+                                + r.intent, e);
+
+                    }
+                }
+
+                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Cancelling BROADCAST_TIMEOUT_MSG");
+                cancelBroadcastTimeoutLocked();
+
+                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
+                        "Finished with ordered broadcast " + r);
+
+                // ... and on to the next...
+                addBroadcastToHistoryLocked(r);
+                if (r.intent.getComponent() == null && r.intent.getPackage() == null
+                        && (r.intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
+                    // This was an implicit broadcast... let's record it for posterity.
+                    mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
+                            r.manifestCount, r.manifestSkipCount, r.finishTime-r.dispatchTime);
+                }
+                mOrderedBroadcasts.remove(0);
+                r = null;
+                looped = true;
+                continue;
+            }
+        } while (r == null);
+
+        // Get the next receiver...
+        int recIdx = r.nextReceiver++;
+
+        // Keep track of when this receiver started, and make sure there
+        // is a timeout message pending to kill it if need be.
+        r.receiverTime = SystemClock.uptimeMillis();
+        if (recIdx == 0) {
+            r.dispatchTime = r.receiverTime;
+            r.dispatchClockTime = System.currentTimeMillis();
+            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
+                    System.identityHashCode(r));
+                Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
+                    System.identityHashCode(r));
+            }
+            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing ordered broadcast ["
+                    + mQueueName + "] " + r);
+        }
+        if (! mPendingBroadcastTimeoutMessage) {
+            long timeoutTime = r.receiverTime + mTimeoutPeriod;
+            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
+                    "Submitting BROADCAST_TIMEOUT_MSG ["
+                    + mQueueName + "] for " + r + " at " + timeoutTime);
+            setBroadcastTimeoutLocked(timeoutTime);
+        }
+
+        final BroadcastOptions brOptions = r.options;
+        final Object nextReceiver = r.receivers.get(recIdx);
+
+        if (nextReceiver instanceof BroadcastFilter) {
+            // Simple case: this is a registered receiver who gets
+            // a direct call.
+            BroadcastFilter filter = (BroadcastFilter)nextReceiver;
+            if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
+                    "Delivering ordered ["
+                    + mQueueName + "] to registered "
+                    + filter + ": " + r);
+            deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
+            if (r.receiver == null || !r.ordered) {
+                // The receiver has already finished, so schedule to
+                // process the next one.
+                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Quick finishing ["
+                        + mQueueName + "]: ordered="
+                        + r.ordered + " receiver=" + r.receiver);
+                r.state = BroadcastRecord.IDLE;
+                scheduleBroadcastsLocked();
+            } else {
+                if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
+                    scheduleTempWhitelistLocked(filter.owningUid,
+                            brOptions.getTemporaryAppWhitelistDuration(), r);
+                }
+            }
+            return;
+        }
+
+        // Hard case: need to instantiate the receiver, possibly
+        // starting its application process to host it.
+
+        ResolveInfo info =
+            (ResolveInfo)nextReceiver;
+        ComponentName component = new ComponentName(
+                info.activityInfo.applicationInfo.packageName,
+                info.activityInfo.name);
+
+        boolean skip = false;
+        if (brOptions != null &&
+                (info.activityInfo.applicationInfo.targetSdkVersion
+                        < brOptions.getMinManifestReceiverApiLevel() ||
+                info.activityInfo.applicationInfo.targetSdkVersion
+                        > brOptions.getMaxManifestReceiverApiLevel())) {
+            skip = true;
+        }
+        int perm = mService.checkComponentPermission(info.activityInfo.permission,
+                r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
+                info.activityInfo.exported);
+        if (!skip && perm != PackageManager.PERMISSION_GRANTED) {
+            if (!info.activityInfo.exported) {
+                Slog.w(TAG, "Permission Denial: broadcasting "
+                        + r.intent.toString()
+                        + " from " + r.callerPackage + " (pid=" + r.callingPid
+                        + ", uid=" + r.callingUid + ")"
+                        + " is not exported from uid " + info.activityInfo.applicationInfo.uid
+                        + " due to receiver " + component.flattenToShortString());
+            } else {
+                Slog.w(TAG, "Permission Denial: broadcasting "
+                        + r.intent.toString()
+                        + " from " + r.callerPackage + " (pid=" + r.callingPid
+                        + ", uid=" + r.callingUid + ")"
+                        + " requires " + info.activityInfo.permission
+                        + " due to receiver " + component.flattenToShortString());
+            }
+            skip = true;
+        } else if (!skip && info.activityInfo.permission != null) {
+            final int opCode = AppOpsManager.permissionToOpCode(info.activityInfo.permission);
+            if (opCode != AppOpsManager.OP_NONE
+                    && mService.mAppOpsService.noteOperation(opCode, r.callingUid,
+                            r.callerPackage) != AppOpsManager.MODE_ALLOWED) {
+                Slog.w(TAG, "Appop Denial: broadcasting "
+                        + r.intent.toString()
+                        + " from " + r.callerPackage + " (pid="
+                        + r.callingPid + ", uid=" + r.callingUid + ")"
+                        + " requires appop " + AppOpsManager.permissionToOp(
+                                info.activityInfo.permission)
+                        + " due to registered receiver "
+                        + component.flattenToShortString());
                 skip = true;
             }
-            int perm = mService.checkComponentPermission(info.activityInfo.permission,
-                    r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
-                    info.activityInfo.exported);
-            if (!skip && perm != PackageManager.PERMISSION_GRANTED) {
-                if (!info.activityInfo.exported) {
-                    Slog.w(TAG, "Permission Denial: broadcasting "
-                            + r.intent.toString()
-                            + " from " + r.callerPackage + " (pid=" + r.callingPid
-                            + ", uid=" + r.callingUid + ")"
-                            + " is not exported from uid " + info.activityInfo.applicationInfo.uid
-                            + " due to receiver " + component.flattenToShortString());
-                } else {
-                    Slog.w(TAG, "Permission Denial: broadcasting "
-                            + r.intent.toString()
-                            + " from " + r.callerPackage + " (pid=" + r.callingPid
-                            + ", uid=" + r.callingUid + ")"
-                            + " requires " + info.activityInfo.permission
-                            + " due to receiver " + component.flattenToShortString());
+        }
+        if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
+            r.requiredPermissions != null && r.requiredPermissions.length > 0) {
+            for (int i = 0; i < r.requiredPermissions.length; i++) {
+                String requiredPermission = r.requiredPermissions[i];
+                try {
+                    perm = AppGlobals.getPackageManager().
+                            checkPermission(requiredPermission,
+                                    info.activityInfo.applicationInfo.packageName,
+                                    UserHandle
+                                            .getUserId(info.activityInfo.applicationInfo.uid));
+                } catch (RemoteException e) {
+                    perm = PackageManager.PERMISSION_DENIED;
                 }
-                skip = true;
-            } else if (!skip && info.activityInfo.permission != null) {
-                final int opCode = AppOpsManager.permissionToOpCode(info.activityInfo.permission);
-                if (opCode != AppOpsManager.OP_NONE
-                        && mService.mAppOpsService.noteOperation(opCode, r.callingUid,
-                                r.callerPackage) != AppOpsManager.MODE_ALLOWED) {
-                    Slog.w(TAG, "Appop Denial: broadcasting "
-                            + r.intent.toString()
-                            + " from " + r.callerPackage + " (pid="
-                            + r.callingPid + ", uid=" + r.callingUid + ")"
+                if (perm != PackageManager.PERMISSION_GRANTED) {
+                    Slog.w(TAG, "Permission Denial: receiving "
+                            + r.intent + " to "
+                            + component.flattenToShortString()
+                            + " requires " + requiredPermission
+                            + " due to sender " + r.callerPackage
+                            + " (uid " + r.callingUid + ")");
+                    skip = true;
+                    break;
+                }
+                int appOp = AppOpsManager.permissionToOpCode(requiredPermission);
+                if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp
+                        && mService.mAppOpsService.noteOperation(appOp,
+                        info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
+                        != AppOpsManager.MODE_ALLOWED) {
+                    Slog.w(TAG, "Appop Denial: receiving "
+                            + r.intent + " to "
+                            + component.flattenToShortString()
                             + " requires appop " + AppOpsManager.permissionToOp(
-                                    info.activityInfo.permission)
-                            + " due to registered receiver "
+                            requiredPermission)
+                            + " due to sender " + r.callerPackage
+                            + " (uid " + r.callingUid + ")");
+                    skip = true;
+                    break;
+                }
+            }
+        }
+        if (!skip && r.appOp != AppOpsManager.OP_NONE
+                && mService.mAppOpsService.noteOperation(r.appOp,
+                info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
+                != AppOpsManager.MODE_ALLOWED) {
+            Slog.w(TAG, "Appop Denial: receiving "
+                    + r.intent + " to "
+                    + component.flattenToShortString()
+                    + " requires appop " + AppOpsManager.opToName(r.appOp)
+                    + " due to sender " + r.callerPackage
+                    + " (uid " + r.callingUid + ")");
+            skip = true;
+        }
+        if (!skip) {
+            skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
+                    r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
+        }
+        boolean isSingleton = false;
+        try {
+            isSingleton = mService.isSingleton(info.activityInfo.processName,
+                    info.activityInfo.applicationInfo,
+                    info.activityInfo.name, info.activityInfo.flags);
+        } catch (SecurityException e) {
+            Slog.w(TAG, e.getMessage());
+            skip = true;
+        }
+        if ((info.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
+            if (ActivityManager.checkUidPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS,
+                    info.activityInfo.applicationInfo.uid)
+                            != PackageManager.PERMISSION_GRANTED) {
+                Slog.w(TAG, "Permission Denial: Receiver " + component.flattenToShortString()
+                        + " requests FLAG_SINGLE_USER, but app does not hold "
+                        + android.Manifest.permission.INTERACT_ACROSS_USERS);
+                skip = true;
+            }
+        }
+        if (!skip && info.activityInfo.applicationInfo.isInstantApp()
+                && r.callingUid != info.activityInfo.applicationInfo.uid) {
+            Slog.w(TAG, "Instant App Denial: receiving "
+                    + r.intent
+                    + " to " + component.flattenToShortString()
+                    + " due to sender " + r.callerPackage
+                    + " (uid " + r.callingUid + ")"
+                    + " Instant Apps do not support manifest receivers");
+            skip = true;
+        }
+        if (!skip && r.callerInstantApp
+                && (info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0
+                && r.callingUid != info.activityInfo.applicationInfo.uid) {
+            Slog.w(TAG, "Instant App Denial: receiving "
+                    + r.intent
+                    + " to " + component.flattenToShortString()
+                    + " requires receiver have visibleToInstantApps set"
+                    + " due to sender " + r.callerPackage
+                    + " (uid " + r.callingUid + ")");
+            skip = true;
+        }
+        if (r.curApp != null && r.curApp.crashing) {
+            // If the target process is crashing, just skip it.
+            Slog.w(TAG, "Skipping deliver ordered [" + mQueueName + "] " + r
+                    + " to " + r.curApp + ": process crashing");
+            skip = true;
+        }
+        if (!skip) {
+            boolean isAvailable = false;
+            try {
+                isAvailable = AppGlobals.getPackageManager().isPackageAvailable(
+                        info.activityInfo.packageName,
+                        UserHandle.getUserId(info.activityInfo.applicationInfo.uid));
+            } catch (Exception e) {
+                // all such failures mean we skip this receiver
+                Slog.w(TAG, "Exception getting recipient info for "
+                        + info.activityInfo.packageName, e);
+            }
+            if (!isAvailable) {
+                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
+                        "Skipping delivery to " + info.activityInfo.packageName + " / "
+                        + info.activityInfo.applicationInfo.uid
+                        + " : package no longer available");
+                skip = true;
+            }
+        }
+
+        // If permissions need a review before any of the app components can run, we drop
+        // the broadcast and if the calling app is in the foreground and the broadcast is
+        // explicit we launch the review UI passing it a pending intent to send the skipped
+        // broadcast.
+        if (mService.mPermissionReviewRequired && !skip) {
+            if (!requestStartTargetPermissionsReviewIfNeededLocked(r,
+                    info.activityInfo.packageName, UserHandle.getUserId(
+                            info.activityInfo.applicationInfo.uid))) {
+                skip = true;
+            }
+        }
+
+        // This is safe to do even if we are skipping the broadcast, and we need
+        // this information now to evaluate whether it is going to be allowed to run.
+        final int receiverUid = info.activityInfo.applicationInfo.uid;
+        // If it's a singleton, it needs to be the same app or a special app
+        if (r.callingUid != Process.SYSTEM_UID && isSingleton
+                && mService.isValidSingletonCall(r.callingUid, receiverUid)) {
+            info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
+        }
+        String targetProcess = info.activityInfo.processName;
+        ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
+                info.activityInfo.applicationInfo.uid, false);
+
+        if (!skip) {
+            final int allowed = mService.getAppStartModeLocked(
+                    info.activityInfo.applicationInfo.uid, info.activityInfo.packageName,
+                    info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false, false);
+            if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
+                // We won't allow this receiver to be launched if the app has been
+                // completely disabled from launches, or it was not explicitly sent
+                // to it and the app is in a state that should not receive it
+                // (depending on how getAppStartModeLocked has determined that).
+                if (allowed == ActivityManager.APP_START_MODE_DISABLED) {
+                    Slog.w(TAG, "Background execution disabled: receiving "
+                            + r.intent + " to "
+                            + component.flattenToShortString());
+                    skip = true;
+                } else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
+                        || (r.intent.getComponent() == null
+                            && r.intent.getPackage() == null
+                            && ((r.intent.getFlags()
+                                    & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0)
+                            && !isSignaturePerm(r.requiredPermissions))) {
+                    mService.addBackgroundCheckViolationLocked(r.intent.getAction(),
+                            component.getPackageName());
+                    Slog.w(TAG, "Background execution not allowed: receiving "
+                            + r.intent + " to "
                             + component.flattenToShortString());
                     skip = true;
                 }
             }
-            if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
-                r.requiredPermissions != null && r.requiredPermissions.length > 0) {
-                for (int i = 0; i < r.requiredPermissions.length; i++) {
-                    String requiredPermission = r.requiredPermissions[i];
-                    try {
-                        perm = AppGlobals.getPackageManager().
-                                checkPermission(requiredPermission,
-                                        info.activityInfo.applicationInfo.packageName,
-                                        UserHandle
-                                                .getUserId(info.activityInfo.applicationInfo.uid));
-                    } catch (RemoteException e) {
-                        perm = PackageManager.PERMISSION_DENIED;
-                    }
-                    if (perm != PackageManager.PERMISSION_GRANTED) {
-                        Slog.w(TAG, "Permission Denial: receiving "
-                                + r.intent + " to "
-                                + component.flattenToShortString()
-                                + " requires " + requiredPermission
-                                + " due to sender " + r.callerPackage
-                                + " (uid " + r.callingUid + ")");
-                        skip = true;
-                        break;
-                    }
-                    int appOp = AppOpsManager.permissionToOpCode(requiredPermission);
-                    if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp
-                            && mService.mAppOpsService.noteOperation(appOp,
-                            info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
-                            != AppOpsManager.MODE_ALLOWED) {
-                        Slog.w(TAG, "Appop Denial: receiving "
-                                + r.intent + " to "
-                                + component.flattenToShortString()
-                                + " requires appop " + AppOpsManager.permissionToOp(
-                                requiredPermission)
-                                + " due to sender " + r.callerPackage
-                                + " (uid " + r.callingUid + ")");
-                        skip = true;
-                        break;
-                    }
-                }
-            }
-            if (!skip && r.appOp != AppOpsManager.OP_NONE
-                    && mService.mAppOpsService.noteOperation(r.appOp,
-                    info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
-                    != AppOpsManager.MODE_ALLOWED) {
-                Slog.w(TAG, "Appop Denial: receiving "
-                        + r.intent + " to "
-                        + component.flattenToShortString()
-                        + " requires appop " + AppOpsManager.opToName(r.appOp)
-                        + " due to sender " + r.callerPackage
-                        + " (uid " + r.callingUid + ")");
-                skip = true;
-            }
-            if (!skip) {
-                skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
-                        r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
-            }
-            boolean isSingleton = false;
-            try {
-                isSingleton = mService.isSingleton(info.activityInfo.processName,
-                        info.activityInfo.applicationInfo,
-                        info.activityInfo.name, info.activityInfo.flags);
-            } catch (SecurityException e) {
-                Slog.w(TAG, e.getMessage());
-                skip = true;
-            }
-            if ((info.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
-                if (ActivityManager.checkUidPermission(
-                        android.Manifest.permission.INTERACT_ACROSS_USERS,
-                        info.activityInfo.applicationInfo.uid)
-                                != PackageManager.PERMISSION_GRANTED) {
-                    Slog.w(TAG, "Permission Denial: Receiver " + component.flattenToShortString()
-                            + " requests FLAG_SINGLE_USER, but app does not hold "
-                            + android.Manifest.permission.INTERACT_ACROSS_USERS);
-                    skip = true;
-                }
-            }
-            if (!skip && info.activityInfo.applicationInfo.isInstantApp()
-                    && r.callingUid != info.activityInfo.applicationInfo.uid) {
-                Slog.w(TAG, "Instant App Denial: receiving "
-                        + r.intent
-                        + " to " + component.flattenToShortString()
-                        + " due to sender " + r.callerPackage
-                        + " (uid " + r.callingUid + ")"
-                        + " Instant Apps do not support manifest receivers");
-                skip = true;
-            }
-            if (!skip && r.callerInstantApp
-                    && (info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0
-                    && r.callingUid != info.activityInfo.applicationInfo.uid) {
-                Slog.w(TAG, "Instant App Denial: receiving "
-                        + r.intent
-                        + " to " + component.flattenToShortString()
-                        + " requires receiver have visibleToInstantApps set"
-                        + " due to sender " + r.callerPackage
-                        + " (uid " + r.callingUid + ")");
-                skip = true;
-            }
-            if (r.curApp != null && r.curApp.crashing) {
-                // If the target process is crashing, just skip it.
-                Slog.w(TAG, "Skipping deliver ordered [" + mQueueName + "] " + r
-                        + " to " + r.curApp + ": process crashing");
-                skip = true;
-            }
-            if (!skip) {
-                boolean isAvailable = false;
-                try {
-                    isAvailable = AppGlobals.getPackageManager().isPackageAvailable(
-                            info.activityInfo.packageName,
-                            UserHandle.getUserId(info.activityInfo.applicationInfo.uid));
-                } catch (Exception e) {
-                    // all such failures mean we skip this receiver
-                    Slog.w(TAG, "Exception getting recipient info for "
-                            + info.activityInfo.packageName, e);
-                }
-                if (!isAvailable) {
-                    if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
-                            "Skipping delivery to " + info.activityInfo.packageName + " / "
-                            + info.activityInfo.applicationInfo.uid
-                            + " : package no longer available");
-                    skip = true;
-                }
-            }
+        }
 
-            // If permissions need a review before any of the app components can run, we drop
-            // the broadcast and if the calling app is in the foreground and the broadcast is
-            // explicit we launch the review UI passing it a pending intent to send the skipped
-            // broadcast.
-            if (mService.mPermissionReviewRequired && !skip) {
-                if (!requestStartTargetPermissionsReviewIfNeededLocked(r,
-                        info.activityInfo.packageName, UserHandle.getUserId(
-                                info.activityInfo.applicationInfo.uid))) {
-                    skip = true;
-                }
-            }
+        if (!skip && !Intent.ACTION_SHUTDOWN.equals(r.intent.getAction())
+                && !mService.mUserController
+                .isUserRunning(UserHandle.getUserId(info.activityInfo.applicationInfo.uid),
+                        0 /* flags */)) {
+            skip = true;
+            Slog.w(TAG,
+                    "Skipping delivery to " + info.activityInfo.packageName + " / "
+                            + info.activityInfo.applicationInfo.uid + " : user is not running");
+        }
 
-            // This is safe to do even if we are skipping the broadcast, and we need
-            // this information now to evaluate whether it is going to be allowed to run.
-            final int receiverUid = info.activityInfo.applicationInfo.uid;
-            // If it's a singleton, it needs to be the same app or a special app
-            if (r.callingUid != Process.SYSTEM_UID && isSingleton
-                    && mService.isValidSingletonCall(r.callingUid, receiverUid)) {
-                info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
-            }
-            String targetProcess = info.activityInfo.processName;
-            ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
-                    info.activityInfo.applicationInfo.uid, false);
-
-            if (!skip) {
-                final int allowed = mService.getAppStartModeLocked(
-                        info.activityInfo.applicationInfo.uid, info.activityInfo.packageName,
-                        info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false, false);
-                if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
-                    // We won't allow this receiver to be launched if the app has been
-                    // completely disabled from launches, or it was not explicitly sent
-                    // to it and the app is in a state that should not receive it
-                    // (depending on how getAppStartModeLocked has determined that).
-                    if (allowed == ActivityManager.APP_START_MODE_DISABLED) {
-                        Slog.w(TAG, "Background execution disabled: receiving "
-                                + r.intent + " to "
-                                + component.flattenToShortString());
-                        skip = true;
-                    } else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
-                            || (r.intent.getComponent() == null
-                                && r.intent.getPackage() == null
-                                && ((r.intent.getFlags()
-                                        & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0)
-                                && !isSignaturePerm(r.requiredPermissions))) {
-                        mService.addBackgroundCheckViolationLocked(r.intent.getAction(),
-                                component.getPackageName());
-                        Slog.w(TAG, "Background execution not allowed: receiving "
-                                + r.intent + " to "
-                                + component.flattenToShortString());
-                        skip = true;
-                    }
-                }
-            }
-
-            if (!skip && !Intent.ACTION_SHUTDOWN.equals(r.intent.getAction())
-                    && !mService.mUserController
-                    .isUserRunning(UserHandle.getUserId(info.activityInfo.applicationInfo.uid),
-                            0 /* flags */)) {
-                skip = true;
-                Slog.w(TAG,
-                        "Skipping delivery to " + info.activityInfo.packageName + " / "
-                                + info.activityInfo.applicationInfo.uid + " : user is not running");
-            }
-
-            if (skip) {
-                if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
-                        "Skipping delivery of ordered [" + mQueueName + "] "
-                        + r + " for whatever reason");
-                r.delivery[recIdx] = BroadcastRecord.DELIVERY_SKIPPED;
-                r.receiver = null;
-                r.curFilter = null;
-                r.state = BroadcastRecord.IDLE;
-                r.manifestSkipCount++;
-                scheduleBroadcastsLocked();
-                return;
-            }
-            r.manifestCount++;
-
-            r.delivery[recIdx] = BroadcastRecord.DELIVERY_DELIVERED;
-            r.state = BroadcastRecord.APP_RECEIVE;
-            r.curComponent = component;
-            r.curReceiver = info.activityInfo;
-            if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) {
-                Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
-                        + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
-                        + receiverUid);
-            }
-
-            if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
-                scheduleTempWhitelistLocked(receiverUid,
-                        brOptions.getTemporaryAppWhitelistDuration(), r);
-            }
-
-            // Broadcast is being executed, its package can't be stopped.
-            try {
-                AppGlobals.getPackageManager().setPackageStoppedState(
-                        r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
-            } catch (RemoteException e) {
-            } catch (IllegalArgumentException e) {
-                Slog.w(TAG, "Failed trying to unstop package "
-                        + r.curComponent.getPackageName() + ": " + e);
-            }
-
-            // Is this receiver's application already running?
-            if (app != null && app.thread != null && !app.killed) {
-                try {
-                    app.addPackage(info.activityInfo.packageName,
-                            info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);
-                    processCurBroadcastLocked(r, app);
-                    return;
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Exception when sending broadcast to "
-                          + r.curComponent, e);
-                } catch (RuntimeException e) {
-                    Slog.wtf(TAG, "Failed sending broadcast to "
-                            + r.curComponent + " with " + r.intent, e);
-                    // If some unexpected exception happened, just skip
-                    // this broadcast.  At this point we are not in the call
-                    // from a client, so throwing an exception out from here
-                    // will crash the entire system instead of just whoever
-                    // sent the broadcast.
-                    logBroadcastReceiverDiscardLocked(r);
-                    finishReceiverLocked(r, r.resultCode, r.resultData,
-                            r.resultExtras, r.resultAbort, false);
-                    scheduleBroadcastsLocked();
-                    // We need to reset the state if we failed to start the receiver.
-                    r.state = BroadcastRecord.IDLE;
-                    return;
-                }
-
-                // If a dead object exception was thrown -- fall through to
-                // restart the application.
-            }
-
-            // Not running -- get it started, to be executed when the app comes up.
+        if (skip) {
             if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
-                    "Need to start app ["
-                    + mQueueName + "] " + targetProcess + " for broadcast " + r);
-            if ((r.curApp=mService.startProcessLocked(targetProcess,
-                    info.activityInfo.applicationInfo, true,
-                    r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
-                    "broadcast", r.curComponent,
-                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
-                            == null) {
-                // Ah, this recipient is unavailable.  Finish it if necessary,
-                // and mark the broadcast record as ready for the next.
-                Slog.w(TAG, "Unable to launch app "
-                        + info.activityInfo.applicationInfo.packageName + "/"
-                        + receiverUid + " for broadcast "
-                        + r.intent + ": process is bad");
+                    "Skipping delivery of ordered [" + mQueueName + "] "
+                    + r + " for whatever reason");
+            r.delivery[recIdx] = BroadcastRecord.DELIVERY_SKIPPED;
+            r.receiver = null;
+            r.curFilter = null;
+            r.state = BroadcastRecord.IDLE;
+            r.manifestSkipCount++;
+            scheduleBroadcastsLocked();
+            return;
+        }
+        r.manifestCount++;
+
+        r.delivery[recIdx] = BroadcastRecord.DELIVERY_DELIVERED;
+        r.state = BroadcastRecord.APP_RECEIVE;
+        r.curComponent = component;
+        r.curReceiver = info.activityInfo;
+        if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) {
+            Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
+                    + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
+                    + receiverUid);
+        }
+
+        if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
+            scheduleTempWhitelistLocked(receiverUid,
+                    brOptions.getTemporaryAppWhitelistDuration(), r);
+        }
+
+        // Broadcast is being executed, its package can't be stopped.
+        try {
+            AppGlobals.getPackageManager().setPackageStoppedState(
+                    r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
+        } catch (RemoteException e) {
+        } catch (IllegalArgumentException e) {
+            Slog.w(TAG, "Failed trying to unstop package "
+                    + r.curComponent.getPackageName() + ": " + e);
+        }
+
+        // Is this receiver's application already running?
+        if (app != null && app.thread != null && !app.killed) {
+            try {
+                app.addPackage(info.activityInfo.packageName,
+                        info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);
+                processCurBroadcastLocked(r, app, skipOomAdj);
+                return;
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Exception when sending broadcast to "
+                      + r.curComponent, e);
+            } catch (RuntimeException e) {
+                Slog.wtf(TAG, "Failed sending broadcast to "
+                        + r.curComponent + " with " + r.intent, e);
+                // If some unexpected exception happened, just skip
+                // this broadcast.  At this point we are not in the call
+                // from a client, so throwing an exception out from here
+                // will crash the entire system instead of just whoever
+                // sent the broadcast.
                 logBroadcastReceiverDiscardLocked(r);
                 finishReceiverLocked(r, r.resultCode, r.resultData,
                         r.resultExtras, r.resultAbort, false);
                 scheduleBroadcastsLocked();
+                // We need to reset the state if we failed to start the receiver.
                 r.state = BroadcastRecord.IDLE;
                 return;
             }
 
-            mPendingBroadcast = r;
-            mPendingBroadcastRecvIndex = recIdx;
+            // If a dead object exception was thrown -- fall through to
+            // restart the application.
         }
+
+        // Not running -- get it started, to be executed when the app comes up.
+        if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
+                "Need to start app ["
+                + mQueueName + "] " + targetProcess + " for broadcast " + r);
+        if ((r.curApp=mService.startProcessLocked(targetProcess,
+                info.activityInfo.applicationInfo, true,
+                r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
+                "broadcast", r.curComponent,
+                (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
+                        == null) {
+            // Ah, this recipient is unavailable.  Finish it if necessary,
+            // and mark the broadcast record as ready for the next.
+            Slog.w(TAG, "Unable to launch app "
+                    + info.activityInfo.applicationInfo.packageName + "/"
+                    + receiverUid + " for broadcast "
+                    + r.intent + ": process is bad");
+            logBroadcastReceiverDiscardLocked(r);
+            finishReceiverLocked(r, r.resultCode, r.resultData,
+                    r.resultExtras, r.resultAbort, false);
+            scheduleBroadcastsLocked();
+            r.state = BroadcastRecord.IDLE;
+            return;
+        }
+
+        mPendingBroadcast = r;
+        mPendingBroadcastRecvIndex = recIdx;
     }
 
     final void setBroadcastTimeoutLocked(long timeoutTime) {
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 3d25325..6c79c1a 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -254,6 +254,7 @@
     private static final int MSG_ACCESSORY_PLUG_MEDIA_UNMUTE = 27;
     private static final int MSG_NOTIFY_VOL_EVENT = 28;
     private static final int MSG_DISPATCH_AUDIO_SERVER_STATE = 29;
+    private static final int MSG_ENABLE_SURROUND_FORMATS = 30;
     // start of messages handled under wakelock
     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
@@ -633,6 +634,10 @@
     private int[] mAccessibilityServiceUids;
     private final Object mAccessibilityServiceUidsLock = new Object();
 
+    private int mEncodedSurroundMode;
+    private String mEnabledSurroundFormats;
+    private boolean mSurroundModeChanged;
+
     // Intent "extra" data keys.
     public static final String CONNECT_INTENT_KEY_PORT_NAME = "portName";
     public static final String CONNECT_INTENT_KEY_STATE = "state";
@@ -1035,6 +1040,7 @@
                     "onAudioServerDied"));
             AudioSystem.setForceUse(AudioSystem.FOR_DOCK, forDock);
             sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
+            sendEnabledSurroundFormats(mContentResolver, true);
         }
         if (mHdmiManager != null) {
             synchronized (mHdmiManager) {
@@ -1288,6 +1294,9 @@
             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS;
                 break;
+            case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL:
+                forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_MANUAL;
+                break;
             default:
                 Log.e(TAG, "updateSurroundSoundSettings: illegal value "
                         + encodedSurroundMode);
@@ -1304,6 +1313,56 @@
         }
     }
 
+    private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) {
+        if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) {
+            // Manually enable surround formats only when the setting is in manual mode.
+            return;
+        }
+        String enabledSurroundFormats = Settings.Global.getString(
+                cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
+        if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) {
+            // Update enabled surround formats to AudioPolicyManager only when forceUpdate
+            // is true or enabled surround formats changed.
+            return;
+        }
+
+        mEnabledSurroundFormats = enabledSurroundFormats;
+        String[] surroundFormats = TextUtils.split(enabledSurroundFormats, ",");
+        ArrayList<Integer> formats = new ArrayList<>();
+        for (String format : surroundFormats) {
+            try {
+                int audioFormat = Integer.valueOf(format);
+                boolean isSurroundFormat = false;
+                for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) {
+                    if (sf == audioFormat) {
+                        isSurroundFormat = true;
+                        break;
+                    }
+                }
+                if (isSurroundFormat && !formats.contains(audioFormat)) {
+                    formats.add(audioFormat);
+                }
+            } catch (Exception e) {
+                Log.e(TAG, "Invalid enabled surround format:" + format);
+            }
+        }
+        // Set filtered surround formats to settings DB in case
+        // there are invalid surround formats in original settings.
+        Settings.Global.putString(mContext.getContentResolver(),
+                Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
+                TextUtils.join(",", formats));
+        sendMsg(mAudioHandler, MSG_ENABLE_SURROUND_FORMATS, SENDMSG_QUEUE, 0, 0, formats, 0);
+    }
+
+    private void onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats) {
+        // Set surround format enabled accordingly.
+        for (int surroundFormat : AudioFormat.SURROUND_SOUND_ENCODING) {
+            boolean enabled = enabledSurroundFormats.contains(surroundFormat);
+            int ret = AudioSystem.setSurroundFormatEnabled(surroundFormat, enabled);
+            Log.i(TAG, "enable surround format:" + surroundFormat + " " + enabled + " " + ret);
+        }
+    }
+
     private void readPersistedSettings() {
         final ContentResolver cr = mContentResolver;
 
@@ -1346,6 +1405,7 @@
             updateRingerAndZenModeAffectedStreams();
             readDockAudioSettings(cr);
             sendEncodedSurroundMode(cr, "readPersistedSettings");
+            sendEnabledSurroundFormats(cr, true);
         }
 
         mMuteAffectedStreams = System.getIntForUser(cr,
@@ -3653,26 +3713,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;
@@ -5623,14 +5692,16 @@
                 case MSG_NOTIFY_VOL_EVENT:
                     onNotifyVolumeEvent((IAudioPolicyCallback) msg.obj, msg.arg1);
                     break;
+
+                case MSG_ENABLE_SURROUND_FORMATS:
+                    onEnableSurroundFormats((ArrayList<Integer>) msg.obj);
+                    break;
             }
         }
     }
 
     private class SettingsObserver extends ContentObserver {
 
-        private int mEncodedSurroundMode;
-
         SettingsObserver() {
             super(new Handler());
             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
@@ -5649,6 +5720,11 @@
                     Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
                     Settings.Global.ENCODED_SURROUND_OUTPUT), false, this);
+
+            mEnabledSurroundFormats = Settings.Global.getString(
+                    mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
+            mContentResolver.registerContentObserver(Settings.Global.getUriFor(
+                    Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS), false, this);
         }
 
         @Override
@@ -5669,6 +5745,7 @@
                 readDockAudioSettings(mContentResolver);
                 updateMasterMono(mContentResolver);
                 updateEncodedSurroundOutput();
+                sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged);
             }
         }
 
@@ -5695,6 +5772,9 @@
                     }
                 }
                 mEncodedSurroundMode = newSurroundMode;
+                mSurroundModeChanged = true;
+            } else {
+                mSurroundModeChanged = false;
             }
         }
     }
@@ -6231,6 +6311,9 @@
                         }
                     }
                 }
+                if ((device & AudioSystem.DEVICE_OUT_HDMI) != 0) {
+                    sendEnabledSurroundFormats(mContentResolver, true);
+                }
             } else {
                 if (isPlatformTelevision() && ((device & AudioSystem.DEVICE_OUT_HDMI) != 0)) {
                     if (mHdmiManager != null) {
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 0425844..1c3342a 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -20,12 +20,14 @@
 import com.android.server.LocalServices;
 
 import android.annotation.Nullable;
+import android.app.ActivityManager;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
 import android.hardware.display.BrightnessConfiguration;
 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -91,6 +93,8 @@
     // The minimum and maximum screen brightnesses.
     private final int mScreenBrightnessRangeMinimum;
     private final int mScreenBrightnessRangeMaximum;
+
+    // How much to scale doze brightness by (should be (0, 1.0]).
     private final float mDozeScaleFactor;
 
     // Initial light sensor event rate in milliseconds.
@@ -122,8 +126,8 @@
     // weighting values positive.
     private final int mWeightingIntercept;
 
-    // accessor object for determining thresholds to change brightness dynamically
-    private final HysteresisLevels mDynamicHysteresis;
+    // Configuration object for determining thresholds to change brightness dynamically
+    private final HysteresisLevels mHysteresisLevels;
 
     // Amount of time to delay auto-brightness after screen on while waiting for
     // the light sensor to warm-up in milliseconds.
@@ -192,7 +196,7 @@
             int lightSensorWarmUpTime, int brightnessMin, int brightnessMax, float dozeScaleFactor,
             int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig,
             long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig,
-            int ambientLightHorizon, HysteresisLevels dynamicHysteresis) {
+            HysteresisLevels hysteresisLevels) {
         mCallbacks = callbacks;
         mSensorManager = sensorManager;
         mBrightnessMapper = mapper;
@@ -206,9 +210,9 @@
         mBrighteningLightDebounceConfig = brighteningLightDebounceConfig;
         mDarkeningLightDebounceConfig = darkeningLightDebounceConfig;
         mResetAmbientLuxAfterWarmUpConfig = resetAmbientLuxAfterWarmUpConfig;
-        mAmbientLightHorizon = ambientLightHorizon;
-        mWeightingIntercept = ambientLightHorizon;
-        mDynamicHysteresis = dynamicHysteresis;
+        mAmbientLightHorizon = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
+        mWeightingIntercept = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
+        mHysteresisLevels = hysteresisLevels;
         mShortTermModelValid = true;
         mShortTermModelAnchor = -1;
 
@@ -330,7 +334,11 @@
     }
 
     public boolean setBrightnessConfiguration(BrightnessConfiguration configuration) {
-        return mBrightnessMapper.setBrightnessConfiguration(configuration);
+        if (mBrightnessMapper.setBrightnessConfiguration(configuration)) {
+            resetShortTermModel();
+            return true;
+        }
+        return false;
     }
 
     public void dump(PrintWriter pw) {
@@ -338,19 +346,24 @@
         pw.println("Automatic Brightness Controller Configuration:");
         pw.println("  mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
         pw.println("  mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
+        pw.println("  mDozeScaleFactor=" + mDozeScaleFactor);
+        pw.println("  mInitialLightSensorRate=" + mInitialLightSensorRate);
+        pw.println("  mNormalLightSensorRate=" + mNormalLightSensorRate);
         pw.println("  mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig);
         pw.println("  mBrighteningLightDebounceConfig=" + mBrighteningLightDebounceConfig);
         pw.println("  mDarkeningLightDebounceConfig=" + mDarkeningLightDebounceConfig);
         pw.println("  mResetAmbientLuxAfterWarmUpConfig=" + mResetAmbientLuxAfterWarmUpConfig);
+        pw.println("  mAmbientLightHorizon=" + mAmbientLightHorizon);
+        pw.println("  mWeightingIntercept=" + mWeightingIntercept);
 
         pw.println();
         pw.println("Automatic Brightness Controller State:");
         pw.println("  mLightSensor=" + mLightSensor);
         pw.println("  mLightSensorEnabled=" + mLightSensorEnabled);
         pw.println("  mLightSensorEnableTime=" + TimeUtils.formatUptime(mLightSensorEnableTime));
+        pw.println("  mCurrentLightSensorRate=" + mCurrentLightSensorRate);
         pw.println("  mAmbientLux=" + mAmbientLux);
         pw.println("  mAmbientLuxValid=" + mAmbientLuxValid);
-        pw.println("  mAmbientLightHorizon=" + mAmbientLightHorizon);
         pw.println("  mBrighteningLuxThreshold=" + mBrighteningLuxThreshold);
         pw.println("  mDarkeningLuxThreshold=" + mDarkeningLuxThreshold);
         pw.println("  mLastObservedLux=" + mLastObservedLux);
@@ -358,11 +371,20 @@
         pw.println("  mRecentLightSamples=" + mRecentLightSamples);
         pw.println("  mAmbientLightRingBuffer=" + mAmbientLightRingBuffer);
         pw.println("  mScreenAutoBrightness=" + mScreenAutoBrightness);
-        pw.println("  mDisplayPolicy=" + mDisplayPolicy);
+        pw.println("  mDisplayPolicy=" + DisplayPowerRequest.policyToString(mDisplayPolicy));
         pw.println("  mShortTermModelAnchor=" + mShortTermModelAnchor);
+        pw.println("  mShortTermModelValid=" + mShortTermModelValid);
+        pw.println("  mBrightnessAdjustmentSamplePending=" + mBrightnessAdjustmentSamplePending);
+        pw.println("  mBrightnessAdjustmentSampleOldLux=" + mBrightnessAdjustmentSampleOldLux);
+        pw.println("  mBrightnessAdjustmentSampleOldBrightness="
+                + mBrightnessAdjustmentSampleOldBrightness);
+        pw.println("  mShortTermModelValid=" + mShortTermModelValid);
 
         pw.println();
         mBrightnessMapper.dump(pw);
+
+        pw.println();
+        mHysteresisLevels.dump(pw);
     }
 
     private boolean setLightSensorEnabled(boolean enable) {
@@ -437,8 +459,8 @@
             lux = 0;
         }
         mAmbientLux = lux;
-        mBrighteningLuxThreshold = mDynamicHysteresis.getBrighteningThreshold(lux);
-        mDarkeningLuxThreshold = mDynamicHysteresis.getDarkeningThreshold(lux);
+        mBrighteningLuxThreshold = mHysteresisLevels.getBrighteningThreshold(lux);
+        mDarkeningLuxThreshold = mHysteresisLevels.getDarkeningThreshold(lux);
 
         // If the short term model was invalidated and the change is drastic enough, reset it.
         if (!mShortTermModelValid && mShortTermModelAnchor != -1) {
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index f7439b9..1b688a6 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -42,7 +42,7 @@
  */
 public abstract class BrightnessMappingStrategy {
     private static final String TAG = "BrightnessMappingStrategy";
-    private static final boolean DEBUG = true;
+    private static final boolean DEBUG = false;
 
     private static final float LUX_GRAD_SMOOTHING = 0.25f;
     private static final float MAX_GRAD = 1.0f;
@@ -341,7 +341,7 @@
         // Extreme edge cases: use a simpler heuristic, as proper gamma correction around the edges
         // affects the curve rather drastically.
         if (currentBrightness <= 0.1f || currentBrightness >= 0.9f) {
-            adjustment = (desiredBrightness - currentBrightness) * 2;
+            adjustment = (desiredBrightness - currentBrightness);
         // Edge case: darkest adjustment possible.
         } else if (desiredBrightness == 0) {
             adjustment = -1;
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index 407fad0..a568fe3 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -68,10 +68,11 @@
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
-
 import java.util.Collections;
+import java.util.Date;
 import java.util.Deque;
 import java.util.HashMap;
 import java.util.Map;
@@ -115,6 +116,8 @@
     private static final int MSG_STOP_SENSOR_LISTENER = 2;
     private static final int MSG_START_SENSOR_LISTENER = 3;
 
+    private static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
+
     // Lock held while accessing mEvents, is held while writing events to flash.
     private final Object mEventsLock = new Object();
     @GuardedBy("mEventsLock")
@@ -127,10 +130,10 @@
 
     private AmbientBrightnessStatsTracker mAmbientBrightnessStatsTracker;
 
-    private UserManager mUserManager;
+    private final UserManager mUserManager;
     private final Context mContext;
     private final ContentResolver mContentResolver;
-    private Handler mBgHandler;
+    private final Handler mBgHandler;
 
     // mBroadcastReceiver,  mSensorListener, mSettingsObserver and mSensorRegistered
     // should only be used on the mBgHandler thread.
@@ -164,6 +167,8 @@
         } else {
             mInjector = new Injector();
         }
+        mBgHandler = new TrackerHandler(mInjector.getBackgroundHandler().getLooper());
+        mUserManager = mContext.getSystemService(UserManager.class);
     }
 
     /**
@@ -175,8 +180,6 @@
         if (DEBUG) {
             Slog.d(TAG, "Start");
         }
-        mBgHandler = new TrackerHandler(mInjector.getBackgroundHandler().getLooper());
-        mUserManager = mContext.getSystemService(UserManager.class);
         mCurrentUserId = ActivityManager.getCurrentUser();
         mBgHandler.obtainMessage(MSG_BACKGROUND_START, (Float) initialBrightness).sendToTarget();
     }
@@ -649,10 +652,12 @@
         }
     }
 
-    public void dump(PrintWriter pw) {
+    public void dump(final PrintWriter pw) {
         pw.println("BrightnessTracker state:");
         synchronized (mDataCollectionLock) {
             pw.println("  mStarted=" + mStarted);
+            pw.println("  mLastBatteryLevel=" + mLastBatteryLevel);
+            pw.println("  mLastBrightness=" + mLastBrightness);
             pw.println("  mLastSensorReadings.size=" + mLastSensorReadings.size());
             if (!mLastSensorReadings.isEmpty()) {
                 pw.println("  mLastSensorReadings time span "
@@ -665,7 +670,8 @@
             pw.println("  mEvents.size=" + mEvents.size());
             BrightnessChangeEvent[] events = mEvents.toArray();
             for (int i = 0; i < events.length; ++i) {
-                pw.print("    " + events[i].timeStamp + ", " + events[i].userId);
+                pw.print("    " + FORMAT.format(new Date(events[i].timeStamp)));
+                pw.print(", userId=" + events[i].userId);
                 pw.print(", " + events[i].lastBrightness + "->" + events[i].brightness);
                 pw.print(", isUserSetBrightness=" + events[i].isUserSetBrightness);
                 pw.print(", powerBrightnessFactor=" + events[i].powerBrightnessFactor);
@@ -680,17 +686,23 @@
                 pw.println("}");
             }
         }
+        pw.println("  mWriteBrightnessTrackerStateScheduled="
+                + mWriteBrightnessTrackerStateScheduled);
+        mBgHandler.runWithScissors(() -> dumpLocal(pw), 1000);
         if (mAmbientBrightnessStatsTracker != null) {
             pw.println();
             mAmbientBrightnessStatsTracker.dump(pw);
         }
     }
 
+    private void dumpLocal(PrintWriter pw) {
+        pw.println("  mSensorRegistered=" + mSensorRegistered);
+    }
+
     public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats(int userId) {
         if (mAmbientBrightnessStatsTracker != null) {
             ArrayList<AmbientBrightnessDayStats> stats =
-                    mAmbientBrightnessStatsTracker.getUserStats(
-                            userId);
+                    mAmbientBrightnessStatsTracker.getUserStats(userId);
             if (stats != null) {
                 return new ParceledListSlice<>(stats);
             }
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 3b35d02..1be507e 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -295,6 +295,10 @@
     private boolean mAppliedAutoBrightness;
     private boolean mAppliedDimming;
     private boolean mAppliedLowPower;
+    private boolean mAppliedScreenBrightnessOverride;
+    private boolean mAppliedTemporaryBrightness;
+    private boolean mAppliedTemporaryAutoBrightnessAdjustment;
+    private boolean mAppliedBrightnessBoost;
 
     // Brightness animation ramp rates in brightness units per second
     private final int mBrightnessRampRateFast;
@@ -424,7 +428,7 @@
                     com.android.internal.R.array.config_dynamicHysteresisDarkLevels);
             int[] luxHysteresisLevels = resources.getIntArray(
                     com.android.internal.R.array.config_dynamicHysteresisLuxLevels);
-            HysteresisLevels dynamicHysteresis = new HysteresisLevels(
+            HysteresisLevels hysteresisLevels = new HysteresisLevels(
                     brightLevels, darkLevels, luxHysteresisLevels);
 
             long brighteningLightDebounce = resources.getInteger(
@@ -433,8 +437,6 @@
                     com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);
             boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
                     com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
-            int ambientLightHorizon = resources.getInteger(
-                    com.android.internal.R.integer.config_autoBrightnessAmbientLightHorizon);
 
             int lightSensorWarmUpTimeConfig = resources.getInteger(
                     com.android.internal.R.integer.config_lightSensorWarmupTime);
@@ -457,8 +459,7 @@
                         lightSensorWarmUpTimeConfig, mScreenBrightnessRangeMinimum,
                         mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
                         initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
-                        autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon,
-                        dynamicHysteresis);
+                        autoBrightnessResetAmbientLuxAfterWarmUp, hysteresisLevels);
             } else {
                 mUseSoftwareAutoBrightnessConfig = false;
             }
@@ -776,6 +777,9 @@
 
         if (brightness < 0 && mPowerRequest.screenBrightnessOverride > 0) {
             brightness = mPowerRequest.screenBrightnessOverride;
+            mAppliedScreenBrightnessOverride = true;
+        } else {
+            mAppliedScreenBrightnessOverride = false;
         }
 
         final boolean autoBrightnessEnabledInDoze =
@@ -784,7 +788,6 @@
                     && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
                     && brightness < 0
                     && mAutomaticBrightnessController != null;
-        boolean brightnessIsTemporary = false;
 
         final boolean userSetBrightnessChanged = updateUserSetScreenBrightness();
         if (userSetBrightnessChanged) {
@@ -795,7 +798,9 @@
         // WindowManager or based on the display state.
         if (mTemporaryScreenBrightness > 0) {
             brightness = mTemporaryScreenBrightness;
-            brightnessIsTemporary = true;
+            mAppliedTemporaryBrightness = true;
+        } else {
+            mAppliedTemporaryBrightness = false;
         }
 
         final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment();
@@ -807,9 +812,10 @@
         final float autoBrightnessAdjustment;
         if (!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) {
             autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment;
-            brightnessIsTemporary = true;
+            mAppliedTemporaryAutoBrightnessAdjustment = true;
         } else {
             autoBrightnessAdjustment = mAutoBrightnessAdjustment;
+            mAppliedTemporaryAutoBrightnessAdjustment = true;
         }
 
         // Apply brightness boost.
@@ -819,6 +825,9 @@
         if (mPowerRequest.boostScreenBrightness
                 && brightness != PowerManager.BRIGHTNESS_OFF) {
             brightness = PowerManager.BRIGHTNESS_ON;
+            mAppliedBrightnessBoost = true;
+        } else {
+            mAppliedBrightnessBoost = false;
         }
 
         // If the brightness is already set then it's been overridden by something other than the
@@ -948,6 +957,8 @@
             // level without it being a noticeable jump since any actual content isn't yet visible.
             final boolean isDisplayContentVisible =
                     mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f;
+            final boolean brightnessIsTemporary =
+                    mAppliedTemporaryBrightness || mAppliedTemporaryAutoBrightnessAdjustment;
             if (initialRampSkip || hasBrightnessBuckets
                     || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
                 animateScreenBrightness(brightness, 0);
@@ -1586,10 +1597,20 @@
         pw.println("  mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
         pw.println("  mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
         pw.println("  mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
+        pw.println("  mScreenBrightnessDefault=" + mScreenBrightnessDefault);
+        pw.println("  mScreenBrightnessForVrRangeMinimum=" + mScreenBrightnessForVrRangeMinimum);
+        pw.println("  mScreenBrightnessForVrRangeMaximum=" + mScreenBrightnessForVrRangeMaximum);
+        pw.println("  mScreenBrightnessForVrDefault=" + mScreenBrightnessForVrDefault);
         pw.println("  mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
         pw.println("  mAllowAutoBrightnessWhileDozingConfig=" +
                 mAllowAutoBrightnessWhileDozingConfig);
+        pw.println("  mBrightnessRampRateFast=" + mBrightnessRampRateFast);
+        pw.println("  mBrightnessRampRateSlow=" + mBrightnessRampRateSlow);
+        pw.println("  mSkipScreenOnBrightnessRamp=" + mSkipScreenOnBrightnessRamp);
         pw.println("  mColorFadeFadesConfig=" + mColorFadeFadesConfig);
+        pw.println("  mColorFadeEnabled=" + mColorFadeEnabled);
+        pw.println("  mDisplayBlanksAfterDozeConfig=" + mDisplayBlanksAfterDozeConfig);
+        pw.println("  mBrightnessBucketsInDozeConfig=" + mBrightnessBucketsInDozeConfig);
 
         mHandler.runWithScissors(new Runnable() {
             @Override
@@ -1603,6 +1624,7 @@
         pw.println();
         pw.println("Display Power Controller Thread State:");
         pw.println("  mPowerRequest=" + mPowerRequest);
+        pw.println("  mUnfinishedBusiness=" + mUnfinishedBusiness);
         pw.println("  mWaitingForNegativeProximity=" + mWaitingForNegativeProximity);
         pw.println("  mProximitySensor=" + mProximitySensor);
         pw.println("  mProximitySensorEnabled=" + mProximitySensorEnabled);
@@ -1615,12 +1637,23 @@
         pw.println("  mLastUserSetScreenBrightness=" + mLastUserSetScreenBrightness);
         pw.println("  mCurrentScreenBrightnessSetting=" + mCurrentScreenBrightnessSetting);
         pw.println("  mPendingScreenBrightnessSetting=" + mPendingScreenBrightnessSetting);
+        pw.println("  mTemporaryScreenBrightness=" + mTemporaryScreenBrightness);
         pw.println("  mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment);
+        pw.println("  mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment);
         pw.println("  mPendingAutoBrightnessAdjustment=" + mPendingAutoBrightnessAdjustment);
+        pw.println("  mScreenBrightnessForVr=" + mScreenBrightnessForVr);
         pw.println("  mAppliedAutoBrightness=" + mAppliedAutoBrightness);
         pw.println("  mAppliedDimming=" + mAppliedDimming);
         pw.println("  mAppliedLowPower=" + mAppliedLowPower);
+        pw.println("  mAppliedScreenBrightnessOverride=" + mAppliedScreenBrightnessOverride);
+        pw.println("  mAppliedTemporaryBrightness=" + mAppliedTemporaryBrightness);
+        pw.println("  mDozing=" + mDozing);
+        pw.println("  mSkipRampState=" + skipRampStateToString(mSkipRampState));
+        pw.println("  mInitialAutoBrightness=" + mInitialAutoBrightness);
+        pw.println("  mScreenOnBlockStartRealTime=" + mScreenOnBlockStartRealTime);
+        pw.println("  mScreenOffBlockStartRealTime=" + mScreenOffBlockStartRealTime);
         pw.println("  mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker);
+        pw.println("  mPendingScreenOffUnblocker=" + mPendingScreenOffUnblocker);
         pw.println("  mPendingScreenOff=" + mPendingScreenOff);
         pw.println("  mReportedToPolicy=" +
                 reportedToPolicyToString(mReportedScreenStateToPolicy));
@@ -1677,6 +1710,19 @@
         }
     }
 
+    private static String skipRampStateToString(int state) {
+        switch (state) {
+            case RAMP_STATE_SKIP_NONE:
+                return "RAMP_STATE_SKIP_NONE";
+            case RAMP_STATE_SKIP_INITIAL:
+                return "RAMP_STATE_SKIP_INITIAL";
+            case RAMP_STATE_SKIP_AUTOBRIGHT:
+                return "RAMP_STATE_SKIP_AUTOBRIGHT";
+            default:
+                return Integer.toString(state);
+        }
+    }
+
     private static int clampAbsoluteBrightness(int value) {
         return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
     }
diff --git a/services/core/java/com/android/server/display/HysteresisLevels.java b/services/core/java/com/android/server/display/HysteresisLevels.java
index b062225..1c02dd1 100644
--- a/services/core/java/com/android/server/display/HysteresisLevels.java
+++ b/services/core/java/com/android/server/display/HysteresisLevels.java
@@ -18,6 +18,9 @@
 
 import android.util.Slog;
 
+import java.io.PrintWriter;
+import java.util.Arrays;
+
 /**
  * A helper class for handling access to illuminance hysteresis level values.
  */
@@ -101,4 +104,11 @@
         }
         return levelArray;
     }
+
+    public void dump(PrintWriter pw) {
+        pw.println("HysteresisLevels");
+        pw.println("  mBrightLevels=" + Arrays.toString(mBrightLevels));
+        pw.println("  mDarkLevels=" + Arrays.toString(mDarkLevels));
+        pw.println("  mLuxLevels=" + Arrays.toString(mLuxLevels));
+    }
 }
diff --git a/services/core/java/com/android/server/job/JobPackageTracker.java b/services/core/java/com/android/server/job/JobPackageTracker.java
index 8b8faa3..e28e5bd 100644
--- a/services/core/java/com/android/server/job/JobPackageTracker.java
+++ b/services/core/java/com/android/server/job/JobPackageTracker.java
@@ -58,14 +58,17 @@
     private final int[] mEventUids = new int[EVENT_BUFFER_SIZE];
     private final String[] mEventTags = new String[EVENT_BUFFER_SIZE];
     private final int[] mEventJobIds = new int[EVENT_BUFFER_SIZE];
+    private final String[] mEventReasons = new String[EVENT_BUFFER_SIZE];
 
-    public void addEvent(int cmd, int uid, String tag, int jobId, int stopReason) {
+    public void addEvent(int cmd, int uid, String tag, int jobId, int stopReason,
+            String debugReason) {
         int index = mEventIndices.add();
         mEventCmds[index] = cmd | ((stopReason<<EVENT_STOP_REASON_SHIFT) & EVENT_STOP_REASON_MASK);
         mEventTimes[index] = sElapsedRealtimeClock.millis();
         mEventUids[index] = uid;
         mEventTags[index] = tag;
         mEventJobIds[index] = jobId;
+        mEventReasons[index] = debugReason;
     }
 
     DataSet mCurDataSet = new DataSet();
@@ -470,10 +473,10 @@
             mCurDataSet.incActive(job.getSourceUid(), job.getSourcePackageName(), now);
         }
         addEvent(job.getJob().isPeriodic() ? EVENT_START_PERIODIC_JOB :  EVENT_START_JOB,
-                job.getSourceUid(), job.getBatteryName(), job.getJobId(), 0);
+                job.getSourceUid(), job.getBatteryName(), job.getJobId(), 0, null);
     }
 
-    public void noteInactive(JobStatus job, int stopReason) {
+    public void noteInactive(JobStatus job, int stopReason, String debugReason) {
         final long now = sUptimeMillisClock.millis();
         if (job.lastEvaluatedPriority >= JobInfo.PRIORITY_TOP_APP) {
             mCurDataSet.decActiveTop(job.getSourceUid(), job.getSourcePackageName(), now,
@@ -483,7 +486,7 @@
         }
         rebatchIfNeeded(now);
         addEvent(job.getJob().isPeriodic() ? EVENT_STOP_JOB :  EVENT_STOP_PERIODIC_JOB,
-                job.getSourceUid(), job.getBatteryName(), job.getJobId(), stopReason);
+                job.getSourceUid(), job.getBatteryName(), job.getJobId(), stopReason, debugReason);
     }
 
     public void noteConcurrency(int totalActive, int fgActive) {
@@ -599,8 +602,13 @@
             pw.print(mEventTags[index]);
             if (cmd == EVENT_STOP_JOB || cmd == EVENT_STOP_PERIODIC_JOB) {
                 pw.print(" ");
-                pw.print(JobParameters.getReasonName((mEventCmds[index] & EVENT_STOP_REASON_MASK)
-                        >> EVENT_STOP_REASON_SHIFT));
+                final String reason = mEventReasons[index];
+                if (reason != null) {
+                    pw.print(mEventReasons[index]);
+                } else {
+                    pw.print(JobParameters.getReasonName((mEventCmds[index] & EVENT_STOP_REASON_MASK)
+                            >> EVENT_STOP_REASON_SHIFT));
+                }
             }
             pw.println();
         }
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/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index 0bb6854..8578bb7 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -770,7 +770,7 @@
         }
         applyStoppedReasonLocked(reason);
         completedJob = mRunningJob;
-        mJobPackageTracker.noteInactive(completedJob, mParams.getStopReason());
+        mJobPackageTracker.noteInactive(completedJob, mParams.getStopReason(), reason);
         try {
             mBatteryStats.noteJobFinish(mRunningJob.getBatteryName(),
                     mRunningJob.getSourceUid(), mParams.getStopReason());
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/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/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 16440c8..5ee7084 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;
 
@@ -1136,6 +1138,7 @@
         }
         getAudioManagerInternal();
         mAudioManagerInternal.silenceRingerModeInternal("volume_hush");
+        mLogger.action(MetricsProto.MetricsEvent.ACTION_HUSH_GESTURE, mRingerToggleChord);
     }
 
     IStatusBarService getStatusBarService() {
@@ -2003,6 +2006,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);
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index 507f0a8..2621c50 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -36,6 +36,7 @@
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentProvider;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -49,6 +50,8 @@
 import android.os.Looper;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
 import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.Slog;
@@ -69,6 +72,7 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.FileDescriptor;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
@@ -320,6 +324,12 @@
         }
     }
 
+    @Override
+    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+            String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
+        new SliceShellCommand(this).exec(this, in, out, err, args, callback, resultReceiver);
+    }
+
     ///  ----- internal code -----
     private void enforceOwner(String pkg, Uri uri, int user) {
         if (!Objects.equals(getProviderPkg(uri, user), pkg) || pkg == null) {
@@ -541,6 +551,14 @@
         }
     };
 
+    public String[] getAllPackagesGranted(String authority) {
+        String pkg = getProviderPkg(new Uri.Builder()
+                .scheme(ContentResolver.SCHEME_CONTENT)
+                .authority(authority)
+                .build(), 0);
+        return mPermissions.getAllPackagesGranted(pkg);
+    }
+
     public static class Lifecycle extends SystemService {
         private SliceManagerService mService;
 
diff --git a/services/core/java/com/android/server/slice/SlicePermissionManager.java b/services/core/java/com/android/server/slice/SlicePermissionManager.java
index c67f94b..780bc96 100644
--- a/services/core/java/com/android/server/slice/SlicePermissionManager.java
+++ b/services/core/java/com/android/server/slice/SlicePermissionManager.java
@@ -133,6 +133,16 @@
         mHandler.obtainMessage(H.MSG_REMOVE, pkgUser);
     }
 
+    public String[] getAllPackagesGranted(String pkg) {
+        ArraySet<String> ret = new ArraySet<>();
+        for (SliceAuthority authority : getProvider(new PkgUser(pkg, 0)).getAuthorities()) {
+            for (PkgUser pkgUser : authority.getPkgs()) {
+                ret.add(pkgUser.mPkg);
+            }
+        }
+        return ret.toArray(new String[ret.size()]);
+    }
+
     public boolean hasFullAccess(String pkg, int userId) {
         PkgUser pkgUser = new PkgUser(pkg, userId);
         return getClient(pkgUser).hasFullAccess();
diff --git a/services/core/java/com/android/server/slice/SliceShellCommand.java b/services/core/java/com/android/server/slice/SliceShellCommand.java
new file mode 100644
index 0000000..9137a3b
--- /dev/null
+++ b/services/core/java/com/android/server/slice/SliceShellCommand.java
@@ -0,0 +1,110 @@
+/*
+ * 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.slice;
+
+import android.app.slice.SliceProvider;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.ShellCommand;
+import android.util.ArraySet;
+
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Set;
+
+public class SliceShellCommand extends ShellCommand {
+
+    private final SliceManagerService mService;
+
+    public SliceShellCommand(SliceManagerService service) {
+        mService = service;
+    }
+
+    @Override
+    public int onCommand(String cmd) {
+        if (cmd == null) {
+            return handleDefaultCommands(cmd);
+        }
+        switch (cmd) {
+            case "get-permissions":
+                return runGetPermissions(getNextArgRequired());
+        }
+        return 0;
+    }
+
+    @Override
+    public void onHelp() {
+        final PrintWriter pw = getOutPrintWriter();
+        pw.println("Status bar commands:");
+        pw.println("  help");
+        pw.println("    Print this help text.");
+        pw.println("");
+        pw.println("  get-permissions <authority>");
+        pw.println("    List the pkgs that have permission to an authority.");
+        pw.println("");
+
+    }
+
+    private int runGetPermissions(String authority) {
+        if (Binder.getCallingUid() != Process.SHELL_UID
+                && Binder.getCallingUid() != Process.ROOT_UID) {
+            getOutPrintWriter().println("Only shell can get permissions");
+            return -1;
+        }
+        Context context = mService.getContext();
+        long ident = Binder.clearCallingIdentity();
+        try {
+            Uri uri = new Uri.Builder()
+                    .scheme(ContentResolver.SCHEME_CONTENT)
+                    .authority(authority)
+                    .build();
+            if (!SliceProvider.SLICE_TYPE.equals(context.getContentResolver().getType(uri))) {
+                getOutPrintWriter().println(authority + " is not a slice provider");
+                return -1;
+            }
+            Bundle b = context.getContentResolver().call(uri, SliceProvider.METHOD_GET_PERMISSIONS,
+                    null, null);
+            if (b == null) {
+                getOutPrintWriter().println("An error occurred getting permissions");
+                return -1;
+            }
+            String[] permissions = b.getStringArray(SliceProvider.EXTRA_RESULT);
+            final PrintWriter pw = getOutPrintWriter();
+            Set<String> listedPackages = new ArraySet<>();
+            if (permissions != null && permissions.length != 0) {
+                List<PackageInfo> apps =
+                        context.getPackageManager().getPackagesHoldingPermissions(permissions, 0);
+                for (PackageInfo app : apps) {
+                    pw.println(app.packageName);
+                    listedPackages.add(app.packageName);
+                }
+            }
+            for (String pkg : mService.getAllPackagesGranted(authority)) {
+                if (!listedPackages.contains(pkg)) {
+                    pw.println(pkg);
+                    listedPackages.add(pkg);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+        return 0;
+    }
+}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index c0dc750..f3423c6 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -390,6 +390,11 @@
      */
     int mLayoutSeq = 0;
 
+    /**
+     * Specifies the count to determine whether to defer updating the IME target until ready.
+     */
+    private int mDeferUpdateImeTargetCount;
+
     /** Temporary float array to retrieve 3x3 matrix values. */
     private final float[] mTmpFloats = new float[9];
 
@@ -2454,6 +2459,12 @@
             return null;
         }
 
+        final WindowState curTarget = mService.mInputMethodTarget;
+        if (!canUpdateImeTarget()) {
+            if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Defer updating IME target");
+            return curTarget;
+        }
+
         // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
         // same display. Or even when the current IME/target are not on the same screen as the next
         // IME/target. For now only look for input windows on the main screen.
@@ -2477,16 +2488,13 @@
         if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.v(TAG_WM,
                 "Proposed new IME target: " + target);
 
-        // Now, a special case -- if the last target's window is in the process of exiting, and is
-        // above the new target, keep on the last target to avoid flicker. Consider for example a
-        // Dialog with the IME shown: when the Dialog is dismissed, we want to keep the IME above it
-        // until it is completely gone so it doesn't drop behind the dialog or its full-screen
-        // scrim.
-        final WindowState curTarget = mService.mInputMethodTarget;
+        // Now, a special case -- if the last target's window is in the process of exiting, and the
+        // new target is home, keep on the last target to avoid flicker. Home is a special case
+        // since its above other stacks in the ordering list, but layed out below the others.
         if (curTarget != null && curTarget.isDisplayedLw() && curTarget.isClosing()
-                && (target == null
-                    || curTarget.mWinAnimator.mAnimLayer > target.mWinAnimator.mAnimLayer)) {
-            if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing");
+                && (target == null || target.isActivityTypeHome())) {
+            if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "New target is home while current target is"
+                    + "closing, not changing");
             return curTarget;
         }
 
@@ -3958,4 +3966,33 @@
     void assignStackOrdering() {
         mTaskStackContainers.assignStackOrdering(getPendingTransaction());
     }
+
+    /**
+     * Increment the deferral count to determine whether to update the IME target.
+     */
+    void deferUpdateImeTarget() {
+        mDeferUpdateImeTargetCount++;
+    }
+
+    /**
+     * Decrement the deferral count to determine whether to update the IME target. If the count
+     * reaches 0, a new ime target will get computed.
+     */
+    void continueUpdateImeTarget() {
+        if (mDeferUpdateImeTargetCount == 0) {
+            return;
+        }
+
+        mDeferUpdateImeTargetCount--;
+        if (mDeferUpdateImeTargetCount == 0) {
+            computeImeTarget(true /* updateImeTarget */);
+        }
+    }
+
+    /**
+     * @return Whether a new IME target should be computed.
+     */
+    private boolean canUpdateImeTarget() {
+        return mDeferUpdateImeTargetCount == 0;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/DisplayWindowController.java b/services/core/java/com/android/server/wm/DisplayWindowController.java
index ba8ec69..a1639c2 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowController.java
@@ -94,6 +94,31 @@
         }
     }
 
+    /**
+     * Starts deferring the ability to update the IME target. This is needed when a call will
+     * attempt to update the IME target before all information about the Windows have been updated.
+     */
+    public void deferUpdateImeTarget() {
+        synchronized (mWindowMap) {
+            final DisplayContent dc = mRoot.getDisplayContent(mDisplayId);
+            if (dc != null) {
+                dc.deferUpdateImeTarget();
+            }
+        }
+    }
+
+    /**
+     * Resumes updating the IME target after deferring. See {@link #deferUpdateImeTarget()}
+     */
+    public void continueUpdateImeTarget() {
+        synchronized (mWindowMap) {
+            final DisplayContent dc = mRoot.getDisplayContent(mDisplayId);
+            if (dc != null) {
+                dc.continueUpdateImeTarget();
+            }
+        }
+    }
+
     @Override
     public String toString() {
         return "{DisplayWindowController displayId=" + mDisplayId + "}";
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 10dfdf2..16399008 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1797,6 +1797,12 @@
                     }
                     w.setDisplayLayoutNeeded();
                     mWindowPlacerLocked.performSurfacePlacement();
+
+                    // We need to report touchable region changes to accessibility.
+                    if (mAccessibilityController != null
+                            && w.getDisplayContent().getDisplayId() == DEFAULT_DISPLAY) {
+                        mAccessibilityController.onSomeWindowResizedOrMovedLocked();
+                    }
                 }
             }
         } finally {
@@ -2691,12 +2697,7 @@
                     + " Callers=" + Debug.getCallers(5));
             if (mAppTransition.isTransitionSet()) {
                 mAppTransition.setReady();
-                final long origId = Binder.clearCallingIdentity();
-                try {
-                    mWindowPlacerLocked.performSurfacePlacement();
-                } finally {
-                    Binder.restoreCallingIdentity(origId);
-                }
+                mWindowPlacerLocked.requestTraversal();
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c710c97..91c449b 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2726,7 +2726,8 @@
     }
 
     boolean isClosing() {
-        return mAnimatingExit || (mService.mClosingApps.contains(mAppToken));
+        return mAnimatingExit || (mAppToken != null && mAppToken.isAnimating()
+                && mAppToken.hiddenRequested);
     }
 
     void addWinAnimatorToList(ArrayList<WindowStateAnimator> animators) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 729dba5..c370a00 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -3351,6 +3351,7 @@
             case SystemService.PHASE_LOCK_SETTINGS_READY:
                 onLockSettingsReady();
                 loadAdminDataAsync();
+                mOwners.systemReady();
                 break;
             case SystemService.PHASE_BOOT_COMPLETED:
                 ensureDeviceOwnerUserStarted(); // TODO Consider better place to do this.
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 8366114..632f0aa 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -17,11 +17,14 @@
 package com.android.server.devicepolicy;
 
 import android.annotation.Nullable;
+import android.app.AppOpsManagerInternal;
 import android.app.admin.SystemUpdateInfo;
 import android.app.admin.SystemUpdatePolicy;
 import android.content.ComponentName;
+import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.UserInfo;
+import android.os.Binder;
 import android.os.Environment;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -32,10 +35,12 @@
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseIntArray;
 import android.util.Xml;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FastXmlSerializer;
+import com.android.server.LocalServices;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -99,6 +104,8 @@
     private final UserManagerInternal mUserManagerInternal;
     private final PackageManagerInternal mPackageManagerInternal;
 
+    private boolean mSystemReady;
+
     // Internal state for the device owner package.
     private OwnerInfo mDeviceOwner;
 
@@ -179,6 +186,7 @@
                         getDeviceOwnerUserId()));
             }
             pushToPackageManagerLocked();
+            pushToAppOpsLocked();
         }
     }
 
@@ -262,6 +270,7 @@
 
             mUserManagerInternal.setDeviceManaged(true);
             pushToPackageManagerLocked();
+            pushToAppOpsLocked();
         }
     }
 
@@ -272,6 +281,7 @@
 
             mUserManagerInternal.setDeviceManaged(false);
             pushToPackageManagerLocked();
+            pushToAppOpsLocked();
         }
     }
 
@@ -283,6 +293,7 @@
                     /* remoteBugreportHash =*/ null));
             mUserManagerInternal.setUserManaged(userId, true);
             pushToPackageManagerLocked();
+            pushToAppOpsLocked();
         }
     }
 
@@ -291,6 +302,7 @@
             mProfileOwners.remove(userId);
             mUserManagerInternal.setUserManaged(userId, false);
             pushToPackageManagerLocked();
+            pushToAppOpsLocked();
         }
     }
 
@@ -302,6 +314,7 @@
                     ownerInfo.remoteBugreportHash);
             mProfileOwners.put(userId, newOwnerInfo);
             pushToPackageManagerLocked();
+            pushToAppOpsLocked();
         }
     }
 
@@ -313,6 +326,7 @@
                     mDeviceOwner.userRestrictionsMigrated, mDeviceOwner.remoteBugreportUri,
                     mDeviceOwner.remoteBugreportHash);
             pushToPackageManagerLocked();
+            pushToAppOpsLocked();
         }
     }
 
@@ -581,6 +595,48 @@
         }
     }
 
+    void pushToAppOpsLocked() {
+        if (!mSystemReady) {
+            return;
+        }
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            final SparseIntArray owners = new SparseIntArray();
+            if (mDeviceOwner != null) {
+                final int uid = mPackageManagerInternal.getPackageUid(mDeviceOwner.packageName,
+                        PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES,
+                        mDeviceOwnerUserId);
+                if (uid >= 0) {
+                    owners.put(mDeviceOwnerUserId, uid);
+                }
+            }
+            if (mProfileOwners != null) {
+                for (int poi = mProfileOwners.size() - 1; poi >= 0; poi--) {
+                    final int uid = mPackageManagerInternal.getPackageUid(
+                            mProfileOwners.valueAt(poi).packageName,
+                            PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES,
+                            mProfileOwners.keyAt(poi));
+                    if (uid >= 0) {
+                        owners.put(mProfileOwners.keyAt(poi), uid);
+                    }
+                }
+            }
+            AppOpsManagerInternal appops = LocalServices.getService(AppOpsManagerInternal.class);
+            if (appops != null) {
+                appops.setDeviceAndProfileOwners(owners.size() > 0 ? owners : null);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    public void systemReady() {
+        synchronized (mLock) {
+            mSystemReady = true;
+            pushToAppOpsLocked();
+        }
+    }
+
     private abstract static class FileReadWriter {
         private final File mFile;
 
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index 83a125d..dc55179 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -18,8 +18,12 @@
 
 import static android.content.pm.PackageManager.GET_SERVICES;
 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
+import static android.content.pm.PackageManager.MATCH_INSTANT;
+import static android.os.Process.ROOT_UID;
+import static android.os.Process.SHELL_UID;
 
 import android.annotation.NonNull;
+import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.content.ComponentName;
@@ -36,6 +40,8 @@
 import android.os.Looper;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.print.IPrintDocumentAdapter;
@@ -122,6 +128,13 @@
         }
 
         @Override
+        public void onShellCommand(FileDescriptor in, FileDescriptor out,
+                FileDescriptor err, String[] args, ShellCallback callback,
+                ResultReceiver resultReceiver) {
+            new PrintShellCommand(this).exec(this, in, out, err, args, callback, resultReceiver);
+        }
+
+        @Override
         public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
                 PrintAttributes attributes, String packageName, int appId, int userId) {
             adapter = Preconditions.checkNotNull(adapter);
@@ -717,6 +730,46 @@
             }
         }
 
+        @Override
+        public boolean getBindInstantServiceAllowed(@UserIdInt int userId) {
+            int callingUid = Binder.getCallingUid();
+            if (callingUid != SHELL_UID && callingUid != ROOT_UID) {
+                throw new SecurityException("Can only be called by uid " + SHELL_UID
+                        + " or " + ROOT_UID);
+            }
+
+            final UserState userState;
+            synchronized (mLock) {
+                userState = getOrCreateUserStateLocked(userId, false);
+            }
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                return userState.getBindInstantServiceAllowed();
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
+        @Override
+        public void setBindInstantServiceAllowed(@UserIdInt int userId, boolean allowed) {
+            int callingUid = Binder.getCallingUid();
+            if (callingUid != SHELL_UID && callingUid != ROOT_UID) {
+                throw new SecurityException("Can only be called by uid " + SHELL_UID
+                        + " or " + ROOT_UID);
+            }
+
+            final UserState userState;
+            synchronized (mLock) {
+                userState = getOrCreateUserStateLocked(userId, false);
+            }
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                userState.setBindInstantServiceAllowed(allowed);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
         private boolean isPrintingEnabled() {
             return !mUserManager.hasUserRestriction(UserManager.DISALLOW_PRINTING,
                     Binder.getCallingUserHandle());
@@ -773,7 +826,7 @@
 
                     List<ResolveInfo> installedServices = mContext.getPackageManager()
                             .queryIntentServicesAsUser(intent,
-                                    GET_SERVICES | MATCH_DEBUG_TRIAGED_MISSING,
+                                    GET_SERVICES | MATCH_DEBUG_TRIAGED_MISSING | MATCH_INSTANT,
                                     getChangingUserId());
 
                     return installedServices != null && !installedServices.isEmpty();
@@ -988,7 +1041,7 @@
                 return appId;
             }
             final int callingAppId = UserHandle.getAppId(callingUid);
-            if (appId == callingAppId || callingAppId == Process.SHELL_UID
+            if (appId == callingAppId || callingAppId == SHELL_UID
                     || callingAppId == Process.SYSTEM_UID) {
                 return appId;
             }
diff --git a/services/print/java/com/android/server/print/PrintShellCommand.java b/services/print/java/com/android/server/print/PrintShellCommand.java
new file mode 100644
index 0000000..11642e5
--- /dev/null
+++ b/services/print/java/com/android/server/print/PrintShellCommand.java
@@ -0,0 +1,112 @@
+/*
+ * 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.print;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.RemoteException;
+import android.os.ShellCommand;
+import android.os.UserHandle;
+import android.print.IPrintManager;
+
+import java.io.PrintWriter;
+
+/**
+ * Shell command implementation for the print manager service
+ */
+final class PrintShellCommand extends ShellCommand {
+    final @NonNull IPrintManager mService;
+
+    PrintShellCommand(@NonNull IPrintManager service) {
+        mService = service;
+    }
+
+    @Override
+    public int onCommand(@Nullable String cmd) {
+        if (cmd == null) {
+            return handleDefaultCommands(cmd);
+        }
+        switch (cmd) {
+            case "get-bind-instant-service-allowed": {
+                return runGetBindInstantServiceAllowed();
+            }
+            case "set-bind-instant-service-allowed": {
+                return runSetBindInstantServiceAllowed();
+            }
+        }
+        return -1;
+    }
+
+    private int runGetBindInstantServiceAllowed() {
+        final Integer userId = parseUserId();
+        if (userId == null) {
+            return -1;
+        }
+        try {
+            getOutPrintWriter().println(
+                    Boolean.toString(mService.getBindInstantServiceAllowed(userId)));
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+        return 0;
+    }
+
+    private int runSetBindInstantServiceAllowed() {
+        final Integer userId = parseUserId();
+        if (userId == null) {
+            return -1;
+        }
+        final String allowed = getNextArgRequired();
+        if (allowed == null) {
+            getErrPrintWriter().println("Error: no true/false specified");
+            return -1;
+        }
+        try {
+            mService.setBindInstantServiceAllowed(userId, Boolean.parseBoolean(allowed));
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+        return 0;
+    }
+
+    private @Nullable Integer parseUserId() {
+        final String option = getNextOption();
+        if (option != null) {
+            if (option.equals("--user")) {
+                return UserHandle.parseUserArg(getNextArgRequired());
+            } else {
+                getErrPrintWriter().println("Unknown option: " + option);
+                return null;
+            }
+        }
+        return UserHandle.USER_SYSTEM;
+    }
+
+    @Override
+    public void onHelp() {
+        PrintWriter pw = getOutPrintWriter();
+        pw.println("Print service commands:");
+        pw.println("  help");
+        pw.println("    Print this help text.");
+        pw.println("  set-bind-instant-service-allowed [--user <USER_ID>] true|false ");
+        pw.println("    Set whether binding to print services provided by instant apps is "
+                + "allowed.");
+        pw.println("  get-bind-instant-service-allowed [--user <USER_ID>]");
+        pw.println("    Get whether binding to print services provided by instant apps is "
+                + "allowed.");
+    }
+}
diff --git a/services/print/java/com/android/server/print/RemotePrintService.java b/services/print/java/com/android/server/print/RemotePrintService.java
index d4cbe7b..4f0d6f1 100644
--- a/services/print/java/com/android/server/print/RemotePrintService.java
+++ b/services/print/java/com/android/server/print/RemotePrintService.java
@@ -571,8 +571,8 @@
         mBinding = true;
 
         boolean wasBound = mContext.bindServiceAsUser(mIntent, mServiceConnection,
-                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
-                new UserHandle(mUserId));
+                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
+                        | Context.BIND_ALLOW_INSTANT, new UserHandle(mUserId));
 
         if (!wasBound) {
             if (DEBUG) {
diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java
index 62185d7..4fbc14c 100644
--- a/services/print/java/com/android/server/print/UserState.java
+++ b/services/print/java/com/android/server/print/UserState.java
@@ -19,6 +19,7 @@
 import static android.content.pm.PackageManager.GET_META_DATA;
 import static android.content.pm.PackageManager.GET_SERVICES;
 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
+import static android.content.pm.PackageManager.MATCH_INSTANT;
 
 import static com.android.internal.print.DumpUtils.writePrintJobInfo;
 import static com.android.internal.print.DumpUtils.writePrinterId;
@@ -155,6 +156,11 @@
      */
     private RemotePrintServiceRecommendationService mPrintServiceRecommendationsService;
 
+    /**
+     * Can services from instant apps be bound? (usually disabled, only used by testing)
+     */
+    private boolean mIsInstantServiceAllowed;
+
     public UserState(Context context, int userId, Object lock, boolean lowPriority) {
         mContext = context;
         mUserId = userId;
@@ -872,9 +878,14 @@
     private void readInstalledPrintServicesLocked() {
         Set<PrintServiceInfo> tempPrintServices = new HashSet<PrintServiceInfo>();
 
+        int queryIntentFlags = GET_SERVICES | GET_META_DATA | MATCH_DEBUG_TRIAGED_MISSING;
+
+        if (mIsInstantServiceAllowed) {
+            queryIntentFlags |= MATCH_INSTANT;
+        }
+
         List<ResolveInfo> installedServices = mContext.getPackageManager()
-                .queryIntentServicesAsUser(mQueryIntent,
-                        GET_SERVICES | GET_META_DATA | MATCH_DEBUG_TRIAGED_MISSING, mUserId);
+                .queryIntentServicesAsUser(mQueryIntent, queryIntentFlags, mUserId);
 
         final int installedCount = installedServices.size();
         for (int i = 0, count = installedCount; i < count; i++) {
@@ -1185,6 +1196,18 @@
         }
     }
 
+    public boolean getBindInstantServiceAllowed() {
+        return mIsInstantServiceAllowed;
+    }
+
+    public void setBindInstantServiceAllowed(boolean allowed) {
+        synchronized (mLock) {
+            mIsInstantServiceAllowed = allowed;
+
+            updateIfNeededLocked();
+        }
+    }
+
     private abstract class PrintJobStateChangeListenerRecord implements DeathRecipient {
         @NonNull final IPrintJobStateChangeListener listener;
         final int appId;
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/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
index 18e842f..1520859 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
@@ -243,7 +243,7 @@
         if (containsConditions(preconditions,PRECONDITION_CANNOT_START_ANY_ACTIVITY)) {
             doReturn(false).when(service.mStackSupervisor).checkStartAnyActivityPermission(
                     any(), any(), any(), anyInt(), anyInt(), anyInt(), any(),
-                    anyBoolean(), any(), any(), any());
+                    anyBoolean(), anyBoolean(), any(), any(), any());
         }
 
         try {
@@ -302,7 +302,7 @@
         // always allow test to start activity.
         doReturn(true).when(mService.mStackSupervisor).checkStartAnyActivityPermission(
                 any(), any(), any(), anyInt(), anyInt(), anyInt(), any(),
-                anyBoolean(), any(), any(), any());
+                anyBoolean(), anyBoolean(), any(), any(), any());
 
         // instrument the stack and task used.
         final ActivityStack stack = mService.mStackSupervisor.getDefaultDisplay().createStack(
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/telecomm/java/android/telecom/CallAudioState.java b/telecomm/java/android/telecom/CallAudioState.java
index 4b827d2..e33ba7e 100644
--- a/telecomm/java/android/telecom/CallAudioState.java
+++ b/telecomm/java/android/telecom/CallAudioState.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.bluetooth.BluetoothDevice;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -100,6 +101,7 @@
     }
 
     /** @hide */
+    @TestApi
     public CallAudioState(boolean isMuted, @CallAudioRoute int route,
             @CallAudioRoute int supportedRouteMask,
             @Nullable BluetoothDevice activeBluetoothDevice,
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/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 5a77a9f..487490c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -3443,14 +3443,13 @@
      * to the TelephonyManager.
      * When the filter is enabled, {@link
      * VisualVoicemailService#onSmsReceived(VisualVoicemailTask, VisualVoicemailSms)} will be
-     * called when a SMS matching the settings is received. The caller should have
-     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} and implement a
-     * VisualVoicemailService.
-     *
-     * <p>Requires Permission:
-     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     * called when a SMS matching the settings is received. Caller must be the default dialer,
+     * system dialer, or carrier visual voicemail app.
      *
      * @param settings The settings for the filter, or {@code null} to disable the filter.
+     *
+     * @see {@link TelecomManager#getDefaultDialerPackage()}
+     * @see {@link CarrierConfigManager#KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY}
      */
     public void setVisualVoicemailSmsFilterSettings(VisualVoicemailSmsFilterSettings settings) {
         if (settings == null) {
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/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/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp
index 4e202df..3689a8f 100644
--- a/tools/incident_section_gen/main.cpp
+++ b/tools/incident_section_gen/main.cpp
@@ -421,7 +421,7 @@
                 printf(" NULL),\n");
                 break;
             case SECTION_DUMPSYS:
-                printf("    new DumpsysSection(%d, \"%s\",", field->number(),
+                printf("    new DumpsysSection(%d, %s,", field->number(),
                        s.userdebug_and_eng_only() ? "true" : "false");
                 splitAndPrint(s.args());
                 printf(" NULL),\n");
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;