Merge "Use WindowProcessController configuration for process"
diff --git a/Android.bp b/Android.bp
index cc9cfe9..c568d36 100644
--- a/Android.bp
+++ b/Android.bp
@@ -162,6 +162,7 @@
         "core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl",
         "core/java/android/hardware/biometrics/IBiometricServiceReceiverInternal.aidl",
         "core/java/android/hardware/biometrics/IBiometricServiceLockoutResetCallback.aidl",
+        "core/java/android/hardware/display/IColorDisplayManager.aidl",
         "core/java/android/hardware/display/IDisplayManager.aidl",
         "core/java/android/hardware/display/IDisplayManagerCallback.aidl",
         "core/java/android/hardware/display/IVirtualDisplayCallback.aidl",
@@ -653,6 +654,8 @@
         "core/java/com/android/server/DropboxLogTags.logtags",
         "core/java/org/chromium/arc/EventLogTags.logtags",
 
+        ":platform-properties",
+
         ":framework-statslog-gen",
     ],
 
diff --git a/Android.mk b/Android.mk
index b7dda9a..92e33e9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -76,10 +76,9 @@
 .KATI_RESTAT: $(INTERNAL_PLATFORM_HIDDENAPI_FLAGS)
 $(INTERNAL_PLATFORM_HIDDENAPI_FLAGS): \
     frameworks/base/tools/hiddenapi/generate_hiddenapi_lists.py \
-    frameworks/base/config/hiddenapi-light-greylist.txt \
-    frameworks/base/config/hiddenapi-vendor-list.txt \
+    frameworks/base/config/hiddenapi-greylist.txt \
+    frameworks/base/config/hiddenapi-greylist-max-p.txt \
     frameworks/base/config/hiddenapi-greylist-max-o.txt \
-    frameworks/base/config/hiddenapi-max-sdk-p-blacklist.txt \
     frameworks/base/config/hiddenapi-force-blacklist.txt \
     $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) \
     $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST) \
@@ -88,10 +87,9 @@
 	    --public $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) \
 	    --private $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST) \
 	    --csv $(PRIVATE_FLAGS_INPUTS) \
-	    --greylist \
-	        frameworks/base/config/hiddenapi-light-greylist.txt \
-	        frameworks/base/config/hiddenapi-vendor-list.txt \
+	    --greylist frameworks/base/config/hiddenapi-greylist.txt \
 	    --greylist-ignore-conflicts $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE) \
+	    --greylist-max-p frameworks/base/config/hiddenapi-greylist-max-p.txt \
 	    --greylist-max-o-ignore-conflicts \
 	        frameworks/base/config/hiddenapi-greylist-max-o.txt \
 	    --blacklist frameworks/base/config/hiddenapi-force-blacklist.txt \
diff --git a/api/current.txt b/api/current.txt
index 83827ea..2eb90d5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7692,6 +7692,7 @@
     method protected void prepareView(android.view.View);
     method public void setAppWidget(int, android.appwidget.AppWidgetProviderInfo);
     method public void setExecutor(java.util.concurrent.Executor);
+    method public void setOnLightBackground(boolean);
     method public void updateAppWidget(android.widget.RemoteViews);
     method public void updateAppWidgetOptions(android.os.Bundle);
     method public void updateAppWidgetSize(android.os.Bundle, int, int, int, int);
@@ -24551,16 +24552,30 @@
 
   public final class MediaFormat {
     ctor public MediaFormat();
+    ctor public MediaFormat(android.media.MediaFormat);
+    method public boolean containsFeature(java.lang.String);
     method public boolean containsKey(java.lang.String);
     method public static android.media.MediaFormat createAudioFormat(java.lang.String, int, int);
     method public static android.media.MediaFormat createSubtitleFormat(java.lang.String, java.lang.String);
     method public static android.media.MediaFormat createVideoFormat(java.lang.String, int, int);
     method public java.nio.ByteBuffer getByteBuffer(java.lang.String);
+    method public java.nio.ByteBuffer getByteBuffer(java.lang.String, java.nio.ByteBuffer);
     method public boolean getFeatureEnabled(java.lang.String);
+    method public java.util.Set<java.lang.String> getFeatures();
     method public float getFloat(java.lang.String);
+    method public float getFloat(java.lang.String, float);
     method public int getInteger(java.lang.String);
+    method public int getInteger(java.lang.String, int);
+    method public java.util.Set<java.lang.String> getKeys();
     method public long getLong(java.lang.String);
+    method public long getLong(java.lang.String, long);
+    method public java.lang.Number getNumber(java.lang.String);
+    method public java.lang.Number getNumber(java.lang.String, java.lang.Number);
     method public java.lang.String getString(java.lang.String);
+    method public java.lang.String getString(java.lang.String, java.lang.String);
+    method public int getValueTypeForKey(java.lang.String);
+    method public void removeFeature(java.lang.String);
+    method public void removeKey(java.lang.String);
     method public void setByteBuffer(java.lang.String, java.nio.ByteBuffer);
     method public void setFeatureEnabled(java.lang.String, boolean);
     method public void setFloat(java.lang.String, float);
@@ -24665,6 +24680,12 @@
     field public static final java.lang.String MIMETYPE_VIDEO_SCRAMBLED = "video/scrambled";
     field public static final java.lang.String MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8";
     field public static final java.lang.String MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
+    field public static final int TYPE_BYTE_BUFFER = 5; // 0x5
+    field public static final int TYPE_FLOAT = 3; // 0x3
+    field public static final int TYPE_INTEGER = 1; // 0x1
+    field public static final int TYPE_LONG = 2; // 0x2
+    field public static final int TYPE_NULL = 0; // 0x0
+    field public static final int TYPE_STRING = 4; // 0x4
   }
 
   public final class MediaMetadata implements android.os.Parcelable {
@@ -37516,8 +37537,8 @@
     field public static final java.lang.String DATE_TAKEN = "datetaken";
     field public static final java.lang.String DESCRIPTION = "description";
     field public static final java.lang.String IS_PRIVATE = "isprivate";
-    field public static final java.lang.String LATITUDE = "latitude";
-    field public static final java.lang.String LONGITUDE = "longitude";
+    field public static final deprecated java.lang.String LATITUDE = "latitude";
+    field public static final deprecated java.lang.String LONGITUDE = "longitude";
     field public static final deprecated java.lang.String MINI_THUMB_MAGIC = "mini_thumb_magic";
     field public static final java.lang.String ORIENTATION = "orientation";
     field public static final deprecated java.lang.String PICASA_ID = "picasa_id";
@@ -37641,8 +37662,8 @@
     field public static final java.lang.String DURATION = "duration";
     field public static final java.lang.String IS_PRIVATE = "isprivate";
     field public static final java.lang.String LANGUAGE = "language";
-    field public static final java.lang.String LATITUDE = "latitude";
-    field public static final java.lang.String LONGITUDE = "longitude";
+    field public static final deprecated java.lang.String LATITUDE = "latitude";
+    field public static final deprecated java.lang.String LONGITUDE = "longitude";
     field public static final deprecated java.lang.String MINI_THUMB_MAGIC = "mini_thumb_magic";
     field public static final java.lang.String RESOLUTION = "resolution";
     field public static final java.lang.String TAGS = "tags";
@@ -45866,8 +45887,8 @@
     method public deprecated java.lang.String getLocale();
     method public java.util.Locale getLocaleObject();
     method public int getSpanTypeId();
-    method public int getUnderlineColor();
     method public java.lang.String[] getSuggestions();
+    method public int getUnderlineColor();
     method public void setFlags(int);
     method public void updateDrawState(android.text.TextPaint);
     method public void writeToParcel(android.os.Parcel, int);
@@ -47868,6 +47889,7 @@
     method public final boolean isFunctionPressed();
     method public static final boolean isGamepadButton(int);
     method public final boolean isLongPress();
+    method public static final boolean isMediaSessionKey(int);
     method public final boolean isMetaPressed();
     method public static boolean isModifierKey(int);
     method public final boolean isNumLockOn();
@@ -55060,6 +55082,7 @@
     method public void setInt(int, java.lang.String, int);
     method public void setIntent(int, java.lang.String, android.content.Intent);
     method public void setLabelFor(int, int);
+    method public void setLightBackgroundLayoutId(int);
     method public void setLong(int, java.lang.String, long);
     method public void setOnClickFillInIntent(int, android.content.Intent);
     method public void setOnClickPendingIntent(int, android.app.PendingIntent);
diff --git a/api/system-current.txt b/api/system-current.txt
index 6ee7afa..ca06b07 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -57,6 +57,7 @@
     field public static final java.lang.String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS";
     field public static final java.lang.String CONNECTIVITY_INTERNAL = "android.permission.CONNECTIVITY_INTERNAL";
     field public static final java.lang.String CONNECTIVITY_USE_RESTRICTED_NETWORKS = "android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS";
+    field public static final java.lang.String CONTROL_DISPLAY_COLOR_TRANSFORMS = "android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS";
     field public static final java.lang.String CONTROL_DISPLAY_SATURATION = "android.permission.CONTROL_DISPLAY_SATURATION";
     field public static final java.lang.String CONTROL_INCALL_EXPERIENCE = "android.permission.CONTROL_INCALL_EXPERIENCE";
     field public static final java.lang.String CONTROL_KEYGUARD_SECURE_NOTIFICATIONS = "android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS";
@@ -108,6 +109,7 @@
     field public static final java.lang.String MANAGE_DEVICE_ADMINS = "android.permission.MANAGE_DEVICE_ADMINS";
     field public static final java.lang.String MANAGE_IPSEC_TUNNELS = "android.permission.MANAGE_IPSEC_TUNNELS";
     field public static final java.lang.String MANAGE_ROLE_HOLDERS = "android.permission.MANAGE_ROLE_HOLDERS";
+    field public static final java.lang.String MANAGE_SMART_SUGGESTIONS = "android.permission.MANAGE_SMART_SUGGESTIONS";
     field public static final java.lang.String MANAGE_SOUND_TRIGGER = "android.permission.MANAGE_SOUND_TRIGGER";
     field public static final java.lang.String MANAGE_SUBSCRIPTION_PLANS = "android.permission.MANAGE_SUBSCRIPTION_PLANS";
     field public static final java.lang.String MANAGE_USB = "android.permission.MANAGE_USB";
@@ -3013,6 +3015,7 @@
 package android.media.session {
 
   public final class MediaSessionManager {
+    method public android.media.session.ISession createSession(android.media.session.MediaSession.CallbackStub, java.lang.String, int);
     method public void setOnMediaKeyListener(android.media.session.MediaSessionManager.OnMediaKeyListener, android.os.Handler);
     method public void setOnVolumeKeyLongPressListener(android.media.session.MediaSessionManager.OnVolumeKeyLongPressListener, android.os.Handler);
   }
@@ -3889,14 +3892,6 @@
 
 }
 
-package android.net.wifi.p2p {
-
-  public class WifiP2pManager {
-    method public void factoryReset(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-  }
-
-}
-
 package android.net.wifi.rtt {
 
   public static final class RangingRequest.Builder {
@@ -4629,6 +4624,7 @@
   public static final class Settings.Secure extends android.provider.Settings.NameValueTable {
     method public static boolean putString(android.content.ContentResolver, java.lang.String, java.lang.String, java.lang.String, boolean);
     method public static void resetToDefaults(android.content.ContentResolver, java.lang.String);
+    field public static final java.lang.String ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED = "accessibility_display_magnification_navbar_enabled";
     field public static final java.lang.String ASSIST_GESTURE_SETUP_COMPLETE = "assist_gesture_setup_complete";
     field public static final java.lang.String AUTOFILL_FEATURE_FIELD_CLASSIFICATION = "autofill_field_classification";
     field public static final java.lang.String AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT = "autofill_user_data_max_category_count";
@@ -5784,6 +5780,8 @@
     method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList();
     method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
     method public void requestEmbeddedSubscriptionInfoListRefresh();
+    method public void setDefaultDataSubId(int);
+    method public void setDefaultSmsSubId(int);
     method public void setSubscriptionOverrideCongested(int, boolean, long);
     method public void setSubscriptionOverrideUnmetered(int, boolean, long);
     method public void setSubscriptionPlans(int, java.util.List<android.telephony.SubscriptionPlan>);
diff --git a/config/hiddenapi-max-sdk-p-blacklist.txt b/config/hiddenapi-greylist-max-p.txt
similarity index 100%
rename from config/hiddenapi-max-sdk-p-blacklist.txt
rename to config/hiddenapi-greylist-max-p.txt
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-greylist.txt
similarity index 94%
rename from config/hiddenapi-light-greylist.txt
rename to config/hiddenapi-greylist.txt
index e10f729..579ef93 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -51,6 +51,7 @@
 Landroid/app/backup/IFullBackupRestoreObserver$Stub;-><init>()V
 Landroid/app/backup/IRestoreObserver$Stub;-><init>()V
 Landroid/app/DownloadManager;->restartDownload([J)V
+Landroid/app/IActivityController$Stub;-><init>()V
 Landroid/app/IActivityManager$Stub$Proxy;->getConfiguration()Landroid/content/res/Configuration;
 Landroid/app/IActivityManager$Stub$Proxy;->getLaunchedFromUid(Landroid/os/IBinder;)I
 Landroid/app/IActivityManager$Stub$Proxy;->getProcessLimit()I
@@ -62,25 +63,35 @@
 Landroid/app/IActivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IActivityManager;
 Landroid/app/IActivityManager;->bindService(Landroid/app/IApplicationThread;Landroid/os/IBinder;Landroid/content/Intent;Ljava/lang/String;Landroid/app/IServiceConnection;ILjava/lang/String;I)I
 Landroid/app/IActivityManager;->broadcastIntent(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I
+Landroid/app/IActivityManager;->cancelRecentsAnimation(Z)V
+Landroid/app/IActivityManager;->cancelTaskWindowTransition(I)V
 Landroid/app/IActivityManager;->checkPermission(Ljava/lang/String;II)I
+Landroid/app/IActivityManager;->closeSystemDialogs(Ljava/lang/String;)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;
 Landroid/app/IActivityManager;->getConfiguration()Landroid/content/res/Configuration;
+Landroid/app/IActivityManager;->getCurrentUser()Landroid/content/pm/UserInfo;
+Landroid/app/IActivityManager;->getFilteredTasks(III)Ljava/util/List;
 Landroid/app/IActivityManager;->getIntentForIntentSender(Landroid/content/IIntentSender;)Landroid/content/Intent;
 Landroid/app/IActivityManager;->getIntentSender(ILjava/lang/String;Landroid/os/IBinder;Ljava/lang/String;I[Landroid/content/Intent;[Ljava/lang/String;ILandroid/os/Bundle;I)Landroid/content/IIntentSender;
 Landroid/app/IActivityManager;->getLaunchedFromPackage(Landroid/os/IBinder;)Ljava/lang/String;
 Landroid/app/IActivityManager;->getLaunchedFromUid(Landroid/os/IBinder;)I
+Landroid/app/IActivityManager;->getLockTaskModeState()I
 Landroid/app/IActivityManager;->getMemoryInfo(Landroid/app/ActivityManager$MemoryInfo;)V
 Landroid/app/IActivityManager;->getPackageProcessState(Ljava/lang/String;Ljava/lang/String;)I
 Landroid/app/IActivityManager;->getProcessLimit()I
+Landroid/app/IActivityManager;->getProcessMemoryInfo([I)[Landroid/os/Debug$MemoryInfo;
 Landroid/app/IActivityManager;->getProcessPss([I)[J
 Landroid/app/IActivityManager;->getProviderMimeType(Landroid/net/Uri;I)Ljava/lang/String;
+Landroid/app/IActivityManager;->getRecentTasks(III)Landroid/content/pm/ParceledListSlice;
+Landroid/app/IActivityManager;->getRunningAppProcesses()Ljava/util/List;
 Landroid/app/IActivityManager;->getServices(II)Ljava/util/List;
 Landroid/app/IActivityManager;->getTaskBounds(I)Landroid/graphics/Rect;
 Landroid/app/IActivityManager;->getTaskForActivity(Landroid/os/IBinder;Z)I
+Landroid/app/IActivityManager;->getTaskSnapshot(IZ)Landroid/app/ActivityManager$TaskSnapshot;
 Landroid/app/IActivityManager;->handleApplicationStrictModeViolation(Landroid/os/IBinder;ILandroid/os/StrictMode$ViolationInfo;)V
 Landroid/app/IActivityManager;->hang(Landroid/os/IBinder;Z)V
 Landroid/app/IActivityManager;->isInLockTaskMode()Z
@@ -98,9 +109,11 @@
 Landroid/app/IActivityManager;->publishContentProviders(Landroid/app/IApplicationThread;Ljava/util/List;)V
 Landroid/app/IActivityManager;->registerProcessObserver(Landroid/app/IProcessObserver;)V
 Landroid/app/IActivityManager;->registerReceiver(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/IIntentReceiver;Landroid/content/IntentFilter;Ljava/lang/String;II)Landroid/content/Intent;
+Landroid/app/IActivityManager;->registerTaskStackListener(Landroid/app/ITaskStackListener;)V
 Landroid/app/IActivityManager;->registerUserSwitchObserver(Landroid/app/IUserSwitchObserver;Ljava/lang/String;)V
 Landroid/app/IActivityManager;->removeContentProviderExternal(Ljava/lang/String;Landroid/os/IBinder;)V
 Landroid/app/IActivityManager;->removeStack(I)V
+Landroid/app/IActivityManager;->removeTask(I)Z
 Landroid/app/IActivityManager;->requestBugReport(I)V
 Landroid/app/IActivityManager;->resizeDockedStack(Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;)V
 Landroid/app/IActivityManager;->resizeStack(ILandroid/graphics/Rect;ZZZI)V
@@ -120,8 +133,12 @@
 Landroid/app/IActivityManager;->setRequestedOrientation(Landroid/os/IBinder;I)V
 Landroid/app/IActivityManager;->setTaskResizeable(II)V
 Landroid/app/IActivityManager;->shutdown(I)Z
+Landroid/app/IActivityManager;->startActivity(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;)I
+Landroid/app/IActivityManager;->startActivityAsUser(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;I)I
+Landroid/app/IActivityManager;->startActivityFromRecents(ILandroid/os/Bundle;)I
 Landroid/app/IActivityManager;->startBinderTracking()Z
 Landroid/app/IActivityManager;->startInstrumentation(Landroid/content/ComponentName;Ljava/lang/String;ILandroid/os/Bundle;Landroid/app/IInstrumentationWatcher;Landroid/app/IUiAutomationConnection;ILjava/lang/String;)Z
+Landroid/app/IActivityManager;->startRecentsActivity(Landroid/content/Intent;Landroid/app/IAssistDataReceiver;Landroid/view/IRecentsAnimationRunner;)V
 Landroid/app/IActivityManager;->startSystemLockTaskMode(I)V
 Landroid/app/IActivityManager;->startUserInBackground(I)Z
 Landroid/app/IActivityManager;->stopAppSwitches()V
@@ -144,12 +161,16 @@
 Landroid/app/IAlarmManager$Stub;->TRANSACTION_set:I
 Landroid/app/IAlarmManager;->getNextAlarmClock(I)Landroid/app/AlarmManager$AlarmClockInfo;
 Landroid/app/IAlarmManager;->set(Ljava/lang/String;IJJJILandroid/app/PendingIntent;Landroid/app/IAlarmListener;Ljava/lang/String;Landroid/os/WorkSource;Landroid/app/AlarmManager$AlarmClockInfo;)V
+Landroid/app/IAlarmManager;->setTime(J)Z
 Landroid/app/IApplicationThread;->scheduleBindService(Landroid/os/IBinder;Landroid/content/Intent;ZI)V
 Landroid/app/IApplicationThread;->scheduleCreateService(Landroid/os/IBinder;Landroid/content/pm/ServiceInfo;Landroid/content/res/CompatibilityInfo;I)V
 Landroid/app/IApplicationThread;->scheduleStopService(Landroid/os/IBinder;)V
 Landroid/app/IApplicationThread;->scheduleTrimMemory(I)V
 Landroid/app/IApplicationThread;->scheduleUnbindService(Landroid/os/IBinder;Landroid/content/Intent;)V
 Landroid/app/IAppTask;->getTaskInfo()Landroid/app/ActivityManager$RecentTaskInfo;
+Landroid/app/IAssistDataReceiver$Stub;-><init>()V
+Landroid/app/IAssistDataReceiver;->onHandleAssistData(Landroid/os/Bundle;)V
+Landroid/app/IAssistDataReceiver;->onHandleAssistScreenshot(Landroid/graphics/Bitmap;)V
 Landroid/app/IInputForwarder;->forwardEvent(Landroid/view/InputEvent;)Z
 Landroid/app/IInstrumentationWatcher$Stub;-><init>()V
 Landroid/app/IInstrumentationWatcher$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IInstrumentationWatcher;
@@ -236,6 +257,7 @@
 Landroid/bluetooth/IBluetooth;->getAddress()Ljava/lang/String;
 Landroid/bluetooth/IBluetooth;->getRemoteAlias(Landroid/bluetooth/BluetoothDevice;)Ljava/lang/String;
 Landroid/bluetooth/IBluetooth;->isEnabled()Z
+Landroid/bluetooth/IBluetooth;->sendConnectionStateChange(Landroid/bluetooth/BluetoothDevice;III)V
 Landroid/bluetooth/IBluetoothA2dp$Stub;-><init>()V
 Landroid/bluetooth/IBluetoothA2dp$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothA2dp;
 Landroid/bluetooth/IBluetoothA2dp;->connect(Landroid/bluetooth/BluetoothDevice;)Z
@@ -266,6 +288,10 @@
 Landroid/bluetooth/IBluetoothManagerCallback$Stub;-><init>()V
 Landroid/bluetooth/IBluetoothPbap$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothPbap;
 Landroid/bluetooth/IBluetoothStateChangeCallback$Stub;-><init>()V
+Landroid/companion/ICompanionDeviceDiscoveryService$Stub;-><init>()V
+Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelected(Ljava/lang/String;ILjava/lang/String;)V
+Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelectionCancel()V
+Landroid/companion/IFindDeviceCallback;->onSuccess(Landroid/app/PendingIntent;)V
 Landroid/content/ContentProviderProxy;->mRemote:Landroid/os/IBinder;
 Landroid/content/IClipboard$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/IClipboard$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IClipboard;
@@ -312,11 +338,13 @@
 Landroid/content/pm/IPackageDataObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/pm/IPackageDataObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/content/pm/IPackageDataObserver$Stub$Proxy;->onRemoveCompleted(Ljava/lang/String;Z)V
+Landroid/content/pm/IPackageDataObserver$Stub;-><init>()V
 Landroid/content/pm/IPackageDataObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDataObserver;
 Landroid/content/pm/IPackageDataObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
 Landroid/content/pm/IPackageDataObserver$Stub;->TRANSACTION_onRemoveCompleted:I
 Landroid/content/pm/IPackageDataObserver;->onRemoveCompleted(Ljava/lang/String;Z)V
 Landroid/content/pm/IPackageDeleteObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/pm/IPackageDeleteObserver$Stub;-><init>()V
 Landroid/content/pm/IPackageDeleteObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDeleteObserver;
 Landroid/content/pm/IPackageDeleteObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
 Landroid/content/pm/IPackageDeleteObserver$Stub;->TRANSACTION_packageDeleted:I
@@ -325,6 +353,7 @@
 Landroid/content/pm/IPackageDeleteObserver2$Stub;-><init>()V
 Landroid/content/pm/IPackageDeleteObserver2$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDeleteObserver2;
 Landroid/content/pm/IPackageDeleteObserver2;->onPackageDeleted(Ljava/lang/String;ILjava/lang/String;)V
+Landroid/content/pm/IPackageDeleteObserver;->packageDeleted(Ljava/lang/String;I)V
 Landroid/content/pm/IPackageInstaller;->uninstall(Landroid/content/pm/VersionedPackage;Ljava/lang/String;ILandroid/content/IntentSender;I)V
 Landroid/content/pm/IPackageInstallerCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/pm/IPackageInstallerCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
@@ -364,11 +393,14 @@
 Landroid/content/pm/IPackageManager;->clearPackagePreferredActivities(Ljava/lang/String;)V
 Landroid/content/pm/IPackageManager;->currentToCanonicalPackageNames([Ljava/lang/String;)[Ljava/lang/String;
 Landroid/content/pm/IPackageManager;->deleteApplicationCacheFiles(Ljava/lang/String;Landroid/content/pm/IPackageDataObserver;)V
+Landroid/content/pm/IPackageManager;->getActivityInfo(Landroid/content/ComponentName;II)Landroid/content/pm/ActivityInfo;
 Landroid/content/pm/IPackageManager;->getApplicationEnabledSetting(Ljava/lang/String;I)I
+Landroid/content/pm/IPackageManager;->getApplicationInfo(Ljava/lang/String;II)Landroid/content/pm/ApplicationInfo;
 Landroid/content/pm/IPackageManager;->getAppOpPermissionPackages(Ljava/lang/String;)[Ljava/lang/String;
 Landroid/content/pm/IPackageManager;->getBlockUninstallForUser(Ljava/lang/String;I)Z
 Landroid/content/pm/IPackageManager;->getComponentEnabledSetting(Landroid/content/ComponentName;I)I
 Landroid/content/pm/IPackageManager;->getFlagsForUid(I)I
+Landroid/content/pm/IPackageManager;->getHomeActivities(Ljava/util/List;)Landroid/content/ComponentName;
 Landroid/content/pm/IPackageManager;->getInstalledApplications(II)Landroid/content/pm/ParceledListSlice;
 Landroid/content/pm/IPackageManager;->getInstalledPackages(II)Landroid/content/pm/ParceledListSlice;
 Landroid/content/pm/IPackageManager;->getInstallerPackageName(Ljava/lang/String;)Ljava/lang/String;
@@ -376,6 +408,7 @@
 Landroid/content/pm/IPackageManager;->getInstrumentationInfo(Landroid/content/ComponentName;I)Landroid/content/pm/InstrumentationInfo;
 Landroid/content/pm/IPackageManager;->getLastChosenActivity(Landroid/content/Intent;Ljava/lang/String;I)Landroid/content/pm/ResolveInfo;
 Landroid/content/pm/IPackageManager;->getNameForUid(I)Ljava/lang/String;
+Landroid/content/pm/IPackageManager;->getPackageInfo(Ljava/lang/String;II)Landroid/content/pm/PackageInfo;
 Landroid/content/pm/IPackageManager;->getPackageInstaller()Landroid/content/pm/IPackageInstaller;
 Landroid/content/pm/IPackageManager;->getPackagesForUid(I)[Ljava/lang/String;
 Landroid/content/pm/IPackageManager;->getPackageUid(Ljava/lang/String;II)I
@@ -415,6 +448,7 @@
 Landroid/content/pm/IPackageStatsObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageStatsObserver;
 Landroid/content/pm/IPackageStatsObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
 Landroid/content/pm/IPackageStatsObserver$Stub;->TRANSACTION_onGetStatsCompleted:I
+Landroid/content/pm/IPackageStatsObserver;->onGetStatsCompleted(Landroid/content/pm/PackageStats;Z)V
 Landroid/content/pm/IShortcutService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/pm/IShortcutService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IShortcutService;
 Landroid/content/res/ConfigurationBoundResourceCache;-><init>()V
@@ -438,6 +472,7 @@
 Landroid/hardware/input/IInputManager$Stub;->TRANSACTION_injectInputEvent:I
 Landroid/hardware/input/IInputManager;->injectInputEvent(Landroid/view/InputEvent;I)Z
 Landroid/hardware/location/IActivityRecognitionHardwareClient$Stub;-><init>()V
+Landroid/hardware/location/IActivityRecognitionHardwareClient;->onAvailabilityChanged(ZLandroid/hardware/location/IActivityRecognitionHardware;)V
 Landroid/hardware/location/IContextHubService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/location/IContextHubService;
 Landroid/hardware/usb/IUsbManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/hardware/usb/IUsbManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/usb/IUsbManager;
@@ -447,7 +482,10 @@
 Landroid/location/ICountryListener$Stub;-><init>()V
 Landroid/location/IGeocodeProvider$Stub;-><init>()V
 Landroid/location/IGeocodeProvider$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/IGeocodeProvider;
+Landroid/location/IGeocodeProvider;->getFromLocation(DDILandroid/location/GeocoderParams;Ljava/util/List;)Ljava/lang/String;
+Landroid/location/IGeocodeProvider;->getFromLocationName(Ljava/lang/String;DDDDILandroid/location/GeocoderParams;Ljava/util/List;)Ljava/lang/String;
 Landroid/location/IGeofenceProvider$Stub;-><init>()V
+Landroid/location/IGeofenceProvider;->setGeofenceHardware(Landroid/hardware/location/IGeofenceHardware;)V
 Landroid/location/ILocationListener$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/location/ILocationListener$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/location/ILocationListener$Stub;-><init>()V
@@ -460,6 +498,10 @@
 Landroid/location/ILocationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ILocationManager;
 Landroid/location/ILocationManager$Stub;->TRANSACTION_getAllProviders:I
 Landroid/location/ILocationManager;->getAllProviders()Ljava/util/List;
+Landroid/location/ILocationManager;->getNetworkProviderPackage()Ljava/lang/String;
+Landroid/location/ILocationManager;->reportLocation(Landroid/location/Location;Z)V
+Landroid/location/INetInitiatedListener$Stub;-><init>()V
+Landroid/location/INetInitiatedListener;->sendNiResponse(II)Z
 Landroid/location/LocationManager$ListenerTransport;-><init>(Landroid/location/LocationManager;Landroid/location/LocationListener;Landroid/os/Looper;)V
 Landroid/Manifest$permission;->CAPTURE_SECURE_VIDEO_OUTPUT:Ljava/lang/String;
 Landroid/Manifest$permission;->CAPTURE_VIDEO_OUTPUT:Ljava/lang/String;
@@ -486,6 +528,17 @@
 Landroid/media/MediaScanner$MyMediaScannerClient;-><init>(Landroid/media/MediaScanner;)V
 Landroid/media/projection/IMediaProjectionManager;->hasProjectionPermission(ILjava/lang/String;)Z
 Landroid/media/session/ISessionManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/session/ISessionManager;
+Landroid/media/tv/ITvRemoteProvider$Stub;-><init>()V
+Landroid/media/tv/ITvRemoteServiceInput;->clearInputBridge(Landroid/os/IBinder;)V
+Landroid/media/tv/ITvRemoteServiceInput;->closeInputBridge(Landroid/os/IBinder;)V
+Landroid/media/tv/ITvRemoteServiceInput;->openInputBridge(Landroid/os/IBinder;Ljava/lang/String;III)V
+Landroid/media/tv/ITvRemoteServiceInput;->sendKeyDown(Landroid/os/IBinder;I)V
+Landroid/media/tv/ITvRemoteServiceInput;->sendKeyUp(Landroid/os/IBinder;I)V
+Landroid/media/tv/ITvRemoteServiceInput;->sendPointerDown(Landroid/os/IBinder;III)V
+Landroid/media/tv/ITvRemoteServiceInput;->sendPointerSync(Landroid/os/IBinder;)V
+Landroid/media/tv/ITvRemoteServiceInput;->sendPointerUp(Landroid/os/IBinder;I)V
+Landroid/media/tv/ITvRemoteServiceInput;->sendTimestamp(Landroid/os/IBinder;J)V
+Landroid/net/ConnectivityManager$PacketKeepaliveCallback;-><init>()V
 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;
@@ -499,6 +552,7 @@
 Landroid/net/IConnectivityManager;->getActiveLinkProperties()Landroid/net/LinkProperties;
 Landroid/net/IConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
 Landroid/net/IConnectivityManager;->getAllNetworkInfo()[Landroid/net/NetworkInfo;
+Landroid/net/IConnectivityManager;->getAllNetworkState()[Landroid/net/NetworkState;
 Landroid/net/IConnectivityManager;->getLastTetherError(Ljava/lang/String;)I
 Landroid/net/IConnectivityManager;->getNetworkInfo(I)Landroid/net/NetworkInfo;
 Landroid/net/IConnectivityManager;->getTetherableIfaces()[Ljava/lang/String;
@@ -508,9 +562,12 @@
 Landroid/net/IConnectivityManager;->getTetheringErroredIfaces()[Ljava/lang/String;
 Landroid/net/IConnectivityManager;->reportInetCondition(II)V
 Landroid/net/IConnectivityManager;->startLegacyVpn(Lcom/android/internal/net/VpnProfile;)V
+Landroid/net/INetd$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetd;
+Landroid/net/INetd;->interfaceAddAddress(Ljava/lang/String;Ljava/lang/String;I)V
 Landroid/net/INetworkManagementEventObserver$Stub;-><init>()V
 Landroid/net/INetworkPolicyListener$Stub;-><init>()V
 Landroid/net/INetworkPolicyManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkPolicyManager;
+Landroid/net/INetworkPolicyManager;->getNetworkQuotaInfo(Landroid/net/NetworkState;)Landroid/net/NetworkQuotaInfo;
 Landroid/net/INetworkPolicyManager;->getRestrictBackground()Z
 Landroid/net/INetworkPolicyManager;->getUidPolicy(I)I
 Landroid/net/INetworkPolicyManager;->setNetworkPolicies([Landroid/net/NetworkPolicy;)V
@@ -520,14 +577,19 @@
 Landroid/net/INetworkScoreService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkScoreService;
 Landroid/net/INetworkStatsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/net/INetworkStatsService$Stub$Proxy;->getMobileIfaces()[Ljava/lang/String;
+Landroid/net/INetworkStatsService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkStatsService;
 Landroid/net/INetworkStatsService;->forceUpdate()V
 Landroid/net/INetworkStatsService;->getDataLayerSnapshotForUid(I)Landroid/net/NetworkStats;
 Landroid/net/INetworkStatsService;->getMobileIfaces()[Ljava/lang/String;
 Landroid/net/INetworkStatsService;->openSession()Landroid/net/INetworkStatsSession;
 Landroid/net/INetworkStatsService;->openSessionForUsageStats(ILjava/lang/String;)Landroid/net/INetworkStatsSession;
 Landroid/net/INetworkStatsSession;->close()V
+Landroid/net/INetworkStatsSession;->getHistoryForNetwork(Landroid/net/NetworkTemplate;I)Landroid/net/NetworkStatsHistory;
+Landroid/net/INetworkStatsSession;->getHistoryForUid(Landroid/net/NetworkTemplate;IIII)Landroid/net/NetworkStatsHistory;
 Landroid/net/INetworkStatsSession;->getSummaryForAllUid(Landroid/net/NetworkTemplate;JJZ)Landroid/net/NetworkStats;
 Landroid/net/INetworkStatsSession;->getSummaryForNetwork(Landroid/net/NetworkTemplate;JJ)Landroid/net/NetworkStats;
+Landroid/net/InterfaceConfiguration;-><init>()V
+Landroid/net/LinkProperties$ProvisioningChange;->values()[Landroid/net/LinkProperties$ProvisioningChange;
 Landroid/net/MobileLinkQualityInfo;-><init>()V
 Landroid/net/nsd/INsdManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/nsd/INsdManager;
 Landroid/net/nsd/INsdManager;->getMessenger()Landroid/os/Messenger;
@@ -552,7 +614,12 @@
 Landroid/nfc/INfcAdapterExtras;->open(Ljava/lang/String;Landroid/os/IBinder;)Landroid/os/Bundle;
 Landroid/nfc/INfcAdapterExtras;->setCardEmulationRoute(Ljava/lang/String;I)V
 Landroid/nfc/INfcAdapterExtras;->transceive(Ljava/lang/String;[B)Landroid/os/Bundle;
+Landroid/os/AsyncResult;-><init>(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Throwable;)V
+Landroid/os/AsyncResult;->exception:Ljava/lang/Throwable;
 Landroid/os/AsyncResult;->forMessage(Landroid/os/Message;)Landroid/os/AsyncResult;
+Landroid/os/AsyncResult;->forMessage(Landroid/os/Message;Ljava/lang/Object;Ljava/lang/Throwable;)Landroid/os/AsyncResult;
+Landroid/os/AsyncResult;->result:Ljava/lang/Object;
+Landroid/os/AsyncResult;->userObj:Ljava/lang/Object;
 Landroid/os/AsyncTask;->mFuture:Ljava/util/concurrent/FutureTask;
 Landroid/os/AsyncTask;->mStatus:Landroid/os/AsyncTask$Status;
 Landroid/os/AsyncTask;->mTaskInvoked:Ljava/util/concurrent/atomic/AtomicBoolean;
@@ -569,18 +636,24 @@
 Landroid/os/BatteryManager;->EXTRA_MAX_CHARGING_VOLTAGE:Ljava/lang/String;
 Landroid/os/BatteryStats$Counter;-><init>()V
 Landroid/os/BatteryStats$Counter;->getCountLocked(I)I
+Landroid/os/BatteryStats$HistoryItem;-><init>()V
 Landroid/os/BatteryStats$HistoryItem;->batteryHealth:B
+Landroid/os/BatteryStats$HistoryItem;->batteryLevel:B
 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:B
 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$HistoryItem;->states:I
+Landroid/os/BatteryStats$HistoryItem;->time:J
 Landroid/os/BatteryStats$Timer;-><init>()V
+Landroid/os/BatteryStats$Timer;->getCountLocked(I)I
 Landroid/os/BatteryStats$Timer;->getTotalTimeLocked(JI)J
 Landroid/os/BatteryStats$Uid$Pkg$Serv;->getLaunches(I)I
 Landroid/os/BatteryStats$Uid$Pkg$Serv;->getStarts(I)I
@@ -604,6 +677,8 @@
 Landroid/os/BatteryStats$Uid$Sensor;->getSensorTime()Landroid/os/BatteryStats$Timer;
 Landroid/os/BatteryStats$Uid$Sensor;->GPS:I
 Landroid/os/BatteryStats$Uid$Wakelock;-><init>()V
+Landroid/os/BatteryStats$Uid$Wakelock;->getWakeTime(I)Landroid/os/BatteryStats$Timer;
+Landroid/os/BatteryStats$Uid;-><init>()V
 Landroid/os/BatteryStats$Uid;->getAudioTurnedOnTimer()Landroid/os/BatteryStats$Timer;
 Landroid/os/BatteryStats$Uid;->getFullWifiLockTime(JI)J
 Landroid/os/BatteryStats$Uid;->getMobileRadioActiveTime(I)J
@@ -616,6 +691,7 @@
 Landroid/os/BatteryStats$Uid;->getWakelockStats()Landroid/util/ArrayMap;
 Landroid/os/BatteryStats$Uid;->getWifiBatchedScanTime(IJI)J
 Landroid/os/BatteryStats$Uid;->getWifiMulticastTime(JI)J
+Landroid/os/BatteryStats$Uid;->getWifiRunningTime(JI)J
 Landroid/os/BatteryStats$Uid;->getWifiScanTime(JI)J
 Landroid/os/BatteryStats;-><init>()V
 Landroid/os/BatteryStats;->computeBatteryRealtime(JI)J
@@ -627,6 +703,7 @@
 Landroid/os/BatteryStats;->getGlobalWifiRunningTime(JI)J
 Landroid/os/BatteryStats;->getMobileRadioActiveTime(JI)J
 Landroid/os/BatteryStats;->getNetworkActivityBytes(II)J
+Landroid/os/BatteryStats;->getNextHistoryLocked(Landroid/os/BatteryStats$HistoryItem;)Z
 Landroid/os/BatteryStats;->getPhoneOnTime(JI)J
 Landroid/os/BatteryStats;->getPhoneSignalStrengthTime(IJI)J
 Landroid/os/BatteryStats;->getScreenBrightnessTime(IJI)J
@@ -640,6 +717,10 @@
 Landroid/os/BatteryStats;->WAKE_TYPE_PARTIAL:I
 Landroid/os/Binder;->execTransact(IJJI)Z
 Landroid/os/Binder;->mObject:J
+Landroid/os/Broadcaster;-><init>()V
+Landroid/os/Broadcaster;->broadcast(Landroid/os/Message;)V
+Landroid/os/Broadcaster;->cancelRequest(ILandroid/os/Handler;I)V
+Landroid/os/Broadcaster;->request(ILandroid/os/Handler;I)V
 Landroid/os/Build$VERSION;->ACTIVE_CODENAMES:[Ljava/lang/String;
 Landroid/os/Build;->getLong(Ljava/lang/String;)J
 Landroid/os/Build;->getString(Ljava/lang/String;)Ljava/lang/String;
@@ -713,6 +794,7 @@
 Landroid/os/Environment;->buildExternalStorageAppObbDirs(Ljava/lang/String;)[Ljava/io/File;
 Landroid/os/Environment;->buildPaths([Ljava/io/File;[Ljava/lang/String;)[Ljava/io/File;
 Landroid/os/Environment;->getDataSystemDirectory()Ljava/io/File;
+Landroid/os/Environment;->getLegacyExternalStorageDirectory()Ljava/io/File;
 Landroid/os/Environment;->getLegacyExternalStorageObbDirectory()Ljava/io/File;
 Landroid/os/Environment;->initForCurrentUser()V
 Landroid/os/Environment;->maybeTranslateEmulatedPathToInternal(Ljava/io/File;)Ljava/io/File;
@@ -733,12 +815,15 @@
 Landroid/os/FileUtils;->stringToFile(Ljava/io/File;Ljava/lang/String;)V
 Landroid/os/FileUtils;->stringToFile(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/os/FileUtils;->sync(Ljava/io/FileOutputStream;)Z
+Landroid/os/Handler;-><init>(Landroid/os/Looper;Landroid/os/Handler$Callback;Z)V
 Landroid/os/Handler;-><init>(Z)V
 Landroid/os/Handler;->getIMessenger()Landroid/os/IMessenger;
+Landroid/os/Handler;->getMain()Landroid/os/Handler;
 Landroid/os/Handler;->getPostMessage(Ljava/lang/Runnable;Ljava/lang/Object;)Landroid/os/Message;
 Landroid/os/Handler;->mCallback:Landroid/os/Handler$Callback;
 Landroid/os/Handler;->mLooper:Landroid/os/Looper;
 Landroid/os/Handler;->mMessenger:Landroid/os/IMessenger;
+Landroid/os/HwBinder;->reportSyspropChanged()V
 Landroid/os/HwParcel;-><init>(Z)V
 Landroid/os/HwRemoteBinder;-><init>()V
 Landroid/os/IBatteryPropertiesRegistrar$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -749,16 +834,26 @@
 Landroid/os/IDeviceIdleController;->getAppIdTempWhitelist()[I
 Landroid/os/IDeviceIdleController;->getFullPowerWhitelistExceptIdle()[Ljava/lang/String;
 Landroid/os/INetworkManagementService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/os/INetworkManagementService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/INetworkManagementService;
+Landroid/os/INetworkManagementService;->clearInterfaceAddresses(Ljava/lang/String;)V
+Landroid/os/INetworkManagementService;->disableIpv6(Ljava/lang/String;)V
 Landroid/os/INetworkManagementService;->disableNat(Ljava/lang/String;Ljava/lang/String;)V
+Landroid/os/INetworkManagementService;->enableIpv6(Ljava/lang/String;)V
 Landroid/os/INetworkManagementService;->enableNat(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/os/INetworkManagementService;->getInterfaceConfig(Ljava/lang/String;)Landroid/net/InterfaceConfiguration;
 Landroid/os/INetworkManagementService;->getIpForwardingEnabled()Z
+Landroid/os/INetworkManagementService;->isBandwidthControlEnabled()Z
 Landroid/os/INetworkManagementService;->isTetheringStarted()Z
 Landroid/os/INetworkManagementService;->listTetheredInterfaces()[Ljava/lang/String;
+Landroid/os/INetworkManagementService;->registerObserver(Landroid/net/INetworkManagementEventObserver;)V
+Landroid/os/INetworkManagementService;->setInterfaceConfig(Ljava/lang/String;Landroid/net/InterfaceConfiguration;)V
+Landroid/os/INetworkManagementService;->setInterfaceIpv6PrivacyExtensions(Ljava/lang/String;Z)V
 Landroid/os/INetworkManagementService;->setIpForwardingEnabled(Z)V
+Landroid/os/INetworkManagementService;->setIPv6AddrGenMode(Ljava/lang/String;I)V
 Landroid/os/INetworkManagementService;->startTethering([Ljava/lang/String;)V
 Landroid/os/INetworkManagementService;->stopTethering()V
 Landroid/os/INetworkManagementService;->tetherInterface(Ljava/lang/String;)V
+Landroid/os/INetworkManagementService;->unregisterObserver(Landroid/net/INetworkManagementEventObserver;)V
 Landroid/os/INetworkManagementService;->untetherInterface(Ljava/lang/String;)V
 Landroid/os/IPermissionController$Stub$Proxy;->checkPermission(Ljava/lang/String;II)Z
 Landroid/os/IPermissionController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPermissionController;
@@ -767,12 +862,15 @@
 Landroid/os/IPowerManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPowerManager;
 Landroid/os/IPowerManager$Stub;->TRANSACTION_acquireWakeLock:I
 Landroid/os/IPowerManager$Stub;->TRANSACTION_goToSleep:I
+Landroid/os/IPowerManager;->goToSleep(JII)V
 Landroid/os/IPowerManager;->isInteractive()Z
 Landroid/os/IPowerManager;->nap(J)V
+Landroid/os/IPowerManager;->reboot(ZLjava/lang/String;Z)V
 Landroid/os/IPowerManager;->releaseWakeLock(Landroid/os/IBinder;I)V
 Landroid/os/IPowerManager;->userActivity(JII)V
 Landroid/os/IPowerManager;->wakeUp(JLjava/lang/String;Ljava/lang/String;)V
 Landroid/os/IRecoverySystem$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IRecoverySystem;
+Landroid/os/IRemoteCallback$Stub;-><init>()V
 Landroid/os/IRemoteCallback;->sendResult(Landroid/os/Bundle;)V
 Landroid/os/IServiceManager;->checkService(Ljava/lang/String;)Landroid/os/IBinder;
 Landroid/os/IServiceManager;->getService(Ljava/lang/String;)Landroid/os/IBinder;
@@ -798,6 +896,7 @@
 Landroid/os/Message;->markInUse()V
 Landroid/os/Message;->next:Landroid/os/Message;
 Landroid/os/Message;->recycleUnchecked()V
+Landroid/os/Message;->setCallback(Ljava/lang/Runnable;)Landroid/os/Message;
 Landroid/os/Message;->target:Landroid/os/Handler;
 Landroid/os/Message;->toString(J)Ljava/lang/String;
 Landroid/os/Message;->when:J
@@ -817,13 +916,16 @@
 Landroid/os/Parcel;->mNativePtr:J
 Landroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;Ljava/lang/ClassLoader;)V
 Landroid/os/Parcel;->readArraySet(Ljava/lang/ClassLoader;)Landroid/util/ArraySet;
+Landroid/os/Parcel;->readBlob()[B
 Landroid/os/Parcel;->readCharSequence()Ljava/lang/CharSequence;
 Landroid/os/Parcel;->readCreator(Landroid/os/Parcelable$Creator;Ljava/lang/ClassLoader;)Landroid/os/Parcelable;
 Landroid/os/Parcel;->readExceptionCode()I
 Landroid/os/Parcel;->readParcelableCreator(Ljava/lang/ClassLoader;)Landroid/os/Parcelable$Creator;
 Landroid/os/Parcel;->readRawFileDescriptor()Ljava/io/FileDescriptor;
+Landroid/os/Parcel;->readStringArray()[Ljava/lang/String;
 Landroid/os/Parcel;->writeArrayMap(Landroid/util/ArrayMap;)V
 Landroid/os/Parcel;->writeArraySet(Landroid/util/ArraySet;)V
+Landroid/os/Parcel;->writeBlob([B)V
 Landroid/os/Parcel;->writeCharSequence(Ljava/lang/CharSequence;)V
 Landroid/os/Parcel;->writeParcelableCreator(Landroid/os/Parcelable;)V
 Landroid/os/ParcelableParcel;-><init>(Ljava/lang/ClassLoader;)V
@@ -890,15 +992,27 @@
 Landroid/os/Process;->VPN_UID:I
 Landroid/os/Process;->WIFI_UID:I
 Landroid/os/RecoverySystem;->verifyPackageCompatibility(Ljava/io/InputStream;)Z
+Landroid/os/Registrant;-><init>(Landroid/os/Handler;ILjava/lang/Object;)V
+Landroid/os/Registrant;->clear()V
 Landroid/os/Registrant;->getHandler()Landroid/os/Handler;
 Landroid/os/Registrant;->messageForRegistrant()Landroid/os/Message;
+Landroid/os/Registrant;->notifyRegistrant()V
+Landroid/os/Registrant;->notifyRegistrant(Landroid/os/AsyncResult;)V
 Landroid/os/Registrant;->notifyResult(Ljava/lang/Object;)V
+Landroid/os/RegistrantList;-><init>()V
 Landroid/os/RegistrantList;->add(Landroid/os/Handler;ILjava/lang/Object;)V
+Landroid/os/RegistrantList;->add(Landroid/os/Registrant;)V
+Landroid/os/RegistrantList;->addUnique(Landroid/os/Handler;ILjava/lang/Object;)V
 Landroid/os/RegistrantList;->get(I)Ljava/lang/Object;
+Landroid/os/RegistrantList;->notifyRegistrants()V
+Landroid/os/RegistrantList;->notifyRegistrants(Landroid/os/AsyncResult;)V
 Landroid/os/RegistrantList;->notifyResult(Ljava/lang/Object;)V
+Landroid/os/RegistrantList;->remove(Landroid/os/Handler;)V
+Landroid/os/RegistrantList;->removeCleared()V
 Landroid/os/RegistrantList;->size()I
 Landroid/os/RemoteCallback;->mHandler:Landroid/os/Handler;
 Landroid/os/RemoteCallbackList;->mCallbacks:Landroid/util/ArrayMap;
+Landroid/os/RemoteException;->rethrowFromSystemServer()Ljava/lang/RuntimeException;
 Landroid/os/SELinux;->checkSELinuxAccess(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
 Landroid/os/SELinux;->getContext()Ljava/lang/String;
 Landroid/os/SELinux;->getFileContext(Ljava/lang/String;)Ljava/lang/String;
@@ -920,6 +1034,7 @@
 Landroid/os/ServiceManagerProxy;->getService(Ljava/lang/String;)Landroid/os/IBinder;
 Landroid/os/ServiceManagerProxy;->mRemote:Landroid/os/IBinder;
 Landroid/os/ServiceSpecificException;-><init>(ILjava/lang/String;)V
+Landroid/os/ServiceSpecificException;->errorCode:I
 Landroid/os/SharedMemory;->getFd()I
 Landroid/os/ShellCommand;->peekNextArg()Ljava/lang/String;
 Landroid/os/StatFs;->mStat:Landroid/system/StructStatVfs;
@@ -927,6 +1042,7 @@
 Landroid/os/storage/IObbActionListener$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IObbActionListener;
 Landroid/os/storage/IStorageManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/os/storage/IStorageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IStorageManager;
+Landroid/os/storage/StorageEventListener;-><init>()V
 Landroid/os/StrictMode$Span;->finish()V
 Landroid/os/StrictMode$ThreadPolicy;->mask:I
 Landroid/os/StrictMode$VmPolicy$Builder;->mMask:I
@@ -954,8 +1070,12 @@
 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;->reportSyspropChanged()V
 Landroid/os/SystemProperties;->sChangeCallbacks:Ljava/util/ArrayList;
 Landroid/os/SystemProperties;->set(Ljava/lang/String;Ljava/lang/String;)V
+Landroid/os/SystemService;->start(Ljava/lang/String;)V
+Landroid/os/SystemService;->stop(Ljava/lang/String;)V
+Landroid/os/SystemVibrator;-><init>()V
 Landroid/os/SystemVibrator;-><init>(Landroid/content/Context;)V
 Landroid/os/Trace;->asyncTraceBegin(JLjava/lang/String;I)V
 Landroid/os/Trace;->asyncTraceEnd(JLjava/lang/String;I)V
@@ -994,6 +1114,7 @@
 Landroid/os/UserHandle;->getUid(II)I
 Landroid/os/UserHandle;->getUserId(I)I
 Landroid/os/UserHandle;->isIsolated(I)Z
+Landroid/os/UserHandle;->isSameApp(II)Z
 Landroid/os/UserHandle;->mHandle:I
 Landroid/os/UserHandle;->MU_ENABLED:Z
 Landroid/os/UserHandle;->OWNER:Landroid/os/UserHandle;
@@ -1023,6 +1144,7 @@
 Landroid/os/UserManager;->getUserStartRealtime()J
 Landroid/os/UserManager;->getUserUnlockRealtime()J
 Landroid/os/UserManager;->hasBaseUserRestriction(Ljava/lang/String;Landroid/os/UserHandle;)Z
+Landroid/os/UserManager;->hasUserRestriction(Ljava/lang/String;Landroid/os/UserHandle;)Z
 Landroid/os/UserManager;->isDeviceInDemoMode(Landroid/content/Context;)Z
 Landroid/os/UserManager;->isGuestUser(I)Z
 Landroid/os/UserManager;->isLinkedUser()Z
@@ -1072,6 +1194,7 @@
 Landroid/R$styleable;->CalendarView_weekDayTextAppearance:I
 Landroid/R$styleable;->CalendarView_weekNumberColor:I
 Landroid/R$styleable;->CalendarView_weekSeparatorLineColor:I
+Landroid/R$styleable;->CheckBoxPreference:[I
 Landroid/R$styleable;->CheckedTextView:[I
 Landroid/R$styleable;->CheckedTextView_checkMark:I
 Landroid/R$styleable;->CompoundButton:[I
@@ -1382,7 +1505,18 @@
 Landroid/telecom/Log;->i(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
 Landroid/telecom/Log;->w(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
 Landroid/telephony/CarrierMessagingServiceManager;-><init>()V
+Landroid/telephony/ims/compat/feature/MMTelFeature;-><init>()V
+Landroid/telephony/ims/compat/ImsService;-><init>()V
+Landroid/telephony/ims/compat/stub/ImsCallSessionImplBase;-><init>()V
+Landroid/telephony/ims/compat/stub/ImsUtListenerImplBase;-><init>()V
 Landroid/telephony/JapanesePhoneNumberFormatter;->format(Landroid/text/Editable;)V
+Landroid/telephony/mbms/IMbmsStreamingSessionCallback$Stub;-><init>()V
+Landroid/telephony/mbms/IStreamingServiceCallback$Stub;-><init>()V
+Landroid/telephony/mbms/vendor/IMbmsStreamingService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/telephony/mbms/vendor/IMbmsStreamingService;
+Landroid/telephony/mbms/vendor/IMbmsStreamingService;->getPlaybackUri(ILjava/lang/String;)Landroid/net/Uri;
+Landroid/telephony/mbms/vendor/IMbmsStreamingService;->initialize(Landroid/telephony/mbms/IMbmsStreamingSessionCallback;I)I
+Landroid/telephony/mbms/vendor/IMbmsStreamingService;->requestUpdateStreamingServices(ILjava/util/List;)I
+Landroid/telephony/mbms/vendor/IMbmsStreamingService;->startStreaming(ILjava/lang/String;Landroid/telephony/mbms/IStreamingServiceCallback;)I
 Landroid/telephony/SmsCbCmasInfo;->getCategory()I
 Landroid/telephony/SmsCbCmasInfo;->getCertainty()I
 Landroid/telephony/SmsCbCmasInfo;->getMessageClass()I
@@ -1424,10 +1558,21 @@
 Landroid/view/AccessibilityIterators$AbstractTextSegmentIterator;-><init>()V
 Landroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/view/autofill/IAutoFillManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/autofill/IAutoFillManager;
+Landroid/view/IAppTransitionAnimationSpecsFuture$Stub;-><init>()V
 Landroid/view/IDockedStackListener$Stub;-><init>()V
 Landroid/view/IGraphicsStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/view/IGraphicsStats$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IGraphicsStats;
+Landroid/view/IRecentsAnimationController;->finish(Z)V
+Landroid/view/IRecentsAnimationController;->screenshotTask(I)Landroid/app/ActivityManager$TaskSnapshot;
 Landroid/view/IRecentsAnimationController;->setAnimationTargetsBehindSystemBars(Z)V
+Landroid/view/IRecentsAnimationController;->setInputConsumerEnabled(Z)V
+Landroid/view/IRecentsAnimationRunner$Stub;-><init>()V
+Landroid/view/IRecentsAnimationRunner;->onAnimationCanceled()V
+Landroid/view/IRecentsAnimationRunner;->onAnimationStart(Landroid/view/IRecentsAnimationController;[Landroid/view/RemoteAnimationTarget;Landroid/graphics/Rect;Landroid/graphics/Rect;)V
+Landroid/view/IRemoteAnimationFinishedCallback;->onAnimationFinished()V
+Landroid/view/IRemoteAnimationRunner$Stub;-><init>()V
+Landroid/view/IRemoteAnimationRunner;->onAnimationCancelled()V
+Landroid/view/IRemoteAnimationRunner;->onAnimationStart([Landroid/view/RemoteAnimationTarget;Landroid/view/IRemoteAnimationFinishedCallback;)V
 Landroid/view/IRotationWatcher$Stub;-><init>()V
 Landroid/view/IWindow$Stub;-><init>()V
 Landroid/view/IWindow$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IWindow;
@@ -1439,6 +1584,9 @@
 Landroid/view/IWindowManager$Stub$Proxy;->watchRotation(Landroid/view/IRotationWatcher;I)I
 Landroid/view/IWindowManager$Stub;-><init>()V
 Landroid/view/IWindowManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IWindowManager;
+Landroid/view/IWindowManager;->createInputConsumer(Landroid/os/IBinder;Ljava/lang/String;ILandroid/view/InputChannel;)V
+Landroid/view/IWindowManager;->destroyInputConsumer(Ljava/lang/String;I)Z
+Landroid/view/IWindowManager;->endProlongedAnimations()V
 Landroid/view/IWindowManager;->executeAppTransition()V
 Landroid/view/IWindowManager;->freezeRotation(I)V
 Landroid/view/IWindowManager;->getAnimationScale(I)F
@@ -1447,16 +1595,20 @@
 Landroid/view/IWindowManager;->getDockedStackSide()I
 Landroid/view/IWindowManager;->getInitialDisplayDensity(I)I
 Landroid/view/IWindowManager;->getInitialDisplaySize(ILandroid/graphics/Point;)V
+Landroid/view/IWindowManager;->getStableInsets(ILandroid/graphics/Rect;)V
 Landroid/view/IWindowManager;->hasNavigationBar(I)Z
 Landroid/view/IWindowManager;->isKeyguardLocked()Z
 Landroid/view/IWindowManager;->isKeyguardSecure()Z
 Landroid/view/IWindowManager;->isSafeModeEnabled()Z
 Landroid/view/IWindowManager;->lockNow(Landroid/os/Bundle;)V
+Landroid/view/IWindowManager;->overridePendingAppTransitionMultiThumbFuture(Landroid/view/IAppTransitionAnimationSpecsFuture;Landroid/os/IRemoteCallback;ZI)V
+Landroid/view/IWindowManager;->overridePendingAppTransitionRemote(Landroid/view/RemoteAnimationAdapter;I)V
 Landroid/view/IWindowManager;->registerDockedStackListener(Landroid/view/IDockedStackListener;)V
 Landroid/view/IWindowManager;->removeRotationWatcher(Landroid/view/IRotationWatcher;)V
 Landroid/view/IWindowManager;->setAnimationScale(IF)V
 Landroid/view/IWindowManager;->setAnimationScales([F)V
 Landroid/view/IWindowManager;->setInTouchMode(Z)V
+Landroid/view/IWindowManager;->setNavBarVirtualKeyHapticFeedbackEnabled(Z)V
 Landroid/view/IWindowManager;->setShelfHeight(ZI)V
 Landroid/view/IWindowManager;->setStrictModeVisualIndicatorPreference(Ljava/lang/String;)V
 Landroid/view/IWindowManager;->showStrictModeViolation(Z)V
@@ -1496,6 +1648,7 @@
 Lcom/android/ims/ImsCall;->reject(I)V
 Lcom/android/ims/ImsCall;->terminate(I)V
 Lcom/android/ims/ImsConfigListener$Stub;-><init>()V
+Lcom/android/ims/ImsConfigListener;->onSetFeatureResponse(IIII)V
 Lcom/android/ims/ImsEcbm;->exitEmergencyCallbackMode()V
 Lcom/android/ims/ImsManager;->getConfigInterface()Lcom/android/ims/ImsConfig;
 Lcom/android/ims/ImsManager;->getInstance(Landroid/content/Context;I)Lcom/android/ims/ImsManager;
@@ -1505,12 +1658,48 @@
 Lcom/android/ims/ImsUtInterface;->queryCallForward(ILjava/lang/String;Landroid/os/Message;)V
 Lcom/android/ims/internal/IImsCallSession$Stub;-><init>()V
 Lcom/android/ims/internal/IImsCallSession$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/ims/internal/IImsCallSession;
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionConferenceStateUpdated(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsConferenceState;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHandover(Lcom/android/ims/internal/IImsCallSession;IILandroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHandoverFailed(Lcom/android/ims/internal/IImsCallSession;IILandroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHeld(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHoldFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHoldReceived(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionInviteParticipantsRequestDelivered(Lcom/android/ims/internal/IImsCallSession;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionInviteParticipantsRequestFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMergeComplete(Lcom/android/ims/internal/IImsCallSession;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMergeFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMergeStarted(Lcom/android/ims/internal/IImsCallSession;Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMultipartyStateChanged(Lcom/android/ims/internal/IImsCallSession;Z)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionProgressing(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsStreamMediaProfile;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionResumed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionResumeFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionResumeReceived(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionStarted(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionStartFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionSuppServiceReceived(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsSuppServiceNotification;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionTerminated(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionTtyModeReceived(Lcom/android/ims/internal/IImsCallSession;I)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionUpdated(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
 Lcom/android/ims/internal/IImsConfig$Stub;-><init>()V
 Lcom/android/ims/internal/IImsEcbm$Stub;-><init>()V
+Lcom/android/ims/internal/IImsRegistrationListener;->registrationAssociatedUriChanged([Landroid/net/Uri;)V
+Lcom/android/ims/internal/IImsRegistrationListener;->registrationChangeFailed(ILandroid/telephony/ims/ImsReasonInfo;)V
 Lcom/android/ims/internal/IImsRegistrationListener;->registrationConnected()V
+Lcom/android/ims/internal/IImsRegistrationListener;->registrationConnectedWithRadioTech(I)V
+Lcom/android/ims/internal/IImsRegistrationListener;->registrationDisconnected(Landroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsRegistrationListener;->registrationFeatureCapabilityChanged(I[I[I)V
+Lcom/android/ims/internal/IImsRegistrationListener;->registrationProgressingWithRadioTech(I)V
+Lcom/android/ims/internal/IImsRegistrationListener;->voiceMessageCountUpdate(I)V
 Lcom/android/ims/internal/IImsService$Stub;-><init>()V
 Lcom/android/ims/internal/IImsService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/ims/internal/IImsService;
 Lcom/android/ims/internal/IImsUt$Stub;-><init>()V
+Lcom/android/ims/internal/IImsUtListener;->utConfigurationCallBarringQueried(Lcom/android/ims/internal/IImsUt;I[Landroid/telephony/ims/ImsSsInfo;)V
+Lcom/android/ims/internal/IImsUtListener;->utConfigurationCallForwardQueried(Lcom/android/ims/internal/IImsUt;I[Landroid/telephony/ims/ImsCallForwardInfo;)V
+Lcom/android/ims/internal/IImsUtListener;->utConfigurationCallWaitingQueried(Lcom/android/ims/internal/IImsUt;I[Landroid/telephony/ims/ImsSsInfo;)V
+Lcom/android/ims/internal/IImsUtListener;->utConfigurationQueried(Lcom/android/ims/internal/IImsUt;ILandroid/os/Bundle;)V
+Lcom/android/ims/internal/IImsUtListener;->utConfigurationQueryFailed(Lcom/android/ims/internal/IImsUt;ILandroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsUtListener;->utConfigurationUpdated(Lcom/android/ims/internal/IImsUt;I)V
+Lcom/android/ims/internal/IImsUtListener;->utConfigurationUpdateFailed(Lcom/android/ims/internal/IImsUt;ILandroid/telephony/ims/ImsReasonInfo;)V
 Lcom/android/ims/internal/IImsVideoCallCallback;->changeCallDataUsage(J)V
 Lcom/android/ims/internal/IImsVideoCallCallback;->changeCameraCapabilities(Landroid/telecom/VideoProfile$CameraCapabilities;)V
 Lcom/android/ims/internal/IImsVideoCallCallback;->changePeerDimensions(II)V
@@ -1521,7 +1710,52 @@
 Lcom/android/ims/internal/IImsVideoCallProvider$Stub;-><init>()V
 Lcom/android/ims/internal/IImsVideoCallProvider;->setCallback(Lcom/android/ims/internal/IImsVideoCallCallback;)V
 Lcom/android/ims/internal/ImsVideoCallProviderWrapper;-><init>(Lcom/android/ims/internal/IImsVideoCallProvider;)V
+Lcom/android/ims/internal/uce/options/IOptionsListener;->cmdStatus(Lcom/android/ims/internal/uce/options/OptionsCmdStatus;)V
+Lcom/android/ims/internal/uce/options/IOptionsListener;->getVersionCb(Ljava/lang/String;)V
+Lcom/android/ims/internal/uce/options/IOptionsListener;->incomingOptions(Ljava/lang/String;Lcom/android/ims/internal/uce/options/OptionsCapInfo;I)V
+Lcom/android/ims/internal/uce/options/IOptionsListener;->serviceAvailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
+Lcom/android/ims/internal/uce/options/IOptionsListener;->serviceUnavailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
+Lcom/android/ims/internal/uce/options/IOptionsListener;->sipResponseReceived(Ljava/lang/String;Lcom/android/ims/internal/uce/options/OptionsSipResponse;Lcom/android/ims/internal/uce/options/OptionsCapInfo;)V
+Lcom/android/ims/internal/uce/options/IOptionsService$Stub;-><init>()V
+Lcom/android/ims/internal/uce/options/IOptionsService;->addListener(ILcom/android/ims/internal/uce/options/IOptionsListener;Lcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/options/IOptionsService;->getContactCap(ILjava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/options/IOptionsService;->getContactListCap(I[Ljava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/options/IOptionsService;->getMyInfo(II)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/options/IOptionsService;->getVersion(I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/options/IOptionsService;->removeListener(ILcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/options/IOptionsService;->responseIncomingOptions(IIILjava/lang/String;Lcom/android/ims/internal/uce/options/OptionsCapInfo;Z)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/options/IOptionsService;->setMyInfo(ILcom/android/ims/internal/uce/common/CapInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->capInfoReceived(Ljava/lang/String;[Lcom/android/ims/internal/uce/presence/PresTupleInfo;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->cmdStatus(Lcom/android/ims/internal/uce/presence/PresCmdStatus;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->getVersionCb(Ljava/lang/String;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->listCapInfoReceived(Lcom/android/ims/internal/uce/presence/PresRlmiInfo;[Lcom/android/ims/internal/uce/presence/PresResInfo;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->publishTriggering(Lcom/android/ims/internal/uce/presence/PresPublishTriggerType;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->serviceAvailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->serviceUnAvailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->sipResponseReceived(Lcom/android/ims/internal/uce/presence/PresSipResponse;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->unpublishMessageSent()V
+Lcom/android/ims/internal/uce/presence/IPresenceService$Stub;-><init>()V
+Lcom/android/ims/internal/uce/presence/IPresenceService;->addListener(ILcom/android/ims/internal/uce/presence/IPresenceListener;Lcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceService;->getContactCap(ILjava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceService;->getContactListCap(I[Ljava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceService;->getVersion(I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceService;->publishMyCap(ILcom/android/ims/internal/uce/presence/PresCapInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceService;->reenableService(II)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceService;->removeListener(ILcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceService;->setNewFeatureTag(ILjava/lang/String;Lcom/android/ims/internal/uce/presence/PresServiceInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
 Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V
+Lcom/android/ims/internal/uce/uceservice/IUceListener;->setStatus(I)V
+Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V
+Lcom/android/ims/internal/uce/uceservice/IUceService;->createOptionsService(Lcom/android/ims/internal/uce/options/IOptionsListener;Lcom/android/ims/internal/uce/common/UceLong;)I
+Lcom/android/ims/internal/uce/uceservice/IUceService;->createPresenceService(Lcom/android/ims/internal/uce/presence/IPresenceListener;Lcom/android/ims/internal/uce/common/UceLong;)I
+Lcom/android/ims/internal/uce/uceservice/IUceService;->destroyOptionsService(I)V
+Lcom/android/ims/internal/uce/uceservice/IUceService;->destroyPresenceService(I)V
+Lcom/android/ims/internal/uce/uceservice/IUceService;->getOptionsService()Lcom/android/ims/internal/uce/options/IOptionsService;
+Lcom/android/ims/internal/uce/uceservice/IUceService;->getPresenceService()Lcom/android/ims/internal/uce/presence/IPresenceService;
+Lcom/android/ims/internal/uce/uceservice/IUceService;->getServiceStatus()Z
+Lcom/android/ims/internal/uce/uceservice/IUceService;->isServiceStarted()Z
+Lcom/android/ims/internal/uce/uceservice/IUceService;->startService(Lcom/android/ims/internal/uce/uceservice/IUceListener;)Z
+Lcom/android/ims/internal/uce/uceservice/IUceService;->stopService()Z
 Lcom/android/internal/app/AlertActivity;-><init>()V
 Lcom/android/internal/app/AlertActivity;->mAlert:Lcom/android/internal/app/AlertController;
 Lcom/android/internal/app/AlertActivity;->mAlertParams:Lcom/android/internal/app/AlertController$AlertParams;
@@ -1552,6 +1786,7 @@
 Lcom/android/internal/app/IAppOpsService$Stub;->TRANSACTION_startOperation:I
 Lcom/android/internal/app/IAppOpsService$Stub;->TRANSACTION_startWatchingMode:I
 Lcom/android/internal/app/IAppOpsService$Stub;->TRANSACTION_stopWatchingMode:I
+Lcom/android/internal/app/IAppOpsService;->finishOperation(Landroid/os/IBinder;IILjava/lang/String;)V
 Lcom/android/internal/app/IAppOpsService;->getOpsForPackage(ILjava/lang/String;[I)Ljava/util/List;
 Lcom/android/internal/app/IAppOpsService;->getPackagesForOps([I)Ljava/util/List;
 Lcom/android/internal/app/IAppOpsService;->resetAllModes(ILjava/lang/String;)V
@@ -1599,6 +1834,7 @@
 Lcom/android/internal/appwidget/IAppWidgetService;->getAppWidgetIds(Landroid/content/ComponentName;)[I
 Lcom/android/internal/appwidget/IAppWidgetService;->getAppWidgetViews(Ljava/lang/String;I)Landroid/widget/RemoteViews;
 Lcom/android/internal/backup/IBackupTransport$Stub;-><init>()V
+Lcom/android/internal/content/PackageMonitor;-><init>()V
 Lcom/android/internal/database/SortCursor;-><init>([Landroid/database/Cursor;Ljava/lang/String;)V
 Lcom/android/internal/database/SortCursor;->mCursor:Landroid/database/Cursor;
 Lcom/android/internal/database/SortCursor;->mCursors:[Landroid/database/Cursor;
@@ -1612,6 +1848,14 @@
 Lcom/android/internal/location/GpsNetInitiatedHandler;->handleNiNotification(Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;)V
 Lcom/android/internal/location/GpsNetInitiatedHandler;->mIsHexInput:Z
 Lcom/android/internal/location/ILocationProvider$Stub;-><init>()V
+Lcom/android/internal/location/ILocationProvider$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/location/ILocationProvider;
+Lcom/android/internal/location/ILocationProvider;->disable()V
+Lcom/android/internal/location/ILocationProvider;->enable()V
+Lcom/android/internal/location/ILocationProvider;->getProperties()Lcom/android/internal/location/ProviderProperties;
+Lcom/android/internal/location/ILocationProvider;->getStatus(Landroid/os/Bundle;)I
+Lcom/android/internal/location/ILocationProvider;->getStatusUpdateTime()J
+Lcom/android/internal/location/ILocationProvider;->sendExtraCommand(Ljava/lang/String;Landroid/os/Bundle;)Z
+Lcom/android/internal/location/ILocationProvider;->setRequest(Lcom/android/internal/location/ProviderRequest;Landroid/os/WorkSource;)V
 Lcom/android/internal/logging/MetricsLogger;-><init>()V
 Lcom/android/internal/net/LegacyVpnInfo;-><init>()V
 Lcom/android/internal/net/VpnConfig;-><init>()V
@@ -1981,6 +2225,7 @@
 Lcom/android/internal/R$styleable;->MenuGroup:[I
 Lcom/android/internal/R$styleable;->MenuItem:[I
 Lcom/android/internal/R$styleable;->MenuView:[I
+Lcom/android/internal/R$styleable;->NumberPicker:[I
 Lcom/android/internal/R$styleable;->PopupWindow:[I
 Lcom/android/internal/R$styleable;->PopupWindow_popupAnimationStyle:I
 Lcom/android/internal/R$styleable;->PopupWindow_popupBackground:I
@@ -2106,6 +2351,7 @@
 Lcom/android/internal/R$styleable;->TextView_typeface:I
 Lcom/android/internal/R$styleable;->TextView_width:I
 Lcom/android/internal/R$styleable;->Theme:[I
+Lcom/android/internal/R$styleable;->TwoLineListItem:[I
 Lcom/android/internal/R$styleable;->View:[I
 Lcom/android/internal/R$styleable;->ViewAnimator:[I
 Lcom/android/internal/R$styleable;->ViewFlipper:[I
@@ -3126,6 +3372,7 @@
 Lcom/android/internal/telephony/ITelephony;->getActivePhoneType()I
 Lcom/android/internal/telephony/ITelephony;->getCallState()I
 Lcom/android/internal/telephony/ITelephony;->getDataActivity()I
+Lcom/android/internal/telephony/ITelephony;->getDataEnabled(I)Z
 Lcom/android/internal/telephony/ITelephony;->getDataState()I
 Lcom/android/internal/telephony/ITelephony;->getNetworkType()I
 Lcom/android/internal/telephony/ITelephony;->handlePinMmi(Ljava/lang/String;)Z
diff --git a/config/hiddenapi-vendor-list.txt b/config/hiddenapi-vendor-list.txt
deleted file mode 100644
index a21fa30..0000000
--- a/config/hiddenapi-vendor-list.txt
+++ /dev/null
@@ -1,247 +0,0 @@
-Landroid/app/IActivityController$Stub;-><init>()V
-Landroid/app/IActivityManager;->cancelRecentsAnimation(Z)V
-Landroid/app/IActivityManager;->cancelTaskWindowTransition(I)V
-Landroid/app/IActivityManager;->closeSystemDialogs(Ljava/lang/String;)V
-Landroid/app/IActivityManager;->getCurrentUser()Landroid/content/pm/UserInfo;
-Landroid/app/IActivityManager;->getFilteredTasks(III)Ljava/util/List;
-Landroid/app/IActivityManager;->getLockTaskModeState()I
-Landroid/app/IActivityManager;->getProcessMemoryInfo([I)[Landroid/os/Debug$MemoryInfo;
-Landroid/app/IActivityManager;->getRecentTasks(III)Landroid/content/pm/ParceledListSlice;
-Landroid/app/IActivityManager;->getRunningAppProcesses()Ljava/util/List;
-Landroid/app/IActivityManager;->getTaskSnapshot(IZ)Landroid/app/ActivityManager$TaskSnapshot;
-Landroid/app/IActivityManager;->registerTaskStackListener(Landroid/app/ITaskStackListener;)V
-Landroid/app/IActivityManager;->removeTask(I)Z
-Landroid/app/IActivityManager;->startActivity(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;)I
-Landroid/app/IActivityManager;->startActivityAsUser(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;I)I
-Landroid/app/IActivityManager;->startActivityFromRecents(ILandroid/os/Bundle;)I
-Landroid/app/IActivityManager;->startRecentsActivity(Landroid/content/Intent;Landroid/app/IAssistDataReceiver;Landroid/view/IRecentsAnimationRunner;)V
-Landroid/app/IAlarmManager;->setTime(J)Z
-Landroid/app/IAssistDataReceiver$Stub;-><init>()V
-Landroid/app/IAssistDataReceiver;->onHandleAssistData(Landroid/os/Bundle;)V
-Landroid/app/IAssistDataReceiver;->onHandleAssistScreenshot(Landroid/graphics/Bitmap;)V
-Landroid/bluetooth/IBluetooth;->sendConnectionStateChange(Landroid/bluetooth/BluetoothDevice;III)V
-Landroid/companion/ICompanionDeviceDiscoveryService$Stub;-><init>()V
-Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelected(Ljava/lang/String;ILjava/lang/String;)V
-Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelectionCancel()V
-Landroid/companion/IFindDeviceCallback;->onSuccess(Landroid/app/PendingIntent;)V
-Landroid/content/pm/IPackageDataObserver$Stub;-><init>()V
-Landroid/content/pm/IPackageDeleteObserver$Stub;-><init>()V
-Landroid/content/pm/IPackageDeleteObserver;->packageDeleted(Ljava/lang/String;I)V
-Landroid/content/pm/IPackageManager;->getActivityInfo(Landroid/content/ComponentName;II)Landroid/content/pm/ActivityInfo;
-Landroid/content/pm/IPackageManager;->getApplicationInfo(Ljava/lang/String;II)Landroid/content/pm/ApplicationInfo;
-Landroid/content/pm/IPackageManager;->getHomeActivities(Ljava/util/List;)Landroid/content/ComponentName;
-Landroid/content/pm/IPackageManager;->getPackageInfo(Ljava/lang/String;II)Landroid/content/pm/PackageInfo;
-Landroid/content/pm/IPackageStatsObserver;->onGetStatsCompleted(Landroid/content/pm/PackageStats;Z)V
-Landroid/hardware/location/IActivityRecognitionHardwareClient;->onAvailabilityChanged(ZLandroid/hardware/location/IActivityRecognitionHardware;)V
-Landroid/location/IGeocodeProvider;->getFromLocation(DDILandroid/location/GeocoderParams;Ljava/util/List;)Ljava/lang/String;
-Landroid/location/IGeocodeProvider;->getFromLocationName(Ljava/lang/String;DDDDILandroid/location/GeocoderParams;Ljava/util/List;)Ljava/lang/String;
-Landroid/location/IGeofenceProvider;->setGeofenceHardware(Landroid/hardware/location/IGeofenceHardware;)V
-Landroid/location/ILocationManager;->getNetworkProviderPackage()Ljava/lang/String;
-Landroid/location/ILocationManager;->reportLocation(Landroid/location/Location;Z)V
-Landroid/location/INetInitiatedListener$Stub;-><init>()V
-Landroid/location/INetInitiatedListener;->sendNiResponse(II)Z
-Landroid/media/tv/ITvRemoteProvider$Stub;-><init>()V
-Landroid/media/tv/ITvRemoteServiceInput;->clearInputBridge(Landroid/os/IBinder;)V
-Landroid/media/tv/ITvRemoteServiceInput;->closeInputBridge(Landroid/os/IBinder;)V
-Landroid/media/tv/ITvRemoteServiceInput;->openInputBridge(Landroid/os/IBinder;Ljava/lang/String;III)V
-Landroid/media/tv/ITvRemoteServiceInput;->sendKeyDown(Landroid/os/IBinder;I)V
-Landroid/media/tv/ITvRemoteServiceInput;->sendKeyUp(Landroid/os/IBinder;I)V
-Landroid/media/tv/ITvRemoteServiceInput;->sendPointerDown(Landroid/os/IBinder;III)V
-Landroid/media/tv/ITvRemoteServiceInput;->sendPointerSync(Landroid/os/IBinder;)V
-Landroid/media/tv/ITvRemoteServiceInput;->sendPointerUp(Landroid/os/IBinder;I)V
-Landroid/media/tv/ITvRemoteServiceInput;->sendTimestamp(Landroid/os/IBinder;J)V
-Landroid/net/ConnectivityManager$PacketKeepaliveCallback;-><init>()V
-Landroid/net/IConnectivityManager;->getAllNetworkState()[Landroid/net/NetworkState;
-Landroid/net/INetd$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetd;
-Landroid/net/INetd;->interfaceAddAddress(Ljava/lang/String;Ljava/lang/String;I)V
-Landroid/net/INetworkPolicyManager;->getNetworkQuotaInfo(Landroid/net/NetworkState;)Landroid/net/NetworkQuotaInfo;
-Landroid/net/INetworkStatsService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkStatsService;
-Landroid/net/INetworkStatsSession;->getHistoryForNetwork(Landroid/net/NetworkTemplate;I)Landroid/net/NetworkStatsHistory;
-Landroid/net/INetworkStatsSession;->getHistoryForUid(Landroid/net/NetworkTemplate;IIII)Landroid/net/NetworkStatsHistory;
-Landroid/net/InterfaceConfiguration;-><init>()V
-Landroid/net/LinkProperties$ProvisioningChange;->values()[Landroid/net/LinkProperties$ProvisioningChange;
-Landroid/os/AsyncResult;-><init>(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Throwable;)V
-Landroid/os/AsyncResult;->exception:Ljava/lang/Throwable;
-Landroid/os/AsyncResult;->forMessage(Landroid/os/Message;Ljava/lang/Object;Ljava/lang/Throwable;)Landroid/os/AsyncResult;
-Landroid/os/AsyncResult;->result:Ljava/lang/Object;
-Landroid/os/AsyncResult;->userObj:Ljava/lang/Object;
-Landroid/os/BatteryStats$HistoryItem;-><init>()V
-Landroid/os/BatteryStats$HistoryItem;->batteryLevel:B
-Landroid/os/BatteryStats$HistoryItem;->cmd:B
-Landroid/os/BatteryStats$HistoryItem;->states:I
-Landroid/os/BatteryStats$HistoryItem;->time:J
-Landroid/os/BatteryStats$Timer;->getCountLocked(I)I
-Landroid/os/BatteryStats$Uid$Wakelock;->getWakeTime(I)Landroid/os/BatteryStats$Timer;
-Landroid/os/BatteryStats$Uid;-><init>()V
-Landroid/os/BatteryStats$Uid;->getWifiRunningTime(JI)J
-Landroid/os/BatteryStats;->getNextHistoryLocked(Landroid/os/BatteryStats$HistoryItem;)Z
-Landroid/os/Broadcaster;-><init>()V
-Landroid/os/Broadcaster;->broadcast(Landroid/os/Message;)V
-Landroid/os/Broadcaster;->cancelRequest(ILandroid/os/Handler;I)V
-Landroid/os/Broadcaster;->request(ILandroid/os/Handler;I)V
-Landroid/os/Environment;->getLegacyExternalStorageDirectory()Ljava/io/File;
-Landroid/os/Handler;-><init>(Landroid/os/Looper;Landroid/os/Handler$Callback;Z)V
-Landroid/os/Handler;->getMain()Landroid/os/Handler;
-Landroid/os/HwBinder;->reportSyspropChanged()V
-Landroid/os/INetworkManagementService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/INetworkManagementService;
-Landroid/os/INetworkManagementService;->clearInterfaceAddresses(Ljava/lang/String;)V
-Landroid/os/INetworkManagementService;->disableIpv6(Ljava/lang/String;)V
-Landroid/os/INetworkManagementService;->enableIpv6(Ljava/lang/String;)V
-Landroid/os/INetworkManagementService;->isBandwidthControlEnabled()Z
-Landroid/os/INetworkManagementService;->registerObserver(Landroid/net/INetworkManagementEventObserver;)V
-Landroid/os/INetworkManagementService;->setInterfaceConfig(Ljava/lang/String;Landroid/net/InterfaceConfiguration;)V
-Landroid/os/INetworkManagementService;->setInterfaceIpv6PrivacyExtensions(Ljava/lang/String;Z)V
-Landroid/os/INetworkManagementService;->setIPv6AddrGenMode(Ljava/lang/String;I)V
-Landroid/os/INetworkManagementService;->unregisterObserver(Landroid/net/INetworkManagementEventObserver;)V
-Landroid/os/IPowerManager;->goToSleep(JII)V
-Landroid/os/IPowerManager;->reboot(ZLjava/lang/String;Z)V
-Landroid/os/IRemoteCallback$Stub;-><init>()V
-Landroid/os/Message;->setCallback(Ljava/lang/Runnable;)Landroid/os/Message;
-Landroid/os/Parcel;->readBlob()[B
-Landroid/os/Parcel;->readStringArray()[Ljava/lang/String;
-Landroid/os/Parcel;->writeBlob([B)V
-Landroid/os/Registrant;-><init>(Landroid/os/Handler;ILjava/lang/Object;)V
-Landroid/os/Registrant;->clear()V
-Landroid/os/Registrant;->notifyRegistrant()V
-Landroid/os/Registrant;->notifyRegistrant(Landroid/os/AsyncResult;)V
-Landroid/os/RegistrantList;-><init>()V
-Landroid/os/RegistrantList;->add(Landroid/os/Registrant;)V
-Landroid/os/RegistrantList;->addUnique(Landroid/os/Handler;ILjava/lang/Object;)V
-Landroid/os/RegistrantList;->notifyRegistrants()V
-Landroid/os/RegistrantList;->notifyRegistrants(Landroid/os/AsyncResult;)V
-Landroid/os/RegistrantList;->remove(Landroid/os/Handler;)V
-Landroid/os/RegistrantList;->removeCleared()V
-Landroid/os/RemoteException;->rethrowFromSystemServer()Ljava/lang/RuntimeException;
-Landroid/os/ServiceSpecificException;->errorCode:I
-Landroid/os/storage/StorageEventListener;-><init>()V
-Landroid/os/SystemProperties;->reportSyspropChanged()V
-Landroid/os/SystemService;->start(Ljava/lang/String;)V
-Landroid/os/SystemService;->stop(Ljava/lang/String;)V
-Landroid/os/SystemVibrator;-><init>()V
-Landroid/os/UserHandle;->isSameApp(II)Z
-Landroid/os/UserManager;->hasUserRestriction(Ljava/lang/String;Landroid/os/UserHandle;)Z
-Landroid/R$styleable;->CheckBoxPreference:[I
-Landroid/telephony/ims/compat/feature/MMTelFeature;-><init>()V
-Landroid/telephony/ims/compat/ImsService;-><init>()V
-Landroid/telephony/ims/compat/stub/ImsCallSessionImplBase;-><init>()V
-Landroid/telephony/ims/compat/stub/ImsUtListenerImplBase;-><init>()V
-Landroid/telephony/mbms/IMbmsStreamingSessionCallback$Stub;-><init>()V
-Landroid/telephony/mbms/IStreamingServiceCallback$Stub;-><init>()V
-Landroid/telephony/mbms/vendor/IMbmsStreamingService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/telephony/mbms/vendor/IMbmsStreamingService;
-Landroid/telephony/mbms/vendor/IMbmsStreamingService;->getPlaybackUri(ILjava/lang/String;)Landroid/net/Uri;
-Landroid/telephony/mbms/vendor/IMbmsStreamingService;->initialize(Landroid/telephony/mbms/IMbmsStreamingSessionCallback;I)I
-Landroid/telephony/mbms/vendor/IMbmsStreamingService;->requestUpdateStreamingServices(ILjava/util/List;)I
-Landroid/telephony/mbms/vendor/IMbmsStreamingService;->startStreaming(ILjava/lang/String;Landroid/telephony/mbms/IStreamingServiceCallback;)I
-Landroid/view/IAppTransitionAnimationSpecsFuture$Stub;-><init>()V
-Landroid/view/IRecentsAnimationController;->finish(Z)V
-Landroid/view/IRecentsAnimationController;->screenshotTask(I)Landroid/app/ActivityManager$TaskSnapshot;
-Landroid/view/IRecentsAnimationController;->setInputConsumerEnabled(Z)V
-Landroid/view/IRecentsAnimationRunner$Stub;-><init>()V
-Landroid/view/IRecentsAnimationRunner;->onAnimationCanceled()V
-Landroid/view/IRecentsAnimationRunner;->onAnimationStart(Landroid/view/IRecentsAnimationController;[Landroid/view/RemoteAnimationTarget;Landroid/graphics/Rect;Landroid/graphics/Rect;)V
-Landroid/view/IRemoteAnimationFinishedCallback;->onAnimationFinished()V
-Landroid/view/IRemoteAnimationRunner$Stub;-><init>()V
-Landroid/view/IRemoteAnimationRunner;->onAnimationCancelled()V
-Landroid/view/IRemoteAnimationRunner;->onAnimationStart([Landroid/view/RemoteAnimationTarget;Landroid/view/IRemoteAnimationFinishedCallback;)V
-Landroid/view/IWindowManager;->createInputConsumer(Landroid/os/IBinder;Ljava/lang/String;ILandroid/view/InputChannel;)V
-Landroid/view/IWindowManager;->destroyInputConsumer(Ljava/lang/String;I)Z
-Landroid/view/IWindowManager;->endProlongedAnimations()V
-Landroid/view/IWindowManager;->getStableInsets(ILandroid/graphics/Rect;)V
-Landroid/view/IWindowManager;->overridePendingAppTransitionMultiThumbFuture(Landroid/view/IAppTransitionAnimationSpecsFuture;Landroid/os/IRemoteCallback;ZI)V
-Landroid/view/IWindowManager;->overridePendingAppTransitionRemote(Landroid/view/RemoteAnimationAdapter;I)V
-Landroid/view/IWindowManager;->setNavBarVirtualKeyHapticFeedbackEnabled(Z)V
-Lcom/android/ims/ImsConfigListener;->onSetFeatureResponse(IIII)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionConferenceStateUpdated(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsConferenceState;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHandover(Lcom/android/ims/internal/IImsCallSession;IILandroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHandoverFailed(Lcom/android/ims/internal/IImsCallSession;IILandroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHeld(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHoldFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHoldReceived(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionInviteParticipantsRequestDelivered(Lcom/android/ims/internal/IImsCallSession;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionInviteParticipantsRequestFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMergeComplete(Lcom/android/ims/internal/IImsCallSession;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMergeFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMergeStarted(Lcom/android/ims/internal/IImsCallSession;Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMultipartyStateChanged(Lcom/android/ims/internal/IImsCallSession;Z)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionProgressing(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsStreamMediaProfile;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionResumed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionResumeFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionResumeReceived(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionStarted(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionStartFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionSuppServiceReceived(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsSuppServiceNotification;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionTerminated(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionTtyModeReceived(Lcom/android/ims/internal/IImsCallSession;I)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionUpdated(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
-Lcom/android/ims/internal/IImsRegistrationListener;->registrationAssociatedUriChanged([Landroid/net/Uri;)V
-Lcom/android/ims/internal/IImsRegistrationListener;->registrationChangeFailed(ILandroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsRegistrationListener;->registrationConnectedWithRadioTech(I)V
-Lcom/android/ims/internal/IImsRegistrationListener;->registrationDisconnected(Landroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsRegistrationListener;->registrationFeatureCapabilityChanged(I[I[I)V
-Lcom/android/ims/internal/IImsRegistrationListener;->registrationProgressingWithRadioTech(I)V
-Lcom/android/ims/internal/IImsRegistrationListener;->voiceMessageCountUpdate(I)V
-Lcom/android/ims/internal/IImsUtListener;->utConfigurationCallBarringQueried(Lcom/android/ims/internal/IImsUt;I[Landroid/telephony/ims/ImsSsInfo;)V
-Lcom/android/ims/internal/IImsUtListener;->utConfigurationCallForwardQueried(Lcom/android/ims/internal/IImsUt;I[Landroid/telephony/ims/ImsCallForwardInfo;)V
-Lcom/android/ims/internal/IImsUtListener;->utConfigurationCallWaitingQueried(Lcom/android/ims/internal/IImsUt;I[Landroid/telephony/ims/ImsSsInfo;)V
-Lcom/android/ims/internal/IImsUtListener;->utConfigurationQueried(Lcom/android/ims/internal/IImsUt;ILandroid/os/Bundle;)V
-Lcom/android/ims/internal/IImsUtListener;->utConfigurationQueryFailed(Lcom/android/ims/internal/IImsUt;ILandroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsUtListener;->utConfigurationUpdated(Lcom/android/ims/internal/IImsUt;I)V
-Lcom/android/ims/internal/IImsUtListener;->utConfigurationUpdateFailed(Lcom/android/ims/internal/IImsUt;ILandroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/uce/options/IOptionsListener;->cmdStatus(Lcom/android/ims/internal/uce/options/OptionsCmdStatus;)V
-Lcom/android/ims/internal/uce/options/IOptionsListener;->getVersionCb(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/options/IOptionsListener;->incomingOptions(Ljava/lang/String;Lcom/android/ims/internal/uce/options/OptionsCapInfo;I)V
-Lcom/android/ims/internal/uce/options/IOptionsListener;->serviceAvailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
-Lcom/android/ims/internal/uce/options/IOptionsListener;->serviceUnavailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
-Lcom/android/ims/internal/uce/options/IOptionsListener;->sipResponseReceived(Ljava/lang/String;Lcom/android/ims/internal/uce/options/OptionsSipResponse;Lcom/android/ims/internal/uce/options/OptionsCapInfo;)V
-Lcom/android/ims/internal/uce/options/IOptionsService$Stub;-><init>()V
-Lcom/android/ims/internal/uce/options/IOptionsService;->addListener(ILcom/android/ims/internal/uce/options/IOptionsListener;Lcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService;->getContactCap(ILjava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService;->getContactListCap(I[Ljava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService;->getMyInfo(II)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService;->getVersion(I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService;->removeListener(ILcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService;->responseIncomingOptions(IIILjava/lang/String;Lcom/android/ims/internal/uce/options/OptionsCapInfo;Z)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService;->setMyInfo(ILcom/android/ims/internal/uce/common/CapInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->capInfoReceived(Ljava/lang/String;[Lcom/android/ims/internal/uce/presence/PresTupleInfo;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->cmdStatus(Lcom/android/ims/internal/uce/presence/PresCmdStatus;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->getVersionCb(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->listCapInfoReceived(Lcom/android/ims/internal/uce/presence/PresRlmiInfo;[Lcom/android/ims/internal/uce/presence/PresResInfo;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->publishTriggering(Lcom/android/ims/internal/uce/presence/PresPublishTriggerType;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->serviceAvailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->serviceUnAvailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->sipResponseReceived(Lcom/android/ims/internal/uce/presence/PresSipResponse;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->unpublishMessageSent()V
-Lcom/android/ims/internal/uce/presence/IPresenceService$Stub;-><init>()V
-Lcom/android/ims/internal/uce/presence/IPresenceService;->addListener(ILcom/android/ims/internal/uce/presence/IPresenceListener;Lcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService;->getContactCap(ILjava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService;->getContactListCap(I[Ljava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService;->getVersion(I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService;->publishMyCap(ILcom/android/ims/internal/uce/presence/PresCapInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService;->reenableService(II)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService;->removeListener(ILcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService;->setNewFeatureTag(ILjava/lang/String;Lcom/android/ims/internal/uce/presence/PresServiceInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/uceservice/IUceListener;->setStatus(I)V
-Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V
-Lcom/android/ims/internal/uce/uceservice/IUceService;->createOptionsService(Lcom/android/ims/internal/uce/options/IOptionsListener;Lcom/android/ims/internal/uce/common/UceLong;)I
-Lcom/android/ims/internal/uce/uceservice/IUceService;->createPresenceService(Lcom/android/ims/internal/uce/presence/IPresenceListener;Lcom/android/ims/internal/uce/common/UceLong;)I
-Lcom/android/ims/internal/uce/uceservice/IUceService;->destroyOptionsService(I)V
-Lcom/android/ims/internal/uce/uceservice/IUceService;->destroyPresenceService(I)V
-Lcom/android/ims/internal/uce/uceservice/IUceService;->getOptionsService()Lcom/android/ims/internal/uce/options/IOptionsService;
-Lcom/android/ims/internal/uce/uceservice/IUceService;->getPresenceService()Lcom/android/ims/internal/uce/presence/IPresenceService;
-Lcom/android/ims/internal/uce/uceservice/IUceService;->getServiceStatus()Z
-Lcom/android/ims/internal/uce/uceservice/IUceService;->isServiceStarted()Z
-Lcom/android/ims/internal/uce/uceservice/IUceService;->startService(Lcom/android/ims/internal/uce/uceservice/IUceListener;)Z
-Lcom/android/ims/internal/uce/uceservice/IUceService;->stopService()Z
-Lcom/android/internal/app/IAppOpsService;->finishOperation(Landroid/os/IBinder;IILjava/lang/String;)V
-Lcom/android/internal/content/PackageMonitor;-><init>()V
-Lcom/android/internal/location/ILocationProvider$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/location/ILocationProvider;
-Lcom/android/internal/location/ILocationProvider;->disable()V
-Lcom/android/internal/location/ILocationProvider;->enable()V
-Lcom/android/internal/location/ILocationProvider;->getProperties()Lcom/android/internal/location/ProviderProperties;
-Lcom/android/internal/location/ILocationProvider;->getStatus(Landroid/os/Bundle;)I
-Lcom/android/internal/location/ILocationProvider;->getStatusUpdateTime()J
-Lcom/android/internal/location/ILocationProvider;->sendExtraCommand(Ljava/lang/String;Landroid/os/Bundle;)Z
-Lcom/android/internal/location/ILocationProvider;->setRequest(Lcom/android/internal/location/ProviderRequest;Landroid/os/WorkSource;)V
-Lcom/android/internal/R$styleable;->NumberPicker:[I
-Lcom/android/internal/R$styleable;->TwoLineListItem:[I
-Lcom/android/internal/telephony/ITelephony;->getDataEnabled(I)Z
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 3f10754..719bba0 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -696,6 +696,23 @@
         return loaders;
     }
 
+    private StrictMode.ThreadPolicy allowThreadDiskReads() {
+        if (mActivityThread == null) {
+            // When LoadedApk is used without an ActivityThread (usually in a
+            // zygote context), don't call into StrictMode, as it initializes
+            // the binder subsystem, which we don't want.
+            return null;
+        }
+
+        return StrictMode.allowThreadDiskReads();
+    }
+
+    private void setThreadPolicy(StrictMode.ThreadPolicy policy) {
+        if (mActivityThread != null && policy != null) {
+            StrictMode.setThreadPolicy(policy);
+        }
+    }
+
     private void createOrUpdateClassLoaderLocked(List<String> addedPaths) {
         if (mPackageName.equals("android")) {
             // Note: This branch is taken for system server and we don't need to setup
@@ -718,8 +735,11 @@
 
         // Avoid the binder call when the package is the current application package.
         // The activity manager will perform ensure that dexopt is performed before
-        // spinning up the process.
-        if (!Objects.equals(mPackageName, ActivityThread.currentPackageName()) && mIncludeCode) {
+        // spinning up the process. Similarly, don't call into binder when we don't
+        // have an ActivityThread object.
+        if (mActivityThread != null
+                && !Objects.equals(mPackageName, ActivityThread.currentPackageName())
+                && mIncludeCode) {
             try {
                 ActivityThread.getPackageManager().notifyPackageUse(mPackageName,
                         PackageManager.NOTIFY_PACKAGE_USE_CROSS_PACKAGE);
@@ -790,12 +810,12 @@
         // mIncludeCode == false).
         if (!mIncludeCode) {
             if (mDefaultClassLoader == null) {
-                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+                StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
                 mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoader(
                         "" /* codePath */, mApplicationInfo.targetSdkVersion, isBundledApp,
                         librarySearchPath, libraryPermittedPath, mBaseClassLoader,
                         null /* classLoaderName */);
-                StrictMode.setThreadPolicy(oldPolicy);
+                setThreadPolicy(oldPolicy);
                 mAppComponentFactory = AppComponentFactory.DEFAULT;
             }
 
@@ -822,7 +842,7 @@
         if (mDefaultClassLoader == null) {
             // Temporarily disable logging of disk reads on the Looper thread
             // as this is early and necessary.
-            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+            StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
 
             List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
                     mApplicationInfo.sharedLibraryInfos, isBundledApp, librarySearchPath,
@@ -834,18 +854,18 @@
                     mApplicationInfo.classLoaderName, sharedLibraries);
             mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
 
-            StrictMode.setThreadPolicy(oldPolicy);
+            setThreadPolicy(oldPolicy);
             // Setup the class loader paths for profiling.
             needToSetupJitProfiles = true;
         }
 
         if (!libPaths.isEmpty() && SystemProperties.getBoolean(PROPERTY_NAME_APPEND_NATIVE, true)) {
             // Temporarily disable logging of disk reads on the Looper thread as this is necessary
-            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+            StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
             try {
                 ApplicationLoaders.getDefault().addNative(mDefaultClassLoader, libPaths);
             } finally {
-                StrictMode.setThreadPolicy(oldPolicy);
+                setThreadPolicy(oldPolicy);
             }
         }
 
@@ -879,11 +899,11 @@
             extraLibPaths.add("/product/lib" + abiSuffix);
         }
         if (!extraLibPaths.isEmpty()) {
-            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+            StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
             try {
                 ApplicationLoaders.getDefault().addNative(mDefaultClassLoader, extraLibPaths);
             } finally {
-                StrictMode.setThreadPolicy(oldPolicy);
+                setThreadPolicy(oldPolicy);
             }
         }
 
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0281e6a..aa1b5af 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -8263,7 +8263,7 @@
                 customContent = customContent.clone();
                 remoteViews.removeAllViewsExceptId(R.id.notification_main_column, R.id.progress);
                 remoteViews.addView(R.id.notification_main_column, customContent, 0 /* index */);
-                remoteViews.setReapplyDisallowed();
+                remoteViews.addFlags(RemoteViews.FLAG_REAPPLY_DISALLOWED);
             }
             // also update the end margin if there is an image
             Resources resources = mBuilder.mContext.getResources();
@@ -8394,7 +8394,7 @@
                 customContent.overrideTextColors(mBuilder.getPrimaryTextColor(mBuilder.mParams));
                 remoteViews.removeAllViews(id);
                 remoteViews.addView(id, customContent);
-                remoteViews.setReapplyDisallowed();
+                remoteViews.addFlags(RemoteViews.FLAG_REAPPLY_DISALLOWED);
             }
             return remoteViews;
         }
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index 32fc0dc..9dcd122 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -119,6 +119,7 @@
     /**
      * @deprecated Use {@link #addConfig(long, byte[])}
      */
+    @Deprecated
     @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
     public boolean addConfiguration(long configKey, byte[] config) {
         try {
@@ -154,6 +155,7 @@
     /**
      * @deprecated Use {@link #removeConfig(long)}
      */
+    @Deprecated
     @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
     public boolean removeConfiguration(long configKey) {
         try {
@@ -222,6 +224,7 @@
     /**
      * @deprecated Use {@link #setBroadcastSubscriber(PendingIntent, long, long)}
      */
+    @Deprecated
     @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
     public boolean setBroadcastSubscriber(
             long configKey, long subscriberId, PendingIntent pendingIntent) {
@@ -275,6 +278,7 @@
     /**
      * @deprecated Use {@link #setFetchReportsOperation(PendingIntent, long)}
      */
+    @Deprecated
     @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
     public boolean setDataFetchOperation(long configKey, PendingIntent pendingIntent) {
         try {
@@ -312,6 +316,7 @@
     /**
      * @deprecated Use {@link #getReports(long)}
      */
+    @Deprecated
     @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
     public @Nullable byte[] getData(long configKey) {
         try {
@@ -348,6 +353,7 @@
     /**
      * @deprecated Use {@link #getStatsMetadata()}
      */
+    @Deprecated
     @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
     public @Nullable byte[] getMetadata() {
         try {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index dfe371c..0404e80 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -59,6 +59,7 @@
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.IBiometricService;
 import android.hardware.camera2.CameraManager;
+import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.DisplayManager;
 import android.hardware.face.FaceManager;
 import android.hardware.face.IFaceService;
@@ -386,6 +387,14 @@
                 return new DisplayManager(ctx.getOuterContext());
             }});
 
+        registerService(Context.COLOR_DISPLAY_SERVICE, ColorDisplayManager.class,
+                new CachedServiceFetcher<ColorDisplayManager>() {
+                    @Override
+                    public ColorDisplayManager createService(ContextImpl ctx) {
+                        return new ColorDisplayManager();
+                    }
+                });
+
         // InputMethodManager has its own cache strategy based on display id to support apps that
         // still assume InputMethodManager is a per-process singleton and it's safe to directly
         // access internal fields via reflection.  Hence directly use ServiceFetcher instead of
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index 78b7d48..257122d 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -75,6 +75,9 @@
     /** The current windowing mode of the configuration. */
     private @WindowingMode int mWindowingMode;
 
+    /** The display windowing mode of the configuration */
+    private @WindowingMode int mDisplayWindowingMode;
+
     /** Windowing mode is currently not defined. */
     public static final int WINDOWING_MODE_UNDEFINED = 0;
     /** Occupies the full area of the screen or the parent container. */
@@ -176,6 +179,10 @@
     /** Bit that indicates that the {@link #mRotation} changed.
      * @hide */
     public static final int WINDOW_CONFIG_ROTATION = 1 << 5;
+    /** Bit that indicates that the {@link #mDisplayWindowingMode} changed.
+     * @hide */
+    public static final int WINDOW_CONFIG_DISPLAY_WINDOWING_MODE = 1 << 6;
+
     /** @hide */
     @IntDef(flag = true, prefix = { "WINDOW_CONFIG_" }, value = {
             WINDOW_CONFIG_BOUNDS,
@@ -184,6 +191,7 @@
             WINDOW_CONFIG_ACTIVITY_TYPE,
             WINDOW_CONFIG_ALWAYS_ON_TOP,
             WINDOW_CONFIG_ROTATION,
+            WINDOW_CONFIG_DISPLAY_WINDOWING_MODE,
     })
     public @interface WindowConfig {}
 
@@ -211,6 +219,7 @@
         dest.writeInt(mActivityType);
         dest.writeInt(mAlwaysOnTop);
         dest.writeInt(mRotation);
+        dest.writeInt(mDisplayWindowingMode);
     }
 
     private void readFromParcel(Parcel source) {
@@ -220,6 +229,7 @@
         mActivityType = source.readInt();
         mAlwaysOnTop = source.readInt();
         mRotation = source.readInt();
+        mDisplayWindowingMode = source.readInt();
     }
 
     @Override
@@ -322,6 +332,12 @@
         return mWindowingMode;
     }
 
+    /** @hide */
+    public void setDisplayWindowingMode(@WindowingMode int windowingMode) {
+        mDisplayWindowingMode = windowingMode;
+    }
+
+
     public void setActivityType(@ActivityType int activityType) {
         if (mActivityType == activityType) {
             return;
@@ -351,6 +367,7 @@
         setActivityType(other.mActivityType);
         setAlwaysOnTop(other.mAlwaysOnTop);
         setRotation(other.mRotation);
+        setDisplayWindowingMode(other.mDisplayWindowingMode);
     }
 
     /** Set this object to completely undefined.
@@ -367,6 +384,7 @@
         setActivityType(ACTIVITY_TYPE_UNDEFINED);
         setAlwaysOnTop(ALWAYS_ON_TOP_UNDEFINED);
         setRotation(ROTATION_UNDEFINED);
+        setDisplayWindowingMode(WINDOWING_MODE_UNDEFINED);
     }
 
     /**
@@ -407,6 +425,11 @@
             changed |= WINDOW_CONFIG_ROTATION;
             setRotation(delta.mRotation);
         }
+        if (delta.mDisplayWindowingMode != WINDOWING_MODE_UNDEFINED
+                && mDisplayWindowingMode != delta.mDisplayWindowingMode) {
+            changed |= WINDOW_CONFIG_DISPLAY_WINDOWING_MODE;
+            setDisplayWindowingMode(delta.mDisplayWindowingMode);
+        }
         return changed;
     }
 
@@ -455,6 +478,11 @@
             changes |= WINDOW_CONFIG_ROTATION;
         }
 
+        if ((compareUndefined || other.mDisplayWindowingMode != WINDOWING_MODE_UNDEFINED)
+                && mDisplayWindowingMode != other.mDisplayWindowingMode) {
+            changes |= WINDOW_CONFIG_DISPLAY_WINDOWING_MODE;
+        }
+
         return changes;
     }
 
@@ -493,6 +521,8 @@
         if (n != 0) return n;
         n = mRotation - that.mRotation;
         if (n != 0) return n;
+        n = mDisplayWindowingMode - that.mDisplayWindowingMode;
+        if (n != 0) return n;
 
         // if (n != 0) return n;
         return n;
@@ -522,6 +552,7 @@
         result = 31 * result + mActivityType;
         result = 31 * result + mAlwaysOnTop;
         result = 31 * result + mRotation;
+        result = 31 * result + mDisplayWindowingMode;
         return result;
     }
 
@@ -531,6 +562,7 @@
         return "{ mBounds=" + mBounds
                 + " mAppBounds=" + mAppBounds
                 + " mWindowingMode=" + windowingModeToString(mWindowingMode)
+                + " mDisplayWindowingMode=" + windowingModeToString(mDisplayWindowingMode)
                 + " mActivityType=" + activityTypeToString(mActivityType)
                 + " mAlwaysOnTop=" + alwaysOnTopToString(mAlwaysOnTop)
                 + " mRotation=" + (mRotation == ROTATION_UNDEFINED
@@ -603,7 +635,8 @@
      * @hide
      */
     public boolean hasWindowDecorCaption() {
-        return mWindowingMode == WINDOWING_MODE_FREEFORM;
+        return mActivityType == ACTIVITY_TYPE_STANDARD && (mWindowingMode == WINDOWING_MODE_FREEFORM
+                || mDisplayWindowingMode == WINDOWING_MODE_FREEFORM);
     }
 
     /**
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 98d2a40..3a97284 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -10092,11 +10092,40 @@
         if (mService != null) {
             try {
                 return mService.isPackageAllowedToAccessCalendarForUser(packageName,
-                        mContext.getUserId());
+                        myUserId());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
         }
         return false;
     }
+
+    /**
+     * Gets a set of package names that are whitelisted to access cross profile calendar APIs.
+     *
+     * <p>To query for a specific user, use
+     * {@link Context#createPackageContextAsUser(String, int, UserHandle)} to create a context for
+     * that user, and get a {@link DevicePolicyManager} from this context.
+     *
+     * @return the set of names of packages that were previously whitelisted via
+     * {@link #addCrossProfileCalendarPackage(ComponentName, String)}, or an
+     * empty set if none have been whitelisted.
+     *
+     * @see #addCrossProfileCalendarPackage(ComponentName, String)
+     * @see #removeCrossProfileCalendarPackage(ComponentName, String)
+     * @see #getCrossProfileCalendarPackages(ComponentName)
+     * @hide
+     */
+    public @NonNull Set<String>  getCrossProfileCalendarPackages() {
+        throwIfParentInstance("getCrossProfileCalendarPackages");
+        if (mService != null) {
+            try {
+                return new ArraySet<>(mService.getCrossProfileCalendarPackagesForUser(
+                        myUserId()));
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+        return Collections.emptySet();
+    }
 }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 297676d..fcf74ee 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -427,4 +427,5 @@
     boolean removeCrossProfileCalendarPackage(in ComponentName admin, String packageName);
     List<String> getCrossProfileCalendarPackages(in ComponentName admin);
     boolean isPackageAllowedToAccessCalendarForUser(String packageName, int userHandle);
+    List<String> getCrossProfileCalendarPackagesForUser(int userHandle);
 }
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index 318dbee..c740c42 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -88,6 +88,7 @@
     int mViewMode = VIEW_MODE_NOINIT;
     int mLayoutId = -1;
     private OnClickHandler mOnClickHandler;
+    private boolean mOnLightBackground;
 
     private Executor mAsyncExecutor;
     private CancellationSignal mLastExecutionSignal;
@@ -374,6 +375,15 @@
     }
 
     /**
+     * Sets whether the widget should is being displayed on a light/white background and use an
+     * alternate UI if available.
+     * @see RemoteViews#setLightBackgroundLayoutId(int)
+     */
+    public void setOnLightBackground(boolean useDarkTextLayout) {
+        mOnLightBackground = useDarkTextLayout;
+    }
+
+    /**
      * Update the AppWidgetProviderInfo for this view, and reset it to the
      * initial layout.
      */
@@ -413,6 +423,10 @@
             mLayoutId = -1;
             mViewMode = VIEW_MODE_DEFAULT;
         } else {
+            if (mOnLightBackground) {
+                remoteViews = remoteViews.getDarkTextViews();
+            }
+
             if (mAsyncExecutor != null && useAsyncIfPossible) {
                 inflateAsync(remoteViews);
                 return;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 68aac64..fe11acb 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3126,6 +3126,7 @@
             //@hide: HDMI_CONTROL_SERVICE,
             INPUT_SERVICE,
             DISPLAY_SERVICE,
+            //@hide COLOR_DISPLAY_SERVICE,
             USER_SERVICE,
             RESTRICTIONS_SERVICE,
             APP_OPS_SERVICE,
@@ -4108,6 +4109,16 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve a
+     * {@link android.hardware.display.ColorDisplayManager} for controlling color transforms.
+     *
+     * @see #getSystemService(String)
+     * @see android.hardware.display.ColorDisplayManager
+     * @hide
+     */
+    public static final String COLOR_DISPLAY_SERVICE = "color_display";
+
+    /**
+     * Use with {@link #getSystemService(String)} to retrieve a
      * {@link android.os.UserManager} for managing users on devices that support multiple users.
      *
      * @see #getSystemService(String)
diff --git a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
index 79bc9a3..73addb7 100644
--- a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
+++ b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
@@ -16,13 +16,15 @@
 
 package android.content.pm.permission;
 
+import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
@@ -32,7 +34,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.os.SomeArgs;
+import com.android.internal.util.function.pooled.PooledLambda;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -109,13 +111,11 @@
      */
     public void getAppPermissions(@NonNull String packageName,
             @NonNull OnResultCallback callback, @Nullable Handler handler) {
-        SomeArgs args = SomeArgs.obtain();
-        args.arg1 = packageName;
-        args.arg2 = callback;
-        args.arg3 = handler;
-        Message message = mRemoteService.obtainMessage(
-                RemoteService.MSG_GET_APP_PERMISSIONS, args);
-        mRemoteService.processMessage(message);
+        checkNotNull(packageName);
+        checkNotNull(callback);
+
+        mRemoteService.processMessage(obtainMessage(RemoteService::getAppPermissions,
+                mRemoteService, packageName, callback, handler));
     }
 
     /**
@@ -124,24 +124,20 @@
      * @param packageName The package for which to revoke
      * @param permissionName The permission to revoke
      */
-    public void revokeRuntimePermission(String packageName, String permissionName) {
-        SomeArgs args = SomeArgs.obtain();
-        args.arg1 = packageName;
-        args.arg2 = permissionName;
+    public void revokeRuntimePermission(@NonNull String packageName,
+            @NonNull String permissionName) {
+        checkNotNull(packageName);
+        checkNotNull(permissionName);
 
-        Message message = mRemoteService.obtainMessage(
-                RemoteService.MSG_REVOKE_APP_PERMISSIONS, args);
-        mRemoteService.processMessage(message);
+        mRemoteService.processMessage(obtainMessage(RemoteService::revokeAppPermissions,
+                mRemoteService, packageName, permissionName));
     }
 
     private static final class RemoteService
             extends Handler implements ServiceConnection {
         private static final long UNBIND_TIMEOUT_MILLIS = 10000;
 
-        public static final int MSG_GET_APP_PERMISSIONS = 1;
-        public static final int MSG_GET_APPS_USING_PERMISSIONS = 2;
-        public static final int MSG_UNBIND = 3;
-        public static final int MSG_REVOKE_APP_PERMISSIONS = 4;
+        public static final int MSG_UNBIND = 0;
 
         private final Object mLock = new Object();
 
@@ -191,82 +187,57 @@
             }
         }
 
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_GET_APP_PERMISSIONS: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    final String packageName = (String) args.arg1;
-                    final OnResultCallback callback = (OnResultCallback) args.arg2;
-                    final Handler handler = (Handler) args.arg3;
-                    args.recycle();
-                    final IRuntimePermissionPresenter remoteInstance;
-                    synchronized (mLock) {
-                        remoteInstance = mRemoteInstance;
-                    }
-                    if (remoteInstance == null) {
-                        return;
-                    }
-                    try {
-                        remoteInstance.getAppPermissions(packageName,
-                                new RemoteCallback(new RemoteCallback.OnResultListener() {
-                            @Override
-                            public void onResult(Bundle result) {
-                                final List<RuntimePermissionPresentationInfo> reportedPermissions;
-                                List<RuntimePermissionPresentationInfo> permissions = null;
-                                if (result != null) {
-                                    permissions = result.getParcelableArrayList(KEY_RESULT);
-                                }
-                                if (permissions == null) {
-                                    permissions = Collections.emptyList();
-                                }
-                                reportedPermissions = permissions;
-                                if (handler != null) {
-                                    handler.post(new Runnable() {
-                                        @Override
-                                        public void run() {
-                                            callback.onGetAppPermissions(reportedPermissions);
-                                        }
-                                    });
-                                } else {
-                                    callback.onGetAppPermissions(reportedPermissions);
-                                }
+        private void getAppPermissions(@NonNull String packageName,
+                @NonNull OnResultCallback callback, @Nullable Handler handler) {
+            final IRuntimePermissionPresenter remoteInstance;
+            synchronized (mLock) {
+                remoteInstance = mRemoteInstance;
+            }
+            if (remoteInstance == null) {
+                return;
+            }
+            try {
+                remoteInstance.getAppPermissions(packageName,
+                        new RemoteCallback(result -> {
+                            final List<RuntimePermissionPresentationInfo> reportedPermissions;
+                            List<RuntimePermissionPresentationInfo> permissions = null;
+                            if (result != null) {
+                                permissions = result.getParcelableArrayList(KEY_RESULT);
+                            }
+                            if (permissions == null) {
+                                permissions = Collections.emptyList();
+                            }
+                            reportedPermissions = permissions;
+                            if (handler != null) {
+                                handler.post(
+                                        () -> callback.onGetAppPermissions(reportedPermissions));
+                            } else {
+                                callback.onGetAppPermissions(reportedPermissions);
                             }
                         }, this));
-                    } catch (RemoteException re) {
-                        Log.e(TAG, "Error getting app permissions", re);
-                    }
-                    scheduleUnbind();
-                } break;
+            } catch (RemoteException re) {
+                Log.e(TAG, "Error getting app permissions", re);
+            }
+            scheduleUnbind();
 
-                case MSG_UNBIND: {
-                    synchronized (mLock) {
-                        if (mBound) {
-                            mContext.unbindService(this);
-                            mBound = false;
-                        }
-                        mRemoteInstance = null;
-                    }
-                } break;
+            synchronized (mLock) {
+                scheduleNextMessageIfNeededLocked();
+            }
+        }
 
-                case MSG_REVOKE_APP_PERMISSIONS: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    final String packageName = (String) args.arg1;
-                    final String permissionName = (String) args.arg2;
-                    args.recycle();
-                    final IRuntimePermissionPresenter remoteInstance;
-                    synchronized (mLock) {
-                        remoteInstance = mRemoteInstance;
-                    }
-                    if (remoteInstance == null) {
-                        return;
-                    }
-                    try {
-                        remoteInstance.revokeRuntimePermission(packageName, permissionName);
-                    } catch (RemoteException re) {
-                        Log.e(TAG, "Error getting app permissions", re);
-                    }
-                } break;
+        private void revokeAppPermissions(@NonNull String packageName,
+                @NonNull String permissionName) {
+            final IRuntimePermissionPresenter remoteInstance;
+            synchronized (mLock) {
+                remoteInstance = mRemoteInstance;
+            }
+            if (remoteInstance == null) {
+                return;
+            }
+            try {
+                remoteInstance.revokeRuntimePermission(packageName, permissionName);
+            } catch (RemoteException re) {
+                Log.e(TAG, "Error getting app permissions", re);
             }
 
             synchronized (mLock) {
@@ -274,6 +245,16 @@
             }
         }
 
+        private void unbind() {
+            synchronized (mLock) {
+                if (mBound) {
+                    mContext.unbindService(this);
+                    mBound = false;
+                }
+                mRemoteInstance = null;
+            }
+        }
+
         @GuardedBy("mLock")
         private void scheduleNextMessageIfNeededLocked() {
             if (mBound && mRemoteInstance != null && !mPendingWork.isEmpty()) {
@@ -284,7 +265,8 @@
 
         private void scheduleUnbind() {
             removeMessages(MSG_UNBIND);
-            sendEmptyMessageDelayed(MSG_UNBIND, UNBIND_TIMEOUT_MILLIS);
+            sendMessageDelayed(PooledLambda.obtainMessage(RemoteService::unbind, this)
+                    .setWhat(MSG_UNBIND), UNBIND_TIMEOUT_MILLIS);
         }
     }
 }
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 7148b12..5e402c7 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -393,7 +393,7 @@
      *         doesn't have any recommendation for this use case or the recommended configurations
      *         are invalid.
      */
-    public RecommendedStreamConfigurationMap getRecommendedStreamConfigurationMap(
+    public @Nullable RecommendedStreamConfigurationMap getRecommendedStreamConfigurationMap(
             @RecommendedStreamConfigurationMap.RecommendedUsecase int usecase) {
         if (((usecase >= RecommendedStreamConfigurationMap.USECASE_PREVIEW) &&
                 (usecase <= RecommendedStreamConfigurationMap.USECASE_RAW)) ||
diff --git a/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java b/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
index 59e4a33..068c0ce 100644
--- a/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
@@ -17,6 +17,7 @@
 package android.hardware.camera2.params;
 
 import android.annotation.IntDef;
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.ImageFormat;
@@ -173,7 +174,7 @@
      *
      * @return Use case id.
      */
-    public int getRecommendedUseCase() {
+    public @RecommendedUsecase int getRecommendedUseCase() {
         return mUsecase;
     }
 
@@ -326,7 +327,7 @@
      * @throws IllegalArgumentException if input size does not exist in the return value of
      *             getHighSpeedVideoSizes
      */
-    public @Nullable Set<Range<Integer>> getHighSpeedVideoFpsRangesFor(Size size) {
+    public @Nullable Set<Range<Integer>> getHighSpeedVideoFpsRangesFor(@NonNull Size size) {
         return getUnmodifiableRangeSet(mRecommendedMap.getHighSpeedVideoFpsRangesFor(size));
     }
 
@@ -349,14 +350,14 @@
      * For further information refer to {@link StreamConfigurationMap#getHighSpeedVideoSizesFor}.
      * </p>
      *
-     * @param fpsRange one of the FPS range returned by {@link #getHighSpeedVideoFpsRanges()}
+     * @param fpsRange one of the FPS ranges returned by {@link #getHighSpeedVideoFpsRanges()}
      * @return A non-modifiable set of video sizes to create high speed capture sessions for high
      *         speed streaming use cases.
      *
      * @throws IllegalArgumentException if input FPS range does not exist in the return value of
      *         getHighSpeedVideoFpsRanges
      */
-    public @Nullable Set<Size> getHighSpeedVideoSizesFor(Range<Integer> fpsRange) {
+    public @Nullable Set<Size> getHighSpeedVideoSizesFor(@NonNull Range<Integer> fpsRange) {
         return getUnmodifiableSizeSet(mRecommendedMap.getHighSpeedVideoSizesFor(fpsRange));
     }
 
@@ -390,10 +391,8 @@
      *          0 if the minimum frame duration is not available.
      *
      * @throws IllegalArgumentException if {@code format} or {@code size} was not supported
-     * @throws NullPointerException if {@code size} was {@code null}
-     *
      */
-    public long getOutputMinFrameDuration(int format, Size size) {
+    public @IntRange(from = 0) long getOutputMinFrameDuration(int format, @NonNull Size size) {
         return mRecommendedMap.getOutputMinFrameDuration(format, size);
     }
 
@@ -409,9 +408,8 @@
      * @return a stall duration {@code >=} 0 in nanoseconds
      *
      * @throws IllegalArgumentException if {@code format} or {@code size} was not supported
-     * @throws NullPointerException if {@code size} was {@code null}
      */
-    public long getOutputStallDuration(int format, Size size) {
+    public @IntRange(from = 0) long getOutputStallDuration(int format, @NonNull Size size) {
         return mRecommendedMap.getOutputStallDuration(format, size);
     }
 
@@ -422,16 +420,12 @@
      * </p>
      *
      * @param klass
-     *          a non-{@code null} {@link Class} object reference
+     *          a {@link Class} object reference
      * @return
      *          a non-modifiable set of supported sizes for {@link ImageFormat#PRIVATE} format,
      *          or {@code null} if the {@code klass} is not a supported output.
-     *
-     *
-     * @throws NullPointerException if {@code klass} was {@code null}
-     *
      */
-    public <T> @Nullable Set<Size> getOutputSizes(Class<T> klass) {
+    public <T> @Nullable Set<Size> getOutputSizes(@NonNull Class<T> klass) {
         if (mSupportsPrivate) {
             return getUnmodifiableSizeSet(mRecommendedMap.getOutputSizes(klass));
         }
@@ -447,16 +441,15 @@
      * {@link StreamConfigurationMap#getOutputMinFrameDuration(Class, Size)}.</p>
      *
      * @param klass
-     *          a class which  has a non-empty array returned by {@link #getOutputSizes(Class)}
+     *          a class which has a non-empty array returned by {@link #getOutputSizes(Class)}
      * @param size an output-compatible size
      * @return a minimum frame duration {@code >} 0 in nanoseconds, or
      *          0 if the minimum frame duration is not available.
      *
      * @throws IllegalArgumentException if {@code klass} or {@code size} was not supported
-     * @throws NullPointerException if {@code size} or {@code klass} was {@code null}
-     *
      */
-    public <T> long getOutputMinFrameDuration(final Class<T> klass, final Size size) {
+    public <T> @IntRange(from = 0) long getOutputMinFrameDuration(@NonNull final Class<T> klass,
+            @NonNull final Size size) {
         if (mSupportsPrivate) {
             return mRecommendedMap.getOutputMinFrameDuration(klass, size);
         }
@@ -473,14 +466,13 @@
      * @param klass
      *          a class which has a non-empty array returned by {@link #getOutputSizes(Class)}.
      * @param size an output-compatible size
-     * @return a minimum frame duration {@code >=} 0 in nanoseconds, or 0 if the stall duration is
+     * @return a minimum frame duration {@code >} 0 in nanoseconds, or 0 if the stall duration is
      *         not available.
      *
      * @throws IllegalArgumentException if {@code klass} or {@code size} was not supported
-     * @throws NullPointerException if {@code size} or {@code klass} was {@code null}
-     *
      */
-    public <T> long getOutputStallDuration(final Class<T> klass, final Size size) {
+    public <T> @IntRange(from = 0) long getOutputStallDuration(@NonNull final Class<T> klass,
+            @NonNull final Size size) {
         if (mSupportsPrivate) {
             return mRecommendedMap.getOutputStallDuration(klass, size);
         }
@@ -495,14 +487,13 @@
      * <p>For more information refer to {@link StreamConfigurationMap#isOutputSupportedFor}.
      * </p>
      *
-     * @param surface a non-{@code null} {@link Surface} object reference
+     * @param surface a {@link Surface} object reference
      * @return {@code true} if this is supported, {@code false} otherwise
      *
-     * @throws NullPointerException if {@code surface} was {@code null}
      * @throws IllegalArgumentException if the Surface endpoint is no longer valid
      *
      */
-    public boolean isOutputSupportedFor(Surface surface) {
+    public boolean isOutputSupportedFor(@NonNull Surface surface) {
         return mRecommendedMap.isOutputSupportedFor(surface);
     }
 
diff --git a/core/java/android/hardware/display/ColorDisplayManager.java b/core/java/android/hardware/display/ColorDisplayManager.java
index 0a76c2b..a4c1332 100644
--- a/core/java/android/hardware/display/ColorDisplayManager.java
+++ b/core/java/android/hardware/display/ColorDisplayManager.java
@@ -16,20 +16,81 @@
 
 package android.hardware.display;
 
+import android.annotation.RequiresPermission;
+import android.annotation.SystemService;
 import android.content.Context;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.ServiceManager.ServiceNotFoundException;
 
 import com.android.internal.R;
 
 /**
  * Manages the display's color transforms and modes.
+ *
  * @hide
  */
+@SystemService(Context.COLOR_DISPLAY_SERVICE)
 public final class ColorDisplayManager {
 
+    private final ColorDisplayManagerInternal mManager;
+
+    /**
+     * @hide
+     */
+    public ColorDisplayManager() {
+        mManager = ColorDisplayManagerInternal.getInstance();
+    }
+
+    /**
+     * Returns whether the device has a wide color gamut display.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
+    public boolean isDeviceColorManaged() {
+        return mManager.isDeviceColorManaged();
+    }
+
     /**
      * Returns {@code true} if Night Display is supported by the device.
      */
     public static boolean isNightDisplayAvailable(Context context) {
         return context.getResources().getBoolean(R.bool.config_nightDisplayAvailable);
     }
+
+    private static class ColorDisplayManagerInternal {
+
+        private static ColorDisplayManagerInternal sInstance;
+
+        private final IColorDisplayManager mCdm;
+
+        private ColorDisplayManagerInternal(IColorDisplayManager colorDisplayManager) {
+            mCdm = colorDisplayManager;
+        }
+
+        public static ColorDisplayManagerInternal getInstance() {
+            synchronized (ColorDisplayManagerInternal.class) {
+                if (sInstance == null) {
+                    try {
+                        IBinder b = ServiceManager.getServiceOrThrow(Context.COLOR_DISPLAY_SERVICE);
+                        sInstance = new ColorDisplayManagerInternal(
+                                IColorDisplayManager.Stub.asInterface(b));
+                    } catch (ServiceNotFoundException e) {
+                        throw new IllegalStateException(e);
+                    }
+                }
+                return sInstance;
+            }
+        }
+
+        boolean isDeviceColorManaged() {
+            try {
+                return mCdm.isDeviceColorManaged();
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
 }
diff --git a/core/java/android/hardware/display/IColorDisplayManager.aidl b/core/java/android/hardware/display/IColorDisplayManager.aidl
new file mode 100644
index 0000000..f786589
--- /dev/null
+++ b/core/java/android/hardware/display/IColorDisplayManager.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.hardware.display;
+
+/** @hide */
+interface IColorDisplayManager {
+    boolean isDeviceColorManaged();
+}
\ No newline at end of file
diff --git a/core/java/android/os/IThermalService.aidl b/core/java/android/os/IThermalService.aidl
index 8160338..9280cb9 100644
--- a/core/java/android/os/IThermalService.aidl
+++ b/core/java/android/os/IThermalService.aidl
@@ -67,7 +67,7 @@
 
     /**
       * Register a listener for thermal status change.
-      * @param listener the IThermalStatusListener to be notified.
+      * @param listener the {@link android.os.IThermalStatusListener} to be notified.
       * @return true if registered successfully.
       * {@hide}
       */
@@ -75,7 +75,7 @@
 
     /**
       * Unregister a previously-registered listener for thermal status.
-      * @param listener the IThermalStatusListener to no longer be notified.
+      * @param listener the {@link android.os.IThermalStatusListener} to no longer be notified.
       * @return true if unregistered successfully.
       * {@hide}
       */
@@ -86,5 +86,5 @@
       * @return status defined in {@link android.os.Temperature}.
       * {@hide}
       */
-    int getCurrentStatus();
+    int getCurrentThermalStatus();
 }
diff --git a/core/java/android/os/Temperature.java b/core/java/android/os/Temperature.java
index bf85fbd..5499181 100644
--- a/core/java/android/os/Temperature.java
+++ b/core/java/android/os/Temperature.java
@@ -28,7 +28,7 @@
  *
  * @hide
  */
-public class Temperature implements Parcelable {
+public final class Temperature implements Parcelable {
     /** Temperature value */
     private float mValue;
     /** A temperature type from ThermalHAL */
@@ -44,7 +44,7 @@
             THROTTLING_MODERATE,
             THROTTLING_SEVERE,
             THROTTLING_CRITICAL,
-            THROTTLING_WARNING,
+            THROTTLING_EMERGENCY,
             THROTTLING_SHUTDOWN,
     })
     @Retention(RetentionPolicy.SOURCE)
@@ -56,7 +56,7 @@
     public static final int THROTTLING_MODERATE = ThrottlingSeverity.MODERATE;
     public static final int THROTTLING_SEVERE = ThrottlingSeverity.SEVERE;
     public static final int THROTTLING_CRITICAL = ThrottlingSeverity.CRITICAL;
-    public static final int THROTTLING_WARNING = ThrottlingSeverity.WARNING;
+    public static final int THROTTLING_EMERGENCY = ThrottlingSeverity.EMERGENCY;
     public static final int THROTTLING_SHUTDOWN = ThrottlingSeverity.SHUTDOWN;
 
     @IntDef(prefix = { "TYPE_" }, value = {
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 8e11d85..d315383 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -56,6 +56,7 @@
 import android.os.ServiceManager.ServiceNotFoundException;
 import android.os.SystemProperties;
 import android.provider.Settings;
+import android.sysprop.VoldProperties;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -1495,7 +1496,7 @@
      * framework, so no service needs to check for changes during their lifespan
      */
     public static boolean isBlockEncrypting() {
-        final String state = SystemProperties.get("vold.encrypt_progress", "");
+        final String state = VoldProperties.encrypt_progress().orElse("");
         return !"".equalsIgnoreCase(state);
     }
 
@@ -1511,7 +1512,7 @@
      * framework, so no service needs to check for changes during their lifespan
      */
     public static boolean inCryptKeeperBounce() {
-        final String status = SystemProperties.get("vold.decrypt");
+        final String status = VoldProperties.decrypt().orElse("");
         return "trigger_restart_min_framework".equals(status);
     }
 
diff --git a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
index 18aea03..a41a644 100644
--- a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
+++ b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
@@ -16,6 +16,9 @@
 
 package android.permissionpresenterservice;
 
+import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.app.Service;
@@ -27,12 +30,8 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
 import android.os.RemoteCallback;
 
-import com.android.internal.os.SomeArgs;
-
 import java.util.List;
 
 /**
@@ -63,7 +62,7 @@
     @Override
     public final void attachBaseContext(Context base) {
         super.attachBaseContext(base);
-        mHandler = new MyHandler(base.getMainLooper());
+        mHandler = new Handler(base.getMainLooper());
     }
 
     /**
@@ -71,7 +70,8 @@
      *
      * @param packageName The package for which to query.
      */
-    public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(String packageName);
+    public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(
+            @NonNull String packageName);
 
     /**
      * Revokes the permission {@code permissionName} for app {@code packageName}
@@ -87,61 +87,35 @@
         return new IRuntimePermissionPresenter.Stub() {
             @Override
             public void getAppPermissions(String packageName, RemoteCallback callback) {
-                SomeArgs args = SomeArgs.obtain();
-                args.arg1 = packageName;
-                args.arg2 = callback;
-                mHandler.obtainMessage(MyHandler.MSG_GET_APP_PERMISSIONS,
-                        args).sendToTarget();
+                checkNotNull(packageName, "packageName");
+                checkNotNull(callback, "callback");
+
+                mHandler.sendMessage(
+                        obtainMessage(RuntimePermissionPresenterService::getAppPermissions,
+                                RuntimePermissionPresenterService.this, packageName, callback));
             }
 
             @Override
             public void revokeRuntimePermission(String packageName, String permissionName) {
-                SomeArgs args = SomeArgs.obtain();
-                args.arg1 = packageName;
-                args.arg2 = permissionName;
-                mHandler.obtainMessage(MyHandler.MSG_REVOKE_APP_PERMISSION,
-                        args).sendToTarget();
+                checkNotNull(packageName, "packageName");
+                checkNotNull(permissionName, "permissionName");
+
+                mHandler.sendMessage(
+                        obtainMessage(RuntimePermissionPresenterService::onRevokeRuntimePermission,
+                                RuntimePermissionPresenterService.this, packageName,
+                                permissionName));
             }
         };
     }
 
-    private final class MyHandler extends Handler {
-        public static final int MSG_GET_APP_PERMISSIONS = 1;
-        public static final int MSG_GET_APPS_USING_PERMISSIONS = 2;
-        public static final int MSG_REVOKE_APP_PERMISSION = 3;
-
-        public MyHandler(Looper looper) {
-            super(looper, null, false);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_GET_APP_PERMISSIONS: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    String packageName = (String) args.arg1;
-                    RemoteCallback callback = (RemoteCallback) args.arg2;
-                    args.recycle();
-                    List<RuntimePermissionPresentationInfo> permissions =
-                            onGetAppPermissions(packageName);
-                    if (permissions != null && !permissions.isEmpty()) {
-                        Bundle result = new Bundle();
-                        result.putParcelableList(RuntimePermissionPresenter.KEY_RESULT,
-                                permissions);
-                        callback.sendResult(result);
-                    } else {
-                        callback.sendResult(null);
-                    }
-                } break;
-                case MSG_REVOKE_APP_PERMISSION: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    String packageName = (String) args.arg1;
-                    String permissionName = (String) args.arg2;
-                    args.recycle();
-
-                    onRevokeRuntimePermission(packageName, permissionName);
-                } break;
-            }
+    private void getAppPermissions(@NonNull String packageName, @NonNull RemoteCallback callback) {
+        List<RuntimePermissionPresentationInfo> permissions = onGetAppPermissions(packageName);
+        if (permissions != null && !permissions.isEmpty()) {
+            Bundle result = new Bundle();
+            result.putParcelableList(RuntimePermissionPresenter.KEY_RESULT, permissions);
+            callback.sendResult(result);
+        } else {
+            callback.sendResult(null);
         }
     }
 }
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 9e26a36..0299e41 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -37,6 +37,7 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Point;
+import android.media.ExifInterface;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.CancellationSignal;
@@ -1166,13 +1167,25 @@
             /**
              * The latitude where the image was captured.
              * <P>Type: DOUBLE</P>
+             *
+             * @deprecated location details are no longer indexed for privacy
+             *             reasons, and this value is now always {@code null}.
+             *             You can still manually obtain location metadata using
+             *             {@link ExifInterface#getLatLong(float[])}.
              */
+            @Deprecated
             public static final String LATITUDE = "latitude";
 
             /**
              * The longitude where the image was captured.
              * <P>Type: DOUBLE</P>
+             *
+             * @deprecated location details are no longer indexed for privacy
+             *             reasons, and this value is now always {@code null}.
+             *             You can still manually obtain location metadata using
+             *             {@link ExifInterface#getLatLong(float[])}.
              */
+            @Deprecated
             public static final String LONGITUDE = "longitude";
 
             /**
@@ -2410,13 +2423,25 @@
             /**
              * The latitude where the video was captured.
              * <P>Type: DOUBLE</P>
+             *
+             * @deprecated location details are no longer indexed for privacy
+             *             reasons, and this value is now always {@code null}.
+             *             You can still manually obtain location metadata using
+             *             {@link ExifInterface#getLatLong(float[])}.
              */
+            @Deprecated
             public static final String LATITUDE = "latitude";
 
             /**
              * The longitude where the video was captured.
              * <P>Type: DOUBLE</P>
+             *
+             * @deprecated location details are no longer indexed for privacy
+             *             reasons, and this value is now always {@code null}.
+             *             You can still manually obtain location metadata using
+             *             {@link ExifInterface#getLatLong(float[])}.
              */
+            @Deprecated
             public static final String LONGITUDE = "longitude";
 
             /**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c297ef4..74ec0b9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6279,6 +6279,7 @@
          *
          * @hide
          */
+        @SystemApi
         public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED =
                 "accessibility_display_magnification_navbar_enabled";
 
@@ -12837,6 +12838,23 @@
                 "max_sound_trigger_detection_service_ops_per_day";
 
         /**
+         * Property used by {@code com.android.server.SystemServer} on start to decide whether
+         * the Smart Suggestions service should be created or not
+         *
+         * <p>By default it should *NOT* be set (in which case the decision is based on whether
+         * the OEM provides an implementation for the service), but it can be overridden to:
+         *
+         * <ul>
+         *   <li>Provide a "kill switch" so OEMs can disable it remotely in case of emergency.
+         *   <li>Enable the CTS tests to be run on AOSP builds
+         * </ul>
+         *
+         * @hide
+         */
+        public static final String SMART_SUGGESTIONS_SERVICE_EXPLICITLY_ENABLED =
+                "smart_suggestions_service_explicitly_enabled";
+
+        /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
          *
@@ -13509,6 +13527,13 @@
          */
         public static final String WARNING_TEMPERATURE = "warning_temperature";
 
+
+        /**
+         * USB Temperature at which the high temperature alarm notification should be shown.
+         * @hide
+         */
+        public static final String USB_ALARM_TEMPERATURE = "usb_alarm_temperature";
+
         /**
          * Whether the diskstats logging task is enabled/disabled.
          * @hide
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index 3ee5f1f..33b3ff4f 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -18,6 +18,7 @@
 
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
 
@@ -225,7 +226,7 @@
     private int mMinimumFlingVelocity;
     private int mMaximumFlingVelocity;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     private static final int LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout();
     private static final int TAP_TIMEOUT = ViewConfiguration.getTapTimeout();
     private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();
@@ -592,8 +593,8 @@
 
                 if (mIsLongpressEnabled) {
                     mHandler.removeMessages(LONG_PRESS);
-                    mHandler.sendEmptyMessageAtTime(LONG_PRESS,
-                            mCurrentDownEvent.getDownTime() + LONGPRESS_TIMEOUT);
+                    mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()
+                            + ViewConfiguration.getLongPressTimeout());
                 }
                 mHandler.sendEmptyMessageAtTime(SHOW_PRESS,
                         mCurrentDownEvent.getDownTime() + TAP_TIMEOUT);
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 8b39cc7..9cced4e 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -1803,6 +1803,28 @@
     }
 
     /**
+     * Returns whether this key will be sent to the
+     * {@link android.media.session.MediaSession.Callback} if not handled.
+     */
+    public static final boolean isMediaSessionKey(int keyCode) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_MEDIA_PLAY:
+            case KeyEvent.KEYCODE_MEDIA_PAUSE:
+            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+            case KeyEvent.KEYCODE_MUTE:
+            case KeyEvent.KEYCODE_HEADSETHOOK:
+            case KeyEvent.KEYCODE_MEDIA_STOP:
+            case KeyEvent.KEYCODE_MEDIA_NEXT:
+            case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+            case KeyEvent.KEYCODE_MEDIA_REWIND:
+            case KeyEvent.KEYCODE_MEDIA_RECORD:
+            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+                return true;
+        }
+        return false;
+    }
+
+    /**
      * Returns true if the specified keycode is a gamepad button.
      * @return True if the keycode is a gamepad button, such as {@link #KEYCODE_BUTTON_A}.
      */
@@ -1861,31 +1883,6 @@
         }
     }
 
-    /**
-     * Returns whether this key can be handled by
-     * {@link android.media.session.MediaSession.Callback}.
-     *
-     * @hide
-     */
-    public static final boolean isMediaSessionKey(int keyCode) {
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_MEDIA_PLAY:
-            case KeyEvent.KEYCODE_MEDIA_PAUSE:
-            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
-            case KeyEvent.KEYCODE_MUTE:
-            case KeyEvent.KEYCODE_HEADSETHOOK:
-            case KeyEvent.KEYCODE_MEDIA_STOP:
-            case KeyEvent.KEYCODE_MEDIA_NEXT:
-            case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
-            case KeyEvent.KEYCODE_MEDIA_REWIND:
-            case KeyEvent.KEYCODE_MEDIA_RECORD:
-            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
-                return true;
-        }
-        return false;
-    }
-
-
     /** Is this a system key? System keys can not be used for menu shortcuts.
      * @hide
      */
diff --git a/core/java/android/view/inspector/InspectionCompanion.java b/core/java/android/view/inspector/InspectionCompanion.java
index ce0aee8..62d769b 100644
--- a/core/java/android/view/inspector/InspectionCompanion.java
+++ b/core/java/android/view/inspector/InspectionCompanion.java
@@ -62,7 +62,7 @@
      * have been mapped and throw a {@link UninitializedPropertyMapException} if this method is
      * called before {mapProperties}.
      *
-     * @param inspectable A object of type {@link T} to read the properties of.
+     * @param inspectable A object of type {T} to read the properties of.
      * @param propertyReader An object which receives the property IDs and values.
      */
     void readProperties(@NonNull T inspectable, @NonNull PropertyReader propertyReader);
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 7b39efe..3b916d1 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -18,6 +18,8 @@
 
 import android.annotation.ColorInt;
 import android.annotation.DimenRes;
+import android.annotation.IntDef;
+import android.annotation.LayoutRes;
 import android.annotation.NonNull;
 import android.annotation.StyleRes;
 import android.annotation.UnsupportedAppUsage;
@@ -131,6 +133,12 @@
     static final String EXTRA_REMOTEADAPTER_APPWIDGET_ID = "remoteAdapterAppWidgetId";
 
     /**
+     * The intent extra that contains {@code true} if inflating as dak text theme.
+     * @hide
+     */
+    static final String EXTRA_REMOTEADAPTER_ON_LIGHT_BACKGROUND = "remoteAdapterOnLightBackground";
+
+    /**
      * The intent extra that contains the bounds for all shared elements.
      */
     public static final String EXTRA_SHARED_ELEMENT_BOUNDS =
@@ -163,6 +171,36 @@
     private static final int SET_RIPPLE_DRAWABLE_COLOR_TAG = 21;
     private static final int SET_INT_TAG_TAG = 22;
 
+    /** @hide **/
+    @IntDef(flag = true, value = {
+            FLAG_REAPPLY_DISALLOWED,
+            FLAG_WIDGET_IS_COLLECTION_CHILD,
+            FLAG_USE_LIGHT_BACKGROUND_LAYOUT
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ApplyFlags {}
+    /**
+     * Whether reapply is disallowed on this remoteview. This maybe be true if some actions modify
+     * the layout in a way that isn't recoverable, since views are being removed.
+     * @hide
+     */
+    public static final int FLAG_REAPPLY_DISALLOWED = 1;
+    /**
+     * This flag indicates whether this RemoteViews object is being created from a
+     * RemoteViewsService for use as a child of a widget collection. This flag is used
+     * to determine whether or not certain features are available, in particular,
+     * setting on click extras and setting on click pending intents. The former is enabled,
+     * and the latter disabled when this flag is true.
+     * @hide
+     */
+    public static final int FLAG_WIDGET_IS_COLLECTION_CHILD = 2;
+    /**
+     * When this flag is set, the views is inflated with {@link #mLightBackgroundLayoutId} instead
+     * of {link #mLayoutId}
+     * @hide
+     */
+    public static final int FLAG_USE_LIGHT_BACKGROUND_LAYOUT = 4;
+
     /**
      * Application that hosts the remote views.
      *
@@ -178,6 +216,11 @@
     private final int mLayoutId;
 
     /**
+     * The resource ID of the layout file in dark text mode. (Added to the parcel)
+     */
+    private int mLightBackgroundLayoutId = 0;
+
+    /**
      * An array of actions to perform on the view tree once it has been
      * inflated
      */
@@ -197,12 +240,6 @@
     private boolean mIsRoot = true;
 
     /**
-     * Whether reapply is disallowed on this remoteview. This maybe be true if some actions modify
-     * the layout in a way that isn't recoverable, since views are being removed.
-     */
-    private boolean mReapplyDisallowed;
-
-    /**
      * Constants to whether or not this RemoteViews is composed of a landscape and portrait
      * RemoteViews.
      */
@@ -218,14 +255,8 @@
     @UnsupportedAppUsage
     private RemoteViews mPortrait = null;
 
-    /**
-     * This flag indicates whether this RemoteViews object is being created from a
-     * RemoteViewsService for use as a child of a widget collection. This flag is used
-     * to determine whether or not certain features are available, in particular,
-     * setting on click extras and setting on click pending intents. The former is enabled,
-     * and the latter disabled when this flag is true.
-     */
-    private boolean mIsWidgetCollectionChild = false;
+    @ApplyFlags
+    private int mApplyFlags = 0;
 
     /** Class cookies of the Parcel this instance was read from. */
     private final Map<Class, Object> mClassCookies;
@@ -289,18 +320,15 @@
      *
      * @hide
      */
-    public void setReapplyDisallowed() {
-        mReapplyDisallowed = true;
+    public void addFlags(@ApplyFlags int flags) {
+        mApplyFlags = mApplyFlags | flags;
     }
 
     /**
-     * @return Whether it is disallowed to reapply another remoteview with the same layout as this
-     * view. True if this remoteview has actions that destroyed view tree of the base layout.
-     *
      * @hide
      */
-    public boolean isReapplyDisallowed() {
-        return mReapplyDisallowed;
+    public boolean hasFlags(@ApplyFlags int flag) {
+        return (mApplyFlags & flag) == flag;
     }
 
     /**
@@ -768,7 +796,10 @@
             // Embed the AppWidget Id for use in RemoteViewsAdapter when connecting to the intent
             // RemoteViewsService
             AppWidgetHostView host = (AppWidgetHostView) rootParent;
-            intent.putExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID, host.getAppWidgetId());
+            intent.putExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID, host.getAppWidgetId())
+                    .putExtra(EXTRA_REMOTEADAPTER_ON_LIGHT_BACKGROUND,
+                            hasFlags(FLAG_USE_LIGHT_BACKGROUND_LAYOUT));
+
             if (target instanceof AbsListView) {
                 AbsListView v = (AbsListView) target;
                 v.setRemoteViewsAdapter(intent, isAsync);
@@ -829,7 +860,7 @@
                 // If the view is an AdapterView, setting a PendingIntent on click doesn't make
                 // much sense, do they mean to set a PendingIntent template for the
                 // AdapterView's children?
-                if (mIsWidgetCollectionChild) {
+                if (hasFlags(FLAG_WIDGET_IS_COLLECTION_CHILD)) {
                     Log.w(LOG_TAG, "Cannot SetOnClickResponse for collection item "
                             + "(id: " + viewId + ")");
                     ApplicationInfo appInfo = root.getContext().getApplicationInfo();
@@ -843,7 +874,7 @@
                 }
                 target.setTagInternal(R.id.pending_intent_tag, mResponse.mPendingIntent);
             } else if (mResponse.mFillIntent != null) {
-                if (!mIsWidgetCollectionChild) {
+                if (!hasFlags(FLAG_WIDGET_IS_COLLECTION_CHILD)) {
                     Log.e(LOG_TAG, "The method setOnClickFillInIntent is available "
                             + "only from RemoteViewsFactory (ie. on collection items).");
                     return;
@@ -1545,6 +1576,7 @@
             viewId = parcel.readInt();
             mIndex = parcel.readInt();
             mNestedViews = new RemoteViews(parcel, bitmapCache, info, depth, classCookies);
+            mNestedViews.addFlags(mApplyFlags);
         }
 
         public void writeToParcel(Parcel dest, int flags) {
@@ -2190,7 +2222,7 @@
      *
      * @hide
      */
-    public RemoteViews(String packageName, int userId, int layoutId) {
+    public RemoteViews(String packageName, int userId, @LayoutRes int layoutId) {
         this(getApplicationInfo(packageName, userId), layoutId);
     }
 
@@ -2203,7 +2235,7 @@
      *
      * @hide
      */
-    protected RemoteViews(ApplicationInfo application, int layoutId) {
+    protected RemoteViews(ApplicationInfo application, @LayoutRes int layoutId) {
         mApplication = application;
         mLayoutId = layoutId;
         mBitmapCache = new BitmapCache();
@@ -2229,7 +2261,8 @@
             throw new RuntimeException("Both RemoteViews must share the same package and user");
         }
         mApplication = portrait.mApplication;
-        mLayoutId = portrait.getLayoutId();
+        mLayoutId = portrait.mLayoutId;
+        mLightBackgroundLayoutId = portrait.mLightBackgroundLayoutId;
 
         mLandscape = landscape;
         mPortrait = portrait;
@@ -2250,8 +2283,8 @@
         mApplication = src.mApplication;
         mIsRoot = src.mIsRoot;
         mLayoutId = src.mLayoutId;
-        mIsWidgetCollectionChild = src.mIsWidgetCollectionChild;
-        mReapplyDisallowed = src.mReapplyDisallowed;
+        mLightBackgroundLayoutId = src.mLightBackgroundLayoutId;
+        mApplyFlags = src.mApplyFlags;
         mClassCookies = src.mClassCookies;
 
         if (src.hasLandscapeAndPortraitLayouts()) {
@@ -2309,7 +2342,7 @@
             mApplication = parcel.readInt() == 0 ? info :
                     ApplicationInfo.CREATOR.createFromParcel(parcel);
             mLayoutId = parcel.readInt();
-            mIsWidgetCollectionChild = parcel.readInt() == 1;
+            mLightBackgroundLayoutId = parcel.readInt();
 
             readActionsFromParcel(parcel, depth);
         } else {
@@ -2318,9 +2351,10 @@
             mPortrait = new RemoteViews(parcel, mBitmapCache, mLandscape.mApplication, depth,
                     mClassCookies);
             mApplication = mPortrait.mApplication;
-            mLayoutId = mPortrait.getLayoutId();
+            mLayoutId = mPortrait.mLayoutId;
+            mLightBackgroundLayoutId = mPortrait.mLightBackgroundLayoutId;
         }
-        mReapplyDisallowed = parcel.readInt() == 0;
+        mApplyFlags = parcel.readInt();
     }
 
     private void readActionsFromParcel(Parcel parcel, int depth) {
@@ -2409,19 +2443,8 @@
      * @return the layout id.
      */
     public int getLayoutId() {
-        return mLayoutId;
-    }
-
-    /*
-     * This flag indicates whether this RemoteViews object is being created from a
-     * RemoteViewsService for use as a child of a widget collection. This flag is used
-     * to determine whether or not certain features are available, in particular,
-     * setting on click extras and setting on click pending intents. The former is enabled,
-     * and the latter disabled when this flag is true.
-     */
-    @UnsupportedAppUsage
-    void setIsWidgetCollectionChild(boolean isWidgetCollectionChild) {
-        mIsWidgetCollectionChild = isWidgetCollectionChild;
+        return hasFlags(FLAG_USE_LIGHT_BACKGROUND_LAYOUT) && (mLightBackgroundLayoutId != 0)
+                ? mLightBackgroundLayoutId : mLayoutId;
     }
 
     /**
@@ -3292,6 +3315,33 @@
         setInt(viewId, "setLabelFor", labeledId);
     }
 
+    /**
+     * Provides an alternate layout ID, which can be used to inflate this view. This layout will be
+     * used by the host when the widgets displayed on a light-background where foreground elements
+     * and text can safely draw using a dark color without any additional background protection.
+     */
+    public void setLightBackgroundLayoutId(@LayoutRes int layoutId) {
+        mLightBackgroundLayoutId = layoutId;
+    }
+
+    /**
+     * If this view supports dark text versions, creates a copy representing that version,
+     * otherwise returns itself.
+     * @hide
+     */
+    public RemoteViews getDarkTextViews() {
+        if (hasFlags(FLAG_USE_LIGHT_BACKGROUND_LAYOUT)) {
+            return this;
+        }
+
+        try {
+            addFlags(FLAG_USE_LIGHT_BACKGROUND_LAYOUT);
+            return new RemoteViews(this);
+        } finally {
+            mApplyFlags &= ~FLAG_USE_LIGHT_BACKGROUND_LAYOUT;
+        }
+    }
+
     private RemoteViews getRemoteViewsToApply(Context context) {
         if (hasLandscapeAndPortraitLayouts()) {
             int orientation = context.getResources().getConfiguration().orientation;
@@ -3652,7 +3702,7 @@
                 mApplication.writeToParcel(dest, flags);
             }
             dest.writeInt(mLayoutId);
-            dest.writeInt(mIsWidgetCollectionChild ? 1 : 0);
+            dest.writeInt(mLightBackgroundLayoutId);
             writeActionsToParcel(dest);
         } else {
             dest.writeInt(MODE_HAS_LANDSCAPE_AND_PORTRAIT);
@@ -3665,7 +3715,7 @@
             // Both RemoteViews already share the same package and user
             mPortrait.writeToParcel(dest, flags | PARCELABLE_ELIDE_DUPLICATES);
         }
-        dest.writeInt(mReapplyDisallowed ? 1 : 0);
+        dest.writeInt(mApplyFlags);
     }
 
     private void writeActionsToParcel(Parcel parcel) {
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index d17c7c5..c5cd1a1 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -16,6 +16,9 @@
 
 package android.widget;
 
+import static android.widget.RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID;
+import static android.widget.RemoteViews.EXTRA_REMOTEADAPTER_ON_LIGHT_BACKGROUND;
+
 import android.annotation.UnsupportedAppUsage;
 import android.annotation.WorkerThread;
 import android.app.IServiceConnection;
@@ -97,6 +100,7 @@
     private final Context mContext;
     private final Intent mIntent;
     private final int mAppWidgetId;
+    private final boolean mOnLightBackground;
     private final Executor mAsyncViewLoadExecutor;
 
     private OnClickHandler mRemoteViewsOnClickHandler;
@@ -817,13 +821,13 @@
             throw new IllegalArgumentException("Non-null Intent must be specified.");
         }
 
-        mAppWidgetId = intent.getIntExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID, -1);
+        mAppWidgetId = intent.getIntExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID, -1);
         mRequestedViews = new RemoteViewsFrameLayoutRefSet();
+        mOnLightBackground = intent.getBooleanExtra(EXTRA_REMOTEADAPTER_ON_LIGHT_BACKGROUND, false);
 
         // Strip the previously injected app widget id from service intent
-        if (intent.hasExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID)) {
-            intent.removeExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID);
-        }
+        intent.removeExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID);
+        intent.removeExtra(EXTRA_REMOTEADAPTER_ON_LIGHT_BACKGROUND);
 
         // Initialize the worker thread
         mWorkerThread = new HandlerThread("RemoteViewsCache-loader");
@@ -1107,6 +1111,7 @@
             } else {
                 layout = new RemoteViewsFrameLayout(parent.getContext(), mCache);
                 layout.setExecutor(mAsyncViewLoadExecutor);
+                layout.setOnLightBackground(mOnLightBackground);
             }
 
             if (isInCache) {
diff --git a/core/java/android/widget/RemoteViewsListAdapter.java b/core/java/android/widget/RemoteViewsListAdapter.java
index e490458..b80fe48 100644
--- a/core/java/android/widget/RemoteViewsListAdapter.java
+++ b/core/java/android/widget/RemoteViewsListAdapter.java
@@ -85,7 +85,7 @@
     public View getView(int position, View convertView, ViewGroup parent) {
         if (position < getCount()) {
             RemoteViews rv = mRemoteViewsList.get(position);
-            rv.setIsWidgetCollectionChild(true);
+            rv.addFlags(RemoteViews.FLAG_WIDGET_IS_COLLECTION_CHILD);
             View v;
             if (convertView != null && rv != null &&
                     convertView.getId() == rv.getLayoutId()) {
diff --git a/core/java/android/widget/RemoteViewsService.java b/core/java/android/widget/RemoteViewsService.java
index 2827f63..214e5cc 100644
--- a/core/java/android/widget/RemoteViewsService.java
+++ b/core/java/android/widget/RemoteViewsService.java
@@ -163,7 +163,7 @@
             try {
                 rv = mFactory.getViewAt(position);
                 if (rv != null) {
-                    rv.setIsWidgetCollectionChild(true);
+                    rv.addFlags(RemoteViews.FLAG_WIDGET_IS_COLLECTION_CHILD);
                 }
             } catch (Exception ex) {
                 Thread t = Thread.currentThread();
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index 875d7c9..a87bbf3 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Binder;
+import android.os.Process;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.text.format.DateFormat;
@@ -78,8 +79,10 @@
     private final Random mRandom;
     private long mStartTime = System.currentTimeMillis();
     private long mCallStatsCount = 0;
+    private boolean mAddDebugEntries = false;
 
     private CachedDeviceState.Readonly mDeviceState;
+    private CachedDeviceState.TimeInStateStopwatch mBatteryStopwatch;
 
     /** Injector for {@link BinderCallsStats}. */
     public static class Injector {
@@ -93,7 +96,11 @@
     }
 
     public void setDeviceState(@NonNull CachedDeviceState.Readonly deviceState) {
+        if (mBatteryStopwatch != null) {
+            mBatteryStopwatch.close();
+        }
         mDeviceState = deviceState;
+        mBatteryStopwatch = deviceState.createTimeOnBatteryStopwatch();
     }
 
     @Override
@@ -317,9 +324,30 @@
             exported.methodName = methodName;
         }
 
+        // Debug entries added to help validate the data.
+        if (mAddDebugEntries && mBatteryStopwatch != null) {
+            resultCallStats.add(createDebugEntry("start_time_millis", mStartTime));
+            resultCallStats.add(createDebugEntry("end_time_millis", System.currentTimeMillis()));
+            resultCallStats.add(
+                    createDebugEntry("battery_time_millis", mBatteryStopwatch.getMillis()));
+        }
+
         return resultCallStats;
     }
 
+    private ExportedCallStat createDebugEntry(String variableName, long value) {
+        final int uid = Process.myUid();
+        final ExportedCallStat callStat = new ExportedCallStat();
+        callStat.className = "";
+        callStat.workSourceUid = uid;
+        callStat.callingUid = uid;
+        callStat.recordedCallCount = 1;
+        callStat.callCount = 1;
+        callStat.methodName = "__DEBUG_" + variableName;
+        callStat.maxReplySizeBytes = value;
+        return callStat;
+    }
+
     /** @hide */
     public ArrayMap<String, Integer> getExportedExceptionStats() {
         synchronized (mLock) {
@@ -341,6 +369,8 @@
         long totalCpuTime = 0;
         pw.print("Start time: ");
         pw.println(DateFormat.format("yyyy-MM-dd HH:mm:ss", mStartTime));
+        pw.print("On battery time (ms): ");
+        pw.println(mBatteryStopwatch != null ? mBatteryStopwatch.getMillis() : 0);
         pw.println("Sampling interval period: " + mPeriodicSamplingInterval);
         final List<UidEntry> entries = new ArrayList<>();
 
@@ -457,6 +487,10 @@
         }
     }
 
+    public void setAddDebugEntries(boolean addDebugEntries) {
+        mAddDebugEntries = addDebugEntries;
+    }
+
     /**
      * Sets the maximum number of items to track.
      */
@@ -496,6 +530,9 @@
             mUidEntries.clear();
             mExceptionCounts.clear();
             mStartTime = System.currentTimeMillis();
+            if (mBatteryStopwatch != null) {
+                mBatteryStopwatch.reset();
+            }
         }
     }
 
diff --git a/core/java/com/android/internal/os/CachedDeviceState.java b/core/java/com/android/internal/os/CachedDeviceState.java
index 8c90682..334cca3 100644
--- a/core/java/com/android/internal/os/CachedDeviceState.java
+++ b/core/java/com/android/internal/os/CachedDeviceState.java
@@ -16,8 +16,14 @@
 
 package com.android.internal.os;
 
+
+import android.os.SystemClock;
+
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.util.ArrayList;
+
 /**
  * Stores the device state (e.g. charging/on battery, screen on/off) to be shared with
  * the System Server telemetry services.
@@ -27,6 +33,9 @@
 public class CachedDeviceState {
     private volatile boolean mScreenInteractive;
     private volatile boolean mCharging;
+    private final Object mStopwatchesLock = new Object();
+    @GuardedBy("mStopwatchLock")
+    private final ArrayList<TimeInStateStopwatch> mOnBatteryStopwatches = new ArrayList<>();
 
     public CachedDeviceState() {
         mCharging = true;
@@ -44,7 +53,23 @@
     }
 
     public void setCharging(boolean charging) {
-        mCharging = charging;
+        if (mCharging != charging) {
+            mCharging = charging;
+            updateStopwatches(/* shouldStart= */ !charging);
+        }
+    }
+
+    private void updateStopwatches(boolean shouldStart) {
+        synchronized (mStopwatchesLock) {
+            final int size = mOnBatteryStopwatches.size();
+            for (int i = 0; i < size; i++) {
+                if (shouldStart) {
+                    mOnBatteryStopwatches.get(i).start();
+                } else {
+                    mOnBatteryStopwatches.get(i).stop();
+                }
+            }
+        }
     }
 
     public Readonly getReadonlyClient() {
@@ -62,5 +87,74 @@
         public boolean isScreenInteractive() {
             return mScreenInteractive;
         }
+
+        /** Creates a {@link TimeInStateStopwatch stopwatch} that tracks the time on battery. */
+        public TimeInStateStopwatch createTimeOnBatteryStopwatch() {
+            synchronized (mStopwatchesLock) {
+                final TimeInStateStopwatch stopwatch = new TimeInStateStopwatch();
+                mOnBatteryStopwatches.add(stopwatch);
+                if (!mCharging) {
+                    stopwatch.start();
+                }
+                return stopwatch;
+            }
+        }
+    }
+
+    /** Tracks the time the device spent in a given state. */
+    public class TimeInStateStopwatch implements AutoCloseable {
+        private final Object mLock = new Object();
+        @GuardedBy("mLock")
+        private long mStartTimeMillis;
+        @GuardedBy("mLock")
+        private long mTotalTimeMillis;
+
+        /** Returns the time in state since the last call to {@link TimeInStateStopwatch#reset}. */
+        public long getMillis() {
+            synchronized (mLock) {
+                return mTotalTimeMillis + elapsedTime();
+            }
+        }
+
+        /** Resets the time in state to 0 without stopping the timer if it's started. */
+        public void reset() {
+            synchronized (mLock) {
+                mTotalTimeMillis = 0;
+                mStartTimeMillis = isRunning() ? SystemClock.elapsedRealtime() : 0;
+            }
+        }
+
+        private void start() {
+            synchronized (mLock) {
+                if (!isRunning()) {
+                    mStartTimeMillis = SystemClock.elapsedRealtime();
+                }
+            }
+        }
+
+        private void stop() {
+            synchronized (mLock) {
+                if (isRunning()) {
+                    mTotalTimeMillis += elapsedTime();
+                    mStartTimeMillis = 0;
+                }
+            }
+        }
+
+        private long elapsedTime() {
+            return isRunning() ? SystemClock.elapsedRealtime() - mStartTimeMillis : 0;
+        }
+
+        @VisibleForTesting
+        public boolean isRunning() {
+            return mStartTimeMillis > 0;
+        }
+
+        @Override
+        public void close() {
+            synchronized (mStopwatchesLock) {
+                mOnBatteryStopwatches.remove(this);
+            }
+        }
     }
 }
diff --git a/core/java/com/android/internal/os/LooperStats.java b/core/java/com/android/internal/os/LooperStats.java
index cf2a297..de85c1f 100644
--- a/core/java/com/android/internal/os/LooperStats.java
+++ b/core/java/com/android/internal/os/LooperStats.java
@@ -49,6 +49,7 @@
     private final int mEntriesSizeCap;
     private int mSamplingInterval;
     private CachedDeviceState.Readonly mDeviceState;
+    private CachedDeviceState.TimeInStateStopwatch mBatteryStopwatch;
     private long mStartTime = System.currentTimeMillis();
     private boolean mAddDebugEntries = false;
 
@@ -58,7 +59,12 @@
     }
 
     public void setDeviceState(@NonNull CachedDeviceState.Readonly deviceState) {
+        if (mBatteryStopwatch != null) {
+            mBatteryStopwatch.close();
+        }
+
         mDeviceState = deviceState;
+        mBatteryStopwatch = deviceState.createTimeOnBatteryStopwatch();
     }
 
     public void setAddDebugEntries(boolean addDebugEntries) {
@@ -148,9 +154,11 @@
         maybeAddSpecialEntry(exportedEntries, mOverflowEntry);
         maybeAddSpecialEntry(exportedEntries, mHashCollisionEntry);
         // Debug entries added to help validate the data.
-        if (mAddDebugEntries) {
+        if (mAddDebugEntries && mBatteryStopwatch != null) {
             exportedEntries.add(createDebugEntry("start_time_millis", mStartTime));
             exportedEntries.add(createDebugEntry("end_time_millis", System.currentTimeMillis()));
+            exportedEntries.add(
+                    createDebugEntry("battery_time_millis", mBatteryStopwatch.getMillis()));
         }
         return exportedEntries;
     }
@@ -168,6 +176,10 @@
         return mStartTime;
     }
 
+    public long getBatteryTimeMillis() {
+        return mBatteryStopwatch != null ? mBatteryStopwatch.getMillis() : 0;
+    }
+
     private void maybeAddSpecialEntry(List<ExportedEntry> exportedEntries, Entry specialEntry) {
         synchronized (specialEntry) {
             if (specialEntry.messageCount > 0 || specialEntry.exceptionCount > 0) {
@@ -188,6 +200,9 @@
             mOverflowEntry.reset();
         }
         mStartTime = System.currentTimeMillis();
+        if (mBatteryStopwatch != null) {
+            mBatteryStopwatch.reset();
+        }
     }
 
     public void setSamplingInterval(int samplingInterval) {
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 600b1b3..53b56f2 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -29,7 +29,7 @@
 {
     void setIcon(String slot, in StatusBarIcon icon);
     void removeIcon(String slot);
-    void disable(int state1, int state2);
+    void disable(int displayId, int state1, int state2);
     void animateExpandNotificationsPanel();
     void animateExpandSettingsPanel(String subPanel);
     void animateCollapsePanels();
@@ -38,8 +38,9 @@
     void showWirelessChargingAnimation(int batteryLevel);
 
     /**
-     * Notifies the status bar of a System UI visibility flag change.
+     * Notifies System UI side of a visibility flag change on the specified display.
      *
+     * @param displayId the id of the display to notify
      * @param vis the visibility flags except SYSTEM_UI_FLAG_LIGHT_STATUS_BAR which will be reported
      *            separately in fullscreenStackVis and dockedStackVis
      * @param fullscreenStackVis the flags which only apply in the region of the fullscreen stack,
@@ -50,13 +51,13 @@
      * @param fullscreenBounds the current bounds of the fullscreen stack, in screen coordinates
      * @param dockedBounds the current bounds of the docked stack, in screen coordinates
      */
-    void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis, int mask,
-            in Rect fullscreenBounds, in Rect dockedBounds);
+    void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis, int dockedStackVis,
+            int mask, in Rect fullscreenBounds, in Rect dockedBounds);
 
-    void topAppWindowChanged(boolean menuVisible);
-    void setImeWindowStatus(in IBinder token, int vis, int backDisposition,
+    void topAppWindowChanged(int displayId, boolean menuVisible);
+    void setImeWindowStatus(int displayId, in IBinder token, int vis, int backDisposition,
             boolean showImeSwitcher);
-    void setWindowState(int window, int state);
+    void setWindowState(int display, int window, int state);
 
     void showRecentApps(boolean triggeredFromAltTab);
     void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
@@ -70,30 +71,38 @@
     void toggleKeyboardShortcutsMenu(int deviceId);
 
     /**
-     * Notifies the status bar that an app transition is pending to delay applying some flags with
-     * visual impact until {@link #appTransitionReady} is called.
-     */
-    void appTransitionPending();
-
-    /**
-     * Notifies the status bar that a pending app transition has been cancelled.
-     */
-    void appTransitionCancelled();
-
-    /**
-     * Notifies the status bar that an app transition is now being executed.
+     * Notifies System UI on the specified display that an app transition is pending to delay
+     * applying some flags with visual impact until {@link #appTransitionReady} is called.
      *
+     * @param displayId the id of the display to notify
+     */
+    void appTransitionPending(int displayId);
+
+    /**
+     * Notifies System UI on the specified display that a pending app transition has been cancelled.
+     *
+     * @param displayId the id of the display to notify
+     */
+    void appTransitionCancelled(int displayId);
+
+    /**
+     * Notifies System UI on the specified display that an app transition is now being executed.
+     *
+     * @param displayId the id of the display to notify
      * @param statusBarAnimationsStartTime the desired start time for all visual animations in the
      *        status bar caused by this app transition in uptime millis
      * @param statusBarAnimationsDuration the duration for all visual animations in the status
      *        bar caused by this app transition in millis
      */
-    void appTransitionStarting(long statusBarAnimationsStartTime, long statusBarAnimationsDuration);
+    void appTransitionStarting(int displayId, long statusBarAnimationsStartTime,
+            long statusBarAnimationsDuration);
 
     /**
-     * Notifies the status bar that an app transition is done.
+     * Notifies System UI on the specified display that an app transition is done.
+     *
+     * @param displayId the id of the display to notify
      */
-    void appTransitionFinished();
+    void appTransitionFinished(int displayId);
 
     void showAssistDisclosure();
     void startAssist(in Bundle args);
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index bf82dc61..5118e5f 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -41,6 +41,7 @@
     void setIcon(String slot, String iconPackage, int iconId, int iconLevel, String contentDescription);
     void setIconVisibility(String slot, boolean visible);
     void removeIcon(String slot);
+    // TODO(b/117478341): support back button change when IME is showing on a external display.
     void setImeWindowStatus(in IBinder token, int vis, int backDisposition,
             boolean showImeSwitcher);
     void expandSettingsPanel(String subPanel);
@@ -69,7 +70,7 @@
     void onNotificationSmartRepliesAdded(in String key, in int replyCount);
     void onNotificationSmartReplySent(in String key, in int replyIndex, in CharSequence reply, boolean generatedByAssistant);
     void onNotificationSettingsViewed(String key);
-    void setSystemUiVisibility(int vis, int mask, String cause);
+    void setSystemUiVisibility(int displayId, int vis, int mask, String cause);
 
     void onGlobalActionsShown();
     void onGlobalActionsHidden();
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 4b66267..f669e94 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -32,6 +32,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.function.IntFunction;
 
 /**
  * ArrayUtils contains some methods that you can call to find out
@@ -656,4 +657,30 @@
             throw new ArrayIndexOutOfBoundsException("length=" + len + "; index=" + index);
         }
     }
+
+    /**
+     * Returns an array with values from {@code val} minus {@code null} values
+     *
+     * @param arrayConstructor typically {@code T[]::new} e.g. {@code String[]::new}
+     */
+    public static <T> T[] filterNotNull(T[] val, IntFunction<T[]> arrayConstructor) {
+        int nullCount = 0;
+        int size = size(val);
+        for (int i = 0; i < size; i++) {
+            if (val[i] == null) {
+                nullCount++;
+            }
+        }
+        if (nullCount == 0) {
+            return val;
+        }
+        T[] result = arrayConstructor.apply(size - nullCount);
+        int outIdx = 0;
+        for (int i = 0; i < size; i++) {
+            if (val[i] != null) {
+                result[outIdx++] = val[i];
+            }
+        }
+        return result;
+    }
 }
diff --git a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
index dcb7874..cfe742d 100644
--- a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
+++ b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
@@ -59,7 +59,7 @@
 static void SkiaGetGlyphWidthAndExtents(SkPaint* paint, hb_codepoint_t codepoint, hb_position_t* width, hb_glyph_extents_t* extents)
 {
     ALOG_ASSERT(codepoint <= 0xFFFF);
-    paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    paint->setTextEncoding(kGlyphID_SkTextEncoding);
 
     SkScalar skWidth;
     SkRect skBounds;
@@ -84,7 +84,7 @@
 {
     HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData);
     SkPaint* paint = hbFontData->m_paint;
-    paint->setTextEncoding(SkPaint::kUTF32_TextEncoding);
+    paint->setTextEncoding(kUTF32_SkTextEncoding);
 
     if (unicode > 0x10ffff) {
         unicode = 0xfffd;
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index a8b0640..c249e20 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -71,7 +71,7 @@
 
 static void defaultSettingsForAndroid(Paint* paint) {
     // GlyphID encoding is required because we are using Harfbuzz shaping
-    paint->setTextEncoding(Paint::kGlyphID_TextEncoding);
+    paint->setTextEncoding(kGlyphID_SkTextEncoding);
 }
 
 namespace PaintGlue {
@@ -321,7 +321,7 @@
         x += MinikinUtils::xOffsetForTextAlign(paint, layout);
         Paint::Align align = paint->getTextAlign();
         paint->setTextAlign(Paint::kLeft_Align);
-        paint->setTextEncoding(Paint::kGlyphID_TextEncoding);
+        paint->setTextEncoding(kGlyphID_SkTextEncoding);
         GetTextFunctor f(layout, path, x, y, paint, glyphs, pos);
         MinikinUtils::forFontRun(layout, paint, f);
         paint->setTextAlign(align);
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index d917536..4c1fc5c 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -761,6 +761,13 @@
     }
     optional SmartSelection smart_selection = 108;
 
+    message SmartSuggestions {
+      option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+      optional SettingProto service_explicitly_enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+    }
+    optional SmartSuggestions smart_suggestions = 145;
+
     message Sms {
         option (android.msg_privacy).dest = DEST_EXPLICIT;
 
@@ -869,6 +876,8 @@
         // Temperature at which the high temperature warning notification should
         // be shown.
         optional SettingProto warning_temperature_level = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        // USB temperature at which the high temperature alarm notification should be shown.
+        optional SettingProto usb_alarm_temperature_level = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
     }
     optional TemperatureWarning temperature_warning = 119;
 
@@ -991,5 +1000,5 @@
 
     // Please insert fields in alphabetical order and group them into messages
     // if possible (to avoid reaching the method limit).
-    // Next tag = 145;
+    // Next tag = 146;
 }
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 679a1d2..3767ed5 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -211,7 +211,7 @@
     repeated AppWindowTokenProto app_window_tokens = 3;
     optional bool fills_parent = 4;
     optional .android.graphics.RectProto bounds = 5;
-    optional .android.graphics.RectProto temp_inset_bounds = 6;
+    optional .android.graphics.RectProto displayed_bounds = 6;
     optional bool defer_removal = 7;
     optional int32 surface_width = 8;
     optional int32 surface_height = 9;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 83f3057..3018614 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3387,6 +3387,13 @@
     <permission android:name="android.permission.CONTROL_DISPLAY_SATURATION"
         android:protectionLevel="signature|privileged" />
 
+    <!-- Allows an application to control display color transformations.
+         <p>Not for use by third-party applications.</p>
+         @hide
+         @SystemApi -->
+    <permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS"
+        android:protectionLevel="signature|privileged" />
+
     <!-- Allows an application to collect usage infomation about brightness slider changes.
          <p>Not for use by third-party applications.</p>
          @hide
@@ -4170,6 +4177,11 @@
     <permission android:name="android.permission.MANAGE_AUTO_FILL"
         android:protectionLevel="signature" />
 
+    <!-- @SystemApi Allows an application to manage the smart suggestions service.
+         @hide  <p>Not for use by third-party applications.</p> -->
+    <permission android:name="android.permission.MANAGE_SMART_SUGGESTIONS"
+        android:protectionLevel="signature" />
+
     <!-- Allows an app to set the theme overlay in /vendor/overlay
          being used.
          @hide  <p>Not for use by third-party applications.</p> -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 0cd6bc5..c62071b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3350,6 +3350,14 @@
     -->
     <string name="config_defaultTextClassifierPackage" translatable="false"></string>
 
+    <!-- The package name for the system's smart suggestion service.
+         This service must be trusted, as it can be activated without explicit consent of the user.
+         If no service with the specified name exists on the device, content capture and
+         smart suggestions will be disabled.
+         Example: "com.android.intelligence/.SmartSuggestionsService"
+    -->
+    <string name="config_defaultSmartSuggestionsService" translatable="false"></string>
+
     <!-- Whether the device uses the default focus highlight when focus state isn't specified. -->
     <bool name="config_useDefaultFocusHighlight">true</bool>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 01422c8..6854a84e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3265,6 +3265,7 @@
   <java-symbol type="string" name="notification_channel_do_not_disturb" />
   <java-symbol type="string" name="config_defaultAutofillService" />
   <java-symbol type="string" name="config_defaultTextClassifierPackage" />
+  <java-symbol type="string" name="config_defaultSmartSuggestionsService" />
 
   <java-symbol type="string" name="notification_channel_foreground_service" />
   <java-symbol type="string" name="foreground_service_app_in_background" />
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index a8f9e8a..ed9c3d5 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -415,6 +415,7 @@
                     Settings.Global.SHOW_TEMPERATURE_WARNING,
                     Settings.Global.SMART_SELECTION_UPDATE_CONTENT_URL,
                     Settings.Global.SMART_SELECTION_UPDATE_METADATA_URL,
+                    Settings.Global.SMART_SUGGESTIONS_SERVICE_EXPLICITLY_ENABLED,
                     Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED,
                     Settings.Global.SMS_OUTGOING_CHECK_INTERVAL_MS,
                     Settings.Global.SMS_OUTGOING_CHECK_MAX_COUNT,
@@ -477,6 +478,7 @@
                     Settings.Global.USER_SWITCHER_ENABLED,
                     Settings.Global.NETWORK_ACCESS_TIMEOUT_MS,
                     Settings.Global.WARNING_TEMPERATURE,
+                    Settings.Global.USB_ALARM_TEMPERATURE,
                     Settings.Global.WEBVIEW_DATA_REDUCTION_PROXY_KEY,
                     Settings.Global.WEBVIEW_FALLBACK_LOGIC_ENABLED,
                     Settings.Global.WEBVIEW_MULTIPROCESS,
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index 8691e73..02a76f8 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -17,6 +17,7 @@
 package com.android.internal.os;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.os.Binder;
 import android.platform.test.annotations.Presubmit;
@@ -387,8 +388,7 @@
 
     @Test
     public void testNoDataCollectedBeforeInitialDeviceStateSet() {
-        TestBinderCallsStats bcs = new TestBinderCallsStats();
-        bcs.setDeviceState(null);
+        TestBinderCallsStats bcs = new TestBinderCallsStats(null);
         bcs.setDetailedTracking(true);
         Binder binder = new Binder();
         CallSession callSession = bcs.callStarted(binder, 1);
@@ -613,6 +613,27 @@
         assertEquals(CALLING_UID, callStats.callingUid);
     }
 
+    @Test
+    public void testAddsDebugEntries() {
+        long startTime = System.currentTimeMillis();
+        TestBinderCallsStats bcs = new TestBinderCallsStats();
+        bcs.setAddDebugEntries(true);
+        ArrayList<BinderCallsStats.ExportedCallStat> callStats = bcs.getExportedCallStats();
+        assertEquals(3, callStats.size());
+        BinderCallsStats.ExportedCallStat debugEntry1 = callStats.get(0);
+        assertEquals("", debugEntry1.className);
+        assertEquals("__DEBUG_start_time_millis", debugEntry1.methodName);
+        assertTrue(startTime <= debugEntry1.maxReplySizeBytes);
+        BinderCallsStats.ExportedCallStat debugEntry2 = callStats.get(1);
+        assertEquals("", debugEntry2.className);
+        assertEquals("__DEBUG_end_time_millis", debugEntry2.methodName);
+        assertTrue(debugEntry1.maxReplySizeBytes <= debugEntry2.maxReplySizeBytes);
+        BinderCallsStats.ExportedCallStat debugEntry3 = callStats.get(2);
+        assertEquals("", debugEntry3.className);
+        assertEquals("__DEBUG_battery_time_millis", debugEntry3.methodName);
+        assertTrue(debugEntry3.maxReplySizeBytes >= 0);
+    }
+
     class TestBinderCallsStats extends BinderCallsStats {
         public int callingUid = CALLING_UID;
         public int workSourceUid = WORKSOURCE_UID;
@@ -620,6 +641,10 @@
         public long elapsedTime = 0;
 
         TestBinderCallsStats() {
+            this(mDeviceState);
+        }
+
+        TestBinderCallsStats(CachedDeviceState deviceState) {
             // Make random generator not random.
             super(new Injector() {
                 public Random getRandomGenerator() {
@@ -633,7 +658,10 @@
                 }
             });
             setSamplingInterval(1);
-            setDeviceState(mDeviceState.getReadonlyClient());
+            setAddDebugEntries(false);
+            if (deviceState != null) {
+                setDeviceState(deviceState.getReadonlyClient());
+            }
         }
 
         @Override
diff --git a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
index 31dde5c..3d7801c 100644
--- a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
@@ -273,8 +273,7 @@
 
     @Test
     public void testDataNotCollectedBeforeDeviceStateSet() {
-        TestableLooperStats looperStats = new TestableLooperStats(1, 100);
-        looperStats.setDeviceState(null);
+        TestableLooperStats looperStats = new TestableLooperStats(1, 100, null);
 
         Object token1 = looperStats.messageDispatchStarting();
         looperStats.messageDispatched(token1, mHandlerFirst.obtainMessage(1000));
@@ -439,7 +438,7 @@
         looperStats.messageDispatched(token, message);
 
         List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
-        assertThat(entries).hasSize(3);
+        assertThat(entries).hasSize(4);
         LooperStats.ExportedEntry debugEntry1 = entries.get(1);
         assertThat(debugEntry1.handlerClassName).isEqualTo("");
         assertThat(debugEntry1.messageName).isEqualTo("__DEBUG_start_time_millis");
@@ -448,6 +447,10 @@
         assertThat(debugEntry2.handlerClassName).isEqualTo("");
         assertThat(debugEntry2.messageName).isEqualTo("__DEBUG_end_time_millis");
         assertThat(debugEntry2.maxDelayMillis).isAtLeast(looperStats.getStartTimeMillis());
+        LooperStats.ExportedEntry debugEntry3 = entries.get(3);
+        assertThat(debugEntry3.handlerClassName).isEqualTo("");
+        assertThat(debugEntry3.messageName).isEqualTo("__DEBUG_battery_time_millis");
+        assertThat(debugEntry3.maxDelayMillis).isAtLeast(0L);
     }
 
     private static void assertThrows(Class<? extends Exception> exceptionClass, Runnable r) {
@@ -468,10 +471,16 @@
         private int mSamplingInterval;
 
         TestableLooperStats(int samplingInterval, int sizeCap) {
+            this(samplingInterval, sizeCap, mDeviceState);
+        }
+
+        TestableLooperStats(int samplingInterval, int sizeCap, CachedDeviceState deviceState) {
             super(samplingInterval, sizeCap);
-            this.mSamplingInterval = samplingInterval;
-            this.setDeviceState(mDeviceState.getReadonlyClient());
-            this.setAddDebugEntries(false);
+            mSamplingInterval = samplingInterval;
+            setAddDebugEntries(false);
+            if (deviceState != null) {
+                setDeviceState(deviceState.getReadonlyClient());
+            }
         }
 
         void tickRealtime(long micros) {
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 9e4ea32..f237344 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -281,6 +281,7 @@
         <permission name="android.permission.WRITE_APN_SETTINGS"/>
         <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
         <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+        <permission name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
     </privapp-permissions>
 
     <privapp-permissions package="com.android.settings.intelligence">
@@ -408,6 +409,7 @@
         <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
         <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
         <permission name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
+        <permission name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
     </privapp-permissions>
 
     <privapp-permissions package="com.android.tv">
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index dea2f45..cb12a7c 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
+import android.app.ActivityThread;
 import android.content.pm.ActivityInfo.Config;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -150,11 +151,14 @@
      */
     AdaptiveIconDrawable(@Nullable LayerState state, @Nullable Resources res) {
         mLayerState = createConstantState(state, res);
-
-        if (sMask == null) {
-            sMask = PathParser.createPathFromPathData(
-                Resources.getSystem().getString(R.string.config_icon_mask));
-        }
+        // config_icon_mask from context bound resource may have been chaged using
+        // OverlayManager. Read that one first.
+        Resources r = ActivityThread.currentActivityThread() == null
+                ? Resources.getSystem()
+                : ActivityThread.currentActivityThread().getApplication().getResources();
+        // TODO: either make sMask update only when config_icon_mask changes OR
+        // get rid of it all-together in layoutlib
+        sMask = PathParser.createPathFromPathData(r.getString(R.string.config_icon_mask));
         mMask = new Path(sMask);
         mMaskScaleOnly = new Path(mMask);
         mMaskMatrix = new Matrix();
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index 68d216d..c20c720 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -583,7 +583,65 @@
           loaded_package->dynamic_package_map_.emplace_back(std::move(package_name),
                                                             dtohl(entry_iter->packageId));
         }
+      } break;
 
+      case RES_TABLE_OVERLAYABLE_TYPE: {
+        const ResTable_overlayable_header* header =
+            child_chunk.header<ResTable_overlayable_header>();
+        if (header == nullptr) {
+          LOG(ERROR) << "RES_TABLE_OVERLAYABLE_TYPE too small.";
+          return {};
+        }
+
+        // Iterate over the overlayable policy chunks
+        ChunkIterator overlayable_iter(child_chunk.data_ptr(), child_chunk.data_size());
+        while (overlayable_iter.HasNext()) {
+          const Chunk overlayable_child_chunk = overlayable_iter.Next();
+
+          switch (overlayable_child_chunk.type()) {
+            case RES_TABLE_OVERLAYABLE_POLICY_TYPE: {
+              const ResTable_overlayable_policy_header* policy_header =
+                  overlayable_child_chunk.header<ResTable_overlayable_policy_header>();
+              if (policy_header == nullptr) {
+                LOG(ERROR) << "RES_TABLE_OVERLAYABLE_POLICY_TYPE too small.";
+                return {};
+              }
+
+              if ((overlayable_child_chunk.data_size() / sizeof(ResTable_ref))
+                  < dtohl(policy_header->entry_count)) {
+                LOG(ERROR) <<  "RES_TABLE_OVERLAYABLE_POLICY_TYPE too small to hold entries.";
+                return {};
+              }
+
+              // Retrieve all the ids belonging to this policy
+              std::unordered_set<uint32_t> ids;
+              const auto ids_begin =
+                  reinterpret_cast<const ResTable_ref*>(overlayable_child_chunk.data_ptr());
+              const auto ids_end = ids_begin + dtohl(policy_header->entry_count);
+              for (auto id_iter = ids_begin; id_iter != ids_end; ++id_iter) {
+                ids.insert(dtohl(id_iter->ident));
+              }
+
+              // Add the pairing of overlayable properties to resource ids to the package
+              OverlayableInfo overlayable_info;
+              overlayable_info.policy_flags = policy_header->policy_flags;
+              loaded_package->overlayable_infos_.push_back(std::make_pair(overlayable_info, ids));
+              break;
+            }
+
+            default:
+              LOG(WARNING) << StringPrintf("Unknown chunk type '%02x'.", chunk.type());
+              break;
+          }
+        }
+
+        if (overlayable_iter.HadError()) {
+          LOG(ERROR) << StringPrintf("Error parsing RES_TABLE_OVERLAYABLE_POLICY_TYPE: %s",
+                                     overlayable_iter.GetLastError().c_str());
+          if (overlayable_iter.HadFatalError()) {
+            return {};
+          }
+        }
       } break;
 
       default:
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 2fe98b0..63b2527 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -7076,7 +7076,7 @@
         }
     }
 
-    const auto& getTypeMapping() const {
+    const std::map<uint8_t, std::set<std::pair<uint32_t, uint32_t>>>& getTypeMapping() const {
         return mTypeMapping->mData;
     }
 
@@ -7137,9 +7137,6 @@
 
     const PackageGroup* packageGroup = mPackageGroups[0];
 
-    // the number of resources overlaid that were not explicitly marked overlayable
-    size_t forcedOverlayCount = 0u;
-
     // find the resources that exist in both packages
     auto typeMapping = std::make_unique<IdmapTypeMapping>();
     for (size_t typeIndex = 0; typeIndex < packageGroup->types.size(); ++typeIndex) {
@@ -7170,11 +7167,6 @@
                 continue;
             }
 
-            if ((dtohl(typeConfigs->typeSpecFlags[entryIndex]) &
-                    ResTable_typeSpec::SPEC_OVERLAYABLE) == 0) {
-                ++forcedOverlayCount;
-            }
-
             typeMapping->add(target_resid, overlay_resid);
         }
     }
@@ -7243,10 +7235,6 @@
         typeData += entryCount * 2;
     }
 
-    if (forcedOverlayCount > 0) {
-        ALOGW("idmap: overlaid %zu resources not marked overlayable", forcedOverlayCount);
-    }
-
     return NO_ERROR;
 }
 
diff --git a/libs/androidfw/include/androidfw/Chunk.h b/libs/androidfw/include/androidfw/Chunk.h
index 99a52dc..a0f2343 100644
--- a/libs/androidfw/include/androidfw/Chunk.h
+++ b/libs/androidfw/include/androidfw/Chunk.h
@@ -89,7 +89,9 @@
         len_(len),
         last_error_(nullptr) {
     CHECK(next_chunk_ != nullptr) << "data can't be nullptr";
-    VerifyNextChunk();
+    if (len_ != 0) {
+      VerifyNextChunk();
+    }
   }
 
   Chunk Next();
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index 349b379..8c5c3b7 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -20,6 +20,7 @@
 #include <memory>
 #include <set>
 #include <vector>
+#include <unordered_set>
 
 #include "android-base/macros.h"
 
@@ -76,6 +77,10 @@
 // TypeSpecPtr is a managed pointer that knows how to delete itself.
 using TypeSpecPtr = util::unique_cptr<TypeSpec>;
 
+struct OverlayableInfo {
+  uint32_t policy_flags;
+};
+
 class LoadedPackage {
  public:
   class iterator {
@@ -216,6 +221,18 @@
     }
   }
 
+  // Retrieve the overlayable properties of the specified resource. If the resource is not
+  // overlayable, this will return a null pointer.
+  const OverlayableInfo* GetOverlayableInfo(uint32_t resid) const {
+    for (const std::pair<OverlayableInfo, std::unordered_set<uint32_t>>& overlayable_info_ids
+        : overlayable_infos_) {
+      if (overlayable_info_ids.second.find(resid) != overlayable_info_ids.second.end()) {
+        return &overlayable_info_ids.first;
+      }
+    }
+    return nullptr;
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(LoadedPackage);
 
@@ -233,6 +250,7 @@
   ByteBucketArray<TypeSpecPtr> type_specs_;
   ByteBucketArray<uint32_t> resource_ids_;
   std::vector<DynamicPackageEntry> dynamic_package_map_;
+  std::vector<const std::pair<OverlayableInfo, std::unordered_set<uint32_t>>> overlayable_infos_;
 };
 
 // Read-only view into a resource table. This class validates all data
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index ad33fcf..91261aa 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -234,7 +234,9 @@
     RES_TABLE_PACKAGE_TYPE      = 0x0200,
     RES_TABLE_TYPE_TYPE         = 0x0201,
     RES_TABLE_TYPE_SPEC_TYPE    = 0x0202,
-    RES_TABLE_LIBRARY_TYPE      = 0x0203
+    RES_TABLE_LIBRARY_TYPE      = 0x0203,
+    RES_TABLE_OVERLAYABLE_TYPE  = 0x0204,
+    RES_TABLE_OVERLAYABLE_POLICY_TYPE = 0x0205,
 };
 
 /**
@@ -1354,10 +1356,6 @@
     enum : uint32_t {
         // Additional flag indicating an entry is public.
         SPEC_PUBLIC = 0x40000000u,
-
-        // Additional flag indicating an entry is overlayable at runtime.
-        // Added in Android-P.
-        SPEC_OVERLAYABLE = 0x80000000u,
     };
 };
 
@@ -1607,6 +1605,49 @@
     uint16_t packageName[128];
 };
 
+/**
+ * Specifies the set of resources that are explicitly allowed to be overlaid by RROs.
+ */
+struct ResTable_overlayable_header
+{
+  struct ResChunk_header header;
+};
+
+/**
+ * Holds a list of resource ids that are protected from being overlaid by a set of policies. If
+ * the overlay fulfils at least one of the policies, then the overlay can overlay the list of
+ * resources.
+ */
+struct ResTable_overlayable_policy_header
+{
+  struct ResChunk_header header;
+
+  enum PolicyFlags {
+    // Any overlay can overlay these resources.
+    POLICY_PUBLIC = 0x00000001,
+
+    // The overlay must reside of the system partition or must have existed on the system partition
+    // before an upgrade to overlay these resources.
+    POLICY_SYSTEM_PARTITION = 0x00000002,
+
+    // The overlay must reside of the vendor partition or must have existed on the vendor partition
+    // before an upgrade to overlay these resources.
+    POLICY_VENDOR_PARTITION = 0x00000004,
+
+    // The overlay must reside of the product partition or must have existed on the product
+    // partition before an upgrade to overlay these resources.
+    POLICY_PRODUCT_PARTITION = 0x00000008,
+
+    // The overlay must reside of the product services partition or must have existed on the product
+    // services partition before an upgrade to overlay these resources.
+    POLICY_PRODUCT_SERVICES_PARTITION = 0x00000010,
+  };
+  uint32_t policy_flags;
+
+  // The number of ResTable_ref that follow this header.
+  uint32_t entry_count;
+};
+
 struct alignas(uint32_t) Idmap_header {
   // Always 0x504D4449 ('IDMP')
   uint32_t magic;
diff --git a/libs/androidfw/tests/LoadedArsc_test.cpp b/libs/androidfw/tests/LoadedArsc_test.cpp
index ffa4836..441356b 100644
--- a/libs/androidfw/tests/LoadedArsc_test.cpp
+++ b/libs/androidfw/tests/LoadedArsc_test.cpp
@@ -22,12 +22,14 @@
 #include "TestHelpers.h"
 #include "data/basic/R.h"
 #include "data/libclient/R.h"
+#include "data/overlayable/R.h"
 #include "data/sparse/R.h"
 #include "data/styles/R.h"
 
 namespace app = com::android::app;
 namespace basic = com::android::basic;
 namespace libclient = com::android::libclient;
+namespace overlayable = com::android::overlayable;
 namespace sparse = com::android::sparse;
 
 using ::android::base::ReadFileToString;
@@ -273,10 +275,44 @@
   ASSERT_THAT(LoadedPackage::GetEntry(type_spec->types[0], 0x0000), NotNull());
 }
 
-// structs with size fields (like Res_value, ResTable_entry) should be
-// backwards and forwards compatible (aka checking the size field against
-// sizeof(Res_value) might not be backwards compatible.
-TEST(LoadedArscTest, LoadingShouldBeForwardsAndBackwardsCompatible) { ASSERT_TRUE(false); }
+TEST(LoadedArscTest, LoadOverlayable) {
+  std::string contents;
+  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/overlayable/overlayable.apk",
+                                      "resources.arsc", &contents));
+
+  std::unique_ptr<const LoadedArsc> loaded_arsc =
+      LoadedArsc::Load(StringPiece(contents), nullptr /*loaded_idmap*/, false /*system*/,
+                       false /*load_as_shared_library*/);
+
+  ASSERT_THAT(loaded_arsc, NotNull());
+  const LoadedPackage* package = loaded_arsc->GetPackageById(
+      get_package_id(overlayable::R::string::not_overlayable));
+
+  const OverlayableInfo* info = package->GetOverlayableInfo(
+      overlayable::R::string::not_overlayable);
+  ASSERT_THAT(info, IsNull());
+
+  info = package->GetOverlayableInfo(overlayable::R::string::overlayable1);
+  ASSERT_THAT(info, NotNull());
+  EXPECT_THAT(info->policy_flags, Eq(ResTable_overlayable_policy_header::POLICY_PUBLIC));
+
+  info = package->GetOverlayableInfo(overlayable::R::string::overlayable2);
+  ASSERT_THAT(info, NotNull());
+  EXPECT_THAT(info->policy_flags,
+              Eq(ResTable_overlayable_policy_header::POLICY_SYSTEM_PARTITION
+                 | ResTable_overlayable_policy_header::POLICY_PRODUCT_PARTITION));
+
+  info = package->GetOverlayableInfo(overlayable::R::string::overlayable3);
+  ASSERT_THAT(info, NotNull());
+  EXPECT_THAT(info->policy_flags,
+              Eq(ResTable_overlayable_policy_header::POLICY_VENDOR_PARTITION
+                 | ResTable_overlayable_policy_header::POLICY_PRODUCT_SERVICES_PARTITION
+                 | ResTable_overlayable_policy_header::POLICY_PRODUCT_PARTITION));
+
+  info = package->GetOverlayableInfo(overlayable::R::string::overlayable4);
+  ASSERT_THAT(info, NotNull());
+  EXPECT_THAT(info->policy_flags, Eq(ResTable_overlayable_policy_header::POLICY_PUBLIC));
+}
 
 TEST(LoadedArscTest, ResourceIdentifierIterator) {
   std::string contents;
@@ -326,4 +362,9 @@
   ASSERT_EQ(end, iter);
 }
 
+// structs with size fields (like Res_value, ResTable_entry) should be
+// backwards and forwards compatible (aka checking the size field against
+// sizeof(Res_value) might not be backwards compatible.
+TEST(LoadedArscTest, LoadingShouldBeForwardsAndBackwardsCompatible) { ASSERT_TRUE(false); }
+
 }  // namespace android
diff --git a/libs/androidfw/tests/data/overlay/overlay.apk b/libs/androidfw/tests/data/overlay/overlay.apk
index 33f9611..d37874d 100644
--- a/libs/androidfw/tests/data/overlay/overlay.apk
+++ b/libs/androidfw/tests/data/overlay/overlay.apk
Binary files differ
diff --git a/packages/SystemUI/res/anim/car_user_switcher_close_name_animation.xml b/libs/androidfw/tests/data/overlayable/AndroidManifest.xml
similarity index 64%
copy from packages/SystemUI/res/anim/car_user_switcher_close_name_animation.xml
copy to libs/androidfw/tests/data/overlayable/AndroidManifest.xml
index 5901ff4..abc2a45 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_close_name_animation.xml
+++ b/libs/androidfw/tests/data/overlayable/AndroidManifest.xml
@@ -1,4 +1,5 @@
-<!-- Copyright (C) 2017 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -12,12 +13,9 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<set xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <objectAnimator
-        android:duration="83"
-        android:propertyName="alpha"
-        android:valueType="floatType"
-        android:valueFrom="0"
-        android:valueTo="1" />
-</set>
\ No newline at end of file
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.overlayable">
+    <application>
+    </application>
+</manifest>
diff --git a/libs/androidfw/tests/data/overlayable/R.h b/libs/androidfw/tests/data/overlayable/R.h
new file mode 100644
index 0000000..e46e264d
--- /dev/null
+++ b/libs/androidfw/tests/data/overlayable/R.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TESTS_DATA_OVERLAYABLE_R_H_
+#define TESTS_DATA_OVERLAYABLE_R_H_
+
+#include <cstdint>
+
+namespace com {
+namespace android {
+namespace overlayable {
+
+struct R {
+  struct string {
+    enum : uint32_t {
+      not_overlayable = 0x7f010000,
+      overlayable1 = 0x7f010001,
+      overlayable2 = 0x7f010002,
+      overlayable3 = 0x7f010003,
+      overlayable4 = 0x7f010004,
+    };
+  };
+};
+
+}  // namespace overlayable
+}  // namespace android
+}  // namespace com
+
+#endif /* TESTS_DATA_OVERLAYABLE_R_H_ */
diff --git a/libs/androidfw/tests/data/overlayable/build b/libs/androidfw/tests/data/overlayable/build
new file mode 100755
index 0000000..98fdc51
--- /dev/null
+++ b/libs/androidfw/tests/data/overlayable/build
@@ -0,0 +1,22 @@
+#!/bin/bash
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+set -e
+
+aapt2 compile --dir res -o compiled.flata
+aapt2 link --manifest AndroidManifest.xml -o overlayable.apk compiled.flata
+rm compiled.flata
diff --git a/libs/androidfw/tests/data/overlayable/overlayable.apk b/libs/androidfw/tests/data/overlayable/overlayable.apk
new file mode 100644
index 0000000..85ab4be
--- /dev/null
+++ b/libs/androidfw/tests/data/overlayable/overlayable.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/overlayable/res/values/overlayable.xml b/libs/androidfw/tests/data/overlayable/res/values/overlayable.xml
new file mode 100644
index 0000000..11aa735
--- /dev/null
+++ b/libs/androidfw/tests/data/overlayable/res/values/overlayable.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+<overlayable>
+    <!-- Any overlay can overlay the value of @string/overlayable1 -->
+    <item type="string" name="overlayable1" />
+
+    <!-- Any overlay on the product or system partition can overlay the value of
+        @string/overlayable2 -->
+    <policy type="product|system">
+        <item type="string" name="overlayable2" />
+    </policy>
+
+    <!-- Any overlay can overlay the value of @string/overlayable4 -->
+    <policy type="public">
+        <item type="string" name="overlayable4" />
+    </policy>
+</overlayable>
+
+<overlayable>
+    <!-- Any overlay on the product_services, vendor, or product partition can overlay the value of
+   @string/overlayable3 -->
+    <policy type="product_services|vendor|product">
+        <item type="string" name="overlayable3" />
+    </policy>
+</overlayable>
+</resources>
\ No newline at end of file
diff --git a/libs/androidfw/tests/data/overlayable/res/values/public.xml b/libs/androidfw/tests/data/overlayable/res/values/public.xml
new file mode 100644
index 0000000..5676d7c
--- /dev/null
+++ b/libs/androidfw/tests/data/overlayable/res/values/public.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <public type="string" name="not_overlayable" id="0x7f010000" />
+    <public type="string" name="overlayable1" id="0x7f010001" />
+    <public type="string" name="overlayable2" id="0x7f010002" />
+    <public type="string" name="overlayable3" id="0x7f010003" />
+    <public type="string" name="overlayable4" id="0x7f010004" />
+</resources>
\ No newline at end of file
diff --git a/libs/androidfw/tests/data/overlayable/res/values/values.xml b/libs/androidfw/tests/data/overlayable/res/values/values.xml
new file mode 100644
index 0000000..a86b312
--- /dev/null
+++ b/libs/androidfw/tests/data/overlayable/res/values/values.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <string name="not_overlayable">Not overlayable</string>
+    <string name="overlayable1">Overlayable One</string>
+    <string name="overlayable2">Overlayable Two</string>
+    <string name="overlayable3">Overlayable Three</string>
+    <string name="overlayable4">Overlayable Four</string>
+</resources>
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 4a3e10c..8067313 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -29,8 +29,6 @@
 namespace android {
 namespace uirenderer {
 
-bool Properties::drawDeferDisabled = false;
-bool Properties::drawReorderDisabled = false;
 bool Properties::debugLayersUpdates = false;
 bool Properties::debugOverdraw = false;
 bool Properties::showDirtyRegions = false;
@@ -40,7 +38,6 @@
 
 DebugLevel Properties::debugLevel = kDebugDisabled;
 OverdrawColorSet Properties::overdrawColorSet = OverdrawColorSet::Default;
-StencilClipDebug Properties::debugStencilClip = StencilClipDebug::Hide;
 
 float Properties::overrideLightRadius = -1.0f;
 float Properties::overrideLightPosY = -1.0f;
@@ -85,7 +82,6 @@
     char property[PROPERTY_VALUE_MAX];
     bool prevDebugLayersUpdates = debugLayersUpdates;
     bool prevDebugOverdraw = debugOverdraw;
-    StencilClipDebug prevDebugStencilClip = debugStencilClip;
 
     debugOverdraw = false;
     if (property_get(PROPERTY_DEBUG_OVERDRAW, property, nullptr) > 0) {
@@ -99,20 +95,6 @@
         }
     }
 
-    // See Properties.h for valid values
-    if (property_get(PROPERTY_DEBUG_STENCIL_CLIP, property, nullptr) > 0) {
-        INIT_LOGD("  Stencil clip debug enabled: %s", property);
-        if (!strcmp(property, "hide")) {
-            debugStencilClip = StencilClipDebug::Hide;
-        } else if (!strcmp(property, "highlight")) {
-            debugStencilClip = StencilClipDebug::ShowHighlight;
-        } else if (!strcmp(property, "region")) {
-            debugStencilClip = StencilClipDebug::ShowRegion;
-        }
-    } else {
-        debugStencilClip = StencilClipDebug::Hide;
-    }
-
     sProfileType = ProfileType::None;
     if (property_get(PROPERTY_PROFILE, property, "") > 0) {
         if (!strcmp(property, PROPERTY_PROFILE_VISUALIZE_BARS)) {
@@ -125,12 +107,6 @@
     debugLayersUpdates = property_get_bool(PROPERTY_DEBUG_LAYERS_UPDATES, false);
     INIT_LOGD("  Layers updates debug enabled: %d", debugLayersUpdates);
 
-    drawDeferDisabled = property_get_bool(PROPERTY_DISABLE_DRAW_DEFER, false);
-    INIT_LOGD("  Draw defer %s", drawDeferDisabled ? "disabled" : "enabled");
-
-    drawReorderDisabled = property_get_bool(PROPERTY_DISABLE_DRAW_REORDER, false);
-    INIT_LOGD("  Draw reorder %s", drawReorderDisabled ? "disabled" : "enabled");
-
     showDirtyRegions = property_get_bool(PROPERTY_DEBUG_SHOW_DIRTY_REGIONS, false);
 
     debugLevel = (DebugLevel)property_get_int(PROPERTY_DEBUG, kDebugDisabled);
@@ -152,8 +128,7 @@
 
     enableForceDarkSupport = property_get_bool(PROPERTY_ENABLE_FORCE_DARK, true);
 
-    return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw) ||
-           (prevDebugStencilClip != debugStencilClip);
+    return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw);
 }
 
 void Properties::overrideProperty(const char* name, const char* value) {
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index da53f66..0a7f4e7 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -95,20 +95,6 @@
 #define PROPERTY_PROFILE_VISUALIZE_BARS "visual_bars"
 
 /**
- * Used to enable/disable non-rectangular clipping debugging.
- *
- * The accepted values are:
- * "highlight", drawing commands clipped by the stencil will
- *              be colored differently
- * "region", renders the clipping region on screen whenever
- *           the stencil is set
- * "hide", don't show the clip
- *
- * The default value is "hide".
- */
-#define PROPERTY_DEBUG_STENCIL_CLIP "debug.hwui.show_non_rect_clip"
-
-/**
  * Turn on to draw dirty regions every other frame.
  *
  * Possible values:
@@ -118,19 +104,6 @@
 #define PROPERTY_DEBUG_SHOW_DIRTY_REGIONS "debug.hwui.show_dirty_regions"
 
 /**
- * Disables draw operation deferral if set to "true", forcing draw
- * commands to be issued to OpenGL in order, and processed in sequence
- * with state-manipulation canvas commands.
- */
-#define PROPERTY_DISABLE_DRAW_DEFER "debug.hwui.disable_draw_defer"
-
-/**
- * Used to disable draw operation reordering when deferring draw operations
- * Has no effect if PROPERTY_DISABLE_DRAW_DEFER is set to "true"
- */
-#define PROPERTY_DISABLE_DRAW_REORDER "debug.hwui.disable_draw_reorder"
-
-/**
  * Setting this property will enable or disable the dropping of frames with
  * empty damage. Default is "true".
  */
@@ -207,8 +180,6 @@
 
 enum class OverdrawColorSet { Default = 0, Deuteranomaly };
 
-enum class StencilClipDebug { Hide, ShowHighlight, ShowRegion };
-
 enum class RenderPipelineType { SkiaGL, SkiaVulkan, NotInitialized = 128 };
 
 /**
@@ -220,8 +191,6 @@
 public:
     static bool load();
 
-    static bool drawDeferDisabled;
-    static bool drawReorderDisabled;
     static bool debugLayersUpdates;
     static bool debugOverdraw;
     static bool showDirtyRegions;
@@ -235,7 +204,6 @@
 
     static DebugLevel debugLevel;
     static OverdrawColorSet overdrawColorSet;
-    static StencilClipDebug debugStencilClip;
 
     // Override the value for a subset of properties in this class
     static void overrideProperty(const char* name, const char* value);
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index ba34384..6be7ef7 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -681,7 +681,7 @@
     if (mPaintFilter) {
         mPaintFilter->filter(&paintCopy);
     }
-    SkASSERT(paintCopy.getTextEncoding() == SkPaint::kGlyphID_TextEncoding);
+    SkASSERT(paintCopy.getTextEncoding() == kGlyphID_SkTextEncoding);
     // Stroke with a hairline is drawn on HW with a fill style for compatibility with Android O and
     // older.
     if (!mCanvasOwned && sApiLevel <= 27 && paintCopy.getStrokeWidth() <= 0 &&
@@ -708,7 +708,7 @@
     if (mPaintFilter) {
         mPaintFilter->filter(&paintCopy);
     }
-    SkASSERT(paintCopy.getTextEncoding() == SkPaint::kGlyphID_TextEncoding);
+    SkASSERT(paintCopy.getTextEncoding() == kGlyphID_SkTextEncoding);
 
     const int N = end - start;
     SkAutoSTMalloc<1024, uint8_t> storage(N * (sizeof(uint16_t) + sizeof(SkRSXform)));
diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp
index 769fce4..84292c8 100644
--- a/libs/hwui/hwui/MinikinSkia.cpp
+++ b/libs/hwui/hwui/MinikinSkia.cpp
@@ -43,7 +43,7 @@
 static void MinikinFontSkia_SetSkiaPaint(const minikin::MinikinFont* font, SkPaint* skPaint,
                                          const minikin::MinikinPaint& paint,
                                          const minikin::FontFakery& fakery) {
-    skPaint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    skPaint->setTextEncoding(kGlyphID_SkTextEncoding);
     skPaint->setTextSize(paint.size);
     skPaint->setTextScaleX(paint.scaleX);
     skPaint->setTextSkewX(paint.skewX);
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index e1f8307..2abb3d5 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -745,7 +745,7 @@
     surface->mWindowWidth = extent.width;
     surface->mWindowHeight = extent.height;
 
-    uint32_t imageCount = caps.minImageCount + 2;
+    uint32_t imageCount = std::max<uint32_t>(3, caps.minImageCount);
     if (caps.maxImageCount > 0 && imageCount > caps.maxImageCount) {
         // Application must settle for fewer images than desired:
         imageCount = caps.maxImageCount;
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 8a1bc4d..f812022 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -81,7 +81,7 @@
     auto utf16 = asciiToUtf16(text);
     uint32_t length = strlen(text);
     SkPaint glyphPaint(paint);
-    glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    glyphPaint.setTextEncoding(kGlyphID_SkTextEncoding);
     canvas->drawText(
             utf16.get(), length,  // text buffer
             0, length,  // draw range
@@ -94,7 +94,7 @@
                                  const SkPath& path) {
     auto utf16 = asciiToUtf16(text);
     SkPaint glyphPaint(paint);
-    glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    glyphPaint.setTextEncoding(kGlyphID_SkTextEncoding);
     canvas->drawTextOnPath(utf16.get(), strlen(text), minikin::Bidi::LTR, path, 0, 0, glyphPaint,
             nullptr);
 }
diff --git a/media/OWNERS b/media/OWNERS
index 0abf9ae..03b751c 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -1,12 +1,13 @@
+chz@google.com
+dwkang@google.com
 elaurent@google.com
 etalvala@google.com
 gkasten@google.com
 hunga@google.com
+jaewan@google.com
 jmtrivi@google.com
+jsharkey@android.com
 lajos@google.com
 marcone@google.com
 sungsoo@google.com
 wjia@google.com
-jaewan@google.com
-chz@google.com
-dwkang@google.com
diff --git a/media/java/android/media/CloseGuard.java b/media/java/android/media/CloseGuard.java
new file mode 100644
index 0000000..2014673
--- /dev/null
+++ b/media/java/android/media/CloseGuard.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2010 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.media;
+
+import android.util.Log;
+
+/**
+ * Note: This file is copied from dalvik.system package with the following modifications:
+ *       - Remove @CorePlatformApi, @IntraCoreApi and @UnsupportedAppUsage annotations.
+ *       - Replace System.logW() with android.util.Log.w().
+ *       This file should be used only within media mainline module.
+ * TODO: Remove this file and use dalvik.system.CloseGuard once
+ *       @CorePlatformApi becomes stable or we have a replacement in SDK API.
+ *       b/120419300
+ *
+ * CloseGuard is a mechanism for flagging implicit finalizer cleanup of
+ * resources that should have been cleaned up by explicit close
+ * methods (aka "explicit termination methods" in Effective Java).
+ * <p>
+ * A simple example: <pre>   {@code
+ *   class Foo {
+ *
+ *       {@literal @}ReachabilitySensitive
+ *       private final CloseGuard guard = CloseGuard.get();
+ *
+ *       ...
+ *
+ *       public Foo() {
+ *           ...;
+ *           guard.open("cleanup");
+ *       }
+ *
+ *       public void cleanup() {
+ *          guard.close();
+ *          ...;
+ *       }
+ *
+ *       protected void finalize() throws Throwable {
+ *           try {
+ *               // Note that guard could be null if the constructor threw.
+ *               if (guard != null) {
+ *                   guard.warnIfOpen();
+ *               }
+ *               cleanup();
+ *           } finally {
+ *               super.finalize();
+ *           }
+ *       }
+ *   }
+ * }</pre>
+ *
+ * In usage where the resource to be explicitly cleaned up is
+ * allocated after object construction, CloseGuard protection can
+ * be deferred. For example: <pre>   {@code
+ *   class Bar {
+ *
+ *       {@literal @}ReachabilitySensitive
+ *       private final CloseGuard guard = CloseGuard.get();
+ *
+ *       ...
+ *
+ *       public Bar() {
+ *           ...;
+ *       }
+ *
+ *       public void connect() {
+ *          ...;
+ *          guard.open("cleanup");
+ *       }
+ *
+ *       public void cleanup() {
+ *          guard.close();
+ *          ...;
+ *       }
+ *
+ *       protected void finalize() throws Throwable {
+ *           try {
+ *               // Note that guard could be null if the constructor threw.
+ *               if (guard != null) {
+ *                   guard.warnIfOpen();
+ *               }
+ *               cleanup();
+ *           } finally {
+ *               super.finalize();
+ *           }
+ *       }
+ *   }
+ * }</pre>
+ *
+ * When used in a constructor, calls to {@code open} should occur at
+ * the end of the constructor since an exception that would cause
+ * abrupt termination of the constructor will mean that the user will
+ * not have a reference to the object to cleanup explicitly. When used
+ * in a method, the call to {@code open} should occur just after
+ * resource acquisition.
+ *
+ * The @ReachabilitySensitive annotation ensures that finalize() cannot be
+ * called during the explicit call to cleanup(), prior to the guard.close call.
+ * There is an extremely small chance that, for code that neglects to call
+ * cleanup(), finalize() and thus cleanup() will be called while a method on
+ * the object is still active, but the "this" reference is no longer required.
+ * If missing cleanup() calls are expected, additional @ReachabilitySensitive
+ * annotations or reachabilityFence() calls may be required.
+ *
+ * @hide
+ */
+final class CloseGuard {
+
+    /**
+     * True if collection of call-site information (the expensive operation
+     * here)  and tracking via a Tracker (see below) are enabled.
+     * Enabled by default so we can diagnose issues early in VM startup.
+     * Note, however, that Android disables this early in its startup,
+     * but enables it with DropBoxing for system apps on debug builds.
+     */
+    private static volatile boolean stackAndTrackingEnabled = true;
+
+    /**
+     * Hook for customizing how CloseGuard issues are reported.
+     * Bypassed if stackAndTrackingEnabled was false when open was called.
+     */
+    private static volatile Reporter reporter = new DefaultReporter();
+
+    /**
+     * Hook for customizing how CloseGuard issues are tracked.
+     */
+    private static volatile Tracker currentTracker = null; // Disabled by default.
+
+    /**
+     * Returns a CloseGuard instance. {@code #open(String)} can be used to set
+     * up the instance to warn on failure to close.
+     */
+    public static CloseGuard get() {
+        return new CloseGuard();
+    }
+
+    /**
+     * Enables/disables stack capture and tracking. A call stack is captured
+     * during open(), and open/close events are reported to the Tracker, only
+     * if enabled is true. If a stack trace was captured, the {@link
+     * #getReporter() reporter} is informed of unclosed resources; otherwise a
+     * one-line warning is logged.
+     */
+    public static void setEnabled(boolean enabled) {
+        CloseGuard.stackAndTrackingEnabled = enabled;
+    }
+
+    /**
+     * True if CloseGuard stack capture and tracking are enabled.
+     */
+    public static boolean isEnabled() {
+        return stackAndTrackingEnabled;
+    }
+
+    /**
+     * Used to replace default Reporter used to warn of CloseGuard
+     * violations when stack tracking is enabled. Must be non-null.
+     */
+    public static void setReporter(Reporter rep) {
+        if (rep == null) {
+            throw new NullPointerException("reporter == null");
+        }
+        CloseGuard.reporter = rep;
+    }
+
+    /**
+     * Returns non-null CloseGuard.Reporter.
+     */
+    public static Reporter getReporter() {
+        return reporter;
+    }
+
+    /**
+     * Sets the {@link Tracker} that is notified when resources are allocated and released.
+     * The Tracker is invoked only if CloseGuard {@link #isEnabled()} held when {@link #open()}
+     * was called. A null argument disables tracking.
+     *
+     * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so
+     * MUST NOT be used for any other purposes.
+     */
+    public static void setTracker(Tracker tracker) {
+        currentTracker = tracker;
+    }
+
+    /**
+     * Returns {@link #setTracker(Tracker) last Tracker that was set}, or null to indicate
+     * there is none.
+     *
+     * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so
+     * MUST NOT be used for any other purposes.
+     */
+    public static Tracker getTracker() {
+        return currentTracker;
+    }
+
+    private CloseGuard() {}
+
+    /**
+     * {@code open} initializes the instance with a warning that the caller
+     * should have explicitly called the {@code closer} method instead of
+     * relying on finalization.
+     *
+     * @param closer non-null name of explicit termination method. Printed by warnIfOpen.
+     * @throws NullPointerException if closer is null.
+     */
+    public void open(String closer) {
+        // always perform the check for valid API usage...
+        if (closer == null) {
+            throw new NullPointerException("closer == null");
+        }
+        // ...but avoid allocating an allocation stack if "disabled"
+        if (!stackAndTrackingEnabled) {
+            closerNameOrAllocationInfo = closer;
+            return;
+        }
+        String message = "Explicit termination method '" + closer + "' not called";
+        Throwable stack = new Throwable(message);
+        closerNameOrAllocationInfo = stack;
+        Tracker tracker = currentTracker;
+        if (tracker != null) {
+            tracker.open(stack);
+        }
+    }
+
+    // We keep either an allocation stack containing the closer String or, when
+    // in disabled state, just the closer String.
+    // We keep them in a single field only to minimize overhead.
+    private Object /* String or Throwable */ closerNameOrAllocationInfo;
+
+    /**
+     * Marks this CloseGuard instance as closed to avoid warnings on
+     * finalization.
+     */
+    public void close() {
+        Tracker tracker = currentTracker;
+        if (tracker != null && closerNameOrAllocationInfo instanceof Throwable) {
+            // Invoke tracker on close only if we invoked it on open. Tracker may have changed.
+            tracker.close((Throwable) closerNameOrAllocationInfo);
+        }
+        closerNameOrAllocationInfo = null;
+    }
+
+    /**
+     * Logs a warning if the caller did not properly cleanup by calling an
+     * explicit close method before finalization. If CloseGuard was enabled
+     * when the CloseGuard was created, passes the stacktrace associated with
+     * the allocation to the current reporter. If it was not enabled, it just
+     * directly logs a brief message.
+     */
+    public void warnIfOpen() {
+        if (closerNameOrAllocationInfo != null) {
+            if (closerNameOrAllocationInfo instanceof String) {
+                Log.w("CloseGuard", "A resource failed to call "
+                        + (String) closerNameOrAllocationInfo + ". ");
+            } else {
+                String message =
+                        "A resource was acquired at attached stack trace but never released. ";
+                message += "See java.io.Closeable for information on avoiding resource leaks.";
+                Throwable stack = (Throwable) closerNameOrAllocationInfo;
+                reporter.report(message, stack);
+            }
+        }
+    }
+
+    /**
+     * Interface to allow customization of tracking behaviour.
+     *
+     * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so
+     * MUST NOT be used for any other purposes.
+     */
+    public interface Tracker {
+        void open(Throwable allocationSite);
+        void close(Throwable allocationSite);
+    }
+
+    /**
+     * Interface to allow customization of reporting behavior.
+     * @hide
+     */
+    public interface Reporter {
+        void report(String message, Throwable allocationSite);
+    }
+
+    /**
+     * Default Reporter which reports CloseGuard violations to the log.
+     */
+    private static final class DefaultReporter implements Reporter {
+        private DefaultReporter() {}
+
+        @Override public void report (String message, Throwable allocationSite) {
+            Log.w("CloseGuard", message, allocationSite);
+        }
+    }
+}
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 284e422..b7743c9 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -17,20 +17,29 @@
 package android.media;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.nio.ByteBuffer;
+import java.util.AbstractSet;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
- * Encapsulates the information describing the format of media data,
- * be it audio or video.
- *
- * The format of the media data is specified as string/value pairs.
- *
+ * Encapsulates the information describing the format of media data, be it audio or video, as
+ * well as optional feature metadata.
+ * <p>
+ * The format of the media data is specified as key/value pairs. Keys are strings. Values can
+ * be integer, long, float, String or ByteBuffer.
+ * <p>
+ * The feature metadata is specificed as string/boolean pairs.
+ * <p>
  * Keys common to all audio/video formats, <b>all keys not marked optional are mandatory</b>:
  *
  * <table>
@@ -938,7 +947,6 @@
      */
     public static final String KEY_CA_SESSION_ID = "ca-session-id";
 
-
     /**
      * A key describing the private data in the CA_descriptor associated with a media track.
      * <p>
@@ -950,7 +958,7 @@
      */
     public static final String KEY_CA_PRIVATE_DATA = "ca-private-data";
 
-    /* package private */ MediaFormat(Map<String, Object> map) {
+    /* package private */ MediaFormat(@NonNull Map<String, Object> map) {
         mMap = map;
     }
 
@@ -969,11 +977,58 @@
     /**
      * Returns true iff a key of the given name exists in the format.
      */
-    public final boolean containsKey(String name) {
+    public final boolean containsKey(@NonNull String name) {
         return mMap.containsKey(name);
     }
 
     /**
+     * Returns true iff a feature of the given name exists in the format.
+     */
+    public final boolean containsFeature(@NonNull String name) {
+        return mMap.containsKey(KEY_FEATURE_ + name);
+    }
+
+    public static final int TYPE_NULL = 0;
+    public static final int TYPE_INTEGER = 1;
+    public static final int TYPE_LONG = 2;
+    public static final int TYPE_FLOAT = 3;
+    public static final int TYPE_STRING = 4;
+    public static final int TYPE_BYTE_BUFFER = 5;
+
+    /** @hide */
+    @IntDef({
+        TYPE_NULL,
+        TYPE_INTEGER,
+        TYPE_LONG,
+        TYPE_FLOAT,
+        TYPE_STRING,
+        TYPE_BYTE_BUFFER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {}
+
+    /**
+     * Returns the value type for a key. If the key does not exist, it returns TYPE_NULL.
+     */
+    public final @Type int getValueTypeForKey(@NonNull String name) {
+        Object value = mMap.get(name);
+        if (value == null) {
+            return TYPE_NULL;
+        } else if (value instanceof Integer) {
+            return TYPE_INTEGER;
+        } else if (value instanceof Long) {
+            return TYPE_LONG;
+        } else if (value instanceof Float) {
+            return TYPE_FLOAT;
+        } else if (value instanceof String) {
+            return TYPE_STRING;
+        } else if (value instanceof ByteBuffer) {
+            return TYPE_BYTE_BUFFER;
+        }
+        throw new RuntimeException("invalid value for key");
+    }
+
+    /**
      * A key prefix used together with a {@link MediaCodecInfo.CodecCapabilities}
      * feature name describing a required or optional feature for a codec capabilities
      * query.
@@ -989,64 +1044,165 @@
     public static final String KEY_FEATURE_ = "feature-";
 
     /**
-     * Returns the value of an integer key.
+     * Returns the value of a numeric key. This is provided as a convenience method for keys
+     * that may take multiple numeric types, such as {@link #KEY_FRAME_RATE}, or {@link
+     * #KEY_I_FRAME_INTERVAL}.
+     *
+     * @return null if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is ByteBuffer or String
      */
-    public final int getInteger(String name) {
+    public final @Nullable Number getNumber(@NonNull String name) {
+        return ((Number)mMap.get(name));
+    }
+
+    /**
+     * Returns the value of a numeric key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is ByteBuffer or String
+     */
+    public final @NonNull Number getNumber(@NonNull String name, @NonNull Number defaultValue) {
+        Number ret = getNumber(name);
+        return ret == null ? defaultValue : ret;
+    }
+
+    /**
+     * Returns the value of an integer key.
+     *
+     * @throws NullPointerException if the key does not exist or the stored value for the key is
+     *         null
+     * @throws ClassCastException if the stored value for the key is long, float, ByteBuffer or
+     *         String
+     */
+    public final int getInteger(@NonNull String name) {
         return ((Integer)mMap.get(name)).intValue();
     }
 
     /**
-     * Returns the value of an integer key, or the default value if the
-     * key is missing or is for another type value.
-     * @hide
+     * Returns the value of an integer key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is long, float, ByteBuffer or
+     *         String
      */
-    public final int getInteger(String name, int defaultValue) {
+    public final int getInteger(@NonNull String name, int defaultValue) {
         try {
             return getInteger(name);
+        } catch (NullPointerException  e) {
+            /* no such field or field is null */
+            return defaultValue;
         }
-        catch (NullPointerException  e) { /* no such field */ }
-        catch (ClassCastException e) { /* field of different type */ }
-        return defaultValue;
     }
 
     /**
      * Returns the value of a long key.
+     *
+     * @throws NullPointerException if the key does not exist or the stored value for the key is
+     *         null
+     * @throws ClassCastException if the stored value for the key is int, float, ByteBuffer or
+     *         String
      */
-    public final long getLong(String name) {
+    public final long getLong(@NonNull String name) {
         return ((Long)mMap.get(name)).longValue();
     }
 
     /**
-     * Returns the value of a float key.
+     * Returns the value of an long key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, float, ByteBuffer or
+     *         String
      */
-    public final float getFloat(String name) {
+    public final long getLong(@NonNull String name, long defaultValue) {
+        try {
+            return getLong(name);
+        } catch (NullPointerException  e) {
+            /* no such field or field is null */
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value of a float key.
+     *
+     * @throws NullPointerException if the key does not exist or the stored value for the key is
+     *         null
+     * @throws ClassCastException if the stored value for the key is int, long, ByteBuffer or
+     *         String
+     */
+    public final float getFloat(@NonNull String name) {
         return ((Float)mMap.get(name)).floatValue();
     }
 
     /**
-     * Returns the value of a string key.
+     * Returns the value of an float key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, ByteBuffer or
+     *         String
      */
-    public final String getString(String name) {
+    public final float getFloat(@NonNull String name, float defaultValue) {
+        try {
+            return getFloat(name);
+        } catch (NullPointerException  e) {
+            /* no such field or field is null */
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value of a string key.
+     *
+     * @return null if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, float or ByteBuffer
+     */
+    public final @Nullable String getString(@NonNull String name) {
         return (String)mMap.get(name);
     }
 
     /**
-     * Returns the value of a ByteBuffer key.
+     * Returns the value of an string key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, float or ByteBuffer
      */
-    public final ByteBuffer getByteBuffer(String name) {
+    public final @NonNull String getString(@NonNull String name, @NonNull String defaultValue) {
+        String ret = getString(name);
+        return ret == null ? defaultValue : ret;
+    }
+
+    /**
+     * Returns the value of a ByteBuffer key.
+     *
+     * @return null if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, float or String
+     */
+    public final @Nullable ByteBuffer getByteBuffer(@NonNull String name) {
         return (ByteBuffer)mMap.get(name);
     }
 
     /**
+     * Returns the value of a ByteBuffer key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, float or String
+     */
+    public final @NonNull ByteBuffer getByteBuffer(
+            @NonNull String name, @NonNull ByteBuffer defaultValue) {
+        ByteBuffer ret = getByteBuffer(name);
+        return ret == null ? defaultValue : ret;
+    }
+
+    /**
      * Returns whether a feature is to be enabled ({@code true}) or disabled
      * ({@code false}).
      *
      * @param feature the name of a {@link MediaCodecInfo.CodecCapabilities} feature.
      *
      * @throws IllegalArgumentException if the feature was neither set to be enabled
-     *        nor to be disabled.
+     *         nor to be disabled.
      */
-    public boolean getFeatureEnabled(String feature) {
+    public boolean getFeatureEnabled(@NonNull String feature) {
         Integer enabled = (Integer)mMap.get(KEY_FEATURE_ + feature);
         if (enabled == null) {
             throw new IllegalArgumentException("feature is not specified");
@@ -1057,39 +1213,239 @@
     /**
      * Sets the value of an integer key.
      */
-    public final void setInteger(String name, int value) {
+    public final void setInteger(@NonNull String name, int value) {
         mMap.put(name, Integer.valueOf(value));
     }
 
     /**
      * Sets the value of a long key.
      */
-    public final void setLong(String name, long value) {
+    public final void setLong(@NonNull String name, long value) {
         mMap.put(name, Long.valueOf(value));
     }
 
     /**
      * Sets the value of a float key.
      */
-    public final void setFloat(String name, float value) {
+    public final void setFloat(@NonNull String name, float value) {
         mMap.put(name, new Float(value));
     }
 
     /**
      * Sets the value of a string key.
+     * <p>
+     * If value is {@code null}, it sets a null value that behaves similarly to a missing key.
+     * This could be used prior to API level {@link android os.Build.VERSION_CODES#Q} to effectively
+     * remove a key.
      */
-    public final void setString(String name, String value) {
+    public final void setString(@NonNull String name, @Nullable String value) {
         mMap.put(name, value);
     }
 
     /**
      * Sets the value of a ByteBuffer key.
+     * <p>
+     * If value is {@code null}, it sets a null value that behaves similarly to a missing key.
+     * This could be used prior to API level {@link android os.Build.VERSION_CODES#Q} to effectively
+     * remove a key.
      */
-    public final void setByteBuffer(String name, ByteBuffer bytes) {
+    public final void setByteBuffer(@NonNull String name, @Nullable ByteBuffer bytes) {
         mMap.put(name, bytes);
     }
 
     /**
+     * Removes a value of a given key if present. Has no effect if the key is not present.
+     */
+    public final void removeKey(@NonNull String name) {
+        // exclude feature mappings
+        if (!name.startsWith(KEY_FEATURE_)) {
+            mMap.remove(name);
+        }
+    }
+
+    /**
+     * Removes a given feature setting if present. Has no effect if the feature setting is not
+     * present.
+     */
+    public final void removeFeature(@NonNull String name) {
+        mMap.remove(KEY_FEATURE_ + name);
+    }
+
+    /**
+     * A Partial set view for a portion of the keys in a MediaFormat object.
+     *
+     * This class is needed as we want to return a portion of the actual format keys in getKeys()
+     * and another portion of the keys in getFeatures(), and still allow the view properties.
+     */
+    private abstract class FilteredMappedKeySet extends AbstractSet<String> {
+        private Set<String> mKeys;
+
+        // Returns true if this set should include this key
+        abstract protected boolean keepKey(String key);
+
+        // Maps a key from the underlying key set into its new value in this key set
+        abstract protected String mapKeyToItem(String key);
+
+        // Maps a key from this key set into its original value in the underlying key set
+        abstract protected String mapItemToKey(String item);
+
+        public FilteredMappedKeySet() {
+            mKeys = mMap.keySet();
+        }
+
+        // speed up contains and remove from abstract implementation (that would iterate
+        // over each element)
+        @Override
+        public boolean contains(Object o) {
+            if (o instanceof String) {
+                String key = mapItemToKey((String)o);
+                return keepKey(key) && mKeys.contains(key);
+            }
+            return false;
+        }
+
+        @Override
+        public boolean remove(Object o) {
+            if (o instanceof String) {
+                String key = mapItemToKey((String)o);
+                if (keepKey(key) && mKeys.remove(key)) {
+                    mMap.remove(key);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        private class KeyIterator implements Iterator<String> {
+            Iterator<String> mIterator;
+            String mLast;
+
+            public KeyIterator() {
+                // We must create a copy of the filtered stream, as remove operation has to modify
+                // the underlying data structure (mMap), so the iterator's operation is undefined.
+                // Use a list as it is likely less memory consuming than the other alternative: set.
+                mIterator =
+                    mKeys.stream().filter(k -> keepKey(k)).collect(Collectors.toList()).iterator();
+            }
+
+            @Override
+            public boolean hasNext() {
+                return mIterator.hasNext();
+            }
+
+            @Override
+            public String next() {
+                mLast = mIterator.next();
+                return mapKeyToItem(mLast);
+            }
+
+            @Override
+            public void remove() {
+                mIterator.remove();
+                mMap.remove(mLast);
+            }
+        }
+
+        @Override
+        public Iterator<String> iterator() {
+            return new KeyIterator();
+        }
+
+        @Override
+        public int size() {
+            return (int)mKeys.stream().filter(k -> keepKey(k)).count();
+        }
+    }
+
+    /**
+     * A Partial set view for a portion of the keys in a MediaFormat object for keys that
+     * don't start with a prefix, such as "feature-"
+     */
+    private class UnprefixedKeySet extends FilteredMappedKeySet {
+        private String mPrefix;
+
+        public UnprefixedKeySet(String prefix) {
+            super();
+            mPrefix = prefix;
+        }
+
+        protected boolean keepKey(String key) {
+            return !key.startsWith(mPrefix);
+        }
+
+        protected String mapKeyToItem(String key) {
+            return key;
+        }
+
+        protected String mapItemToKey(String item) {
+            return item;
+        }
+    }
+
+    /**
+     * A Partial set view for a portion of the keys in a MediaFormat object for keys that
+     * start with a prefix, such as "feature-", with the prefix removed
+     */
+    private class PrefixedKeySetWithPrefixRemoved extends FilteredMappedKeySet {
+        private String mPrefix;
+        private int mPrefixLength;
+
+        public PrefixedKeySetWithPrefixRemoved(String prefix) {
+            super();
+            mPrefix = prefix;
+            mPrefixLength = prefix.length();
+        }
+
+        protected boolean keepKey(String key) {
+            return key.startsWith(mPrefix);
+        }
+
+        protected String mapKeyToItem(String key) {
+            return key.substring(mPrefixLength);
+        }
+
+        protected String mapItemToKey(String item) {
+            return mPrefix + item;
+        }
+    }
+
+
+   /**
+     * Returns a {@link java.util.Set Set} view of the keys contained in this MediaFormat.
+     *
+     * The set is backed by the MediaFormat object, so changes to the format are reflected in the
+     * set, and vice-versa. If the format is modified while an iteration over the set is in progress
+     * (except through the iterator's own remove operation), the results of the iteration are
+     * undefined. The set supports element removal, which removes the corresponding mapping from the
+     * format, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations.
+     * It does not support the add or addAll operations.
+     */
+    public final @NonNull java.util.Set<String> getKeys() {
+        return new UnprefixedKeySet(KEY_FEATURE_);
+    }
+
+   /**
+     * Returns a {@link java.util.Set Set} view of the features contained in this MediaFormat.
+     *
+     * The set is backed by the MediaFormat object, so changes to the format are reflected in the
+     * set, and vice-versa. If the format is modified while an iteration over the set is in progress
+     * (except through the iterator's own remove operation), the results of the iteration are
+     * undefined. The set supports element removal, which removes the corresponding mapping from the
+     * format, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations.
+     * It does not support the add or addAll operations.
+     */
+    public final @NonNull java.util.Set<String> getFeatures() {
+        return new PrefixedKeySetWithPrefixRemoved(KEY_FEATURE_);
+    }
+
+    /**
+     * Create a copy of a media format object.
+     */
+    public MediaFormat(@NonNull MediaFormat other) {
+        mMap.putAll(other.mMap);
+    }
+
+    /**
      * Sets whether a feature is to be enabled ({@code true}) or disabled
      * ({@code false}).
      *
@@ -1102,7 +1458,7 @@
      * @see MediaCodecList#findEncoderForFormat
      * @see MediaCodecInfo.CodecCapabilities#isFormatSupported
      */
-    public void setFeatureEnabled(String feature, boolean enabled) {
+    public void setFeatureEnabled(@NonNull String feature, boolean enabled) {
         setInteger(KEY_FEATURE_ + feature, enabled ? 1 : 0);
     }
 
@@ -1112,8 +1468,8 @@
      * @param sampleRate The sampling rate of the content.
      * @param channelCount The number of audio channels in the content.
      */
-    public static final MediaFormat createAudioFormat(
-            String mime,
+    public static final @NonNull MediaFormat createAudioFormat(
+            @NonNull String mime,
             int sampleRate,
             int channelCount) {
         MediaFormat format = new MediaFormat();
@@ -1132,8 +1488,8 @@
      *        in the content.  (This will also work if there are multiple language
      *        tracks in the content.)
      */
-    public static final MediaFormat createSubtitleFormat(
-            String mime,
+    public static final @NonNull MediaFormat createSubtitleFormat(
+            @NonNull String mime,
             String language) {
         MediaFormat format = new MediaFormat();
         format.setString(KEY_MIME, mime);
@@ -1148,8 +1504,8 @@
      * @param width The width of the content (in pixels)
      * @param height The height of the content (in pixels)
      */
-    public static final MediaFormat createVideoFormat(
-            String mime,
+    public static final @NonNull MediaFormat createVideoFormat(
+            @NonNull String mime,
             int width,
             int height) {
         MediaFormat format = new MediaFormat();
@@ -1161,7 +1517,7 @@
     }
 
     @Override
-    public String toString() {
+    public @NonNull String toString() {
         return mMap.toString();
     }
 }
diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java
index 111dd0f..4b99a13 100644
--- a/media/java/android/media/MediaPlayer2.java
+++ b/media/java/android/media/MediaPlayer2.java
@@ -48,8 +48,6 @@
 import com.android.framework.protobuf.InvalidProtocolBufferException;
 import com.android.internal.annotations.GuardedBy;
 
-import dalvik.system.CloseGuard;
-
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileDescriptor;
@@ -3503,7 +3501,7 @@
         }
     }
 
-    private native void native_releaseDrm();
+    private native void native_releaseDrm(long mSrcId);
 
     /**
      * A key request/response exchange occurs between the app and a license server
@@ -3823,7 +3821,8 @@
         }
     }
 
-    private native void native_prepareDrm(@NonNull byte[] uuid, @NonNull byte[] drmSessionId);
+    private native void native_prepareDrm(
+            long srcId, @NonNull byte[] uuid, @NonNull byte[] drmSessionId);
 
     // Instantiated from the native side
     @SuppressWarnings("unused")
@@ -4066,6 +4065,7 @@
         static final int PROVISION_TIMEOUT_MS = 60000;
 
         final DataSourceDesc mDSD;
+        final long mSrcId;
 
         //--- guarded by |this| start
         MediaDrm mDrmObj;
@@ -4077,8 +4077,9 @@
         Future<?> mProvisionResult;
         //--- guarded by |this| end
 
-        DrmHandle(DataSourceDesc dsd) {
+        DrmHandle(DataSourceDesc dsd, long srcId) {
             mDSD = dsd;
+            mSrcId = srcId;
         }
 
         void prepare(UUID uuid) throws UnsupportedSchemeException,
@@ -4188,7 +4189,8 @@
 
                 // Sending it down to native/mediaserver to create the crypto object
                 // This call could simply fail due to bad player state, e.g., after play().
-                MediaPlayer2.this.native_prepareDrm(getByteArrayFromUUID(uuid), mDrmSessionId);
+                final MediaPlayer2 mp2 = MediaPlayer2.this;
+                mp2.native_prepareDrm(mSrcId, getByteArrayFromUUID(uuid), mDrmSessionId);
                 Log.v(TAG, "prepareDrm_openSessionStep: native_prepareDrm/Crypto succeeded");
 
             } catch (Exception e) { //ResourceBusyException, NotProvisionedException
@@ -4369,7 +4371,7 @@
                     // exception if we're in a non-stopped/prepared state.
 
                     // for cleaning native/mediaserver crypto object
-                    native_releaseDrm();
+                    native_releaseDrm(mSrcId);
 
                     // for cleaning client-side MediaDrm object; only called if above has succeeded
                     cleanDrmObj();
@@ -4575,7 +4577,7 @@
 
         SourceInfo(DataSourceDesc dsd) {
             this.mDSD = dsd;
-            mDrmHandle = new DrmHandle(dsd);
+            mDrmHandle = new DrmHandle(dsd, mId);
         }
 
         void close() {
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 0950a24..90cfc53 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1015,12 +1015,6 @@
                     // exif is null
                 }
                 if (exif != null) {
-                    float[] latlng = new float[2];
-                    if (exif.getLatLong(latlng)) {
-                        values.put(Images.Media.LATITUDE, latlng[0]);
-                        values.put(Images.Media.LONGITUDE, latlng[1]);
-                    }
-
                     long time = exif.getGpsDateTime();
                     if (time != -1) {
                         values.put(Images.Media.DATE_TAKEN, time);
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 8215779..d91cf87 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -96,9 +96,15 @@
      * @return The binder object from the system
      * @hide
      */
+    @SystemApi
     public @NonNull ISession createSession(@NonNull MediaSession.CallbackStub cbStub,
-            @NonNull String tag, int userId) throws RemoteException {
-        return mService.createSession(mContext.getPackageName(), cbStub, tag, userId);
+            @NonNull String tag, int userId) {
+        try {
+            return mService.createSession(mContext.getPackageName(), cbStub, tag, userId);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+        return null;
     }
 
     /**
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
index 4567492..8b6009e 100644
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ b/media/jni/android_media_MediaPlayer2.cpp
@@ -1192,7 +1192,7 @@
 }
 
 static void android_media_MediaPlayer2_prepareDrm(JNIEnv *env, jobject thiz,
-                    jbyteArray uuidObj, jbyteArray drmSessionIdObj)
+                    jlong srcId, jbyteArray uuidObj, jbyteArray drmSessionIdObj)
 {
     sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
     if (mp == NULL) {
@@ -1225,7 +1225,7 @@
         return;
     }
 
-    status_t err = mp->prepareDrm(uuid.array(), drmSessionId);
+    status_t err = mp->prepareDrm(srcId, uuid.array(), drmSessionId);
     if (err != OK) {
         if (err == INVALID_OPERATION) {
             jniThrowException(
@@ -1243,7 +1243,7 @@
     }
 }
 
-static void android_media_MediaPlayer2_releaseDrm(JNIEnv *env, jobject thiz)
+static void android_media_MediaPlayer2_releaseDrm(JNIEnv *env, jobject thiz, jlong srcId)
 {
     sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
     if (mp == NULL ) {
@@ -1251,7 +1251,7 @@
         return;
     }
 
-    status_t err = mp->releaseDrm();
+    status_t err = mp->releaseDrm(srcId);
     if (err != OK) {
         if (err == INVALID_OPERATION) {
             jniThrowException(
@@ -1425,8 +1425,8 @@
     {"native_setAuxEffectSendLevel", "(F)V",                    (void *)android_media_MediaPlayer2_setAuxEffectSendLevel},
     {"native_attachAuxEffect", "(I)V",                          (void *)android_media_MediaPlayer2_attachAuxEffect},
     // Modular DRM
-    { "native_prepareDrm", "([B[B)V",                           (void *)android_media_MediaPlayer2_prepareDrm },
-    { "native_releaseDrm", "()V",                               (void *)android_media_MediaPlayer2_releaseDrm },
+    { "native_prepareDrm", "(J[B[B)V",                          (void *)android_media_MediaPlayer2_prepareDrm },
+    { "native_releaseDrm", "(J)V",                              (void *)android_media_MediaPlayer2_releaseDrm },
 
     // AudioRouting
     {"native_setPreferredDevice", "(Landroid/media/AudioDeviceInfo;)Z", (void *)android_media_MediaPlayer2_setPreferredDevice},
diff --git a/packages/SystemUI/res/anim/car_arrow_fade_in_rotate_down.xml b/packages/CarSystemUI/res/anim/car_arrow_fade_in_rotate_down.xml
similarity index 100%
rename from packages/SystemUI/res/anim/car_arrow_fade_in_rotate_down.xml
rename to packages/CarSystemUI/res/anim/car_arrow_fade_in_rotate_down.xml
diff --git a/packages/SystemUI/res/anim/car_arrow_fade_in_rotate_up.xml b/packages/CarSystemUI/res/anim/car_arrow_fade_in_rotate_up.xml
similarity index 100%
rename from packages/SystemUI/res/anim/car_arrow_fade_in_rotate_up.xml
rename to packages/CarSystemUI/res/anim/car_arrow_fade_in_rotate_up.xml
diff --git a/packages/SystemUI/res/anim/car_arrow_fade_out.xml b/packages/CarSystemUI/res/anim/car_arrow_fade_out.xml
similarity index 100%
rename from packages/SystemUI/res/anim/car_arrow_fade_out.xml
rename to packages/CarSystemUI/res/anim/car_arrow_fade_out.xml
diff --git a/packages/SystemUI/res/anim/car_user_switcher_close_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_close_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_close_animation.xml
index ed637a7..6f12338 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_close_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_close_animation.xml
@@ -1,4 +1,4 @@
-<!-- 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_close_icon_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_icon_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_close_icon_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_close_icon_animation.xml
index 227c981..9f8c12e 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_close_icon_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_close_icon_animation.xml
@@ -1,4 +1,4 @@
-<!-- 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_close_name_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_name_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_close_name_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_close_name_animation.xml
index 5901ff4..adc1f72 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_close_name_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_close_name_animation.xml
@@ -1,4 +1,4 @@
-<!-- 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_close_pages_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_pages_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_close_pages_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_close_pages_animation.xml
index 41cbe4b..dec5c05 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_close_pages_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_close_pages_animation.xml
@@ -1,4 +1,4 @@
-<!-- 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_close_pod_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_pod_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_close_pod_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_close_pod_animation.xml
index 341e7e0..986a9cb 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_close_pod_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_close_pod_animation.xml
@@ -1,4 +1,4 @@
-<!-- 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_open_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_open_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_open_animation.xml
index 6ae7413..80b38b3 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_open_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_open_animation.xml
@@ -1,4 +1,4 @@
-<!-- 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_open_icon_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_icon_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_open_icon_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_open_icon_animation.xml
index 06ac9e3..721376c 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_open_icon_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_open_icon_animation.xml
@@ -1,4 +1,4 @@
-<!-- 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_open_name_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_name_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_open_name_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_open_name_animation.xml
index 4baefb8..246099e 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_open_name_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_open_name_animation.xml
@@ -1,4 +1,4 @@
-<!-- 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_open_pages_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_pages_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_open_pages_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_open_pages_animation.xml
index 2d0deb9..9a1c642 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_open_pages_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_open_pages_animation.xml
@@ -1,4 +1,4 @@
-<!-- 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_open_pod_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_pod_animation.xml
similarity index 95%
rename from packages/SystemUI/res/anim/car_user_switcher_open_pod_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_open_pod_animation.xml
index 3315220..1414b66 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_open_pod_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_open_pod_animation.xml
@@ -1,4 +1,4 @@
-<!-- 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.
diff --git a/packages/SystemUI/res/drawable/car_add_circle_round.xml b/packages/CarSystemUI/res/drawable/car_add_circle_round.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/car_add_circle_round.xml
rename to packages/CarSystemUI/res/drawable/car_add_circle_round.xml
diff --git a/packages/SystemUI/res/drawable/car_ic_add_white.xml b/packages/CarSystemUI/res/drawable/car_ic_add_white.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/car_ic_add_white.xml
rename to packages/CarSystemUI/res/drawable/car_ic_add_white.xml
diff --git a/packages/SystemUI/res/drawable/car_ic_arrow.xml b/packages/CarSystemUI/res/drawable/car_ic_arrow.xml
similarity index 94%
rename from packages/SystemUI/res/drawable/car_ic_arrow.xml
rename to packages/CarSystemUI/res/drawable/car_ic_arrow.xml
index d400ed8..cfacbf9 100644
--- a/packages/SystemUI/res/drawable/car_ic_arrow.xml
+++ b/packages/CarSystemUI/res/drawable/car_ic_arrow.xml
@@ -1,5 +1,5 @@
 <!--
-  ~ 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.
diff --git a/packages/SystemUI/res/drawable/car_ic_arrow_drop_up.xml b/packages/CarSystemUI/res/drawable/car_ic_arrow_drop_up.xml
similarity index 93%
rename from packages/SystemUI/res/drawable/car_ic_arrow_drop_up.xml
rename to packages/CarSystemUI/res/drawable/car_ic_arrow_drop_up.xml
index 33a512e..81e7262 100644
--- a/packages/SystemUI/res/drawable/car_ic_arrow_drop_up.xml
+++ b/packages/CarSystemUI/res/drawable/car_ic_arrow_drop_up.xml
@@ -1,5 +1,5 @@
 <!--
-  ~ Copyright (C) 2015 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.
diff --git a/packages/SystemUI/res/drawable/car_ic_hvac.xml b/packages/CarSystemUI/res/drawable/car_ic_hvac.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/car_ic_hvac.xml
rename to packages/CarSystemUI/res/drawable/car_ic_hvac.xml
diff --git a/packages/SystemUI/res/drawable/car_ic_keyboard_arrow_down.xml b/packages/CarSystemUI/res/drawable/car_ic_keyboard_arrow_down.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/car_ic_keyboard_arrow_down.xml
rename to packages/CarSystemUI/res/drawable/car_ic_keyboard_arrow_down.xml
diff --git a/packages/CarSystemUI/res/drawable/car_rounded_bg_bottom.xml b/packages/CarSystemUI/res/drawable/car_rounded_bg_bottom.xml
new file mode 100644
index 0000000..eb501e5
--- /dev/null
+++ b/packages/CarSystemUI/res/drawable/car_rounded_bg_bottom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2018 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="?android:attr/colorBackgroundFloating" />
+    <corners
+        android:bottomLeftRadius="@dimen/car_radius_3"
+        android:topLeftRadius="0dp"
+        android:bottomRightRadius="@dimen/car_radius_3"
+        android:topRightRadius="0dp"
+        />
+</shape>
diff --git a/packages/CarSystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml b/packages/CarSystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml
new file mode 100644
index 0000000..34578fe
--- /dev/null
+++ b/packages/CarSystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2018 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="17dp"
+        android:height="17dp"
+        android:viewportWidth="18.0"
+        android:viewportHeight="18.0">
+    <group
+        android:translateY="0.5"
+        android:translateX="0.5" >
+        <path
+            android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+            android:fillColor="#FFFFFF"/>
+    </group>
+</vector>
diff --git a/packages/CarSystemUI/res/drawable/ic_mic_white.xml b/packages/CarSystemUI/res/drawable/ic_mic_white.xml
index f5a91b5..e1e389d 100644
--- a/packages/CarSystemUI/res/drawable/ic_mic_white.xml
+++ b/packages/CarSystemUI/res/drawable/ic_mic_white.xml
@@ -1,3 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2018 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="48dp"
         android:height="48dp"
diff --git a/packages/SystemUI/res/layout/car_facet_button.xml b/packages/CarSystemUI/res/layout/car_facet_button.xml
similarity index 97%
rename from packages/SystemUI/res/layout/car_facet_button.xml
rename to packages/CarSystemUI/res/layout/car_facet_button.xml
index ad86049..8e7ebad 100644
--- a/packages/SystemUI/res/layout/car_facet_button.xml
+++ b/packages/CarSystemUI/res/layout/car_facet_button.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 **
-** Copyright 2017, The Android Open Source Project
+** Copyright 2018, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml b/packages/CarSystemUI/res/layout/car_fullscreen_user_pod.xml
similarity index 96%
rename from packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
rename to packages/CarSystemUI/res/layout/car_fullscreen_user_pod.xml
index ee8d357..1d67286 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
+++ b/packages/CarSystemUI/res/layout/car_fullscreen_user_pod.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-     Copyright (C) 2015 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.
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml
similarity index 96%
rename from packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
rename to packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml
index c9f5148..6cd70d6 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
+++ b/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2015 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.
diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml
similarity index 98%
rename from packages/SystemUI/res/layout/car_left_navigation_bar.xml
rename to packages/CarSystemUI/res/layout/car_left_navigation_bar.xml
index 02be457..141b28a 100644
--- a/packages/SystemUI/res/layout/car_left_navigation_bar.xml
+++ b/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 **
-** Copyright 2016, The Android Open Source Project
+** Copyright 2018, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
similarity index 100%
rename from packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
rename to packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
diff --git a/packages/SystemUI/res/layout/car_navigation_button.xml b/packages/CarSystemUI/res/layout/car_navigation_button.xml
similarity index 95%
rename from packages/SystemUI/res/layout/car_navigation_button.xml
rename to packages/CarSystemUI/res/layout/car_navigation_button.xml
index 4062eb8..6d8cca9 100644
--- a/packages/SystemUI/res/layout/car_navigation_button.xml
+++ b/packages/CarSystemUI/res/layout/car_navigation_button.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 **
-** Copyright 2016, The Android Open Source Project
+** Copyright 2018, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
diff --git a/packages/SystemUI/res/layout/car_qs_footer.xml b/packages/CarSystemUI/res/layout/car_qs_footer.xml
similarity index 98%
rename from packages/SystemUI/res/layout/car_qs_footer.xml
rename to packages/CarSystemUI/res/layout/car_qs_footer.xml
index 3afd4ea..6f19cfc 100644
--- a/packages/SystemUI/res/layout/car_qs_footer.xml
+++ b/packages/CarSystemUI/res/layout/car_qs_footer.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
diff --git a/packages/SystemUI/res/layout/car_qs_panel.xml b/packages/CarSystemUI/res/layout/car_qs_panel.xml
similarity index 96%
rename from packages/SystemUI/res/layout/car_qs_panel.xml
rename to packages/CarSystemUI/res/layout/car_qs_panel.xml
index e7413de..dfa48c3 100644
--- a/packages/SystemUI/res/layout/car_qs_panel.xml
+++ b/packages/CarSystemUI/res/layout/car_qs_panel.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml
similarity index 98%
copy from packages/SystemUI/res/layout/car_left_navigation_bar.xml
copy to packages/CarSystemUI/res/layout/car_right_navigation_bar.xml
index 02be457..141b28a 100644
--- a/packages/SystemUI/res/layout/car_left_navigation_bar.xml
+++ b/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 **
-** Copyright 2016, The Android Open Source Project
+** Copyright 2018, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
diff --git a/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
similarity index 100%
rename from packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
rename to packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
diff --git a/packages/SystemUI/res/values/colors_car.xml b/packages/CarSystemUI/res/values/colors_car.xml
similarity index 95%
rename from packages/SystemUI/res/values/colors_car.xml
rename to packages/CarSystemUI/res/values/colors_car.xml
index 49bfb25..2f720f5 100644
--- a/packages/SystemUI/res/values/colors_car.xml
+++ b/packages/CarSystemUI/res/values/colors_car.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 /*
- * Copyright 2017, The Android Open Source Project
+ * Copyright 2018, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/packages/SystemUI/res/values/dimens_car.xml b/packages/CarSystemUI/res/values/dimens_car.xml
similarity index 97%
rename from packages/SystemUI/res/values/dimens_car.xml
rename to packages/CarSystemUI/res/values/dimens_car.xml
index afbe176..c027f81 100644
--- a/packages/SystemUI/res/values/dimens_car.xml
+++ b/packages/CarSystemUI/res/values/dimens_car.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- * Copyright (c) 2016, 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.
diff --git a/packages/SystemUI/res/values/ids_car.xml b/packages/CarSystemUI/res/values/ids_car.xml
similarity index 100%
rename from packages/SystemUI/res/values/ids_car.xml
rename to packages/CarSystemUI/res/values/ids_car.xml
diff --git a/packages/SystemUI/res/values/integers_car.xml b/packages/CarSystemUI/res/values/integers_car.xml
similarity index 95%
rename from packages/SystemUI/res/values/integers_car.xml
rename to packages/CarSystemUI/res/values/integers_car.xml
index fc3623c..472c957 100644
--- a/packages/SystemUI/res/values/integers_car.xml
+++ b/packages/CarSystemUI/res/values/integers_car.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  Copyright (c) 2017, The Android Open Source Project
+  Copyright (c) 2018, The Android Open Source Project
 
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
diff --git a/packages/SystemUI/res/values/strings_car.xml b/packages/CarSystemUI/res/values/strings_car.xml
similarity index 96%
rename from packages/SystemUI/res/values/strings_car.xml
rename to packages/CarSystemUI/res/values/strings_car.xml
index 2890cf2..83e91c5 100644
--- a/packages/SystemUI/res/values/strings_car.xml
+++ b/packages/CarSystemUI/res/values/strings_car.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 /**
- * Copyright (c) 2016, 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.
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
index dfe5704..f57f26d 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
@@ -28,6 +28,8 @@
 import com.android.systemui.statusbar.car.hvac.HvacController;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.volume.CarVolumeDialogComponent;
+import com.android.systemui.volume.VolumeDialogComponent;
 
 /**
  * Class factory to provide car specific SystemUI components.
@@ -39,6 +41,10 @@
         return new CarStatusBarKeyguardViewManager(context, viewMediatorCallback, lockPatternUtils);
     }
 
+    public VolumeDialogComponent createVolumeDialogComponent(SystemUI systemUi, Context context) {
+        return new CarVolumeDialogComponent(systemUi, context);
+    }
+
     @Override
     public void injectDependencies(ArrayMap<Object, DependencyProvider> providers,
         Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
rename to packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
index 50fefe9..0563418 100644
--- a/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -11,8 +11,9 @@
  * 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
+ * limitations under the License.
  */
+
 package com.android.systemui.car;
 
 import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
rename to packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
index 0389030..b74f199 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
+++ b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
@@ -1,16 +1,19 @@
 /*
- * 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
  *
- * 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.
  */
+
 package com.android.systemui.qs.car;
 
 import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFragment.java b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
rename to packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
index 3e82c54..41c37d3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
+++ b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
@@ -1,16 +1,19 @@
 /*
- * 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
  *
- * 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.
  */
+
 package com.android.systemui.qs.car;
 
 import android.animation.Animator;
@@ -223,7 +226,7 @@
 
     private void animateHeightChange(boolean opening) {
         // Animation in progress; cancel it to avoid contention.
-        if (mAnimatorSet != null){
+        if (mAnimatorSet != null) {
             mAnimatorSet.cancel();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java
similarity index 81%
rename from packages/SystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java
rename to packages/CarSystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java
index 083a747..d5dd3c3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java
+++ b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java
@@ -1,16 +1,19 @@
 /*
- * 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
  *
- * 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.
  */
+
 package com.android.systemui.qs.car;
 
 import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
index fc39648..58f80a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
@@ -58,28 +58,31 @@
     private final Context mContext;
 
     private final BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
-    private BluetoothHeadsetClient mBluetoothHeadsetClient;
-
     private final ArrayList<BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
+    private BluetoothHeadsetClient mBluetoothHeadsetClient;
+    private final ServiceListener mHfpServiceListener = new ServiceListener() {
+        @Override
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            if (profile == BluetoothProfile.HEADSET_CLIENT) {
+                mBluetoothHeadsetClient = (BluetoothHeadsetClient) proxy;
+            }
+        }
 
+        @Override
+        public void onServiceDisconnected(int profile) {
+            if (profile == BluetoothProfile.HEADSET_CLIENT) {
+                mBluetoothHeadsetClient = null;
+            }
+        }
+    };
     private int mLevel;
-
-    /**
-     * An interface indicating the container of a View that will display what the information
-     * in the {@link CarBatteryController}.
-     */
-    public interface BatteryViewHandler {
-        void hideBatteryView();
-        void showBatteryView();
-    }
-
     private BatteryViewHandler mBatteryViewHandler;
 
     public CarBatteryController(Context context) {
         mContext = context;
 
         if (mAdapter == null) {
-           return;
+            return;
         }
 
         mAdapter.getProfileProxy(context.getApplicationContext(), mHfpServiceListener,
@@ -159,7 +162,7 @@
 
             }
             BluetoothDevice device =
-                    (BluetoothDevice)intent.getExtra(BluetoothDevice.EXTRA_DEVICE);
+                    (BluetoothDevice) intent.getExtra(BluetoothDevice.EXTRA_DEVICE);
             updateBatteryIcon(device, newState);
         }
     }
@@ -261,20 +264,14 @@
         }
     }
 
-    private final ServiceListener mHfpServiceListener = new ServiceListener() {
-        @Override
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (profile == BluetoothProfile.HEADSET_CLIENT) {
-                mBluetoothHeadsetClient = (BluetoothHeadsetClient) proxy;
-            }
-        }
+    /**
+     * An interface indicating the container of a View that will display what the information
+     * in the {@link CarBatteryController}.
+     */
+    public interface BatteryViewHandler {
+        void hideBatteryView();
 
-        @Override
-        public void onServiceDisconnected(int profile) {
-            if (profile == BluetoothProfile.HEADSET_CLIENT) {
-                mBluetoothHeadsetClient = null;
-            }
-        }
-    };
+        void showBatteryView();
+    }
 
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
similarity index 87%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
index 20986ad..56db242 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.android.systemui.statusbar.car;
 
 import android.app.ActivityManager;
@@ -34,7 +50,6 @@
      * Add facet button to this controller. The expected use is for the facet button
      * to get a reference to this controller via {@link com.android.systemui.Dependency}
      * and self add.
-     * @param facetButton
      */
     public void addFacetButton(CarFacetButton facetButton) {
         String[] categories = facetButton.getCategories();
@@ -70,15 +85,16 @@
      * They will then be compared with the supplied StackInfo list.
      * The StackInfo is expected to be supplied in order of recency and StackInfo will only be used
      * for consideration if it has the same displayId as the CarFacetButtons.
-     * @param taskInfo of the currently running application
+     *
+     * @param stackInfoList of the currently running application
      */
     public void taskChanged(List<ActivityManager.StackInfo> stackInfoList) {
         int displayId = getDisplayId();
         ActivityManager.StackInfo validStackInfo = null;
-        for (ActivityManager.StackInfo stackInfo :stackInfoList) {
+        for (ActivityManager.StackInfo stackInfo : stackInfoList) {
             // If the display id is unknown or it matches the stack, it's valid for use
-            if ((displayId == -1 || displayId == stackInfo.displayId) &&
-                    stackInfo.topActivity != null) {
+            if ((displayId == -1 || displayId == stackInfo.displayId)
+                    && stackInfo.topActivity != null) {
                 validStackInfo = stackInfo;
                 break;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
similarity index 100%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
similarity index 86%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
index 084c136..e640baa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.android.systemui.statusbar.car;
 
 import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 4bff5ba..2d90f8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 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.
@@ -35,6 +35,8 @@
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.plugins.qs.QS;
+import com.android.systemui.qs.car.CarQSFragment;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.statusbar.StatusBarState;
@@ -252,6 +254,11 @@
         addTemperatureViewToController(mStatusBarWindow);
     }
 
+    @Override
+    protected QS createDefaultQSFragment() {
+        return new CarQSFragment();
+    }
+
     private BatteryController createBatteryController() {
         mCarBatteryController = new CarBatteryController(mContext);
         mCarBatteryController.addBatteryViewHandler(this);
@@ -549,7 +556,7 @@
      */
     public void dismissKeyguard() {
         executeRunnableDismissingKeyguard(null/* runnable */, null /* cancelAction */,
-            true /* dismissShade */, true /* afterKeyguardGone */, true /* deferred */);
+                true /* dismissShade */, true /* afterKeyguardGone */, true /* deferred */);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
similarity index 70%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
index d0f0629..8c6b9b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.android.systemui.statusbar.car;
 
 import android.content.Context;
@@ -16,13 +32,13 @@
             ViewMediatorCallback callback,
             LockPatternUtils lockPatternUtils) {
         super(context, callback, lockPatternUtils);
-        mShouldHideNavBar =context.getResources()
+        mShouldHideNavBar = context.getResources()
                 .getBoolean(R.bool.config_hideNavWhenKeyguardBouncerShown);
     }
 
     @Override
     protected void updateNavigationBarVisibility(boolean navBarVisible) {
-        if(!mShouldHideNavBar) {
+        if (!mShouldHideNavBar) {
             return;
         }
         CarStatusBar statusBar = (CarStatusBar) mStatusBar;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
index f2923f7..3288927 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.android.systemui.statusbar.car;
 
 import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
@@ -29,7 +45,7 @@
  */
 public class ConnectedDeviceSignalController extends BroadcastReceiver implements
         BluetoothController.Callback {
-    private final static String TAG = "DeviceSignalCtlr";
+    private static final String TAG = "DeviceSignalCtlr";
 
     /**
      * The value that indicates if a network is unavailable. This value is according ot the
@@ -70,6 +86,21 @@
     private final SignalDrawable mSignalDrawable;
 
     private BluetoothHeadsetClient mBluetoothHeadsetClient;
+    private final ServiceListener mHfpServiceListener = new ServiceListener() {
+        @Override
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            if (profile == BluetoothProfile.HEADSET_CLIENT) {
+                mBluetoothHeadsetClient = (BluetoothHeadsetClient) proxy;
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(int profile) {
+            if (profile == BluetoothProfile.HEADSET_CLIENT) {
+                mBluetoothHeadsetClient = null;
+            }
+        }
+    };
 
     public ConnectedDeviceSignalController(Context context, View signalsView) {
         mContext = context;
@@ -87,7 +118,7 @@
                 new ScalingDrawableWrapper(mSignalDrawable, mIconScaleFactor));
 
         if (mAdapter == null) {
-          return;
+            return;
         }
 
         mAdapter.getProfileProxy(context.getApplicationContext(), mHfpServiceListener,
@@ -236,20 +267,4 @@
             mSignalsView.setVisibility(View.GONE);
         }
     }
-
-    private final ServiceListener mHfpServiceListener = new ServiceListener() {
-        @Override
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (profile == BluetoothProfile.HEADSET_CLIENT) {
-                mBluetoothHeadsetClient = (BluetoothHeadsetClient) proxy;
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(int profile) {
-            if (profile == BluetoothProfile.HEADSET_CLIENT) {
-                mBluetoothHeadsetClient = null;
-            }
-        }
-    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java
index 47941bf..730c3e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java
@@ -124,4 +124,4 @@
             Log.d(TAG, message);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index 2ebf5eb..23fe594 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 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.
@@ -11,7 +11,7 @@
  * 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
+ * limitations under the License.
  */
 
 package com.android.systemui.statusbar.car;
@@ -44,7 +44,7 @@
         // Initialize user grid.
         mUserGridView = container.findViewById(R.id.user_grid);
         GridLayoutManager layoutManager = new GridLayoutManager(context,
-            context.getResources().getInteger(R.integer.user_fullscreen_switcher_num_col));
+                context.getResources().getInteger(R.integer.user_fullscreen_switcher_num_col));
         mUserGridView.getRecyclerView().setLayoutManager(layoutManager);
         mUserGridView.buildAdapter();
         mUserGridView.setUserSelectionListener(this::onUserSelected);
@@ -54,7 +54,7 @@
         hide();
 
         mShortAnimDuration = container.getResources()
-            .getInteger(android.R.integer.config_shortAnimTime);
+                .getInteger(android.R.integer.config_shortAnimTime);
     }
 
     /**
@@ -108,4 +108,4 @@
                 });
 
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java
similarity index 100%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
index d802ed8..fb2b57b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
@@ -11,7 +11,7 @@
  * 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
+ * limitations under the License.
  */
 
 package com.android.systemui.statusbar.car;
@@ -210,7 +210,7 @@
         public void onBindViewHolder(UserAdapterViewHolder holder, int position) {
             UserRecord userRecord = mUsers.get(position);
             RoundedBitmapDrawable circleIcon = RoundedBitmapDrawableFactory.create(mRes,
-                getUserRecordIcon(userRecord));
+                    getUserRecordIcon(userRecord));
             circleIcon.setCircular(true);
             holder.mUserAvatarImageView.setImageDrawable(circleIcon);
             holder.mUserNameTextView.setText(userRecord.mInfo.name);
@@ -254,13 +254,13 @@
 
         private void showMaxUserLimitReachedDialog() {
             AlertDialog maxUsersDialog = new Builder(mContext, R.style.Theme_Car_Dark_Dialog_Alert)
-                .setTitle(R.string.user_limit_reached_title)
-                .setMessage(getResources().getQuantityString(
-                    R.plurals.user_limit_reached_message,
-                    mCarUserManagerHelper.getMaxSupportedRealUsers(),
-                    mCarUserManagerHelper.getMaxSupportedRealUsers()))
-                .setPositiveButton(android.R.string.ok, null)
-                .create();
+                    .setTitle(R.string.user_limit_reached_title)
+                    .setMessage(getResources().getQuantityString(
+                            R.plurals.user_limit_reached_message,
+                            mCarUserManagerHelper.getMaxSupportedRealUsers(),
+                            mCarUserManagerHelper.getMaxSupportedRealUsers()))
+                    .setPositiveButton(android.R.string.ok, null)
+                    .create();
             // Sets window flags for the SysUI dialog
             SystemUIDialog.applyFlags(maxUsersDialog);
             maxUsersDialog.show();
@@ -268,17 +268,17 @@
 
         private void showConfirmAddUserDialog() {
             String message = mRes.getString(R.string.user_add_user_message_setup)
-                .concat(System.getProperty("line.separator"))
-                .concat(System.getProperty("line.separator"))
-                .concat(mRes.getString(R.string.user_add_user_message_update));
+                    .concat(System.getProperty("line.separator"))
+                    .concat(System.getProperty("line.separator"))
+                    .concat(mRes.getString(R.string.user_add_user_message_update));
 
             AlertDialog addUserDialog = new Builder(mContext, R.style.Theme_Car_Dark_Dialog_Alert)
-                .setTitle(R.string.user_add_user_title)
-                .setMessage(message)
-                .setNegativeButton(android.R.string.cancel, this)
-                .setPositiveButton(android.R.string.ok, this)
-                .setOnCancelListener(this)
-                .create();
+                    .setTitle(R.string.user_add_user_title)
+                    .setMessage(message)
+                    .setNegativeButton(android.R.string.cancel, this)
+                    .setPositiveButton(android.R.string.ok, this)
+                    .setOnCancelListener(this)
+                    .create();
             // Sets window flags for the SysUI dialog
             SystemUIDialog.applyFlags(addUserDialog);
             addUserDialog.show();
@@ -298,7 +298,7 @@
 
             if (userRecord.mIsAddUser) {
                 return UserIcons.convertToBitmap(mContext
-                    .getDrawable(R.drawable.car_add_circle_round));
+                        .getDrawable(R.drawable.car_add_circle_round));
             }
 
             return mCarUserManagerHelper.getUserIcon(userRecord.mInfo);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
index 6c924e3..aec31ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
@@ -41,117 +41,13 @@
 public class HvacController {
 
     public static final String TAG = "HvacController";
-    public final static int BIND_TO_HVAC_RETRY_DELAY = 5000;
+    public static final int BIND_TO_HVAC_RETRY_DELAY = 5000;
 
     private Context mContext;
     private Handler mHandler;
     private Car mCar;
     private CarHvacManager mHvacManager;
     private HashMap<HvacKey, List<TemperatureView>> mTempComponents = new HashMap<>();
-
-    public HvacController(Context context) {
-        mContext = context;
-    }
-
-    /**
-     * Create connection to the Car service. Note: call backs from the Car service
-     * ({@link CarHvacManager}) will happen on the same thread this method was called from.
-     */
-    public void connectToCarService() {
-        mHandler = new Handler();
-        mCar = Car.createCar(mContext, mServiceConnection, mHandler);
-        if (mCar != null) {
-            // note: this connect call handles the retries
-            mCar.connect();
-        }
-    }
-
-    /**
-     * Registers callbacks and initializes components upon connection.
-     */
-    private ServiceConnection mServiceConnection = new ServiceConnection() {
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            try {
-                service.linkToDeath(mRestart, 0);
-                mHvacManager = (CarHvacManager) mCar.getCarManager(Car.HVAC_SERVICE);
-                mHvacManager.registerCallback(mHardwareCallback);
-                initComponents();
-            } catch (Exception e) {
-                Log.e(TAG, "Failed to correctly connect to HVAC", e);
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            destroyHvacManager();
-        }
-    };
-
-    private void destroyHvacManager() {
-        if (mHvacManager != null) {
-            mHvacManager.unregisterCallback(mHardwareCallback);
-            mHvacManager = null;
-        }
-    }
-
-    /**
-     * If the connection to car service goes away then restart it.
-     */
-    private final IBinder.DeathRecipient mRestart = new IBinder.DeathRecipient() {
-        @Override
-        public void binderDied() {
-            Log.d(TAG, "Death of HVAC triggering a restart");
-            if (mCar != null) {
-                mCar.disconnect();
-            }
-            destroyHvacManager();
-            mHandler.postDelayed(() -> mCar.connect(), BIND_TO_HVAC_RETRY_DELAY);
-        }
-    };
-
-    /**
-     * Add component to list and initialize it if the connection is up.
-     * @param temperatureView
-     */
-    public void addHvacTextView(TemperatureView temperatureView) {
-
-        HvacKey hvacKey = new HvacKey(temperatureView.getPropertyId(), temperatureView.getAreaId());
-        if (!mTempComponents.containsKey(hvacKey)) {
-            mTempComponents.put(hvacKey, new ArrayList<>());
-        }
-        mTempComponents.get(hvacKey).add(temperatureView);
-        initComponent(temperatureView);
-    }
-
-    private void initComponents() {
-        Iterator<Map.Entry<HvacKey, List<TemperatureView>>> iterator =
-                mTempComponents.entrySet().iterator();
-        while (iterator.hasNext()) {
-            Map.Entry<HvacKey, List<TemperatureView>> next = iterator.next();
-            List<TemperatureView> temperatureViews = next.getValue();
-            for (TemperatureView view : temperatureViews) {
-                initComponent(view);
-            }
-        }
-    }
-
-
-    private void initComponent(TemperatureView view) {
-        int id = view.getPropertyId();
-        int zone = view.getAreaId();
-        try {
-            if (mHvacManager == null || !mHvacManager.isPropertyAvailable(id, zone)) {
-                view.setTemp(Float.NaN);
-                return;
-            }
-            view.setTemp(mHvacManager.getFloatProperty(id, zone));
-        } catch (Exception e) {
-            view.setTemp(Float.NaN);
-            Log.e(TAG, "Failed to get value from hvac service", e);
-        }
-    }
-
     /**
      * Callback for getting changes from {@link CarHvacManager} and setting the UI elements to
      * match.
@@ -179,10 +75,109 @@
 
         @Override
         public void onErrorEvent(final int propertyId, final int zone) {
-            Log.d(TAG, "HVAC error event, propertyId: " + propertyId +
-                    " zone: " + zone);
+            Log.d(TAG, "HVAC error event, propertyId: " + propertyId
+                    + " zone: " + zone);
         }
     };
+    /**
+     * If the connection to car service goes away then restart it.
+     */
+    private final IBinder.DeathRecipient mRestart = new IBinder.DeathRecipient() {
+        @Override
+        public void binderDied() {
+            Log.d(TAG, "Death of HVAC triggering a restart");
+            if (mCar != null) {
+                mCar.disconnect();
+            }
+            destroyHvacManager();
+            mHandler.postDelayed(() -> mCar.connect(), BIND_TO_HVAC_RETRY_DELAY);
+        }
+    };
+    /**
+     * Registers callbacks and initializes components upon connection.
+     */
+    private ServiceConnection mServiceConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            try {
+                service.linkToDeath(mRestart, 0);
+                mHvacManager = (CarHvacManager) mCar.getCarManager(Car.HVAC_SERVICE);
+                mHvacManager.registerCallback(mHardwareCallback);
+                initComponents();
+            } catch (Exception e) {
+                Log.e(TAG, "Failed to correctly connect to HVAC", e);
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            destroyHvacManager();
+        }
+    };
+
+    public HvacController(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Create connection to the Car service. Note: call backs from the Car service
+     * ({@link CarHvacManager}) will happen on the same thread this method was called from.
+     */
+    public void connectToCarService() {
+        mHandler = new Handler();
+        mCar = Car.createCar(mContext, mServiceConnection, mHandler);
+        if (mCar != null) {
+            // note: this connect call handles the retries
+            mCar.connect();
+        }
+    }
+
+    private void destroyHvacManager() {
+        if (mHvacManager != null) {
+            mHvacManager.unregisterCallback(mHardwareCallback);
+            mHvacManager = null;
+        }
+    }
+
+    /**
+     * Add component to list and initialize it if the connection is up.
+     */
+    public void addHvacTextView(TemperatureView temperatureView) {
+
+        HvacKey hvacKey = new HvacKey(temperatureView.getPropertyId(), temperatureView.getAreaId());
+        if (!mTempComponents.containsKey(hvacKey)) {
+            mTempComponents.put(hvacKey, new ArrayList<>());
+        }
+        mTempComponents.get(hvacKey).add(temperatureView);
+        initComponent(temperatureView);
+    }
+
+    private void initComponents() {
+        Iterator<Map.Entry<HvacKey, List<TemperatureView>>> iterator =
+                mTempComponents.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Map.Entry<HvacKey, List<TemperatureView>> next = iterator.next();
+            List<TemperatureView> temperatureViews = next.getValue();
+            for (TemperatureView view : temperatureViews) {
+                initComponent(view);
+            }
+        }
+    }
+
+    private void initComponent(TemperatureView view) {
+        int id = view.getPropertyId();
+        int zone = view.getAreaId();
+        try {
+            if (mHvacManager == null || !mHvacManager.isPropertyAvailable(id, zone)) {
+                view.setTemp(Float.NaN);
+                return;
+            }
+            view.setTemp(mHvacManager.getFloatProperty(id, zone));
+        } catch (Exception e) {
+            view.setTemp(Float.NaN);
+            Log.e(TAG, "Failed to get value from hvac service", e);
+        }
+    }
 
     /**
      * Removes all registered components. This is useful if you need to rebuild the UI since
@@ -200,7 +195,7 @@
         int mPropertyId;
         int mAreaId;
 
-        public HvacKey(int propertyId, int areaId) {
+        private HvacKey(int propertyId, int areaId) {
             mPropertyId = propertyId;
             mAreaId = areaId;
         }
@@ -210,8 +205,8 @@
             if (this == o) return true;
             if (o == null || getClass() != o.getClass()) return false;
             HvacKey hvacKey = (HvacKey) o;
-            return mPropertyId == hvacKey.mPropertyId &&
-                    mAreaId == hvacKey.mAreaId;
+            return mPropertyId == hvacKey.mPropertyId
+                    && mAreaId == hvacKey.mAreaId;
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
index 4d8ce43..507c60f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
@@ -40,7 +40,7 @@
     public TemperatureTextView(Context context, AttributeSet attrs) {
         super(context, attrs);
         TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TemperatureView);
-        mAreaId = typedArray.getInt(R.styleable.TemperatureView_hvacAreaId,-1);
+        mAreaId = typedArray.getInt(R.styleable.TemperatureView_hvacAreaId, -1);
         mPropertyId = typedArray.getInt(R.styleable.TemperatureView_hvacPropertyId, -1);
         String format = typedArray.getString(R.styleable.TemperatureView_hvacTempFormat);
         mTempFormat = (format == null) ? "%.1f\u00B0" : format;
@@ -48,6 +48,7 @@
 
     /**
      * Formats the float for display
+     *
      * @param temp - The current temp or NaN
      */
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureView.java
similarity index 100%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureView.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureView.java
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java
new file mode 100644
index 0000000..71cc19b
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java
@@ -0,0 +1,36 @@
+/*
+ * 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.volume;
+
+import android.content.Context;
+
+import com.android.systemui.SystemUI;
+import com.android.systemui.plugins.VolumeDialog;
+
+/**
+ * Allows for adding car specific dialog when the volume dialog is created.
+ */
+public class CarVolumeDialogComponent extends VolumeDialogComponent {
+
+    public CarVolumeDialogComponent(SystemUI sysui, Context context) {
+        super(sysui, context);
+    }
+
+    protected VolumeDialog createDefault() {
+        return new CarVolumeDialogImpl(mContext);
+    }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
new file mode 100644
index 0000000..12df263
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
@@ -0,0 +1,602 @@
+/*
+ * 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.volume;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
+import android.annotation.DrawableRes;
+import android.annotation.Nullable;
+import android.app.Dialog;
+import android.app.KeyguardManager;
+import android.car.Car;
+import android.car.CarNotConnectedException;
+import android.car.media.CarAudioManager;
+import android.car.media.ICarVolumeCallback;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.ServiceConnection;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.Xml;
+import android.view.ContextThemeWrapper;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+
+import androidx.car.widget.ListItem;
+import androidx.car.widget.ListItemAdapter;
+import androidx.car.widget.ListItemAdapter.BackgroundStyle;
+import androidx.car.widget.ListItemProvider.ListProvider;
+import androidx.car.widget.PagedListView;
+import androidx.car.widget.SeekbarListItem;
+
+import com.android.systemui.R;
+import com.android.systemui.plugins.VolumeDialog;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Car version of the volume dialog.
+ *
+ * Methods ending in "H" must be called on the (ui) handler.
+ */
+public class CarVolumeDialogImpl implements VolumeDialog {
+
+    private static final String TAG = Util.logTag(CarVolumeDialogImpl.class);
+
+    private static final String XML_TAG_VOLUME_ITEMS = "carVolumeItems";
+    private static final String XML_TAG_VOLUME_ITEM = "item";
+    private static final int HOVERING_TIMEOUT = 16000;
+    private static final int NORMAL_TIMEOUT = 3000;
+    private static final int LISTVIEW_ANIMATION_DURATION_IN_MILLIS = 250;
+    private static final int DISMISS_DELAY_IN_MILLIS = 50;
+    private static final int ARROW_FADE_IN_START_DELAY_IN_MILLIS = 100;
+
+    private final Context mContext;
+    private final H mHandler = new H();
+    // All the volume items.
+    private final SparseArray<VolumeItem> mVolumeItems = new SparseArray<>();
+    // Available volume items in car audio manager.
+    private final List<VolumeItem> mAvailableVolumeItems = new ArrayList<>();
+    // Volume items in the PagedListView.
+    private final List<ListItem> mVolumeLineItems = new ArrayList<>();
+    private final KeyguardManager mKeyguard;
+    private Window mWindow;
+    private CustomDialog mDialog;
+    private PagedListView mListView;
+    private ListItemAdapter mPagedListAdapter;
+    private Car mCar;
+    private CarAudioManager mCarAudioManager;
+    private final ICarVolumeCallback mVolumeChangeCallback = new ICarVolumeCallback.Stub() {
+        @Override
+        public void onGroupVolumeChanged(int groupId, int flags) {
+            VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
+            int value = getSeekbarValue(mCarAudioManager, groupId);
+            // Do not update the progress if it is the same as before. When car audio manager sets
+            // its group volume caused by the seekbar progress changed, it also triggers this
+            // callback. Updating the seekbar at the same time could block the continuous seeking.
+            if (value != volumeItem.progress) {
+                volumeItem.listItem.setProgress(value);
+                volumeItem.progress = value;
+            }
+            if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
+                mHandler.obtainMessage(H.SHOW, Events.SHOW_REASON_VOLUME_CHANGED).sendToTarget();
+            }
+        }
+
+        @Override
+        public void onMasterMuteChanged(int flags) {
+            // ignored
+        }
+    };
+    private boolean mHovering;
+    private boolean mShowing;
+    private boolean mExpanded;
+    private final ServiceConnection mServiceConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            try {
+                mExpanded = false;
+                mCarAudioManager = (CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE);
+                int volumeGroupCount = mCarAudioManager.getVolumeGroupCount();
+                // Populates volume slider items from volume groups to UI.
+                for (int groupId = 0; groupId < volumeGroupCount; groupId++) {
+                    VolumeItem volumeItem = getVolumeItemForUsages(
+                            mCarAudioManager.getUsagesForVolumeGroupId(groupId));
+                    mAvailableVolumeItems.add(volumeItem);
+                    // The first one is the default item.
+                    if (groupId == 0) {
+                        volumeItem.defaultItem = true;
+                        addSeekbarListItem(volumeItem, groupId,
+                                R.drawable.car_ic_keyboard_arrow_down,
+                                new ExpandIconListener());
+                    }
+                }
+
+                // If list is already initiated, update its content.
+                if (mPagedListAdapter != null) {
+                    mPagedListAdapter.notifyDataSetChanged();
+                }
+                mCarAudioManager.registerVolumeCallback(mVolumeChangeCallback.asBinder());
+            } catch (CarNotConnectedException e) {
+                Log.e(TAG, "Car is not connected!", e);
+            }
+        }
+
+        /**
+         * This does not get called when service is properly disconnected.
+         * So we need to also handle cleanups in destroy().
+         */
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            cleanupAudioManager();
+        }
+    };
+
+    public CarVolumeDialogImpl(Context context) {
+        mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
+        mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+        mCar = Car.createCar(mContext, mServiceConnection);
+    }
+
+    private static int getSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
+        try {
+            return carAudioManager.getGroupVolume(volumeGroupId);
+        } catch (CarNotConnectedException e) {
+            Log.e(TAG, "Car is not connected!", e);
+        }
+        return 0;
+    }
+
+    private static int getMaxSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
+        try {
+            return carAudioManager.getGroupMaxVolume(volumeGroupId);
+        } catch (CarNotConnectedException e) {
+            Log.e(TAG, "Car is not connected!", e);
+        }
+        return 0;
+    }
+
+    /**
+     * Build the volume window and connect to the CarService which registers with car audio
+     * manager.
+     */
+    @Override
+    public void init(int windowType, Callback callback) {
+        initDialog();
+
+        mCar.connect();
+    }
+
+    @Override
+    public void destroy() {
+        mHandler.removeCallbacksAndMessages(null);
+
+        cleanupAudioManager();
+        // unregisterVolumeCallback is not being called when disconnect car, so we manually cleanup
+        // audio manager beforehand.
+        mCar.disconnect();
+    }
+
+    private void initDialog() {
+        loadAudioUsageItems();
+        mVolumeLineItems.clear();
+        mDialog = new CustomDialog(mContext);
+
+        mHovering = false;
+        mShowing = false;
+        mExpanded = false;
+        mWindow = mDialog.getWindow();
+        mWindow.requestFeature(Window.FEATURE_NO_TITLE);
+        mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+        mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
+                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
+        mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+                | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
+        mWindow.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
+        mWindow.setWindowAnimations(com.android.internal.R.style.Animation_Toast);
+        final WindowManager.LayoutParams lp = mWindow.getAttributes();
+        lp.format = PixelFormat.TRANSLUCENT;
+        lp.setTitle(VolumeDialogImpl.class.getSimpleName());
+        lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
+        lp.windowAnimations = -1;
+        mWindow.setAttributes(lp);
+        mWindow.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+        mDialog.setCanceledOnTouchOutside(true);
+        mDialog.setContentView(R.layout.car_volume_dialog);
+        mDialog.setOnShowListener(dialog -> {
+            mListView.setTranslationY(-mListView.getHeight());
+            mListView.setAlpha(0);
+            mListView.animate()
+                    .alpha(1)
+                    .translationY(0)
+                    .setDuration(LISTVIEW_ANIMATION_DURATION_IN_MILLIS)
+                    .setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
+                    .start();
+        });
+        mListView = (PagedListView) mWindow.findViewById(R.id.volume_list);
+        mListView.setOnHoverListener((v, event) -> {
+            int action = event.getActionMasked();
+            mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
+                    || (action == MotionEvent.ACTION_HOVER_MOVE);
+            rescheduleTimeoutH();
+            return true;
+        });
+
+        mPagedListAdapter = new ListItemAdapter(mContext, new ListProvider(mVolumeLineItems),
+                BackgroundStyle.PANEL);
+        mListView.setAdapter(mPagedListAdapter);
+        mListView.setMaxPages(PagedListView.UNLIMITED_PAGES);
+    }
+
+
+    private void showH(int reason) {
+        if (D.BUG) {
+            Log.d(TAG, "showH r=" + Events.DISMISS_REASONS[reason]);
+        }
+
+        mHandler.removeMessages(H.SHOW);
+        mHandler.removeMessages(H.DISMISS);
+        rescheduleTimeoutH();
+        // Refresh the data set before showing.
+        mPagedListAdapter.notifyDataSetChanged();
+        if (mShowing) {
+            return;
+        }
+        mShowing = true;
+
+        mDialog.show();
+        Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
+    }
+
+    private void rescheduleTimeoutH() {
+        mHandler.removeMessages(H.DISMISS);
+        final int timeout = computeTimeoutH();
+        mHandler.sendMessageDelayed(mHandler
+                .obtainMessage(H.DISMISS, Events.DISMISS_REASON_TIMEOUT), timeout);
+
+        if (D.BUG) {
+            Log.d(TAG, "rescheduleTimeout " + timeout + " " + Debug.getCaller());
+        }
+    }
+
+    private int computeTimeoutH() {
+        return mHovering ? HOVERING_TIMEOUT : NORMAL_TIMEOUT;
+    }
+
+    private void dismissH(int reason) {
+        if (D.BUG) {
+            Log.d(TAG, "dismissH r=" + Events.DISMISS_REASONS[reason]);
+        }
+
+        mHandler.removeMessages(H.DISMISS);
+        mHandler.removeMessages(H.SHOW);
+        if (!mShowing) {
+            return;
+        }
+
+        mListView.animate().cancel();
+
+        mListView.setTranslationY(0);
+        mListView.setAlpha(1);
+        mListView.animate()
+                .alpha(0)
+                .translationY(-mListView.getHeight())
+                .setDuration(LISTVIEW_ANIMATION_DURATION_IN_MILLIS)
+                .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
+                .withEndAction(() -> mHandler.postDelayed(() -> {
+                    if (D.BUG) {
+                        Log.d(TAG, "mDialog.dismiss()");
+                    }
+                    mDialog.dismiss();
+                    mShowing = false;
+                }, DISMISS_DELAY_IN_MILLIS))
+                .start();
+
+        Events.writeEvent(mContext, Events.EVENT_DISMISS_DIALOG, reason);
+    }
+
+    private void loadAudioUsageItems() {
+        try (XmlResourceParser parser = mContext.getResources().getXml(R.xml.car_volume_items)) {
+            AttributeSet attrs = Xml.asAttributeSet(parser);
+            int type;
+            // Traverse to the first start tag
+            while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT
+                    && type != XmlResourceParser.START_TAG) {
+                // Do Nothing (moving parser to start element)
+            }
+
+            if (!XML_TAG_VOLUME_ITEMS.equals(parser.getName())) {
+                throw new RuntimeException("Meta-data does not start with carVolumeItems tag");
+            }
+            int outerDepth = parser.getDepth();
+            int rank = 0;
+            while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT
+                    && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) {
+                if (type == XmlResourceParser.END_TAG) {
+                    continue;
+                }
+                if (XML_TAG_VOLUME_ITEM.equals(parser.getName())) {
+                    TypedArray item = mContext.getResources().obtainAttributes(
+                            attrs, R.styleable.carVolumeItems_item);
+                    int usage = item.getInt(R.styleable.carVolumeItems_item_usage, -1);
+                    if (usage >= 0) {
+                        VolumeItem volumeItem = new VolumeItem();
+                        volumeItem.rank = rank;
+                        volumeItem.icon = item.getResourceId(R.styleable.carVolumeItems_item_icon,
+                                0);
+                        mVolumeItems.put(usage, volumeItem);
+                        rank++;
+                    }
+                    item.recycle();
+                }
+            }
+        } catch (XmlPullParserException | IOException e) {
+            Log.e(TAG, "Error parsing volume groups configuration", e);
+        }
+    }
+
+    private VolumeItem getVolumeItemForUsages(int[] usages) {
+        int rank = Integer.MAX_VALUE;
+        VolumeItem result = null;
+        for (int usage : usages) {
+            VolumeItem volumeItem = mVolumeItems.get(usage);
+            if (volumeItem.rank < rank) {
+                rank = volumeItem.rank;
+                result = volumeItem;
+            }
+        }
+        return result;
+    }
+
+    private SeekbarListItem addSeekbarListItem(VolumeItem volumeItem,
+            int volumeGroupId,
+            int supplementalIconId,
+            @Nullable View.OnClickListener supplementalIconOnClickListener) {
+        SeekbarListItem listItem = new SeekbarListItem(mContext);
+        listItem.setMax(getMaxSeekbarValue(mCarAudioManager, volumeGroupId));
+        int color = mContext.getResources().getColor(R.color.car_volume_dialog_tint);
+        int progress = getSeekbarValue(mCarAudioManager, volumeGroupId);
+        listItem.setProgress(progress);
+        listItem.setOnSeekBarChangeListener(new CarVolumeDialogImpl
+                .VolumeSeekBarChangeListener(volumeGroupId, mCarAudioManager));
+        Drawable primaryIcon = mContext.getResources().getDrawable(volumeItem.icon);
+        primaryIcon.mutate().setTint(color);
+        listItem.setPrimaryActionIcon(primaryIcon);
+        if (supplementalIconId != 0) {
+            Drawable supplementalIcon = mContext.getResources().getDrawable(supplementalIconId);
+            supplementalIcon.mutate().setTint(color);
+            listItem.setSupplementalIcon(supplementalIcon, true);
+            listItem.setSupplementalIconListener(supplementalIconOnClickListener);
+        } else {
+            listItem.setSupplementalEmptyIcon(true);
+            listItem.setSupplementalIconListener(null);
+        }
+
+        mVolumeLineItems.add(listItem);
+        volumeItem.listItem = listItem;
+        volumeItem.progress = progress;
+        return listItem;
+    }
+
+    private VolumeItem findVolumeItem(SeekbarListItem targetItem) {
+        for (int i = 0; i < mVolumeItems.size(); ++i) {
+            VolumeItem volumeItem = mVolumeItems.valueAt(i);
+            if (volumeItem.listItem == targetItem) {
+                return volumeItem;
+            }
+        }
+        return null;
+    }
+
+    private void cleanupAudioManager() {
+        try {
+            mCarAudioManager.unregisterVolumeCallback(mVolumeChangeCallback.asBinder());
+        } catch (CarNotConnectedException e) {
+            Log.e(TAG, "Car is not connected!", e);
+        }
+        mVolumeLineItems.clear();
+        mCarAudioManager = null;
+    }
+
+    /**
+     * Wrapper class which contains information of each volume group.
+     */
+    private static class VolumeItem {
+
+        private int rank;
+        private boolean defaultItem = false;
+        private @DrawableRes int icon;
+        private SeekbarListItem listItem;
+        private int progress;
+    }
+
+    private final class H extends Handler {
+
+        private static final int SHOW = 1;
+        private static final int DISMISS = 2;
+
+        private H() {
+            super(Looper.getMainLooper());
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case SHOW:
+                    showH(msg.arg1);
+                    break;
+                case DISMISS:
+                    dismissH(msg.arg1);
+                    break;
+                default:
+            }
+        }
+    }
+
+    private final class CustomDialog extends Dialog implements DialogInterface {
+
+        private CustomDialog(Context context) {
+            super(context, com.android.systemui.R.style.qs_theme);
+        }
+
+        @Override
+        public boolean dispatchTouchEvent(MotionEvent ev) {
+            rescheduleTimeoutH();
+            return super.dispatchTouchEvent(ev);
+        }
+
+        @Override
+        protected void onStart() {
+            super.setCanceledOnTouchOutside(true);
+            super.onStart();
+        }
+
+        @Override
+        protected void onStop() {
+            super.onStop();
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent event) {
+            if (isShowing()) {
+                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
+                    mHandler.obtainMessage(
+                            H.DISMISS, Events.DISMISS_REASON_TOUCH_OUTSIDE).sendToTarget();
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    private final class ExpandIconListener implements View.OnClickListener {
+
+        @Override
+        public void onClick(final View v) {
+            mExpanded = !mExpanded;
+            Animator inAnimator;
+            if (mExpanded) {
+                for (int groupId = 0; groupId < mAvailableVolumeItems.size(); ++groupId) {
+                    // Adding the items which are not coming from the default item.
+                    VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
+                    if (volumeItem.defaultItem) {
+                        // Set progress here due to the progress of seekbar may not be updated.
+                        volumeItem.listItem.setProgress(volumeItem.progress);
+                    } else {
+                        addSeekbarListItem(volumeItem, groupId, 0, null);
+                    }
+                }
+                inAnimator = AnimatorInflater.loadAnimator(
+                        mContext, R.anim.car_arrow_fade_in_rotate_up);
+            } else {
+                // Only keeping the default stream if it is not expended.
+                Iterator itr = mVolumeLineItems.iterator();
+                while (itr.hasNext()) {
+                    SeekbarListItem seekbarListItem = (SeekbarListItem) itr.next();
+                    VolumeItem volumeItem = findVolumeItem(seekbarListItem);
+                    if (!volumeItem.defaultItem) {
+                        itr.remove();
+                    } else {
+                        // Set progress here due to the progress of seekbar may not be updated.
+                        seekbarListItem.setProgress(volumeItem.progress);
+                    }
+                }
+                inAnimator = AnimatorInflater.loadAnimator(
+                        mContext, R.anim.car_arrow_fade_in_rotate_down);
+            }
+
+            Animator outAnimator = AnimatorInflater.loadAnimator(
+                    mContext, R.anim.car_arrow_fade_out);
+            inAnimator.setStartDelay(ARROW_FADE_IN_START_DELAY_IN_MILLIS);
+            AnimatorSet animators = new AnimatorSet();
+            animators.playTogether(outAnimator, inAnimator);
+            animators.setTarget(v);
+            animators.start();
+            mPagedListAdapter.notifyDataSetChanged();
+        }
+    }
+
+    private final class VolumeSeekBarChangeListener implements OnSeekBarChangeListener {
+
+        private final int mVolumeGroupId;
+        private final CarAudioManager mCarAudioManager;
+
+        private VolumeSeekBarChangeListener(int volumeGroupId, CarAudioManager carAudioManager) {
+            mVolumeGroupId = volumeGroupId;
+            mCarAudioManager = carAudioManager;
+        }
+
+        @Override
+        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+            if (!fromUser) {
+                // For instance, if this event is originated from AudioService,
+                // we can ignore it as it has already been handled and doesn't need to be
+                // sent back down again.
+                return;
+            }
+            try {
+                if (mCarAudioManager == null) {
+                    Log.w(TAG, "Ignoring volume change event because the car isn't connected");
+                    return;
+                }
+                mAvailableVolumeItems.get(mVolumeGroupId).progress = progress;
+                mCarAudioManager.setGroupVolume(mVolumeGroupId, progress, 0);
+            } catch (CarNotConnectedException e) {
+                Log.e(TAG, "Car is not connected!", e);
+            }
+        }
+
+        @Override
+        public void onStartTrackingTouch(SeekBar seekBar) {
+        }
+
+        @Override
+        public void onStopTrackingTouch(SeekBar seekBar) {
+        }
+    }
+}
diff --git a/packages/CarrierDefaultApp/OWNERS b/packages/CarrierDefaultApp/OWNERS
index 7057ce6..aef6a3c 100644
--- a/packages/CarrierDefaultApp/OWNERS
+++ b/packages/CarrierDefaultApp/OWNERS
@@ -9,4 +9,5 @@
 jminjie@google.com
 satk@google.com
 shuoq@google.com
-refuhoo@google.com
\ No newline at end of file
+refuhoo@google.com
+nazaninb@google.com
\ No newline at end of file
diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
index 4b212c2..0cad5af 100644
--- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java
+++ b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
@@ -19,8 +19,7 @@
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_MIN;
 import static android.service.notification.Adjustment.KEY_IMPORTANCE;
-import static android.service.notification.NotificationListenerService.Ranking
-        .USER_SENTIMENT_NEGATIVE;
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -241,7 +240,7 @@
             signals.putCharSequenceArrayList(Adjustment.KEY_SMART_REPLIES, smartReplies);
         }
         if (Settings.Secure.getInt(getContentResolver(),
-                Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL, 0) == 1) {
+                Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL, 1) == 1) {
             if (mNotificationCategorizer.shouldSilence(entry)) {
                 final int importance = entry.getImportance() < IMPORTANCE_LOW
                         ? entry.getImportance() : IMPORTANCE_LOW;
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index c9ee5c8..1eb4b74 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -224,7 +224,7 @@
                 root.flags |= Root.FLAG_REMOVABLE_USB;
             }
 
-            if (!VolumeInfo.ID_EMULATED_INTERNAL.equals(volume.getId())) {
+            if (volume.getType() != VolumeInfo.TYPE_EMULATED) {
                 root.flags |= Root.FLAG_SUPPORTS_EJECT;
             }
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 56b768f..df5b146 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1165,6 +1165,12 @@
                 GlobalSettingsProto.SmartSelection.UPDATE_METADATA_URL);
         p.end(smartSelectToken);
 
+        final long smartSuggestionsToken = p.start(GlobalSettingsProto.SMART_SUGGESTIONS);
+        dumpSetting(s, p,
+                Settings.Global.SMART_SUGGESTIONS_SERVICE_EXPLICITLY_ENABLED,
+                GlobalSettingsProto.SmartSuggestions.SERVICE_EXPLICITLY_ENABLED);
+        p.end(smartSuggestionsToken);
+
         final long smsToken = p.start(GlobalSettingsProto.SMS);
         dumpSetting(s, p,
                 Settings.Global.SMS_OUTGOING_CHECK_INTERVAL_MS,
@@ -1306,6 +1312,9 @@
         dumpSetting(s, p,
                 Settings.Global.WARNING_TEMPERATURE,
                 GlobalSettingsProto.TemperatureWarning.WARNING_TEMPERATURE_LEVEL);
+        dumpSetting(s, p,
+                Settings.Global.USB_ALARM_TEMPERATURE,
+                GlobalSettingsProto.TemperatureWarning.USB_ALARM_TEMPERATURE_LEVEL);
         p.end(tempWarningToken);
 
         final long tetherToken = p.start(GlobalSettingsProto.TETHER);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index cb55231..83e8369 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -130,6 +130,7 @@
     <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
     <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
     <uses-permission android:name="android.permission.MANAGE_AUTO_FILL" />
+    <uses-permission android:name="android.permission.MANAGE_SMART_SUGGESTIONS" />
     <uses-permission android:name="android.permission.NETWORK_SETTINGS" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.SET_TIME" />
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 0b9b27f..7d53c2f 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -223,6 +223,9 @@
 
     <uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS" />
 
+    <!-- Permission to change the display color -->
+    <uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
+
     <protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
     <protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
     <protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
diff --git a/packages/SystemUI/res/drawable/car_ic_music.xml b/packages/SystemUI/res/drawable/car_ic_music.xml
deleted file mode 100644
index f90cd69..0000000
--- a/packages/SystemUI/res/drawable/car_ic_music.xml
+++ /dev/null
@@ -1,30 +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="56dp"
-    android:height="56dp"
-    android:viewportWidth="48"
-    android:viewportHeight="48">
-
-  <path
-      android:fillAlpha=".1"
-      android:strokeAlpha=".1"
-      android:pathData="M0 0h48v48H0z" />
-  <path
-      android:fillColor="@color/car_grey_50"
-      android:pathData="M24 2C14.06 2 6 10.06 6 20v14c0 3.31 2.69 6 6 6h6V24h-8v-4c0-7.73 6.27-14
-14-14s14 6.27 14 14v4h-8v16h6c3.31 0 6-2.69 6-6V20c0-9.94-8.06-18-18-18z" />
-</vector>
diff --git a/packages/SystemUI/res/drawable/car_ic_navigation.xml b/packages/SystemUI/res/drawable/car_ic_navigation.xml
deleted file mode 100644
index 328efa0..0000000
--- a/packages/SystemUI/res/drawable/car_ic_navigation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2018 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="32dp"
-    android:height="37dp"
-    android:viewportWidth="32.0"
-    android:viewportHeight="37.0">
-  <path
-      android:pathData="M16.62,0.61L31.33,35.21C31.55,35.72 31.31,36.3 30.8,36.52C30.48,36.66 30.12,36.62 29.83,36.42L15.7,26.44L1.58,36.42C1.13,36.73 0.5,36.63 0.18,36.18C-0.02,35.89 -0.06,35.53 0.08,35.21L14.78,0.61C15,0.1 15.59,-0.14 16.1,0.08C16.33,0.18 16.52,0.37 16.62,0.61Z"
-      android:strokeColor="#00000000"
-      android:fillType="evenOdd"
-      android:fillColor="@color/car_grey_50"
-      android:strokeWidth="1"/>
-</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/car_ic_notification.xml b/packages/SystemUI/res/drawable/car_ic_notification.xml
deleted file mode 100644
index 61d937b90..0000000
--- a/packages/SystemUI/res/drawable/car_ic_notification.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-    Copyright (C) 2018 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="56dp"
-    android:height="56dp"
-    android:viewportWidth="48"
-    android:viewportHeight="48">
-
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M24 44c2.21 0 4-1.79 4-4h-8c0 2.21 1.79 4 4
-4zm12-12V22c0-6.15-3.27-11.28-9-12.64V8c0-1.66-1.34-3-3-3s-3 1.34-3 3v1.36c-5.73
-1.36-9 6.49-9 12.64v10l-4 4v2h32v-2l-4-4zm-4 2H16V22c0-4.97 3.03-9 8-9s8 4.03 8
-9v12z" />
-</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/car_ic_overview.xml b/packages/SystemUI/res/drawable/car_ic_overview.xml
deleted file mode 100644
index 4651dcb..0000000
--- a/packages/SystemUI/res/drawable/car_ic_overview.xml
+++ /dev/null
@@ -1,28 +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="56dp"
-    android:height="56dp"
-    android:viewportWidth="48"
-    android:viewportHeight="48">
-
-    <path
-        android:pathData="M0 0h48v48H0z" />
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M24 4C12.95 4 4 12.95 4 24s8.95 20 20 20 20-8.95 20-20S35.05 4 24 4zm0 36c-8.82
-0-16-7.18-16-16S15.18 8 24 8s16 7.18 16 16-7.18 16-16 16z" />
-</vector>
diff --git a/packages/SystemUI/res/drawable/car_rounded_bg_bottom.xml b/packages/SystemUI/res/drawable/car_rounded_bg_bottom.xml
deleted file mode 100644
index 25b449a..0000000
--- a/packages/SystemUI/res/drawable/car_rounded_bg_bottom.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle">
-    <solid android:color="?android:attr/colorBackgroundFloating" />
-    <corners
-        android:bottomLeftRadius="@dimen/car_radius_3"
-        android:topLeftRadius="0dp"
-        android:bottomRightRadius="@dimen/car_radius_3"
-        android:topRightRadius="0dp"
-        />
-</shape>
diff --git a/packages/SystemUI/res/layout/car_navigation_bar.xml b/packages/SystemUI/res/layout/car_navigation_bar.xml
deleted file mode 100644
index d568d0d..0000000
--- a/packages/SystemUI/res/layout/car_navigation_bar.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 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.
-*/
--->
-
-<com.android.systemui.statusbar.car.CarNavigationBarView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:background="@drawable/system_bar_background">
-
-    <LinearLayout
-        android:layout_height="match_parent"
-        android:layout_width="wrap_content"
-        android:orientation="horizontal"
-        android:id="@+id/nav_buttons"
-        android:gravity="left"
-        android:paddingLeft="30dp"
-        android:layout_weight="1"
-        android:animateLayoutChanges="true">
-
-        <com.android.systemui.statusbar.car.CarNavigationButton
-            android:id="@+id/home"
-            android:layout_height="match_parent"
-            android:layout_width="wrap_content"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
-            android:src="@drawable/car_ic_overview"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingLeft="30dp"
-            android:paddingRight="30dp"
-        />
-
-        <com.android.systemui.statusbar.car.CarNavigationButton
-            android:id="@+id/hvac"
-            android:layout_height="match_parent"
-            android:layout_width="wrap_content"
-            systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
-            systemui:broadcast="true"
-            android:src="@drawable/car_ic_hvac"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingLeft="30dp"
-            android:paddingRight="30dp"
-        />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:gravity="right"
-        android:orientation="horizontal">
-
-        <com.android.keyguard.AlphaOptimizedImageButton
-            android:id="@+id/notifications"
-            android:layout_height="match_parent"
-            android:layout_width="wrap_content"
-            android:src="@drawable/car_ic_notification"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingLeft="20dp"
-            android:paddingRight="20dp"
-            android:alpha="0.7"
-        />
-
-        <com.android.systemui.statusbar.policy.Clock
-            android:id="@+id/clock"
-            android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:singleLine="true"
-            android:paddingStart="@dimen/status_bar_clock_starting_padding"
-            android:paddingEnd="@dimen/status_bar_clock_end_padding"
-            android:gravity="center_vertical"
-            android:paddingRight="20dp"
-        />
-
-        <Space
-            android:layout_width="10dp"
-            android:layout_height="match_parent"/>
-
-    </LinearLayout>
-
-</com.android.systemui.statusbar.car.CarNavigationBarView>
-
diff --git a/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml b/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml
deleted file mode 100644
index 4ba6c06..0000000
--- a/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2018, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<com.android.systemui.statusbar.car.CarNavigationBarView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:background="@drawable/system_bar_background">
-
-    <LinearLayout
-        android:layout_height="match_parent"
-        android:layout_width="wrap_content"
-        android:orientation="horizontal"
-        android:id="@+id/nav_buttons"
-        android:gravity="left"
-        android:paddingLeft="30dp"
-        android:layout_weight="1"
-        android:animateLayoutChanges="true">
-
-        <com.android.systemui.statusbar.car.CarNavigationButton
-            android:id="@+id/home"
-            android:layout_height="match_parent"
-            android:layout_width="wrap_content"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
-            android:src="@drawable/car_ic_overview"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingLeft="30dp"
-            android:paddingRight="30dp"
-        />
-
-        <com.android.systemui.statusbar.car.CarNavigationButton
-            android:id="@+id/hvac"
-            android:layout_height="match_parent"
-            android:layout_width="wrap_content"
-            systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
-            systemui:broadcast="true"
-            android:src="@drawable/car_ic_hvac"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingLeft="30dp"
-            android:paddingRight="30dp"
-        />
-    </LinearLayout>
-</com.android.systemui.statusbar.car.CarNavigationBarView>
-
diff --git a/packages/SystemUI/res/layout/car_right_navigation_bar.xml b/packages/SystemUI/res/layout/car_right_navigation_bar.xml
deleted file mode 100644
index 91ba026..0000000
--- a/packages/SystemUI/res/layout/car_right_navigation_bar.xml
+++ /dev/null
@@ -1,101 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 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.
-*/
--->
-
-<com.android.systemui.statusbar.car.CarNavigationBarView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:orientation="vertical"
-    android:background="@drawable/system_bar_background">
-
-    <LinearLayout
-        android:layout_height="match_parent"
-        android:layout_width="match_parent"
-        android:id="@+id/nav_buttons"
-        android:orientation="vertical"
-        android:gravity="top"
-        android:paddingTop="30dp"
-        android:layout_weight="1"
-        android:background="@drawable/system_bar_background"
-        android:animateLayoutChanges="true">
-
-        <com.android.systemui.statusbar.car.CarNavigationButton
-            android:id="@+id/home"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
-            android:src="@drawable/car_ic_overview"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingTop="30dp"
-            android:paddingBottom="30dp"
-        />
-
-        <com.android.systemui.statusbar.car.CarNavigationButton
-            android:id="@+id/hvac"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
-            systemui:broadcast="true"
-            android:src="@drawable/car_ic_hvac"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingTop="30dp"
-            android:paddingBottom="30dp"
-        />
-
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:gravity="bottom"
-        android:orientation="vertical">
-
-        <com.android.keyguard.AlphaOptimizedImageButton
-            android:id="@+id/notifications"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            android:src="@drawable/car_ic_notification"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingTop="20dp"
-            android:paddingBottom="20dp"
-            android:alpha="0.7"
-        />
-
-
-        <com.android.systemui.statusbar.policy.Clock
-            android:id="@+id/clock"
-            android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            android:singleLine="true"
-            android:paddingStart="@dimen/status_bar_clock_starting_padding"
-            android:paddingEnd="@dimen/status_bar_clock_end_padding"
-            android:gravity="center_horizontal"
-            android:paddingBottom="20dp"
-        />
-
-        <Space
-            android:layout_height="10dp"
-            android:layout_width="match_parent"/>
-
-    </LinearLayout>
-
-</com.android.systemui.statusbar.car.CarNavigationBarView>
diff --git a/packages/SystemUI/res/layout/car_status_bar_header.xml b/packages/SystemUI/res/layout/car_status_bar_header.xml
deleted file mode 100644
index f2ef301..0000000
--- a/packages/SystemUI/res/layout/car_status_bar_header.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<!-- Extends LinearLayout -->
-<com.android.systemui.qs.car.CarStatusBarHeader
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/header"
-    android:layout_width="match_parent"
-    android:layout_height="@dimen/car_qs_header_system_icons_area_height"
-    android:paddingStart="8dp"
-    android:paddingEnd="8dp" >
-
-    <include layout="@layout/system_icons"
-             android:layout_width="wrap_content"
-             android:layout_height="match_parent"
-             android:gravity="center_vertical|end"
-             android:layout_weight="1"
-    />
-
-    <com.android.systemui.statusbar.policy.Clock
-        android:id="@+id/clock"
-        android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:singleLine="true"
-        android:paddingStart="@dimen/status_bar_clock_starting_padding"
-        android:paddingEnd="@dimen/status_bar_clock_end_padding"
-        android:gravity="center_vertical|end"
-    />
-</com.android.systemui.qs.car.CarStatusBarHeader>
diff --git a/packages/SystemUI/res/layout/car_top_navigation_bar.xml b/packages/SystemUI/res/layout/car_top_navigation_bar.xml
deleted file mode 100644
index e16014b..0000000
--- a/packages/SystemUI/res/layout/car_top_navigation_bar.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/**
-** Copyright 2018, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<com.android.systemui.statusbar.car.CarNavigationBarView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:background="@drawable/system_bar_background">
-
-    <com.android.systemui.statusbar.policy.Clock
-        android:id="@+id/clock"
-        android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:singleLine="true"
-        android:paddingStart="@dimen/status_bar_clock_starting_padding"
-        android:paddingEnd="@dimen/status_bar_clock_end_padding"
-        android:gravity="center_vertical"
-    />
-
-</com.android.systemui.statusbar.car.CarNavigationBarView>
-
diff --git a/packages/SystemUI/res/layout/car_volume_dialog.xml b/packages/SystemUI/res/layout/car_volume_dialog.xml
deleted file mode 100644
index a6beaa1..0000000
--- a/packages/SystemUI/res/layout/car_volume_dialog.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-     Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<androidx.car.widget.PagedListView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:background="@drawable/car_card_rounded_background"
-    android:id="@+id/volume_list"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_marginStart="@dimen/car_margin"
-    android:layout_marginEnd="@dimen/car_margin"
-    android:minWidth="@dimen/volume_dialog_panel_width"
-    android:theme="@style/Theme.Car.NoActionBar"
-    app:dividerStartMargin="@dimen/car_keyline_1"
-    app:dividerEndMargin="@dimen/car_keyline_1"
-    app:gutter="none"
-    app:showPagedListViewDivider="true"
-    app:scrollBarEnabled="false" />
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 0cc3c9e..34c208a 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -56,11 +56,6 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content" />
 
-    <ViewStub android:id="@+id/fullscreen_user_switcher_stub"
-              android:layout="@layout/car_fullscreen_user_switcher"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"/>
-
     <include layout="@layout/status_bar_expanded"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/values/arrays_car.xml b/packages/SystemUI/res/values/arrays_car.xml
deleted file mode 100644
index 8c760fc..0000000
--- a/packages/SystemUI/res/values/arrays_car.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources>
-    <!-- These should be overriden in an overlay. The default implementation is empty.
-         There needs to be correspondence per index between these arrays, which means that if there
-         isn't a longpress action associated with a shortcut item, put in an empty item to make
-         sure everything lines up.
-    -->
-    <array name="car_facet_icons" />
-    <array name="car_facet_intent_uris" />
-    <array name="car_facet_longpress_intent_uris" />
-    <array name="car_facet_package_filters"/>
-    <array name="car_facet_category_filters"/>
-</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index b0a519c..8e0bfb6 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -881,6 +881,7 @@
     <dimen name="smart_reply_button_stroke_width">1dp</dimen>
     <dimen name="smart_reply_button_font_size">14sp</dimen>
     <dimen name="smart_reply_button_line_spacing_extra">6sp</dimen> <!-- Total line height 20sp. -->
+    <dimen name="smart_action_button_icon_size">24dp</dimen>
     <dimen name="smart_action_button_icon_padding">10dp</dimen>
 
     <!-- A reasonable upper bound for the height of the smart reply button. The measuring code
diff --git a/packages/SystemUI/res/xml/car_volume_items.xml b/packages/SystemUI/res/xml/car_volume_items.xml
deleted file mode 100644
index 742dfdd..0000000
--- a/packages/SystemUI/res/xml/car_volume_items.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- * Copyright 2018, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
--->
-
-<!--
-  Defines all possible items on car volume settings UI, keyed by usage.
-
-  This enables the CarSettings UI to associate VolumeGroups surfaced by
-  CarAudioManager.getVolumeGroupCount with renderable assets (ie: title, icon)
-  for presentation.
-
-  Order matters in this configuration. If one volume group contains multiple
-  audio usages, the first one appears in this file would be picked to be
-  presented on UI.
-
-  When overriding this configuration, please consult also the
-  car_volume_groups.xml, which is read by car audio service.
--->
-<carVolumeItems xmlns:car="http://schemas.android.com/apk/res-auto">
-  <item car:usage="unknown"
-        car:icon="@drawable/car_ic_music"/>
-  <item car:usage="media"
-        car:icon="@drawable/car_ic_music"/>
-  <item car:usage="voice_communication"
-        car:icon="@*android:drawable/ic_audio_ring_notif"/>
-  <item car:usage="voice_communication_signalling"
-        car:icon="@*android:drawable/ic_audio_ring_notif"/>
-  <item car:usage="alarm"
-        car:icon="@*android:drawable/ic_audio_alarm"/>
-  <item car:usage="notification"
-        car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="notification_ringtone"
-        car:icon="@*android:drawable/ic_audio_ring_notif"/>
-  <item car:usage="notification_communication_request"
-        car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="notification_communication_instant"
-        car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="notification_communication_delayed"
-        car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="notification_event"
-        car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="assistance_accessibility"
-        car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="assistance_navigation_guidance"
-        car:icon="@drawable/car_ic_navigation"/>
-  <item car:usage="assistance_sonification"
-        car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="game"
-        car:icon="@drawable/car_ic_music"/>
-  <item car:usage="assistant"
-        car:icon="@drawable/car_ic_music"/>
-</carVolumeItems>
-
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 12699d5..18dc185 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
@@ -58,4 +58,8 @@
         encoder.endStream();
         return true;
     }
+
+    public int getDisplayId() {
+        return mWrapped.getDisplayId();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 417d516..867c917 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -62,6 +62,7 @@
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
 import com.android.systemui.statusbar.policy.SmartReplyConstants;
+import com.android.systemui.volume.VolumeDialogComponent;
 
 import java.util.function.Consumer;
 
@@ -132,6 +133,10 @@
         return new QSTileHost(context, statusBar, iconController);
     }
 
+    public VolumeDialogComponent createVolumeDialogComponent(SystemUI systemUi, Context context) {
+        return new VolumeDialogComponent(systemUi, context);
+    }
+
     public void injectDependencies(ArrayMap<Object, DependencyProvider> providers,
             Context context) {
         providers.put(StatusBarStateController.class, StatusBarStateController::new);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
index a90a7d2..ba89fe6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
@@ -140,7 +140,7 @@
         createDialogs();
 
         if (!mDialogs.isEmpty()) {
-            getComponent(CommandQueue.class).addCallbacks(this);
+            getComponent(CommandQueue.class).addCallback(this);
             mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java
deleted file mode 100644
index 09c000b..0000000
--- a/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.car;
-
-import android.content.Context;
-import android.util.ArrayMap;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.ViewMediatorCallback;
-import com.android.systemui.Dependency.DependencyProvider;
-import com.android.systemui.SystemUIFactory;
-import com.android.systemui.statusbar.NotificationMediaManager;
-import com.android.systemui.statusbar.car.CarFacetButtonController;
-import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.car.hvac.HvacController;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-
-/**
- * Class factory to provide car specific SystemUI components.
- */
-public class CarSystemUIFactory extends SystemUIFactory {
-
-    public StatusBarKeyguardViewManager createStatusBarKeyguardViewManager(Context context,
-            ViewMediatorCallback viewMediatorCallback, LockPatternUtils lockPatternUtils) {
-        return new CarStatusBarKeyguardViewManager(context, viewMediatorCallback, lockPatternUtils);
-    }
-
-    @Override
-    public void injectDependencies(ArrayMap<Object, DependencyProvider> providers,
-            Context context) {
-        super.injectDependencies(providers, context);
-        providers.put(NotificationEntryManager.class,
-                () -> new CarNotificationEntryManager(context));
-        providers.put(CarFacetButtonController.class, () -> new CarFacetButtonController(context));
-        providers.put(HvacController.class, () -> new HvacController(context));
-        providers.put(NotificationMediaManager.class,
-                () -> new CarNotificationMediaManager(context));
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
index 2c61da3..1718cff 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
@@ -108,7 +108,7 @@
                 UserHandle.USER_ALL);
 
         updateConfiguration();
-        Dependency.get(StatusBarStateController.class).addListener(mStateListener);
+        Dependency.get(StatusBarStateController.class).addCallback(mStateListener);
     }
 
     public static FalsingManager getInstance(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index bf8e04d..7e77843 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -401,7 +401,9 @@
                 }
                 mCallback.onSensorPulse(mPulseReason, sensorPerformsProxCheck, screenX, screenY,
                         event.values);
-                updateListener();  // reregister, this sensor only fires once
+                if (!mRegistered) {
+                    updateListener();  // reregister, this sensor only fires once
+                }
             }));
         }
 
@@ -440,7 +442,9 @@
                 mRegistered = false;
                 mCallback.onSensorPulse(mPulseReason, true /* sensorPerformsProxCheck */, -1, -1,
                         event.getValues());
-                updateListener();  // reregister, this sensor only fires once
+                if (!mRegistered) {
+                    updateListener();  // reregister, this sensor only fires once
+                }
             }));
         };
 
@@ -487,7 +491,6 @@
             }
             return sb.append(']').toString();
         }
-
     }
 
     public interface Callback {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index bad0148..afe9a74 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -184,6 +184,7 @@
             if (DEBUG) Log.i(TAG, "Prox changed, ignore touch = " + ignoreTouch);
             mDozeHost.onIgnoreTouchWhilePulsing(ignoreTouch);
         }
+
         if (far && (paused || pausing)) {
             if (DEBUG) Log.i(TAG, "Prox FAR, unpausing AOD");
             mMachine.requestState(DozeMachine.State.DOZE_AOD);
@@ -205,13 +206,13 @@
                     // In pocket, drop event.
                     return;
                 }
-                if (pausing || paused) {
+                if (mMachine.getState() == DozeMachine.State.DOZE) {
                     mMachine.requestState(DozeMachine.State.DOZE_AOD);
                 }
             }, false /* alreadyPerformedProxCheck */, DozeLog.REASON_SENSOR_WAKE_UP);
         } else {
             if (!pausing && !paused) {
-                mMachine.requestState(DozeMachine.State.DOZE_AOD_PAUSING);
+                mMachine.requestState(DozeMachine.State.DOZE);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
index aa08562..e8ef454 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
@@ -45,7 +45,7 @@
                 .withCallback(this::onExtensionCallback)
                 .build();
         mPlugin = mExtension.get();
-        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallbacks(this);
+        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallback(this);
     }
 
     private void onExtensionCallback(GlobalActions newPlugin) {
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index 0394998..dc11b4c 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -55,12 +55,12 @@
         mContext = context;
         mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
         mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
-        SysUiServiceProvider.getComponent(context, CommandQueue.class).addCallbacks(this);
+        SysUiServiceProvider.getComponent(context, CommandQueue.class).addCallback(this);
     }
 
     @Override
     public void destroy() {
-        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallbacks(this);
+        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallback(this);
         if (mGlobalActions != null) {
             mGlobalActions.destroy();
             mGlobalActions = null;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
index 7792e17..37c8163 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
@@ -58,7 +58,7 @@
                 : com.android.systemui.pip.phone.PipManager.getInstance();
         mPipManager.initialize(mContext);
 
-        getComponent(CommandQueue.class).addCallbacks(this);
+        getComponent(CommandQueue.class).addCallback(this);
         putComponent(PipUI.class, this);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 953eb70..2acbea4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -108,12 +108,12 @@
                 mQSPanel.getTileLayout().restoreInstanceState(savedInstanceState);
             }
         }
-        SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this);
+        SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallback(this);
     }
 
     @Override
     public void onDestroyView() {
-        SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).removeCallbacks(this);
+        SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).removeCallback(this);
         super.onDestroyView();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index d1c2df5..ca8e824 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -308,7 +308,7 @@
     protected static List<String> loadTileSpecs(Context context, String tileList) {
         final Resources res = context.getResources();
         final String defaultTileList = res.getString(R.string.quick_settings_tiles_default);
-        if (tileList == null) {
+        if (TextUtils.isEmpty(tileList)) {
             tileList = res.getString(R.string.quick_settings_tiles);
             if (DEBUG) Log.d(TAG, "Loaded tile specs from config: " + tileList);
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 0702d74..f13b565 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -37,7 +37,7 @@
 
     @Override
     public void start() {
-        getComponent(CommandQueue.class).addCallbacks(this);
+        getComponent(CommandQueue.class).addCallback(this);
         putComponent(Recents.class, this);
         mImpl = createRecentsImplementationFromConfig();
         mImpl.onStart(mContext, this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 8b93995..95019ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -35,6 +35,8 @@
 import com.android.internal.statusbar.IStatusBar;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.SystemUI;
+import com.android.systemui.statusbar.CommandQueue.Callbacks;
+import com.android.systemui.statusbar.policy.CallbackController;
 
 import java.util.ArrayList;
 
@@ -45,7 +47,7 @@
  * coalescing these calls so they don't stack up.  For the calls
  * are coalesced, note that they are all idempotent.
  */
-public class CommandQueue extends IStatusBar.Stub {
+public class CommandQueue extends IStatusBar.Stub implements CallbackController<Callbacks> {
     private static final int INDEX_MASK = 0xffff;
     private static final int MSG_SHIFT  = 16;
     private static final int MSG_MASK   = 0xffff << MSG_SHIFT;
@@ -183,12 +185,12 @@
                 && !ONLY_CORE_APPS;
     }
 
-    public void addCallbacks(Callbacks callbacks) {
+    public void addCallback(Callbacks callbacks) {
         mCallbacks.add(callbacks);
         callbacks.disable(mDisable1, mDisable2, false /* animate */);
     }
 
-    public void removeCallbacks(Callbacks callbacks) {
+    public void removeCallback(Callbacks callbacks) {
         mCallbacks.remove(callbacks);
     }
 
@@ -223,7 +225,9 @@
         }
     }
 
-    public void disable(int state1, int state2) {
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void disable(int displayId, int state1, int state2) {
         disable(state1, state2, true);
     }
 
@@ -266,8 +270,10 @@
         }
     }
 
-    public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
-            int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis,
+            int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
         synchronized (mLock) {
             // Don't coalesce these, since it might have one time flags set such as
             // STATUS_BAR_UNHIDE which might get lost.
@@ -282,7 +288,9 @@
         }
     }
 
-    public void topAppWindowChanged(boolean menuVisible) {
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void topAppWindowChanged(int displayId, boolean menuVisible) {
         synchronized (mLock) {
             mHandler.removeMessages(MSG_TOP_APP_WINDOW_CHANGED);
             mHandler.obtainMessage(MSG_TOP_APP_WINDOW_CHANGED, menuVisible ? 1 : 0, 0,
@@ -290,7 +298,9 @@
         }
     }
 
-    public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
             boolean showImeSwitcher) {
         synchronized (mLock) {
             mHandler.removeMessages(MSG_SHOW_IME_BUTTON);
@@ -371,7 +381,9 @@
         }
     }
 
-    public void setWindowState(int window, int state) {
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void setWindowState(int displayId, int window, int state) {
         synchronized (mLock) {
             // don't coalesce these
             mHandler.obtainMessage(MSG_SET_WINDOW_STATE, window, state, null).sendToTarget();
@@ -385,7 +397,9 @@
         }
     }
 
-    public void appTransitionPending() {
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void appTransitionPending(int displayId) {
         appTransitionPending(false /* forced */);
     }
 
@@ -395,13 +409,17 @@
         }
     }
 
-    public void appTransitionCancelled() {
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void appTransitionCancelled(int displayId) {
         synchronized (mLock) {
             mHandler.sendEmptyMessage(MSG_APP_TRANSITION_CANCELLED);
         }
     }
 
-    public void appTransitionStarting(long startTime, long duration) {
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void appTransitionStarting(int displayId, long startTime, long duration) {
         appTransitionStarting(startTime, duration, false /* forced */);
     }
 
@@ -412,8 +430,9 @@
         }
     }
 
+    // TODO(b/117478341): Add multi-display support.
     @Override
-    public void appTransitionFinished() {
+    public void appTransitionFinished(int displayId) {
         synchronized (mLock) {
             mHandler.sendEmptyMessage(MSG_APP_TRANSITION_FINISHED);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 960d221..7d1b640 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -156,7 +156,7 @@
                 new IntentFilter(Intent.ACTION_TIME_TICK), null,
                 Dependency.get(Dependency.TIME_TICK_HANDLER));
 
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
     }
 
     /**
@@ -167,7 +167,7 @@
      */
     public void destroy() {
         mContext.unregisterReceiver(mTickReceiver);
-        Dependency.get(StatusBarStateController.class).removeListener(this);
+        Dependency.get(StatusBarStateController.class).removeCallback(this);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index b0724b1..bba4369 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -165,7 +165,7 @@
         mCurrentUserId = ActivityManager.getCurrentUser();
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
         mLockPatternUtils = new LockPatternUtils(context);
         mKeyguardManager = context.getSystemService(KeyguardManager.class);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 7be5461..ecadf96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -141,7 +141,7 @@
                 ActivityManager.getService().resumeAppSwitches();
             } catch (RemoteException e) {
             }
-            return mCallback.handleRemoteViewClick(pendingIntent, () -> {
+            return mCallback.handleRemoteViewClick(view, pendingIntent, () -> {
                 Pair<Intent, ActivityOptions> options = response.getLaunchOptions(view);
                 options.second.setLaunchWindowingMode(
                         WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
@@ -666,11 +666,13 @@
          * Performs any special handling for a remote view click. The default behaviour can be
          * called through the defaultHandler parameter.
          *
+         * @param view
          * @param pendingIntent
          * @param defaultHandler
          * @return  true iff the click was handled
          */
-        boolean handleRemoteViewClick(PendingIntent pendingIntent, ClickHandler defaultHandler);
+        boolean handleRemoteViewClick(View view, PendingIntent pendingIntent,
+                ClickHandler defaultHandler);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index e7b4904..6cec36a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -121,13 +121,13 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         Dependency.get(StatusBarStateController.class)
-                .addListener(mStateListener, StatusBarStateController.RANK_SHELF);
+                .addCallback(mStateListener, StatusBarStateController.RANK_SHELF);
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        Dependency.get(StatusBarStateController.class).removeListener(mStateListener);
+        Dependency.get(StatusBarStateController.class).removeCallback(mStateListener);
     }
 
     public void bind(AmbientState ambientState, NotificationStackScrollLayout hostLayout) {
@@ -225,7 +225,7 @@
             }
             viewState.hasItemsInStableShelf = lastViewState.inShelf;
             viewState.hidden = !mAmbientState.isShadeExpanded()
-                    || mAmbientState.isQsCustomizerShowing();
+                    || mAmbientState.isQsCustomizerShowing() || mAmbientState.isFullyDark();
             viewState.maxShelfEnd = maxShelfEnd;
         } else {
             viewState.hidden = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index daa2fd4..dc3a607 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -129,7 +129,7 @@
                 res.getBoolean(R.bool.config_alwaysExpandNonGroupedNotifications);
         mStatusBarStateListener = new StatusBarStateListener(mBubbleController);
         mEntryManager.setStatusBarStateListener(mStatusBarStateListener);
-        Dependency.get(StatusBarStateController.class).addListener(mStatusBarStateListener);
+        Dependency.get(StatusBarStateController.class).addCallback(mStatusBarStateListener);
     }
 
     public void setUpWithPresenter(NotificationPresenter presenter,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
index eaf52cb..3f84416 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
@@ -26,8 +26,10 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.systemui.Interpolators;
+import com.android.systemui.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.policy.CallbackController;
 
 import java.lang.annotation.Retention;
 import java.util.ArrayList;
@@ -36,7 +38,7 @@
 /**
  * Tracks and reports on {@link StatusBarState}.
  */
-public class StatusBarStateController {
+public class StatusBarStateController implements CallbackController<StateListener> {
     private static final String TAG = "SbStateController";
 
     private static final int MAX_STATE = StatusBarState.FULLSCREEN_USER_SWITCHER;
@@ -228,7 +230,7 @@
         return mLastState == StatusBarState.SHADE_LOCKED;
     }
 
-    public void addListener(StateListener listener) {
+    public void addCallback(StateListener listener) {
         synchronized (mListeners) {
             addListenerInternalLocked(listener, Integer.MAX_VALUE);
         }
@@ -244,7 +246,7 @@
      * StatusBarState out of StatusBar.java. Any new listeners should be built not to need ranking
      * (i.e., they are non-dependent on the order of operations of StatusBarState listeners).
      */
-    public void addListener(StateListener listener, @SbStateListenerRank int rank) {
+    public void addCallback(StateListener listener, @SbStateListenerRank int rank) {
         synchronized (mListeners) {
             addListenerInternalLocked(listener, rank);
         }
@@ -264,7 +266,7 @@
         mListeners.sort(mComparator);
     }
 
-    public void removeListener(StateListener listener) {
+    public void removeCallback(StateListener listener) {
         synchronized (mListeners) {
             mListeners.removeIf((it) -> it.listener.equals(listener));
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java
deleted file mode 100644
index bd32856..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java
+++ /dev/null
@@ -1,186 +0,0 @@
-package com.android.systemui.statusbar.car;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.TypedArray;
-import android.os.UserHandle;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-
-import com.android.keyguard.AlphaOptimizedImageButton;
-import com.android.systemui.Dependency;
-import com.android.systemui.R;
-
-/**
- * CarFacetButton is a ui component designed to be used as a shortcut for an app of a defined
- * category. It can also render a indicator impling that there are more options of apps to launch
- * using this component. This is done with a "More icon" currently an arrow as defined in the layout
- * file. The class is to serve as an example.
- * Usage example: A button that allows a user to select a music app and indicate that there are
- * other music apps installed.
- */
-public class CarFacetButton extends LinearLayout {
-    private static final String FACET_FILTER_DELIMITER = ";";
-    /**
-     * Extra information to be sent to a helper to make the decision of what app to launch when
-     * clicked.
-     */
-    private static final String EXTRA_FACET_CATEGORIES = "categories";
-    private static final String EXTRA_FACET_PACKAGES = "packages";
-    private static final String EXTRA_FACET_ID = "filter_id";
-    private static final String EXTRA_FACET_LAUNCH_PICKER = "launch_picker";
-
-    private Context mContext;
-    private AlphaOptimizedImageButton mIcon;
-    private AlphaOptimizedImageButton mMoreIcon;
-    private boolean mSelected = false;
-    private String[] mComponentNames;
-    /** App categories that are to be used with this widget */
-    private String[] mFacetCategories;
-    /** App packages that are allowed to be used with this widget */
-    private String[] mFacetPackages;
-    private int mIconResourceId;
-    /**
-     * If defined in the xml this will be the icon that's rendered when the button is marked as
-     * selected
-     */
-    private int mSelectedIconResourceId;
-    private boolean mUseMoreIcon = true;
-    private float mSelectedAlpha = 1f;
-    private float mUnselectedAlpha = 1f;
-
-
-    public CarFacetButton(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mContext = context;
-        View.inflate(context, R.layout.car_facet_button, this);
-
-        // extract custom attributes
-        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CarFacetButton);
-        setupIntents(typedArray);
-        setupIcons(typedArray);
-        CarFacetButtonController carFacetButtonController = Dependency.get(
-                CarFacetButtonController.class);
-        carFacetButtonController.addFacetButton(this);
-
-    }
-
-    /**
-     * Reads the custom attributes to setup click handlers for this component.
-     */
-    private void setupIntents(TypedArray typedArray) {
-        String intentString = typedArray.getString(R.styleable.CarFacetButton_intent);
-        String longPressIntentString = typedArray.getString(R.styleable.CarFacetButton_longIntent);
-        String categoryString = typedArray.getString(R.styleable.CarFacetButton_categories);
-        String packageString = typedArray.getString(R.styleable.CarFacetButton_packages);
-        String componentNameString =
-                typedArray.getString(R.styleable.CarFacetButton_componentNames);
-        try {
-            final Intent intent = Intent.parseUri(intentString, Intent.URI_INTENT_SCHEME);
-            intent.putExtra(EXTRA_FACET_ID, Integer.toString(getId()));
-
-            if (packageString != null) {
-                mFacetPackages = packageString.split(FACET_FILTER_DELIMITER);
-                intent.putExtra(EXTRA_FACET_PACKAGES, mFacetPackages);
-            }
-            if (categoryString != null) {
-                mFacetCategories = categoryString.split(FACET_FILTER_DELIMITER);
-                intent.putExtra(EXTRA_FACET_CATEGORIES, mFacetCategories);
-            }
-            if (componentNameString != null) {
-                mComponentNames = componentNameString.split(FACET_FILTER_DELIMITER);
-            }
-
-            setOnClickListener(v -> {
-                intent.putExtra(EXTRA_FACET_LAUNCH_PICKER, mSelected);
-                mContext.startActivityAsUser(intent, UserHandle.CURRENT);
-            });
-
-            if (longPressIntentString != null) {
-                final Intent longPressIntent = Intent.parseUri(longPressIntentString,
-                        Intent.URI_INTENT_SCHEME);
-                setOnLongClickListener(v -> {
-                    mContext.startActivityAsUser(longPressIntent, UserHandle.CURRENT);
-                    return true;
-                });
-            }
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to attach intent", e);
-        }
-    }
-
-
-    private void setupIcons(TypedArray styledAttributes) {
-        mSelectedAlpha = styledAttributes.getFloat(
-                R.styleable.CarFacetButton_selectedAlpha, mSelectedAlpha);
-        mUnselectedAlpha = styledAttributes.getFloat(
-                R.styleable.CarFacetButton_unselectedAlpha, mUnselectedAlpha);
-        mIcon = findViewById(R.id.car_nav_button_icon);
-        mIcon.setScaleType(ImageView.ScaleType.CENTER);
-        mIcon.setClickable(false);
-        mIcon.setAlpha(mUnselectedAlpha);
-        mIconResourceId = styledAttributes.getResourceId(R.styleable.CarFacetButton_icon, 0);
-        mIcon.setImageResource(mIconResourceId);
-        mSelectedIconResourceId = styledAttributes.getResourceId(
-                R.styleable.CarFacetButton_selectedIcon, mIconResourceId);
-
-        mMoreIcon = findViewById(R.id.car_nav_button_more_icon);
-        mMoreIcon.setClickable(false);
-        mMoreIcon.setAlpha(mSelectedAlpha);
-        mMoreIcon.setVisibility(GONE);
-        mUseMoreIcon = styledAttributes.getBoolean(R.styleable.CarFacetButton_useMoreIcon, true);
-    }
-
-    /**
-     * @return The app categories the component represents
-     */
-    public String[] getCategories() {
-        if (mFacetCategories == null) {
-            return new String[0];
-        }
-        return mFacetCategories;
-    }
-
-    /**
-     * @return The valid packages that should be considered.
-     */
-    public String[] getFacetPackages() {
-        if (mFacetPackages == null) {
-            return new String[0];
-        }
-        return mFacetPackages;
-    }
-
-    public String[] getComponentName() {
-        if (mComponentNames == null) {
-            return new String[0];
-        }
-        return mComponentNames;
-    }
-
-    /**
-     * Updates the alpha of the icons to "selected" and shows the "More icon"
-     * @param selected true if the view must be selected, false otherwise
-     */
-    public void setSelected(boolean selected) {
-        super.setSelected(selected);
-        setSelected(selected, selected);
-    }
-
-    /**
-     * Updates the visual state to let the user know if it's been selected.
-     * @param selected true if should update the alpha of the icon to selected, false otherwise
-     * @param showMoreIcon true if the "more icon" should be shown, false otherwise. Note this
-     *                     is ignored if the attribute useMoreIcon is set to false
-     */
-    public void setSelected(boolean selected, boolean showMoreIcon) {
-        mSelected = selected;
-        mIcon.setAlpha(mSelected ? mSelectedAlpha : mUnselectedAlpha);
-        mIcon.setImageResource(mSelected ? mSelectedIconResourceId : mIconResourceId);
-        if (mUseMoreIcon) {
-            mMoreIcon.setVisibility(showMoreIcon ? VISIBLE : GONE);
-        }
-    }
-}
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 f506753..f899863 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -299,6 +299,10 @@
             return top;
         }
 
+        public int getBottom() {
+            return bottom;
+        }
+
         public int getWidth() {
             return right - left;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 1616b6d..70d144e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -952,10 +952,12 @@
 
         // Has a copy of the current UI adjustments.
         ArrayMap<String, NotificationUiAdjustment> oldAdjustments = new ArrayMap<>();
+        ArrayMap<String, Integer> oldImportances = new ArrayMap<>();
         for (NotificationData.Entry entry : entries) {
             NotificationUiAdjustment adjustment =
                     NotificationUiAdjustment.extractFromNotificationEntry(entry);
             oldAdjustments.put(entry.key, adjustment);
+            oldImportances.put(entry.key, entry.importance);
         }
 
         // Populate notification entries from the new rankings.
@@ -978,6 +980,11 @@
                     // Once the RowInflaterTask is done, it will pick up the updated entry, so
                     // no-op here.
                 }
+            } else if (oldImportances.containsKey(entry.key)
+                    && entry.importance != oldImportances.get(entry.key)) {
+                if (entry.rowExists()) {
+                    entry.getRow().onNotificationRankingUpdated();
+                }
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
index 1f48c15..09eb8a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
@@ -75,6 +75,6 @@
     /** Returns the value of the new interruption model setting. */
     public static boolean useNewInterruptionModel(Context context) {
         return Settings.Secure.getInt(context.getContentResolver(),
-                NOTIFICATION_NEW_INTERRUPTION_MODEL, 0) != 0;
+                NOTIFICATION_NEW_INTERRUPTION_MODEL, 1) != 0;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
index 87313b8..9f02e54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
@@ -149,7 +149,7 @@
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
         // Not expected to be destroyed, don't need to unsubscribe
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
     }
 
     public void setUpWithContainer(NotificationListContainer listContainer) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index d4d45ea..69e698f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -588,6 +588,13 @@
         updateRippleAllowed();
     }
 
+    /** Called when the notification's ranking was changed (but nothing else changed). */
+    public void onNotificationRankingUpdated() {
+        if (mMenuRow != null) {
+            mMenuRow.onNotificationUpdated(mStatusBarNotification);
+        }
+    }
+
     @VisibleForTesting
     void updateShelfIconColor() {
         StatusBarIconView expandedIcon = mEntry.expandedIcon;
@@ -2001,7 +2008,8 @@
         float interpolation = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(params.getProgress());
         int startClipTopAmount = params.getStartClipTopAmount();
         if (mNotificationParent != null) {
-            top -= mNotificationParent.getTranslationY();
+            float parentY = mNotificationParent.getTranslationY();
+            top -= parentY;
             mNotificationParent.setTranslationZ(translationZ);
             int parentStartClipTopAmount = params.getParentStartClipTopAmount();
             if (startClipTopAmount != 0) {
@@ -2011,8 +2019,12 @@
                 mNotificationParent.setClipTopAmount(clipTopAmount);
             }
             mNotificationParent.setExtraWidthForClipping(extraWidthForClipping);
-            mNotificationParent.setMinimumHeightForClipping(params.getHeight()
-                    + mNotificationParent.getActualHeight());
+            float clipBottom = Math.max(params.getBottom(),
+                    parentY + mNotificationParent.getActualHeight()
+                            - mNotificationParent.getClipBottomAmount());
+            float clipTop = Math.min(params.getTop(), parentY);
+            int minimumHeightForClipping = (int) (clipBottom - clipTop);
+            mNotificationParent.setMinimumHeightForClipping(minimumHeightForClipping);
         } else if (startClipTopAmount != 0) {
             int clipTopAmount = (int) MathUtils.lerp(startClipTopAmount, 0, interpolation);
             setClipTopAmount(clipTopAmount);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java
index 70860258..ef343fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java
@@ -697,7 +697,7 @@
                         && newView.getPackage() != null
                         && newView.getPackage().equals(oldView.getPackage())
                         && newView.getLayoutId() == oldView.getLayoutId()
-                        && !oldView.isReapplyDisallowed());
+                        && !oldView.hasFlags(RemoteViews.FLAG_REAPPLY_DISALLOWED));
     }
 
     public void setInflationCallback(InflationCallback callback) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index 948d2a5..50564e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -267,7 +267,9 @@
         } else {
             mRightMenuItems.add(mInfoItem);
             mRightMenuItems.add(mAppOpsItem);
-            mRightMenuItems.add(mSnoozeItem);
+            if (!isForeground) {
+                mRightMenuItems.add(mSnoozeItem);
+            }
         }
 
         populateMenuViews();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 5d640e0..eca1a14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -618,7 +618,7 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         Dependency.get(StatusBarStateController.class)
-                .addListener(mStateListener, StatusBarStateController.RANK_STACK_SCROLLER);
+                .addCallback(mStateListener, StatusBarStateController.RANK_STACK_SCROLLER);
         Dependency.get(ConfigurationController.class).addCallback(this);
     }
 
@@ -626,7 +626,7 @@
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        Dependency.get(StatusBarStateController.class).removeListener(mStateListener);
+        Dependency.get(StatusBarStateController.class).removeCallback(mStateListener);
         Dependency.get(ConfigurationController.class).removeCallback(this);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index 3b13fe9..24570ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -120,15 +120,15 @@
     @Override
     public void onResume() {
         super.onResume();
-        mCommandQueue.addCallbacks(this);
-        mStatusBarStateController.addListener(this);
+        mCommandQueue.addCallback(this);
+        mStatusBarStateController.addCallback(this);
     }
 
     @Override
     public void onPause() {
         super.onPause();
-        mCommandQueue.removeCallbacks(this);
-        mStatusBarStateController.removeListener(this);
+        mCommandQueue.removeCallback(this);
+        mStatusBarStateController.removeCallback(this);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index 94b2cde..cfa751c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -88,7 +88,7 @@
     public DozeScrimController(DozeParameters dozeParameters) {
         mDozeParameters = dozeParameters;
         //Never expected to be destroyed
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index 9faada0..aa0b7b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -129,7 +129,7 @@
                 updateTouchableRegionListener();
             }
         });
-        Dependency.get(StatusBarStateController.class).addListener(mStateListener);
+        Dependency.get(StatusBarStateController.class).addCallback(mStateListener);
         mBubbleController.setBubbleStateChangeListener((hasBubbles) -> {
             if (!hasBubbles) {
                 mBubbleGoingAway = true;
@@ -143,7 +143,7 @@
     }
 
     public void destroy() {
-        Dependency.get(StatusBarStateController.class).removeListener(mStateListener);
+        Dependency.get(StatusBarStateController.class).removeCallback(mStateListener);
     }
 
     private void initResources() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
index b29889d..57cc7d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
@@ -73,15 +73,15 @@
         mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
         mStatusBarStateController = Dependency.get(StatusBarStateController.class);
         SysUiServiceProvider.getComponent(context, CommandQueue.class)
-                .addCallbacks(this);
-        mStatusBarStateController.addListener(this);
+                .addCallback(this);
+        mStatusBarStateController.addCallback(this);
         mDozeAmount = mStatusBarStateController.getDozeAmount();
     }
 
     public void destroy(Context context) {
         SysUiServiceProvider.getComponent(context, CommandQueue.class)
-                .removeCallbacks(this);
-        mStatusBarStateController.removeListener(this);
+                .removeCallback(this);
+        mStatusBarStateController.removeCallback(this);
     }
 
     public void saveState(Bundle outState) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 8657003..d2bfd12 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -199,7 +199,7 @@
     public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mCommandQueue = SysUiServiceProvider.getComponent(getContext(), CommandQueue.class);
-        mCommandQueue.addCallbacks(this);
+        mCommandQueue.addCallback(this);
         mStatusBar = SysUiServiceProvider.getComponent(getContext(), StatusBar.class);
         mRecents = SysUiServiceProvider.getComponent(getContext(), Recents.class);
         mDivider = SysUiServiceProvider.getComponent(getContext(), Divider.class);
@@ -225,7 +225,7 @@
     @Override
     public void onDestroy() {
         super.onDestroy();
-        mCommandQueue.removeCallbacks(this);
+        mCommandQueue.removeCallback(this);
         Dependency.get(AccessibilityManagerWrapper.class).removeCallback(
                 mAccessibilityListener);
         mContentResolver.unregisterContentObserver(mMagnificationObserver);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
index 12a0cc8..3984405 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
@@ -24,7 +24,6 @@
 import android.view.Display;
 import android.view.IWallpaperVisibilityListener;
 import android.view.IWindowManager;
-import android.view.MotionEvent;
 import android.view.View;
 
 import com.android.internal.statusbar.IStatusBarService;
@@ -165,23 +164,4 @@
         }
         mView.onDarkIntensityChange(darkIntensity);
     }
-
-    private final View.OnTouchListener mLightsOutListener = new View.OnTouchListener() {
-        @Override
-        public boolean onTouch(View v, MotionEvent ev) {
-            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-                // even though setting the systemUI visibility below will turn these views
-                // on, we need them to come up faster so that they can catch this motion
-                // event
-                applyLightsOut(false, false, false);
-
-                try {
-                    mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE,
-                            "LightsOutListener");
-                } catch (android.os.RemoteException ex) {
-                }
-            }
-            return false;
-        }
-    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
index 3e31fa0..2a68fa5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
@@ -82,7 +82,7 @@
     private boolean mIsDozing;
 
     public NotificationGroupAlertTransferHelper() {
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
     }
 
     /**
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 448b5c3..8f4369a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -55,7 +55,7 @@
     private boolean mIsUpdatingUnchangedGroup;
 
     public NotificationGroupManager() {
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
     }
 
     /**
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 33d176a..a2a11bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -366,7 +366,7 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         FragmentHostManager.get(this).addTagListener(QS.TAG, mFragmentListener);
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
         Dependency.get(ZenModeController.class).addCallback(this);
         Dependency.get(ConfigurationController.class).addCallback(this);
     }
@@ -375,7 +375,7 @@
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         FragmentHostManager.get(this).removeTagListener(QS.TAG, mFragmentListener);
-        Dependency.get(StatusBarStateController.class).removeListener(this);
+        Dependency.get(StatusBarStateController.class).removeCallback(this);
         Dependency.get(ZenModeController.class).removeCallback(this);
         Dependency.get(ConfigurationController.class).removeCallback(this);
     }
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 c84f3db..ee1eb42 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -268,7 +268,7 @@
         mLocationController.addCallback(this);
         mPrivacyItemController.setListening(true);
 
-        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallbacks(this);
+        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallback(this);
         ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskListener);
 
         // Clear out all old notifications on startup (only present in the case where sysui dies)
@@ -296,7 +296,7 @@
         mKeyguardMonitor.removeCallback(this);
         mLocationController.removeCallback(this);
         mPrivacyItemController.setListening(false);
-        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallbacks(this);
+        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallback(this);
         mContext.unregisterReceiver(mIntentReceiver);
 
         NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index 2cbf27c..4983618 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -185,6 +185,7 @@
 
         // Requires proxy and an active gesture or able to perform any gesture to continue
         if (mOverviewEventSender.getProxy() == null
+                || !mOverviewEventSender.shouldShowSwipeUpUI()
                 || (mCurrentAction == null && !canPerformAnyAction())) {
             return deadZoneConsumed;
         }
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 5723948..962e214 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -161,7 +161,6 @@
 import com.android.systemui.qs.QSFragment;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSTileHost;
-import com.android.systemui.qs.car.CarQSFragment;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.ScreenPinningRequest;
 import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -580,6 +579,7 @@
     private boolean mVibrateOnOpening;
     private VibratorHelper mVibratorHelper;
     protected NotificationPresenter mPresenter;
+    private boolean mPulsing;
 
     @Override
     public void onActiveStateChanged(int code, int uid, String packageName, boolean active) {
@@ -628,7 +628,7 @@
         mBubbleController.setExpandListener(mBubbleExpandListener);
 
         mColorExtractor.addOnColorsChangedListener(this);
-        mStatusBarStateController.addListener(this, StatusBarStateController.RANK_STATUS_BAR);
+        mStatusBarStateController.addCallback(this, StatusBarStateController.RANK_STATUS_BAR);
 
         mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
         mDreamManager = IDreamManager.Stub.asInterface(
@@ -664,7 +664,7 @@
 
         // Connect in to the status bar manager service
         mCommandQueue = getComponent(CommandQueue.class);
-        mCommandQueue.addCallbacks(this);
+        mCommandQueue.addCallback(this);
 
         int[] switches = new int[9];
         ArrayList<IBinder> binders = new ArrayList<>();
@@ -920,8 +920,7 @@
                     Dependency.get(ExtensionController.class)
                             .newExtension(QS.class)
                             .withPlugin(QS.class)
-                            .withFeature(PackageManager.FEATURE_AUTOMOTIVE, CarQSFragment::new)
-                            .withDefault(QSFragment::new)
+                            .withDefault(this::createDefaultQSFragment)
                             .build());
             final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this,
                     mIconController);
@@ -1009,6 +1008,10 @@
         ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
     }
 
+    protected QS createDefaultQSFragment() {
+        return new QSFragment();
+    }
+
     protected void setUpPresenter() {
         // Set up the initial notification state.
         mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanel,
@@ -1542,7 +1545,7 @@
     }
 
     public boolean isPulsing() {
-        return mAmbientPulseManager.hasNotifications();
+        return mPulsing;
     }
 
     public boolean isLaunchTransitionFadingAway() {
@@ -2887,7 +2890,7 @@
         mContext.unregisterReceiver(mDemoReceiver);
         mAssistManager.destroy();
         mHeadsUpManager.destroy();
-        mStatusBarStateController.removeListener(this);
+        mStatusBarStateController.removeCallback(this);
 
         if (mQSPanel != null && mQSPanel.getHost() != null) {
             mQSPanel.getHost().destroy();
@@ -3933,6 +3936,10 @@
                 return;
             }
 
+            // Set the state to pulsing, so ScrimController will know what to do once we ask it to
+            // execute the transition. The pulse callback will then be invoked when the scrims
+            // are black, indicating that StatusBar is ready to present the rest of the UI.
+            mPulsing = true;
             mDozeScrimController.pulse(new PulseCallback() {
                 @Override
                 public void onPulseStarted() {
@@ -3946,6 +3953,7 @@
 
                 @Override
                 public void onPulseFinished() {
+                    mPulsing = false;
                     callback.onPulseFinished();
                     setPulsing(false);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index 7c17c01..4f25349 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -76,7 +76,7 @@
         loadDimens();
 
         SysUiServiceProvider.getComponent(context, CommandQueue.class)
-                .addCallbacks(this);
+                .addCallback(this);
         Dependency.get(TunerService.class).addTunable(this, ICON_BLACKLIST);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 484fe11..0f8970f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -151,7 +151,7 @@
         mLockPatternUtils = lockPatternUtils;
         mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
         KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitorCallback);
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
     }
 
     public void registerStatusBar(StatusBar statusBar,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
index a743d41e..e3f6bd8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
@@ -70,10 +70,10 @@
         mContext = context;
         mContext.registerReceiverAsUser(mChallengeReceiver, UserHandle.ALL,
                 new IntentFilter(ACTION_DEVICE_LOCKED_CHANGED), null, null);
-        mStatusBarStateController.addListener(mStateListener);
+        mStatusBarStateController.addCallback(mStateListener);
         mKeyguardManager = context.getSystemService(KeyguardManager.class);
         mCommandQueue = getComponent(context, CommandQueue.class);
-        mCommandQueue.addCallbacks(this);
+        mCommandQueue.addCallback(this);
     }
 
     private void setStatusBarState(int state) {
@@ -206,7 +206,7 @@
     }
 
     @Override
-    public boolean handleRemoteViewClick(PendingIntent pendingIntent,
+    public boolean handleRemoteViewClick(View view, PendingIntent pendingIntent,
             NotificationRemoteInputManager.ClickHandler defaultHandler) {
         final boolean isActivity = pendingIntent.isActivity();
         if (isActivity) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index 158ee8a..986a86d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -92,7 +92,7 @@
         mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation();
         mDozeParameters = dozeParameters;
         mScreenBrightnessDoze = mDozeParameters.getScreenBrightnessDoze();
-        Dependency.get(StatusBarStateController.class).addListener(
+        Dependency.get(StatusBarStateController.class).addCallback(
                 mStateListener, StatusBarStateController.RANK_STATUS_BAR_WINDOW_CONTROLLER);
         Dependency.get(ConfigurationController.class).addCallback(this);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index c2af95e..aafdcd5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -187,7 +187,7 @@
                     null, Dependency.get(Dependency.TIME_TICK_HANDLER));
             Dependency.get(TunerService.class).addTunable(this, CLOCK_SECONDS,
                     StatusBarIconController.ICON_BLACKLIST);
-            SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this);
+            SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallback(this);
             if (mShowDark) {
                 Dependency.get(DarkIconDispatcher.class).addDarkReceiver(this);
             }
@@ -215,7 +215,7 @@
             mAttached = false;
             Dependency.get(TunerService.class).removeTunable(this);
             SysUiServiceProvider.getComponent(getContext(), CommandQueue.class)
-                    .removeCallbacks(this);
+                    .removeCallback(this);
             if (mShowDark) {
                 Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(this);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java
index 639e50c..9c099f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.statusbar.policy;
 
-import android.os.SystemProperties;
+import android.sysprop.VoldProperties;
 
 /**
  * Helper for determining whether the phone is decrypted yet.
@@ -26,7 +26,7 @@
     public static final boolean IS_DATA_ENCRYPTED = isDataEncrypted();
 
     private static boolean isDataEncrypted() {
-        String voldState = SystemProperties.get("vold.decrypt");
+        String voldState = VoldProperties.decrypt().orElse("");
         return "1".equals(voldState) || "trigger_restart_min_framework".equals(voldState);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index f36066c..2a4336e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -21,7 +21,6 @@
 import android.text.method.TransformationMethod;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.util.Size;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -41,6 +40,7 @@
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
 
 import java.text.BreakIterator;
+import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
 import java.util.PriorityQueue;
@@ -282,9 +282,9 @@
 
         Drawable iconDrawable = action.getIcon().loadDrawable(context);
         // Add the action icon to the Smart Action button.
-        Size newIconSize = calculateIconSizeFromSingleLineButton(context, root,
-                new Size(iconDrawable.getIntrinsicWidth(), iconDrawable.getIntrinsicHeight()));
-        iconDrawable.setBounds(0, 0, newIconSize.getWidth(), newIconSize.getHeight());
+        int newIconSize = context.getResources().getDimensionPixelSize(
+                R.dimen.smart_action_button_icon_size);
+        iconDrawable.setBounds(0, 0, newIconSize, newIconSize);
         button.setCompoundDrawables(iconDrawable, null, null, null);
 
         button.setOnClickListener(view ->
@@ -295,30 +295,12 @@
 
         // TODO(b/119010281): handle accessibility
 
+        // Mark this as an Action button
+        final LayoutParams lp = (LayoutParams) button.getLayoutParams();
+        lp.buttonType = SmartButtonType.ACTION;
         return button;
     }
 
-    private static Size calculateIconSizeFromSingleLineButton(Context context, ViewGroup root,
-            Size originalIconSize) {
-        Button button = (Button) LayoutInflater.from(context).inflate(
-                R.layout.smart_action_button, root, false);
-        // Add simple text here to ensure the button displays one line of text.
-        button.setText("a");
-        return calculateIconSizeFromButtonHeight(button, originalIconSize);
-    }
-
-    // Given a button with text on a single line - we want to add an icon to that button. This
-    // method calculates the icon height to use to avoid making the button grow in height.
-    private static Size calculateIconSizeFromButtonHeight(Button button, Size originalIconSize) {
-        // A completely permissive measure spec should make the button text single-line.
-        button.measure(MEASURE_SPEC_ANY_LENGTH, MEASURE_SPEC_ANY_LENGTH);
-        int buttonHeight = button.getMeasuredHeight();
-        int newIconHeight = buttonHeight / 2;
-        int newIconWidth = (int) (originalIconSize.getWidth()
-                * ((double) newIconHeight) / originalIconSize.getHeight());
-        return new Size(newIconWidth, newIconHeight);
-    }
-
     @Override
     public LayoutParams generateLayoutParams(AttributeSet attrs) {
         return new LayoutParams(mContext, attrs);
@@ -352,18 +334,26 @@
         int displayedChildCount = 0;
         int buttonPaddingHorizontal = mSingleLineButtonPaddingHorizontal;
 
-        final int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            final View child = getChildAt(i);
+        // Set up a list of suggestions where actions come before replies. Note that the Buttons
+        // themselves have already been added to the view hierarchy in an order such that Smart
+        // Replies are shown before Smart Actions. The order of the list below determines which
+        // suggestions will be shown at all - only the first X elements are shown (where X depends
+        // on how much space each suggestion button needs).
+        List<View> smartActions = filterActionsOrReplies(SmartButtonType.ACTION);
+        List<View> smartReplies = filterActionsOrReplies(SmartButtonType.REPLY);
+        List<View> smartSuggestions = new ArrayList<>(smartActions);
+        smartSuggestions.addAll(smartReplies);
+        List<View> coveredSuggestions = new ArrayList<>();
+
+        for (View child : smartSuggestions) {
             final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-            if (child.getVisibility() != View.VISIBLE || !(child instanceof Button)) {
-                continue;
-            }
 
             child.setPadding(buttonPaddingHorizontal, child.getPaddingTop(),
                     buttonPaddingHorizontal, child.getPaddingBottom());
             child.measure(MEASURE_SPEC_ANY_LENGTH, heightMeasureSpec);
 
+            coveredSuggestions.add(child);
+
             final int lineCount = ((Button) child).getLineCount();
             if (lineCount < 1 || lineCount > 2) {
                 // If smart reply has no text, or more than two lines, then don't show it.
@@ -417,7 +407,8 @@
 
                     // Mark all buttons from the last squeezing round as "failed to squeeze", so
                     // that they're re-measured without squeezing later.
-                    markButtonsWithPendingSqueezeStatusAs(LayoutParams.SQUEEZE_STATUS_FAILED, i);
+                    markButtonsWithPendingSqueezeStatusAs(
+                            LayoutParams.SQUEEZE_STATUS_FAILED, coveredSuggestions);
 
                     // The current button doesn't fit, so there's no point in measuring further
                     // buttons.
@@ -426,7 +417,8 @@
 
                 // The current button fits, so mark all squeezed buttons as "successfully squeezed"
                 // to prevent them from being un-squeezed in a subsequent squeezing round.
-                markButtonsWithPendingSqueezeStatusAs(LayoutParams.SQUEEZE_STATUS_SUCCESSFUL, i);
+                markButtonsWithPendingSqueezeStatusAs(
+                        LayoutParams.SQUEEZE_STATUS_SUCCESSFUL, coveredSuggestions);
             }
 
             lp.show = true;
@@ -445,6 +437,22 @@
                         mPaddingTop + maxChildHeight + mPaddingBottom), heightMeasureSpec));
     }
 
+    private List<View> filterActionsOrReplies(SmartButtonType buttonType) {
+        List<View> actions = new ArrayList<>();
+        final int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = getChildAt(i);
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            if (child.getVisibility() != View.VISIBLE || !(child instanceof Button)) {
+                continue;
+            }
+            if (lp.buttonType == buttonType) {
+                actions.add(child);
+            }
+        }
+        return actions;
+    }
+
     private void resetButtonsLayoutParams() {
         final int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
@@ -615,9 +623,9 @@
         }
     }
 
-    private void markButtonsWithPendingSqueezeStatusAs(int squeezeStatus, int maxChildIndex) {
-        for (int i = 0; i <= maxChildIndex; i++) {
-            final View child = getChildAt(i);
+    private void markButtonsWithPendingSqueezeStatusAs(
+            int squeezeStatus, List<View> coveredChildren) {
+        for (View child : coveredChildren) {
             final LayoutParams lp = (LayoutParams) child.getLayoutParams();
             if (lp.squeezeStatus == LayoutParams.SQUEEZE_STATUS_PENDING) {
                 lp.squeezeStatus = squeezeStatus;
@@ -712,6 +720,11 @@
         return mActivityStarter;
     }
 
+    private enum SmartButtonType {
+        REPLY,
+        ACTION
+    }
+
     @VisibleForTesting
     static class LayoutParams extends ViewGroup.LayoutParams {
 
@@ -737,6 +750,7 @@
 
         private boolean show = false;
         private int squeezeStatus = SQUEEZE_STATUS_NONE;
+        private SmartButtonType buttonType = SmartButtonType.REPLY;
 
         private LayoutParams(Context c, AttributeSet attrs) {
             super(c, attrs);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index cd379c5..4a69cd7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -42,7 +42,7 @@
     public void start() {
         putComponent(TvStatusBar.class, this);
         CommandQueue commandQueue = getComponent(CommandQueue.class);
-        commandQueue.addCallbacks(this);
+        commandQueue.addCallback(this);
         int[] switches = new int[9];
         ArrayList<IBinder> binders = new ArrayList<>();
         ArrayList<String> iconSlots = new ArrayList<>();
diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java
index 6812410..490cdd5c 100644
--- a/packages/SystemUI/src/com/android/systemui/util/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java
@@ -57,13 +57,13 @@
         public void onViewAttachedToWindow(View v) {
             mView = v;
             SysUiServiceProvider.getComponent(v.getContext(), CommandQueue.class)
-                    .addCallbacks(this);
+                    .addCallback(this);
         }
 
         @Override
         public void onViewDetachedFromWindow(View v) {
             SysUiServiceProvider.getComponent(mView.getContext(), CommandQueue.class)
-                    .removeCallbacks(this);
+                    .removeCallback(this);
             mView = null;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
deleted file mode 100644
index 9b616e0..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.volume;
-
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.AnimatorSet;
-import android.annotation.DrawableRes;
-import android.annotation.Nullable;
-import android.app.Dialog;
-import android.app.KeyguardManager;
-import android.car.Car;
-import android.car.CarNotConnectedException;
-import android.car.media.CarAudioManager;
-import android.car.media.ICarVolumeCallback;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.ServiceConnection;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.media.AudioAttributes;
-import android.media.AudioManager;
-import android.os.Debug;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.Xml;
-import android.view.ContextThemeWrapper;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.SeekBar;
-import android.widget.SeekBar.OnSeekBarChangeListener;
-
-import androidx.car.widget.ListItem;
-import androidx.car.widget.ListItemAdapter;
-import androidx.car.widget.ListItemAdapter.BackgroundStyle;
-import androidx.car.widget.ListItemProvider.ListProvider;
-import androidx.car.widget.PagedListView;
-import androidx.car.widget.SeekbarListItem;
-
-import com.android.systemui.R;
-import com.android.systemui.plugins.VolumeDialog;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Car version of the volume dialog.
- *
- * Methods ending in "H" must be called on the (ui) handler.
- */
-public class CarVolumeDialogImpl implements VolumeDialog {
-  private static final String TAG = Util.logTag(CarVolumeDialogImpl.class);
-
-  private static final String XML_TAG_VOLUME_ITEMS = "carVolumeItems";
-  private static final String XML_TAG_VOLUME_ITEM = "item";
-  private static final int HOVERING_TIMEOUT = 16000;
-  private static final int NORMAL_TIMEOUT = 3000;
-  private static final int LISTVIEW_ANIMATION_DURATION_IN_MILLIS = 250;
-  private static final int DISMISS_DELAY_IN_MILLIS = 50;
-  private static final int ARROW_FADE_IN_START_DELAY_IN_MILLIS = 100;
-
-  private final Context mContext;
-  private final H mHandler = new H();
-
-  private Window mWindow;
-  private CustomDialog mDialog;
-  private PagedListView mListView;
-  private ListItemAdapter mPagedListAdapter;
-  // All the volume items.
-  private final SparseArray<VolumeItem> mVolumeItems = new SparseArray<>();
-  // Available volume items in car audio manager.
-  private final List<VolumeItem> mAvailableVolumeItems = new ArrayList<>();
-  // Volume items in the PagedListView.
-  private final List<ListItem> mVolumeLineItems = new ArrayList<>();
-  private final KeyguardManager mKeyguard;
-
-  private Car mCar;
-  private CarAudioManager mCarAudioManager;
-
-  private boolean mHovering;
-  private boolean mShowing;
-  private boolean mExpanded;
-
-  public CarVolumeDialogImpl(Context context) {
-    mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
-    mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
-    mCar = Car.createCar(mContext, mServiceConnection);
-  }
-
-  public void init(int windowType, Callback callback) {
-    initDialog();
-
-    mCar.connect();
-  }
-
-  @Override
-  public void destroy() {
-    mHandler.removeCallbacksAndMessages(null);
-
-    cleanupAudioManager();
-    // unregisterVolumeCallback is not being called when disconnect car, so we manually cleanup
-    // audio manager beforehand.
-    mCar.disconnect();
-  }
-
-  private void initDialog() {
-    loadAudioUsageItems();
-    mVolumeLineItems.clear();
-    mDialog = new CustomDialog(mContext);
-
-    mHovering = false;
-    mShowing = false;
-    mExpanded = false;
-    mWindow = mDialog.getWindow();
-    mWindow.requestFeature(Window.FEATURE_NO_TITLE);
-    mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
-    mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
-        | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
-    mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
-        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-        | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
-    mWindow.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
-    mWindow.setWindowAnimations(com.android.internal.R.style.Animation_Toast);
-    final WindowManager.LayoutParams lp = mWindow.getAttributes();
-    lp.format = PixelFormat.TRANSLUCENT;
-    lp.setTitle(VolumeDialogImpl.class.getSimpleName());
-    lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
-    lp.windowAnimations = -1;
-    mWindow.setAttributes(lp);
-    mWindow.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-
-    mDialog.setCanceledOnTouchOutside(true);
-    mDialog.setContentView(R.layout.car_volume_dialog);
-    mDialog.setOnShowListener(dialog -> {
-      mListView.setTranslationY(-mListView.getHeight());
-      mListView.setAlpha(0);
-      mListView.animate()
-          .alpha(1)
-          .translationY(0)
-          .setDuration(LISTVIEW_ANIMATION_DURATION_IN_MILLIS)
-          .setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
-          .start();
-    });
-    mListView = (PagedListView) mWindow.findViewById(R.id.volume_list);
-    mListView.setOnHoverListener((v, event) -> {
-      int action = event.getActionMasked();
-      mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
-          || (action == MotionEvent.ACTION_HOVER_MOVE);
-      rescheduleTimeoutH();
-      return true;
-    });
-
-    mPagedListAdapter = new ListItemAdapter(mContext, new ListProvider(mVolumeLineItems),
-        BackgroundStyle.PANEL);
-    mListView.setAdapter(mPagedListAdapter);
-    mListView.setMaxPages(PagedListView.UNLIMITED_PAGES);
-  }
-
-  public void show(int reason) {
-    mHandler.obtainMessage(H.SHOW, reason).sendToTarget();
-  }
-
-  public void dismiss(int reason) {
-    mHandler.obtainMessage(H.DISMISS, reason).sendToTarget();
-  }
-
-  private void showH(int reason) {
-    if (D.BUG) {
-      Log.d(TAG, "showH r=" + Events.DISMISS_REASONS[reason]);
-    }
-
-    mHandler.removeMessages(H.SHOW);
-    mHandler.removeMessages(H.DISMISS);
-    rescheduleTimeoutH();
-    // Refresh the data set before showing.
-    mPagedListAdapter.notifyDataSetChanged();
-    if (mShowing) {
-      return;
-    }
-    mShowing = true;
-
-    mDialog.show();
-    Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
-  }
-
-  protected void rescheduleTimeoutH() {
-    mHandler.removeMessages(H.DISMISS);
-    final int timeout = computeTimeoutH();
-    mHandler.sendMessageDelayed(mHandler
-        .obtainMessage(H.DISMISS, Events.DISMISS_REASON_TIMEOUT), timeout);
-
-    if (D.BUG) {
-      Log.d(TAG, "rescheduleTimeout " + timeout + " " + Debug.getCaller());
-    }
-  }
-
-  private int computeTimeoutH() {
-    return mHovering ? HOVERING_TIMEOUT : NORMAL_TIMEOUT;
-  }
-
-  protected void dismissH(int reason) {
-    if (D.BUG) {
-      Log.d(TAG, "dismissH r=" + Events.DISMISS_REASONS[reason]);
-    }
-
-    mHandler.removeMessages(H.DISMISS);
-    mHandler.removeMessages(H.SHOW);
-    if (!mShowing) {
-      return;
-    }
-
-    mListView.animate().cancel();
-
-    mListView.setTranslationY(0);
-    mListView.setAlpha(1);
-    mListView.animate()
-        .alpha(0)
-        .translationY(-mListView.getHeight())
-        .setDuration(LISTVIEW_ANIMATION_DURATION_IN_MILLIS)
-        .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
-        .withEndAction(() -> mHandler.postDelayed(() -> {
-          if (D.BUG) {
-            Log.d(TAG, "mDialog.dismiss()");
-          }
-          mDialog.dismiss();
-          mShowing = false;
-        }, DISMISS_DELAY_IN_MILLIS))
-        .start();
-
-    Events.writeEvent(mContext, Events.EVENT_DISMISS_DIALOG, reason);
-  }
-
-  public void dump(PrintWriter writer) {
-    writer.println(VolumeDialogImpl.class.getSimpleName() + " state:");
-    writer.print("  mShowing: "); writer.println(mShowing);
-  }
-
-  private void loadAudioUsageItems() {
-    try (XmlResourceParser parser = mContext.getResources().getXml(R.xml.car_volume_items)) {
-      AttributeSet attrs = Xml.asAttributeSet(parser);
-      int type;
-      // Traverse to the first start tag
-      while ((type=parser.next()) != XmlResourceParser.END_DOCUMENT
-          && type != XmlResourceParser.START_TAG) {
-      }
-
-      if (!XML_TAG_VOLUME_ITEMS.equals(parser.getName())) {
-        throw new RuntimeException("Meta-data does not start with carVolumeItems tag");
-      }
-      int outerDepth = parser.getDepth();
-      int rank = 0;
-      while ((type=parser.next()) != XmlResourceParser.END_DOCUMENT
-          && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) {
-        if (type == XmlResourceParser.END_TAG) {
-          continue;
-        }
-        if (XML_TAG_VOLUME_ITEM.equals(parser.getName())) {
-          TypedArray item = mContext.getResources().obtainAttributes(
-              attrs, R.styleable.carVolumeItems_item);
-          int usage = item.getInt(R.styleable.carVolumeItems_item_usage, -1);
-          if (usage >= 0) {
-            VolumeItem volumeItem = new VolumeItem();
-            volumeItem.usage = usage;
-            volumeItem.rank = rank;
-            volumeItem.icon = item.getResourceId(R.styleable.carVolumeItems_item_icon, 0);
-            mVolumeItems.put(usage, volumeItem);
-            rank++;
-          }
-          item.recycle();
-        }
-      }
-    } catch (XmlPullParserException | IOException e) {
-      Log.e(TAG, "Error parsing volume groups configuration", e);
-    }
-  }
-
-  private VolumeItem getVolumeItemForUsages(int[] usages) {
-    int rank = Integer.MAX_VALUE;
-    VolumeItem result = null;
-    for (int usage : usages) {
-      VolumeItem volumeItem = mVolumeItems.get(usage);
-      if (volumeItem.rank < rank) {
-        rank = volumeItem.rank;
-        result = volumeItem;
-      }
-    }
-    return result;
-  }
-
-  private static int getSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
-    try {
-      return carAudioManager.getGroupVolume(volumeGroupId);
-    } catch (CarNotConnectedException e) {
-      Log.e(TAG, "Car is not connected!", e);
-    }
-    return 0;
-  }
-
-  private static int getMaxSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
-    try {
-      return carAudioManager.getGroupMaxVolume(volumeGroupId);
-    } catch (CarNotConnectedException e) {
-      Log.e(TAG, "Car is not connected!", e);
-    }
-    return 0;
-  }
-
-  private SeekbarListItem addSeekbarListItem(VolumeItem volumeItem, int volumeGroupId,
-      int supplementalIconId, @Nullable View.OnClickListener supplementalIconOnClickListener) {
-    SeekbarListItem listItem = new SeekbarListItem(mContext);
-    listItem.setMax(getMaxSeekbarValue(mCarAudioManager, volumeGroupId));
-    int color = mContext.getResources().getColor(R.color.car_volume_dialog_tint);
-    int progress = getSeekbarValue(mCarAudioManager, volumeGroupId);
-    listItem.setProgress(progress);
-    listItem.setOnSeekBarChangeListener(
-        new CarVolumeDialogImpl.VolumeSeekBarChangeListener(volumeGroupId, mCarAudioManager));
-    Drawable primaryIcon = mContext.getResources().getDrawable(volumeItem.icon);
-    primaryIcon.mutate().setTint(color);
-    listItem.setPrimaryActionIcon(primaryIcon);
-    if (supplementalIconId != 0) {
-      Drawable supplementalIcon = mContext.getResources().getDrawable(supplementalIconId);
-      supplementalIcon.mutate().setTint(color);
-      listItem.setSupplementalIcon(supplementalIcon, true);
-      listItem.setSupplementalIconListener(supplementalIconOnClickListener);
-    } else {
-      listItem.setSupplementalEmptyIcon(true);
-      listItem.setSupplementalIconListener(null);
-    }
-
-    mVolumeLineItems.add(listItem);
-    volumeItem.listItem = listItem;
-    volumeItem.progress = progress;
-    return listItem;
-  }
-
-  private VolumeItem findVolumeItem(SeekbarListItem targetItem) {
-    for (int i = 0; i < mVolumeItems.size(); ++i) {
-      VolumeItem volumeItem = mVolumeItems.valueAt(i);
-      if (volumeItem.listItem == targetItem) {
-        return volumeItem;
-      }
-    }
-    return null;
-  }
-
-  private void cleanupAudioManager() {
-    try {
-      mCarAudioManager.unregisterVolumeCallback(mVolumeChangeCallback.asBinder());
-    } catch (CarNotConnectedException e) {
-      Log.e(TAG, "Car is not connected!", e);
-    }
-    mVolumeLineItems.clear();
-    mCarAudioManager = null;
-  }
-
-  private final class H extends Handler {
-    private static final int SHOW = 1;
-    private static final int DISMISS = 2;
-
-    public H() {
-      super(Looper.getMainLooper());
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-      switch (msg.what) {
-        case SHOW:
-          showH(msg.arg1);
-          break;
-        case DISMISS:
-          dismissH(msg.arg1);
-          break;
-        default:
-      }
-    }
-  }
-
-  private final class CustomDialog extends Dialog implements DialogInterface {
-    public CustomDialog(Context context) {
-      super(context, com.android.systemui.R.style.qs_theme);
-    }
-
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent ev) {
-      rescheduleTimeoutH();
-      return super.dispatchTouchEvent(ev);
-    }
-
-    @Override
-    protected void onStart() {
-      super.setCanceledOnTouchOutside(true);
-      super.onStart();
-    }
-
-    @Override
-    protected void onStop() {
-      super.onStop();
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-      if (isShowing()) {
-        if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
-          mHandler.obtainMessage(
-            H.DISMISS, Events.DISMISS_REASON_TOUCH_OUTSIDE).sendToTarget();
-          return true;
-        }
-      }
-      return false;
-    }
-  }
-
-  private final class ExpandIconListener implements View.OnClickListener {
-    @Override
-    public void onClick(final View v) {
-      mExpanded = !mExpanded;
-      Animator inAnimator;
-      if (mExpanded) {
-        for (int groupId = 0; groupId < mAvailableVolumeItems.size(); ++groupId) {
-          // Adding the items which are not coming from the default item.
-          VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
-          if (volumeItem.defaultItem) {
-            // Set progress here due to the progress of seekbar may not be updated.
-            volumeItem.listItem.setProgress(volumeItem.progress);
-          } else {
-            addSeekbarListItem(volumeItem, groupId, 0, null);
-          }
-        }
-        inAnimator = AnimatorInflater.loadAnimator(
-            mContext, R.anim.car_arrow_fade_in_rotate_up);
-      } else {
-        // Only keeping the default stream if it is not expended.
-        Iterator itr = mVolumeLineItems.iterator();
-        while (itr.hasNext()) {
-          SeekbarListItem seekbarListItem = (SeekbarListItem) itr.next();
-          VolumeItem volumeItem = findVolumeItem(seekbarListItem);
-          if (!volumeItem.defaultItem) {
-            itr.remove();
-          } else {
-            // Set progress here due to the progress of seekbar may not be updated.
-            seekbarListItem.setProgress(volumeItem.progress);
-          }
-        }
-        inAnimator = AnimatorInflater.loadAnimator(
-            mContext, R.anim.car_arrow_fade_in_rotate_down);
-      }
-
-      Animator outAnimator = AnimatorInflater.loadAnimator(
-          mContext, R.anim.car_arrow_fade_out);
-      inAnimator.setStartDelay(ARROW_FADE_IN_START_DELAY_IN_MILLIS);
-      AnimatorSet animators = new AnimatorSet();
-      animators.playTogether(outAnimator, inAnimator);
-      animators.setTarget(v);
-      animators.start();
-      mPagedListAdapter.notifyDataSetChanged();
-    }
-  }
-
-  private final class VolumeSeekBarChangeListener implements OnSeekBarChangeListener {
-    private final int mVolumeGroupId;
-    private final CarAudioManager mCarAudioManager;
-
-    private VolumeSeekBarChangeListener(int volumeGroupId, CarAudioManager carAudioManager) {
-      mVolumeGroupId = volumeGroupId;
-      mCarAudioManager = carAudioManager;
-    }
-
-    @Override
-    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-      if (!fromUser) {
-        // For instance, if this event is originated from AudioService,
-        // we can ignore it as it has already been handled and doesn't need to be
-        // sent back down again.
-        return;
-      }
-      try {
-        if (mCarAudioManager == null) {
-          Log.w(TAG, "Ignoring volume change event because the car isn't connected");
-          return;
-        }
-        mAvailableVolumeItems.get(mVolumeGroupId).progress = progress;
-        mCarAudioManager.setGroupVolume(mVolumeGroupId, progress, 0);
-      } catch (CarNotConnectedException e) {
-        Log.e(TAG, "Car is not connected!", e);
-      }
-    }
-
-    @Override
-    public void onStartTrackingTouch(SeekBar seekBar) {}
-
-    @Override
-    public void onStopTrackingTouch(SeekBar seekBar) {}
-  }
-
-  private final ICarVolumeCallback mVolumeChangeCallback = new ICarVolumeCallback.Stub() {
-    @Override
-    public void onGroupVolumeChanged(int groupId, int flags) {
-      VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
-      int value = getSeekbarValue(mCarAudioManager, groupId);
-      // Do not update the progress if it is the same as before. When car audio manager sets its
-      // group volume caused by the seekbar progress changed, it also triggers this callback.
-      // Updating the seekbar at the same time could block the continuous seeking.
-      if (value != volumeItem.progress) {
-        volumeItem.listItem.setProgress(value);
-        volumeItem.progress = value;
-      }
-      if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
-        show(Events.SHOW_REASON_VOLUME_CHANGED);
-      }
-    }
-
-    @Override
-    public void onMasterMuteChanged(int flags) {
-      // ignored
-    }
-  };
-
-  private final ServiceConnection mServiceConnection = new ServiceConnection() {
-    @Override
-    public void onServiceConnected(ComponentName name, IBinder service) {
-      try {
-        mExpanded = false;
-        mCarAudioManager = (CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE);
-        int volumeGroupCount = mCarAudioManager.getVolumeGroupCount();
-        // Populates volume slider items from volume groups to UI.
-        for (int groupId = 0; groupId < volumeGroupCount; groupId++) {
-          VolumeItem volumeItem = getVolumeItemForUsages(
-              mCarAudioManager.getUsagesForVolumeGroupId(groupId));
-          mAvailableVolumeItems.add(volumeItem);
-          // The first one is the default item.
-          if (groupId == 0) {
-            volumeItem.defaultItem = true;
-            addSeekbarListItem(volumeItem, groupId, R.drawable.car_ic_keyboard_arrow_down,
-                new ExpandIconListener());
-          }
-        }
-
-        // If list is already initiated, update its content.
-        if (mPagedListAdapter != null) {
-          mPagedListAdapter.notifyDataSetChanged();
-        }
-        mCarAudioManager.registerVolumeCallback(mVolumeChangeCallback.asBinder());
-      } catch (CarNotConnectedException e) {
-        Log.e(TAG, "Car is not connected!", e);
-      }
-    }
-
-    /**
-     * This does not get called when service is properly disconnected.
-     * So we need to also handle cleanups in destroy().
-     */
-    @Override
-    public void onServiceDisconnected(ComponentName name) {
-      cleanupAudioManager();
-    }
-  };
-
-  /**
-   * Wrapper class which contains information of each volume group.
-   */
-  private static class VolumeItem {
-    private @AudioAttributes.AttributeUsage int usage;
-    private int rank;
-    private boolean defaultItem = false;
-    private @DrawableRes int icon;
-    private SeekbarListItem listItem;
-    private int progress;
-  }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
index 2861dff..0805677 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
@@ -19,12 +19,10 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.media.AudioManager;
 import android.media.VolumePolicy;
 import android.os.Bundle;
-import android.os.Handler;
 import android.view.WindowManager.LayoutParams;
 
 import com.android.settingslib.applications.InterestingConfigChanges;
@@ -57,7 +55,7 @@
     public static final boolean DEFAULT_DO_NOT_DISTURB_WHEN_SILENT = false;
 
     private final SystemUI mSysui;
-    private final Context mContext;
+    protected final Context mContext;
     private final VolumeDialogControllerImpl mController;
     private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges(
             ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_LOCALE
@@ -70,7 +68,7 @@
             400    // vibrateToSilentDebounce
     );
 
-    public VolumeDialogComponent(SystemUI sysui, Context context, Handler handler) {
+    public VolumeDialogComponent(SystemUI sysui, Context context) {
         mSysui = sysui;
         mContext = context;
         mController = (VolumeDialogControllerImpl) Dependency.get(VolumeDialogController.class);
@@ -81,7 +79,6 @@
         Dependency.get(ExtensionController.class).newExtension(VolumeDialog.class)
                 .withPlugin(VolumeDialog.class)
                 .withDefault(this::createDefault)
-                .withFeature(PackageManager.FEATURE_AUTOMOTIVE, this::createCarDefault)
                 .withCallback(dialog -> {
                     if (mDialog != null) {
                         mDialog.destroy();
@@ -94,7 +91,7 @@
                 VOLUME_SILENT_DO_NOT_DISTURB);
     }
 
-    private VolumeDialog createDefault() {
+    protected VolumeDialog createDefault() {
         VolumeDialogImpl impl = new VolumeDialogImpl(mContext);
         impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false);
         impl.setAutomute(true);
@@ -102,10 +99,6 @@
         return impl;
     }
 
-    private VolumeDialog createCarDefault() {
-        return new CarVolumeDialogImpl(mContext);
-    }
-
     @Override
     public void onTuningChanged(String key, String newValue) {
         if (VOLUME_DOWN_SILENT.equals(key)) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index e4f37de..f8cf793 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -22,6 +22,7 @@
 
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
+import com.android.systemui.SystemUIFactory;
 import com.android.systemui.qs.tiles.DndTile;
 
 import java.io.FileDescriptor;
@@ -43,7 +44,9 @@
             mContext.getResources().getBoolean(R.bool.enable_safety_warning);
         mEnabled = enableVolumeUi || enableSafetyWarning;
         if (!mEnabled) return;
-        mVolumeComponent = new VolumeDialogComponent(this, mContext, null);
+
+        mVolumeComponent = SystemUIFactory.getInstance()
+                .createVolumeDialogComponent(this, mContext);
         mVolumeComponent.setEnableDialogs(enableVolumeUi, enableSafetyWarning);
         putComponent(VolumeComponent.class, getVolumeComponent());
         setDefaultVolumeController();
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index b32bf99..83ec33c 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -38,8 +38,6 @@
     android.test.runner \
     telephony-common \
     android.test.base \
-    android.car \
-    android.car.userlib
 
 LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui:com.android.keyguard
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
new file mode 100644
index 0000000..78700b8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.qs;
+
+
+import static junit.framework.TestCase.assertFalse;
+
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class QSTileHostTest extends SysuiTestCase {
+
+    @Test
+    public void testLoadTileSpecs_emptySetting() {
+        List<String> tiles = QSTileHost.loadTileSpecs(mContext, "");
+        assertFalse(tiles.isEmpty());
+    }
+
+    @Test
+    public void testLoadTileSpecs_nullSetting() {
+        List<String> tiles = QSTileHost.loadTileSpecs(mContext, null);
+        assertFalse(tiles.isEmpty());
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/car/CarQsFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/car/CarQsFragmentTest.java
deleted file mode 100644
index f89a932..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/car/CarQsFragmentTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.android.systemui.qs.car;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.mock;
-
-import android.content.Context;
-import android.support.test.filters.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.LayoutInflaterBuilder;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import com.android.keyguard.CarrierText;
-import com.android.systemui.Dependency;
-import com.android.systemui.SysuiBaseFragmentTest;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.policy.Clock;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests for {@link CarQSFragment}.
- */
-@RunWith(AndroidTestingRunner.class)
-@RunWithLooper(setAsMainLooper = true)
-@SmallTest
-@Ignore
-public class CarQsFragmentTest extends SysuiBaseFragmentTest {
-    public CarQsFragmentTest() {
-        super(CarQSFragment.class);
-    }
-
-    @Before
-    public void initDependencies() {
-        mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE,
-                new LayoutInflaterBuilder(mContext)
-                        .replace("com.android.systemui.statusbar.policy.SplitClockView",
-                                FrameLayout.class)
-                        .replace("TextClock", View.class)
-                        .replace(CarrierText.class, View.class)
-                        .replace(Clock.class, View.class)
-                        .build());
-        mSysuiContext.putComponent(CommandQueue.class, mock(CommandQueue.class));
-        mDependency.injectTestDependency(Dependency.BG_LOOPER,
-                TestableLooper.get(this).getLooper());
-    }
-
-    @Test
-    @Ignore("Flaky")
-    public void testLayoutInflation() {
-        CarQSFragment fragment = (CarQSFragment) mFragment;
-        mFragments.dispatchResume();
-
-        assertNotNull(fragment.getHeader());
-        assertNotNull(fragment.getFooter());
-    }
-
-    @Test
-    @Ignore("Flaky")
-    public void testListening() {
-        CarQSFragment qs = (CarQSFragment) mFragment;
-        mFragments.dispatchResume();
-        processAllMessages();
-
-        qs.setListening(true);
-        processAllMessages();
-
-        qs.setListening(false);
-        processAllMessages();
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index 8ae3cd8..a04e57b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -14,6 +14,8 @@
 
 package com.android.systemui.statusbar;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -42,7 +44,7 @@
     public void setup() {
         mCommandQueue = new CommandQueue();
         mCallbacks = mock(Callbacks.class);
-        mCommandQueue.addCallbacks(mCallbacks);
+        mCommandQueue.addCallback(mCallbacks);
         verify(mCallbacks).disable(eq(0), eq(0), eq(false));
     }
 
@@ -64,11 +66,12 @@
         verify(mCallbacks).removeIcon(eq(slot));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testDisable() {
         int state1 = 14;
         int state2 = 42;
-        mCommandQueue.disable(state1, state2);
+        mCommandQueue.disable(DEFAULT_DISPLAY, state1, state2);
         waitForIdleSync();
         verify(mCallbacks).disable(eq(state1), eq(state2), eq(true));
     }
@@ -95,24 +98,27 @@
         verify(mCallbacks).animateExpandSettingsPanel(eq(panel));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testSetSystemUiVisibility() {
         Rect r = new Rect();
-        mCommandQueue.setSystemUiVisibility(1, 2, 3, 4, null, r);
+        mCommandQueue.setSystemUiVisibility(DEFAULT_DISPLAY, 1, 2, 3, 4, null, r);
         waitForIdleSync();
         verify(mCallbacks).setSystemUiVisibility(eq(1), eq(2), eq(3), eq(4), eq(null), eq(r));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testTopAppWindowChanged() {
-        mCommandQueue.topAppWindowChanged(true);
+        mCommandQueue.topAppWindowChanged(DEFAULT_DISPLAY, true);
         waitForIdleSync();
         verify(mCallbacks).topAppWindowChanged(eq(true));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testShowImeButton() {
-        mCommandQueue.setImeWindowStatus(null, 1, 2, true);
+        mCommandQueue.setImeWindowStatus(DEFAULT_DISPLAY, null, 1, 2, true);
         waitForIdleSync();
         verify(mCallbacks).setImeWindowStatus(eq(null), eq(1), eq(2), eq(true));
     }
@@ -166,9 +172,10 @@
         verify(mCallbacks).toggleKeyboardShortcutsMenu(eq(1));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testSetWindowState() {
-        mCommandQueue.setWindowState(1, 2);
+        mCommandQueue.setWindowState(DEFAULT_DISPLAY, 1, 2);
         waitForIdleSync();
         verify(mCallbacks).setWindowState(eq(1), eq(2));
     }
@@ -180,30 +187,34 @@
         verify(mCallbacks).showScreenPinningRequest(eq(1));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testAppTransitionPending() {
-        mCommandQueue.appTransitionPending();
+        mCommandQueue.appTransitionPending(DEFAULT_DISPLAY);
         waitForIdleSync();
         verify(mCallbacks).appTransitionPending(eq(false));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testAppTransitionCancelled() {
-        mCommandQueue.appTransitionCancelled();
+        mCommandQueue.appTransitionCancelled(DEFAULT_DISPLAY);
         waitForIdleSync();
         verify(mCallbacks).appTransitionCancelled();
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testAppTransitionStarting() {
-        mCommandQueue.appTransitionStarting(1, 2);
+        mCommandQueue.appTransitionStarting(DEFAULT_DISPLAY, 1, 2);
         waitForIdleSync();
         verify(mCallbacks).appTransitionStarting(eq(1L), eq(2L), eq(false));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testAppTransitionFinished() {
-        mCommandQueue.appTransitionFinished();
+        mCommandQueue.appTransitionFinished(DEFAULT_DISPLAY);
         waitForIdleSync();
         verify(mCallbacks).appTransitionFinished();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
index 906e718..51492da 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
@@ -25,7 +25,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.app.Notification;
+import android.app.NotificationChannel;
 import android.service.notification.StatusBarNotification;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -35,6 +35,7 @@
 import android.view.ViewGroup;
 
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.utils.leaks.LeakCheckedTest;
 
 import org.junit.Before;
@@ -43,19 +44,26 @@
 import org.mockito.Mockito;
 
 @RunWith(AndroidTestingRunner.class)
-@RunWithLooper()
+@RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class NotificationMenuRowTest extends LeakCheckedTest {
 
+    private ExpandableNotificationRow mRow;
+
     @Before
     public void setup() {
         injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
+        mRow = mock(ExpandableNotificationRow.class);
+        NotificationData.Entry entry = new NotificationData.Entry(
+                mock(StatusBarNotification.class));
+        entry.channel = mock(NotificationChannel.class);
+        when(mRow.getEntry()).thenReturn(entry);
     }
 
     @Test
     public void testAttachDetach() {
         NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
-        row.createMenu(null, null);
+        row.createMenu(mRow, null);
         ViewUtils.attachView(row.getMenuView());
         TestableLooper.get(this).processAllMessages();
         ViewUtils.detachView(row.getMenuView());
@@ -65,9 +73,9 @@
     @Test
     public void testRecreateMenu() {
         NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
-        row.createMenu(null, null);
+        row.createMenu(mRow, null);
         assertTrue(row.getMenuView() != null);
-        row.createMenu(null, null);
+        row.createMenu(mRow, null);
         assertTrue(row.getMenuView() != null);
     }
 
@@ -81,12 +89,7 @@
     @Test
     public void testNoAppOpsInSlowSwipe() {
         NotificationMenuRow row = new NotificationMenuRow(mContext);
-        Notification n = mock(Notification.class);
-        StatusBarNotification sbn = mock(StatusBarNotification.class);
-        when(sbn.getNotification()).thenReturn(n);
-        ExpandableNotificationRow parent = mock(ExpandableNotificationRow.class);
-        when(parent.getStatusBarNotification()).thenReturn(sbn);
-        row.createMenu(parent, null);
+        row.createMenu(mRow, null);
 
         ViewGroup container = (ViewGroup) row.getMenuView();
         // one for snooze and one for noti blocking
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
index 8fc15b2..1783d0c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
@@ -78,6 +78,7 @@
         mProxyService = mock(OverviewProxyService.class);
         mProxy = mock(IOverviewProxy.Stub.class);
         doReturn(mProxy).when(mProxyService).getProxy();
+        doReturn(true).when(mProxyService).shouldShowSwipeUpUI();
         mDependency.injectTestDependency(OverviewProxyService.class, mProxyService);
 
         mStatusBar = mock(StatusBar.class);
@@ -106,6 +107,18 @@
     }
 
     @Test
+    public void testNoGesturesWhenSwipeUpDisabled() throws Exception {
+        doReturn(false).when(mProxyService).shouldShowSwipeUpUI();
+        mController.setGestureActions(mockAction(true), null /* swipeDownAction */,
+                null /* swipeLeftAction */, null /* swipeRightAction */);
+
+        MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
+        assertFalse(mController.onInterceptTouchEvent(ev));
+        verify(mNavigationBarView, never()).requestUnbufferedDispatch(ev);
+        assertNull(mController.getCurrentAction());
+    }
+
+    @Test
     public void testHasActionDetectGesturesTouchdown() throws Exception {
         MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
 
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 e9e8eb7..c207fef 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
@@ -72,6 +72,8 @@
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.classifier.FalsingManager;
+import com.android.systemui.doze.DozeHost;
+import com.android.systemui.doze.DozeLog;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
@@ -123,6 +125,7 @@
     @Mock private IStatusBarService mBarService;
     @Mock private IDreamManager mDreamManager;
     @Mock private ScrimController mScrimController;
+    @Mock private DozeScrimController mDozeScrimController;
     @Mock private ArrayList<Entry> mNotificationList;
     @Mock private BiometricUnlockController mBiometricUnlockController;
     @Mock private NotificationData mNotificationData;
@@ -211,7 +214,7 @@
                 mKeyguardViewMediator, mRemoteInputManager, mock(NotificationGroupManager.class),
                 mock(NotificationGroupAlertTransferHelper.class), mock(FalsingManager.class),
                 mock(StatusBarWindowController.class), mock(NotificationIconAreaController.class),
-                mock(DozeScrimController.class), mock(NotificationShelf.class),
+                mDozeScrimController, mock(NotificationShelf.class),
                 mLockscreenUserManager, mCommandQueue, mNotificationPresenter,
                 mock(BubbleController.class));
         mStatusBar.mContext = mContext;
@@ -570,7 +573,28 @@
     }
 
     @Test
+    public void testPulseWhileDozing_updatesScrimController() {
+        mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
+        mStatusBar.showKeyguardImpl();
 
+        // Keep track of callback to be able to stop the pulse
+        DozeHost.PulseCallback[] pulseCallback = new DozeHost.PulseCallback[1];
+        doAnswer(invocation -> {
+            pulseCallback[0] = invocation.getArgument(0);
+            return null;
+        }).when(mDozeScrimController).pulse(any(), anyInt());
+
+        // Starting a pulse should change the scrim controller to the pulsing state
+        mStatusBar.mDozeServiceHost.pulseWhileDozing(mock(DozeHost.PulseCallback.class),
+                DozeLog.PULSE_REASON_NOTIFICATION);
+        verify(mScrimController).transitionTo(eq(ScrimState.PULSING), any());
+
+        // Ending a pulse should take it back to keyguard state
+        pulseCallback[0].onPulseFinished();
+        verify(mScrimController).transitionTo(eq(ScrimState.KEYGUARD));
+    }
+
+    @Test
     public void testSetState_changesIsFullScreenUserSwitcherState() {
         mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
         assertFalse(mStatusBar.isFullScreenUserSwitcherState());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index df7aeab..506fa97 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -801,4 +801,55 @@
         assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(1), mView.getChildAt(1));
         assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(2), mView.getChildAt(2));
     }
+
+    @Test
+    public void testMeasure_choicesAndActionsPrioritizeActionsOnlyActions() {
+        String[] choices = new String[] {"Reply"};
+        String[] actions = new String[] {"Looooooong actioooon", "second action", "third action"};
+
+        // All actions should be displayed as DOUBLE-line smart action buttons.
+        ViewGroup expectedView = buildExpectedView(new String[0], 2,
+                createActions(new String[] {
+                        "Looooooong \nactioooon", "second \naction", "third \naction"}));
+        expectedView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+
+        setSmartRepliesAndActions(choices, actions);
+        mView.measure(
+                MeasureSpec.makeMeasureSpec(expectedView.getMeasuredWidth(), MeasureSpec.AT_MOST),
+                MeasureSpec.UNSPECIFIED);
+
+        assertEqualMeasures(expectedView, mView);
+        // smart replies
+        assertReplyButtonHidden(mView.getChildAt(0));
+        // smart actions
+        assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(0), mView.getChildAt(1));
+        assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(1), mView.getChildAt(2));
+        assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(2), mView.getChildAt(3));
+    }
+
+    @Test
+    public void testMeasure_choicesAndActionsPrioritizeActions() {
+        String[] choices = new String[] {"Short", "longer reply"};
+        String[] actions = new String[] {"Looooooong actioooon", "second action"};
+
+        // All actions should be displayed as DOUBLE-line smart action buttons.
+        ViewGroup expectedView = buildExpectedView(new String[] {"Short"}, 2,
+                createActions(new String[] {"Looooooong \nactioooon", "second \naction"}));
+        expectedView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+
+        setSmartRepliesAndActions(choices, actions);
+        mView.measure(
+                MeasureSpec.makeMeasureSpec(expectedView.getMeasuredWidth(), MeasureSpec.AT_MOST),
+                MeasureSpec.UNSPECIFIED);
+
+        Button firstAction = ((Button) mView.getChildAt(1));
+
+        assertEqualMeasures(expectedView, mView);
+        // smart replies
+        assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(0), mView.getChildAt(0));
+        assertReplyButtonHidden(mView.getChildAt(1));
+        // smart actions
+        assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(1), mView.getChildAt(2));
+        assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(2), mView.getChildAt(3));
+    }
 }
diff --git a/packages/overlays/AdaptiveIconChangeOverlay/Android.mk b/packages/overlays/AdaptiveIconChangeOverlay/Android.mk
new file mode 100644
index 0000000..6e3b8cb
--- /dev/null
+++ b/packages/overlays/AdaptiveIconChangeOverlay/Android.mk
@@ -0,0 +1,30 @@
+#
+#  Copyright 2018, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := SquareIcon
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := SquareIconOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/AdaptiveIconChangeOverlay/AndroidManifest.xml b/packages/overlays/AdaptiveIconChangeOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..33da510
--- /dev/null
+++ b/packages/overlays/AdaptiveIconChangeOverlay/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<!--
+/**
+ * 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.theme.icon.square"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <overlay android:targetPackage="android"
+        android:category="android.theme.customization.adaptive_icon_shape"
+        android:priority="1"/>
+
+    <application android:label="@string/square_icon_overlay" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/AdaptiveIconChangeOverlay/res/values/config.xml b/packages/overlays/AdaptiveIconChangeOverlay/res/values/config.xml
new file mode 100644
index 0000000..54623f5
--- /dev/null
+++ b/packages/overlays/AdaptiveIconChangeOverlay/res/values/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2018, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Specifies the path that is used by AdaptiveIconDrawable class to crop launcher icons. -->
+    <string name="config_icon_mask" translatable="false">"M50,0L100,0 100,100 0,100 0,0z"</string>
+    <!-- Flag indicating whether round icons should be parsed from the application manifest. -->
+    <bool name="config_useRoundIcon">false</bool>
+
+</resources>
+
diff --git a/packages/overlays/AdaptiveIconChangeOverlay/res/values/strings.xml b/packages/overlays/AdaptiveIconChangeOverlay/res/values/strings.xml
new file mode 100644
index 0000000..64b7d0d
--- /dev/null
+++ b/packages/overlays/AdaptiveIconChangeOverlay/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Square icon overlay [DO NOT TRANSLATE] -->
+    <string name="square_icon_overlay">Square Icons</string>
+
+</resources>
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index c56f31e..0da07ae 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -175,10 +175,6 @@
         }
     };
 
-    // TODO(b/117779333): move to superclass / create super-class for ShellCommand
-    @GuardedBy("mLock")
-    private boolean mAllowInstantService;
-
     /**
      * Supported modes for Augmented Autofill Smart Suggestions.
      */
@@ -271,6 +267,11 @@
         addCompatibilityModeRequestsLocked(service, userId);
     }
 
+    @Override // from AbstractMasterSystemService
+    protected void enforceCallingPermissionForManagement() {
+        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+    }
+
     @Override // from SystemService
     public void onStart() {
         publishBinderService(AUTOFILL_MANAGER_SERVICE, new AutoFillManagerServiceStub());
@@ -290,7 +291,7 @@
     // Called by Shell command.
     void destroySessions(@UserIdInt int userId, IResultReceiver receiver) {
         Slog.i(TAG, "destroySessions() for userId " + userId);
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         synchronized (mLock) {
             if (userId != UserHandle.USER_ALL) {
@@ -313,7 +314,7 @@
     // Called by Shell command.
     void listSessions(int userId, IResultReceiver receiver) {
         Slog.i(TAG, "listSessions() for userId " + userId);
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         final Bundle resultData = new Bundle();
         final ArrayList<String> sessions = new ArrayList<>();
@@ -340,7 +341,7 @@
     // Called by Shell command.
     void reset() {
         Slog.i(TAG, "reset()");
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         synchronized (mLock) {
             visitServicesLocked((s) -> s.destroyLocked());
@@ -351,7 +352,7 @@
     // Called by Shell command.
     void setLogLevel(int level) {
         Slog.i(TAG, "setLogLevel(): " + level);
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         final long token = Binder.clearCallingIdentity();
         try {
@@ -388,7 +389,7 @@
 
     // Called by Shell command.
     int getLogLevel() {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         synchronized (mLock) {
             if (sVerbose) return AutofillManager.FLAG_ADD_CLIENT_VERBOSE;
@@ -399,7 +400,7 @@
 
     // Called by Shell command.
     int getMaxPartitions() {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         synchronized (mLock) {
             return sPartitionMaxCount;
@@ -408,8 +409,8 @@
 
     // Called by Shell command.
     void setMaxPartitions(int max) {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
         Slog.i(TAG, "setMaxPartitions(): " + max);
+        enforceCallingPermissionForManagement();
 
         final long token = Binder.clearCallingIdentity();
         try {
@@ -433,7 +434,7 @@
 
     // Called by Shell command.
     int getMaxVisibleDatasets() {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         synchronized (sLock) {
             return sVisibleDatasetsMaxCount;
@@ -442,8 +443,8 @@
 
     // Called by Shell command.
     void setMaxVisibleDatasets(int max) {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
         Slog.i(TAG, "setMaxVisibleDatasets(): " + max);
+        enforceCallingPermissionForManagement();
 
         final long token = Binder.clearCallingIdentity();
         try {
@@ -480,7 +481,7 @@
     // Called by Shell command.
     void getScore(@Nullable String algorithmName, @NonNull String value1,
             @NonNull String value2, @NonNull RemoteCallback callback) {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         final FieldClassificationStrategy strategy =
                 new FieldClassificationStrategy(getContext(), UserHandle.USER_CURRENT);
@@ -491,33 +492,16 @@
 
     // Called by Shell command.
     Boolean getFullScreenMode() {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
         return sFullScreenMode;
     }
 
     // Called by Shell command.
     void setFullScreenMode(@Nullable Boolean mode) {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
         sFullScreenMode = mode;
     }
 
-    // Called by Shell command.
-    boolean getAllowInstantService() {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
-        synchronized (mLock) {
-            return mAllowInstantService;
-        }
-    }
-
-    // Called by Shell command.
-    void setAllowInstantService(boolean mode) {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
-        Slog.i(TAG, "setAllowInstantService(): " + mode);
-        synchronized (mLock) {
-            mAllowInstantService = mode;
-        }
-    }
-
     private void setLoggingLevelsLocked(boolean debug, boolean verbose) {
         com.android.server.autofill.Helper.sDebug = debug;
         android.view.autofill.Helper.sDebug = debug;
@@ -1218,7 +1202,6 @@
                     mAutofillCompatState.dump(prefix, pw);
                     pw.print("from settings: ");
                     pw.println(getWhitelistedCompatModePackagesFromSettings());
-                    pw.print("Allow instant service: "); pw.println(mAllowInstantService);
                     if (mSupportedSmartSuggestionModes != 0) {
                         pw.print("Smart Suggestion modes: ");
                         pw.println(smartSuggestionFlagsToString(mSupportedSmartSuggestionModes));
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 0df99d4..18bc856 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -190,6 +190,11 @@
         return mInfo.getServiceInfo();
     }
 
+    @Override // from PerUserSystemService
+    protected String getDefaultComponentName() {
+        return getComponentNameFromSettings();
+    }
+
     @Nullable
     String[] getUrlBarResourceIdsForCompatMode(@NonNull String packageName) {
         return mAutofillCompatState.getUrlBarResourceIds(packageName, mUserId);
@@ -369,7 +374,7 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            final String autoFillService = getComponentNameFromSettings();
+            final String autoFillService = getComponentNameLocked();
             final ComponentName componentName = serviceInfo.getComponentName();
             if (componentName.equals(ComponentName.unflattenFromString(autoFillService))) {
                 mMetricsLogger.action(MetricsEvent.AUTOFILL_SERVICE_DISABLED_SELF,
diff --git a/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java b/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java
new file mode 100644
index 0000000..f356b4f
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java
@@ -0,0 +1,117 @@
+/*
+ * 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.backup.encryption.keys;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.IntDef;
+import android.content.Context;
+import android.security.keystore.recovery.InternalRecoveryServiceException;
+import android.security.keystore.recovery.RecoveryController;
+import android.util.Slog;
+
+import javax.crypto.SecretKey;
+
+/**
+ * Wraps a {@link RecoveryController}'s {@link SecretKey}. These are kept in "AndroidKeyStore" (a
+ * provider for {@link java.security.KeyStore} and {@link javax.crypto.KeyGenerator}. They are also
+ * synced with the recoverable key store, wrapped by the primary key. This allows them to be
+ * recovered on a user's subsequent device through providing their lock screen secret.
+ */
+public class RecoverableKeyStoreSecondaryKey {
+    private static final String TAG = "RecoverableKeyStoreSecondaryKey";
+
+    private final String mAlias;
+    private final SecretKey mSecretKey;
+
+    /**
+     * A new instance.
+     *
+     * @param alias The alias. It is keyed with this in AndroidKeyStore and the recoverable key
+     *     store.
+     * @param secretKey The key.
+     */
+    public RecoverableKeyStoreSecondaryKey(String alias, SecretKey secretKey) {
+        mAlias = checkNotNull(alias);
+        mSecretKey = checkNotNull(secretKey);
+    }
+
+    /**
+     * The ID, as stored in the recoverable {@link java.security.KeyStore}, and as used to identify
+     * wrapped tertiary keys on the backup server.
+     */
+    public String getAlias() {
+        return mAlias;
+    }
+
+    /** The secret key, to be used to wrap tertiary keys. */
+    public SecretKey getSecretKey() {
+        return mSecretKey;
+    }
+
+    /**
+     * The status of the key. i.e., whether it's been synced to remote trusted hardware.
+     *
+     * @param context The application context.
+     * @return One of {@link Status#SYNCED}, {@link Status#NOT_SYNCED} or {@link Status#DESTROYED}.
+     */
+    public @Status int getStatus(Context context) {
+        try {
+            return getStatusInternal(context);
+        } catch (InternalRecoveryServiceException e) {
+            Slog.wtf(TAG, "Internal error getting recovery status", e);
+            // Return NOT_SYNCED by default, as we do not want the backups to fail or to repeatedly
+            // attempt to reinitialize.
+            return Status.NOT_SYNCED;
+        }
+    }
+
+    private @Status int getStatusInternal(Context context) throws InternalRecoveryServiceException {
+        int status = RecoveryController.getInstance(context).getRecoveryStatus(mAlias);
+        switch (status) {
+            case RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE:
+                return Status.DESTROYED;
+            case RecoveryController.RECOVERY_STATUS_SYNCED:
+                return Status.SYNCED;
+            case RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS:
+                return Status.NOT_SYNCED;
+            default:
+                // Throw an exception if we encounter a status that doesn't match any of the above.
+                throw new InternalRecoveryServiceException(
+                        "Unexpected status from getRecoveryStatus: " + status);
+        }
+    }
+
+    /** Status of a key in the recoverable key store. */
+    @IntDef({Status.NOT_SYNCED, Status.SYNCED, Status.DESTROYED})
+    public @interface Status {
+        /**
+         * The key has not yet been synced to remote trusted hardware. This may be because the user
+         * has not yet unlocked their device.
+         */
+        int NOT_SYNCED = 1;
+
+        /**
+         * The key has been synced with remote trusted hardware. It should now be recoverable on
+         * another device.
+         */
+        int SYNCED = 2;
+
+        /** The key has been lost forever. This can occur if the user disables their lock screen. */
+        int DESTROYED = 3;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java b/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java
new file mode 100644
index 0000000..db5fe77
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java
@@ -0,0 +1,119 @@
+/*
+ * 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.backup.encryption.keys;
+
+import android.content.Context;
+import android.security.keystore.recovery.InternalRecoveryServiceException;
+import android.security.keystore.recovery.LockScreenRequiredException;
+import android.security.keystore.recovery.RecoveryController;
+import android.util.ByteStringUtils;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.util.Optional;
+
+import javax.crypto.SecretKey;
+
+/**
+ * Manages generating, deleting, and retrieving secondary keys through {@link RecoveryController}.
+ *
+ * <p>The recoverable key store will be synced remotely via the {@link RecoveryController}, allowing
+ * recovery of keys on other devices owned by the user.
+ */
+public class RecoverableKeyStoreSecondaryKeyManager {
+    private static final String BACKUP_KEY_ALIAS_PREFIX =
+            "com.android.server.backup/recoverablekeystore/";
+    private static final int BACKUP_KEY_SUFFIX_LENGTH_BITS = 128;
+    private static final int BITS_PER_BYTE = 8;
+
+    /** A new instance. */
+    public static RecoverableKeyStoreSecondaryKeyManager getInstance(Context context) {
+        return new RecoverableKeyStoreSecondaryKeyManager(
+                RecoveryController.getInstance(context), new SecureRandom());
+    }
+
+    private final RecoveryController mRecoveryController;
+    private final SecureRandom mSecureRandom;
+
+    @VisibleForTesting
+    public RecoverableKeyStoreSecondaryKeyManager(
+            RecoveryController recoveryController, SecureRandom secureRandom) {
+        mRecoveryController = recoveryController;
+        mSecureRandom = secureRandom;
+    }
+
+    /**
+     * Generates a new recoverable key using the {@link RecoveryController}.
+     *
+     * @throws InternalRecoveryServiceException if an unexpected error occurred generating the key.
+     * @throws LockScreenRequiredException if the user does not have a lock screen. A lock screen is
+     *     required to generate a recoverable key.
+     */
+    public RecoverableKeyStoreSecondaryKey generate()
+            throws InternalRecoveryServiceException, LockScreenRequiredException,
+                    UnrecoverableKeyException {
+        String alias = generateId();
+        mRecoveryController.generateKey(alias);
+        SecretKey key = (SecretKey) mRecoveryController.getKey(alias);
+        if (key == null) {
+            throw new InternalRecoveryServiceException(
+                    String.format(
+                            "Generated key %s but could not get it back immediately afterwards.",
+                            alias));
+        }
+        return new RecoverableKeyStoreSecondaryKey(alias, key);
+    }
+
+    /**
+     * Removes the secondary key. This means the key will no longer be recoverable.
+     *
+     * @param alias The alias of the key.
+     * @throws InternalRecoveryServiceException if there was a {@link RecoveryController} error.
+     */
+    public void remove(String alias) throws InternalRecoveryServiceException {
+        mRecoveryController.removeKey(alias);
+    }
+
+    /**
+     * Returns the {@link RecoverableKeyStoreSecondaryKey} with {@code alias} if it is in the {@link
+     * RecoveryController}. Otherwise, {@link Optional#empty()}.
+     */
+    public Optional<RecoverableKeyStoreSecondaryKey> get(String alias)
+            throws InternalRecoveryServiceException, UnrecoverableKeyException {
+        SecretKey secretKey = (SecretKey) mRecoveryController.getKey(alias);
+        return Optional.ofNullable(secretKey)
+                .map(key -> new RecoverableKeyStoreSecondaryKey(alias, key));
+    }
+
+    /**
+     * Generates a new key alias. This has more entropy than a UUID - it can be considered
+     * universally unique.
+     */
+    private String generateId() {
+        byte[] id = new byte[BACKUP_KEY_SUFFIX_LENGTH_BITS / BITS_PER_BYTE];
+        mSecureRandom.nextBytes(id);
+        return BACKUP_KEY_ALIAS_PREFIX + ByteStringUtils.toHexString(id);
+    }
+
+    /** Constructs a {@link RecoverableKeyStoreSecondaryKeyManager}. */
+    public interface RecoverableKeyStoreSecondaryKeyManagerProvider {
+        /** Returns a newly constructed {@link RecoverableKeyStoreSecondaryKeyManager}. */
+        RecoverableKeyStoreSecondaryKeyManager get();
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java b/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java
new file mode 100644
index 0000000..ebf09df
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java
@@ -0,0 +1,47 @@
+/*
+ * 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.backup.encryption.keys;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+
+/** 256-bit AES key generator. Each app should have its own separate AES key. */
+public class TertiaryKeyGenerator {
+    private static final int KEY_SIZE_BITS = 256;
+    private static final String KEY_ALGORITHM = "AES";
+
+    private final KeyGenerator mKeyGenerator;
+
+    /** New instance generating keys using {@code secureRandom}. */
+    public TertiaryKeyGenerator(SecureRandom secureRandom) {
+        try {
+            mKeyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
+            mKeyGenerator.init(KEY_SIZE_BITS, secureRandom);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(
+                    "Impossible condition: JCE thinks it does not support AES.", e);
+        }
+    }
+
+    /** Generates a new random AES key. */
+    public SecretKey generate() {
+        return mKeyGenerator.generateKey();
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java b/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java
new file mode 100644
index 0000000..ec90f6c
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java
@@ -0,0 +1,113 @@
+/*
+ * 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.backup.encryption.keys;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Locale;
+
+/**
+ * Tracks when a tertiary key rotation is due.
+ *
+ * <p>After a certain number of incremental backups, the device schedules a full backup, which will
+ * generate a new encryption key, effecting a key rotation. We should do this on a regular basis so
+ * that if a key does become compromised it has limited value to the attacker.
+ *
+ * <p>No additional synchronization of this class is provided. Only one instance should be used at
+ * any time. This should be fine as there should be no parallelism in backups.
+ */
+public class TertiaryKeyRotationTracker {
+    private static final int MAX_BACKUPS_UNTIL_TERTIARY_KEY_ROTATION = 31;
+    private static final String SHARED_PREFERENCES_NAME = "tertiary_key_rotation_tracker";
+
+    private static final String TAG = "TertiaryKeyRotationTracker";
+    private static final boolean DEBUG = false;
+
+    /**
+     * A new instance, using {@code context} to commit data to disk via {@link SharedPreferences}.
+     */
+    public static TertiaryKeyRotationTracker getInstance(Context context) {
+        return new TertiaryKeyRotationTracker(
+                context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE));
+    }
+
+    private final SharedPreferences mSharedPreferences;
+
+    /** New instance, storing data in {@code mSharedPreferences}. */
+    @VisibleForTesting
+    TertiaryKeyRotationTracker(SharedPreferences sharedPreferences) {
+        mSharedPreferences = sharedPreferences;
+    }
+
+    /**
+     * Returns {@code true} if the given app is due having its key rotated.
+     *
+     * @param packageName The package name of the app.
+     */
+    public boolean isKeyRotationDue(String packageName) {
+        return getBackupsSinceRotation(packageName) >= MAX_BACKUPS_UNTIL_TERTIARY_KEY_ROTATION;
+    }
+
+    /**
+     * Records that an incremental backup has occurred. Each incremental backup brings the app
+     * closer to the time when its key should be rotated.
+     *
+     * @param packageName The package name of the app for which the backup occurred.
+     */
+    public void recordBackup(String packageName) {
+        int backupsSinceRotation = getBackupsSinceRotation(packageName) + 1;
+        mSharedPreferences.edit().putInt(packageName, backupsSinceRotation).apply();
+        if (DEBUG) {
+            Slog.d(
+                    TAG,
+                    String.format(
+                            Locale.US,
+                            "Incremental backup for %s. %d backups until key rotation.",
+                            packageName,
+                            Math.max(
+                                    0,
+                                    MAX_BACKUPS_UNTIL_TERTIARY_KEY_ROTATION
+                                            - backupsSinceRotation)));
+        }
+    }
+
+    /**
+     * Resets the rotation delay for the given app. Should be invoked after a key rotation.
+     *
+     * @param packageName Package name of the app whose key has rotated.
+     */
+    public void resetCountdown(String packageName) {
+        mSharedPreferences.edit().putInt(packageName, 0).apply();
+    }
+
+    /** Marks all enrolled packages for key rotation. */
+    public void markAllForRotation() {
+        SharedPreferences.Editor editor = mSharedPreferences.edit();
+        for (String packageName : mSharedPreferences.getAll().keySet()) {
+            editor.putInt(packageName, MAX_BACKUPS_UNTIL_TERTIARY_KEY_ROTATION);
+        }
+        editor.apply();
+    }
+
+    private int getBackupsSinceRotation(String packageName) {
+        return mSharedPreferences.getInt(packageName, 0);
+    }
+}
diff --git a/services/core/java/com/android/server/AbstractMasterSystemService.java b/services/core/java/com/android/server/AbstractMasterSystemService.java
index 9c1e3cd..76010b3 100644
--- a/services/core/java/com/android/server/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/AbstractMasterSystemService.java
@@ -39,6 +39,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.Preconditions;
 
 import java.io.PrintWriter;
 import java.util.List;
@@ -93,6 +94,12 @@
     public boolean debug = false;
 
     /**
+     * Whether the service is allowed to bind to an instant-app.
+     */
+    @GuardedBy("mLock")
+    protected boolean mAllowInstantService;
+
+    /**
      * Users disabled due to {@link UserManager} restrictions, or {@code null} if the service cannot
      * be disabled through {@link UserManager}.
      */
@@ -176,6 +183,107 @@
     }
 
     /**
+     * Gets whether the service is allowed to bind to an instant-app.
+     *
+     * <p>Typically called by {@code ShellCommand} during CTS tests.
+     *
+     * @throws SecurityException if caller is not allowed to manage this service's settings.
+     */
+    public final boolean getAllowInstantService() {
+        enforceCallingPermissionForManagement();
+        synchronized (mLock) {
+            return mAllowInstantService;
+        }
+    }
+
+    /**
+     * Sets whether the service is allowed to bind to an instant-app.
+     *
+     * <p>Typically called by {@code ShellCommand} during CTS tests.
+     *
+     * @throws SecurityException if caller is not allowed to manage this service's settings.
+     */
+    public final void setAllowInstantService(boolean mode) {
+        Slog.i(mTag, "setAllowInstantService(): " + mode);
+        enforceCallingPermissionForManagement();
+        synchronized (mLock) {
+            mAllowInstantService = mode;
+        }
+    }
+
+    /**
+     * Temporary sets the service implementation.
+     *
+     * <p>Typically used by Shell command and/or CTS tests.
+     *
+     * @param componentName name of the new component
+     * @param durationMs how long the change will be valid (the service will be automatically reset
+     *            to the default component after this timeout expires).
+     * @throws SecurityException if caller is not allowed to manage this service's settings.
+     * @throws IllegalArgumentException if value of {@code durationMs} is higher than
+     *             {@link #getMaximumTemporaryServiceDurationMs()}.
+     */
+    public final void setTemporaryService(@UserIdInt int userId, @NonNull String componentName,
+            int durationMs) {
+        Slog.i(mTag, "setTemporaryService(" + userId + ") to " + componentName + " for "
+                + durationMs + "ms");
+        enforceCallingPermissionForManagement();
+
+        Preconditions.checkNotNull(componentName);
+        final int maxDurationMs = getMaximumTemporaryServiceDurationMs();
+        if (durationMs > maxDurationMs) {
+            throw new IllegalArgumentException(
+                    "Max duration is " + maxDurationMs + " (called with " + durationMs + ")");
+        }
+
+        synchronized (mLock) {
+            final S service = getServiceForUserLocked(userId);
+            if (service != null) {
+                service.setTemporaryServiceLocked(componentName, durationMs);
+            }
+        }
+    }
+
+    /**
+     * Gets the maximum time the service implementation can be changed.
+     *
+     * @throws UnsupportedOperationException if subclass doesn't override it.
+     */
+    protected int getMaximumTemporaryServiceDurationMs() {
+        throw new UnsupportedOperationException("Not implemented by " + getClass());
+    }
+
+    /**
+     * Resets the temporary service implementation to the default component.
+     *
+     * <p>Typically used by Shell command and/or CTS tests.
+     *
+     * @throws SecurityException if caller is not allowed to manage this service's settings.
+     */
+    public final void resetTemporaryService(@UserIdInt int userId) {
+        Slog.i(mTag, "resetTemporaryService(): " + userId);
+        enforceCallingPermissionForManagement();
+        synchronized (mLock) {
+            final S service = getServiceForUserLocked(userId);
+            if (service != null) {
+                service.resetTemporaryServiceLocked();
+            }
+        }
+    }
+
+    /**
+     * Asserts that the caller has permissions to manage this service.
+     *
+     * <p>Typically called by {@code ShellCommand} implementations.
+     *
+     * @throws UnsupportedOperationException if subclass doesn't override it.
+     * @throws SecurityException if caller is not allowed to manage this service's settings.
+     */
+    protected void enforceCallingPermissionForManagement() {
+        throw new UnsupportedOperationException("Not implemented by " + getClass());
+    }
+
+    /**
      * Creates a new service that will be added to the cache.
      *
      * @param resolvedUserId the resolved user id for the service.
@@ -362,6 +470,7 @@
             pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
             pw.print(" Verbose: "); pw.println(realVerbose);
             pw.print(prefix); pw.print("Disabled users: "); pw.println(mDisabledUsers);
+            pw.print(prefix); pw.print("Allow instant service: "); pw.println(mAllowInstantService);
             pw.print(prefix); pw.print("Settings property: "); pw.println(
                     getServiceSettingsProperty());
             pw.print(prefix); pw.print("Cached services: ");
diff --git a/services/core/java/com/android/server/AbstractPerUserSystemService.java b/services/core/java/com/android/server/AbstractPerUserSystemService.java
index 001d85f..a26102d 100644
--- a/services/core/java/com/android/server/AbstractPerUserSystemService.java
+++ b/services/core/java/com/android/server/AbstractPerUserSystemService.java
@@ -26,12 +26,17 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ServiceInfo;
 import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.UserManager;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Slog;
+import android.util.TimeUtils;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -49,6 +54,9 @@
 public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSystemService<S, M>,
         M extends AbstractMasterSystemService<M, S>> {
 
+    /** Handler message to {@link #resetTemporaryServiceLocked()} */
+    private static final int MSG_RESET_TEMPORARY_SERVICE = 0;
+
     protected final @UserIdInt int mUserId;
     protected final Object mLock;
     protected final String mTag = getClass().getSimpleName();
@@ -70,6 +78,26 @@
     @GuardedBy("mLock")
     private ServiceInfo mServiceInfo;
 
+    /**
+     * Temporary service name set by {@link #setTemporaryServiceLocked(String, int)}.
+     *
+     * <p>Typically used by Shell command and/or CTS tests.
+     */
+    @GuardedBy("mLock")
+    private String mTemporaryServiceName;
+
+    /**
+     * When the temporary service will expire (and reset back to the default).
+     */
+    @GuardedBy("mLock")
+    private long mTemporaryServiceExpiration;
+
+    /**
+     * Handler used to reset the temporary service name.
+     */
+    @GuardedBy("mLock")
+    private Handler mTemporaryHandler;
+
     protected AbstractPerUserSystemService(@NonNull M master, @NonNull Object lock,
             @UserIdInt int userId) {
         mMaster = master;
@@ -130,7 +158,7 @@
         mDisabled = disabled;
         ComponentName serviceComponent = null;
         ServiceInfo serviceInfo = null;
-        final String componentName = getComponentNameFromSettings();
+        final String componentName = getComponentNameLocked();
         if (!TextUtils.isEmpty(componentName)) {
             try {
                 serviceComponent = ComponentName.unflattenFromString(componentName);
@@ -191,6 +219,29 @@
     }
 
     /**
+     * Gets the current name of the service, which is either the
+     *  {@link #getDefaultComponentName() default service} or the
+     *  {@link #setTemporaryServiceLocked(String, int) temporary one}.
+     */
+    protected final String getComponentNameLocked() {
+        if (mTemporaryServiceName != null) {
+            // Always log it, as it should only be used on CTS or during development
+            Slog.w(mTag, "getComponentName(): using temporary name " + mTemporaryServiceName);
+            return mTemporaryServiceName;
+        }
+        return getDefaultComponentName();
+    }
+
+    /**
+     * Gets the name of the default component for the service.
+     *
+     * <p>Typically implemented by returning {@link #getComponentNameFromSettings()} or by using
+     * a string from the system resources.
+     */
+    @Nullable
+    protected abstract String getDefaultComponentName();
+
+    /**
      * Gets this name of the remote service this service binds to as defined by {@link Settings}.
      */
     @Nullable
@@ -201,6 +252,66 @@
     }
 
     /**
+     * Checks whether the current service for the user was temporarily set.
+     */
+    public final boolean isTemporaryServiceSetLocked() {
+        return mTemporaryServiceName != null;
+    }
+
+    /**
+     * Temporary sets the service implementation.
+     *
+     * @param componentName name of the new component
+     * @param durationMs how long the change will be valid (the service will be automatically reset
+     * to the default component after this timeout expires).
+     */
+    protected final void setTemporaryServiceLocked(@NonNull String componentName, int durationMs) {
+        mTemporaryServiceName = componentName;
+
+        if (mTemporaryHandler == null) {
+            mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) {
+                @Override
+                public void handleMessage(Message msg) {
+                    if (msg.what == MSG_RESET_TEMPORARY_SERVICE) {
+                        synchronized (mLock) {
+                            resetTemporaryServiceLocked();
+                        }
+                    } else {
+                        Slog.wtf(mTag, "invalid handler msg: " + msg);
+                    }
+                }
+            };
+        } else {
+            removeResetTemporaryServiceMessageLocked();
+        }
+        mTemporaryServiceExpiration = SystemClock.elapsedRealtime() + durationMs;
+        mTemporaryHandler.sendEmptyMessageDelayed(MSG_RESET_TEMPORARY_SERVICE, durationMs);
+
+        updateLocked(mDisabled);
+    }
+
+    private void removeResetTemporaryServiceMessageLocked() {
+        if (mMaster.verbose) {
+            Slog.v(mTag, "setTemporaryServiceLocked(): removing old message");
+        }
+        // NOTE: caller should already have checked it
+        mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_SERVICE);
+    }
+
+    /**
+     * Resets the temporary service implementation to the default component.
+     */
+    protected final void resetTemporaryServiceLocked() {
+        Slog.i(mTag, "resetting temporary service from " + mTemporaryServiceName);
+        mTemporaryServiceName = null;
+        if (mTemporaryHandler != null) {
+            removeResetTemporaryServiceMessageLocked();
+            mTemporaryHandler = null;
+        }
+        updateLocked(mDisabled);
+    }
+
+    /**
      * Gets the {@link ComponentName} of the remote service this service binds to, or {@code null}
      * if the service is disabled.
      */
@@ -290,12 +401,14 @@
             pw.print(prefix); pw.print("Service UID: ");
             pw.println(mServiceInfo.applicationInfo.uid);
         }
-        final String componentName = getComponentNameFromSettings();
-        if (componentName != null) {
-            pw.print(prefix); pw.print("Service name: ");
-            pw.println(componentName);
+        if (mTemporaryServiceName != null) {
+            pw.print(prefix); pw.print("Temporary service name: "); pw.print(mTemporaryServiceName);
+            final long ttl = mTemporaryServiceExpiration - SystemClock.elapsedRealtime();
+            pw.print(" (expires in "); TimeUtils.formatDuration(ttl, pw); pw.println(")");
+            pw.print(prefix); pw.print(prefix);
+            pw.print("Default service name: "); pw.println(getDefaultComponentName());
         } else {
-            pw.println("No service package set");
+            pw.print(prefix); pw.print("Service name: "); pw.println(getDefaultComponentName());
         }
     }
 }
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index 01716a0..81f0259 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -116,6 +116,7 @@
                 }
                 mEnabled = enabled;
                 mBinderCallsStats.reset();
+                mBinderCallsStats.setAddDebugEntries(enabled);
             }
         }
     }
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 7ee3d3b..126bf65 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -1236,7 +1236,8 @@
                     OsConstants.UDP_ENCAP,
                     OsConstants.UDP_ENCAP_ESPINUDP);
 
-            mSrvConfig.getNetdInstance().ipSecSetEncapSocketOwner(sockFd, callingUid);
+            mSrvConfig.getNetdInstance().ipSecSetEncapSocketOwner(
+                        new ParcelFileDescriptor(sockFd), callingUid);
             if (port != 0) {
                 Log.v(TAG, "Binding to port " + port);
                 Os.bind(sockFd, INADDR_ANY, port);
@@ -1696,7 +1697,7 @@
         mSrvConfig
                 .getNetdInstance()
                 .ipSecApplyTransportModeTransform(
-                        socket.getFileDescriptor(),
+                        socket,
                         callingUid,
                         direction,
                         c.getSourceAddress(),
@@ -1715,7 +1716,7 @@
             throws RemoteException {
         mSrvConfig
                 .getNetdInstance()
-                .ipSecRemoveTransportModeTransform(socket.getFileDescriptor());
+                .ipSecRemoveTransportModeTransform(socket);
     }
 
     /**
diff --git a/services/core/java/com/android/server/LooperStatsService.java b/services/core/java/com/android/server/LooperStatsService.java
index c563ad2..fa3baba 100644
--- a/services/core/java/com/android/server/LooperStatsService.java
+++ b/services/core/java/com/android/server/LooperStatsService.java
@@ -94,6 +94,8 @@
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
         pw.print("Start time: ");
         pw.println(DateFormat.format("yyyy-MM-dd HH:mm:ss", mStats.getStartTimeMillis()));
+        pw.print("On battery time (ms): ");
+        pw.println(mStats.getBatteryTimeMillis());
         final List<LooperStats.ExportedEntry> entries = mStats.getEntries();
         entries.sort(Comparator
                 .comparing((LooperStats.ExportedEntry entry) -> entry.workSourceUid)
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index e933bd0..390126c 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -99,6 +99,7 @@
 import android.os.storage.VolumeRecord;
 import android.provider.MediaStore;
 import android.provider.Settings;
+import android.sysprop.VoldProperties;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
@@ -1015,7 +1016,7 @@
 
         // On an encrypted device we can't see system properties yet, so pull
         // the system locale out of the mount service.
-        if ("".equals(SystemProperties.get("vold.encrypt_progress"))) {
+        if ("".equals(VoldProperties.encrypt_progress().orElse(""))) {
             copyLocaleFromMountService();
         }
     }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 562e80d..8842f41 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -272,6 +272,7 @@
 import android.os.WorkSource;
 import android.os.storage.StorageManager;
 import android.provider.Settings;
+import android.sysprop.VoldProperties;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.text.style.SuggestionSpan;
@@ -4807,8 +4808,8 @@
             SystemProperties.set("sys.boot_completed", "1");
 
             // And trigger dev.bootcomplete if we are not showing encryption progress
-            if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
-                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
+            if (!"trigger_restart_min_framework".equals(VoldProperties.decrypt().orElse(""))
+                    || "".equals(VoldProperties.encrypt_progress().orElse(""))) {
                 SystemProperties.set("dev.bootcomplete", "1");
             }
             mUserController.sendBootCompleted(
diff --git a/services/core/java/com/android/server/display/ColorDisplayService.java b/services/core/java/com/android/server/display/ColorDisplayService.java
index 0b6786c..521fa23 100644
--- a/services/core/java/com/android/server/display/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/ColorDisplayService.java
@@ -16,6 +16,8 @@
 
 package com.android.server.display;
 
+import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.TypeEvaluator;
@@ -29,8 +31,10 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.database.ContentObserver;
+import android.hardware.display.IColorDisplayManager;
 import android.net.Uri;
 import android.opengl.Matrix;
+import android.os.Binder;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.UserHandle;
@@ -39,6 +43,7 @@
 import android.util.Slog;
 import android.view.animation.AnimationUtils;
 
+import com.android.internal.R;
 import com.android.internal.app.ColorDisplayController;
 import com.android.server.SystemService;
 import com.android.server.twilight.TwilightListener;
@@ -49,12 +54,8 @@
 import java.time.LocalTime;
 import java.time.ZoneId;
 
-import com.android.internal.R;
-
-import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
-
 /**
- * Tints the display at night.
+ * Controls the display's color transforms.
  */
 public final class ColorDisplayService extends SystemService
         implements ColorDisplayController.Callback {
@@ -101,7 +102,7 @@
 
     @Override
     public void onStart() {
-        // Nothing to publish.
+        publishBinderService(Context.COLOR_DISPLAY_SERVICE, new BinderService());
     }
 
     @Override
@@ -171,7 +172,7 @@
                     }
                 };
                 cr.registerContentObserver(Secure.getUriFor(Secure.USER_SETUP_COMPLETE),
-                        false /* notifyForDescendents */, mUserSetupObserver, mCurrentUser);
+                        false /* notifyForDescendants */, mUserSetupObserver, mCurrentUser);
             } else if (mBootCompleted) {
                 setUp();
             }
@@ -405,8 +406,8 @@
     }
 
     /**
-     * Returns the first date time corresponding to the local time that occurs before the
-     * provided date time.
+     * Returns the first date time corresponding to the local time that occurs before the provided
+     * date time.
      *
      * @param compareTime the LocalDateTime to compare against
      * @return the prior LocalDateTime corresponding to this local time
@@ -420,8 +421,8 @@
     }
 
     /**
-     * Returns the first date time corresponding to this local time that occurs after the
-     * provided date time.
+     * Returns the first date time corresponding to this local time that occurs after the provided
+     * date time.
      *
      * @param compareTime the LocalDateTime to compare against
      * @return the next LocalDateTime corresponding to this local time
@@ -434,6 +435,11 @@
         return ldt.isBefore(compareTime) ? ldt.plusDays(1) : ldt;
     }
 
+    private boolean isDeviceColorManagedInternal() {
+        final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
+        return dtm.isDeviceColorManaged();
+    }
+
     private abstract class AutoMode implements ColorDisplayController.Callback {
         public abstract void onStart();
 
@@ -616,4 +622,16 @@
             return mResultMatrix;
         }
     }
+
+    private final class BinderService extends IColorDisplayManager.Stub {
+        @Override
+        public boolean isDeviceColorManaged() {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                return isDeviceColorManagedInternal();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/display/DisplayTransformManager.java b/services/core/java/com/android/server/display/DisplayTransformManager.java
index d6931e0..5ca1755 100644
--- a/services/core/java/com/android/server/display/DisplayTransformManager.java
+++ b/services/core/java/com/android/server/display/DisplayTransformManager.java
@@ -16,7 +16,6 @@
 
 package com.android.server.display;
 
-import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.opengl.Matrix;
 import android.os.IBinder;
@@ -27,8 +26,10 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.ColorDisplayController;
+
 import java.util.Arrays;
 
 /**
@@ -59,10 +60,6 @@
 
     private static final int SURFACE_FLINGER_TRANSACTION_COLOR_MATRIX = 1015;
     private static final int SURFACE_FLINGER_TRANSACTION_DALTONIZER = 1014;
-
-    private static final String PERSISTENT_PROPERTY_SATURATION = "persist.sys.sf.color_saturation";
-    private static final String PERSISTENT_PROPERTY_DISPLAY_COLOR = "persist.sys.sf.native_mode";
-
     /**
      * SurfaceFlinger global saturation factor.
      */
@@ -71,6 +68,10 @@
      * SurfaceFlinger display color (managed, unmanaged, etc.).
      */
     private static final int SURFACE_FLINGER_TRANSACTION_DISPLAY_COLOR = 1023;
+    private static final int SURFACE_FLINGER_TRANSACTION_QUERY_WIDE_COLOR = 1030;
+
+    private static final String PERSISTENT_PROPERTY_SATURATION = "persist.sys.sf.color_saturation";
+    private static final String PERSISTENT_PROPERTY_DISPLAY_COLOR = "persist.sys.sf.native_mode";
 
     private static final float COLOR_SATURATION_NATURAL = 1.0f;
     private static final float COLOR_SATURATION_BOOSTED = 1.1f;
@@ -269,6 +270,29 @@
     }
 
     /**
+     * Returns whether the screen is wide color gamut via SurfaceFlinger's
+     * {@link #SURFACE_FLINGER_TRANSACTION_QUERY_WIDE_COLOR}.
+     */
+    public boolean isDeviceColorManaged() {
+        final IBinder flinger = ServiceManager.getService(SURFACE_FLINGER);
+        if (flinger != null) {
+            final Parcel data = Parcel.obtain();
+            final Parcel reply = Parcel.obtain();
+            data.writeInterfaceToken("android.ui.ISurfaceComposer");
+            try {
+                flinger.transact(SURFACE_FLINGER_TRANSACTION_QUERY_WIDE_COLOR, data, reply, 0);
+                return reply.readBoolean();
+            } catch (RemoteException ex) {
+                Log.e(TAG, "Failed to query wide color support", ex);
+            } finally {
+                data.recycle();
+                reply.recycle();
+            }
+        }
+        return false;
+    }
+
+    /**
      * Propagates the provided saturation to the SurfaceFlinger.
      */
     private void applySaturation(float saturation) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index b148a2f..c0d3fdf 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -980,7 +980,7 @@
      * @param sourceAddress a logical address of source device where sends polling message
      * @param pickStrategy strategy how to pick polling candidates
      * @param retryCount the number of retry used to send polling message to remote devices
-     * @throw IllegalArgumentException if {@code pickStrategy} is invalid value
+     * @throws IllegalArgumentException if {@code pickStrategy} is invalid value
      */
     @ServiceThreadOnly
     void pollDevices(DevicePollingCallback callback, int sourceAddress, int pickStrategy,
diff --git a/services/core/java/com/android/server/notification/NotificationComparator.java b/services/core/java/com/android/server/notification/NotificationComparator.java
index 2584187..9b9f4de 100644
--- a/services/core/java/com/android/server/notification/NotificationComparator.java
+++ b/services/core/java/com/android/server/notification/NotificationComparator.java
@@ -15,12 +15,15 @@
  */
 package com.android.server.notification;
 
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.provider.Settings;
 import android.telecom.TelecomManager;
 
 import com.android.internal.util.NotificationMessagingUtil;
@@ -47,6 +50,21 @@
 
     @Override
     public int compare(NotificationRecord left, NotificationRecord right) {
+        final int leftImportance = left.getImportance();
+        final int rightImportance = right.getImportance();
+        final boolean isLeftHighImportance = leftImportance >= IMPORTANCE_DEFAULT;
+        final boolean isRightHighImportance = rightImportance >= IMPORTANCE_DEFAULT;
+
+        // With new interruption model, prefer importance bucket above all other criteria
+        // (to ensure buckets are contiguous)
+        if (Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL, 1) == 1) {
+            if (isLeftHighImportance != isRightHighImportance) {
+                // by importance bucket, high importance higher than low importance
+                return -1 * Boolean.compare(isLeftHighImportance, isRightHighImportance);
+            }
+        }
+
         // first all colorized notifications
         boolean leftImportantColorized = isImportantColorized(left);
         boolean rightImportantColorized = isImportantColorized(right);
@@ -86,8 +104,6 @@
             return -1 * Boolean.compare(leftPeople, rightPeople);
         }
 
-        final int leftImportance = left.getImportance();
-        final int rightImportance = right.getImportance();
         if (leftImportance != rightImportance) {
             // by importance, high to low
             return -1 * Integer.compare(leftImportance, rightImportance);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 6c2549e..95e1962 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -207,7 +207,6 @@
 import com.android.internal.util.XmlUtils;
 import com.android.server.DeviceIdleController;
 import com.android.server.EventLogTags;
-import com.android.server.IoThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.lights.Light;
@@ -266,7 +265,7 @@
 
     // message codes
     static final int MESSAGE_DURATION_REACHED = 2;
-    // 3: removed to a different handler
+    static final int MESSAGE_SAVE_POLICY_FILE = 3;
     static final int MESSAGE_SEND_RANKING_UPDATE = 4;
     static final int MESSAGE_LISTENER_HINTS_CHANGED = 5;
     static final int MESSAGE_LISTENER_NOTIFICATION_FILTER_CHANGED = 6;
@@ -428,6 +427,7 @@
     private GroupHelper mGroupHelper;
     private int mAutoGroupAtCount;
     private boolean mIsTelevision;
+    private boolean mIsAutomotive;
 
     private MetricsLogger mMetricsLogger;
     private Predicate<String> mAllowedManagedServicePackages;
@@ -573,7 +573,7 @@
             mListeners.migrateToXml();
             mAssistants.migrateToXml();
             mConditionProviders.migrateToXml();
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         mAssistants.ensureAssistant();
@@ -603,28 +603,34 @@
         }
     }
 
-    private void handleSavePolicyFile() {
-        IoThread.getHandler().post(() -> {
-            if (DBG) Slog.d(TAG, "handleSavePolicyFile");
-            synchronized (mPolicyFile) {
-                final FileOutputStream stream;
-                try {
-                    stream = mPolicyFile.startWrite();
-                } catch (IOException e) {
-                    Slog.w(TAG, "Failed to save policy file", e);
-                    return;
-                }
+    /**
+     * Saves notification policy
+     */
+    public void savePolicyFile() {
+        mHandler.removeMessages(MESSAGE_SAVE_POLICY_FILE);
+        mHandler.sendEmptyMessage(MESSAGE_SAVE_POLICY_FILE);
+    }
 
-                try {
-                    writePolicyXml(stream, false /*forBackup*/);
-                    mPolicyFile.finishWrite(stream);
-                } catch (IOException e) {
-                    Slog.w(TAG, "Failed to save policy file, restoring backup", e);
-                    mPolicyFile.failWrite(stream);
-                }
+    private void handleSavePolicyFile() {
+        if (DBG) Slog.d(TAG, "handleSavePolicyFile");
+        synchronized (mPolicyFile) {
+            final FileOutputStream stream;
+            try {
+                stream = mPolicyFile.startWrite();
+            } catch (IOException e) {
+                Slog.w(TAG, "Failed to save policy file", e);
+                return;
             }
-            BackupManager.dataChanged(getContext().getPackageName());
-        });
+
+            try {
+                writePolicyXml(stream, false /*forBackup*/);
+                mPolicyFile.finishWrite(stream);
+            } catch (IOException e) {
+                Slog.w(TAG, "Failed to save policy file, restoring backup", e);
+                mPolicyFile.failWrite(stream);
+            }
+        }
+        BackupManager.dataChanged(getContext().getPackageName());
     }
 
     private void writePolicyXml(OutputStream stream, boolean forBackup) throws IOException {
@@ -1132,8 +1138,8 @@
 
                     }
                 }
-
                 mHandler.scheduleOnPackageChanged(removingPackage, changeUserId, pkgList, uidList);
+                savePolicyFile();
             }
         }
     };
@@ -1200,7 +1206,7 @@
                 mListeners.onUserRemoved(userId);
                 mConditionProviders.onUserRemoved(userId);
                 mAssistants.onUserRemoved(userId);
-                handleSavePolicyFile();
+                savePolicyFile();
             } else if (action.equals(Intent.ACTION_USER_UNLOCKED)) {
                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                 mUserProfiles.updateCache(context);
@@ -1388,6 +1394,11 @@
     }
 
     @VisibleForTesting
+    void setIsAutomotive(boolean isAutomotive) {
+        mIsAutomotive = isAutomotive;
+    }
+
+    @VisibleForTesting
     void setIsTelevision(boolean isTelevision) {
         mIsTelevision = isTelevision;
     }
@@ -1451,7 +1462,7 @@
         mZenModeHelper.addCallback(new ZenModeHelper.Callback() {
             @Override
             public void onConfigChanged() {
-                handleSavePolicyFile();
+                savePolicyFile();
             }
 
             @Override
@@ -1543,6 +1554,9 @@
 
         mIsTelevision = mPackageManagerClient.hasSystemFeature(FEATURE_LEANBACK)
                 || mPackageManagerClient.hasSystemFeature(FEATURE_TELEVISION);
+
+        mIsAutomotive =
+                mPackageManagerClient.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0);
     }
 
     @Override
@@ -1750,7 +1764,7 @@
                     modifiedChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
         }
 
-        handleSavePolicyFile();
+        savePolicyFile();
     }
 
     private void maybeNotifyChannelOwner(String pkg, int uid, NotificationChannel preUpdate,
@@ -2218,7 +2232,7 @@
                 Slog.w(TAG, "Can't notify app about app block change", e);
             }
 
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         /**
@@ -2275,7 +2289,7 @@
         public void setShowBadge(String pkg, int uid, boolean showBadge) {
             checkCallerIsSystem();
             mPreferencesHelper.setShowBadge(pkg, uid, showBadge);
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         @Override
@@ -2291,7 +2305,7 @@
                 if (info != null) {
                     mPreferencesHelper.setNotificationDelegate(
                             callingPkg, callingUid, delegate, info.uid);
-                    handleSavePolicyFile();
+                    savePolicyFile();
                 }
             } catch (RemoteException e) {
                 // :(
@@ -2302,7 +2316,7 @@
         public void revokeNotificationDelegate(String callingPkg) {
             checkCallerIsSameApp(callingPkg);
             mPreferencesHelper.revokeNotificationDelegate(callingPkg, Binder.getCallingUid());
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         @Override
@@ -2337,7 +2351,7 @@
                 NotificationChannelGroup group) throws RemoteException {
             enforceSystemOrSystemUI("Caller not system or systemui");
             createNotificationChannelGroup(pkg, uid, group, false, false);
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         @Override
@@ -2350,7 +2364,7 @@
                 final NotificationChannelGroup group = groups.get(i);
                 createNotificationChannelGroup(pkg, Binder.getCallingUid(), group, true, false);
             }
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         private void createNotificationChannelsImpl(String pkg, int uid,
@@ -2368,7 +2382,7 @@
                         mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(), false),
                         NOTIFICATION_CHANNEL_OR_GROUP_ADDED);
             }
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         @Override
@@ -2413,7 +2427,7 @@
                     UserHandle.getUserHandleForUid(callingUid),
                     mPreferencesHelper.getNotificationChannel(pkg, callingUid, channelId, true),
                     NOTIFICATION_CHANNEL_OR_GROUP_DELETED);
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         @Override
@@ -2455,7 +2469,7 @@
                 mListeners.notifyNotificationChannelGroupChanged(
                         pkg, UserHandle.getUserHandleForUid(callingUid), groupToDelete,
                         NOTIFICATION_CHANNEL_OR_GROUP_DELETED);
-                handleSavePolicyFile();
+                savePolicyFile();
             }
         }
 
@@ -2588,7 +2602,7 @@
                         true, UserHandle.getCallingUserId(), packages, uids);
             }
 
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
 
@@ -3376,7 +3390,7 @@
                 final ByteArrayInputStream bais = new ByteArrayInputStream(payload);
                 try {
                     readPolicyXml(bais, true /*forRestore*/);
-                    handleSavePolicyFile();
+                    savePolicyFile();
                 } catch (NumberFormatException | XmlPullParserException | IOException e) {
                     Slog.w(TAG, "applyRestore: error reading payload", e);
                 }
@@ -3417,7 +3431,7 @@
                                     .setPackage(pkg)
                                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
                             UserHandle.of(userId), null);
-                    handleSavePolicyFile();
+                    savePolicyFile();
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -3561,7 +3575,7 @@
                                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
                             UserHandle.of(userId), null);
 
-                    handleSavePolicyFile();
+                    savePolicyFile();
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -3587,7 +3601,7 @@
                                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
                             UserHandle.of(userId), null);
 
-                    handleSavePolicyFile();
+                    savePolicyFile();
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -3670,7 +3684,7 @@
             verifyPrivilegedListener(token, user, false);
             createNotificationChannelGroup(
                     pkg, getUidForPackageAndUser(pkg, user), group, false, true);
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         @Override
@@ -3719,7 +3733,7 @@
             }
             if (allow != mLockScreenAllowSecureNotifications) {
                 mLockScreenAllowSecureNotifications = allow;
-                handleSavePolicyFile();
+                savePolicyFile();
             }
         }
 
@@ -4478,7 +4492,7 @@
                 Slog.d(TAG, "Ignored enqueue for snoozed notification " + r.getKey());
             }
             mSnoozeHelper.update(userId, r);
-            handleSavePolicyFile();
+            savePolicyFile();
             return false;
         }
 
@@ -4609,7 +4623,7 @@
                 mSnoozeHelper.snooze(r, mDuration);
             }
             r.recordSnoozed();
-            handleSavePolicyFile();
+            savePolicyFile();
         }
     }
 
@@ -4687,7 +4701,7 @@
                     if (mReason != REASON_SNOOZED) {
                         final boolean wasSnoozed = mSnoozeHelper.cancel(mUserId, mPkg, mTag, mId);
                         if (wasSnoozed) {
-                            handleSavePolicyFile();
+                            savePolicyFile();
                         }
                     }
                 }
@@ -5131,7 +5145,9 @@
 
         // Should this notification make noise, vibe, or use the LED?
         final boolean aboveThreshold =
-                record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT;
+                mIsAutomotive
+                        ? record.getImportance() > NotificationManager.IMPORTANCE_DEFAULT
+                        : record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT;
 
         // Remember if this notification already owns the notification channels.
         boolean wasBeep = key != null && key.equals(mSoundNotificationKey);
@@ -5729,6 +5745,9 @@
                 case MESSAGE_FINISH_TOKEN_TIMEOUT:
                     handleKillTokenTimeout((ToastRecord) msg.obj);
                     break;
+                case MESSAGE_SAVE_POLICY_FILE:
+                    handleSavePolicyFile();
+                    break;
                 case MESSAGE_SEND_RANKING_UPDATE:
                     handleSendRankingUpdate();
                     break;
@@ -6246,7 +6265,7 @@
             Slog.d(TAG, String.format("unsnooze event(%s, %s)", key, listenerName));
         }
         mSnoozeHelper.repost(key);
-        handleSavePolicyFile();
+        savePolicyFile();
     }
 
     @GuardedBy("mNotificationLock")
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8abb500..dab4e79 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -58,6 +58,7 @@
 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
 import static android.content.pm.PackageManager.INSTALL_INTERNAL;
+import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
@@ -10299,12 +10300,21 @@
                         compareSignatures(
                             signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures,
                             pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) {
-                        // Treat mismatched signatures on system packages using a shared UID as
-                        // fatal for the system overall, rather than just failing to install
-                        // whichever package happened to be scanned later.
-                        throw new IllegalStateException(
-                                "Signature mismatch on system package " + pkg.packageName
-                                + " for shared user " + pkgSetting.sharedUser);
+                        if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 28) {
+                            // Mismatched signatures is an error and silently skipping system
+                            // packages will likely break the device in unforeseen ways. However,
+                            // we allow the device to boot anyway because, prior to P, vendors were
+                            // not expecting the platform to crash in this situation.
+                            throw new PackageManagerException(
+                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
+                                    "Signature mismatch for shared user: " + pkgSetting.sharedUser);
+                        } else {
+                            // Treat mismatched signatures on system packages using a shared UID as
+                            // fatal for the system overall, rather than just failing to install
+                            // whichever package happened to be scanned later.
+                            throw new IllegalStateException("Signature mismatch on system package "
+                                + pkg.packageName + " for shared user " + pkgSetting.sharedUser);
+                        }
                     }
 
                     signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails;
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 68fe1d8..51619cf 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -46,7 +46,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
 import android.permission.PermissionManager;
@@ -1059,6 +1058,17 @@
             return;
         }
 
+        // Intersect the requestedPermissions for a factory image with that of its current update
+        // in case the latter one removed a <uses-permission>
+        String[] requestedByNonSystemPackage = getPackageInfo(pkg.packageName).requestedPermissions;
+        int size = requestedPermissions.length;
+        for (int i = 0; i < size; i++) {
+            if (!ArrayUtils.contains(requestedByNonSystemPackage, requestedPermissions[i])) {
+                requestedPermissions[i] = null;
+            }
+        }
+        requestedPermissions = ArrayUtils.filterNotNull(requestedPermissions, String[]::new);
+
         PackageManager pm = mContext.getPackageManager();
         final ArraySet<String> permissions = new ArraySet<>(permissionsWithoutSplits);
         ApplicationInfo applicationInfo = pkg.applicationInfo;
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index 79e2688..07bebad 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -29,8 +29,12 @@
 import android.os.IThermalService;
 import android.os.IThermalStatusListener;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.os.ShellCommand;
 import android.os.Temperature;
 import android.util.ArrayMap;
 import android.util.Slog;
@@ -77,6 +81,10 @@
     @GuardedBy("mLock")
     private int mStatus;
 
+    /** If override status takes effect*/
+    @GuardedBy("mLock")
+    private boolean mIsStatusOverride;
+
     /** Current thermal map, key as name */
     @GuardedBy("mLock")
     private ArrayMap<String, Temperature> mTemperatureMap = new ArrayMap<>();
@@ -184,13 +192,19 @@
                 newStatus = t.getStatus();
             }
         }
+        // Do not update if override from shell
+        if (!mIsStatusOverride) {
+            setStatusLocked(newStatus);
+        }
+    }
+
+    private void setStatusLocked(int newStatus) {
         if (newStatus != mStatus) {
             mStatus = newStatus;
             notifyStatusListenersLocked();
         }
     }
 
-
     private void postEventListenerCurrentTemperatures(IThermalEventListener listener,
             @Nullable Integer type) {
         synchronized (mLock) {
@@ -241,12 +255,7 @@
             // Thermal Shutdown for Skin temperature
             if (temperature.getStatus() == Temperature.THROTTLING_SHUTDOWN
                     && temperature.getType() == Temperature.TYPE_SKIN) {
-                final long token = Binder.clearCallingIdentity();
-                try {
-                    mPowerManager.shutdown(false, PowerManager.SHUTDOWN_THERMAL_STATE, false);
-                } finally {
-                    Binder.restoreCallingIdentity(token);
-                }
+                mPowerManager.shutdown(false, PowerManager.SHUTDOWN_THERMAL_STATE, false);
             }
 
             Temperature old = mTemperatureMap.put(temperature.getName(), temperature);
@@ -263,8 +272,14 @@
         }
     }
 
+    /* HwBinder callback **/
     private void onTemperatureChangedCallback(Temperature temperature) {
-        onTemperatureChanged(temperature, true);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            onTemperatureChanged(temperature, true);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     private void dumpTemperaturesLocked(PrintWriter pw, String prefix,
@@ -393,7 +408,7 @@
         }
 
         @Override
-        public int getCurrentStatus() {
+        public int getCurrentThermalStatus() {
             synchronized (mLock) {
                 final long token = Binder.clearCallingIdentity();
                 try {
@@ -434,8 +449,93 @@
                 Binder.restoreCallingIdentity(token);
             }
         }
+
+        private boolean isCallerShell() {
+            final int callingUid = Binder.getCallingUid();
+            return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID;
+        }
+
+        @Override
+        public void onShellCommand(FileDescriptor in, FileDescriptor out,
+                FileDescriptor err, String[] args, ShellCallback callback,
+                ResultReceiver resultReceiver) {
+            if (!isCallerShell()) {
+                Slog.w(TAG, "Only shell is allowed to call thermalservice shell commands");
+                return;
+            }
+            (new ThermalShellCommand()).exec(
+                    this, in, out, err, args, callback, resultReceiver);
+        }
+
     };
 
+    class ThermalShellCommand extends ShellCommand {
+        @Override
+        public int onCommand(String cmd) {
+            switch(cmd != null ? cmd : "") {
+                case "override-status":
+                    return runOverrideStatus();
+                case "reset":
+                    return runReset();
+                default:
+                    return handleDefaultCommands(cmd);
+            }
+        }
+
+        private int runReset() {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    mIsStatusOverride = false;
+                    onTemperatureMapChangedLocked();
+                    return 0;
+                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        private int runOverrideStatus() {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                final PrintWriter pw = getOutPrintWriter();
+                int status;
+                try {
+                    status = Integer.parseInt(getNextArgRequired());
+                } catch (RuntimeException ex) {
+                    pw.println("Error: " + ex.toString());
+                    return -1;
+                }
+                if (!Temperature.isValidStatus(status)) {
+                    pw.println("Invalid status: " + Integer.toString(status));
+                    return -1;
+                }
+                synchronized (mLock) {
+                    mIsStatusOverride = true;
+                    setStatusLocked(status);
+                }
+                return 0;
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void onHelp() {
+            final PrintWriter pw = getOutPrintWriter();
+            pw.println("Thermal service (thermalservice) commands:");
+            pw.println("  help");
+            pw.println("    Print this help text.");
+            pw.println("");
+            pw.println("  override-status STATUS");
+            pw.println("    sets and locks the thermal status of the device to STATUS.");
+            pw.println("    status code is defined in android.os.Temperature.");
+            pw.println("  reset");
+            pw.println("    unlocks the thermal status of the device.");
+            pw.println();
+        }
+    }
+
     abstract static class ThermalHalWrapper {
         protected static final String TAG = ThermalHalWrapper.class.getSimpleName();
 
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index b065470..b5ad235 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -55,6 +55,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
@@ -106,7 +107,7 @@
         intentFilter.addAction(Intent.ACTION_USER_REMOVED);
         getContext().registerReceiverAsUser(new BroadcastReceiver() {
             @Override
-            public void onReceive(Context context, Intent intent) {
+            public void onReceive(@NonNull Context context, @NonNull Intent intent) {
                 if (TextUtils.equals(intent.getAction(), Intent.ACTION_USER_REMOVED)) {
                     int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                     onRemoveUser(userId);
@@ -129,10 +130,11 @@
             userState = getUserStateLocked(userId);
         }
         String packagesHash = computeComponentStateHash(userId);
-        boolean needGrant;
+        String lastGrantPackagesHash;
         synchronized (mLock) {
-            needGrant = !packagesHash.equals(userState.getLastGrantPackagesHashLocked());
+            lastGrantPackagesHash = userState.getLastGrantPackagesHashLocked();
         }
+        boolean needGrant = !Objects.equals(packagesHash, lastGrantPackagesHash);
         if (needGrant) {
             // Some vital packages state has changed since last role grant
             // Run grants again
@@ -144,7 +146,6 @@
                         public void onSuccess() {
                             result.complete(null);
                         }
-
                         @Override
                         public void onFailure() {
                             result.completeExceptionally(new RuntimeException());
@@ -163,7 +164,8 @@
         }
     }
 
-    private String computeComponentStateHash(int userId) {
+    @Nullable
+    private String computeComponentStateHash(@UserIdInt int userId) {
         PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
         ByteArrayOutputStream out = new ByteArrayOutputStream();
 
@@ -198,8 +200,7 @@
     private RoleUserState getUserStateLocked(@UserIdInt int userId) {
         RoleUserState userState = mUserStates.get(userId);
         if (userState == null) {
-            userState = new RoleUserState(userId);
-            userState.readSyncLocked();
+            userState = RoleUserState.newInstanceLocked(userId);
             mUserStates.put(userId, userState);
         }
         return userState;
@@ -386,11 +387,11 @@
         }
 
         @Override
-        public void onShellCommand(FileDescriptor in, FileDescriptor out,
-                FileDescriptor err, String[] args, ShellCallback callback,
-                ResultReceiver resultReceiver) {
-            (new RoleManagerShellCommand(this)).exec(
-                    this, in, out, err, args, callback, resultReceiver);
+        public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+                @Nullable FileDescriptor err, @NonNull String[] args,
+                @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver) {
+            new RoleManagerShellCommand(this).exec(this, in, out, err, args, callback,
+                    resultReceiver);
         }
     }
 }
diff --git a/services/core/java/com/android/server/role/RoleManagerShellCommand.java b/services/core/java/com/android/server/role/RoleManagerShellCommand.java
index e1977ef..336b311 100644
--- a/services/core/java/com/android/server/role/RoleManagerShellCommand.java
+++ b/services/core/java/com/android/server/role/RoleManagerShellCommand.java
@@ -16,6 +16,8 @@
 
 package com.android.server.role;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.role.IRoleManager;
 import android.app.role.IRoleManagerCallback;
 import android.os.RemoteException;
@@ -27,13 +29,17 @@
 import java.util.concurrent.TimeUnit;
 
 class RoleManagerShellCommand extends ShellCommand {
+
+    @NonNull
     private final IRoleManager mRoleManager;
 
-    RoleManagerShellCommand(IRoleManager roleManager) {
+    RoleManagerShellCommand(@NonNull IRoleManager roleManager) {
         mRoleManager = roleManager;
     }
 
     private class Callback extends IRoleManagerCallback.Stub {
+
+        @NonNull
         private final CompletableFuture<Void> mResult = new CompletableFuture<>();
 
         public int waitForResult() {
@@ -58,7 +64,7 @@
     }
 
     @Override
-    public int onCommand(String cmd) {
+    public int onCommand(@Nullable String cmd) {
         if (cmd == null) {
             return handleDefaultCommands(cmd);
         }
diff --git a/services/core/java/com/android/server/role/RoleUserState.java b/services/core/java/com/android/server/role/RoleUserState.java
index f218d3a..3e3e156 100644
--- a/services/core/java/com/android/server/role/RoleUserState.java
+++ b/services/core/java/com/android/server/role/RoleUserState.java
@@ -47,6 +47,7 @@
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Stores the state of roles for a user.
@@ -70,25 +71,41 @@
     private final int mUserId;
 
     @GuardedBy("RoleManagerService.mLock")
-    private int mVersion;
+    private int mVersion = VERSION_UNDEFINED;
 
     @GuardedBy("RoleManagerService.mLock")
-    private String mLastGrantPackagesHash = null;
+    @Nullable
+    private String mLastGrantPackagesHash;
 
     /**
      * Maps role names to its holders' package names. The values should never be null.
      */
     @GuardedBy("RoleManagerService.mLock")
-    @Nullable
-    private ArrayMap<String, ArraySet<String>> mRoles = null;
+    @NonNull
+    private ArrayMap<String, ArraySet<String>> mRoles = new ArrayMap<>();
 
     @GuardedBy("RoleManagerService.mLock")
     private boolean mDestroyed;
 
+    @NonNull
     private final Handler mWriteHandler = new Handler(BackgroundThread.getHandler().getLooper());
 
-    public RoleUserState(@UserIdInt int userId) {
+    private RoleUserState(@UserIdInt int userId) {
         mUserId = userId;
+
+        readSyncLocked();
+    }
+
+    /**
+     * Create a new instance of user state, and read its state from disk if previously persisted.
+     *
+     * @param userId the user id for the new user state
+     *
+     * @return the new user state
+     */
+    @GuardedBy("RoleManagerService.mLock")
+    public static RoleUserState newInstanceLocked(@UserIdInt int userId) {
+        return new RoleUserState(userId);
     }
 
     /**
@@ -116,7 +133,9 @@
     }
 
     /**
-     * Get the hash representing the state of packages during the last time initial grants was run
+     * Get the hash representing the state of packages during the last time initial grants was run.
+     *
+     * @return the hash representing the state of packages
      */
     @GuardedBy("RoleManagerService.mLock")
     public String getLastGrantPackagesHashLocked() {
@@ -124,10 +143,16 @@
     }
 
     /**
-     * Set the hash representing the state of packages during the last time initial grants was run
+     * Set the hash representing the state of packages during the last time initial grants was run.
+     *
+     * @param lastGrantPackagesHash the hash representing the state of packages
      */
     @GuardedBy("RoleManagerService.mLock")
-    public void setLastGrantPackagesHashLocked(String lastGrantPackagesHash) {
+    public void setLastGrantPackagesHashLocked(@Nullable String lastGrantPackagesHash) {
+        throwIfDestroyedLocked();
+        if (Objects.equals(mLastGrantPackagesHash, lastGrantPackagesHash)) {
+            return;
+        }
         mLastGrantPackagesHash = lastGrantPackagesHash;
         writeAsyncLocked();
     }
@@ -250,9 +275,9 @@
      * Schedule writing the state to file.
      */
     @GuardedBy("RoleManagerService.mLock")
-    void writeAsyncLocked() {
+    private void writeAsyncLocked() {
         throwIfDestroyedLocked();
-        int version = mVersion;
+
         ArrayMap<String, ArraySet<String>> roles = new ArrayMap<>();
         for (int i = 0, size = CollectionUtils.size(mRoles); i < size; ++i) {
             String roleName = mRoles.keyAt(i);
@@ -260,15 +285,16 @@
             roleHolders = new ArraySet<>(roleHolders);
             roles.put(roleName, roleHolders);
         }
+
         mWriteHandler.removeCallbacksAndMessages(null);
         // TODO: Throttle writes.
-        mWriteHandler.sendMessage(PooledLambda.obtainMessage(
-                RoleUserState::writeSync, this, version, roles, mLastGrantPackagesHash));
+        mWriteHandler.sendMessage(PooledLambda.obtainMessage(RoleUserState::writeSync, this,
+                mVersion, mLastGrantPackagesHash, roles));
     }
 
     @WorkerThread
-    private void writeSync(int version, @NonNull ArrayMap<String, ArraySet<String>> roles,
-            String packagesHash) {
+    private void writeSync(int version, @Nullable String packagesHash,
+            @NonNull ArrayMap<String, ArraySet<String>> roles) {
         AtomicFile atomicFile = new AtomicFile(getFile(mUserId), "roles-" + mUserId);
         FileOutputStream out = null;
         try {
@@ -280,7 +306,7 @@
                     "http://xmlpull.org/v1/doc/features.html#indent-output", true);
             serializer.startDocument(null, true);
 
-            serializeRoles(serializer, version, roles, packagesHash);
+            serializeRoles(serializer, version, packagesHash, roles);
 
             serializer.endDocument();
             atomicFile.finishWrite(out);
@@ -296,19 +322,26 @@
 
     @WorkerThread
     private void serializeRoles(@NonNull XmlSerializer serializer, int version,
-            @NonNull ArrayMap<String, ArraySet<String>> roles, String packagesHash)
+            @Nullable String packagesHash, @NonNull ArrayMap<String, ArraySet<String>> roles)
             throws IOException {
         serializer.startTag(null, TAG_ROLES);
+
         serializer.attribute(null, ATTRIBUTE_VERSION, Integer.toString(version));
-        serializer.attribute(null, ATTRIBUTE_PACKAGES_HASH, packagesHash);
+
+        if (packagesHash != null) {
+            serializer.attribute(null, ATTRIBUTE_PACKAGES_HASH, packagesHash);
+        }
+
         for (int i = 0, size = roles.size(); i < size; ++i) {
             String roleName = roles.keyAt(i);
             ArraySet<String> roleHolders = roles.valueAt(i);
+
             serializer.startTag(null, TAG_ROLE);
             serializer.attribute(null, ATTRIBUTE_NAME, roleName);
             serializeRoleHolders(serializer, roleHolders);
             serializer.endTag(null, TAG_ROLE);
         }
+
         serializer.endTag(null, TAG_ROLES);
     }
 
@@ -317,6 +350,7 @@
             @NonNull ArraySet<String> roleHolders) throws IOException {
         for (int i = 0, size = roleHolders.size(); i < size; ++i) {
             String roleHolder = roleHolders.valueAt(i);
+
             serializer.startTag(null, TAG_HOLDER);
             serializer.attribute(null, ATTRIBUTE_NAME, roleHolder);
             serializer.endTag(null, TAG_HOLDER);
@@ -327,11 +361,7 @@
      * Read the state from file.
      */
     @GuardedBy("RoleManagerService.mLock")
-    public void readSyncLocked() {
-        if (mRoles != null) {
-            throw new IllegalStateException("This RoleUserState has already read the roles.xml");
-        }
-
+    private void readSyncLocked() {
         File file = getFile(mUserId);
         try (FileInputStream in = new AtomicFile(file).openRead()) {
             XmlPullParser parser = Xml.newPullParser();
@@ -339,8 +369,6 @@
             parseXmlLocked(parser);
         } catch (FileNotFoundException e) {
             Slog.i(LOG_TAG, "roles.xml not found");
-            mRoles = new ArrayMap<>();
-            mVersion = VERSION_UNDEFINED;
         } catch (XmlPullParserException | IOException e) {
             throw new IllegalStateException("Failed to parse roles.xml: " + file, e);
         }
@@ -362,13 +390,14 @@
                 return;
             }
         }
+        Slog.w(LOG_TAG, "Missing <" + TAG_ROLES + "> in roles.xml");
     }
 
     private void parseRolesLocked(@NonNull XmlPullParser parser) throws IOException,
             XmlPullParserException {
         mVersion = Integer.parseInt(parser.getAttributeValue(null, ATTRIBUTE_VERSION));
         mLastGrantPackagesHash = parser.getAttributeValue(null, ATTRIBUTE_PACKAGES_HASH);
-        mRoles = new ArrayMap<>();
+        mRoles.clear();
 
         int type;
         int depth;
diff --git a/services/core/java/com/android/server/signedconfig/SignedConfigApplicator.java b/services/core/java/com/android/server/signedconfig/SignedConfigApplicator.java
new file mode 100644
index 0000000..7ce071f
--- /dev/null
+++ b/services/core/java/com/android/server/signedconfig/SignedConfigApplicator.java
@@ -0,0 +1,28 @@
+/*
+ * 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.signedconfig;
+
+import android.content.Context;
+
+class SignedConfigApplicator {
+
+    static void applyConfig(Context context, String config, String signature) {
+        //TODO verify signature
+        //TODO parse & apply config
+    }
+
+}
diff --git a/services/core/java/com/android/server/signedconfig/SignedConfigService.java b/services/core/java/com/android/server/signedconfig/SignedConfigService.java
new file mode 100644
index 0000000..1485686
--- /dev/null
+++ b/services/core/java/com/android/server/signedconfig/SignedConfigService.java
@@ -0,0 +1,105 @@
+/*
+ * 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.signedconfig;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Slog;
+
+import com.android.server.LocalServices;
+
+/**
+ * Signed config service. This is not an Android Service, but just owns a broadcast receiver for
+ * receiving package install and update notifications from the package manager.
+ */
+public class SignedConfigService {
+
+    private static final boolean DBG = false;
+    private static final String TAG = "SignedConfig";
+
+    // TODO should these be elsewhere? In a public API?
+    private static final String KEY_CONFIG = "android.signedconfig";
+    private static final String KEY_CONFIG_SIGNATURE = "android.signedconfig.signature";
+
+    private static class UpdateReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            new SignedConfigService(context).handlePackageBroadcast(intent);
+        }
+    }
+
+    private final Context mContext;
+    private final PackageManagerInternal mPacMan;
+
+    public SignedConfigService(Context context) {
+        mContext = context;
+        mPacMan = LocalServices.getService(PackageManagerInternal.class);
+    }
+
+    void handlePackageBroadcast(Intent intent) {
+        if (DBG) Slog.d(TAG, "handlePackageBroadcast " + intent);
+        Uri packageData = intent.getData();
+        String packageName = packageData == null ? null : packageData.getSchemeSpecificPart();
+        if (DBG) Slog.d(TAG, "handlePackageBroadcast package=" + packageName);
+        if (packageName == null) {
+            return;
+        }
+        int userId = mContext.getUser().getIdentifier();
+        PackageInfo pi = mPacMan.getPackageInfo(packageName, PackageManager.GET_META_DATA,
+                android.os.Process.SYSTEM_UID, userId);
+        if (pi == null) {
+            Slog.w(TAG, "Got null PackageInfo for " + packageName + "; user " + userId);
+            return;
+        }
+        Bundle metaData = pi.applicationInfo.metaData;
+        if (metaData == null) {
+            if (DBG) Slog.d(TAG, "handlePackageBroadcast: no metadata");
+            return;
+        }
+        if (metaData.containsKey(KEY_CONFIG)
+                && metaData.containsKey(KEY_CONFIG_SIGNATURE)) {
+            String config = metaData.getString(KEY_CONFIG);
+            String signature = metaData.getString(KEY_CONFIG_SIGNATURE);
+            if (DBG) {
+                Slog.d(TAG, "Got signed config: " + config);
+                Slog.d(TAG, "Got config signature: " + signature);
+            }
+            SignedConfigApplicator.applyConfig(mContext, config, signature);
+        } else {
+            if (DBG) Slog.d(TAG, "Package has no config/signature.");
+        }
+    }
+
+    /**
+     * Register to receive broadcasts from the package manager.
+     */
+    public static void registerUpdateReceiver(Context context) {
+        if (DBG) Slog.d(TAG, "Registering receiver");
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+        filter.addDataScheme("package");
+        context.registerReceiver(new UpdateReceiver(), filter);
+    }
+}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index e645b84..6e4c00e 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -17,6 +17,7 @@
 package com.android.server.statusbar;
 
 import static android.app.StatusBarManager.DISABLE2_GLOBAL_ACTIONS;
+import static android.view.Display.DEFAULT_DISPLAY;
 
 import android.app.ActivityThread;
 import android.app.Notification;
@@ -25,6 +26,8 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.hardware.biometrics.IBiometricServiceReceiverInternal;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManager.DisplayListener;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -40,7 +43,7 @@
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
-import android.view.Display;
+import android.util.SparseArray;
 
 import com.android.internal.R;
 import com.android.internal.statusbar.IStatusBar;
@@ -63,7 +66,7 @@
  * A note on locking:  We rely on the fact that calls onto mBar are oneway or
  * if they are local, that they just enqueue messages to not deadlock.
  */
-public class StatusBarManagerService extends IStatusBarService.Stub {
+public class StatusBarManagerService extends IStatusBarService.Stub implements DisplayListener {
     private static final String TAG = "StatusBarManagerService";
     private static final boolean SPEW = false;
 
@@ -79,24 +82,13 @@
     private final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
     private GlobalActionsProvider.GlobalActionsListener mGlobalActionListener;
     private IBinder mSysUiVisToken = new Binder();
-    private int mDisabled1 = 0;
-    private int mDisabled2 = 0;
 
     private final Object mLock = new Object();
     private final DeathRecipient mDeathRecipient = new DeathRecipient();
-    // encompasses lights-out mode and other flags defined on View
-    private int mSystemUiVisibility = 0;
-    private int mFullscreenStackSysUiVisibility;
-    private int mDockedStackSysUiVisibility;
-    private final Rect mFullscreenStackBounds = new Rect();
-    private final Rect mDockedStackBounds = new Rect();
-    private boolean mMenuVisible = false;
-    private int mImeWindowVis = 0;
-    private int mImeBackDisposition;
-    private boolean mShowImeSwitcher;
-    private IBinder mImeToken = null;
     private int mCurrentUserId;
 
+    private SparseArray<UiState> mDisplayUiState = new SparseArray<>();
+
     private class DeathRecipient implements IBinder.DeathRecipient {
         public void binderDied() {
             mBar.asBinder().unlinkToDeath(this,0);
@@ -185,8 +177,29 @@
 
         LocalServices.addService(StatusBarManagerInternal.class, mInternalService);
         LocalServices.addService(GlobalActionsProvider.class, mGlobalActionsProvider);
+
+        // We always have a default display.
+        final UiState state = new UiState();
+        mDisplayUiState.put(DEFAULT_DISPLAY, state);
+
+        final DisplayManager displayManager =
+                (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
+        displayManager.registerDisplayListener(this, mHandler);
     }
 
+    @Override
+    public void onDisplayAdded(int displayId) {}
+
+    @Override
+    public void onDisplayRemoved(int displayId) {
+        synchronized (mLock) {
+            mDisplayUiState.remove(displayId);
+        }
+    }
+
+    @Override
+    public void onDisplayChanged(int displayId) {}
+
     /**
      * Private API used by NotificationManagerService.
      */
@@ -240,22 +253,14 @@
 
         @Override
         public void topAppWindowChanged(int displayId, boolean menuVisible) {
-            if (displayId != Display.DEFAULT_DISPLAY) {
-                // TODO (b/117478341): Resolve one status bar/ navigation bar assumption
-                return;
-            }
-            StatusBarManagerService.this.topAppWindowChanged(menuVisible);
+            StatusBarManagerService.this.topAppWindowChanged(displayId, menuVisible);
         }
 
         @Override
         public void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis,
                 int dockedStackVis, int mask, Rect fullscreenBounds, Rect dockedBounds,
                 String cause) {
-            if (displayId != Display.DEFAULT_DISPLAY) {
-                // TODO (b/117478341): Resolve one status bar/ navigation bar assumption
-                return;
-            }
-            StatusBarManagerService.this.setSystemUiVisibility(vis, fullscreenStackVis,
+            StatusBarManagerService.this.setSystemUiVisibility(displayId, vis, fullscreenStackVis,
                     dockedStackVis, mask, fullscreenBounds, dockedBounds, cause);
         }
 
@@ -272,13 +277,9 @@
         @Override
         public void appTransitionFinished(int displayId) {
             enforceStatusBarService();
-            if (displayId != Display.DEFAULT_DISPLAY) {
-                // TODO (b/117478341): Resolve one status bar/ navigation bar assumption
-                return;
-            }
             if (mBar != null) {
                 try {
-                    mBar.appTransitionFinished();
+                    mBar.appTransitionFinished(displayId);
                 } catch (RemoteException ex) {}
             }
         }
@@ -374,39 +375,27 @@
 
         @Override
         public void setWindowState(int displayId, int window, int state) {
-            if (displayId != Display.DEFAULT_DISPLAY) {
-                // TODO (b/117478341): Resolve one status bar/ navigation bar assumption
-                return;
-            }
             if (mBar != null) {
                 try {
-                    mBar.setWindowState(window, state);
+                    mBar.setWindowState(displayId, window, state);
                 } catch (RemoteException ex) {}
             }
         }
 
         @Override
         public void appTransitionPending(int displayId) {
-            if (displayId != Display.DEFAULT_DISPLAY) {
-                // TODO (b/117478341): Resolve one status bar/ navigation bar assumption
-                return;
-            }
             if (mBar != null) {
                 try {
-                    mBar.appTransitionPending();
+                    mBar.appTransitionPending(displayId);
                 } catch (RemoteException ex) {}
             }
         }
 
         @Override
         public void appTransitionCancelled(int displayId) {
-            if (displayId != Display.DEFAULT_DISPLAY) {
-                // TODO (b/117478341): Resolve one status bar/ navigation bar assumption
-                return;
-            }
             if (mBar != null) {
                 try {
-                    mBar.appTransitionCancelled();
+                    mBar.appTransitionCancelled(displayId);
                 } catch (RemoteException ex) {}
             }
         }
@@ -414,14 +403,10 @@
         @Override
         public void appTransitionStarting(int displayId, long statusBarAnimationsStartTime,
                 long statusBarAnimationsDuration) {
-            if (displayId != Display.DEFAULT_DISPLAY) {
-                // TODO (b/117478341): Resolve one status bar/ navigation bar assumption
-                return;
-            }
             if (mBar != null) {
                 try {
                     mBar.appTransitionStarting(
-                            statusBarAnimationsStartTime, statusBarAnimationsDuration);
+                            displayId, statusBarAnimationsStartTime, statusBarAnimationsDuration);
                 } catch (RemoteException ex) {}
             }
         }
@@ -449,6 +434,7 @@
             return false;
         }
 
+        // TODO(b/118592525): support it per display if necessary.
         @Override
         public void onProposedRotationChanged(int rotation, boolean isValid) {
             if (mBar != null){
@@ -462,7 +448,9 @@
     private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() {
         @Override
         public boolean isGlobalActionsDisabled() {
-            return (mDisabled2 & DISABLE2_GLOBAL_ACTIONS) != 0;
+            // TODO(b/118592525): support global actions for multi-display.
+            final int disabled2 = mDisplayUiState.get(DEFAULT_DISPLAY).getDisabled2();
+            return (disabled2 & DISABLE2_GLOBAL_ACTIONS) != 0;
         }
 
         @Override
@@ -664,20 +652,23 @@
         }
     }
 
+    // TODO(b/117478341): make it aware of multi-display if needed.
     @Override
     public void disable(int what, IBinder token, String pkg) {
         disableForUser(what, token, pkg, mCurrentUserId);
     }
 
+    // TODO(b/117478341): make it aware of multi-display if needed.
     @Override
     public void disableForUser(int what, IBinder token, String pkg, int userId) {
         enforceStatusBar();
 
         synchronized (mLock) {
-            disableLocked(userId, what, token, pkg, 1);
+            disableLocked(DEFAULT_DISPLAY, userId, what, token, pkg, 1);
         }
     }
 
+    // TODO(b/117478341): make it aware of multi-display if needed.
     /**
      * Disable additional status bar features. Pass the bitwise-or of the DISABLE2_* flags.
      * To re-enable everything, pass {@link #DISABLE_NONE}.
@@ -689,6 +680,7 @@
         disable2ForUser(what, token, pkg, mCurrentUserId);
     }
 
+    // TODO(b/117478341): make it aware of multi-display if needed.
     /**
      * Disable additional status bar features for a given user. Pass the bitwise-or of the
      * DISABLE2_* flags. To re-enable everything, pass {@link #DISABLE_NONE}.
@@ -700,11 +692,12 @@
         enforceStatusBar();
 
         synchronized (mLock) {
-            disableLocked(userId, what, token, pkg, 2);
+            disableLocked(DEFAULT_DISPLAY, userId, what, token, pkg, 2);
         }
     }
 
-    private void disableLocked(int userId, int what, IBinder token, String pkg, int whichFlag) {
+    private void disableLocked(int displayId, int userId, int what, IBinder token, String pkg,
+            int whichFlag) {
         // It's important that the the callback and the call to mBar get done
         // in the same order when multiple threads are calling this function
         // so they are paired correctly.  The messages on the handler will be
@@ -723,22 +716,19 @@
                 disabledData += "    ([" + i + "] " + tok + "), ";
             }
             disabledData += " }";
-            Log.d(TAG, "disabledlocked (b/113914868): net1=" + net1 + ", mDisabled1=" + mDisabled1
-                    + ", token=" + token + ", mDisableRecords=" + mDisableRecords.size() + " => "
-                    + disabledData);
-        }
+            final UiState state = getUiState(displayId);
 
-        if (net1 != mDisabled1 || net2 != mDisabled2) {
-            mDisabled1 = net1;
-            mDisabled2 = net2;
-            mHandler.post(new Runnable() {
-                    public void run() {
-                        mNotificationDelegate.onSetDisabled(net1);
-                    }
-                });
+            Log.d(TAG, "disabledlocked (b/113914868): displayId=" + displayId + "net1=" + net1
+                    + ", mDisabled1=" + state.mDisabled1 + ", token=" + token
+                    + ", mDisableRecords=" + mDisableRecords.size() + " => " + disabledData);
+        }
+        final UiState state = getUiState(displayId);
+        if (state.disableEquals(net1, net2)) {
+            state.setDisabled(net1, net2);
+            mHandler.post(() -> mNotificationDelegate.onSetDisabled(net1));
             if (mBar != null) {
                 try {
-                    mBar.disable(net1, net2);
+                    mBar.disable(displayId, net1, net2);
                 } catch (RemoteException ex) {
                 }
             }
@@ -808,26 +798,27 @@
      * response to a window with {@link android.view.WindowManager.LayoutParams#needsMenuKey} set
      * to {@link android.view.WindowManager.LayoutParams#NEEDS_MENU_SET_TRUE}.
      */
-    private void topAppWindowChanged(final boolean menuVisible) {
+    private void topAppWindowChanged(int displayId, final boolean menuVisible) {
         enforceStatusBar();
 
-        if (SPEW) Slog.d(TAG, (menuVisible?"showing":"hiding") + " MENU key");
-
+        if (SPEW) {
+            Slog.d(TAG, "display#" + displayId + ": "
+                    + (menuVisible ? "showing" : "hiding") + " MENU key");
+        }
         synchronized(mLock) {
-            mMenuVisible = menuVisible;
-            mHandler.post(new Runnable() {
-                public void run() {
-                    if (mBar != null) {
-                        try {
-                            mBar.topAppWindowChanged(menuVisible);
-                        } catch (RemoteException ex) {
-                        }
+            getUiState(displayId).setMenuVisible(menuVisible);
+            mHandler.post(() -> {
+                if (mBar != null) {
+                    try {
+                        mBar.topAppWindowChanged(displayId, menuVisible);
+                    } catch (RemoteException ex) {
                     }
                 }
             });
         }
     }
 
+    // TODO(b/117478341): support back button change when IME is showing on a external display.
     @Override
     public void setImeWindowStatus(final IBinder token, final int vis, final int backDisposition,
             final boolean showImeSwitcher) {
@@ -841,39 +832,42 @@
             // In case of IME change, we need to call up setImeWindowStatus() regardless of
             // mImeWindowVis because mImeWindowVis may not have been set to false when the
             // previous IME was destroyed.
-            mImeWindowVis = vis;
-            mImeBackDisposition = backDisposition;
-            mImeToken = token;
-            mShowImeSwitcher = showImeSwitcher;
-            mHandler.post(new Runnable() {
-                public void run() {
-                    if (mBar != null) {
-                        try {
-                            mBar.setImeWindowStatus(token, vis, backDisposition, showImeSwitcher);
-                        } catch (RemoteException ex) {
-                        }
-                    }
-                }
+            // TODO(b/117478341): support back button change when IME is showing on a external
+            // display.
+            getUiState(DEFAULT_DISPLAY)
+                    .setImeWindowState(vis, backDisposition, showImeSwitcher, token);
+
+            mHandler.post(() -> {
+                if (mBar == null) return;
+                try {
+                    // TODO(b/117478341): support back button change when IME is showing on a
+                    // external display.
+                    mBar.setImeWindowStatus(
+                            DEFAULT_DISPLAY, token, vis, backDisposition, showImeSwitcher);
+                } catch (RemoteException ex) { }
             });
         }
     }
 
     @Override
-    public void setSystemUiVisibility(int vis, int mask, String cause) {
-        setSystemUiVisibility(vis, 0, 0, mask, mFullscreenStackBounds, mDockedStackBounds, cause);
+    public void setSystemUiVisibility(int displayId, int vis, int mask, String cause) {
+        final UiState state = getUiState(displayId);
+        setSystemUiVisibility(displayId, vis, 0, 0, mask,
+                state.mFullscreenStackBounds, state.mDockedStackBounds, cause);
     }
 
-    private void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis, int mask,
-            Rect fullscreenBounds, Rect dockedBounds, String cause) {
+    private void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis,
+            int dockedStackVis, int mask, Rect fullscreenBounds, Rect dockedBounds, String cause) {
         // also allows calls from window manager which is in this process.
         enforceStatusBarService();
 
         if (SPEW) Slog.d(TAG, "setSystemUiVisibility(0x" + Integer.toHexString(vis) + ")");
 
         synchronized (mLock) {
-            updateUiVisibilityLocked(vis, fullscreenStackVis, dockedStackVis, mask,
+            updateUiVisibilityLocked(displayId, vis, fullscreenStackVis, dockedStackVis, mask,
                     fullscreenBounds, dockedBounds);
             disableLocked(
+                    displayId,
                     mCurrentUserId,
                     vis & StatusBarManager.DISABLE_MASK,
                     mSysUiVisToken,
@@ -881,30 +875,107 @@
         }
     }
 
-    private void updateUiVisibilityLocked(final int vis,
+    private void updateUiVisibilityLocked(final int displayId, final int vis,
             final int fullscreenStackVis, final int dockedStackVis, final int mask,
             final Rect fullscreenBounds, final Rect dockedBounds) {
-        if (mSystemUiVisibility != vis
-                || mFullscreenStackSysUiVisibility != fullscreenStackVis
-                || mDockedStackSysUiVisibility != dockedStackVis
-                || !mFullscreenStackBounds.equals(fullscreenBounds)
-                || !mDockedStackBounds.equals(dockedBounds)) {
+        final UiState state = getUiState(displayId);
+        if (!state.systemUiStateEquals(vis, fullscreenStackVis, dockedStackVis,
+                fullscreenBounds, dockedBounds)) {
+            state.setSystemUiState(vis, fullscreenStackVis, dockedStackVis, fullscreenBounds,
+                    dockedBounds);
+            mHandler.post(() -> {
+                if (mBar != null) {
+                    try {
+                        mBar.setSystemUiVisibility(displayId, vis, fullscreenStackVis,
+                                dockedStackVis, mask, fullscreenBounds, dockedBounds);
+                    } catch (RemoteException ex) {
+                        Log.w(TAG, "Can not get StatusBar!");
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * @return {@link UiState} specified by {@code displayId}.
+     *
+     * <p>
+     *   Note: If {@link UiState} specified by {@code displayId} does not exist, {@link UiState}
+     *   will be allocated and {@code mDisplayUiState} will be updated accordingly.
+     * <p/>
+     */
+    private UiState getUiState(int displayId) {
+        UiState state = mDisplayUiState.get(displayId);
+        if (state == null) {
+            state = new UiState();
+            mDisplayUiState.put(displayId, state);
+        }
+        return state;
+    }
+
+    private class UiState {
+        private int mSystemUiVisibility = 0;
+        private int mFullscreenStackSysUiVisibility = 0;
+        private int mDockedStackSysUiVisibility = 0;
+        private final Rect mFullscreenStackBounds = new Rect();
+        private final Rect mDockedStackBounds = new Rect();
+        private boolean mMenuVisible = false;
+        private int mDisabled1 = 0;
+        private int mDisabled2 = 0;
+        private int mImeWindowVis = 0;
+        private int mImeBackDisposition = 0;
+        private boolean mShowImeSwitcher = false;
+        private IBinder mImeToken = null;
+
+        private int getDisabled1() {
+            return mDisabled1;
+        }
+
+        private int getDisabled2() {
+            return mDisabled2;
+        }
+
+        private void setDisabled(int disabled1, int disabled2) {
+            mDisabled1 = disabled1;
+            mDisabled2 = disabled2;
+        }
+
+        private boolean isMenuVisible() {
+            return mMenuVisible;
+        }
+
+        private void setMenuVisible(boolean menuVisible) {
+            mMenuVisible = menuVisible;
+        }
+
+        private boolean disableEquals(int disabled1, int disabled2) {
+            return mDisabled1 == disabled1 && mDisabled2 == disabled2;
+        }
+
+        private void setSystemUiState(final int vis, final int fullscreenStackVis,
+                final int dockedStackVis, final Rect fullscreenBounds, final Rect dockedBounds) {
             mSystemUiVisibility = vis;
             mFullscreenStackSysUiVisibility = fullscreenStackVis;
             mDockedStackSysUiVisibility = dockedStackVis;
             mFullscreenStackBounds.set(fullscreenBounds);
             mDockedStackBounds.set(dockedBounds);
-            mHandler.post(new Runnable() {
-                    public void run() {
-                        if (mBar != null) {
-                            try {
-                                mBar.setSystemUiVisibility(vis, fullscreenStackVis, dockedStackVis,
-                                        mask, fullscreenBounds, dockedBounds);
-                            } catch (RemoteException ex) {
-                            }
-                        }
-                    }
-                });
+        }
+
+        private boolean systemUiStateEquals(final int vis, final int fullscreenStackVis,
+                final int dockedStackVis, final Rect fullscreenBounds, final Rect dockedBounds) {
+            return mSystemUiVisibility == vis
+                && mFullscreenStackSysUiVisibility == fullscreenStackVis
+                && mDockedStackSysUiVisibility == dockedStackVis
+                && mFullscreenStackBounds.equals(fullscreenBounds)
+                && mDockedStackBounds.equals(dockedBounds);
+        }
+
+        private void setImeWindowState(final int vis, final int backDisposition,
+                final boolean showImeSwitcher, final IBinder token) {
+            mImeWindowVis = vis;
+            mImeBackDisposition = backDisposition;
+            mShowImeSwitcher = showImeSwitcher;
+            mImeToken = token;
         }
     }
 
@@ -939,6 +1010,7 @@
     // ================================================================================
     // Callbacks from the status bar service.
     // ================================================================================
+    // TODO(b/118592525): refactor it as an IStatusBar API.
     @Override
     public void registerStatusBar(IStatusBar bar, List<String> iconSlots,
             List<StatusBarIcon> iconList, int switches[], List<IBinder> binders,
@@ -956,18 +1028,21 @@
             }
         }
         synchronized (mLock) {
+            // TODO(b/118592525): Currently, status bar only works on the default display.
+            // Make it aware of multi-display if needed.
+            final UiState state = mDisplayUiState.get(DEFAULT_DISPLAY);
             switches[0] = gatherDisableActionsLocked(mCurrentUserId, 1);
-            switches[1] = mSystemUiVisibility;
-            switches[2] = mMenuVisible ? 1 : 0;
-            switches[3] = mImeWindowVis;
-            switches[4] = mImeBackDisposition;
-            switches[5] = mShowImeSwitcher ? 1 : 0;
+            switches[1] = state.mSystemUiVisibility;
+            switches[2] = state.mMenuVisible ? 1 : 0;
+            switches[3] = state.mImeWindowVis;
+            switches[4] = state.mImeBackDisposition;
+            switches[5] = state.mShowImeSwitcher ? 1 : 0;
             switches[6] = gatherDisableActionsLocked(mCurrentUserId, 2);
-            switches[7] = mFullscreenStackSysUiVisibility;
-            switches[8] = mDockedStackSysUiVisibility;
-            binders.add(mImeToken);
-            fullscreenStackBounds.set(mFullscreenStackBounds);
-            dockedStackBounds.set(mDockedStackBounds);
+            switches[7] = state.mFullscreenStackSysUiVisibility;
+            switches[8] = state.mDockedStackSysUiVisibility;
+            binders.add(state.mImeToken);
+            fullscreenStackBounds.set(state.mFullscreenStackBounds);
+            dockedStackBounds.set(state.mDockedStackBounds);
         }
     }
 
@@ -1309,8 +1384,13 @@
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
         synchronized (mLock) {
-            pw.println("  mDisabled1=0x" + Integer.toHexString(mDisabled1));
-            pw.println("  mDisabled2=0x" + Integer.toHexString(mDisabled2));
+            for (int i = 0; i < mDisplayUiState.size(); i++) {
+                final int key = mDisplayUiState.keyAt(i);
+                final UiState state = mDisplayUiState.get(key);
+                pw.println("  displayId=" + key);
+                pw.println("    mDisabled1=0x" + Integer.toHexString(state.getDisabled1()));
+                pw.println("    mDisabled2=0x" + Integer.toHexString(state.getDisabled2()));
+            }
             final int N = mDisableRecords.size();
             pw.println("  mDisableRecords.size=" + N);
             for (int i=0; i<N; i++) {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index cfec8ef..64ff9cf 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -2822,8 +2822,6 @@
         IoUtils.closeQuietly(stream);
 
         if (!success) {
-            wpdData.mWidth = -1;
-            wpdData.mHeight = -1;
             wallpaper.cropHint.set(0, 0, 0, 0);
             wpdData.mPadding.set(0, 0, 0, 0);
             wallpaper.name = "";
@@ -2839,6 +2837,7 @@
             }
         }
 
+        ensureSaneWallpaperDisplaySize(wpdData, DEFAULT_DISPLAY);
         ensureSaneWallpaperData(wallpaper, DEFAULT_DISPLAY);
         WallpaperData lockWallpaper = mLockWallpaperMap.get(userId);
         if (lockWallpaper != null) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 25399ef..255a003 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2543,7 +2543,7 @@
 
         // Bounds changed...update configuration to match.
         if (!matchParentBounds()) {
-            task.computeOverrideConfiguration(mTmpConfig, updatedBounds, null /* insetBounds */,
+            task.computeOverrideConfiguration(mTmpConfig, updatedBounds,
                     false /* overrideWidth */, false /* overrideHeight */);
         }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index d40a4fa..3ccede0 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -4944,9 +4944,12 @@
                 }
             }
 
-            mTmpBounds.put(task.taskId, task.getOverrideBounds());
-            if (tempTaskInsetBounds != null) {
-                mTmpInsetBounds.put(task.taskId, tempTaskInsetBounds);
+            if (task.hasDisplayedBounds()) {
+                mTmpBounds.put(task.taskId, task.getDisplayedBounds());
+                mTmpInsetBounds.put(task.taskId, task.getOverrideBounds());
+            } else {
+                mTmpBounds.put(task.taskId, task.getOverrideBounds());
+                mTmpInsetBounds.put(task.taskId, null);
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index fb93d39..c458c94 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -2178,9 +2178,9 @@
         final TaskStack stack = getStack();
         final Task task = getTask();
         if (task != null && task.inFreeformWindowingMode()) {
-            task.getRelativePosition(outPosition);
+            task.getRelativeDisplayedPosition(outPosition);
         } else if (stack != null) {
-            stack.getRelativePosition(outPosition);
+            stack.getRelativeDisplayedPosition(outPosition);
         }
 
         // Always use stack bounds in order to have the ability to animate outside the task region.
@@ -2193,6 +2193,18 @@
         outBounds.offsetTo(0, 0);
     }
 
+    @Override
+    Rect getDisplayedBounds() {
+        final Task task = getTask();
+        if (task != null) {
+            final Rect overrideDisplayedBounds = task.getOverrideDisplayedBounds();
+            if (!overrideDisplayedBounds.isEmpty()) {
+                return overrideDisplayedBounds;
+            }
+        }
+        return getBounds();
+    }
+
     boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
             boolean isVoiceInteraction) {
 
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index 64553a8..e779d1b 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -319,6 +319,13 @@
         onOverrideConfigurationChanged(mTmpConfig);
     }
 
+    /** Sets the windowing mode for the configuration container. */
+    void setDisplayWindowingMode(int windowingMode) {
+        mTmpConfig.setTo(getOverrideConfiguration());
+        mTmpConfig.windowConfiguration.setDisplayWindowingMode(windowingMode);
+        onOverrideConfigurationChanged(mTmpConfig);
+    }
+
     /**
      * Returns true if this container is currently in multi-window mode. I.e. sharing the screen
      * with another activity.
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 05e8267..aba2eb3 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1546,6 +1546,7 @@
         final int dh = displayInfo.logicalHeight;
         config.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
         config.windowConfiguration.setWindowingMode(getWindowingMode());
+        config.windowConfiguration.setDisplayWindowingMode(getWindowingMode());
         config.windowConfiguration.setRotation(displayInfo.rotation);
 
         final float density = mDisplayMetrics.density;
@@ -1953,6 +1954,17 @@
         mWmService.mWindowsChanged = true;
     }
 
+    @Override
+    public void setWindowingMode(int windowingMode) {
+        super.setWindowingMode(windowingMode);
+        super.setDisplayWindowingMode(windowingMode);
+    }
+
+    @Override
+    void setDisplayWindowingMode(int windowingMode) {
+        setWindowingMode(windowingMode);
+    }
+
     /**
      * In split-screen mode we process the IME containers above the docked divider
      * rather than directly above their target.
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index b6609e4..83ba384 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -504,10 +504,12 @@
     public void binderDied() {
         cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");
 
-        // Clear associated input consumers on runner death
-        final InputMonitor inputMonitor =
-                mService.mRoot.getDisplayContent(mDisplayId).getInputMonitor();
-        inputMonitor.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
+        synchronized (mService.getWindowManagerLock()) {
+            // Clear associated input consumers on runner death
+            final InputMonitor inputMonitor =
+                    mService.mRoot.getDisplayContent(mDisplayId).getInputMonitor();
+            inputMonitor.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
+        }
     }
 
     void checkAnimationReady(WallpaperController wallpaperController) {
@@ -603,8 +605,8 @@
             mTask = task;
             mIsRecentTaskInvisible = isRecentTaskInvisible;
             final WindowContainer container = mTask.getParent();
-            container.getRelativePosition(mPosition);
-            container.getBounds(mBounds);
+            container.getRelativeDisplayedPosition(mPosition);
+            mBounds.set(container.getDisplayedBounds());
         }
 
         RemoteAnimationTarget createRemoteAnimationApp() {
diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java
index 35264a2..8f18aa5 100644
--- a/services/core/java/com/android/server/wm/StackWindowController.java
+++ b/services/core/java/com/android/server/wm/StackWindowController.java
@@ -252,7 +252,7 @@
      * before mContainer has been updated, any relevant properties (like {@param windowingMode})
      * need to be passed in.
      */
-    public void adjustConfigurationForBounds(Rect bounds, Rect insetBounds,
+    public void adjustConfigurationForBounds(Rect bounds,
             Rect nonDecorBounds, Rect stableBounds, boolean overrideWidth,
             boolean overrideHeight, float density, Configuration config,
             Configuration parentConfig, int windowingMode) {
@@ -303,11 +303,9 @@
                 // Additionally task dimensions should not be bigger than its parents dimensions.
                 // The non decor inset are areas that could never be removed in Honeycomb. See
                 // {@link WindowManagerPolicy#getNonDecorInsetsLw}.
-                intersectDisplayBoundsExcludeInsets(nonDecorBounds,
-                        insetBounds != null ? insetBounds : bounds, mTmpNonDecorInsets,
+                intersectDisplayBoundsExcludeInsets(nonDecorBounds, bounds, mTmpNonDecorInsets,
                         mTmpDisplayBounds, overrideWidth, overrideHeight);
-                intersectDisplayBoundsExcludeInsets(stableBounds,
-                        insetBounds != null ? insetBounds : bounds, mTmpStableInsets,
+                intersectDisplayBoundsExcludeInsets(stableBounds, bounds, mTmpStableInsets,
                         mTmpDisplayBounds, overrideWidth, overrideHeight);
                 width = Math.min((int) (stableBounds.width() / density),
                         parentConfig.screenWidthDp);
@@ -323,7 +321,7 @@
             config.screenWidthDp = width;
             config.screenHeightDp = height;
             config.smallestScreenWidthDp = getSmallestWidthForTaskBounds(
-                    insetBounds != null ? insetBounds : bounds, density, windowingMode);
+                    bounds, density, windowingMode);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index d3db5df..c70f075 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -27,11 +27,11 @@
 import static com.android.server.wm.TaskProto.APP_WINDOW_TOKENS;
 import static com.android.server.wm.TaskProto.BOUNDS;
 import static com.android.server.wm.TaskProto.DEFER_REMOVAL;
+import static com.android.server.wm.TaskProto.DISPLAYED_BOUNDS;
 import static com.android.server.wm.TaskProto.FILLS_PARENT;
 import static com.android.server.wm.TaskProto.ID;
 import static com.android.server.wm.TaskProto.SURFACE_HEIGHT;
 import static com.android.server.wm.TaskProto.SURFACE_WIDTH;
-import static com.android.server.wm.TaskProto.TEMP_INSET_BOUNDS;
 import static com.android.server.wm.TaskProto.WINDOW_CONTAINER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -66,8 +66,8 @@
     final Rect mPreparedFrozenBounds = new Rect();
     final Configuration mPreparedFrozenMergedConfig = new Configuration();
 
-    // Bounds used to calculate the insets.
-    private final Rect mTempInsetBounds = new Rect();
+    // If non-empty, bounds used to display the task during animations/interactions.
+    private final Rect mOverrideDisplayedBounds = new Rect();
 
     /** ID of the display which rotation {@link #mRotation} has. */
     private int mLastRotationDisplayId = Display.INVALID_DISPLAY;
@@ -307,23 +307,23 @@
     }
 
     /**
-     * Sets the bounds used to calculate the insets. See
-     * {@link android.app.IActivityTaskManager#resizeDockedStack} why this is needed.
+     * Sets bounds that override where the task is displayed. Used during transient operations
+     * like animation / interaction.
      */
-    void setTempInsetBounds(Rect tempInsetBounds) {
-        if (tempInsetBounds != null) {
-            mTempInsetBounds.set(tempInsetBounds);
+    void setOverrideDisplayedBounds(Rect overrideDisplayedBounds) {
+        if (overrideDisplayedBounds != null) {
+            mOverrideDisplayedBounds.set(overrideDisplayedBounds);
         } else {
-            mTempInsetBounds.setEmpty();
+            mOverrideDisplayedBounds.setEmpty();
         }
     }
 
     /**
-     * Gets the bounds used to calculate the insets. See
+     * Gets the bounds that override where the task is displayed. See
      * {@link android.app.IActivityTaskManager#resizeDockedStack} why this is needed.
      */
-    void getTempInsetBounds(Rect out) {
-        out.set(mTempInsetBounds);
+    Rect getOverrideDisplayedBounds() {
+        return mOverrideDisplayedBounds;
     }
 
     void setResizeable(int resizeMode) {
@@ -380,8 +380,13 @@
         } else {
             mTmpRect2.offsetTo(adjustedBounds.left, adjustedBounds.top);
         }
-        setTempInsetBounds(tempInsetBounds);
-        setBounds(mTmpRect2, false /* forced */);
+        if (tempInsetBounds == null || tempInsetBounds.isEmpty()) {
+            setOverrideDisplayedBounds(null);
+            setBounds(mTmpRect2);
+        } else {
+            setOverrideDisplayedBounds(mTmpRect2);
+            setBounds(tempInsetBounds);
+        }
     }
 
     /** Return true if the current bound can get outputted to the rest of the system as-is. */
@@ -407,6 +412,15 @@
         mStack.getDisplayContent().getBounds(out);
     }
 
+    @Override
+    public Rect getDisplayedBounds() {
+        if (mOverrideDisplayedBounds.isEmpty()) {
+            return super.getDisplayedBounds();
+        } else {
+            return mOverrideDisplayedBounds;
+        }
+    }
+
     /**
      * Calculate the maximum visible area of this task. If the task has only one app,
      * the result will be visible frame of that app. If the task has more than one apps,
@@ -723,7 +737,7 @@
         }
         proto.write(FILLS_PARENT, matchParentBounds());
         getBounds().writeToProto(proto, BOUNDS);
-        mTempInsetBounds.writeToProto(proto, TEMP_INSET_BOUNDS);
+        mOverrideDisplayedBounds.writeToProto(proto, DISPLAYED_BOUNDS);
         proto.write(DEFER_REMOVAL, mDeferRemoval);
         proto.write(SURFACE_WIDTH, mSurfaceControl.getWidth());
         proto.write(SURFACE_HEIGHT, mSurfaceControl.getHeight());
@@ -739,7 +753,7 @@
         pw.println(doublePrefix + "mBounds=" + getBounds().toShortString());
         pw.println(doublePrefix + "mdr=" + mDeferRemoval);
         pw.println(doublePrefix + "appTokens=" + mChildren);
-        pw.println(doublePrefix + "mTempInsetBounds=" + mTempInsetBounds.toShortString());
+        pw.println(doublePrefix + "mDisplayedBounds=" + mOverrideDisplayedBounds.toShortString());
 
         final String triplePrefix = doublePrefix + "  ";
         final String quadruplePrefix = triplePrefix + "  ";
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 30751bc..3cf0bd7 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -310,6 +310,11 @@
     // This number will be assigned when we evaluate OOM scores for all visible tasks.
     int mLayerRank = -1;
 
+    // When non-empty, this represents the bounds this task will be drawn at. This gets set during
+    // transient operations such as split-divider dragging and animations.
+    // TODO(b/119687367): This member is temporary.
+    final Rect mDisplayedBounds = new Rect();
+
     /** Helper object used for updating override configuration. */
     private Configuration mTmpConfig = new Configuration();
 
@@ -447,6 +452,9 @@
         }
 
         mWindowContainerController = controller;
+        if (!mDisplayedBounds.isEmpty() && controller.mContainer != null) {
+            controller.mContainer.setOverrideDisplayedBounds(mDisplayedBounds);
+        }
     }
 
     void removeWindowContainer() {
@@ -1732,9 +1740,15 @@
         final Configuration newOverrideConfig = new Configuration();
         if (bounds != null) {
             newOverrideConfig.setTo(getOverrideConfiguration());
-            mTmpRect.set(bounds);
+            if (insetBounds != null && !insetBounds.isEmpty()) {
+                mTmpRect.set(insetBounds);
+                setDisplayedBounds(bounds);
+            } else {
+                mTmpRect.set(bounds);
+                setDisplayedBounds(null);
+            }
             adjustForMinimalTaskDimensions(mTmpRect);
-            computeOverrideConfiguration(newOverrideConfig, mTmpRect, insetBounds,
+            computeOverrideConfiguration(newOverrideConfig, mTmpRect,
                     mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
         }
 
@@ -1782,16 +1796,23 @@
                 setLastNonFullscreenBounds(currentBounds);
             }
             setBounds(null);
+            setDisplayedBounds(null);
             newConfig.unset();
         } else {
-            mTmpRect.set(bounds);
+            if (insetBounds != null && !insetBounds.isEmpty()) {
+                mTmpRect.set(insetBounds);
+                setDisplayedBounds(bounds);
+            } else {
+                mTmpRect.set(bounds);
+                setDisplayedBounds(null);
+            }
             adjustForMinimalTaskDimensions(mTmpRect);
             setBounds(mTmpRect);
 
             if (mStack == null || persistBounds) {
                 setLastNonFullscreenBounds(getOverrideBounds());
             }
-            computeOverrideConfiguration(newConfig, mTmpRect, insetBounds,
+            computeOverrideConfiguration(newConfig, mTmpRect,
                     mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
         }
         onOverrideConfigurationChanged(newConfig);
@@ -1847,11 +1868,44 @@
         mService.mStackSupervisor.mLaunchParamsPersister.saveTask(this);
     }
 
+    /**
+     * Displayed bounds are used to set where the task is drawn at any given time. This is
+     * separate from its actual bounds so that the app doesn't see any meaningful configuration
+     * changes during transitionary periods.
+     */
+    void setDisplayedBounds(Rect bounds) {
+        if (bounds == null) {
+            mDisplayedBounds.setEmpty();
+        } else {
+            mDisplayedBounds.set(bounds);
+        }
+        final TaskWindowContainerController controller = getWindowContainerController();
+        if (controller != null && controller.mContainer != null) {
+            controller.mContainer.setOverrideDisplayedBounds(
+                    mDisplayedBounds.isEmpty() ? null : mDisplayedBounds);
+        }
+    }
+
+    /**
+     * Gets the current overridden displayed bounds. These will be empty if the task is not
+     * currently overriding where it is displayed.
+     */
+    Rect getDisplayedBounds() {
+        return mDisplayedBounds;
+    }
+
+    /**
+     * @return {@code true} if this has overridden displayed bounds.
+     */
+    boolean hasDisplayedBounds() {
+        return !mDisplayedBounds.isEmpty();
+    }
+
     /** Clears passed config and fills it with new override values. */
     // TODO(b/36505427): TaskRecord.computeOverrideConfiguration() is a utility method that doesn't
     // depend on task or stacks, but uses those object to get the display to base the calculation
     // on. Probably best to centralize calculations like this in ConfigurationContainer.
-    void computeOverrideConfiguration(Configuration config, Rect bounds, Rect insetBounds,
+    void computeOverrideConfiguration(Configuration config, Rect bounds,
             boolean overrideWidth, boolean overrideHeight) {
         mTmpNonDecorBounds.set(bounds);
         mTmpStableBounds.set(bounds);
@@ -1863,7 +1917,7 @@
 
         if (mStack != null) {
             final StackWindowController stackController = mStack.getWindowContainerController();
-            stackController.adjustConfigurationForBounds(bounds, insetBounds,
+            stackController.adjustConfigurationForBounds(bounds,
                     mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density,
                     config, parentConfig, getWindowingMode());
         } else {
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index b1f95f8..b16e184c 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -184,9 +184,15 @@
         // Update bounds of containing tasks.
         for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
             final Task task = mChildren.get(taskNdx);
-            task.setBounds(taskBounds.get(task.mTaskId), false /* forced */);
-            task.setTempInsetBounds(taskTempInsetBounds != null ?
-                    taskTempInsetBounds.get(task.mTaskId) : null);
+            final Rect insetBounds =
+                    taskTempInsetBounds != null ? taskTempInsetBounds.get(task.mTaskId) : null;
+            if (insetBounds != null) {
+                task.setBounds(insetBounds);
+                task.setOverrideDisplayedBounds(taskBounds.get(task.mTaskId));
+            } else {
+                task.setBounds(taskBounds.get(task.mTaskId));
+                task.setOverrideDisplayedBounds(null);
+            }
         }
         return true;
     }
@@ -739,7 +745,7 @@
             return;
         }
 
-        final Rect stackBounds = getBounds();
+        final Rect stackBounds = getDisplayedBounds();
         int width = stackBounds.width();
         int height = stackBounds.height();
 
@@ -1754,14 +1760,6 @@
         scheduleAnimation();
     }
 
-    @Override
-    void getRelativePosition(Point outPos) {
-        super.getRelativePosition(outPos);
-        final int outset = getStackOutset();
-        outPos.x -= outset;
-        outPos.y -= outset;
-    }
-
     AnimatingAppWindowTokenRegistry getAnimatingAppWindowTokenRegistry() {
         return mAnimatingAppWindowTokenRegistry;
     }
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 1275ca0..c30cc17 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -1266,7 +1266,7 @@
             return;
         }
 
-        getRelativePosition(mTmpPos);
+        getRelativeDisplayedPosition(mTmpPos);
         if (mTmpPos.equals(mLastSurfacePosition)) {
             return;
         }
@@ -1275,12 +1275,22 @@
         mLastSurfacePosition.set(mTmpPos.x, mTmpPos.y);
     }
 
-    void getRelativePosition(Point outPos) {
-        final Rect bounds = getBounds();
-        outPos.set(bounds.left, bounds.top);
+    /**
+     * Displayed bounds specify where to display this container at. It differs from bounds during
+     * certain operations (like animation or interactive dragging).
+     *
+     * @return the bounds to display this container at.
+     */
+    Rect getDisplayedBounds() {
+        return getBounds();
+    }
+
+    void getRelativeDisplayedPosition(Point outPos) {
+        final Rect dispBounds = getDisplayedBounds();
+        outPos.set(dispBounds.left, dispBounds.top);
         final WindowContainer parent = getParent();
         if (parent != null) {
-            final Rect parentBounds = parent.getBounds();
+            final Rect parentBounds = parent.getDisplayedBounds();
             outPos.offset(-parentBounds.left, -parentBounds.top);
         }
     }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 8d5d433..31e0d83 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -790,6 +790,18 @@
     }
 
     @Override
+    public Rect getDisplayedBounds() {
+        final Task task = getTask();
+        if (task != null) {
+            Rect bounds = task.getOverrideDisplayedBounds();
+            if (!bounds.isEmpty()) {
+                return bounds;
+            }
+        }
+        return super.getDisplayedBounds();
+    }
+
+    @Override
     public void computeFrameLw() {
         if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) {
             // This window is being replaced and either already got information that it's being
@@ -805,16 +817,7 @@
         final boolean windowsAreFloating = task != null && task.isFloating();
         final DisplayContent dc = getDisplayContent();
 
-        // If the task has temp inset bounds set, we have to make sure all its windows uses
-        // the temp inset frame. Otherwise different display frames get applied to the main
-        // window and the child window, making them misaligned.
-        // Otherwise we need to clear the inset frame, to avoid using a stale frame after leaving
-        // multi window mode.
-        if (task != null && isInMultiWindowMode()) {
-            task.getTempInsetBounds(mInsetFrame);
-        } else {
-            mInsetFrame.setEmpty();
-        }
+        mInsetFrame.set(getBounds());
 
         // Denotes the actual frame used to calculate the insets and to perform the layout. When
         // resizing in docked mode, we'd like to freeze the layout, so we also need to freeze the
@@ -834,7 +837,7 @@
             layoutXDiff = 0;
             layoutYDiff = 0;
         } else {
-            getBounds(mWindowFrames.mContainingFrame);
+            mWindowFrames.mContainingFrame.set(getDisplayedBounds());
             if (mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) {
 
                 // If the bounds are frozen, we still want to translate the window freely and only
@@ -884,14 +887,9 @@
 
             layoutDisplayFrame = new Rect(mWindowFrames.mDisplayFrame);
             mWindowFrames.mDisplayFrame.set(mWindowFrames.mContainingFrame);
-            layoutXDiff =
-                    !mInsetFrame.isEmpty() ? mInsetFrame.left - mWindowFrames.mContainingFrame.left
-                            : 0;
-            layoutYDiff =
-                    !mInsetFrame.isEmpty() ? mInsetFrame.top - mWindowFrames.mContainingFrame.top
-                            : 0;
-            layoutContainingFrame =
-                    !mInsetFrame.isEmpty() ? mInsetFrame : mWindowFrames.mContainingFrame;
+            layoutXDiff = mInsetFrame.left - mWindowFrames.mContainingFrame.left;
+            layoutYDiff = mInsetFrame.top - mWindowFrames.mContainingFrame.top;
+            layoutContainingFrame = mInsetFrame;
             mTmpRect.set(0, 0, dc.getDisplayInfo().logicalWidth, dc.getDisplayInfo().logicalHeight);
             subtractInsets(mWindowFrames.mDisplayFrame, layoutContainingFrame, layoutDisplayFrame,
                     mTmpRect);
@@ -2176,9 +2174,6 @@
             getTouchableRegion(region);
         }
 
-        // The area containing the shadows is not touchable.
-        region.translate(mAttrs.surfaceInsets.left, mAttrs.surfaceInsets.top);
-
         return flags;
     }
 
@@ -4616,7 +4611,7 @@
             outPoint.offset(-parent.mWindowFrames.mFrame.left + parent.mAttrs.surfaceInsets.left,
                     -parent.mWindowFrames.mFrame.top + parent.mAttrs.surfaceInsets.top);
         } else if (parentWindowContainer != null) {
-            final Rect parentBounds = parentWindowContainer.getBounds();
+            final Rect parentBounds = parentWindowContainer.getDisplayedBounds();
             outPoint.offset(-parentBounds.left, -parentBounds.top);
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 8bc6db7..fb5c556 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1020,7 +1020,7 @@
                         mTmpPos.x = 0;
                         mTmpPos.y = 0;
                         if (stack != null) {
-                            stack.getRelativePosition(mTmpPos);
+                            stack.getRelativeDisplayedPosition(mTmpPos);
                         }
 
                         xOffset = -mTmpPos.x;
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 8b873e3..b85489a 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -2,8 +2,6 @@
     name: "libservices.core",
     defaults: ["libservices.core-libs"],
 
-    cpp_std: "c++17",
-
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index b9dabb9..65d3245 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -120,4 +120,9 @@
             int userHandle) {
         return false;
     }
+
+    @Override
+    public List<String> getCrossProfileCalendarPackagesForUser(int userHandle) {
+        return Collections.emptyList();
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 6fbb850..f68f4d7 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -13426,10 +13426,25 @@
         enforceCrossUsersPermission(userHandle);
         synchronized (getLockObject()) {
             final ActiveAdmin admin = getProfileOwnerAdminLocked(userHandle);
-            if (admin != null && admin.mCrossProfileCalendarPackages != null) {
+            if (admin != null) {
                 return admin.mCrossProfileCalendarPackages.contains(packageName);
             }
         }
         return false;
     }
+
+    @Override
+    public List<String> getCrossProfileCalendarPackagesForUser(int userHandle) {
+        if (!mHasFeature) {
+            return Collections.emptyList();
+        }
+        enforceCrossUsersPermission(userHandle);
+        synchronized (getLockObject()) {
+            final ActiveAdmin admin = getProfileOwnerAdminLocked(userHandle);
+            if (admin != null) {
+                return new ArrayList<String>(admin.mCrossProfileCalendarPackages);
+            }
+        }
+        return Collections.emptyList();
+    }
 }
diff --git a/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java
index 108f91c..14912c4 100644
--- a/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java
+++ b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java
@@ -146,7 +146,7 @@
     }
 
     @Override // from RemoteScreenObservationServiceCallbacks
-    public void onServiceDied(AbstractRemoteService service) {
+    public void onServiceDied(AbstractRemoteService<?> service) {
         // TODO(b/111276913): implement (remove session from PerUserSession?)
         if (mService.isDebug()) {
             Slog.d(TAG, "onServiceDied() for " + mId);
@@ -176,6 +176,10 @@
         pw.println(mAutofillCallback != null);
     }
 
+    String toShortString() {
+        return mId.getValue() + ":" + mActivityToken;
+    }
+
     @Override
     public String toString() {
         return "ContentCaptureSession[id=" + mId.getValue() + ", act=" + mActivityToken + "]";
diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java
index e0d47d2..b8f2ad0 100644
--- a/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java
+++ b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.intelligence;
 
+import static android.Manifest.permission.MANAGE_SMART_SUGGESTIONS;
 import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE;
 
 import android.annotation.NonNull;
@@ -26,8 +27,13 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.service.intelligence.InteractionSessionId;
+import android.util.Slog;
 import android.view.autofill.AutofillId;
 import android.view.autofill.IAutoFillManagerClient;
 import android.view.intelligence.ContentCaptureEvent;
@@ -42,6 +48,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -56,6 +63,10 @@
 
     private static final String TAG = "IntelligenceManagerService";
 
+    static final String RECEIVER_BUNDLE_EXTRA_SESSIONS = "sessions";
+
+    private static final int MAX_TEMP_SERVICE_DURATION_MS = 1_000 * 60 * 2; // 2 minutes
+
     @GuardedBy("mLock")
     private ActivityManagerInternal mAm;
 
@@ -66,12 +77,6 @@
     }
 
     @Override // from AbstractMasterSystemService
-    protected String getServiceSettingsProperty() {
-        // TODO(b/111276913): STOPSHIP temporary settings, until it's set by resourcs + cmd
-        return "smart_suggestions_service";
-    }
-
-    @Override // from AbstractMasterSystemService
     protected IntelligencePerUserService newServiceLocked(@UserIdInt int resolvedUserId,
             boolean disabled) {
         return new IntelligencePerUserService(this, mLock, resolvedUserId);
@@ -90,6 +95,66 @@
         service.destroyLocked();
     }
 
+    @Override // from AbstractMasterSystemService
+    protected void enforceCallingPermissionForManagement() {
+        getContext().enforceCallingPermission(MANAGE_SMART_SUGGESTIONS, TAG);
+    }
+
+    @Override // from AbstractMasterSystemService
+    protected int getMaximumTemporaryServiceDurationMs() {
+        return MAX_TEMP_SERVICE_DURATION_MS;
+    }
+
+    // Called by Shell command.
+    void destroySessions(@UserIdInt int userId, @NonNull IResultReceiver receiver) {
+        Slog.i(TAG, "destroySessions() for userId " + userId);
+        enforceCallingPermissionForManagement();
+
+        synchronized (mLock) {
+            if (userId != UserHandle.USER_ALL) {
+                final IntelligencePerUserService service = peekServiceForUserLocked(userId);
+                if (service != null) {
+                    service.destroySessionsLocked();
+                }
+            } else {
+                visitServicesLocked((s) -> s.destroySessionsLocked());
+            }
+        }
+
+        try {
+            receiver.send(0, new Bundle());
+        } catch (RemoteException e) {
+            // Just ignore it...
+        }
+    }
+
+    // Called by Shell command.
+    void listSessions(int userId, IResultReceiver receiver) {
+        Slog.i(TAG, "listSessions() for userId " + userId);
+        enforceCallingPermissionForManagement();
+
+        final Bundle resultData = new Bundle();
+        final ArrayList<String> sessions = new ArrayList<>();
+
+        synchronized (mLock) {
+            if (userId != UserHandle.USER_ALL) {
+                final IntelligencePerUserService service = peekServiceForUserLocked(userId);
+                if (service != null) {
+                    service.listSessionsLocked(sessions);
+                }
+            } else {
+                visitServicesLocked((s) -> s.listSessionsLocked(sessions));
+            }
+        }
+
+        resultData.putStringArrayList(RECEIVER_BUNDLE_EXTRA_SESSIONS, sessions);
+        try {
+            receiver.send(0, resultData);
+        } catch (RemoteException e) {
+            // Just ignore it...
+        }
+    }
+
     private ActivityManagerInternal getAmInternal() {
         synchronized (mLock) {
             if (mAm == null) {
@@ -119,7 +184,7 @@
             synchronized (mLock) {
                 final IntelligencePerUserService service = getServiceForUserLocked(userId);
                 service.startSessionLocked(activityToken, componentName, taskId, displayId,
-                        sessionId, flags, result);
+                        sessionId, flags, mAllowInstantService, result);
             }
         }
 
@@ -154,6 +219,14 @@
                 dumpLocked("", pw);
             }
         }
+
+        @Override
+        public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+                String[] args, ShellCallback callback, ResultReceiver resultReceiver)
+                throws RemoteException {
+            new IntelligenceServiceShellCommand(IntelligenceManagerService.this).exec(
+                    this, in, out, err, args, callback, resultReceiver);
+        }
     }
 
     private final class LocalService extends IntelligenceManagerInternal {
diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java
index e3b09c6..6f047c5 100644
--- a/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java
+++ b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java
@@ -36,6 +36,7 @@
 import android.os.RemoteException;
 import android.service.intelligence.InteractionSessionId;
 import android.service.intelligence.SnapshotData;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Slog;
 import android.view.autofill.AutofillId;
@@ -49,6 +50,7 @@
 import com.android.server.intelligence.IntelligenceManagerInternal.AugmentedAutofillCallback;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -76,17 +78,24 @@
     protected ServiceInfo newServiceInfo(@NonNull ComponentName serviceComponent)
             throws NameNotFoundException {
 
+        int flags = PackageManager.GET_META_DATA;
+        final boolean isTemp = isTemporaryServiceSetLocked();
+        if (!isTemp) {
+            flags |= PackageManager.MATCH_SYSTEM_ONLY;
+        }
+
         ServiceInfo si;
         try {
-            // TODO(b/111276913): must check that either the service is from a system component,
-            // or it matches a service set by shell cmd (so it can be used on CTS tests and when
-            // OEMs are implementing the real service
-            si = AppGlobals.getPackageManager().getServiceInfo(serviceComponent,
-                    PackageManager.GET_META_DATA, mUserId);
+            si = AppGlobals.getPackageManager().getServiceInfo(serviceComponent, flags, mUserId);
         } catch (RemoteException e) {
             Slog.w(TAG, "Could not get service for " + serviceComponent + ": " + e);
             return null;
         }
+        if (si == null) {
+            Slog.w(TAG, "Could not get serviceInfo for " + (isTemp ? " (temp)" : "(default system)")
+                    + " " + serviceComponent.flattenToShortString());
+            return null;
+        }
         if (!Manifest.permission.BIND_SMART_SUGGESTIONS_SERVICE.equals(si.permission)) {
             Slog.w(TAG, "SmartSuggestionsService from '" + si.packageName
                     + "' does not require permission "
@@ -104,11 +113,18 @@
         return super.updateLocked(disabled);
     }
 
+    @Override // from PerUserSystemService
+    protected String getDefaultComponentName() {
+        final String name = getContext()
+                .getString(com.android.internal.R.string.config_defaultSmartSuggestionsService);
+        return TextUtils.isEmpty(name) ? null : name;
+    }
+
     // TODO(b/111276913): log metrics
     @GuardedBy("mLock")
     public void startSessionLocked(@NonNull IBinder activityToken,
             @NonNull ComponentName componentName, int taskId, int displayId,
-            @NonNull InteractionSessionId sessionId, int flags,
+            @NonNull InteractionSessionId sessionId, int flags, boolean bindInstantServiceAllowed,
             @NonNull IResultReceiver resultReceiver) {
         if (!isEnabledLocked()) {
             sendToClient(resultReceiver, ContentCaptureManager.STATE_DISABLED);
@@ -138,9 +154,6 @@
             return;
         }
 
-        // TODO(b/117779333): get from mMaster once it's moved to superclass
-        final boolean bindInstantServiceAllowed = false;
-
         session = new ContentCaptureSession(getContext(), mUserId, mLock, activityToken,
                 this, serviceComponentName, componentName, taskId, displayId, sessionId, flags,
                 bindInstantServiceAllowed, mMaster.verbose);
@@ -253,6 +266,11 @@
     @GuardedBy("mLock")
     public void destroyLocked() {
         if (mMaster.debug) Slog.d(TAG, "destroyLocked()");
+        destroySessionsLocked();
+    }
+
+    @GuardedBy("mLock")
+    void destroySessionsLocked() {
         final int numSessions = mSessions.size();
         for (int i = 0; i < numSessions; i++) {
             final ContentCaptureSession session = mSessions.valueAt(i);
@@ -261,6 +279,15 @@
         mSessions.clear();
     }
 
+    @GuardedBy("mLock")
+    void listSessionsLocked(ArrayList<String> output) {
+        final int numSessions = mSessions.size();
+        for (int i = 0; i < numSessions; i++) {
+            final ContentCaptureSession session = mSessions.valueAt(i);
+            output.add(session.toShortString());
+        }
+    }
+
     public AugmentedAutofillCallback requestAutofill(@NonNull IAutoFillManagerClient client,
             @NonNull IBinder activityToken, int autofillSessionId, @NonNull AutofillId focusedId) {
         synchronized (mLock) {
diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligenceServiceShellCommand.java b/services/intelligence/java/com/android/server/intelligence/IntelligenceServiceShellCommand.java
new file mode 100644
index 0000000..0d92a97
--- /dev/null
+++ b/services/intelligence/java/com/android/server/intelligence/IntelligenceServiceShellCommand.java
@@ -0,0 +1,229 @@
+/*
+ * 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.intelligence;
+
+import static com.android.server.intelligence.IntelligenceManagerService.RECEIVER_BUNDLE_EXTRA_SESSIONS;
+
+import android.annotation.NonNull;
+import android.os.Bundle;
+import android.os.ShellCommand;
+import android.os.UserHandle;
+
+import com.android.internal.os.IResultReceiver;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Shell Command implementation for {@link IntelligenceManagerService}.
+ */
+//TODO(b/111276913): rename once the final name is defined
+public final class IntelligenceServiceShellCommand extends ShellCommand {
+
+    private final IntelligenceManagerService mService;
+
+    public IntelligenceServiceShellCommand(@NonNull IntelligenceManagerService service) {
+        mService = service;
+    }
+
+    @Override
+    public int onCommand(String cmd) {
+        if (cmd == null) {
+            return handleDefaultCommands(cmd);
+        }
+        final PrintWriter pw = getOutPrintWriter();
+        switch (cmd) {
+            case "list":
+                return requestList(pw);
+            case "destroy":
+                return requestDestroy(pw);
+            case "get":
+                return requestGet(pw);
+            case "set":
+                return requestSet(pw);
+            default:
+                return handleDefaultCommands(cmd);
+        }
+    }
+
+    @Override
+    public void onHelp() {
+        try (PrintWriter pw = getOutPrintWriter();) {
+            // TODO(b/111276913): rename "intelligence" once SELinux rule changed
+            pw.println("Intelligence Service (intelligence) commands:");
+            pw.println("  help");
+            pw.println("    Prints this help text.");
+            pw.println("");
+            pw.println("  get bind-instant-service-allowed");
+            pw.println("    Gets whether binding to services provided by instant apps is allowed");
+            pw.println("");
+            pw.println("  set bind-instant-service-allowed [true | false]");
+            pw.println("    Sets whether binding to services provided by instant apps is allowed");
+            pw.println("");
+            pw.println("  set temporary-service USER_ID [COMPONENT_NAME DURATION]");
+            pw.println("    Temporarily (for DURATION ms) changes the service implemtation.");
+            pw.println("    To reset, call with just the USER_ID argument.");
+            pw.println("");
+            pw.println("  list sessions [--user USER_ID]");
+            pw.println("    Lists all pending sessions.");
+            pw.println("");
+            pw.println("  destroy sessions [--user USER_ID]");
+            pw.println("    Destroys all pending sessions.");
+            pw.println("");
+        }
+    }
+
+    private int requestGet(PrintWriter pw) {
+        final String what = getNextArgRequired();
+        switch(what) {
+            case "bind-instant-service-allowed":
+                return getBindInstantService(pw);
+            default:
+                pw.println("Invalid set: " + what);
+                return -1;
+        }
+    }
+
+    private int requestSet(PrintWriter pw) {
+        final String what = getNextArgRequired();
+
+        switch(what) {
+            case "bind-instant-service-allowed":
+                return setBindInstantService(pw);
+            case "temporary-service":
+                return setTemporaryService();
+            default:
+                pw.println("Invalid set: " + what);
+                return -1;
+        }
+    }
+
+    private int getBindInstantService(PrintWriter pw) {
+        if (mService.getAllowInstantService()) {
+            pw.println("true");
+        } else {
+            pw.println("false");
+        }
+        return 0;
+    }
+
+    private int setBindInstantService(PrintWriter pw) {
+        final String mode = getNextArgRequired();
+        switch (mode.toLowerCase()) {
+            case "true":
+                mService.setAllowInstantService(true);
+                return 0;
+            case "false":
+                mService.setAllowInstantService(false);
+                return 0;
+            default:
+                pw.println("Invalid mode: " + mode);
+                return -1;
+        }
+    }
+
+    private int setTemporaryService() {
+        final int userId = getNextIntArgRequired();
+        final String serviceName = getNextArg();
+        if (serviceName == null) {
+            mService.resetTemporaryService(userId);
+            return 0;
+        }
+        final int duration = getNextIntArgRequired();
+        mService.setTemporaryService(userId, serviceName, duration);
+        return 0;
+    }
+
+    private int requestDestroy(PrintWriter pw) {
+        if (!isNextArgSessions(pw)) {
+            return -1;
+        }
+
+        final int userId = getUserIdFromArgsOrAllUsers();
+        final CountDownLatch latch = new CountDownLatch(1);
+        final IResultReceiver receiver = new IResultReceiver.Stub() {
+            @Override
+            public void send(int resultCode, Bundle resultData) {
+                latch.countDown();
+            }
+        };
+        return requestSessionCommon(pw, latch, () -> mService.destroySessions(userId, receiver));
+    }
+
+    private int requestList(PrintWriter pw) {
+        if (!isNextArgSessions(pw)) {
+            return -1;
+        }
+
+        final int userId = getUserIdFromArgsOrAllUsers();
+        final CountDownLatch latch = new CountDownLatch(1);
+        final IResultReceiver receiver = new IResultReceiver.Stub() {
+            @Override
+            public void send(int resultCode, Bundle resultData) {
+                final ArrayList<String> sessions = resultData
+                        .getStringArrayList(RECEIVER_BUNDLE_EXTRA_SESSIONS);
+                for (String session : sessions) {
+                    pw.println(session);
+                }
+                latch.countDown();
+            }
+        };
+        return requestSessionCommon(pw, latch, () -> mService.listSessions(userId, receiver));
+    }
+
+    private boolean isNextArgSessions(PrintWriter pw) {
+        final String type = getNextArgRequired();
+        if (!type.equals("sessions")) {
+            pw.println("Error: invalid list type");
+            return false;
+        }
+        return true;
+    }
+
+    private int requestSessionCommon(PrintWriter pw, CountDownLatch latch,
+            Runnable command) {
+        command.run();
+        return waitForLatch(pw, latch);
+    }
+
+    private int waitForLatch(PrintWriter pw, CountDownLatch latch) {
+        try {
+            final boolean received = latch.await(5, TimeUnit.SECONDS);
+            if (!received) {
+                pw.println("Timed out after 5 seconds");
+                return -1;
+            }
+        } catch (InterruptedException e) {
+            pw.println("System call interrupted");
+            Thread.currentThread().interrupt();
+            return -1;
+        }
+        return 0;
+    }
+
+    private int getUserIdFromArgsOrAllUsers() {
+        if ("--user".equals(getNextArg())) {
+            return UserHandle.parseUserArg(getNextArgRequired());
+        }
+        return UserHandle.USER_ALL;
+    }
+
+    private int getNextIntArgRequired() {
+        return Integer.parseInt(getNextArgRequired());
+    }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 63751fd..c4d2a91 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -22,6 +22,7 @@
 import static android.os.IServiceManager.DUMP_FLAG_PROTO;
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import android.annotation.NonNull;
 import android.app.ActivityThread;
 import android.app.INotificationManager;
 import android.app.usage.UsageStatsManagerInternal;
@@ -55,6 +56,9 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.storage.IStorageManager;
+import android.provider.Settings;
+import android.sysprop.VoldProperties;
+import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Slog;
@@ -120,6 +124,7 @@
 import com.android.server.role.RoleManagerService;
 import com.android.server.security.KeyAttestationApplicationIdProviderService;
 import com.android.server.security.KeyChainSystemService;
+import com.android.server.signedconfig.SignedConfigService;
 import com.android.server.soundtrigger.SoundTriggerService;
 import com.android.server.stats.StatsCompanionService;
 import com.android.server.statusbar.StatusBarManagerService;
@@ -654,7 +659,7 @@
         traceEnd();
 
         // Only run "core" apps if we're encrypting the device.
-        String cryptState = SystemProperties.get("vold.decrypt");
+        String cryptState = VoldProperties.decrypt().orElse("");
         if (ENCRYPTING_STATE.equals(cryptState)) {
             Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
             mOnlyCore = true;
@@ -796,10 +801,6 @@
         boolean disableSystemTextClassifier = SystemProperties.getBoolean(
                 "config.disable_systemtextclassifier", false);
 
-        //TODO(b/111276913): temporarily disabled until the manager is properly implemented to
-        // ignore events when disabled and buffer when enabled
-        boolean disableIntelligence = SystemProperties.getBoolean(
-                "config.disable_intelligence", true);
         boolean disableNetworkTime = SystemProperties.getBoolean("config.disable_networktime",
                 false);
         boolean disableCameraService = SystemProperties.getBoolean("config.disable_cameraservice",
@@ -994,6 +995,11 @@
             traceBeginAndSlog("PinnerService");
             mSystemServiceManager.startService(PinnerService.class);
             traceEnd();
+
+            traceBeginAndSlog("SignedConfigService");
+            SignedConfigService.registerUpdateReceiver(mSystemContext);
+            traceEnd();
+
         } catch (RuntimeException e) {
             Slog.e("System", "******************************************");
             Slog.e("System", "************ Failure starting core service", e);
@@ -1130,13 +1136,7 @@
                 traceEnd();
             }
 
-            if (!disableIntelligence) {
-                traceBeginAndSlog("StartIntelligenceService");
-                mSystemServiceManager.startService(INTELLIGENCE_MANAGER_SERVICE_CLASS);
-                traceEnd();
-            } else {
-                Slog.d(TAG, "IntelligenceService disabled");
-            }
+            startIntelligenceService(context);
 
             // NOTE: ClipboardService indirectly depends on IntelligenceService
             traceBeginAndSlog("StartClipboardService");
@@ -2100,6 +2100,37 @@
         }, BOOT_TIMINGS_TRACE_LOG);
     }
 
+    private void startIntelligenceService(@NonNull Context context) {
+
+        // First check if it was explicitly enabled by Settings
+        boolean explicitlySupported = false;
+        final String settings = Settings.Global.getString(context.getContentResolver(),
+                Settings.Global.SMART_SUGGESTIONS_SERVICE_EXPLICITLY_ENABLED);
+        if (settings != null) {
+            explicitlySupported = Boolean.parseBoolean(settings);
+            if (explicitlySupported) {
+                Slog.d(TAG, "IntelligenceService explicitly enabled by Settings");
+            } else {
+                Slog.d(TAG, "IntelligenceService explicitly disabled by Settings");
+                return;
+            }
+        }
+
+        // Then check if OEM overlaid the resource that defines the service.
+        if (!explicitlySupported) {
+            final String serviceName = context
+                    .getString(com.android.internal.R.string.config_defaultSmartSuggestionsService);
+            if (TextUtils.isEmpty(serviceName)) {
+                Slog.d(TAG, "IntelligenceService disabled because config resource is not overlaid");
+                return;
+            }
+        }
+
+        traceBeginAndSlog("StartIntelligenceService");
+        mSystemServiceManager.startService(INTELLIGENCE_MANAGER_SERVICE_CLASS);
+        traceEnd();
+    }
+
     static final void startSystemUi(Context context, WindowManagerService windowManager) {
         Intent intent = new Intent();
         intent.setComponent(new ComponentName("com.android.systemui",
diff --git a/services/robotests/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java b/services/robotests/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java
new file mode 100644
index 0000000..5342efa
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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.backup.encryption.keys;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+import android.security.keystore.recovery.InternalRecoveryServiceException;
+import android.security.keystore.recovery.RecoveryController;
+
+import com.android.server.testing.shadows.ShadowInternalRecoveryServiceException;
+import com.android.server.testing.shadows.ShadowRecoveryController;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.security.SecureRandom;
+import java.util.Optional;
+
+/** Tests for {@link RecoverableKeyStoreSecondaryKeyManager}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+@Config(shadows = {ShadowRecoveryController.class, ShadowInternalRecoveryServiceException.class})
+public class RecoverableKeyStoreSecondaryKeyManagerTest {
+    private static final String BACKUP_KEY_ALIAS_PREFIX =
+            "com.android.server.backup/recoverablekeystore/";
+    private static final int BITS_PER_BYTE = 8;
+    private static final int BACKUP_KEY_SUFFIX_LENGTH_BYTES = 128 / BITS_PER_BYTE;
+    private static final int HEX_PER_BYTE = 2;
+    private static final int BACKUP_KEY_ALIAS_LENGTH =
+            BACKUP_KEY_ALIAS_PREFIX.length() + BACKUP_KEY_SUFFIX_LENGTH_BYTES * HEX_PER_BYTE;
+    private static final String NONEXISTENT_KEY_ALIAS = "NONEXISTENT_KEY_ALIAS";
+
+    private RecoverableKeyStoreSecondaryKeyManager mRecoverableKeyStoreSecondaryKeyManager;
+    private Context mContext;
+
+    /** Create a new {@link RecoverableKeyStoreSecondaryKeyManager} to use in tests. */
+    @Before
+    public void setUp() throws Exception {
+        mContext = RuntimeEnvironment.application;
+
+        mRecoverableKeyStoreSecondaryKeyManager =
+                new RecoverableKeyStoreSecondaryKeyManager(
+                        RecoveryController.getInstance(mContext), new SecureRandom());
+    }
+
+    /** Reset the {@link ShadowRecoveryController}. */
+    @After
+    public void tearDown() throws Exception {
+        ShadowRecoveryController.reset();
+    }
+
+    /** The generated key should always have the prefix {@code BACKUP_KEY_ALIAS_PREFIX}. */
+    @Test
+    public void generate_generatesKeyWithExpectedPrefix() throws Exception {
+        RecoverableKeyStoreSecondaryKey key = mRecoverableKeyStoreSecondaryKeyManager.generate();
+
+        assertThat(key.getAlias()).startsWith(BACKUP_KEY_ALIAS_PREFIX);
+    }
+
+    /** The generated key should always have length {@code BACKUP_KEY_ALIAS_LENGTH}. */
+    @Test
+    public void generate_generatesKeyWithExpectedLength() throws Exception {
+        RecoverableKeyStoreSecondaryKey key = mRecoverableKeyStoreSecondaryKeyManager.generate();
+
+        assertThat(key.getAlias()).hasLength(BACKUP_KEY_ALIAS_LENGTH);
+    }
+
+    /** Ensure that hidden API exceptions are rethrown when generating keys. */
+    @Test
+    public void generate_encounteringHiddenApiException_rethrowsException() {
+        ShadowRecoveryController.setThrowsInternalError(true);
+
+        assertThrows(
+                InternalRecoveryServiceException.class,
+                mRecoverableKeyStoreSecondaryKeyManager::generate);
+    }
+
+    /** Ensure that retrieved keys correspond to those generated earlier. */
+    @Test
+    public void get_getsKeyGeneratedByController() throws Exception {
+        RecoverableKeyStoreSecondaryKey key = mRecoverableKeyStoreSecondaryKeyManager.generate();
+
+        Optional<RecoverableKeyStoreSecondaryKey> retrievedKey =
+                mRecoverableKeyStoreSecondaryKeyManager.get(key.getAlias());
+
+        assertThat(retrievedKey.isPresent()).isTrue();
+        assertThat(retrievedKey.get().getAlias()).isEqualTo(key.getAlias());
+        assertThat(retrievedKey.get().getSecretKey()).isEqualTo(key.getSecretKey());
+    }
+
+    /**
+     * Ensure that a call to {@link RecoverableKeyStoreSecondaryKeyManager#get(java.lang.String)}
+     * for nonexistent aliases returns an emtpy {@link Optional}.
+     */
+    @Test
+    public void get_forNonExistentKey_returnsEmptyOptional() throws Exception {
+        Optional<RecoverableKeyStoreSecondaryKey> retrievedKey =
+                mRecoverableKeyStoreSecondaryKeyManager.get(NONEXISTENT_KEY_ALIAS);
+
+        assertThat(retrievedKey.isPresent()).isFalse();
+    }
+
+    /**
+     * Ensure that exceptions occurring during {@link
+     * RecoverableKeyStoreSecondaryKeyManager#get(java.lang.String)} are not rethrown.
+     */
+    @Test
+    public void get_encounteringInternalException_doesNotPropagateException() throws Exception {
+        ShadowRecoveryController.setThrowsInternalError(true);
+
+        // Should not throw exception
+        mRecoverableKeyStoreSecondaryKeyManager.get(NONEXISTENT_KEY_ALIAS);
+    }
+
+    /** Ensure that keys are correctly removed from the store. */
+    @Test
+    public void remove_removesKeyFromRecoverableStore() throws Exception {
+        RecoverableKeyStoreSecondaryKey key = mRecoverableKeyStoreSecondaryKeyManager.generate();
+
+        mRecoverableKeyStoreSecondaryKeyManager.remove(key.getAlias());
+
+        assertThat(RecoveryController.getInstance(mContext).getAliases())
+                .doesNotContain(key.getAlias());
+    }
+}
diff --git a/services/robotests/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java b/services/robotests/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java
new file mode 100644
index 0000000..89977f8
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java
@@ -0,0 +1,163 @@
+/*
+ * 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.backup.encryption.keys;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+import android.security.keystore.recovery.RecoveryController;
+
+import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey.Status;
+import com.android.server.backup.testing.CryptoTestUtils;
+import com.android.server.testing.shadows.ShadowInternalRecoveryServiceException;
+import com.android.server.testing.shadows.ShadowRecoveryController;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import javax.crypto.SecretKey;
+
+/** Tests for {@link RecoverableKeyStoreSecondaryKey}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+@Config(shadows = {ShadowRecoveryController.class, ShadowInternalRecoveryServiceException.class})
+public class RecoverableKeyStoreSecondaryKeyTest {
+    private static final String TEST_ALIAS = "test";
+    private static final int NONEXISTENT_STATUS_CODE = 42;
+
+    private RecoverableKeyStoreSecondaryKey mSecondaryKey;
+    private SecretKey mGeneratedSecretKey;
+    private Context mContext;
+
+    /** Instantiate a {@link RecoverableKeyStoreSecondaryKey} to use in tests. */
+    @Before
+    public void setUp() throws Exception {
+        mContext = RuntimeEnvironment.application;
+        mGeneratedSecretKey = CryptoTestUtils.generateAesKey();
+        mSecondaryKey = new RecoverableKeyStoreSecondaryKey(TEST_ALIAS, mGeneratedSecretKey);
+    }
+
+    /** Reset the {@link ShadowRecoveryController}. */
+    @After
+    public void tearDown() throws Exception {
+        ShadowRecoveryController.reset();
+    }
+
+    /**
+     * Checks that {@link RecoverableKeyStoreSecondaryKey#getAlias()} returns the value supplied in
+     * the constructor.
+     */
+    @Test
+    public void getAlias() {
+        String alias = mSecondaryKey.getAlias();
+
+        assertThat(alias).isEqualTo(TEST_ALIAS);
+    }
+
+    /**
+     * Checks that {@link RecoverableKeyStoreSecondaryKey#getSecretKey()} returns the value supplied
+     * in the constructor.
+     */
+    @Test
+    public void getSecretKey() {
+        SecretKey secretKey = mSecondaryKey.getSecretKey();
+
+        assertThat(secretKey).isEqualTo(mGeneratedSecretKey);
+    }
+
+    /**
+     * Checks that passing a secret key that is null to the constructor throws an exception.
+     */
+    @Test
+    public void constructor_withNullSecretKey_throwsNullPointerException() {
+        assertThrows(
+                NullPointerException.class,
+                () -> new RecoverableKeyStoreSecondaryKey(TEST_ALIAS, null));
+    }
+
+    /**
+     * Checks that passing an alias that is null to the constructor throws an exception.
+     */
+    @Test
+    public void constructor_withNullAlias_throwsNullPointerException() {
+        assertThrows(
+                NullPointerException.class,
+                () -> new RecoverableKeyStoreSecondaryKey(null, mGeneratedSecretKey));
+    }
+
+    /** Checks that the synced status is returned correctly. */
+    @Test
+    public void getStatus_whenSynced_returnsSynced() throws Exception {
+        setStatus(RecoveryController.RECOVERY_STATUS_SYNCED);
+
+        int status = mSecondaryKey.getStatus(mContext);
+
+        assertThat(status).isEqualTo(Status.SYNCED);
+    }
+
+    /** Checks that the in progress sync status is returned correctly. */
+    @Test
+    public void getStatus_whenNotSynced_returnsNotSynced() throws Exception {
+        setStatus(RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS);
+
+        int status = mSecondaryKey.getStatus(mContext);
+
+        assertThat(status).isEqualTo(Status.NOT_SYNCED);
+    }
+
+    /** Checks that the failure status is returned correctly. */
+    @Test
+    public void getStatus_onPermanentFailure_returnsDestroyed() throws Exception {
+        setStatus(RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE);
+
+        int status = mSecondaryKey.getStatus(mContext);
+
+        assertThat(status).isEqualTo(Status.DESTROYED);
+    }
+
+    /** Checks that an unknown status results in {@code NOT_SYNCED} being returned. */
+    @Test
+    public void getStatus_forUnknownStatusCode_returnsNotSynced() throws Exception {
+        setStatus(NONEXISTENT_STATUS_CODE);
+
+        int status = mSecondaryKey.getStatus(mContext);
+
+        assertThat(status).isEqualTo(Status.NOT_SYNCED);
+    }
+
+    /** Checks that an internal error results in {@code NOT_SYNCED} being returned. */
+    @Test
+    public void getStatus_onInternalError_returnsNotSynced() throws Exception {
+        ShadowRecoveryController.setThrowsInternalError(true);
+
+        int status = mSecondaryKey.getStatus(mContext);
+
+        assertThat(status).isEqualTo(Status.NOT_SYNCED);
+    }
+
+    private void setStatus(int status) throws Exception {
+        ShadowRecoveryController.setRecoveryStatus(TEST_ALIAS, status);
+    }
+}
diff --git a/services/robotests/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java b/services/robotests/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java
new file mode 100644
index 0000000..48216f8
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.encryption.keys;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import java.security.SecureRandom;
+
+import javax.crypto.SecretKey;
+
+/** Tests for {@link TertiaryKeyGenerator}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+public class TertiaryKeyGeneratorTest {
+    private static final String KEY_ALGORITHM = "AES";
+    private static final int KEY_SIZE_BITS = 256;
+
+    private TertiaryKeyGenerator mTertiaryKeyGenerator;
+
+    /** Instantiate a new {@link TertiaryKeyGenerator} for use in tests. */
+    @Before
+    public void setUp() {
+        mTertiaryKeyGenerator = new TertiaryKeyGenerator(new SecureRandom());
+    }
+
+    /** Generated keys should be AES keys. */
+    @Test
+    public void generate_generatesAESKeys() {
+        SecretKey secretKey = mTertiaryKeyGenerator.generate();
+
+        assertThat(secretKey.getAlgorithm()).isEqualTo(KEY_ALGORITHM);
+    }
+
+    /** Generated keys should be 256 bits in size. */
+    @Test
+    public void generate_generates256BitKeys() {
+        SecretKey secretKey = mTertiaryKeyGenerator.generate();
+
+        assertThat(secretKey.getEncoded()).hasLength(KEY_SIZE_BITS / 8);
+    }
+
+    /**
+     * Subsequent calls to {@link TertiaryKeyGenerator#generate()} should generate different keys.
+     */
+    @Test
+    public void generate_generatesNewKeys() {
+        SecretKey key1 = mTertiaryKeyGenerator.generate();
+        SecretKey key2 = mTertiaryKeyGenerator.generate();
+
+        assertThat(key1).isNotEqualTo(key2);
+    }
+}
diff --git a/services/robotests/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java b/services/robotests/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java
new file mode 100644
index 0000000..49bb410
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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.backup.encryption.keys;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+/** Tests for {@link TertiaryKeyRotationTracker}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+public class TertiaryKeyRotationTrackerTest {
+    private static final String PACKAGE_1 = "com.package.one";
+    private static final int NUMBER_OF_BACKUPS_BEFORE_ROTATION = 31;
+
+    private TertiaryKeyRotationTracker mTertiaryKeyRotationTracker;
+
+    /** Instantiate a {@link TertiaryKeyRotationTracker} for use in tests. */
+    @Before
+    public void setUp() {
+        mTertiaryKeyRotationTracker = newInstance();
+    }
+
+    /** New packages should not be due for key rotation. */
+    @Test
+    public void isKeyRotationDue_forNewPackage_isFalse() {
+        // Simulate a new package by not calling simulateBackups(). As a result, PACKAGE_1 hasn't
+        // been seen by mTertiaryKeyRotationTracker before.
+        boolean keyRotationDue = mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1);
+
+        assertThat(keyRotationDue).isFalse();
+    }
+
+    /**
+     * Key rotation should not be due after less than {@code NUMBER_OF_BACKUPS_BEFORE_ROTATION}
+     * backups.
+     */
+    @Test
+    public void isKeyRotationDue_afterLessThanRotationAmountBackups_isFalse() {
+        simulateBackups(PACKAGE_1, NUMBER_OF_BACKUPS_BEFORE_ROTATION - 1);
+
+        boolean keyRotationDue = mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1);
+
+        assertThat(keyRotationDue).isFalse();
+    }
+
+    /** Key rotation should be due after {@code NUMBER_OF_BACKUPS_BEFORE_ROTATION} backups. */
+    @Test
+    public void isKeyRotationDue_afterRotationAmountBackups_isTrue() {
+        simulateBackups(PACKAGE_1, NUMBER_OF_BACKUPS_BEFORE_ROTATION);
+
+        boolean keyRotationDue = mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1);
+
+        assertThat(keyRotationDue).isTrue();
+    }
+
+    /**
+     * A call to {@link TertiaryKeyRotationTracker#resetCountdown(String)} should make sure no key
+     * rotation is due.
+     */
+    @Test
+    public void resetCountdown_makesKeyRotationNotDue() {
+        simulateBackups(PACKAGE_1, NUMBER_OF_BACKUPS_BEFORE_ROTATION);
+
+        mTertiaryKeyRotationTracker.resetCountdown(PACKAGE_1);
+
+        assertThat(mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1)).isFalse();
+    }
+
+    /**
+     * New instances of {@link TertiaryKeyRotationTracker} should read state about the number of
+     * backups from disk.
+     */
+    @Test
+    public void isKeyRotationDue_forNewInstance_readsStateFromDisk() {
+        simulateBackups(PACKAGE_1, NUMBER_OF_BACKUPS_BEFORE_ROTATION);
+
+        boolean keyRotationDueForNewInstance = newInstance().isKeyRotationDue(PACKAGE_1);
+
+        assertThat(keyRotationDueForNewInstance).isTrue();
+    }
+
+    /**
+     * A call to {@link TertiaryKeyRotationTracker#markAllForRotation()} should mark all previously
+     * seen packages for rotation.
+     */
+    @Test
+    public void markAllForRotation_marksSeenPackagesForKeyRotation() {
+        simulateBackups(PACKAGE_1, /*numberOfBackups=*/ 1);
+
+        mTertiaryKeyRotationTracker.markAllForRotation();
+
+        assertThat(mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1)).isTrue();
+    }
+
+    /**
+     * A call to {@link TertiaryKeyRotationTracker#markAllForRotation()} should not mark any new
+     * packages for rotation.
+     */
+    @Test
+    public void markAllForRotation_doesNotMarkUnseenPackages() {
+        mTertiaryKeyRotationTracker.markAllForRotation();
+
+        assertThat(mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1)).isFalse();
+    }
+
+    private void simulateBackups(String packageName, int numberOfBackups) {
+        while (numberOfBackups > 0) {
+            mTertiaryKeyRotationTracker.recordBackup(packageName);
+            numberOfBackups--;
+        }
+    }
+
+    private static TertiaryKeyRotationTracker newInstance() {
+        return TertiaryKeyRotationTracker.getInstance(RuntimeEnvironment.application);
+    }
+}
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java b/services/robotests/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java
new file mode 100644
index 0000000..9c06d81
--- /dev/null
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java
@@ -0,0 +1,43 @@
+/*
+ * 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.testing.shadows;
+
+import android.security.keystore.recovery.InternalRecoveryServiceException;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+/** Shadow {@link InternalRecoveryServiceException}. */
+@Implements(InternalRecoveryServiceException.class)
+public class ShadowInternalRecoveryServiceException {
+    private String mMessage;
+
+    @Implementation
+    public void __constructor__(String message) {
+        mMessage = message;
+    }
+
+    @Implementation
+    public void __constructor__(String message, Throwable cause) {
+        mMessage = message;
+    }
+
+    @Implementation
+    public String getMessage() {
+        return mMessage;
+    }
+}
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowRecoveryController.java b/services/robotests/src/com/android/server/testing/shadows/ShadowRecoveryController.java
new file mode 100644
index 0000000..7dad8a4
--- /dev/null
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowRecoveryController.java
@@ -0,0 +1,152 @@
+/*
+ * 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.testing.shadows;
+
+import android.content.Context;
+import android.security.keystore.recovery.InternalRecoveryServiceException;
+import android.security.keystore.recovery.LockScreenRequiredException;
+import android.security.keystore.recovery.RecoveryController;
+
+import com.google.common.collect.ImmutableList;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+import java.lang.reflect.Constructor;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.crypto.KeyGenerator;
+
+/**
+ * Shadow of {@link RecoveryController}.
+ *
+ * <p>Instead of generating keys via the {@link RecoveryController}, this shadow generates them in
+ * memory.
+ */
+@Implements(RecoveryController.class)
+public class ShadowRecoveryController {
+    private static final String KEY_GENERATOR_ALGORITHM = "AES";
+    private static final int KEY_SIZE_BITS = 256;
+
+    private static boolean sIsSupported = true;
+    private static boolean sThrowsInternalError = false;
+    private static HashMap<String, Key> sKeysByAlias = new HashMap<>();
+    private static HashMap<String, Integer> sKeyStatusesByAlias = new HashMap<>();
+
+    @Implementation
+    public void __constructor__() {
+        // do not throw
+    }
+
+    @Implementation
+    public static RecoveryController getInstance(Context context) {
+        // Call non-public constructor.
+        try {
+            Constructor<RecoveryController> constructor = RecoveryController.class.getConstructor();
+            return constructor.newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Implementation
+    public static boolean isRecoverableKeyStoreEnabled(Context context) {
+        return sIsSupported;
+    }
+
+    @Implementation
+    public Key generateKey(String alias)
+            throws InternalRecoveryServiceException, LockScreenRequiredException {
+        maybeThrowError();
+        KeyGenerator keyGenerator;
+        try {
+            keyGenerator = KeyGenerator.getInstance(KEY_GENERATOR_ALGORITHM);
+        } catch (NoSuchAlgorithmException e) {
+            // Should never happen
+            throw new RuntimeException(e);
+        }
+
+        keyGenerator.init(KEY_SIZE_BITS);
+        Key key = keyGenerator.generateKey();
+        sKeysByAlias.put(alias, key);
+        sKeyStatusesByAlias.put(alias, RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS);
+        return key;
+    }
+
+    @Implementation
+    public Key getKey(String alias)
+            throws InternalRecoveryServiceException, UnrecoverableKeyException {
+        return sKeysByAlias.get(alias);
+    }
+
+    @Implementation
+    public void removeKey(String alias) throws InternalRecoveryServiceException {
+        sKeyStatusesByAlias.remove(alias);
+        sKeysByAlias.remove(alias);
+    }
+
+    @Implementation
+    public int getRecoveryStatus(String alias) throws InternalRecoveryServiceException {
+        maybeThrowError();
+        return sKeyStatusesByAlias.getOrDefault(
+                alias, RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE);
+    }
+
+    @Implementation
+    public List<String> getAliases() throws InternalRecoveryServiceException {
+        return ImmutableList.copyOf(sKeyStatusesByAlias.keySet());
+    }
+
+    private static void maybeThrowError() throws InternalRecoveryServiceException {
+        if (sThrowsInternalError) {
+            throw new InternalRecoveryServiceException("test error");
+        }
+    }
+
+    /** Sets the recovery status of the key with {@code alias} to {@code status}. */
+    public static void setRecoveryStatus(String alias, int status) {
+        sKeyStatusesByAlias.put(alias, status);
+    }
+
+    /** Sets all existing keys to being synced. */
+    public static void syncAllKeys() {
+        for (String alias : sKeysByAlias.keySet()) {
+            sKeyStatusesByAlias.put(alias, RecoveryController.RECOVERY_STATUS_SYNCED);
+        }
+    }
+
+    public static void setThrowsInternalError(boolean throwsInternalError) {
+        ShadowRecoveryController.sThrowsInternalError = throwsInternalError;
+    }
+
+    public static void setIsSupported(boolean isSupported) {
+        ShadowRecoveryController.sIsSupported = isSupported;
+    }
+
+    @Resetter
+    public static void reset() {
+        sIsSupported = true;
+        sThrowsInternalError = false;
+        sKeysByAlias.clear();
+        sKeyStatusesByAlias.clear();
+    }
+}
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 746c453..cf4d3a8 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -66,6 +66,7 @@
     <uses-permission android:name="android.permission.SUSPEND_APPS"/>
     <uses-permission android:name="android.permission.CONTROL_KEYGUARD"/>
     <uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE"/>
+    <uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
 
     <!-- Uses API introduced in O (26) -->
     <uses-sdk android:minSdkVersion="1"
diff --git a/services/tests/servicestests/src/com/android/server/CachedDeviceStateServiceTest.java b/services/tests/servicestests/src/com/android/server/CachedDeviceStateServiceTest.java
index 81107cf..2a78b6f 100644
--- a/services/tests/servicestests/src/com/android/server/CachedDeviceStateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/CachedDeviceStateServiceTest.java
@@ -17,9 +17,10 @@
 package com.android.server;
 
 
-import static org.mockito.Mockito.when;
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.when;
+
 import android.content.Context;
 import android.content.Intent;
 import android.os.BatteryManager;
@@ -134,4 +135,44 @@
         mContext.sendBroadcast(intentUnplugged);
         assertThat(deviceState.isCharging()).isFalse();
     }
+
+    @Test
+    public void correctlyTracksTimeOnBattery() throws Exception {
+        CachedDeviceStateService service = new CachedDeviceStateService(mContext);
+        when(mBatteryManager.getPlugType()).thenReturn(OsProtoEnums.BATTERY_PLUGGED_NONE);
+
+        service.onStart();
+        CachedDeviceState.Readonly deviceState =
+                LocalServices.getService(CachedDeviceState.Readonly.class);
+
+        CachedDeviceState.TimeInStateStopwatch stopwatch =
+                deviceState.createTimeOnBatteryStopwatch();
+
+        // State can be initialized correctly only after PHASE_SYSTEM_SERVICES_READY.
+        assertThat(stopwatch.isRunning()).isFalse();
+        service.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
+
+        assertThat(stopwatch.isRunning()).isTrue();
+        stopwatch.reset();
+
+        Thread.sleep(100);
+        assertThat(stopwatch.isRunning()).isTrue();
+        assertThat(stopwatch.getMillis()).isAtLeast(100L);
+
+        long timeOnBatteryBeforePluggedIn = stopwatch.getMillis();
+        Intent intentPluggedIn = new Intent(Intent.ACTION_BATTERY_CHANGED);
+        intentPluggedIn.putExtra(BatteryManager.EXTRA_PLUGGED, OsProtoEnums.BATTERY_PLUGGED_AC);
+        mContext.sendBroadcast(intentPluggedIn);
+
+        assertThat(stopwatch.getMillis()).isAtLeast(timeOnBatteryBeforePluggedIn);
+        assertThat(stopwatch.isRunning()).isFalse();
+
+        long timeOnBatteryAfterPluggedIn = stopwatch.getMillis();
+        Thread.sleep(20);
+        assertThat(stopwatch.getMillis()).isEqualTo(timeOnBatteryAfterPluggedIn);
+
+        stopwatch.reset();
+        assertThat(stopwatch.getMillis()).isEqualTo(0L);
+        assertThat(stopwatch.isRunning()).isFalse();
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
index 53711a6..e0ecd3e 100644
--- a/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
@@ -35,6 +35,7 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.R;
 import com.android.internal.app.ColorDisplayController;
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.LocalServices;
@@ -911,7 +912,11 @@
         startService();
         assertAccessibilityTransformActivated(true /* activated */ );
         assertUserColorMode(ColorDisplayController.COLOR_MODE_NATURAL);
-        assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
+        if (isColorModeValid(ColorDisplayController.COLOR_MODE_SATURATED)) {
+            assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
+        } else if (isColorModeValid(ColorDisplayController.COLOR_MODE_AUTOMATIC)) {
+            assertActiveColorMode(ColorDisplayController.COLOR_MODE_AUTOMATIC);
+        }
     }
 
     @Test
@@ -926,7 +931,11 @@
         startService();
         assertAccessibilityTransformActivated(true /* activated */ );
         assertUserColorMode(ColorDisplayController.COLOR_MODE_NATURAL);
-        assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
+        if (isColorModeValid(ColorDisplayController.COLOR_MODE_SATURATED)) {
+            assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
+        } else if (isColorModeValid(ColorDisplayController.COLOR_MODE_AUTOMATIC)) {
+            assertActiveColorMode(ColorDisplayController.COLOR_MODE_AUTOMATIC);
+        }
     }
 
     @Test
@@ -942,7 +951,11 @@
         startService();
         assertAccessibilityTransformActivated(true /* activated */ );
         assertUserColorMode(ColorDisplayController.COLOR_MODE_NATURAL);
-        assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
+        if (isColorModeValid(ColorDisplayController.COLOR_MODE_SATURATED)) {
+            assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
+        } else if (isColorModeValid(ColorDisplayController.COLOR_MODE_AUTOMATIC)) {
+            assertActiveColorMode(ColorDisplayController.COLOR_MODE_AUTOMATIC);
+        }
     }
 
     @Test
@@ -1030,6 +1043,24 @@
     }
 
     /**
+     * Returns whether the color mode is valid on the device the tests are running on.
+     *
+     * @param mode the mode to check
+     */
+    private boolean isColorModeValid(int mode) {
+        final int[] availableColorModes = mContext.getResources().getIntArray(
+            R.array.config_availableColorModes);
+        if (availableColorModes != null) {
+            for (int availableMode : availableColorModes) {
+                if (mode == availableMode) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
      * Convenience method to start {@link #mColorDisplayService}.
      */
     private void startService() {
@@ -1038,7 +1069,6 @@
         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
-                mColorDisplayService.onStart();
                 mColorDisplayService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
                 mColorDisplayService.onStartUser(mUserId);
             }
diff --git a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
index 7cf7df13..c1963da 100644
--- a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
@@ -268,10 +268,10 @@
 
     @Test
     public void testGetCurrentStatus() throws RemoteException {
-        int status = Temperature.THROTTLING_WARNING;
+        int status = Temperature.THROTTLING_EMERGENCY;
         Temperature newSkin = new Temperature(100, Temperature.TYPE_SKIN, "skin1", status);
         mFakeHal.mCallback.onValues(newSkin);
-        assertEquals(status, mService.mService.getCurrentStatus());
+        assertEquals(status, mService.mService.getCurrentThermalStatus());
     }
 
     @Test
@@ -294,6 +294,6 @@
         assertEquals(0, mService.mService.getCurrentTemperatures().size());
         assertEquals(0,
                 mService.mService.getCurrentTemperaturesWithType(Temperature.TYPE_SKIN).size());
-        assertEquals(Temperature.THROTTLING_NONE, mService.mService.getCurrentStatus());
+        assertEquals(Temperature.THROTTLING_NONE, mService.mService.getCurrentThermalStatus());
     }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 9da204f..41d5a1c 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -456,6 +456,31 @@
     }
 
     @Test
+    public void testNoBeepForImportanceDefaultInAutomotive() throws Exception {
+        mService.setIsAutomotive(true);
+
+        NotificationRecord r = getBeepyNotification();
+        r.setSystemImportance(NotificationManager.IMPORTANCE_DEFAULT);
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyNeverBeep();
+        assertFalse(r.isInterruptive());
+    }
+
+    @Test
+    public void testBeepForImportanceHighInAutomotive() throws Exception {
+        mService.setIsAutomotive(true);
+
+        NotificationRecord r = getBeepyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyBeepLooped();
+        assertTrue(r.isInterruptive());
+    }
+
+    @Test
     public void testNoInterruptionForMin() throws Exception {
         NotificationRecord r = getBeepyNotification();
         r.setSystemImportance(NotificationManager.IMPORTANCE_MIN);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
index b30bb4b..0681295 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
@@ -15,8 +15,9 @@
  */
 package com.android.server.notification;
 
-import static org.junit.Assert.assertEquals;
+import static org.hamcrest.Matchers.contains;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
@@ -34,8 +35,8 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.StatusBarNotification;
-import android.telecom.TelecomManager;
 import android.support.test.runner.AndroidJUnit4;
+import android.telecom.TelecomManager;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.server.UiServiceTestCase;
@@ -211,7 +212,7 @@
         mRecordColorized = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "colorized", uid2, uid2, n13,
                 new UserHandle(userId), "", 1999), getDefaultChannel());
-        mRecordHighCall.setSystemImportance(NotificationManager.IMPORTANCE_HIGH);
+        mRecordColorized.setSystemImportance(NotificationManager.IMPORTANCE_HIGH);
 
         Notification n14 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                 .setCategory(Notification.CATEGORY_CALL)
@@ -225,11 +226,11 @@
     }
 
     @Test
-    public void testOrdering() throws Exception {
+    public void testOrdering() {
         final List<NotificationRecord> expected = new ArrayList<>();
         expected.add(mRecordColorizedCall);
-        expected.add(mRecordDefaultMedia);
         expected.add(mRecordColorized);
+        expected.add(mRecordDefaultMedia);
         expected.add(mRecordHighCall);
         expected.add(mRecordInlineReply);
         if (mRecordSms != null) {
@@ -250,11 +251,11 @@
 
         Collections.sort(actual, new NotificationComparator(mContext));
 
-        assertEquals(expected, actual);
+        assertThat(actual, contains(expected.toArray()));
     }
 
     @Test
-    public void testMessaging() throws Exception {
+    public void testMessaging() {
         NotificationComparator comp = new NotificationComparator(mContext);
         assertTrue(comp.isImportantMessaging(mRecordInlineReply));
         if (mRecordSms != null) {
@@ -265,7 +266,7 @@
     }
 
     @Test
-    public void testPeople() throws Exception {
+    public void testPeople() {
         NotificationComparator comp = new NotificationComparator(mContext);
         assertTrue(comp.isImportantPeople(mRecordStarredContact));
         assertTrue(comp.isImportantPeople(mRecordContact));
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
index 3643457..885a7e0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
@@ -231,7 +231,7 @@
 
         final Configuration config = new Configuration();
         final WindowConfiguration winConfig = config.windowConfiguration;
-        stackController.adjustConfigurationForBounds(bounds, null /*insetBounds*/,
+        stackController.adjustConfigurationForBounds(bounds,
                 new Rect() /*nonDecorBounds*/, new Rect() /*stableBounds*/, false /*overrideWidth*/,
                 false /*overrideHeight*/, mDisplayInfo.logicalDensityDpi, config, parentConfig,
                 windowingMode);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
index b3e90de..60a8aeb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
@@ -76,7 +76,7 @@
 
     private static class TaskWithBounds extends Task {
         final Rect mBounds;
-        final Rect mInsetBounds = new Rect();
+        final Rect mOverrideDisplayedBounds = new Rect();
         boolean mFullscreenForTest = true;
 
         TaskWithBounds(TaskStack stack, WindowManagerService wm, Rect bounds) {
@@ -100,8 +100,8 @@
             outBounds.set(mBounds);
         }
         @Override
-        void getTempInsetBounds(Rect outBounds) {
-            outBounds.set(mInsetBounds);
+        Rect getOverrideDisplayedBounds() {
+            return mOverrideDisplayedBounds;
         }
         @Override
         boolean isFullscreen() {
@@ -343,14 +343,14 @@
                 taskBottom - contentInsetBottom));
 
         pf.set(0, 0, logicalWidth, logicalHeight);
-        // However if we set temp inset bounds, the insets will be computed
-        // as if our window was laid out there,  but it will be laid out according to
-        // the task bounds.
+        // If we set displayed bounds, the insets will be computed with the main task bounds
+        // but the frame will be positioned according to the displayed bounds.
         final int insetLeft = logicalWidth / 5;
         final int insetTop = logicalHeight / 5;
         final int insetRight = insetLeft + (taskRight - taskLeft);
         final int insetBottom = insetTop + (taskBottom - taskTop);
-        task.mInsetBounds.set(insetLeft, insetTop, insetRight, insetBottom);
+        task.mOverrideDisplayedBounds.set(taskBounds);
+        task.mBounds.set(insetLeft, insetTop, insetRight, insetBottom);
         windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
         w.computeFrameLw();
         assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
@@ -430,7 +430,6 @@
         final int taskBottom = logicalHeight / 4 * 3;
         final Rect taskBounds = new Rect(taskLeft, taskTop, taskRight, taskBottom);
         final TaskWithBounds task = new TaskWithBounds(mStubStack, mWm, taskBounds);
-        task.mInsetBounds.set(taskLeft, taskTop, taskRight, taskBottom);
         task.mFullscreenForTest = false;
         WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
@@ -486,12 +485,12 @@
     }
 
     @Test
-    public void testDisplayCutout_tempInsetBounds() {
+    public void testDisplayCutout_tempDisplayedBounds() {
         // Regular fullscreen task and window
         final TaskWithBounds task = new TaskWithBounds(mStubStack, mWm,
-                new Rect(0, -500, 1000, 1500));
+                new Rect(0, 0, 1000, 2000));
         task.mFullscreenForTest = false;
-        task.mInsetBounds.set(0, 0, 1000, 2000);
+        task.setOverrideDisplayedBounds(new Rect(0, -500, 1000, 1500));
         WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRule.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRule.java
index 7ce3da4..50fd188 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRule.java
@@ -175,21 +175,21 @@
         };
     }
 
-    public WindowManagerService getWindowManagerService() {
+    WindowManagerService getWindowManagerService() {
         return mService;
     }
 
-    public TestWindowManagerPolicy getWindowManagerPolicy() {
-        return mPolicy;
-    }
-
-    public void waitUntilWindowManagerHandlersIdle() {
+    void waitUntilWindowManagerHandlersIdle() {
         final WindowManagerService wm = getWindowManagerService();
-        if (wm != null) {
-            wm.mH.runWithScissors(() -> { }, 0);
-            wm.mAnimationHandler.runWithScissors(() -> { }, 0);
-            SurfaceAnimationThread.getHandler().runWithScissors(() -> { }, 0);
+        if (wm == null) {
+            return;
         }
+        wm.mH.removeCallbacksAndMessages(null);
+        wm.mAnimationHandler.removeCallbacksAndMessages(null);
+        SurfaceAnimationThread.getHandler().removeCallbacksAndMessages(null);
+        wm.mH.runWithScissors(() -> { }, 0);
+        wm.mAnimationHandler.runWithScissors(() -> { }, 0);
+        SurfaceAnimationThread.getHandler().runWithScissors(() -> { }, 0);
     }
 
     private void destroyAllSurfaceTransactions() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
index a1b0411..aa0ecf8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
@@ -28,6 +28,9 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -117,11 +120,11 @@
         // many components rely on the {@link StackWindowController#adjustConfigurationForBounds}
         // to properly set bounds values in the configuration. We must mimick those actions here.
         doAnswer((InvocationOnMock invocationOnMock) -> {
-            final Configuration config = invocationOnMock.<Configuration>getArgument(7);
+            final Configuration config = invocationOnMock.<Configuration>getArgument(6);
             final Rect bounds = invocationOnMock.<Rect>getArgument(0);
             config.windowConfiguration.setBounds(bounds);
             return null;
-        }).when(controller).adjustConfigurationForBounds(any(), any(), any(), any(),
+        }).when(controller).adjustConfigurationForBounds(any(), any(), any(),
                 anyBoolean(), anyBoolean(), anyFloat(), any(), any(), anyInt());
 
         return controller;
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index cef99865..d617de0 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -29,7 +29,6 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
-import java.lang.String;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.nio.charset.StandardCharsets;
@@ -908,10 +907,16 @@
         @Override
         public String toString() {
             StringBuilder sb = new StringBuilder();
-            sb.append("[pa: ");
+            sb.append("[id: ");
+            sb.append(mTelecomCallId);
+            sb.append(", pa: ");
             sb.append(mAccountHandle);
             sb.append(", hdl: ");
-            sb.append(Log.pii(mHandle));
+            sb.append(Log.piiHandle(mHandle));
+            sb.append(", hdlPres: ");
+            sb.append(mHandlePresentation);
+            sb.append(", videoState: ");
+            sb.append(VideoProfile.videoStateToString(mVideoState));
             sb.append(", caps: ");
             sb.append(capabilitiesToString(mCallCapabilities));
             sb.append(", props: ");
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index 7db6940..6628743 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -27,8 +27,8 @@
 import android.os.RemoteException;
 
 import com.android.internal.os.SomeArgs;
-import com.android.internal.telecom.ICallScreeningService;
 import com.android.internal.telecom.ICallScreeningAdapter;
+import com.android.internal.telecom.ICallScreeningService;
 
 /**
  * This service can be implemented by the default dialer (see
@@ -147,7 +147,7 @@
             private boolean mShouldSkipCallLog;
             private boolean mShouldSkipNotification;
 
-            /*
+            /**
              * Sets whether the incoming call should be blocked.
              */
             public Builder setDisallowCall(boolean shouldDisallowCall) {
@@ -155,7 +155,7 @@
                 return this;
             }
 
-            /*
+            /**
              * Sets whether the incoming call should be disconnected as if the user had manually
              * rejected it. This property should only be set to true if the call is disallowed.
              */
@@ -164,16 +164,20 @@
                 return this;
             }
 
-            /*
+            /**
              * Sets whether the incoming call should not be displayed in the call log. This property
              * should only be set to true if the call is disallowed.
+             * <p>
+             * Note: Calls will still be logged with type
+             * {@link android.provider.CallLog.Calls#BLOCKED_TYPE}, regardless of how this property
+             * is set.
              */
             public Builder setSkipCallLog(boolean shouldSkipCallLog) {
                 mShouldSkipCallLog = shouldSkipCallLog;
                 return this;
             }
 
-            /*
+            /**
              * Sets whether a missed call notification should not be shown for the incoming call.
              * This property should only be set to true if the call is disallowed.
              */
@@ -211,6 +215,17 @@
      * Called when a new incoming call is added.
      * {@link CallScreeningService#respondToCall(Call.Details, CallScreeningService.CallResponse)}
      * should be called to allow or disallow the call.
+     * <p>
+     * Note: The {@link Call.Details} instance provided to a call screening service will only have
+     * the following properties set.  The rest of the {@link Call.Details} properties will be set to
+     * their default value or {@code null}.
+     * <ul>
+     *     <li>{@link Call.Details#getState()}</li>
+     *     <li>{@link Call.Details#getConnectTimeMillis()}</li>
+     *     <li>{@link Call.Details#getCreationTimeMillis()}</li>
+     *     <li>{@link Call.Details#getHandle()}</li>
+     *     <li>{@link Call.Details#getHandlePresentation()}</li>
+     * </ul>
      *
      * @param callDetails Information about a new incoming call, see {@link Call.Details}.
      */
diff --git a/telephony/OWNERS b/telephony/OWNERS
index 054288b..2236cba 100644
--- a/telephony/OWNERS
+++ b/telephony/OWNERS
@@ -13,3 +13,4 @@
 shuoq@google.com
 refuhoo@google.com
 paulye@google.com
+nazaninb@google.com
\ No newline at end of file
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 185c886..62cead1 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1154,20 +1154,33 @@
      */
     public static final String KEY_CARRIER_NAME_STRING = "carrier_name_string";
 
- /**
-  * The Component Name of a carrier-provided CallScreeningService implementation. Telecom will
-  * bind to {@link android.telecom.CallScreeningService} for ALL incoming calls and provide
-  * the carrier
-  * CallScreeningService with the opportunity to allow or block calls.
-  * <p>
-  * The String includes the package name/the class name.
-  * Example:
-  * <item>com.android.carrier/com.android.carrier.callscreeningserviceimpl</item>
-  * <p>
-  * Using {@link ComponentName#flattenToString()} to convert a ComponentName object to String.
-  * Using {@link ComponentName#unflattenFromString(String)} to convert a String object to a
-  * ComponentName.
-  */
+    /**
+     * String to override sim country iso.
+     * Sim country iso is based on sim MCC which is coarse and doesn't work with dual IMSI SIM where
+     * a SIM can have multiple MCC from different countries.
+     * Instead, each sim carrier should have a single country code, apply per carrier based iso
+     * code as an override. The overridden value can be read from
+     * {@link TelephonyManager#getSimCountryIso()} and {@link SubscriptionInfo#getCountryIso()}
+     *
+     * @hide
+     */
+    public static final String KEY_SIM_COUNTRY_ISO_OVERRIDE_STRING =
+            "sim_country_iso_override_string";
+
+   /**
+    * The Component Name of a carrier-provided CallScreeningService implementation. Telecom will
+    * bind to {@link android.telecom.CallScreeningService} for ALL incoming calls and provide
+    * the carrier
+    * CallScreeningService with the opportunity to allow or block calls.
+    * <p>
+    * The String includes the package name/the class name.
+    * Example:
+    * <item>com.android.carrier/com.android.carrier.callscreeningserviceimpl</item>
+    * <p>
+    * Using {@link ComponentName#flattenToString()} to convert a ComponentName object to String.
+    * Using {@link ComponentName#unflattenFromString(String)} to convert a String object to a
+    * ComponentName.
+    */
     public static final String KEY_CARRIER_CALL_SCREENING_APP_STRING = "call_screening_app";
 
     /**
@@ -2533,6 +2546,7 @@
         sDefaults.putBoolean(KEY_CONFIG_WIFI_DISABLE_IN_ECBM, false);
         sDefaults.putBoolean(KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
         sDefaults.putString(KEY_CARRIER_NAME_STRING, "");
+        sDefaults.putString(KEY_SIM_COUNTRY_ISO_OVERRIDE_STRING, "");
         sDefaults.putString(KEY_CARRIER_CALL_SCREENING_APP_STRING, "");
         sDefaults.putBoolean(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL, false);
         sDefaults.putString(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING, "");
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationStates.java b/telephony/java/android/telephony/DataSpecificRegistrationStates.java
index b6e6cba..5d809d0 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationStates.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationStates.java
@@ -33,17 +33,31 @@
      */
     public final boolean isNrAvailable;
 
+    /**
+     * Indicates that if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving
+     * cell.
+     *
+     * True the primary serving cell is LTE cell and the plmn-InfoList-r15 is present in SIB2 and
+     * at least one bit in this list is true, otherwise this value should be false.
+     *
+     * Reference: 3GPP TS 36.331 v15.2.2 6.3.1 System information blocks.
+     */
+    public final boolean isEnDcAvailable;
+
     DataSpecificRegistrationStates(
-            int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable) {
+            int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable,
+            boolean isEnDcAvailable) {
         this.maxDataCalls = maxDataCalls;
         this.isDcNrRestricted = isDcNrRestricted;
         this.isNrAvailable = isNrAvailable;
+        this.isEnDcAvailable = isEnDcAvailable;
     }
 
     private DataSpecificRegistrationStates(Parcel source) {
         maxDataCalls = source.readInt();
         isDcNrRestricted = source.readBoolean();
         isNrAvailable = source.readBoolean();
+        isEnDcAvailable = source.readBoolean();
     }
 
     @Override
@@ -51,6 +65,7 @@
         dest.writeInt(maxDataCalls);
         dest.writeBoolean(isDcNrRestricted);
         dest.writeBoolean(isNrAvailable);
+        dest.writeBoolean(isEnDcAvailable);
     }
 
     @Override
@@ -65,13 +80,14 @@
                 .append(" maxDataCalls = " + maxDataCalls)
                 .append(" isDcNrRestricted = " + isDcNrRestricted)
                 .append(" isNrAvailable = " + isNrAvailable)
+                .append(" isEnDcAvailable = " + isEnDcAvailable)
                 .append(" }")
                 .toString();
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable);
+        return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable);
     }
 
     @Override
@@ -83,7 +99,8 @@
         DataSpecificRegistrationStates other = (DataSpecificRegistrationStates) o;
         return this.maxDataCalls == other.maxDataCalls
                 && this.isDcNrRestricted == other.isDcNrRestricted
-                && this.isNrAvailable == other.isNrAvailable;
+                && this.isNrAvailable == other.isNrAvailable
+                && this.isEnDcAvailable == other.isEnDcAvailable;
     }
 
     public static final Parcelable.Creator<DataSpecificRegistrationStates> CREATOR =
diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java
index aee744f..b00665e 100644
--- a/telephony/java/android/telephony/NetworkRegistrationState.java
+++ b/telephony/java/android/telephony/NetworkRegistrationState.java
@@ -219,12 +219,13 @@
     public NetworkRegistrationState(int domain, int transportType, int regState,
             int accessNetworkTechnology, int rejectCause, boolean emergencyOnly,
             int[] availableServices, @Nullable CellIdentity cellIdentity, int maxDataCalls,
-            boolean isDcNrRestricted, boolean isNrAvailable) {
+            boolean isDcNrRestricted, boolean isNrAvailable, boolean isEndcAvailable) {
         this(domain, transportType, regState, accessNetworkTechnology, rejectCause, emergencyOnly,
                 availableServices, cellIdentity);
 
         mDataSpecificStates = new DataSpecificRegistrationStates(
-                maxDataCalls, isDcNrRestricted, isNrAvailable);
+                maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable);
+        updateNrStatus(mDataSpecificStates);
     }
 
     protected NetworkRegistrationState(Parcel source) {
@@ -448,6 +449,34 @@
         dest.writeInt(mNrStatus);
     }
 
+    /**
+     * Use the 5G NR Non-Standalone indicators from the network registration state to update the
+     * NR status. There are 3 indicators in the network registration state:
+     *
+     * 1. if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving cell.
+     * 2. if NR is supported by the selected PLMN.
+     * 3. if the use of dual connectivity with NR is restricted.
+     *
+     * The network has 5G NR capability if E-UTRA-NR Dual Connectivity is supported by the primary
+     * serving cell.
+     *
+     * The use of NR 5G is not restricted If the network has 5G NR capability and both the use of
+     * DCNR is not restricted and NR is supported by the selected PLMN. Otherwise the use of 5G
+     * NR is restricted.
+     *
+     * @param state data specific registration state contains the 5G NR indicators.
+     */
+    private void updateNrStatus(DataSpecificRegistrationStates state) {
+        mNrStatus = NR_STATUS_NONE;
+        if (state.isEnDcAvailable) {
+            if (!state.isDcNrRestricted && state.isNrAvailable) {
+                mNrStatus = NR_STATUS_NOT_RESTRICTED;
+            } else {
+                mNrStatus = NR_STATUS_RESTRICTED;
+            }
+        }
+    }
+
     public static final Parcelable.Creator<NetworkRegistrationState> CREATOR =
             new Parcelable.Creator<NetworkRegistrationState>() {
         @Override
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 13fbeaa..ca0c854 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -118,6 +118,13 @@
      */
     public static final int FREQUENCY_RANGE_MMWAVE = 4;
 
+    private static final List<Integer> FREQUENCY_RANGE_ORDER = Arrays.asList(
+            FREQUENCY_RANGE_UNKNOWN,
+            FREQUENCY_RANGE_LOW,
+            FREQUENCY_RANGE_MID,
+            FREQUENCY_RANGE_HIGH,
+            FREQUENCY_RANGE_MMWAVE);
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = "DUPLEX_MODE_",
@@ -1835,4 +1842,13 @@
             mNetworkRegistrationStates.add(regState);
         }
     }
+
+    /**
+     * @hide
+     */
+    public static final int getBetterNRFrequencyRange(int range1, int range2) {
+        return FREQUENCY_RANGE_ORDER.indexOf(range1) > FREQUENCY_RANGE_ORDER.indexOf(range2)
+                ? range1
+                : range2;
+    }
 }
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 4b24646..2c06c47 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -407,6 +407,13 @@
     public static final String MNC = "mnc";
 
     /**
+     * TelephonyProvider column name for the iso country code associated with a SIM.
+     * <P>Type: TEXT (String)</P>
+     * @hide
+     */
+    public static final String ISO_COUNTRY_CODE = "iso_country_code";
+
+    /**
      * TelephonyProvider column name for the sim provisioning status associated with a SIM.
      * <P>Type: INTEGER (int)</P>
      * @hide
@@ -1583,14 +1590,23 @@
         return subId;
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setDefaultSmsSubId(int subId) {
-        if (VDBG) logd("setDefaultSmsSubId sub id = " + subId);
+    /**
+     * Set the subscription which will be used by default for SMS, with the subscription which
+     * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
+     * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}).
+     *
+     * @param subscriptionId the supplied subscription ID
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public void setDefaultSmsSubId(int subscriptionId) {
+        if (VDBG) logd("setDefaultSmsSubId sub id = " + subscriptionId);
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                iSub.setDefaultSmsSubId(subId);
+                iSub.setDefaultSmsSubId(subscriptionId);
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1638,14 +1654,23 @@
         return subId;
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setDefaultDataSubId(int subId) {
-        if (VDBG) logd("setDataSubscription sub id = " + subId);
+    /**
+     * Set the subscription which will be used by default for data, with the subscription which
+     * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
+     * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}).
+     *
+     * @param subscriptionId the supplied subscription ID
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public void setDefaultDataSubId(int subscriptionId) {
+        if (VDBG) logd("setDataSubscription sub id = " + subscriptionId);
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                iSub.setDefaultDataSubId(subId);
+                iSub.setDefaultDataSubId(subscriptionId);
             }
         } catch (RemoteException ex) {
             // ignore it
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 45d914e..fa9b76d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -5541,19 +5541,40 @@
     public void requestNumberVerification(@NonNull PhoneNumberRange range, long timeoutMillis,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull NumberVerificationCallback callback) {
+        if (executor == null) {
+            throw new NullPointerException("Executor must be non-null");
+        }
+        if (callback == null) {
+            throw new NullPointerException("Callback must be non-null");
+        }
+
         INumberVerificationCallback internalCallback = new INumberVerificationCallback.Stub() {
             @Override
-            public void onCallReceived(String phoneNumber) throws RemoteException {
-                Binder.withCleanCallingIdentity(() -> callback.onCallReceived(phoneNumber));
+            public void onCallReceived(String phoneNumber) {
+                Binder.withCleanCallingIdentity(() ->
+                        executor.execute(() ->
+                                callback.onCallReceived(phoneNumber)));
             }
 
             @Override
-            public void onVerificationFailed(int reason) throws RemoteException {
-                Binder.withCleanCallingIdentity(() -> callback.onVerificationFailed(reason));
+            public void onVerificationFailed(int reason) {
+                Binder.withCleanCallingIdentity(() ->
+                        executor.execute(() ->
+                                callback.onVerificationFailed(reason)));
             }
         };
 
-        // TODO -- call the aidl method
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                telephony.requestNumberVerification(range, timeoutMillis, internalCallback,
+                        getOpPackageName());
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "requestNumberVerification RemoteException", ex);
+            executor.execute(() ->
+                    callback.onVerificationFailed(NumberVerificationCallback.REASON_UNSPECIFIED));
+        }
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 32e939a0..399dc52 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -35,6 +35,7 @@
 import android.telephony.ModemActivityInfo;
 import android.telephony.NeighboringCellInfo;
 import android.telephony.NetworkScanRequest;
+import android.telephony.PhoneNumberRange;
 import android.telephony.RadioAccessFamily;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
@@ -49,6 +50,7 @@
 import android.telephony.ims.aidl.IImsRegistrationCallback;
 import com.android.ims.internal.IImsServiceFeatureCallback;
 import com.android.internal.telephony.CellNetworkScanResult;
+import com.android.internal.telephony.INumberVerificationCallback;
 import com.android.internal.telephony.OperatorInfo;
 
 import java.util.List;
@@ -871,6 +873,17 @@
     String getCdmaMin(int subId);
 
     /**
+     * Request that the next incoming call from a number matching {@code range} be intercepted.
+     * @param range The range of phone numbers the caller expects a phone call from.
+     * @param timeoutMillis The amount of time to wait for such a call, or
+     *                      {@link #MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS}, whichever is lesser.
+     * @param callback the callback aidl
+     * @param callingPackage the calling package name.
+     */
+    void requestNumberVerification(in PhoneNumberRange range, long timeoutMillis,
+            in INumberVerificationCallback callback, String callingPackage);
+
+    /**
      * Has the calling application been granted special privileges by the carrier.
      *
      * If any of the packages in the calling UID has carrier privileges, the
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 4dc0341..d8f9618 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -542,7 +542,7 @@
 
         verify(mMockNetd)
                 .ipSecApplyTransportModeTransform(
-                        eq(pfd.getFileDescriptor()),
+                        eq(pfd),
                         eq(mUid),
                         eq(IpSecManager.DIRECTION_OUT),
                         anyString(),
@@ -555,7 +555,7 @@
         ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
         mIpSecService.removeTransportModeTransforms(pfd);
 
-        verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd.getFileDescriptor());
+        verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd);
     }
 
     private IpSecTunnelInterfaceResponse createAndValidateTunnel(
diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java
index 2c94a60..724446e 100644
--- a/tests/net/java/com/android/server/IpSecServiceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceTest.java
@@ -425,7 +425,7 @@
         ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
         mIpSecService.removeTransportModeTransforms(pfd);
 
-        verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd.getFileDescriptor());
+        verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd);
     }
 
     @Test
@@ -620,10 +620,10 @@
                 mIpSecService.openUdpEncapsulationSocket(0, new Binder());
 
         FileDescriptor sockFd = udpEncapResp.fileDescriptor.getFileDescriptor();
-        ArgumentMatcher<FileDescriptor> fdMatcher = (arg) -> {
+        ArgumentMatcher<ParcelFileDescriptor> fdMatcher = (arg) -> {
                     try {
                         StructStat sockStat = Os.fstat(sockFd);
-                        StructStat argStat = Os.fstat(arg);
+                        StructStat argStat = Os.fstat(arg.getFileDescriptor());
 
                         return sockStat.st_ino == argStat.st_ino
                                 && sockStat.st_dev == argStat.st_dev;
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.cpp b/tools/aapt2/format/binary/BinaryResourceParser.cpp
index ed70fb3..df0daeb 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.cpp
+++ b/tools/aapt2/format/binary/BinaryResourceParser.cpp
@@ -240,6 +240,12 @@
         }
         break;
 
+      case android::RES_TABLE_OVERLAYABLE_TYPE:
+        if (!ParseOverlayable(parser.chunk())) {
+          return false;
+        }
+        break;
+
       default:
         diag_->Warn(DiagMessage(source_)
                     << "unexpected chunk type "
@@ -383,24 +389,12 @@
       return false;
     }
 
-    const uint32_t type_spec_flags = entry_type_spec_flags_[res_id];
-    if ((entry->flags & ResTable_entry::FLAG_PUBLIC) != 0 ||
-        (type_spec_flags & ResTable_typeSpec::SPEC_OVERLAYABLE) != 0) {
-      if (entry->flags & ResTable_entry::FLAG_PUBLIC) {
-        Visibility visibility;
-        visibility.level = Visibility::Level::kPublic;
-        visibility.source = source_.WithLine(0);
-        if (!table_->SetVisibilityWithIdMangled(name, visibility, res_id, diag_)) {
-          return false;
-        }
-      }
-
-      if (type_spec_flags & ResTable_typeSpec::SPEC_OVERLAYABLE) {
-        Overlayable overlayable;
-        overlayable.source = source_.WithLine(0);
-        if (!table_->AddOverlayableMangled(name, overlayable, diag_)) {
-          return false;
-        }
+    if (entry->flags & ResTable_entry::FLAG_PUBLIC) {
+      Visibility visibility;
+      visibility.level = Visibility::Level::kPublic;
+      visibility.source = source_.WithLine(0);
+      if (!table_->SetVisibilityWithIdMangled(name, visibility, res_id, diag_)) {
+        return false;
       }
 
       // Erase the ID from the map once processed, so that we don't mark the same symbol more than
@@ -433,6 +427,72 @@
   return true;
 }
 
+bool BinaryResourceParser::ParseOverlayable(const ResChunk_header* chunk) {
+  const ResTable_overlayable_header* header = ConvertTo<ResTable_overlayable_header>(chunk);
+  if (!header) {
+    diag_->Error(DiagMessage(source_) << "corrupt ResTable_category_header chunk");
+    return false;
+  }
+
+  ResChunkPullParser parser(GetChunkData(chunk),
+                            GetChunkDataLen(chunk));
+  while (ResChunkPullParser::IsGoodEvent(parser.Next())) {
+    if (util::DeviceToHost16(parser.chunk()->type) == android::RES_TABLE_OVERLAYABLE_POLICY_TYPE) {
+      const ResTable_overlayable_policy_header* policy_header =
+          ConvertTo<ResTable_overlayable_policy_header>(parser.chunk());
+
+      std::vector<Overlayable::Policy> policies;
+      if (policy_header->policy_flags & ResTable_overlayable_policy_header::POLICY_PUBLIC) {
+        policies.push_back(Overlayable::Policy::kPublic);
+      }
+      if (policy_header->policy_flags
+          & ResTable_overlayable_policy_header::POLICY_SYSTEM_PARTITION) {
+        policies.push_back(Overlayable::Policy::kSystem);
+      }
+      if (policy_header->policy_flags
+          & ResTable_overlayable_policy_header::POLICY_VENDOR_PARTITION) {
+        policies.push_back(Overlayable::Policy::kVendor);
+      }
+      if (policy_header->policy_flags
+          & ResTable_overlayable_policy_header::POLICY_PRODUCT_PARTITION) {
+        policies.push_back(Overlayable::Policy::kProduct);
+      }
+      if (policy_header->policy_flags
+          & ResTable_overlayable_policy_header::POLICY_PRODUCT_SERVICES_PARTITION) {
+        policies.push_back(Overlayable::Policy::kProductServices);
+      }
+
+      const ResTable_ref* const ref_begin = reinterpret_cast<const ResTable_ref*>(
+          ((uint8_t *)policy_header) + util::DeviceToHost32(policy_header->header.headerSize));
+      const ResTable_ref* const ref_end = ref_begin
+          + util::DeviceToHost32(policy_header->entry_count);
+      for (auto ref_iter = ref_begin; ref_iter != ref_end; ++ref_iter) {
+        ResourceId res_id(util::DeviceToHost32(ref_iter->ident));
+        const auto iter = id_index_.find(res_id);
+
+        // If the overlayable chunk comes before the type chunks, the resource ids and resource name
+        // pairing will not exist at this point.
+        if (iter == id_index_.cend()) {
+          diag_->Error(DiagMessage(source_) << "failed to find resource name for overlayable"
+                                            << " resource " << res_id);
+          return false;
+        }
+
+        for (Overlayable::Policy policy : policies) {
+          Overlayable overlayable;
+          overlayable.source = source_.WithLine(0);
+          overlayable.policy = policy;
+          if (!table_->AddOverlayable(iter->second, overlayable, diag_)) {
+            return false;
+          }
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
 std::unique_ptr<Item> BinaryResourceParser::ParseValue(const ResourceNameRef& name,
                                                        const ConfigDescription& config,
                                                        const android::Res_value& value) {
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.h b/tools/aapt2/format/binary/BinaryResourceParser.h
index 2bdc051..a2eee50 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.h
+++ b/tools/aapt2/format/binary/BinaryResourceParser.h
@@ -54,6 +54,7 @@
   bool ParseTypeSpec(const ResourceTablePackage* package, const android::ResChunk_header* chunk);
   bool ParseType(const ResourceTablePackage* package, const android::ResChunk_header* chunk);
   bool ParseLibrary(const android::ResChunk_header* chunk);
+  bool ParseOverlayable(const android::ResChunk_header* chunk);
 
   std::unique_ptr<Item> ParseValue(const ResourceNameRef& name,
                                    const android::ConfigDescription& config,
diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp
index 6c1a9ba..976c328 100644
--- a/tools/aapt2/format/binary/TableFlattener.cpp
+++ b/tools/aapt2/format/binary/TableFlattener.cpp
@@ -24,6 +24,7 @@
 #include "android-base/logging.h"
 #include "android-base/macros.h"
 #include "android-base/stringprintf.h"
+#include "androidfw/ResourceUtils.h"
 
 #include "ResourceTable.h"
 #include "ResourceValues.h"
@@ -216,6 +217,11 @@
   size_t entry_count_ = 0;
 };
 
+struct PolicyChunk {
+  uint32_t policy_flags;
+  std::set<ResourceId> ids;
+};
+
 class PackageFlattener {
  public:
   PackageFlattener(IAaptContext* context, ResourceTablePackage* package,
@@ -267,6 +273,8 @@
       FlattenLibrarySpec(buffer);
     }
 
+    FlattenOverlayable(buffer);
+
     pkg_writer.Finish();
     return true;
   }
@@ -413,6 +421,97 @@
     return sorted_entries;
   }
 
+  void FlattenOverlayable(BigBuffer* buffer) {
+    std::vector<PolicyChunk> policies;
+
+    CHECK(bool(package_->id)) << "package must have an ID set when flattening <overlayable>";
+    for (auto& type : package_->types) {
+      CHECK(bool(type->id)) << "type must have an ID set when flattening <overlayable>";
+      for (auto& entry : type->entries) {
+        CHECK(bool(type->id)) << "entry must have an ID set when flattening <overlayable>";
+
+        // TODO(b/120298168): Convert the policies vector to a policy set or bitmask
+        if (!entry->overlayable_declarations.empty()) {
+          uint16_t policy_flags = 0;
+          for (Overlayable overlayable : entry->overlayable_declarations) {
+            if (overlayable.policy) {
+              switch (overlayable.policy.value()) {
+                case Overlayable::Policy::kPublic:
+                  policy_flags |= ResTable_overlayable_policy_header::POLICY_PUBLIC;
+                  break;
+                case Overlayable::Policy::kSystem:
+                  policy_flags |= ResTable_overlayable_policy_header::POLICY_SYSTEM_PARTITION;
+                  break;
+                case Overlayable::Policy::kVendor:
+                  policy_flags |= ResTable_overlayable_policy_header::POLICY_VENDOR_PARTITION;
+                  break;
+                case Overlayable::Policy::kProduct:
+                  policy_flags |= ResTable_overlayable_policy_header::POLICY_PRODUCT_PARTITION;
+                  break;
+                case Overlayable::Policy::kProductServices:
+                  policy_flags |=
+                      ResTable_overlayable_policy_header::POLICY_PRODUCT_SERVICES_PARTITION;
+                  break;
+              }
+            } else {
+              // Encode overlayable entries defined without a policy as publicly overlayable
+              policy_flags |= ResTable_overlayable_policy_header::POLICY_PUBLIC;
+            }
+          }
+
+          // Find the overlayable policy chunk with the same policies as the entry
+          PolicyChunk* policy_chunk = nullptr;
+          for (PolicyChunk& policy : policies) {
+            if (policy.policy_flags == policy_flags) {
+              policy_chunk = &policy;
+              break;
+            }
+          }
+
+          // Create a new policy chunk if an existing one with the same policy cannot be found
+          if (policy_chunk == nullptr) {
+            PolicyChunk p;
+            p.policy_flags = policy_flags;
+            policies.push_back(p);
+            policy_chunk = &policies.back();
+          }
+
+          policy_chunk->ids.insert(android::make_resid(package_->id.value(), type->id.value(),
+                                                       entry->id.value()));
+        }
+      }
+    }
+
+    if (policies.empty()) {
+      // Only write the overlayable chunk if the APK has overlayable entries
+      return;
+    }
+
+    ChunkWriter writer(buffer);
+    writer.StartChunk<ResTable_overlayable_header>(RES_TABLE_OVERLAYABLE_TYPE);
+
+    // Write each policy block for the overlayable
+    for (PolicyChunk& policy : policies) {
+      ChunkWriter policy_writer(buffer);
+      ResTable_overlayable_policy_header* policy_type =
+          policy_writer.StartChunk<ResTable_overlayable_policy_header>(
+              RES_TABLE_OVERLAYABLE_POLICY_TYPE);
+      policy_type->policy_flags = util::HostToDevice32(policy.policy_flags);
+      policy_type->entry_count = util::HostToDevice32(static_cast<uint32_t>(policy.ids.size()));
+
+      // Write the ids after the policy header
+      ResTable_ref* id_block = policy_writer.NextBlock<ResTable_ref>(policy.ids.size());
+      for (const ResourceId& id : policy.ids) {
+        id_block->ident = util::HostToDevice32(id.id);
+        id_block++;
+      }
+
+      policy_writer.Finish();
+    }
+
+    writer.Finish();
+  }
+
   bool FlattenTypeSpec(ResourceTableType* type, std::vector<ResourceEntry*>* sorted_entries,
                        BigBuffer* buffer) {
     ChunkWriter type_spec_writer(buffer);
@@ -446,11 +545,6 @@
         config_masks[entry->id.value()] |= util::HostToDevice32(ResTable_typeSpec::SPEC_PUBLIC);
       }
 
-      if (!entry->overlayable_declarations.empty()) {
-        config_masks[entry->id.value()] |=
-            util::HostToDevice32(ResTable_typeSpec::SPEC_OVERLAYABLE);
-      }
-
       const size_t config_count = entry->values.size();
       for (size_t i = 0; i < config_count; i++) {
         const ConfigDescription& config = entry->values[i]->config;
diff --git a/tools/aapt2/format/binary/TableFlattener_test.cpp b/tools/aapt2/format/binary/TableFlattener_test.cpp
index cd1414c..410efbe 100644
--- a/tools/aapt2/format/binary/TableFlattener_test.cpp
+++ b/tools/aapt2/format/binary/TableFlattener_test.cpp
@@ -628,24 +628,108 @@
 }
 
 TEST_F(TableFlattenerTest, FlattenOverlayable) {
+  std::string name = "com.app.test:integer/overlayable";
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
           .SetPackageId("com.app.test", 0x7f)
-          .AddSimple("com.app.test:integer/overlayable", ResourceId(0x7f020000))
+          .AddSimple(name, ResourceId(0x7f020000))
+          .AddOverlayable(name, Overlayable::Policy::kProduct)
+          .AddOverlayable(name, Overlayable::Policy::kSystem)
+          .AddOverlayable(name, Overlayable::Policy::kVendor)
           .Build();
 
-  ASSERT_TRUE(table->AddOverlayable(test::ParseNameOrDie("com.app.test:integer/overlayable"),
-                                    Overlayable{}, test::GetDiagnostics()));
+  ResourceTable output_table;
+  ASSERT_TRUE(Flatten(context_.get(), {}, table.get(), &output_table));
 
-  ResTable res_table;
-  ASSERT_TRUE(Flatten(context_.get(), {}, table.get(), &res_table));
-
-  const StringPiece16 overlayable_name(u"com.app.test:integer/overlayable");
-  uint32_t spec_flags = 0u;
-  ASSERT_THAT(res_table.identifierForName(overlayable_name.data(), overlayable_name.size(), nullptr,
-                                          0u, nullptr, 0u, &spec_flags),
-              Gt(0u));
-  EXPECT_TRUE(spec_flags & android::ResTable_typeSpec::SPEC_OVERLAYABLE);
+  auto search_result = output_table.FindResource(test::ParseNameOrDie(name));
+  ASSERT_TRUE(search_result);
+  ASSERT_THAT(search_result.value().entry, NotNull());
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations.size(), 3);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[0].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[0].policy,
+            Overlayable::Policy::kSystem);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[1].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[1].policy,
+            Overlayable::Policy::kVendor);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[2].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[2].policy,
+            Overlayable::Policy::kProduct);
 }
 
+TEST_F(TableFlattenerTest, FlattenMultipleOverlayablePolicies) {
+  std::string name_zero = "com.app.test:integer/overlayable_zero";
+  std::string name_one = "com.app.test:integer/overlayable_one";
+  std::string name_two = "com.app.test:integer/overlayable_two";
+  std::string name_three = "com.app.test:integer/overlayable_three";
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId("com.app.test", 0x7f)
+          .AddSimple(name_zero, ResourceId(0x7f020000))
+          .AddOverlayable(name_zero, Overlayable::Policy::kProduct)
+          .AddOverlayable(name_zero, Overlayable::Policy::kSystem)
+          .AddOverlayable(name_zero, Overlayable::Policy::kProductServices)
+          .AddSimple(name_one, ResourceId(0x7f020001))
+          .AddOverlayable(name_one, Overlayable::Policy::kPublic)
+          .AddOverlayable(name_one, Overlayable::Policy::kSystem)
+          .AddSimple(name_two, ResourceId(0x7f020002))
+          .AddOverlayable(name_two, Overlayable::Policy::kProduct)
+          .AddOverlayable(name_two, Overlayable::Policy::kSystem)
+          .AddOverlayable(name_two, Overlayable::Policy::kProductServices)
+          .AddSimple(name_three, ResourceId(0x7f020003))
+          .AddOverlayable(name_three, {})
+          .Build();
+
+  ResourceTable output_table;
+  ASSERT_TRUE(Flatten(context_.get(), {}, table.get(), &output_table));
+
+  auto search_result = output_table.FindResource(test::ParseNameOrDie(name_zero));
+  ASSERT_TRUE(search_result);
+  ASSERT_THAT(search_result.value().entry, NotNull());
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations.size(), 3);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[0].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[0].policy,
+            Overlayable::Policy::kSystem);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[1].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[1].policy,
+            Overlayable::Policy::kProduct);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[2].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[2].policy,
+            Overlayable::Policy::kProductServices);
+
+  search_result = output_table.FindResource(test::ParseNameOrDie(name_one));
+  ASSERT_TRUE(search_result);
+  ASSERT_THAT(search_result.value().entry, NotNull());
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations.size(), 2);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[0].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[0].policy,
+            Overlayable::Policy::kPublic);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[1].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[1].policy,
+            Overlayable::Policy::kSystem);
+
+  search_result = output_table.FindResource(test::ParseNameOrDie(name_two));
+  ASSERT_TRUE(search_result);
+  ASSERT_THAT(search_result.value().entry, NotNull());
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations.size(), 3);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[0].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[0].policy,
+            Overlayable::Policy::kSystem);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[1].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[1].policy,
+            Overlayable::Policy::kProduct);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[2].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[2].policy,
+            Overlayable::Policy::kProductServices);
+
+  search_result = output_table.FindResource(test::ParseNameOrDie(name_three));
+  ASSERT_TRUE(search_result);
+  ASSERT_THAT(search_result.value().entry, NotNull());
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations.size(), 1);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[0].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[0].policy,
+            Overlayable::Policy::kPublic);
+
+}
+
+
 }  // namespace aapt
diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp
index 3a5d585..1b6626a 100644
--- a/tools/aapt2/link/ReferenceLinker.cpp
+++ b/tools/aapt2/link/ReferenceLinker.cpp
@@ -368,7 +368,16 @@
         // Symbol state information may be lost if there is no value for the resource.
         if (entry->visibility.level != Visibility::Level::kUndefined && entry->values.empty()) {
           context->GetDiagnostics()->Error(DiagMessage(entry->visibility.source)
-                                           << "no definition for declared symbol '" << name << "'");
+                                               << "no definition for declared symbol '" << name
+                                               << "'");
+          error = true;
+        }
+
+        // Ensure that definitions for values declared as overlayable exist
+        if (!entry->overlayable_declarations.empty() && entry->values.empty()) {
+          context->GetDiagnostics()->Error(DiagMessage(entry->overlayable_declarations[0].source)
+                                           << "no definition for overlayable symbol '"
+                                           << name << "'");
           error = true;
         }
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 8e0d4ac..89b6703 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1982,6 +1982,8 @@
     public static final int WIFI_FEATURE_WPA3_SUITE_B     = 0x10000000; // WPA3-Enterprise Suite-B
     /** @hide */
     public static final int WIFI_FEATURE_OWE              = 0x20000000; // Enhanced Open
+    /** @hide */
+    public static final int WIFI_FEATURE_LOW_LATENCY      = 0x40000000; // Low Latency modes
 
     private int getSupportedFeatures() {
         try {
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index b0ed110..e0442f2 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -22,7 +22,6 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
@@ -1695,7 +1694,6 @@
      * @param listener for callback on success or failure. Can be null.
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
     public void factoryReset(@NonNull Channel c, @Nullable ActionListener listener) {
         checkChannel(c);