Merge "Flatten the transitions to tethering and hotspot." into oc-dev
diff --git a/api/current.txt b/api/current.txt
index 5697b39..143e3d8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5604,7 +5604,6 @@
     method public boolean removeAutomaticZenRule(java.lang.String);
     method public final void setInterruptionFilter(int);
     method public void setNotificationPolicy(android.app.NotificationManager.Policy);
-    method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
     method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
     field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
@@ -6625,7 +6624,7 @@
 
   public static class AssistStructure.ViewNode {
     method public float getAlpha();
-    method public java.lang.String[] getAutoFillHints();
+    method public java.lang.String[] getAutofillHints();
     method public android.view.autofill.AutofillId getAutofillId();
     method public java.lang.String[] getAutofillOptions();
     method public int getAutofillType();
@@ -6890,7 +6889,7 @@
   }
 
   public abstract class JobServiceEngine {
-    ctor public JobServiceEngine(android.content.Context);
+    ctor public JobServiceEngine(android.app.Service);
     method public final android.os.IBinder getBinder();
     method public final void jobFinished(android.app.job.JobParameters, boolean);
     method public abstract boolean onStartJob(android.app.job.JobParameters);
@@ -6994,12 +6993,12 @@
   }
 
   public class StorageStatsManager {
-    method public long getFreeBytes(java.lang.String);
-    method public long getTotalBytes(java.lang.String);
-    method public android.app.usage.ExternalStorageStats queryExternalStatsForUser(java.lang.String, android.os.UserHandle);
-    method public android.app.usage.StorageStats queryStatsForPackage(java.lang.String, java.lang.String, android.os.UserHandle);
-    method public android.app.usage.StorageStats queryStatsForUid(java.lang.String, int);
-    method public android.app.usage.StorageStats queryStatsForUser(java.lang.String, android.os.UserHandle);
+    method public long getFreeBytes(java.util.UUID) throws java.io.IOException;
+    method public long getTotalBytes(java.util.UUID) throws java.io.IOException;
+    method public android.app.usage.ExternalStorageStats queryExternalStatsForUser(java.util.UUID, android.os.UserHandle) throws java.io.IOException;
+    method public android.app.usage.StorageStats queryStatsForPackage(java.util.UUID, java.lang.String, android.os.UserHandle) throws java.io.IOException, android.content.pm.PackageManager.NameNotFoundException;
+    method public android.app.usage.StorageStats queryStatsForUid(java.util.UUID, int) throws java.io.IOException;
+    method public android.app.usage.StorageStats queryStatsForUser(java.util.UUID, android.os.UserHandle) throws java.io.IOException;
   }
 
   public final class UsageEvents implements android.os.Parcelable {
@@ -10217,12 +10216,12 @@
     field public java.lang.String[] splitNames;
     field public java.lang.String[] splitPublicSourceDirs;
     field public java.lang.String[] splitSourceDirs;
+    field public java.util.UUID storageUuid;
     field public int targetSdkVersion;
     field public java.lang.String taskAffinity;
     field public int theme;
     field public int uiOptions;
     field public int uid;
-    field public java.lang.String volumeUuid;
   }
 
   public static class ApplicationInfo.DisplayNameComparator implements java.util.Comparator {
@@ -10341,7 +10340,7 @@
 
   public class LauncherApps {
     method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(java.lang.String, android.os.UserHandle);
-    method public android.content.pm.ApplicationInfo getApplicationInfo(java.lang.String, int, android.os.UserHandle);
+    method public android.content.pm.ApplicationInfo getApplicationInfo(java.lang.String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
     method public android.content.pm.LauncherApps.PinItemRequest getPinItemRequest(android.content.Intent);
     method public java.util.List<android.os.UserHandle> getProfiles();
     method public android.graphics.drawable.Drawable getShortcutBadgedIconDrawable(android.content.pm.ShortcutInfo, int);
@@ -22979,11 +22978,12 @@
     method public void setMaxDuration(int) throws java.lang.IllegalArgumentException;
     method public void setMaxFileSize(long) throws java.lang.IllegalArgumentException;
     method public void setNextOutputFile(java.io.FileDescriptor) throws java.io.IOException, java.lang.IllegalStateException;
-    method public void setNextOutputFile(java.lang.String) throws java.io.IOException, java.lang.IllegalStateException;
+    method public void setNextOutputFile(java.io.File) throws java.io.IOException, java.lang.IllegalStateException;
     method public void setOnErrorListener(android.media.MediaRecorder.OnErrorListener);
     method public void setOnInfoListener(android.media.MediaRecorder.OnInfoListener);
     method public void setOrientationHint(int);
     method public void setOutputFile(java.io.FileDescriptor) throws java.lang.IllegalStateException;
+    method public void setOutputFile(java.io.File);
     method public void setOutputFile(java.lang.String) throws java.lang.IllegalStateException;
     method public void setOutputFormat(int) throws java.lang.IllegalStateException;
     method public void setPreviewDisplay(android.view.Surface);
@@ -24010,7 +24010,6 @@
     method public android.content.ComponentName getServiceComponent();
     method public android.media.session.MediaSession.Token getSessionToken();
     method public boolean isConnected();
-    method public void search(java.lang.String, android.os.Bundle, android.media.browse.MediaBrowser.SearchCallback);
     method public void subscribe(java.lang.String, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void subscribe(java.lang.String, android.os.Bundle, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void unsubscribe(java.lang.String);
@@ -24046,12 +24045,6 @@
     field public static final int FLAG_PLAYABLE = 2; // 0x2
   }
 
-  public static abstract class MediaBrowser.SearchCallback {
-    ctor public MediaBrowser.SearchCallback();
-    method public void onError(java.lang.String, android.os.Bundle);
-    method public void onSearchResult(java.lang.String, android.os.Bundle, java.util.List<android.media.browse.MediaBrowser.MediaItem>);
-  }
-
   public static abstract class MediaBrowser.SubscriptionCallback {
     ctor public MediaBrowser.SubscriptionCallback();
     method public void onChildrenLoaded(java.lang.String, java.util.List<android.media.browse.MediaBrowser.MediaItem>);
@@ -24260,8 +24253,6 @@
 
   public final class MediaController {
     ctor public MediaController(android.content.Context, android.media.session.MediaSession.Token);
-    method public void addQueueItem(android.media.MediaDescription);
-    method public void addQueueItem(android.media.MediaDescription, int);
     method public void adjustVolume(int, int);
     method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
     method public android.os.Bundle getExtras();
@@ -24273,15 +24264,11 @@
     method public java.util.List<android.media.session.MediaSession.QueueItem> getQueue();
     method public java.lang.CharSequence getQueueTitle();
     method public int getRatingType();
-    method public int getRepeatMode();
     method public android.app.PendingIntent getSessionActivity();
     method public android.media.session.MediaSession.Token getSessionToken();
     method public android.media.session.MediaController.TransportControls getTransportControls();
-    method public boolean isShuffleModeEnabled();
     method public void registerCallback(android.media.session.MediaController.Callback);
     method public void registerCallback(android.media.session.MediaController.Callback, android.os.Handler);
-    method public void removeQueueItem(android.media.MediaDescription);
-    method public void removeQueueItemAt(int);
     method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void setVolumeTo(int, int);
     method public void unregisterCallback(android.media.session.MediaController.Callback);
@@ -24295,10 +24282,8 @@
     method public void onPlaybackStateChanged(android.media.session.PlaybackState);
     method public void onQueueChanged(java.util.List<android.media.session.MediaSession.QueueItem>);
     method public void onQueueTitleChanged(java.lang.CharSequence);
-    method public void onRepeatModeChanged(int);
     method public void onSessionDestroyed();
     method public void onSessionEvent(java.lang.String, android.os.Bundle);
-    method public void onShuffleModeChanged(boolean);
   }
 
   public static final class MediaController.PlaybackInfo {
@@ -24327,8 +24312,6 @@
     method public void sendCustomAction(android.media.session.PlaybackState.CustomAction, android.os.Bundle);
     method public void sendCustomAction(java.lang.String, android.os.Bundle);
     method public void setRating(android.media.Rating);
-    method public void setRepeatMode(int);
-    method public void setShuffleModeEnabled(boolean);
     method public void skipToNext();
     method public void skipToPrevious();
     method public void skipToQueueItem(long);
@@ -24355,18 +24338,13 @@
     method public void setQueue(java.util.List<android.media.session.MediaSession.QueueItem>);
     method public void setQueueTitle(java.lang.CharSequence);
     method public void setRatingType(int);
-    method public void setRepeatMode(int);
     method public void setSessionActivity(android.app.PendingIntent);
-    method public void setShuffleModeEnabled(boolean);
     field public static final deprecated int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
-    field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
     field public static final deprecated int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
   }
 
   public static abstract class MediaSession.Callback {
     ctor public MediaSession.Callback();
-    method public void onAddQueueItem(android.media.MediaDescription);
-    method public void onAddQueueItem(android.media.MediaDescription, int);
     method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void onCustomAction(java.lang.String, android.os.Bundle);
     method public void onFastForward();
@@ -24380,13 +24358,9 @@
     method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
     method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
     method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
-    method public void onRemoveQueueItem(android.media.MediaDescription);
-    method public void onRemoveQueueItemAt(int);
     method public void onRewind();
     method public void onSeekTo(long);
     method public void onSetRating(android.media.Rating);
-    method public void onSetRepeatMode(int);
-    method public void onSetShuffleModeEnabled(boolean);
     method public void onSkipToNext();
     method public void onSkipToPrevious();
     method public void onSkipToQueueItem(long);
@@ -24447,17 +24421,12 @@
     field public static final long ACTION_REWIND = 8L; // 0x8L
     field public static final long ACTION_SEEK_TO = 256L; // 0x100L
     field public static final long ACTION_SET_RATING = 128L; // 0x80L
-    field public static final long ACTION_SET_REPEAT_MODE = 262144L; // 0x40000L
-    field public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 524288L; // 0x80000L
     field public static final long ACTION_SKIP_TO_NEXT = 32L; // 0x20L
     field public static final long ACTION_SKIP_TO_PREVIOUS = 16L; // 0x10L
     field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
     field public static final long ACTION_STOP = 1L; // 0x1L
     field public static final android.os.Parcelable.Creator<android.media.session.PlaybackState> CREATOR;
     field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL
-    field public static final int REPEAT_MODE_ALL = 2; // 0x2
-    field public static final int REPEAT_MODE_NONE = 0; // 0x0
-    field public static final int REPEAT_MODE_ONE = 1; // 0x1
     field public static final int STATE_BUFFERING = 6; // 0x6
     field public static final int STATE_CONNECTING = 8; // 0x8
     field public static final int STATE_ERROR = 7; // 0x7
@@ -30801,6 +30770,7 @@
     method public android.util.SizeF getSizeF(java.lang.String);
     method public <T extends android.os.Parcelable> android.util.SparseArray<T> getSparseParcelableArray(java.lang.String);
     method public java.util.ArrayList<java.lang.String> getStringArrayList(java.lang.String);
+    method public java.util.UUID getUuid(java.lang.String);
     method public boolean hasFileDescriptors();
     method public void putAll(android.os.Bundle);
     method public void putBinder(java.lang.String, android.os.IBinder);
@@ -30825,6 +30795,7 @@
     method public void putSizeF(java.lang.String, android.util.SizeF);
     method public void putSparseParcelableArray(java.lang.String, android.util.SparseArray<? extends android.os.Parcelable>);
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
+    method public void putUuid(java.lang.String, java.util.UUID);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
     method public void writeToParcel(android.os.Parcel, int);
@@ -31354,6 +31325,7 @@
     method public final <T> void readTypedArray(T[], android.os.Parcelable.Creator<T>);
     method public final <T> void readTypedList(java.util.List<T>, android.os.Parcelable.Creator<T>);
     method public final <T> T readTypedObject(android.os.Parcelable.Creator<T>);
+    method public final java.util.UUID readUuid();
     method public final java.lang.Object readValue(java.lang.ClassLoader);
     method public final void recycle();
     method public final void setDataCapacity(int);
@@ -31399,6 +31371,7 @@
     method public final <T extends android.os.Parcelable> void writeTypedArray(T[], int);
     method public final <T extends android.os.Parcelable> void writeTypedList(java.util.List<T>);
     method public final <T extends android.os.Parcelable> void writeTypedObject(T, int);
+    method public final void writeUuid(java.util.UUID);
     method public final void writeValue(java.lang.Object);
     field public static final android.os.Parcelable.Creator<java.lang.String> STRING_CREATOR;
   }
@@ -32029,15 +32002,16 @@
   }
 
   public class StorageManager {
-    method public void allocateBytes(java.io.File, long, int) throws java.io.IOException;
+    method public void allocateBytes(java.util.UUID, long, int) throws java.io.IOException;
     method public void allocateBytes(java.io.FileDescriptor, long, int) throws java.io.IOException;
-    method public long getAllocatableBytes(java.io.File, int) throws java.io.IOException;
-    method public long getCacheQuotaBytes(java.io.File);
-    method public long getCacheSizeBytes(java.io.File);
+    method public long getAllocatableBytes(java.util.UUID, int) throws java.io.IOException;
+    method public long getCacheQuotaBytes(java.util.UUID) throws java.io.IOException;
+    method public long getCacheSizeBytes(java.util.UUID) throws java.io.IOException;
     method public java.lang.String getMountedObbPath(java.lang.String);
     method public android.os.storage.StorageVolume getPrimaryStorageVolume();
     method public android.os.storage.StorageVolume getStorageVolume(java.io.File);
     method public java.util.List<android.os.storage.StorageVolume> getStorageVolumes();
+    method public java.util.UUID getUuidForPath(java.io.File) throws java.io.IOException;
     method public boolean isCacheBehaviorGroup(java.io.File) throws java.io.IOException;
     method public boolean isCacheBehaviorTombstone(java.io.File) throws java.io.IOException;
     method public boolean isEncrypted(java.io.File);
@@ -32049,7 +32023,10 @@
     method public void setCacheBehaviorTombstone(java.io.File, boolean) throws java.io.IOException;
     method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener);
     field public static final java.lang.String ACTION_MANAGE_STORAGE = "android.os.storage.action.MANAGE_STORAGE";
+    field public static final java.lang.String EXTRA_REQUESTED_BYTES = "android.os.storage.extra.REQUESTED_BYTES";
+    field public static final java.lang.String EXTRA_UUID = "android.os.storage.extra.UUID";
     field public static final int FLAG_ALLOCATE_AGGRESSIVE = 1; // 0x1
+    field public static final java.util.UUID UUID_DEFAULT;
   }
 
   public final class StorageVolume implements android.os.Parcelable {
@@ -35486,6 +35463,16 @@
     field public static final java.lang.String SUBSCRIPTION_ID = "pending_sub_id";
   }
 
+  public static final class Telephony.ServiceStateTable {
+    method public static android.net.Uri getUriForSubId(int);
+    method public static android.net.Uri getUriForSubIdAndField(int, java.lang.String);
+    field public static final java.lang.String AUTHORITY = "service-state";
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String IS_MANUAL_NETWORK_SELECTION = "is_manual_network_selection";
+    field public static final java.lang.String VOICE_OPERATOR_NUMERIC = "voice_operator_numeric";
+    field public static final java.lang.String VOICE_REG_STATE = "voice_reg_state";
+  }
+
   public static final class Telephony.Sms implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
     method public static java.lang.String getDefaultSmsPackage(android.content.Context);
     field public static final android.net.Uri CONTENT_URI;
@@ -37149,6 +37136,7 @@
     method public android.service.autofill.SaveInfo.Builder setDescription(java.lang.CharSequence);
     method public android.service.autofill.SaveInfo.Builder setNegativeAction(java.lang.CharSequence, android.content.IntentSender);
     method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
+    method public android.service.autofill.SaveInfo.Builder setSaveOnAllViewsInvisible(boolean);
   }
 
   public final class SaveRequest implements android.os.Parcelable {
@@ -37340,7 +37328,6 @@
     method public abstract void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>);
     method public void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>, android.os.Bundle);
     method public void onLoadItem(java.lang.String, android.service.media.MediaBrowserService.Result<android.media.browse.MediaBrowser.MediaItem>);
-    method public void onSearch(java.lang.String, android.os.Bundle, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>);
     method public void setSessionToken(android.media.session.MediaSession.Token);
     field public static final java.lang.String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService";
   }
@@ -37420,16 +37407,16 @@
     method public final int getCurrentInterruptionFilter();
     method public final int getCurrentListenerHints();
     method public android.service.notification.NotificationListenerService.RankingMap getCurrentRanking();
-    method public final java.util.List<android.app.NotificationChannelGroup> getNotificationChannelGroups(java.lang.String);
-    method public final java.util.List<android.app.NotificationChannel> getNotificationChannels(java.lang.String);
+    method public final java.util.List<android.app.NotificationChannelGroup> getNotificationChannelGroups(java.lang.String, android.os.UserHandle);
+    method public final java.util.List<android.app.NotificationChannel> getNotificationChannels(java.lang.String, android.os.UserHandle);
     method public final android.service.notification.StatusBarNotification[] getSnoozedNotifications();
     method public android.os.IBinder onBind(android.content.Intent);
     method public void onInterruptionFilterChanged(int);
     method public void onListenerConnected();
     method public void onListenerDisconnected();
     method public void onListenerHintsChanged(int);
-    method public void onNotificationChannelGroupModified(java.lang.String, android.app.NotificationChannelGroup, int);
-    method public void onNotificationChannelModified(java.lang.String, android.app.NotificationChannel, int);
+    method public void onNotificationChannelGroupModified(java.lang.String, android.os.UserHandle, android.app.NotificationChannelGroup, int);
+    method public void onNotificationChannelModified(java.lang.String, android.os.UserHandle, android.app.NotificationChannel, int);
     method public void onNotificationPosted(android.service.notification.StatusBarNotification);
     method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
     method public void onNotificationRankingUpdate(android.service.notification.NotificationListenerService.RankingMap);
@@ -37442,7 +37429,7 @@
     method public final void requestUnbind();
     method public final void setNotificationsShown(java.lang.String[]);
     method public final void snoozeNotification(java.lang.String, long);
-    method public final void updateNotificationChannel(java.lang.String, android.app.NotificationChannel);
+    method public final void updateNotificationChannel(java.lang.String, android.os.UserHandle, android.app.NotificationChannel);
     field public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 4; // 0x4
     field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
     field public static final int HINT_HOST_DISABLE_NOTIFICATION_EFFECTS = 2; // 0x2
@@ -39472,6 +39459,8 @@
     field public static final java.lang.String ACTION_CONFIGURE_PHONE_ACCOUNT = "android.telecom.action.CONFIGURE_PHONE_ACCOUNT";
     field public static final java.lang.String ACTION_DEFAULT_DIALER_CHANGED = "android.telecom.action.DEFAULT_DIALER_CHANGED";
     field public static final deprecated java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
+    field public static final java.lang.String ACTION_PHONE_ACCOUNT_REGISTERED = "android.telecom.action.PHONE_ACCOUNT_REGISTERED";
+    field public static final java.lang.String ACTION_PHONE_ACCOUNT_UNREGISTERED = "android.telecom.action.PHONE_ACCOUNT_UNREGISTERED";
     field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
     field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS";
     field public static final java.lang.String ACTION_SHOW_MISSED_CALLS_NOTIFICATION = "android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION";
@@ -40916,7 +40905,6 @@
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
     method public android.content.ComponentName startService(android.content.Intent);
-    method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
     method public boolean stopService(android.content.Intent);
     method public void unbindService(android.content.ServiceConnection);
     method public void unregisterReceiver(android.content.BroadcastReceiver);
@@ -49730,6 +49718,7 @@
     method public java.lang.String getFormat();
     method public android.widget.Chronometer.OnChronometerTickListener getOnChronometerTickListener();
     method public boolean isCountDown();
+    method public boolean isTheFinalCountDown();
     method public void setBase(long);
     method public void setCountDown(boolean);
     method public void setFormat(java.lang.String);
@@ -55399,6 +55388,7 @@
     method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.util.List<java.lang.Class<?>>);
     method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.lang.Class<?>...);
     method public static java.lang.invoke.MethodHandle exactInvoker(java.lang.invoke.MethodType);
+    method public static java.lang.invoke.MethodHandle explicitCastArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType);
     method public static java.lang.invoke.MethodHandle filterArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle...);
     method public static java.lang.invoke.MethodHandle filterReturnValue(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
     method public static java.lang.invoke.MethodHandle foldArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
diff --git a/api/removed.txt b/api/removed.txt
index 82705fd..0f5b81a 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -5,10 +5,6 @@
     method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
   }
 
-  public static class Notification.Builder {
-    method public deprecated android.app.Notification.Builder chooseBadgeIcon(int);
-  }
-
   public final class RecoverableSecurityException extends java.lang.SecurityException implements android.os.Parcelable {
     method public deprecated void showAsNotification(android.content.Context);
   }
@@ -26,6 +22,20 @@
 
 }
 
+package android.app.usage {
+
+  public class StorageStatsManager {
+    method public deprecated long getFreeBytes(java.lang.String) throws java.io.IOException;
+    method public deprecated long getTotalBytes(java.lang.String) throws java.io.IOException;
+    method public deprecated boolean isQuotaSupported(java.lang.String);
+    method public deprecated android.app.usage.ExternalStorageStats queryExternalStatsForUser(java.lang.String, android.os.UserHandle) throws java.io.IOException;
+    method public deprecated android.app.usage.StorageStats queryStatsForPackage(java.lang.String, java.lang.String, android.os.UserHandle) throws java.io.IOException, android.content.pm.PackageManager.NameNotFoundException;
+    method public deprecated android.app.usage.StorageStats queryStatsForUid(java.lang.String, int) throws java.io.IOException;
+    method public deprecated android.app.usage.StorageStats queryStatsForUser(java.lang.String, android.os.UserHandle) throws java.io.IOException;
+  }
+
+}
+
 package android.content {
 
   public abstract class Context {
@@ -41,6 +51,10 @@
 
 package android.content.pm {
 
+  public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
+    field public deprecated java.lang.String volumeUuid;
+  }
+
   public class ComponentInfo extends android.content.pm.PackageItemInfo {
     field public deprecated boolean encryptionAware;
   }
@@ -184,10 +198,14 @@
 package android.os.storage {
 
   public class StorageManager {
-    method public deprecated long getCacheQuotaBytes();
-    method public deprecated long getCacheSizeBytes();
-    method public deprecated long getExternalCacheQuotaBytes();
-    method public deprecated long getExternalCacheSizeBytes();
+    method public deprecated void allocateBytes(java.io.File, long, int) throws java.io.IOException;
+    method public deprecated long getAllocatableBytes(java.io.File, int) throws java.io.IOException;
+    method public deprecated long getCacheQuotaBytes(java.io.File) throws java.io.IOException;
+    method public deprecated long getCacheQuotaBytes() throws java.io.IOException;
+    method public deprecated long getCacheSizeBytes(java.io.File) throws java.io.IOException;
+    method public deprecated long getCacheSizeBytes() throws java.io.IOException;
+    method public deprecated long getExternalCacheQuotaBytes() throws java.io.IOException;
+    method public deprecated long getExternalCacheSizeBytes() throws java.io.IOException;
     method public android.os.storage.StorageVolume getPrimaryVolume();
     method public android.os.storage.StorageVolume[] getVolumeList();
     method public deprecated boolean isCacheBehaviorAtomic(java.io.File) throws java.io.IOException;
diff --git a/api/system-current.txt b/api/system-current.txt
index 8b2ac55..e014809 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1197,6 +1197,8 @@
     field public static final int requiredFeature = 16844119; // 0x1010557
     field public static final int requiredForAllUsers = 16843728; // 0x10103d0
     field public static final int requiredNotFeature = 16844120; // 0x1010558
+    field public static final int requiredSystemPropertyName = 16844136; // 0x1010568
+    field public static final int requiredSystemPropertyValue = 16844137; // 0x1010569
     field public static final int requiresFadingEdge = 16843685; // 0x10103a5
     field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364
     field public static final int resizeClip = 16843983; // 0x10104cf
@@ -5804,7 +5806,6 @@
     method public boolean removeAutomaticZenRule(java.lang.String);
     method public final void setInterruptionFilter(int);
     method public void setNotificationPolicy(android.app.NotificationManager.Policy);
-    method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
     method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
     field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
@@ -6868,7 +6869,7 @@
 
   public static class AssistStructure.ViewNode {
     method public float getAlpha();
-    method public java.lang.String[] getAutoFillHints();
+    method public java.lang.String[] getAutofillHints();
     method public android.view.autofill.AutofillId getAutofillId();
     method public java.lang.String[] getAutofillOptions();
     method public int getAutofillType();
@@ -7324,7 +7325,7 @@
   }
 
   public abstract class JobServiceEngine {
-    ctor public JobServiceEngine(android.content.Context);
+    ctor public JobServiceEngine(android.app.Service);
     method public final android.os.IBinder getBinder();
     method public final void jobFinished(android.app.job.JobParameters, boolean);
     method public abstract boolean onStartJob(android.app.job.JobParameters);
@@ -7457,12 +7458,12 @@
   }
 
   public class StorageStatsManager {
-    method public long getFreeBytes(java.lang.String);
-    method public long getTotalBytes(java.lang.String);
-    method public android.app.usage.ExternalStorageStats queryExternalStatsForUser(java.lang.String, android.os.UserHandle);
-    method public android.app.usage.StorageStats queryStatsForPackage(java.lang.String, java.lang.String, android.os.UserHandle);
-    method public android.app.usage.StorageStats queryStatsForUid(java.lang.String, int);
-    method public android.app.usage.StorageStats queryStatsForUser(java.lang.String, android.os.UserHandle);
+    method public long getFreeBytes(java.util.UUID) throws java.io.IOException;
+    method public long getTotalBytes(java.util.UUID) throws java.io.IOException;
+    method public android.app.usage.ExternalStorageStats queryExternalStatsForUser(java.util.UUID, android.os.UserHandle) throws java.io.IOException;
+    method public android.app.usage.StorageStats queryStatsForPackage(java.util.UUID, java.lang.String, android.os.UserHandle) throws java.io.IOException, android.content.pm.PackageManager.NameNotFoundException;
+    method public android.app.usage.StorageStats queryStatsForUid(java.util.UUID, int) throws java.io.IOException;
+    method public android.app.usage.StorageStats queryStatsForUser(java.util.UUID, android.os.UserHandle) throws java.io.IOException;
   }
 
   public final class UsageEvents implements android.os.Parcelable {
@@ -10790,12 +10791,12 @@
     field public java.lang.String[] splitNames;
     field public java.lang.String[] splitPublicSourceDirs;
     field public java.lang.String[] splitSourceDirs;
+    field public java.util.UUID storageUuid;
     field public int targetSdkVersion;
     field public java.lang.String taskAffinity;
     field public int theme;
     field public int uiOptions;
     field public int uid;
-    field public java.lang.String volumeUuid;
   }
 
   public static class ApplicationInfo.DisplayNameComparator implements java.util.Comparator {
@@ -11004,7 +11005,7 @@
 
   public class LauncherApps {
     method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(java.lang.String, android.os.UserHandle);
-    method public android.content.pm.ApplicationInfo getApplicationInfo(java.lang.String, int, android.os.UserHandle);
+    method public android.content.pm.ApplicationInfo getApplicationInfo(java.lang.String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
     method public android.content.pm.LauncherApps.PinItemRequest getPinItemRequest(android.content.Intent);
     method public java.util.List<android.os.UserHandle> getProfiles();
     method public android.graphics.drawable.Drawable getShortcutBadgedIconDrawable(android.content.pm.ShortcutInfo, int);
@@ -11274,6 +11275,7 @@
     method public abstract byte[] getInstantAppCookie();
     method public abstract int getInstantAppCookieMaxSize();
     method public abstract android.graphics.drawable.Drawable getInstantAppIcon(java.lang.String);
+    method public abstract android.content.ComponentName getInstantAppInstallerComponent();
     method public abstract android.content.ComponentName getInstantAppResolverSettingsComponent();
     method public abstract java.util.List<android.content.pm.InstantAppInfo> getInstantApps();
     method public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -24812,11 +24814,12 @@
     method public void setMaxDuration(int) throws java.lang.IllegalArgumentException;
     method public void setMaxFileSize(long) throws java.lang.IllegalArgumentException;
     method public void setNextOutputFile(java.io.FileDescriptor) throws java.io.IOException, java.lang.IllegalStateException;
-    method public void setNextOutputFile(java.lang.String) throws java.io.IOException, java.lang.IllegalStateException;
+    method public void setNextOutputFile(java.io.File) throws java.io.IOException, java.lang.IllegalStateException;
     method public void setOnErrorListener(android.media.MediaRecorder.OnErrorListener);
     method public void setOnInfoListener(android.media.MediaRecorder.OnInfoListener);
     method public void setOrientationHint(int);
     method public void setOutputFile(java.io.FileDescriptor) throws java.lang.IllegalStateException;
+    method public void setOutputFile(java.io.File);
     method public void setOutputFile(java.lang.String) throws java.lang.IllegalStateException;
     method public void setOutputFormat(int) throws java.lang.IllegalStateException;
     method public void setPreviewDisplay(android.view.Surface);
@@ -25929,7 +25932,6 @@
     method public android.content.ComponentName getServiceComponent();
     method public android.media.session.MediaSession.Token getSessionToken();
     method public boolean isConnected();
-    method public void search(java.lang.String, android.os.Bundle, android.media.browse.MediaBrowser.SearchCallback);
     method public void subscribe(java.lang.String, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void subscribe(java.lang.String, android.os.Bundle, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void unsubscribe(java.lang.String);
@@ -25965,12 +25967,6 @@
     field public static final int FLAG_PLAYABLE = 2; // 0x2
   }
 
-  public static abstract class MediaBrowser.SearchCallback {
-    ctor public MediaBrowser.SearchCallback();
-    method public void onError(java.lang.String, android.os.Bundle);
-    method public void onSearchResult(java.lang.String, android.os.Bundle, java.util.List<android.media.browse.MediaBrowser.MediaItem>);
-  }
-
   public static abstract class MediaBrowser.SubscriptionCallback {
     ctor public MediaBrowser.SubscriptionCallback();
     method public void onChildrenLoaded(java.lang.String, java.util.List<android.media.browse.MediaBrowser.MediaItem>);
@@ -26179,8 +26175,6 @@
 
   public final class MediaController {
     ctor public MediaController(android.content.Context, android.media.session.MediaSession.Token);
-    method public void addQueueItem(android.media.MediaDescription);
-    method public void addQueueItem(android.media.MediaDescription, int);
     method public void adjustVolume(int, int);
     method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
     method public android.os.Bundle getExtras();
@@ -26192,15 +26186,11 @@
     method public java.util.List<android.media.session.MediaSession.QueueItem> getQueue();
     method public java.lang.CharSequence getQueueTitle();
     method public int getRatingType();
-    method public int getRepeatMode();
     method public android.app.PendingIntent getSessionActivity();
     method public android.media.session.MediaSession.Token getSessionToken();
     method public android.media.session.MediaController.TransportControls getTransportControls();
-    method public boolean isShuffleModeEnabled();
     method public void registerCallback(android.media.session.MediaController.Callback);
     method public void registerCallback(android.media.session.MediaController.Callback, android.os.Handler);
-    method public void removeQueueItem(android.media.MediaDescription);
-    method public void removeQueueItemAt(int);
     method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void setVolumeTo(int, int);
     method public void unregisterCallback(android.media.session.MediaController.Callback);
@@ -26214,10 +26204,8 @@
     method public void onPlaybackStateChanged(android.media.session.PlaybackState);
     method public void onQueueChanged(java.util.List<android.media.session.MediaSession.QueueItem>);
     method public void onQueueTitleChanged(java.lang.CharSequence);
-    method public void onRepeatModeChanged(int);
     method public void onSessionDestroyed();
     method public void onSessionEvent(java.lang.String, android.os.Bundle);
-    method public void onShuffleModeChanged(boolean);
   }
 
   public static final class MediaController.PlaybackInfo {
@@ -26246,8 +26234,6 @@
     method public void sendCustomAction(android.media.session.PlaybackState.CustomAction, android.os.Bundle);
     method public void sendCustomAction(java.lang.String, android.os.Bundle);
     method public void setRating(android.media.Rating);
-    method public void setRepeatMode(int);
-    method public void setShuffleModeEnabled(boolean);
     method public void skipToNext();
     method public void skipToPrevious();
     method public void skipToQueueItem(long);
@@ -26274,18 +26260,13 @@
     method public void setQueue(java.util.List<android.media.session.MediaSession.QueueItem>);
     method public void setQueueTitle(java.lang.CharSequence);
     method public void setRatingType(int);
-    method public void setRepeatMode(int);
     method public void setSessionActivity(android.app.PendingIntent);
-    method public void setShuffleModeEnabled(boolean);
     field public static final deprecated int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
-    field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
     field public static final deprecated int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
   }
 
   public static abstract class MediaSession.Callback {
     ctor public MediaSession.Callback();
-    method public void onAddQueueItem(android.media.MediaDescription);
-    method public void onAddQueueItem(android.media.MediaDescription, int);
     method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void onCustomAction(java.lang.String, android.os.Bundle);
     method public void onFastForward();
@@ -26299,13 +26280,9 @@
     method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
     method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
     method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
-    method public void onRemoveQueueItem(android.media.MediaDescription);
-    method public void onRemoveQueueItemAt(int);
     method public void onRewind();
     method public void onSeekTo(long);
     method public void onSetRating(android.media.Rating);
-    method public void onSetRepeatMode(int);
-    method public void onSetShuffleModeEnabled(boolean);
     method public void onSkipToNext();
     method public void onSkipToPrevious();
     method public void onSkipToQueueItem(long);
@@ -26376,17 +26353,12 @@
     field public static final long ACTION_REWIND = 8L; // 0x8L
     field public static final long ACTION_SEEK_TO = 256L; // 0x100L
     field public static final long ACTION_SET_RATING = 128L; // 0x80L
-    field public static final long ACTION_SET_REPEAT_MODE = 262144L; // 0x40000L
-    field public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 524288L; // 0x80000L
     field public static final long ACTION_SKIP_TO_NEXT = 32L; // 0x20L
     field public static final long ACTION_SKIP_TO_PREVIOUS = 16L; // 0x10L
     field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
     field public static final long ACTION_STOP = 1L; // 0x1L
     field public static final android.os.Parcelable.Creator<android.media.session.PlaybackState> CREATOR;
     field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL
-    field public static final int REPEAT_MODE_ALL = 2; // 0x2
-    field public static final int REPEAT_MODE_NONE = 0; // 0x0
-    field public static final int REPEAT_MODE_ONE = 1; // 0x1
     field public static final int STATE_BUFFERING = 6; // 0x6
     field public static final int STATE_CONNECTING = 8; // 0x8
     field public static final int STATE_ERROR = 7; // 0x7
@@ -33557,6 +33529,7 @@
     method public android.util.SizeF getSizeF(java.lang.String);
     method public <T extends android.os.Parcelable> android.util.SparseArray<T> getSparseParcelableArray(java.lang.String);
     method public java.util.ArrayList<java.lang.String> getStringArrayList(java.lang.String);
+    method public java.util.UUID getUuid(java.lang.String);
     method public boolean hasFileDescriptors();
     method public void putAll(android.os.Bundle);
     method public void putBinder(java.lang.String, android.os.IBinder);
@@ -33581,6 +33554,7 @@
     method public void putSizeF(java.lang.String, android.util.SizeF);
     method public void putSparseParcelableArray(java.lang.String, android.util.SparseArray<? extends android.os.Parcelable>);
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
+    method public void putUuid(java.lang.String, java.util.UUID);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
     method public void writeToParcel(android.os.Parcel, int);
@@ -34140,6 +34114,7 @@
     method public final <T> void readTypedArray(T[], android.os.Parcelable.Creator<T>);
     method public final <T> void readTypedList(java.util.List<T>, android.os.Parcelable.Creator<T>);
     method public final <T> T readTypedObject(android.os.Parcelable.Creator<T>);
+    method public final java.util.UUID readUuid();
     method public final java.lang.Object readValue(java.lang.ClassLoader);
     method public final void recycle();
     method public final void setDataCapacity(int);
@@ -34185,6 +34160,7 @@
     method public final <T extends android.os.Parcelable> void writeTypedArray(T[], int);
     method public final <T extends android.os.Parcelable> void writeTypedList(java.util.List<T>);
     method public final <T extends android.os.Parcelable> void writeTypedObject(T, int);
+    method public final void writeUuid(java.util.UUID);
     method public final void writeValue(java.lang.Object);
     field public static final android.os.Parcelable.Creator<java.lang.String> STRING_CREATOR;
   }
@@ -34920,15 +34896,16 @@
   }
 
   public class StorageManager {
-    method public void allocateBytes(java.io.File, long, int) throws java.io.IOException;
+    method public void allocateBytes(java.util.UUID, long, int) throws java.io.IOException;
     method public void allocateBytes(java.io.FileDescriptor, long, int) throws java.io.IOException;
-    method public long getAllocatableBytes(java.io.File, int) throws java.io.IOException;
-    method public long getCacheQuotaBytes(java.io.File);
-    method public long getCacheSizeBytes(java.io.File);
+    method public long getAllocatableBytes(java.util.UUID, int) throws java.io.IOException;
+    method public long getCacheQuotaBytes(java.util.UUID) throws java.io.IOException;
+    method public long getCacheSizeBytes(java.util.UUID) throws java.io.IOException;
     method public java.lang.String getMountedObbPath(java.lang.String);
     method public android.os.storage.StorageVolume getPrimaryStorageVolume();
     method public android.os.storage.StorageVolume getStorageVolume(java.io.File);
     method public java.util.List<android.os.storage.StorageVolume> getStorageVolumes();
+    method public java.util.UUID getUuidForPath(java.io.File) throws java.io.IOException;
     method public boolean isCacheBehaviorGroup(java.io.File) throws java.io.IOException;
     method public boolean isCacheBehaviorTombstone(java.io.File) throws java.io.IOException;
     method public boolean isEncrypted(java.io.File);
@@ -34940,7 +34917,10 @@
     method public void setCacheBehaviorTombstone(java.io.File, boolean) throws java.io.IOException;
     method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener);
     field public static final java.lang.String ACTION_MANAGE_STORAGE = "android.os.storage.action.MANAGE_STORAGE";
+    field public static final java.lang.String EXTRA_REQUESTED_BYTES = "android.os.storage.extra.REQUESTED_BYTES";
+    field public static final java.lang.String EXTRA_UUID = "android.os.storage.extra.UUID";
     field public static final int FLAG_ALLOCATE_AGGRESSIVE = 1; // 0x1
+    field public static final java.util.UUID UUID_DEFAULT;
   }
 
   public final class StorageVolume implements android.os.Parcelable {
@@ -38134,7 +38114,6 @@
     field public static final deprecated java.lang.String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
     field public static final java.lang.String MODE_RINGER = "mode_ringer";
     field public static final java.lang.String NETWORK_PREFERENCE = "network_preference";
-    field public static final java.lang.String NETWORK_RECOMMENDATIONS_ENABLED = "network_recommendations_enabled";
     field public static final java.lang.String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update";
     field public static final java.lang.String RADIO_BLUETOOTH = "bluetooth";
     field public static final java.lang.String RADIO_CELL = "cell";
@@ -38584,6 +38563,16 @@
     field public static final java.lang.String SUBSCRIPTION_ID = "pending_sub_id";
   }
 
+  public static final class Telephony.ServiceStateTable {
+    method public static android.net.Uri getUriForSubId(int);
+    method public static android.net.Uri getUriForSubIdAndField(int, java.lang.String);
+    field public static final java.lang.String AUTHORITY = "service-state";
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String IS_MANUAL_NETWORK_SELECTION = "is_manual_network_selection";
+    field public static final java.lang.String VOICE_OPERATOR_NUMERIC = "voice_operator_numeric";
+    field public static final java.lang.String VOICE_REG_STATE = "voice_reg_state";
+  }
+
   public static final class Telephony.Sms implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
     method public static java.lang.String getDefaultSmsPackage(android.content.Context);
     field public static final android.net.Uri CONTENT_URI;
@@ -40259,6 +40248,7 @@
     method public android.service.autofill.SaveInfo.Builder setDescription(java.lang.CharSequence);
     method public android.service.autofill.SaveInfo.Builder setNegativeAction(java.lang.CharSequence, android.content.IntentSender);
     method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
+    method public android.service.autofill.SaveInfo.Builder setSaveOnAllViewsInvisible(boolean);
   }
 
   public final class SaveRequest implements android.os.Parcelable {
@@ -40450,7 +40440,6 @@
     method public abstract void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>);
     method public void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>, android.os.Bundle);
     method public void onLoadItem(java.lang.String, android.service.media.MediaBrowserService.Result<android.media.browse.MediaBrowser.MediaItem>);
-    method public void onSearch(java.lang.String, android.os.Bundle, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>);
     method public void setSessionToken(android.media.session.MediaSession.Token);
     field public static final java.lang.String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService";
   }
@@ -40558,16 +40547,16 @@
     method public final int getCurrentInterruptionFilter();
     method public final int getCurrentListenerHints();
     method public android.service.notification.NotificationListenerService.RankingMap getCurrentRanking();
-    method public final java.util.List<android.app.NotificationChannelGroup> getNotificationChannelGroups(java.lang.String);
-    method public final java.util.List<android.app.NotificationChannel> getNotificationChannels(java.lang.String);
+    method public final java.util.List<android.app.NotificationChannelGroup> getNotificationChannelGroups(java.lang.String, android.os.UserHandle);
+    method public final java.util.List<android.app.NotificationChannel> getNotificationChannels(java.lang.String, android.os.UserHandle);
     method public final android.service.notification.StatusBarNotification[] getSnoozedNotifications();
     method public android.os.IBinder onBind(android.content.Intent);
     method public void onInterruptionFilterChanged(int);
     method public void onListenerConnected();
     method public void onListenerDisconnected();
     method public void onListenerHintsChanged(int);
-    method public void onNotificationChannelGroupModified(java.lang.String, android.app.NotificationChannelGroup, int);
-    method public void onNotificationChannelModified(java.lang.String, android.app.NotificationChannel, int);
+    method public void onNotificationChannelGroupModified(java.lang.String, android.os.UserHandle, android.app.NotificationChannelGroup, int);
+    method public void onNotificationChannelModified(java.lang.String, android.os.UserHandle, android.app.NotificationChannel, int);
     method public void onNotificationPosted(android.service.notification.StatusBarNotification);
     method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
     method public void onNotificationRankingUpdate(android.service.notification.NotificationListenerService.RankingMap);
@@ -40584,7 +40573,7 @@
     method public final void snoozeNotification(java.lang.String, java.lang.String);
     method public final void snoozeNotification(java.lang.String, long);
     method public void unregisterAsSystemService() throws android.os.RemoteException;
-    method public final void updateNotificationChannel(java.lang.String, android.app.NotificationChannel);
+    method public final void updateNotificationChannel(java.lang.String, android.os.UserHandle, android.app.NotificationChannel);
     field public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 4; // 0x4
     field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
     field public static final int HINT_HOST_DISABLE_NOTIFICATION_EFFECTS = 2; // 0x2
@@ -44472,7 +44461,6 @@
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
     method public android.content.ComponentName startService(android.content.Intent);
-    method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
     method public boolean stopService(android.content.Intent);
     method public void unbindService(android.content.ServiceConnection);
     method public void unregisterReceiver(android.content.BroadcastReceiver);
@@ -44574,6 +44562,7 @@
     method public byte[] getInstantAppCookie();
     method public int getInstantAppCookieMaxSize();
     method public android.graphics.drawable.Drawable getInstantAppIcon(java.lang.String);
+    method public android.content.ComponentName getInstantAppInstallerComponent();
     method public android.content.ComponentName getInstantAppResolverSettingsComponent();
     method public java.util.List<android.content.pm.InstantAppInfo> getInstantApps();
     method public android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -53672,6 +53661,7 @@
     method public java.lang.String getFormat();
     method public android.widget.Chronometer.OnChronometerTickListener getOnChronometerTickListener();
     method public boolean isCountDown();
+    method public boolean isTheFinalCountDown();
     method public void setBase(long);
     method public void setCountDown(boolean);
     method public void setFormat(java.lang.String);
@@ -59341,6 +59331,7 @@
     method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.util.List<java.lang.Class<?>>);
     method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.lang.Class<?>...);
     method public static java.lang.invoke.MethodHandle exactInvoker(java.lang.invoke.MethodType);
+    method public static java.lang.invoke.MethodHandle explicitCastArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType);
     method public static java.lang.invoke.MethodHandle filterArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle...);
     method public static java.lang.invoke.MethodHandle filterReturnValue(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
     method public static java.lang.invoke.MethodHandle foldArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index bdcafae..823d88f 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -5,10 +5,6 @@
     method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
   }
 
-  public static class Notification.Builder {
-    method public deprecated android.app.Notification.Builder chooseBadgeIcon(int);
-  }
-
   public final class RecoverableSecurityException extends java.lang.SecurityException implements android.os.Parcelable {
     method public deprecated void showAsNotification(android.content.Context);
   }
@@ -24,6 +20,20 @@
 
 }
 
+package android.app.usage {
+
+  public class StorageStatsManager {
+    method public deprecated long getFreeBytes(java.lang.String) throws java.io.IOException;
+    method public deprecated long getTotalBytes(java.lang.String) throws java.io.IOException;
+    method public deprecated boolean isQuotaSupported(java.lang.String);
+    method public deprecated android.app.usage.ExternalStorageStats queryExternalStatsForUser(java.lang.String, android.os.UserHandle) throws java.io.IOException;
+    method public deprecated android.app.usage.StorageStats queryStatsForPackage(java.lang.String, java.lang.String, android.os.UserHandle) throws java.io.IOException, android.content.pm.PackageManager.NameNotFoundException;
+    method public deprecated android.app.usage.StorageStats queryStatsForUid(java.lang.String, int) throws java.io.IOException;
+    method public deprecated android.app.usage.StorageStats queryStatsForUser(java.lang.String, android.os.UserHandle) throws java.io.IOException;
+  }
+
+}
+
 package android.content {
 
   public abstract class Context {
@@ -39,6 +49,10 @@
 
 package android.content.pm {
 
+  public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
+    field public deprecated java.lang.String volumeUuid;
+  }
+
   public class ComponentInfo extends android.content.pm.PackageItemInfo {
     field public deprecated boolean encryptionAware;
   }
@@ -178,10 +192,14 @@
 package android.os.storage {
 
   public class StorageManager {
-    method public deprecated long getCacheQuotaBytes();
-    method public deprecated long getCacheSizeBytes();
-    method public deprecated long getExternalCacheQuotaBytes();
-    method public deprecated long getExternalCacheSizeBytes();
+    method public deprecated void allocateBytes(java.io.File, long, int) throws java.io.IOException;
+    method public deprecated long getAllocatableBytes(java.io.File, int) throws java.io.IOException;
+    method public deprecated long getCacheQuotaBytes(java.io.File) throws java.io.IOException;
+    method public deprecated long getCacheQuotaBytes() throws java.io.IOException;
+    method public deprecated long getCacheSizeBytes(java.io.File) throws java.io.IOException;
+    method public deprecated long getCacheSizeBytes() throws java.io.IOException;
+    method public deprecated long getExternalCacheQuotaBytes() throws java.io.IOException;
+    method public deprecated long getExternalCacheSizeBytes() throws java.io.IOException;
     method public android.os.storage.StorageVolume getPrimaryVolume();
     method public android.os.storage.StorageVolume[] getVolumeList();
     method public deprecated boolean isCacheBehaviorAtomic(java.io.File) throws java.io.IOException;
diff --git a/api/test-current.txt b/api/test-current.txt
index 86227a7..543fcc6 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5618,7 +5618,6 @@
     method public boolean removeAutomaticZenRule(java.lang.String);
     method public final void setInterruptionFilter(int);
     method public void setNotificationPolicy(android.app.NotificationManager.Policy);
-    method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
     method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
     field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
@@ -6655,7 +6654,7 @@
 
   public static class AssistStructure.ViewNode {
     method public float getAlpha();
-    method public java.lang.String[] getAutoFillHints();
+    method public java.lang.String[] getAutofillHints();
     method public android.view.autofill.AutofillId getAutofillId();
     method public java.lang.String[] getAutofillOptions();
     method public int getAutofillType();
@@ -6920,7 +6919,7 @@
   }
 
   public abstract class JobServiceEngine {
-    ctor public JobServiceEngine(android.content.Context);
+    ctor public JobServiceEngine(android.app.Service);
     method public final android.os.IBinder getBinder();
     method public final void jobFinished(android.app.job.JobParameters, boolean);
     method public abstract boolean onStartJob(android.app.job.JobParameters);
@@ -7024,13 +7023,13 @@
   }
 
   public class StorageStatsManager {
-    method public long getFreeBytes(java.lang.String);
-    method public long getTotalBytes(java.lang.String);
-    method public boolean isQuotaSupported(java.lang.String);
-    method public android.app.usage.ExternalStorageStats queryExternalStatsForUser(java.lang.String, android.os.UserHandle);
-    method public android.app.usage.StorageStats queryStatsForPackage(java.lang.String, java.lang.String, android.os.UserHandle);
-    method public android.app.usage.StorageStats queryStatsForUid(java.lang.String, int);
-    method public android.app.usage.StorageStats queryStatsForUser(java.lang.String, android.os.UserHandle);
+    method public long getFreeBytes(java.util.UUID) throws java.io.IOException;
+    method public long getTotalBytes(java.util.UUID) throws java.io.IOException;
+    method public boolean isQuotaSupported(java.util.UUID);
+    method public android.app.usage.ExternalStorageStats queryExternalStatsForUser(java.util.UUID, android.os.UserHandle) throws java.io.IOException;
+    method public android.app.usage.StorageStats queryStatsForPackage(java.util.UUID, java.lang.String, android.os.UserHandle) throws java.io.IOException, android.content.pm.PackageManager.NameNotFoundException;
+    method public android.app.usage.StorageStats queryStatsForUid(java.util.UUID, int) throws java.io.IOException;
+    method public android.app.usage.StorageStats queryStatsForUser(java.util.UUID, android.os.UserHandle) throws java.io.IOException;
   }
 
   public final class UsageEvents implements android.os.Parcelable {
@@ -10253,12 +10252,12 @@
     field public java.lang.String[] splitNames;
     field public java.lang.String[] splitPublicSourceDirs;
     field public java.lang.String[] splitSourceDirs;
+    field public java.util.UUID storageUuid;
     field public int targetSdkVersion;
     field public java.lang.String taskAffinity;
     field public int theme;
     field public int uiOptions;
     field public int uid;
-    field public java.lang.String volumeUuid;
   }
 
   public static class ApplicationInfo.DisplayNameComparator implements java.util.Comparator {
@@ -10378,7 +10377,7 @@
   public class LauncherApps {
     ctor public LauncherApps(android.content.Context);
     method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(java.lang.String, android.os.UserHandle);
-    method public android.content.pm.ApplicationInfo getApplicationInfo(java.lang.String, int, android.os.UserHandle);
+    method public android.content.pm.ApplicationInfo getApplicationInfo(java.lang.String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
     method public android.content.pm.LauncherApps.PinItemRequest getPinItemRequest(android.content.Intent);
     method public java.util.List<android.os.UserHandle> getProfiles();
     method public android.graphics.drawable.Drawable getShortcutBadgedIconDrawable(android.content.pm.ShortcutInfo, int);
@@ -23086,11 +23085,12 @@
     method public void setMaxDuration(int) throws java.lang.IllegalArgumentException;
     method public void setMaxFileSize(long) throws java.lang.IllegalArgumentException;
     method public void setNextOutputFile(java.io.FileDescriptor) throws java.io.IOException, java.lang.IllegalStateException;
-    method public void setNextOutputFile(java.lang.String) throws java.io.IOException, java.lang.IllegalStateException;
+    method public void setNextOutputFile(java.io.File) throws java.io.IOException, java.lang.IllegalStateException;
     method public void setOnErrorListener(android.media.MediaRecorder.OnErrorListener);
     method public void setOnInfoListener(android.media.MediaRecorder.OnInfoListener);
     method public void setOrientationHint(int);
     method public void setOutputFile(java.io.FileDescriptor) throws java.lang.IllegalStateException;
+    method public void setOutputFile(java.io.File);
     method public void setOutputFile(java.lang.String) throws java.lang.IllegalStateException;
     method public void setOutputFormat(int) throws java.lang.IllegalStateException;
     method public void setPreviewDisplay(android.view.Surface);
@@ -24117,7 +24117,6 @@
     method public android.content.ComponentName getServiceComponent();
     method public android.media.session.MediaSession.Token getSessionToken();
     method public boolean isConnected();
-    method public void search(java.lang.String, android.os.Bundle, android.media.browse.MediaBrowser.SearchCallback);
     method public void subscribe(java.lang.String, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void subscribe(java.lang.String, android.os.Bundle, android.media.browse.MediaBrowser.SubscriptionCallback);
     method public void unsubscribe(java.lang.String);
@@ -24153,12 +24152,6 @@
     field public static final int FLAG_PLAYABLE = 2; // 0x2
   }
 
-  public static abstract class MediaBrowser.SearchCallback {
-    ctor public MediaBrowser.SearchCallback();
-    method public void onError(java.lang.String, android.os.Bundle);
-    method public void onSearchResult(java.lang.String, android.os.Bundle, java.util.List<android.media.browse.MediaBrowser.MediaItem>);
-  }
-
   public static abstract class MediaBrowser.SubscriptionCallback {
     ctor public MediaBrowser.SubscriptionCallback();
     method public void onChildrenLoaded(java.lang.String, java.util.List<android.media.browse.MediaBrowser.MediaItem>);
@@ -24367,8 +24360,6 @@
 
   public final class MediaController {
     ctor public MediaController(android.content.Context, android.media.session.MediaSession.Token);
-    method public void addQueueItem(android.media.MediaDescription);
-    method public void addQueueItem(android.media.MediaDescription, int);
     method public void adjustVolume(int, int);
     method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
     method public android.os.Bundle getExtras();
@@ -24380,15 +24371,11 @@
     method public java.util.List<android.media.session.MediaSession.QueueItem> getQueue();
     method public java.lang.CharSequence getQueueTitle();
     method public int getRatingType();
-    method public int getRepeatMode();
     method public android.app.PendingIntent getSessionActivity();
     method public android.media.session.MediaSession.Token getSessionToken();
     method public android.media.session.MediaController.TransportControls getTransportControls();
-    method public boolean isShuffleModeEnabled();
     method public void registerCallback(android.media.session.MediaController.Callback);
     method public void registerCallback(android.media.session.MediaController.Callback, android.os.Handler);
-    method public void removeQueueItem(android.media.MediaDescription);
-    method public void removeQueueItemAt(int);
     method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void setVolumeTo(int, int);
     method public void unregisterCallback(android.media.session.MediaController.Callback);
@@ -24402,10 +24389,8 @@
     method public void onPlaybackStateChanged(android.media.session.PlaybackState);
     method public void onQueueChanged(java.util.List<android.media.session.MediaSession.QueueItem>);
     method public void onQueueTitleChanged(java.lang.CharSequence);
-    method public void onRepeatModeChanged(int);
     method public void onSessionDestroyed();
     method public void onSessionEvent(java.lang.String, android.os.Bundle);
-    method public void onShuffleModeChanged(boolean);
   }
 
   public static final class MediaController.PlaybackInfo {
@@ -24434,8 +24419,6 @@
     method public void sendCustomAction(android.media.session.PlaybackState.CustomAction, android.os.Bundle);
     method public void sendCustomAction(java.lang.String, android.os.Bundle);
     method public void setRating(android.media.Rating);
-    method public void setRepeatMode(int);
-    method public void setShuffleModeEnabled(boolean);
     method public void skipToNext();
     method public void skipToPrevious();
     method public void skipToQueueItem(long);
@@ -24462,18 +24445,13 @@
     method public void setQueue(java.util.List<android.media.session.MediaSession.QueueItem>);
     method public void setQueueTitle(java.lang.CharSequence);
     method public void setRatingType(int);
-    method public void setRepeatMode(int);
     method public void setSessionActivity(android.app.PendingIntent);
-    method public void setShuffleModeEnabled(boolean);
     field public static final deprecated int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
-    field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
     field public static final deprecated int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
   }
 
   public static abstract class MediaSession.Callback {
     ctor public MediaSession.Callback();
-    method public void onAddQueueItem(android.media.MediaDescription);
-    method public void onAddQueueItem(android.media.MediaDescription, int);
     method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void onCustomAction(java.lang.String, android.os.Bundle);
     method public void onFastForward();
@@ -24487,13 +24465,9 @@
     method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
     method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
     method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
-    method public void onRemoveQueueItem(android.media.MediaDescription);
-    method public void onRemoveQueueItemAt(int);
     method public void onRewind();
     method public void onSeekTo(long);
     method public void onSetRating(android.media.Rating);
-    method public void onSetRepeatMode(int);
-    method public void onSetShuffleModeEnabled(boolean);
     method public void onSkipToNext();
     method public void onSkipToPrevious();
     method public void onSkipToQueueItem(long);
@@ -24554,17 +24528,12 @@
     field public static final long ACTION_REWIND = 8L; // 0x8L
     field public static final long ACTION_SEEK_TO = 256L; // 0x100L
     field public static final long ACTION_SET_RATING = 128L; // 0x80L
-    field public static final long ACTION_SET_REPEAT_MODE = 262144L; // 0x40000L
-    field public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 524288L; // 0x80000L
     field public static final long ACTION_SKIP_TO_NEXT = 32L; // 0x20L
     field public static final long ACTION_SKIP_TO_PREVIOUS = 16L; // 0x10L
     field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
     field public static final long ACTION_STOP = 1L; // 0x1L
     field public static final android.os.Parcelable.Creator<android.media.session.PlaybackState> CREATOR;
     field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL
-    field public static final int REPEAT_MODE_ALL = 2; // 0x2
-    field public static final int REPEAT_MODE_NONE = 0; // 0x0
-    field public static final int REPEAT_MODE_ONE = 1; // 0x1
     field public static final int STATE_BUFFERING = 6; // 0x6
     field public static final int STATE_CONNECTING = 8; // 0x8
     field public static final int STATE_ERROR = 7; // 0x7
@@ -30908,6 +30877,7 @@
     method public android.util.SizeF getSizeF(java.lang.String);
     method public <T extends android.os.Parcelable> android.util.SparseArray<T> getSparseParcelableArray(java.lang.String);
     method public java.util.ArrayList<java.lang.String> getStringArrayList(java.lang.String);
+    method public java.util.UUID getUuid(java.lang.String);
     method public boolean hasFileDescriptors();
     method public void putAll(android.os.Bundle);
     method public void putBinder(java.lang.String, android.os.IBinder);
@@ -30932,6 +30902,7 @@
     method public void putSizeF(java.lang.String, android.util.SizeF);
     method public void putSparseParcelableArray(java.lang.String, android.util.SparseArray<? extends android.os.Parcelable>);
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
+    method public void putUuid(java.lang.String, java.util.UUID);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
     method public void writeToParcel(android.os.Parcel, int);
@@ -31482,6 +31453,7 @@
     method public final <T> void readTypedArray(T[], android.os.Parcelable.Creator<T>);
     method public final <T> void readTypedList(java.util.List<T>, android.os.Parcelable.Creator<T>);
     method public final <T> T readTypedObject(android.os.Parcelable.Creator<T>);
+    method public final java.util.UUID readUuid();
     method public final java.lang.Object readValue(java.lang.ClassLoader);
     method public final void recycle();
     method public final void setDataCapacity(int);
@@ -31527,6 +31499,7 @@
     method public final <T extends android.os.Parcelable> void writeTypedArray(T[], int);
     method public final <T extends android.os.Parcelable> void writeTypedList(java.util.List<T>);
     method public final <T extends android.os.Parcelable> void writeTypedObject(T, int);
+    method public final void writeUuid(java.util.UUID);
     method public final void writeValue(java.lang.Object);
     field public static final android.os.Parcelable.Creator<java.lang.String> STRING_CREATOR;
   }
@@ -32161,15 +32134,16 @@
   }
 
   public class StorageManager {
-    method public void allocateBytes(java.io.File, long, int) throws java.io.IOException;
+    method public void allocateBytes(java.util.UUID, long, int) throws java.io.IOException;
     method public void allocateBytes(java.io.FileDescriptor, long, int) throws java.io.IOException;
-    method public long getAllocatableBytes(java.io.File, int) throws java.io.IOException;
-    method public long getCacheQuotaBytes(java.io.File);
-    method public long getCacheSizeBytes(java.io.File);
+    method public long getAllocatableBytes(java.util.UUID, int) throws java.io.IOException;
+    method public long getCacheQuotaBytes(java.util.UUID) throws java.io.IOException;
+    method public long getCacheSizeBytes(java.util.UUID) throws java.io.IOException;
     method public java.lang.String getMountedObbPath(java.lang.String);
     method public android.os.storage.StorageVolume getPrimaryStorageVolume();
     method public android.os.storage.StorageVolume getStorageVolume(java.io.File);
     method public java.util.List<android.os.storage.StorageVolume> getStorageVolumes();
+    method public java.util.UUID getUuidForPath(java.io.File) throws java.io.IOException;
     method public boolean isCacheBehaviorGroup(java.io.File) throws java.io.IOException;
     method public boolean isCacheBehaviorTombstone(java.io.File) throws java.io.IOException;
     method public boolean isEncrypted(java.io.File);
@@ -32181,7 +32155,10 @@
     method public void setCacheBehaviorTombstone(java.io.File, boolean) throws java.io.IOException;
     method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener);
     field public static final java.lang.String ACTION_MANAGE_STORAGE = "android.os.storage.action.MANAGE_STORAGE";
+    field public static final java.lang.String EXTRA_REQUESTED_BYTES = "android.os.storage.extra.REQUESTED_BYTES";
+    field public static final java.lang.String EXTRA_UUID = "android.os.storage.extra.UUID";
     field public static final int FLAG_ALLOCATE_AGGRESSIVE = 1; // 0x1
+    field public static final java.util.UUID UUID_DEFAULT;
   }
 
   public final class StorageVolume implements android.os.Parcelable {
@@ -35626,6 +35603,16 @@
     field public static final java.lang.String SUBSCRIPTION_ID = "pending_sub_id";
   }
 
+  public static final class Telephony.ServiceStateTable {
+    method public static android.net.Uri getUriForSubId(int);
+    method public static android.net.Uri getUriForSubIdAndField(int, java.lang.String);
+    field public static final java.lang.String AUTHORITY = "service-state";
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String IS_MANUAL_NETWORK_SELECTION = "is_manual_network_selection";
+    field public static final java.lang.String VOICE_OPERATOR_NUMERIC = "voice_operator_numeric";
+    field public static final java.lang.String VOICE_REG_STATE = "voice_reg_state";
+  }
+
   public static final class Telephony.Sms implements android.provider.BaseColumns android.provider.Telephony.TextBasedSmsColumns {
     method public static java.lang.String getDefaultSmsPackage(android.content.Context);
     field public static final android.net.Uri CONTENT_URI;
@@ -37302,6 +37289,7 @@
     method public android.service.autofill.SaveInfo.Builder setDescription(java.lang.CharSequence);
     method public android.service.autofill.SaveInfo.Builder setNegativeAction(java.lang.CharSequence, android.content.IntentSender);
     method public android.service.autofill.SaveInfo.Builder setOptionalIds(android.view.autofill.AutofillId[]);
+    method public android.service.autofill.SaveInfo.Builder setSaveOnAllViewsInvisible(boolean);
   }
 
   public final class SaveRequest implements android.os.Parcelable {
@@ -37493,7 +37481,6 @@
     method public abstract void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>);
     method public void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>, android.os.Bundle);
     method public void onLoadItem(java.lang.String, android.service.media.MediaBrowserService.Result<android.media.browse.MediaBrowser.MediaItem>);
-    method public void onSearch(java.lang.String, android.os.Bundle, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>);
     method public void setSessionToken(android.media.session.MediaSession.Token);
     field public static final java.lang.String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService";
   }
@@ -37599,16 +37586,16 @@
     method public final int getCurrentInterruptionFilter();
     method public final int getCurrentListenerHints();
     method public android.service.notification.NotificationListenerService.RankingMap getCurrentRanking();
-    method public final java.util.List<android.app.NotificationChannelGroup> getNotificationChannelGroups(java.lang.String);
-    method public final java.util.List<android.app.NotificationChannel> getNotificationChannels(java.lang.String);
+    method public final java.util.List<android.app.NotificationChannelGroup> getNotificationChannelGroups(java.lang.String, android.os.UserHandle);
+    method public final java.util.List<android.app.NotificationChannel> getNotificationChannels(java.lang.String, android.os.UserHandle);
     method public final android.service.notification.StatusBarNotification[] getSnoozedNotifications();
     method public android.os.IBinder onBind(android.content.Intent);
     method public void onInterruptionFilterChanged(int);
     method public void onListenerConnected();
     method public void onListenerDisconnected();
     method public void onListenerHintsChanged(int);
-    method public void onNotificationChannelGroupModified(java.lang.String, android.app.NotificationChannelGroup, int);
-    method public void onNotificationChannelModified(java.lang.String, android.app.NotificationChannel, int);
+    method public void onNotificationChannelGroupModified(java.lang.String, android.os.UserHandle, android.app.NotificationChannelGroup, int);
+    method public void onNotificationChannelModified(java.lang.String, android.os.UserHandle, android.app.NotificationChannel, int);
     method public void onNotificationPosted(android.service.notification.StatusBarNotification);
     method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
     method public void onNotificationRankingUpdate(android.service.notification.NotificationListenerService.RankingMap);
@@ -37622,7 +37609,7 @@
     method public final void setNotificationsShown(java.lang.String[]);
     method public final void snoozeNotification(java.lang.String, java.lang.String);
     method public final void snoozeNotification(java.lang.String, long);
-    method public final void updateNotificationChannel(java.lang.String, android.app.NotificationChannel);
+    method public final void updateNotificationChannel(java.lang.String, android.os.UserHandle, android.app.NotificationChannel);
     field public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 4; // 0x4
     field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
     field public static final int HINT_HOST_DISABLE_NOTIFICATION_EFFECTS = 2; // 0x2
@@ -39666,6 +39653,8 @@
     field public static final java.lang.String ACTION_CONFIGURE_PHONE_ACCOUNT = "android.telecom.action.CONFIGURE_PHONE_ACCOUNT";
     field public static final java.lang.String ACTION_DEFAULT_DIALER_CHANGED = "android.telecom.action.DEFAULT_DIALER_CHANGED";
     field public static final deprecated java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
+    field public static final java.lang.String ACTION_PHONE_ACCOUNT_REGISTERED = "android.telecom.action.PHONE_ACCOUNT_REGISTERED";
+    field public static final java.lang.String ACTION_PHONE_ACCOUNT_UNREGISTERED = "android.telecom.action.PHONE_ACCOUNT_UNREGISTERED";
     field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
     field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS";
     field public static final java.lang.String ACTION_SHOW_MISSED_CALLS_NOTIFICATION = "android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION";
@@ -41111,7 +41100,6 @@
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
     method public android.content.ComponentName startService(android.content.Intent);
-    method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
     method public boolean stopService(android.content.Intent);
     method public void unbindService(android.content.ServiceConnection);
     method public void unregisterReceiver(android.content.BroadcastReceiver);
@@ -50109,6 +50097,7 @@
     method public java.lang.String getFormat();
     method public android.widget.Chronometer.OnChronometerTickListener getOnChronometerTickListener();
     method public boolean isCountDown();
+    method public boolean isTheFinalCountDown();
     method public void setBase(long);
     method public void setCountDown(boolean);
     method public void setFormat(java.lang.String);
@@ -55792,6 +55781,7 @@
     method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.util.List<java.lang.Class<?>>);
     method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.lang.Class<?>...);
     method public static java.lang.invoke.MethodHandle exactInvoker(java.lang.invoke.MethodType);
+    method public static java.lang.invoke.MethodHandle explicitCastArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType);
     method public static java.lang.invoke.MethodHandle filterArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle...);
     method public static java.lang.invoke.MethodHandle filterReturnValue(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
     method public static java.lang.invoke.MethodHandle foldArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 82705fd..0f5b81a 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -5,10 +5,6 @@
     method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
   }
 
-  public static class Notification.Builder {
-    method public deprecated android.app.Notification.Builder chooseBadgeIcon(int);
-  }
-
   public final class RecoverableSecurityException extends java.lang.SecurityException implements android.os.Parcelable {
     method public deprecated void showAsNotification(android.content.Context);
   }
@@ -26,6 +22,20 @@
 
 }
 
+package android.app.usage {
+
+  public class StorageStatsManager {
+    method public deprecated long getFreeBytes(java.lang.String) throws java.io.IOException;
+    method public deprecated long getTotalBytes(java.lang.String) throws java.io.IOException;
+    method public deprecated boolean isQuotaSupported(java.lang.String);
+    method public deprecated android.app.usage.ExternalStorageStats queryExternalStatsForUser(java.lang.String, android.os.UserHandle) throws java.io.IOException;
+    method public deprecated android.app.usage.StorageStats queryStatsForPackage(java.lang.String, java.lang.String, android.os.UserHandle) throws java.io.IOException, android.content.pm.PackageManager.NameNotFoundException;
+    method public deprecated android.app.usage.StorageStats queryStatsForUid(java.lang.String, int) throws java.io.IOException;
+    method public deprecated android.app.usage.StorageStats queryStatsForUser(java.lang.String, android.os.UserHandle) throws java.io.IOException;
+  }
+
+}
+
 package android.content {
 
   public abstract class Context {
@@ -41,6 +51,10 @@
 
 package android.content.pm {
 
+  public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
+    field public deprecated java.lang.String volumeUuid;
+  }
+
   public class ComponentInfo extends android.content.pm.PackageItemInfo {
     field public deprecated boolean encryptionAware;
   }
@@ -184,10 +198,14 @@
 package android.os.storage {
 
   public class StorageManager {
-    method public deprecated long getCacheQuotaBytes();
-    method public deprecated long getCacheSizeBytes();
-    method public deprecated long getExternalCacheQuotaBytes();
-    method public deprecated long getExternalCacheSizeBytes();
+    method public deprecated void allocateBytes(java.io.File, long, int) throws java.io.IOException;
+    method public deprecated long getAllocatableBytes(java.io.File, int) throws java.io.IOException;
+    method public deprecated long getCacheQuotaBytes(java.io.File) throws java.io.IOException;
+    method public deprecated long getCacheQuotaBytes() throws java.io.IOException;
+    method public deprecated long getCacheSizeBytes(java.io.File) throws java.io.IOException;
+    method public deprecated long getCacheSizeBytes() throws java.io.IOException;
+    method public deprecated long getExternalCacheQuotaBytes() throws java.io.IOException;
+    method public deprecated long getExternalCacheSizeBytes() throws java.io.IOException;
     method public android.os.storage.StorageVolume getPrimaryVolume();
     method public android.os.storage.StorageVolume[] getVolumeList();
     method public deprecated boolean isCacheBehaviorAtomic(java.io.File) throws java.io.IOException;
diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp
index 67874a8..d69dd79 100644
--- a/cmds/idmap/scan.cpp
+++ b/cmds/idmap/scan.cpp
@@ -10,6 +10,7 @@
 #include <androidfw/StreamingZipInflater.h>
 #include <androidfw/ZipFileRO.h>
 #include <cutils/jstring.h>
+#include <cutils/properties.h>
 #include <private/android_filesystem_config.h> // for AID_SYSTEM
 #include <utils/SortedVector.h>
 #include <utils/String16.h>
@@ -82,12 +83,26 @@
         return String8(tmp);
     }
 
+    bool check_property(String16 property, String16 value) {
+        const char *prop;
+        const char *val;
+
+        prop = strndup16to8(property.string(), property.size());
+        char propBuf[PROPERTY_VALUE_MAX];
+        property_get(prop, propBuf, NULL);
+        val = strndup16to8(value.string(), value.size());
+
+        return (strcmp(propBuf, val) == 0);
+    }
+
     int parse_overlay_tag(const ResXMLTree& parser, const char *target_package_name,
             bool* is_static_overlay)
     {
         const size_t N = parser.getAttributeCount();
         String16 target;
         int priority = -1;
+        String16 propName = String16();
+        String16 propValue = String16();
         for (size_t i = 0; i < N; ++i) {
             size_t len;
             String16 key(parser.getAttributeName(i, &len));
@@ -109,36 +124,34 @@
                 if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) {
                     *is_static_overlay = (v.data != 0);
                 }
+            } else if (key == String16("requiredSystemPropertyName")) {
+                const char16_t *p = parser.getAttributeStringValue(i, &len);
+                if (p != NULL) {
+                    propName = String16(p, len);
+                }
+            } else if (key == String16("requiredSystemPropertyValue")) {
+                const char16_t *p = parser.getAttributeStringValue(i, &len);
+                if (p != NULL) {
+                    propValue = String16(p, len);
+                }
             }
         }
+
+        // Note that conditional property enablement/exclusion only applies if
+        // the attribute is present. In its absence, all overlays are presumed enabled.
+        if (propName.size() > 0 && propValue.size() > 0) {
+            // if property set & equal to value, then include overlay - otherwise skip
+            if (!check_property(propName, propValue)) {
+                return NO_OVERLAY_TAG;
+            }
+        }
+
         if (target == String16(target_package_name)) {
             return priority;
         }
         return NO_OVERLAY_TAG;
     }
 
-    String16 parse_package_name(const ResXMLTree& parser)
-    {
-        const size_t N = parser.getAttributeCount();
-        String16 package_name;
-        for (size_t i = 0; i < N; ++i) {
-            size_t len;
-            String16 key(parser.getAttributeName(i, &len));
-            if (key == String16("package")) {
-                const char16_t *p = parser.getAttributeStringValue(i, &len);
-                if (p != NULL) {
-                    package_name = String16(p, len);
-                }
-            }
-        }
-        return package_name;
-    }
-
-    bool isValidStaticOverlayPackage(const String16& package_name) {
-        // TODO(b/35742444): Need to support selection method based on a package name.
-        return package_name.size() > 0;
-    }
-
     int parse_manifest(const void *data, size_t size, const char *target_package_name)
     {
         ResXMLTree parser;
@@ -149,7 +162,6 @@
         }
 
         ResXMLParser::event_code_t type;
-        String16 package_name;
         bool is_static_overlay = false;
         int priority = NO_OVERLAY_TAG;
         do {
@@ -157,16 +169,14 @@
             if (type == ResXMLParser::START_TAG) {
                 size_t len;
                 String16 tag(parser.getElementName(&len));
-                if (tag == String16("manifest")) {
-                    package_name = parse_package_name(parser);
-                } else if (tag == String16("overlay")) {
+                if (tag == String16("overlay")) {
                     priority = parse_overlay_tag(parser, target_package_name, &is_static_overlay);
                     break;
                 }
             }
         } while (type != ResXMLParser::BAD_DOCUMENT && type != ResXMLParser::END_DOCUMENT);
 
-        if (is_static_overlay && isValidStaticOverlayPackage(package_name)) {
+        if (is_static_overlay) {
             return priority;
         }
         return NO_OVERLAY_TAG;
diff --git a/cmds/media/src/com/android/commands/media/Media.java b/cmds/media/src/com/android/commands/media/Media.java
index 4be4654..9df229c 100644
--- a/cmds/media/src/com/android/commands/media/Media.java
+++ b/cmds/media/src/com/android/commands/media/Media.java
@@ -228,16 +228,6 @@
             System.out.println("onVolumeInfoChanged " + info);
         }
 
-        @Override
-        public void onRepeatModeChanged(int repeatMode) throws RemoteException {
-            System.out.println("onRepeatModeChanged " + repeatMode);
-        }
-
-        @Override
-        public void onShuffleModeChanged(boolean enabled) throws RemoteException {
-            System.out.println("onShuffleModeChanged " + enabled);
-        }
-
         void printUsageMessage() {
             try {
                 System.out.println("V2Monitoring session " + mController.getTag()
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b36a160..c4b7ed7 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -16,21 +16,16 @@
 
 package android.app;
 
-import android.metrics.LogMaker;
 import android.graphics.Rect;
 import android.os.SystemClock;
 import android.view.ViewRootImpl.ActivityConfigCallback;
-import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillPopupWindow;
-import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutofillWindowPresenter;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.app.ToolbarActionBar;
 import com.android.internal.app.WindowDecorActionBar;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.policy.PhoneWindow;
 
 import android.annotation.CallSuper;
@@ -1234,6 +1229,13 @@
         mFragments.doLoaderStart();
 
         getApplication().dispatchActivityStarted(this);
+
+        if (mAutoFillResetNeeded) {
+            AutofillManager afm = getAutofillManager();
+            if (afm != null) {
+                afm.onVisibleForAutofill();
+            }
+        }
     }
 
     /**
@@ -2068,6 +2070,7 @@
             if (args == null) {
                 throw new IllegalArgumentException("Expected non-null picture-in-picture args");
             }
+            updatePictureInPictureArgsForContentInsets(args);
             return ActivityManagerNative.getDefault().enterPictureInPictureMode(mToken, args);
         } catch (RemoteException e) {
             return false;
@@ -2085,11 +2088,27 @@
             if (args == null) {
                 throw new IllegalArgumentException("Expected non-null picture-in-picture args");
             }
+            updatePictureInPictureArgsForContentInsets(args);
             ActivityManagerNative.getDefault().setPictureInPictureArgs(mToken, args);
         } catch (RemoteException e) {
         }
     }
 
+    /**
+     * Updates the provided {@param args} with the last known content insets for this activity, to
+     * be used with the source hint rect for the transition into PiP.
+     */
+    private void updatePictureInPictureArgsForContentInsets(PictureInPictureArgs args) {
+        if (args != null && args.hasSourceBoundsHint() && getWindow() != null &&
+                getWindow().peekDecorView() != null &&
+                getWindow().peekDecorView().getViewRootImpl() != null) {
+            args.setSourceRectHintInsets(
+                    getWindow().peekDecorView().getViewRootImpl().getLastContentInsets());
+        } else {
+            args.setSourceRectHintInsets(null);
+        }
+    }
+
     void dispatchMovedToDisplay(int displayId, Configuration config) {
         updateDisplay(displayId);
         onMovedToDisplay(displayId, config);
@@ -7407,6 +7426,54 @@
         return true;
     }
 
+    /** @hide */
+    @Override
+    public boolean getViewVisibility(int viewId) {
+        Window window = getWindow();
+        if (window == null) {
+            Log.i(TAG, "no window");
+            return false;
+        }
+
+        View decorView = window.peekDecorView();
+        if (decorView == null) {
+            Log.i(TAG, "no decorView");
+            return false;
+        }
+
+        View view = decorView.findViewByAccessibilityIdTraversal(viewId);
+        if (view == null) {
+            Log.i(TAG, "cannot find view");
+            return false;
+        }
+
+        // Check if the view is visible by checking all parents
+        while (view != null) {
+            if (view == decorView) {
+                break;
+            }
+
+            if (view.getVisibility() != View.VISIBLE) {
+                Log.i(TAG, view + " is not visible");
+                return false;
+            }
+
+            if (view.getParent() instanceof View) {
+                view = (View) view.getParent();
+            } else {
+                break;
+            }
+        }
+
+        return true;
+    }
+
+    /** @hide */
+    @Override
+    public boolean isVisibleForAutofill() {
+        return !mStopped;
+    }
+
     /**
      * If set to true, this indicates to the system that it should never take a
      * screenshot of the activity to be used as a representation while it is not in a started state.
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index a6838f8b..e07b7e4 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2639,4 +2639,13 @@
             throw e.rethrowAsRuntimeException();
         }
     }
+
+    @Override
+    public ComponentName getInstantAppInstallerComponent() {
+        try {
+            return mPM.getInstantAppInstallerComponent();
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
 }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 6cc8a14..80de64b 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1447,21 +1447,13 @@
     @Override
     public ComponentName startService(Intent service) {
         warnIfCallingFromSystemProcess();
-        return startServiceCommon(service, -1, null, false, mUser);
+        return startServiceCommon(service, false, mUser);
     }
 
     @Override
     public ComponentName startForegroundService(Intent service) {
         warnIfCallingFromSystemProcess();
-        return startServiceCommon(service, -1, null, true, mUser);
-    }
-
-    // STOPSHIP: remove when NotificationManager.startServiceInForeground() is retired
-    @Override
-    public ComponentName startServiceInForeground(Intent service,
-            int id, Notification notification) {
-        warnIfCallingFromSystemProcess();
-        return startServiceCommon(service, id, notification, false, mUser);
+        return startServiceCommon(service, true, mUser);
     }
 
     @Override
@@ -1472,29 +1464,22 @@
 
     @Override
     public ComponentName startServiceAsUser(Intent service, UserHandle user) {
-        return startServiceCommon(service, -1, null, false, user);
+        return startServiceCommon(service, false, user);
     }
 
     @Override
     public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
-        return startServiceCommon(service, -1, null, true, user);
+        return startServiceCommon(service, true, user);
     }
 
-    // STOPSHIP: remove when NotificationManager.startServiceInForeground() is retired
-    @Override
-    public ComponentName startServiceInForegroundAsUser(Intent service,
-            int id, Notification notification, UserHandle user) {
-        return startServiceCommon(service, id, notification, false, user);
-    }
-
-    private ComponentName startServiceCommon(Intent service, int id, Notification notification,
-            boolean requireForeground, UserHandle user) {
+    private ComponentName startServiceCommon(Intent service, boolean requireForeground,
+            UserHandle user) {
         try {
             validateServiceIntent(service);
             service.prepareToLeaveProcess(this);
             ComponentName cn = ActivityManager.getService().startService(
                 mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
-                            getContentResolver()), id, notification, requireForeground,
+                            getContentResolver()), requireForeground,
                             getOpPackageName(), user.getIdentifier());
             if (cn != null) {
                 if (cn.getPackageName().equals("!")) {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 4210d2e..d270244 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -129,8 +129,7 @@
     void finishSubActivity(in IBinder token, in String resultWho, int requestCode);
     PendingIntent getRunningServiceControlPanel(in ComponentName service);
     ComponentName startService(in IApplicationThread caller, in Intent service,
-            in String resolvedType, int id, in Notification notification,
-            boolean requireForeground, in String callingPackage, int userId);
+            in String resolvedType, boolean requireForeground, in String callingPackage, int userId);
     int stopService(in IApplicationThread caller, in Intent service,
             in String resolvedType, int userId);
     int bindService(in IApplicationThread caller, in IBinder token, in Intent service,
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index f4e8f3f..cd9c095 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -27,6 +27,7 @@
 import android.content.pm.ParceledListSlice;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.service.notification.Adjustment;
 import android.service.notification.Condition;
 import android.service.notification.IConditionListener;
@@ -101,9 +102,9 @@
     void setOnNotificationPostedTrimFromListener(in INotificationListener token, int trim);
     void setInterruptionFilter(String pkg, int interruptionFilter);
 
-    void updateNotificationChannelFromPrivilegedListener(in INotificationListener token, String pkg, in NotificationChannel channel);
-    ParceledListSlice getNotificationChannelsFromPrivilegedListener(in INotificationListener token, String pkg);
-    ParceledListSlice getNotificationChannelGroupsFromPrivilegedListener(in INotificationListener token, String pkg);
+    void updateNotificationChannelFromPrivilegedListener(in INotificationListener token, String pkg, in UserHandle user, in NotificationChannel channel);
+    ParceledListSlice getNotificationChannelsFromPrivilegedListener(in INotificationListener token, String pkg, in UserHandle user);
+    ParceledListSlice getNotificationChannelGroupsFromPrivilegedListener(in INotificationListener token, String pkg, in UserHandle user);
 
     void applyEnqueuedAdjustmentFromAssistant(in INotificationListener token, in Adjustment adjustment);
     void applyAdjustmentFromAssistant(in INotificationListener token, in Adjustment adjustment);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 7f26f4f..cab2114 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2339,7 +2339,9 @@
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        sb.append("Notification(pri=");
+        sb.append("Notification(channel=");
+        sb.append(getChannel());
+        sb.append(" pri=");
         sb.append(priority);
         sb.append(" contentView=");
         if (contentView != null) {
@@ -2729,21 +2731,6 @@
         }
 
         /**
-         * @removed
-         * Sets which icon to display as a badge for this notification.
-         *
-         * Must be one of {@link #BADGE_ICON_NONE}, {@link #BADGE_ICON_SMALL},
-         * {@link #BADGE_ICON_LARGE}.
-         *
-         * Note: This value might be ignored, for launchers that don't support badge icons.
-         */
-        @Deprecated
-        public Builder chooseBadgeIcon(int icon) {
-            mN.mBadgeIcon = icon;
-            return this;
-        }
-
-        /**
          * Sets which icon to display as a badge for this notification.
          *
          * Must be one of {@link #BADGE_ICON_NONE}, {@link #BADGE_ICON_SMALL},
@@ -3259,9 +3246,10 @@
          * This should only be used for high priority ongoing tasks like navigation, an ongoing
          * call, or other similarly high-priority events for the user.
          * <p>
-         * For most styles, the coloring will only be applied if the notification is ongoing.
+         * For most styles, the coloring will only be applied if the notification is for a
+         * foreground service notification.
          * However, for {@link MediaStyle} and {@link DecoratedMediaCustomViewStyle} notifications
-         * that have a media session attached there is no requirement for it to be ongoing.
+         * that have a media session attached there is no such requirement.
          *
          * @see Builder#setOngoing(boolean)
          * @see Builder#setColor(int)
@@ -4214,9 +4202,22 @@
          * @hide
          */
         public RemoteViews makePublicContentView() {
+            return makePublicView(false /* ambient */);
+        }
+
+        /**
+         * Construct a RemoteViews for the display in public contexts like on the lockscreen.
+         *
+         * @hide
+         */
+        public RemoteViews makePublicAmbientNotification() {
+            return makePublicView(true /* ambient */);
+        }
+
+        private RemoteViews makePublicView(boolean ambient) {
             if (mN.publicVersion != null) {
                 final Builder builder = recoverBuilder(mContext, mN.publicVersion);
-                return builder.createContentView();
+                return ambient ? builder.makeAmbientNotification() : builder.createContentView();
             }
             Bundle savedBundle = mN.extras;
             Style style = mStyle;
@@ -4233,14 +4234,15 @@
             publicExtras.putBoolean(EXTRA_CHRONOMETER_COUNT_DOWN,
                     savedBundle.getBoolean(EXTRA_CHRONOMETER_COUNT_DOWN));
             publicExtras.putCharSequence(EXTRA_TITLE,
-                    mContext.getString(R.string.notification_hidden_text));
+                    mContext.getString(com.android.internal.R.string.notification_hidden_text));
             mN.extras = publicExtras;
-            final RemoteViews publicView = applyStandardTemplate(getBaseLayoutResource());
+            final RemoteViews view = ambient ? makeAmbientNotification()
+                    : applyStandardTemplate(getBaseLayoutResource());
             mN.extras = savedBundle;
             mN.mLargeIcon = largeIcon;
             mN.largeIcon = largeIconLegacy;
             mStyle = style;
-            return publicView;
+            return view;
         }
 
         /**
@@ -4759,12 +4761,10 @@
     }
 
     /**
-     * @return whether this notification is ongoing and can't be dismissed by the user.
+     * @return whether this notification is a foreground service notification
      */
-    private boolean isOngoing() {
-        final int ongoingFlags = Notification.FLAG_FOREGROUND_SERVICE
-                | Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
-        return (flags & ongoingFlags) != 0;
+    private boolean isForegroundService() {
+        return (flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
     }
 
     /**
@@ -4789,8 +4789,7 @@
     }
 
     /**
-     * @return true if this notification is colorized. This also factors in whether the
-     * notification is ongoing.
+     * @return true if this notification is colorized.
      *
      * @hide
      */
@@ -4806,7 +4805,7 @@
                 return true;
             }
         }
-        return extras.getBoolean(EXTRA_COLORIZED) && isOngoing();
+        return extras.getBoolean(EXTRA_COLORIZED) && isForegroundService();
     }
 
     private boolean hasLargeIcon() {
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 72c5978..242d4a5 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1155,40 +1155,4 @@
         }
     }
 
-    /**
-     * Start a service directly into the "foreground service" state.  Unlike
-     * {@link android.content.Context#startService(Intent)}, this method
-     * can be used from within background operations like broadcast receivers
-     * or scheduled jobs.
-     *
-     * @param service Description of the service to be started.  The Intent must be either
-     *      fully explicit (supplying a component name) or specify a specific package
-     *      name it is targeted to.
-     * @param id The identifier for this notification as per
-     *      {@link #notify(int, Notification) NotificationManager.notify(int, Notification)};
-     *      must not be 0.
-     * @param notification The Notification to be displayed.
-     * @return If the service is being started or is already running, the
-     *      {@link ComponentName} of the actual service that was started is
-     *      returned; else if the service does not exist null is returned.
-     *
-     * @deprecated STOPSHIP transition away from this for O
-     */
-    @Nullable
-    @Deprecated
-    public ComponentName startServiceInForeground(Intent service,
-            int id, Notification notification) {
-        return mContext.startServiceInForeground(service, id, notification);
-    }
-
-    /**
-     * @hide like {@link #startServiceInForeground(Intent, int, Notification)}
-     * but for a specific user.
-     */
-    @Nullable
-    public ComponentName startServiceInForegroundAsUser(Intent service,
-            int id, Notification notification, UserHandle user) {
-        return mContext.startServiceInForegroundAsUser(service, id, notification, user);
-    }
-
 }
diff --git a/core/java/android/app/PictureInPictureArgs.java b/core/java/android/app/PictureInPictureArgs.java
index 0ce5eeb..2fa6360 100644
--- a/core/java/android/app/PictureInPictureArgs.java
+++ b/core/java/android/app/PictureInPictureArgs.java
@@ -49,6 +49,13 @@
     @Nullable
     private Rect mSourceRectHint;
 
+    /**
+     * The content insets that are used with the source hint rect for the transition into PiP where
+     * the insets are removed at the beginning of the transition.
+     */
+    @Nullable
+    private Rect mSourceRectHintInsets;
+
     PictureInPictureArgs(Parcel in) {
         if (in.readInt() != 0) {
             mAspectRatio = in.readFloat();
@@ -60,6 +67,9 @@
         if (in.readInt() != 0) {
             mSourceRectHint = Rect.CREATOR.createFromParcel(in);
         }
+        if (in.readInt() != 0) {
+            mSourceRectHintInsets = Rect.CREATOR.createFromParcel(in);
+        }
     }
 
     /**
@@ -94,6 +104,9 @@
         if (otherArgs.hasSourceBoundsHint()) {
             mSourceRectHint = new Rect(otherArgs.getSourceRectHint());
         }
+        if (otherArgs.hasSourceBoundsHintInsets()) {
+            mSourceRectHintInsets = new Rect(otherArgs.getSourceRectHintInsets());
+        }
     }
 
     /**
@@ -167,7 +180,19 @@
     }
 
     /**
-     * @return the launch bounds
+     * Sets the insets to be used with the source rect hint bounds.
+     * @hide
+     */
+    public void setSourceRectHintInsets(Rect insets) {
+        if (insets == null) {
+            mSourceRectHintInsets = null;
+        } else {
+            mSourceRectHintInsets = new Rect(insets);
+        }
+    }
+
+    /**
+     * @return the source rect hint
      * @hide
      */
     public Rect getSourceRectHint() {
@@ -175,6 +200,14 @@
     }
 
     /**
+     * @return the source rect hint insets.
+     * @hide
+     */
+    public Rect getSourceRectHintInsets() {
+        return mSourceRectHintInsets;
+    }
+
+    /**
      * @return whether there are launch bounds set
      * @hide
      */
@@ -182,12 +215,23 @@
         return mSourceRectHint != null && !mSourceRectHint.isEmpty();
     }
 
+    /**
+     * @return whether there are source rect hint insets set
+     * @hide
+     */
+    public boolean hasSourceBoundsHintInsets() {
+        return mSourceRectHintInsets != null;
+    }
+
     @Override
     public PictureInPictureArgs clone() {
         PictureInPictureArgs args = new PictureInPictureArgs(mAspectRatio, mUserActions);
         if (mSourceRectHint != null) {
             args.setSourceRectHint(mSourceRectHint);
         }
+        if (mSourceRectHintInsets != null) {
+            args.setSourceRectHintInsets(mSourceRectHintInsets);
+        }
         return args;
     }
 
@@ -216,6 +260,12 @@
         } else {
             out.writeInt(0);
         }
+        if (mSourceRectHintInsets != null) {
+            out.writeInt(1);
+            mSourceRectHintInsets.writeToParcel(out, 0);
+        } else {
+            out.writeInt(0);
+        }
     }
 
     public static final Creator<PictureInPictureArgs> CREATOR =
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 3191eec..6f326de 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -112,13 +112,6 @@
     private final ArrayMap<Pair<Integer, DisplayAdjustments>, WeakReference<Display>>
             mAdjustedDisplays = new ArrayMap<>();
 
-    /**
-     * A cache of DisplayId, Resources to Display. These display adjustments associated with these
-     * {@link Display}s will change as the resources change.
-     */
-    private final ArrayMap<Pair<Integer, ResourcesKey>, WeakReference<Display>> mResourceDisplays =
-        new ArrayMap<>();
-
     public static ResourcesManager getInstance() {
         synchronized (ResourcesManager.class) {
             if (sResourcesManager == null) {
@@ -251,51 +244,16 @@
      */
     public Display getAdjustedDisplay(final int displayId, Resources resources) {
         synchronized (this) {
-            // Note that the ResourcesKey might be {@code null} in the case that the
-            // {@link Resources} is actually from {@link Resources#getSystem}. In this case, it is
-            // not managed by {@link ResourcesManager}, but we still want to cache the display
-            // object.
-            final Pair<Integer, ResourcesKey> key = Pair.create(displayId,
-                    findKeyForResourceImplLocked(resources.getImpl()));
-
-            WeakReference<Display> wd = mResourceDisplays.get(key);
-            if (wd != null) {
-                final Display display = wd.get();
-                if (display != null) {
-                    return display;
-                }
-            }
             final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
             if (dm == null) {
                 // may be null early in system startup
                 return null;
             }
-            final Display display = dm.getCompatibleDisplay(displayId, resources);
-            if (display != null) {
-                mResourceDisplays.put(key, new WeakReference<>(display));
-            }
-            return display;
+            return dm.getCompatibleDisplay(displayId, resources);
         }
     }
 
     private void cleanupResourceImpl(ResourcesKey removedKey) {
-        // Remove any resource to display mapping based on this key.
-        final Iterator<Map.Entry<Pair<Integer, ResourcesKey>, WeakReference<Display>>> iter =
-                mResourceDisplays.entrySet().iterator();
-        while (iter.hasNext()) {
-            final Map.Entry<Pair<Integer, ResourcesKey>, WeakReference<Display>> entry =
-                    iter.next();
-            final ResourcesKey key = entry.getKey().second;
-
-            // Do not touch system resource displays (indicated by a {@code null} key) or
-            // non-matching keys.
-            if (key == null || !key.equals(removedKey)) {
-                continue;
-            }
-
-            iter.remove();
-        }
-
         // Remove resource key to resource impl mapping and flush cache
         final ResourcesImpl res = mResourceImpls.remove(removedKey).get();
 
@@ -887,7 +845,6 @@
             int changes = mResConfiguration.updateFrom(config);
             // Things might have changed in display manager, so clear the cached displays.
             mAdjustedDisplays.clear();
-            mResourceDisplays.clear();
 
             DisplayMetrics defaultDisplayMetrics = getDisplayMetrics();
 
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 545aef5..9f911f5 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -964,6 +964,16 @@
          *
          * @return The hints for this view
          */
+        @Nullable public String[] getAutofillHints() {
+            return mAutofillHints;
+        }
+
+        /**
+         * @hide
+         * @deprecated use getAutofillHints() instead.
+         */
+        // TODO(b/33197203): remove once clients don't use it anymore...
+        @Deprecated
         @Nullable public String[] getAutoFillHints() {
             return mAutofillHints;
         }
diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java
index 016a0fa..673d1b8 100644
--- a/core/java/android/app/job/JobParameters.java
+++ b/core/java/android/app/job/JobParameters.java
@@ -164,6 +164,20 @@
      * you should not call {@link JobService#jobFinished(JobParameters, boolean)} yourself
      * (otherwise you risk losing an upcoming JobWorkItem that is being enqueued at the same time).
      *
+     * <p>Once you are done with the {@link JobWorkItem} returned by this method, you must call
+     * {@link #completeWork(JobWorkItem)} with it to inform the system that you are done
+     * executing the work.  The job will not be finished until all dequeued work has been
+     * completed.  You do not, however, have to complete each returned work item before deqeueing
+     * the next one -- you can use {@link #dequeueWork()} multiple times before completing
+     * previous work if you want to process work in parallel, and you can complete the work
+     * in whatever order you want.</p>
+     *
+     * <p>If the job runs to the end of its available time period before all work has been
+     * completed, it will stop as normal.  You should return true from
+     * {@link JobService#onStopJob(JobParameters)} in order to have the job rescheduled, and by
+     * doing so any pending as well as remaining uncompleted work will be re-queued
+     * for the next time the job runs.</p>
+     *
      * @return Returns a new {@link JobWorkItem} if there is one pending, otherwise null.
      * If null is returned, the system will also stop the job if all work has also been completed.
      * (This means that for correct operation, you must always call dequeueWork() after you have
diff --git a/core/java/android/app/job/JobServiceEngine.java b/core/java/android/app/job/JobServiceEngine.java
index 879212e..a628619 100644
--- a/core/java/android/app/job/JobServiceEngine.java
+++ b/core/java/android/app/job/JobServiceEngine.java
@@ -54,7 +54,7 @@
     /**
      * Context we are running in.
      */
-    private final Context mContext;
+    private final Service mService;
 
     private final IJobService mBinder;
 
@@ -182,12 +182,12 @@
     /**
      * Create a new engine, ready for use.
      *
-     * @param context The {@link Service} that is creating this engine.
+     * @param service The {@link Service} that is creating this engine and in which it will run.
      */
-    public JobServiceEngine(Context context) {
-        mContext = context;
+    public JobServiceEngine(Service service) {
+        mService = service;
         mBinder = new JobInterface(this);
-        mHandler = new JobHandler(mContext.getMainLooper());
+        mHandler = new JobHandler(mService.getMainLooper());
     }
 
     /**
diff --git a/core/java/android/app/job/JobWorkItem.java b/core/java/android/app/job/JobWorkItem.java
index 4bb057e..05687ee 100644
--- a/core/java/android/app/job/JobWorkItem.java
+++ b/core/java/android/app/job/JobWorkItem.java
@@ -27,6 +27,7 @@
 final public class JobWorkItem implements Parcelable {
     final Intent mIntent;
     int mWorkId;
+    Object mGrants;
 
     /**
      * Create a new piece of work.
@@ -57,6 +58,20 @@
         return mWorkId;
     }
 
+    /**
+     * @hide
+     */
+    public void setGrants(Object grants) {
+        mGrants = grants;
+    }
+
+    /**
+     * @hide
+     */
+    public Object getGrants() {
+        return mGrants;
+    }
+
     public String toString() {
         return "JobWorkItem{id=" + mWorkId + " intent=" + mIntent + "}";
     }
diff --git a/core/java/android/app/usage/StorageStatsManager.java b/core/java/android/app/usage/StorageStatsManager.java
index 6fc4f5c..4b6479a 100644
--- a/core/java/android/app/usage/StorageStatsManager.java
+++ b/core/java/android/app/usage/StorageStatsManager.java
@@ -16,17 +16,25 @@
 
 package android.app.usage;
 
+import static android.os.storage.StorageManager.convert;
+
+import android.annotation.NonNull;
 import android.annotation.TestApi;
 import android.annotation.WorkerThread;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.ParcelableException;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.os.storage.StorageManager;
 
 import com.android.internal.util.Preconditions;
 
 import java.io.File;
+import java.io.IOException;
+import java.util.UUID;
 
 /**
  * Provides access to detailed storage statistics.
@@ -50,36 +58,49 @@
 
     /** {@hide} */
     @TestApi
-    public boolean isQuotaSupported(String volumeUuid) {
+    public boolean isQuotaSupported(@NonNull UUID storageUuid) {
         try {
-            return mService.isQuotaSupported(volumeUuid, mContext.getOpPackageName());
+            return mService.isQuotaSupported(convert(storageUuid), mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
+    /** @removed */
+    @Deprecated
+    public boolean isQuotaSupported(String uuid) {
+        return isQuotaSupported(convert(uuid));
+    }
+
     /**
-     * Return the total space on the requested storage volume.
+     * Return the total size of the media hosting this storage volume.
      * <p>
-     * To reduce end user confusion, this value is the total storage size
+     * To reduce end user confusion, this value matches the total storage size
      * advertised in a retail environment, which is typically larger than the
-     * actual writable partition total size.
-     * <p>
-     * This method may take several seconds to calculate the requested values,
-     * so it should only be called from a worker thread.
+     * actual usable partition space.
      *
-     * @param volumeUuid the UUID of the storage volume you're interested in, or
-     *            {@code null} to specify the default internal storage.
+     * @param storageUuid the UUID of the storage volume you're interested in,
+     *            such as {@link StorageManager#UUID_DEFAULT}.
+     * @throws IOException when the storage device isn't present.
      */
     @WorkerThread
-    public long getTotalBytes(String volumeUuid) {
+    public long getTotalBytes(@NonNull UUID storageUuid) throws IOException {
         try {
-            return mService.getTotalBytes(volumeUuid, mContext.getOpPackageName());
+            return mService.getTotalBytes(convert(storageUuid), mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
+    /** @removed */
+    @Deprecated
+    public long getTotalBytes(String uuid) throws IOException {
+        return getTotalBytes(convert(uuid));
+    }
+
     /**
      * Return the free space on the requested storage volume.
      * <p>
@@ -90,18 +111,28 @@
      * This method may take several seconds to calculate the requested values,
      * so it should only be called from a worker thread.
      *
-     * @param volumeUuid the UUID of the storage volume you're interested in, or
-     *            {@code null} to specify the default internal storage.
+     * @param storageUuid the UUID of the storage volume you're interested in,
+     *            such as {@link StorageManager#UUID_DEFAULT}.
+     * @throws IOException when the storage device isn't present.
      */
     @WorkerThread
-    public long getFreeBytes(String volumeUuid) {
+    public long getFreeBytes(@NonNull UUID storageUuid) throws IOException {
         try {
-            return mService.getFreeBytes(volumeUuid, mContext.getOpPackageName());
+            return mService.getFreeBytes(convert(storageUuid), mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
+    /** @removed */
+    @Deprecated
+    public long getFreeBytes(String uuid) throws IOException {
+        return getFreeBytes(convert(uuid));
+    }
+
     /**
      * Return storage statistics for a specific package on the requested storage
      * volume.
@@ -112,27 +143,41 @@
      * Note: if the requested package uses the {@code android:sharedUserId}
      * manifest feature, this call will be forced into a slower manual
      * calculation path. If possible, consider always using
-     * {@link #queryStatsForUid(String, int)}, which is typically faster.
+     * {@link #queryStatsForUid(UUID, int)}, which is typically faster.
      * </p>
      *
-     * @param volumeUuid the UUID of the storage volume you're interested in, or
-     *            {@code null} to specify the default internal storage.
+     * @param storageUuid the UUID of the storage volume you're interested in,
+     *            such as {@link StorageManager#UUID_DEFAULT}.
      * @param packageName the package name you're interested in.
      * @param user the user you're interested in.
-     * @see ApplicationInfo#volumeUuid
+     * @throws PackageManager.NameNotFoundException when the requested package
+     *             name isn't installed for the requested user.
+     * @throws IOException when the storage device isn't present.
+     * @see ApplicationInfo#storageUuid
      * @see PackageInfo#packageName
      */
     @WorkerThread
-    public StorageStats queryStatsForPackage(String volumeUuid, String packageName,
-            UserHandle user) {
+    public @NonNull StorageStats queryStatsForPackage(@NonNull UUID storageUuid, String packageName,
+            UserHandle user) throws PackageManager.NameNotFoundException, IOException {
         try {
-            return mService.queryStatsForPackage(volumeUuid, packageName, user.getIdentifier(),
-                    mContext.getOpPackageName());
+            return mService.queryStatsForPackage(convert(storageUuid), packageName,
+                    user.getIdentifier(), mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(PackageManager.NameNotFoundException.class);
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
+    /** @removed */
+    @Deprecated
+    public StorageStats queryStatsForPackage(String uuid, String packageName,
+            UserHandle user) throws PackageManager.NameNotFoundException, IOException {
+        return queryStatsForPackage(convert(uuid), packageName, user);
+    }
+
     /**
      * Return storage statistics for a specific UID on the requested storage
      * volume.
@@ -140,21 +185,32 @@
      * This method may take several seconds to calculate the requested values,
      * so it should only be called from a worker thread.
      *
-     * @param volumeUuid the UUID of the storage volume you're interested in, or
-     *            {@code null} to specify the default internal storage.
+     * @param storageUuid the UUID of the storage volume you're interested in,
+     *            such as {@link StorageManager#UUID_DEFAULT}.
      * @param uid the UID you're interested in.
-     * @see ApplicationInfo#volumeUuid
+     * @throws IOException when the storage device isn't present.
+     * @see ApplicationInfo#storageUuid
      * @see ApplicationInfo#uid
      */
     @WorkerThread
-    public StorageStats queryStatsForUid(String volumeUuid, int uid) {
+    public StorageStats queryStatsForUid(@NonNull UUID storageUuid, int uid) throws IOException {
         try {
-            return mService.queryStatsForUid(volumeUuid, uid, mContext.getOpPackageName());
+            return mService.queryStatsForUid(convert(storageUuid), uid,
+                    mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
+    /** @removed */
+    @Deprecated
+    public StorageStats queryStatsForUid(String uuid, int uid) throws IOException {
+        return queryStatsForUid(convert(uuid), uid);
+    }
+
     /**
      * Return storage statistics for a specific {@link UserHandle} on the
      * requested storage volume.
@@ -162,21 +218,32 @@
      * This method may take several seconds to calculate the requested values,
      * so it should only be called from a worker thread.
      *
-     * @param volumeUuid the UUID of the storage volume you're interested in, or
-     *            {@code null} to specify the default internal storage.
+     * @param storageUuid the UUID of the storage volume you're interested in,
+     *            such as {@link StorageManager#UUID_DEFAULT}.
      * @param user the user you're interested in.
+     * @throws IOException when the storage device isn't present.
      * @see android.os.Process#myUserHandle()
      */
     @WorkerThread
-    public StorageStats queryStatsForUser(String volumeUuid, UserHandle user) {
+    public StorageStats queryStatsForUser(@NonNull UUID storageUuid, UserHandle user)
+            throws IOException {
         try {
-            return mService.queryStatsForUser(volumeUuid, user.getIdentifier(),
+            return mService.queryStatsForUser(convert(storageUuid), user.getIdentifier(),
                     mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
+    /** @removed */
+    @Deprecated
+    public StorageStats queryStatsForUser(String uuid, UserHandle user) throws IOException {
+        return queryStatsForUser(convert(uuid), user);
+    }
+
     /**
      * Return shared/external storage statistics for a specific
      * {@link UserHandle} on the requested storage volume.
@@ -184,20 +251,32 @@
      * This method may take several seconds to calculate the requested values,
      * so it should only be called from a worker thread.
      *
-     * @param volumeUuid the UUID of the storage volume you're interested in, or
-     *            {@code null} to specify the default internal storage.
+     * @param storageUuid the UUID of the storage volume you're interested in,
+     *            such as {@link StorageManager#UUID_DEFAULT}.
+     * @throws IOException when the storage device isn't present.
      * @see android.os.Process#myUserHandle()
      */
     @WorkerThread
-    public ExternalStorageStats queryExternalStatsForUser(String volumeUuid, UserHandle user) {
+    public ExternalStorageStats queryExternalStatsForUser(@NonNull UUID storageUuid,
+            UserHandle user) throws IOException {
         try {
-            return mService.queryExternalStatsForUser(volumeUuid, user.getIdentifier(),
+            return mService.queryExternalStatsForUser(convert(storageUuid), user.getIdentifier(),
                     mContext.getOpPackageName());
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
+    /** @removed */
+    @Deprecated
+    public ExternalStorageStats queryExternalStatsForUser(String uuid, UserHandle user)
+            throws IOException {
+        return queryExternalStatsForUser(convert(uuid), user);
+    }
+
     /** {@hide} */
     public long getCacheQuotaBytes(String volumeUuid, int uid) {
         try {
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index ef3b1c5..624ec87 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -498,8 +498,13 @@
     private void updateContentDescription(AppWidgetProviderInfo info) {
         if (info != null) {
             LauncherApps launcherApps = getContext().getSystemService(LauncherApps.class);
-            ApplicationInfo appInfo = launcherApps.getApplicationInfo(
-                    info.provider.getPackageName(), 0, info.getProfile());
+            ApplicationInfo appInfo = null;
+            try {
+                appInfo = launcherApps.getApplicationInfo(
+                        info.provider.getPackageName(), 0, info.getProfile());
+            } catch (NameNotFoundException e) {
+                // ignore -- use null.
+            }
             if (appInfo != null &&
                     (appInfo.flags & ApplicationInfo.FLAG_SUSPENDED) != 0) {
                 setContentDescription(
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 18120c7..0adab1a 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2647,18 +2647,6 @@
     public abstract ComponentName startForegroundServiceAsUser(Intent service, UserHandle user);
 
     /**
-     * Start a service directly into the "foreground service" state.  Unlike {@link #startService},
-     * this method can be used from within background operations like broadcast receivers
-     * or scheduled jobs.  The API entry point for this is in NotificationManager in order to
-     * preserve appropriate public package layering.
-     * @hide
-     * @deprecated STOPSHIP remove in favor of two-step startForegroundService() + startForeground()
-     */
-    @Nullable
-    public abstract ComponentName startServiceInForeground(Intent service,
-            int id, Notification notification);
-
-    /**
      * Request that a given application service be stopped.  If the service is
      * not running, nothing happens.  Otherwise it is stopped.  Note that calls
      * to startService() are not counted -- this stops the service no matter
@@ -2696,16 +2684,6 @@
     public abstract ComponentName startServiceAsUser(Intent service, UserHandle user);
 
     /**
-     * @hide like {@link #startServiceInForeground(Intent, int, Notification)}
-     * but for a specific user.
-     * @deprecated STOPSHIP remove when trial API is turned off
-     */
-    @Deprecated
-    @Nullable
-    public abstract ComponentName startServiceInForegroundAsUser(Intent service,
-            int id, Notification notification, UserHandle user);
-
-    /**
      * @hide like {@link #stopService(Intent)} but for a specific user.
      */
     public abstract boolean stopServiceAsUser(Intent service, UserHandle user);
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 53b021c..b59fc3dd 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -649,13 +649,6 @@
         return mBase.startForegroundService(service);
     }
 
-    /** @hide STOPSHIP remove when trial API is turned down */
-    @Override
-    public ComponentName startServiceInForeground(Intent service,
-            int id, Notification notification) {
-        return mBase.startServiceInForeground(service, id, notification);
-    }
-
     @Override
     public boolean stopService(Intent name) {
         return mBase.stopService(name);
@@ -673,13 +666,6 @@
         return mBase.startForegroundServiceAsUser(service, user);
     }
 
-    /** @hide STOPSHIP removed when trial API is turned down */
-    @Override
-    public ComponentName startServiceInForegroundAsUser(Intent service,
-            int id, Notification notification, UserHandle user) {
-        return mBase.startServiceInForegroundAsUser(service, id, notification, user);
-    }
-
     /** @hide */
     @Override
     public boolean stopServiceAsUser(Intent name, UserHandle user) {
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 23e54ba..d64f018 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -1787,7 +1787,7 @@
                     sb.append(", mHasPartialTypes="); sb.append(mHasPartialTypes);
             du.println(sb.toString());
         }
-        {
+        if (getAutoVerify()) {
             sb.setLength(0);
             sb.append(prefix); sb.append("AutoVerify="); sb.append(getAutoVerify());
             du.println(sb.toString());
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 5f53e27..8b2809a 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -29,6 +29,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.UserHandle;
+import android.os.storage.StorageManager;
 import android.text.TextUtils;
 import android.util.Printer;
 import android.util.SparseArray;
@@ -41,6 +42,7 @@
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Objects;
+import java.util.UUID;
 
 /**
  * Information you can retrieve about a particular application.  This
@@ -621,12 +623,17 @@
      */
     public float maxAspectRatio;
 
+    /** @removed */
+    @Deprecated
+    public String volumeUuid;
+
     /**
      * UUID of the storage volume on which this application is being hosted. For
      * apps hosted on the default internal storage at
-     * {@link Environment#getDataDirectory()}, the UUID value is {@code null}.
+     * {@link Environment#getDataDirectory()}, the UUID value is
+     * {@link StorageManager#UUID_DEFAULT}.
      */
-    public String volumeUuid;
+    public UUID storageUuid;
 
     /** {@hide} */
     public String scanSourceDir;
@@ -1134,6 +1141,7 @@
         compatibleWidthLimitDp = orig.compatibleWidthLimitDp;
         largestWidthLimitDp = orig.largestWidthLimitDp;
         volumeUuid = orig.volumeUuid;
+        storageUuid = orig.storageUuid;
         scanSourceDir = orig.scanSourceDir;
         scanPublicSourceDir = orig.scanPublicSourceDir;
         sourceDir = orig.sourceDir;
@@ -1195,7 +1203,7 @@
         dest.writeInt(requiresSmallestWidthDp);
         dest.writeInt(compatibleWidthLimitDp);
         dest.writeInt(largestWidthLimitDp);
-        dest.writeString(volumeUuid);
+        dest.writeUuid(storageUuid);
         dest.writeString(scanSourceDir);
         dest.writeString(scanPublicSourceDir);
         dest.writeString(sourceDir);
@@ -1257,7 +1265,8 @@
         requiresSmallestWidthDp = source.readInt();
         compatibleWidthLimitDp = source.readInt();
         largestWidthLimitDp = source.readInt();
-        volumeUuid = source.readString();
+        storageUuid = source.readUuid();
+        volumeUuid = StorageManager.convert(storageUuid);
         scanSourceDir = source.readString();
         scanPublicSourceDir = source.readString();
         sourceDir = source.readString();
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 147df76..bbc942a 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -632,4 +632,6 @@
     void deletePreloadsFileCache();
 
     ComponentName getInstantAppResolverSettingsComponent();
+
+    ComponentName getInstantAppInstallerComponent();
 }
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index c3bdde5..8ead0ec 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -22,6 +22,8 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.TestApi;
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
@@ -52,6 +54,8 @@
 import android.util.DisplayMetrics;
 import android.util.Log;
 
+import com.android.internal.util.Preconditions;
+
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -612,11 +616,20 @@
      *         null if the package isn't installed for the given user, or the target user
      *         is not enabled.
      */
-    public ApplicationInfo getApplicationInfo(String packageName, @ApplicationInfoFlags int flags,
-            UserHandle user) {
+    public ApplicationInfo getApplicationInfo(@NonNull String packageName,
+            @ApplicationInfoFlags int flags, @NonNull UserHandle user)
+            throws PackageManager.NameNotFoundException {
+        Preconditions.checkNotNull(packageName, "packageName");
+        Preconditions.checkNotNull(packageName, "user");
         logErrorForInvalidProfileAccess(user);
         try {
-            return mService.getApplicationInfo(mContext.getPackageName(), packageName, flags, user);
+            final ApplicationInfo ai = mService
+                    .getApplicationInfo(mContext.getPackageName(), packageName, flags, user);
+            if (ai == null) {
+                throw new NameNotFoundException("Package " + packageName + " not found for user "
+                        + user.getIdentifier());
+            }
+            return ai;
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
@@ -1268,15 +1281,34 @@
      * an {@link #ACTION_CONFIRM_PIN_SHORTCUT} or {@link #ACTION_CONFIRM_PIN_APPWIDGET} intent
      * respectively to the default launcher app.
      *
-     * <p>Note the launcher may receive a request to pin a shortcut that is already pinned, because
-     * the user may actually want to have multiple icons of the same shortcut on the launcher.
-     * The launcher can tell this case by calling {@link ShortcutInfo#isPinned()} on the shortcut
-     * returned by {@link #getShortcutInfo()}.  In this case, calling {@link #accept()} is optional;
-     * even if the launcher does not call it, the shortcut is already pinned.  Also in this case,
-     * the {@code options} argument to {@link #accept(Bundle)} will be ignored.
+     * <h3>Request of the {@link #REQUEST_TYPE_SHORTCUT} type.
      *
-     * <p>For AppWidget pin requests launcher should send back the appwidget id as an extra for
-     * {@link #accept(Bundle)} as {@link android.appwidget.AppWidgetManager#EXTRA_APPWIDGET_ID}.
+     * <p>A {@link #REQUEST_TYPE_SHORTCUT} request represents a request to pin a
+     * {@link ShortcutInfo}.  If the launcher accepts a request, call {@link #accept()},
+     * or {@link #accept(Bundle)} with a null or empty Bundle.  No options are defined for
+     * pin-shortcuts requests.
+     *
+     * <p>{@link #getShortcutInfo()} always returns a non-null {@link ShortcutInfo} for this type.
+     *
+     * <p>The launcher may receive a request with a {@link ShortcutInfo} that is already pinned, in
+     * which case {@link ShortcutInfo#isPinned()} returns true.  This means the user wants to create
+     * another pinned shortcut for a shortcut that's already pinned.  If the launcher accepts it,
+     * {@link #accept()} must still be called even though the shortcut is already pinned, and
+     * create a new pinned shortcut icon for it.
+     *
+     * <p>See also {@link ShortcutManager} for more details.
+     *
+     * <h3>Request of the {@link #REQUEST_TYPE_APPWIDGET} type.
+     *
+     * <p>A {@link #REQUEST_TYPE_SHORTCUT} request represents a request to pin a
+     * an AppWidget.  If the launcher accepts a request, call {@link #accept(Bundle)} with
+     * the appwidget integer ID set to the
+     * {@link android.appwidget.AppWidgetManager#EXTRA_APPWIDGET_ID} extra.
+     *
+     * <p>{@link #getAppWidgetProviderInfo(Context)} always returns a non-null
+     * {@link AppWidgetProviderInfo} for this type.
+     *
+     * <p>See also {@link AppWidgetManager} for more details.
      *
      * @see #EXTRA_PIN_ITEM_REQUEST
      * @see #getPinItemRequest(Intent)
@@ -1306,8 +1338,9 @@
         }
 
         /**
-         * Represents the type of a request.  For now {@link #REQUEST_TYPE_SHORTCUT} is the only
-         * valid type.
+         * Represents the type of a request, which is one of the {@code REQUEST_TYPE_} constants.
+         *
+         * @return one of the {@code REQUEST_TYPE_} constants.
          */
         @RequestType
         public int getRequestType() {
@@ -1315,8 +1348,12 @@
         }
 
         /**
-         * {@link ShortcutInfo} sent by the requesting app.  Always non-null for a
-         * {@link #REQUEST_TYPE_SHORTCUT} request.
+         * {@link ShortcutInfo} sent by the requesting app.
+         * Always non-null for a {@link #REQUEST_TYPE_SHORTCUT} request, and always null for a
+         * different request type.
+         *
+         * @return requested {@link ShortcutInfo} when a request is of the
+         * {@link #REQUEST_TYPE_SHORTCUT} type.  Null otherwise.
          */
         @Nullable
         public ShortcutInfo getShortcutInfo() {
@@ -1328,8 +1365,12 @@
         }
 
         /**
-         * {@link AppWidgetProviderInfo} sent by the requesting app.  Always non-null for a
-         * {@link #REQUEST_TYPE_APPWIDGET} request.
+         * {@link AppWidgetProviderInfo} sent by the requesting app.
+         * Always non-null for a {@link #REQUEST_TYPE_APPWIDGET} request, and always null for a
+         * different request type.
+         *
+         * @return requested {@link AppWidgetProviderInfo} when a request is of the
+         * {@link #REQUEST_TYPE_APPWIDGET} type.  Null otherwise.
          */
         @Nullable
         public AppWidgetProviderInfo getAppWidgetProviderInfo(Context context) {
@@ -1347,6 +1388,11 @@
 
         /**
          * Any extras sent by the requesting app.
+         *
+         * @return For a shortcut request, this method always return null.  For an AppWidget
+         * request, this method returns the extras passed to the
+         * {@link android.appwidget.AppWidgetManager#requestPinAppWidget(
+         * ComponentName, Bundle, PendingIntent)} API.  See {@link AppWidgetManager} for details.
          */
         @Nullable
         public Bundle getExtras() {
@@ -1358,8 +1404,9 @@
         }
 
         /**
-         * Return {@code TRUE} if a request is valid -- i.e. {@link #accept(Bundle)} has not been
-         * called yet.
+         * Return whether a request is still valid.
+         *
+         * @return {@code TRUE} if a request is valid and {@link #accept(Bundle)} may be called.
          */
         public boolean isValid() {
             try {
@@ -1371,6 +1418,12 @@
 
         /**
          * Called by the receiving launcher app when the user accepts the request.
+         *
+         * @param options must be set for a {@link #REQUEST_TYPE_APPWIDGET} request.
+         *
+         * @return {@code TRUE} if the shortcut or the AppWidget has actually been pinned.
+         * {@code FALSE} if the item hasn't been pinned, for example, because the request had
+         * already been canceled, in which case the launcher must not pin the requested item.
          */
         public boolean accept(@Nullable Bundle options) {
             try {
@@ -1381,7 +1434,11 @@
         }
 
         /**
-         * Same as as {@link #accept(Bundle)} with no options.
+         * Called by the receiving launcher app when the user accepts the request, with no options.
+         *
+         * @return {@code TRUE} if the shortcut or the AppWidget has actually been pinned.
+         * {@code FALSE} if the item hasn't been pinned, for example, because the request had
+         * already been canceled, in which case the launcher must not pin the requested item.
          */
         public boolean accept() {
             return accept(/* options= */ null);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index e5c8f0d..09906be 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -6275,9 +6275,19 @@
      * Return the {@link ComponentName} of the activity providing Settings for the Instant App
      * resolver.
      *
-     * @see {@link android.content.intent#ACTION_INSTANT_APP_RESOLVER_SETTINGS}
+     * @see {@link android.content.Intent#ACTION_INSTANT_APP_RESOLVER_SETTINGS}
      * @hide
      */
     @SystemApi
     public abstract ComponentName getInstantAppResolverSettingsComponent();
+
+    /**
+     * Return the {@link ComponentName} of the activity responsible for installing instant
+     * applications.
+     *
+     * @see {@link android.content.Intent#ACTION_INSTALL_INSTANT_APP_PACKAGE}
+     * @hide
+     */
+    @SystemApi
+    public abstract ComponentName getInstantAppInstallerComponent();
 }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 430d8b1..1f78bff 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -64,8 +64,10 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PatternMatcher;
+import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.os.storage.StorageManager;
 import android.system.ErrnoException;
 import android.system.OsConstants;
 import android.system.StructStat;
@@ -116,6 +118,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
+import java.util.UUID;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.zip.ZipEntry;
 
@@ -2111,6 +2114,12 @@
                 pkg.mIsStaticOverlay = sa.getBoolean(
                         com.android.internal.R.styleable.AndroidManifestResourceOverlay_isStatic,
                         false);
+                final String propName = sa.getString(
+                        com.android.internal.R.styleable
+                        .AndroidManifestResourceOverlay_requiredSystemPropertyName);
+                final String propValue = sa.getString(
+                        com.android.internal.R.styleable
+                        .AndroidManifestResourceOverlay_requiredSystemPropertyValue);
                 sa.recycle();
 
                 if (pkg.mOverlayTarget == null) {
@@ -2118,15 +2127,22 @@
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return null;
                 }
+
                 if (pkg.mOverlayPriority < 0 || pkg.mOverlayPriority > 9999) {
                     outError[0] = "<overlay> priority must be between 0 and 9999";
                     mParseError =
                         PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return null;
                 }
-                if (pkg.mIsStaticOverlay) {
-                    // TODO(b/35742444): Need to support selection method based on a package name.
+
+                // check to see if overlay should be excluded based on system property condition
+                if (!checkOverlayRequiredSystemProperty(propName, propValue)) {
+                    Slog.i(TAG, "Skipping target and overlay pair " + pkg.mOverlayTarget + " and "
+                        + pkg.baseCodePath+ ": overlay ignored due to required system property: "
+                        + propName + " with value: " + propValue);
+                    return null;
                 }
+
                 XmlUtils.skipCurrentTag(parser);
 
             } else if (tagName.equals(TAG_KEY_SETS)) {
@@ -2531,6 +2547,25 @@
         return pkg;
     }
 
+    private boolean checkOverlayRequiredSystemProperty(String propName, String propValue) {
+
+        if (TextUtils.isEmpty(propName) || TextUtils.isEmpty(propValue)) {
+            if (!TextUtils.isEmpty(propName) || !TextUtils.isEmpty(propValue)) {
+                // malformed condition - incomplete
+                Slog.w(TAG, "Disabling overlay - incomplete property :'" + propName
+                    + "=" + propValue + "' - require both requiredSystemPropertyName"
+                    + " AND requiredSystemPropertyValue to be specified.");
+                return false;
+            }
+            // no valid condition set - so no exclusion criteria, overlay will be included.
+            return true;
+        }
+
+        // check property value - make sure it is both set and equal to expected value
+        final String currValue = SystemProperties.get(propName);
+        return (currValue != null && currValue.equals(propValue));
+    }
+
     /**
      * This is a pre-density application which will get scaled - instead of being pixel perfect.
      * This type of application is not resizable.
@@ -5741,11 +5776,14 @@
         }
 
         public void setApplicationVolumeUuid(String volumeUuid) {
+            final UUID storageUuid = StorageManager.convert(volumeUuid);
             this.applicationInfo.volumeUuid = volumeUuid;
+            this.applicationInfo.storageUuid = storageUuid;
             if (childPackages != null) {
                 final int packageCount = childPackages.size();
                 for (int i = 0; i < packageCount; i++) {
                     childPackages.get(i).applicationInfo.volumeUuid = volumeUuid;
+                    childPackages.get(i).applicationInfo.storageUuid = storageUuid;
                 }
             }
         }
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index e8e989f..f61032e 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -290,7 +290,8 @@
                         cameraId,
                         callback,
                         handler,
-                        characteristics);
+                        characteristics,
+                        mContext.getApplicationInfo().targetSdkVersion);
 
             ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();
 
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index e75b375..ab87f15 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -36,6 +36,7 @@
 import android.hardware.camera2.utils.SubmitInfo;
 import android.hardware.camera2.utils.SurfaceUtils;
 import android.hardware.ICameraService;
+import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -118,6 +119,8 @@
     private CameraCaptureSessionCore mCurrentSession;
     private int mNextSessionId = 0;
 
+    private final int mAppTargetSdkVersion;
+
     // Runnables for all state transitions, except error, which needs the
     // error code argument
 
@@ -234,7 +237,7 @@
     };
 
     public CameraDeviceImpl(String cameraId, StateCallback callback, Handler handler,
-                        CameraCharacteristics characteristics) {
+                        CameraCharacteristics characteristics, int appTargetSdkVersion) {
         if (cameraId == null || callback == null || handler == null || characteristics == null) {
             throw new IllegalArgumentException("Null argument given");
         }
@@ -242,6 +245,7 @@
         mDeviceCallback = callback;
         mDeviceHandler = handler;
         mCharacteristics = characteristics;
+        mAppTargetSdkVersion = appTargetSdkVersion;
 
         final int MAX_TAG_LEN = 23;
         String tag = String.format("CameraDevice-JV-%s", mCameraId);
@@ -671,6 +675,16 @@
         }
     }
 
+    private void overrideEnableZsl(CameraMetadataNative request, boolean newValue) {
+        Boolean enableZsl = request.get(CaptureRequest.CONTROL_ENABLE_ZSL);
+        if (enableZsl == null) {
+            // If enableZsl is not available, don't override.
+            return;
+        }
+
+        request.set(CaptureRequest.CONTROL_ENABLE_ZSL, newValue);
+    }
+
     @Override
     public CaptureRequest.Builder createCaptureRequest(int templateType)
             throws CameraAccessException {
@@ -681,6 +695,13 @@
 
             templatedRequest = mRemoteDevice.createDefaultRequest(templateType);
 
+            // If app target SDK is older than O, or it's not a still capture template, enableZsl
+            // must be false in the default request.
+            if (mAppTargetSdkVersion < Build.VERSION_CODES.O ||
+                    templateType != TEMPLATE_STILL_CAPTURE) {
+                overrideEnableZsl(templatedRequest, false);
+            }
+
             CaptureRequest.Builder builder = new CaptureRequest.Builder(
                     templatedRequest, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
 
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index 9b5ff29..167c46d 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -25,6 +25,7 @@
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.UUID;
 
 /**
  * A mapping from String keys to various {@link Parcelable} values.
@@ -476,6 +477,18 @@
     }
 
     /**
+     * Inserts a UUID value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a UUID object, or null
+     */
+    public void putUuid(@Nullable String key, @Nullable UUID value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
      * Inserts an array of Parcelable values into the mapping of this Bundle,
      * replacing any existing value for the given key.  Either key or value may
      * be null.
@@ -858,6 +871,26 @@
      * value is explicitly associated with the key.
      *
      * @param key a String, or null
+     * @return a UUID value, or null
+     */
+    @Nullable
+    public UUID getUuid(@Nullable String key) {
+        unparcel();
+        final Object o = mMap.get(key);
+        try {
+            return (UUID) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "UUID", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
      * @return a Bundle value, or null
      */
     @Nullable
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index c3836a3..c1647c7 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -16,8 +16,6 @@
 
 package android.os;
 
-import android.annotation.IntegerRes;
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -29,6 +27,9 @@
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 
+import dalvik.annotation.optimization.FastNative;
+import dalvik.system.VMRuntime;
+
 import libcore.util.SneakyThrow;
 
 import java.io.ByteArrayInputStream;
@@ -49,9 +50,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
-import dalvik.annotation.optimization.FastNative;
-import dalvik.system.VMRuntime;
+import java.util.UUID;
 
 /**
  * Container for a message (data and object references) that can
@@ -243,6 +242,7 @@
     private static final int VAL_SIZE = 26;
     private static final int VAL_SIZEF = 27;
     private static final int VAL_DOUBLEARRAY = 28;
+    private static final int VAL_UUID = 29;
 
     // The initial int32 in a Binder call's reply Parcel header:
     // Keep these in sync with libbinder's binder/Status.h.
@@ -831,6 +831,15 @@
     }
 
     /**
+     * Flatten a UUID into the parcel at the current dataPosition(),
+     * growing dataCapacity() if needed.
+     */
+    public final void writeUuid(UUID val) {
+        writeLong(val.getMostSignificantBits());
+        writeLong(val.getLeastSignificantBits());
+    }
+
+    /**
      * Flatten a List into the parcel at the current dataPosition(), growing
      * dataCapacity() if needed.  The List values are written using
      * {@link #writeValue} and must follow the specification there.
@@ -1678,6 +1687,9 @@
         } else if (v instanceof double[]) {
             writeInt(VAL_DOUBLEARRAY);
             writeDoubleArray((double[]) v);
+        } else if (v instanceof UUID) {
+            writeInt(VAL_UUID);
+            writeUuid((UUID) v);
         } else {
             Class<?> clazz = v.getClass();
             if (clazz.isArray() && clazz.getComponentType() == Object.class) {
@@ -2182,6 +2194,13 @@
     }
 
     /**
+     * Read a UUID from the parcel at the current dataPosition().
+     */
+    public final UUID readUuid() {
+        return new UUID(readLong(), readLong());
+    }
+
+    /**
      * Read and return a byte[] object from the parcel.
      */
     public final byte[] createByteArray() {
@@ -2731,6 +2750,9 @@
         case VAL_DOUBLEARRAY:
             return createDoubleArray();
 
+        case VAL_UUID:
+            return readUuid();
+
         default:
             int off = dataPosition() - 4;
             throw new RuntimeException(
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index b5af766..3942531 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -66,6 +66,7 @@
 
 import java.io.File;
 import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -77,6 +78,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
+import java.util.UUID;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -117,19 +119,66 @@
     public static final String UUID_PRIVATE_INTERNAL = null;
     /** {@hide} */
     public static final String UUID_PRIMARY_PHYSICAL = "primary_physical";
+    /** {@hide} */
+    public static final String UUID_SYSTEM = "system";
 
+    // NOTE: UUID constants below are namespaced
+    // uuid -v5 ad99aa3d-308e-4191-a200-ebcab371c0ad default
+    // uuid -v5 ad99aa3d-308e-4191-a200-ebcab371c0ad primary_physical
+    // uuid -v5 ad99aa3d-308e-4191-a200-ebcab371c0ad system
 
     /**
-     * Activity Action: Allows the user to manage their storage. This activity provides the ability
-     * to free up space on the device by deleting data such as apps.
+     * UUID representing the default internal storage of this device which
+     * provides {@link Environment#getDataDirectory()}.
      * <p>
-     * Input: Nothing.
+     * This value is constant across all devices and it will never change, and
+     * thus it cannot be used to uniquely identify a particular physical device.
+     *
+     * @see #getUuidForPath(File)
+     */
+    public static final UUID UUID_DEFAULT = UUID
+            .fromString("41217664-9172-527a-b3d5-edabb50a7d69");
+
+    /** {@hide} */
+    public static final UUID UUID_PRIMARY_PHYSICAL_ = UUID
+            .fromString("0f95a519-dae7-5abf-9519-fbd6209e05fd");
+
+    /** {@hide} */
+    public static final UUID UUID_SYSTEM_ = UUID
+            .fromString("5d258386-e60d-59e3-826d-0089cdd42cc0");
+
+    /**
+     * Activity Action: Allows the user to manage their storage. This activity
+     * provides the ability to free up space on the device by deleting data such
+     * as apps.
      * <p>
-     * Output: Nothing.
+     * If the sending application has a specific storage device or allocation
+     * size in mind, they can optionally define {@link #EXTRA_UUID} or
+     * {@link #EXTRA_REQUESTED_BYTES}, respectively.
      */
     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_MANAGE_STORAGE
-            = "android.os.storage.action.MANAGE_STORAGE";
+    public static final String ACTION_MANAGE_STORAGE = "android.os.storage.action.MANAGE_STORAGE";
+
+    /**
+     * Extra {@link UUID} used to indicate the storage volume where an
+     * application is interested in allocating or managing disk space.
+     *
+     * @see #ACTION_MANAGE_STORAGE
+     * @see #UUID_DEFAULT
+     * @see #getUuidForPath(File)
+     */
+    public static final String EXTRA_UUID = "android.os.storage.extra.UUID";
+
+    /**
+     * Extra used to indicate the total size (in bytes) that an application is
+     * interested in allocating.
+     * <p>
+     * When defined, the management UI will help guide the user to free up
+     * enough disk space to reach this requested value.
+     *
+     * @see #ACTION_MANAGE_STORAGE
+     */
+    public static final String EXTRA_REQUESTED_BYTES = "android.os.storage.extra.REQUESTED_BYTES";
 
     /** {@hide} */
     public static final int DEBUG_FORCE_ADOPTABLE = 1 << 0;
@@ -668,34 +717,44 @@
         }
     }
 
-    /** {@hide} */
-    public @Nullable String findUuidForPath(File path) {
+    /**
+     * Return a UUID identifying the storage volume that hosts the given
+     * filesystem path.
+     * <p>
+     * If this path is hosted by the default internal storage of the device at
+     * {@link Environment#getDataDirectory()}, the returned value will be
+     * {@link #UUID_DEFAULT}.
+     *
+     * @throws IOException when the storage device at the given path isn't
+     *             present, or when it doesn't have a valid UUID.
+     */
+    public @NonNull UUID getUuidForPath(@NonNull File path) throws IOException {
         Preconditions.checkNotNull(path);
         final String pathString = path.getAbsolutePath();
         if (FileUtils.contains(Environment.getDataDirectory().getAbsolutePath(), pathString)) {
-            return StorageManager.UUID_PRIVATE_INTERNAL;
+            return UUID_DEFAULT;
         }
         try {
             for (VolumeInfo vol : mStorageManager.getVolumes(0)) {
                 if (vol.path != null && FileUtils.contains(vol.path, pathString)) {
                     // TODO: verify that emulated adopted devices have UUID of
                     // underlying volume
-                    return vol.fsUuid;
+                    return convert(vol.fsUuid);
                 }
             }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
-        throw new IllegalStateException("Failed to find a storage device for " + path);
+        throw new FileNotFoundException("Failed to find a storage device for " + path);
     }
 
     /** {@hide} */
-    public @Nullable File findPathForUuid(String volumeUuid) {
+    public @NonNull File findPathForUuid(String volumeUuid) throws FileNotFoundException {
         final VolumeInfo vol = findVolumeByQualifiedUuid(volumeUuid);
         if (vol != null) {
             return vol.getPath();
         }
-        throw new IllegalStateException("Failed to find a storage device for " + volumeUuid);
+        throw new FileNotFoundException("Failed to find a storage device for " + volumeUuid);
     }
 
     /** {@hide} */
@@ -1451,7 +1510,7 @@
 
     /**
      * Return quota size in bytes for all cached data belonging to the calling
-     * app on the filesystem that hosts the given path.
+     * app on the given storage volume.
      * <p>
      * If your app goes above this quota, your cached files will be some of the
      * first to be deleted when additional disk space is needed. Conversely, if
@@ -1466,21 +1525,34 @@
      * as a single unit.
      * </p>
      *
-     * @see #getCacheSizeBytes(File)
+     * @param storageUuid the UUID of the storage volume that you're interested
+     *            in. The UUID for a specific path can be obtained using
+     *            {@link #getUuidForPath(File)}.
+     * @throws IOException when the storage device isn't present, or when it
+     *             doesn't support cache quotas.
+     * @see #getCacheSizeBytes(UUID)
      */
-    public long getCacheQuotaBytes(File path) {
+    public long getCacheQuotaBytes(@NonNull UUID storageUuid) throws IOException {
         try {
-            final String volumeUuid = findUuidForPath(path);
             final ApplicationInfo app = mContext.getApplicationInfo();
-            return mStorageManager.getCacheQuotaBytes(volumeUuid, app.uid);
+            return mStorageManager.getCacheQuotaBytes(convert(storageUuid), app.uid);
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
+    /** @removed */
+    @Deprecated
+    public long getCacheQuotaBytes(@NonNull File path) throws IOException {
+        return getCacheQuotaBytes(getUuidForPath(path));
+    }
+
     /**
      * Return total size in bytes of all cached data belonging to the calling
-     * app on the filesystem that hosts the given path.
+     * app on the given storage volume.
      * <p>
      * Cached data tracked by this method always includes
      * {@link Context#getCacheDir()} and {@link Context#getCodeCacheDir()}, and
@@ -1493,13 +1565,20 @@
      * as a single unit.
      * </p>
      *
-     * @see #getCacheQuotaBytes()
+     * @param storageUuid the UUID of the storage volume that you're interested
+     *            in. The UUID for a specific path can be obtained using
+     *            {@link #getUuidForPath(File)}.
+     * @throws IOException when the storage device isn't present, or when it
+     *             doesn't support cache quotas.
+     * @see #getCacheQuotaBytes(UUID)
      */
-    public long getCacheSizeBytes(File path) {
+    public long getCacheSizeBytes(@NonNull UUID storageUuid) throws IOException {
         try {
-            final String volumeUuid = findUuidForPath(path);
             final ApplicationInfo app = mContext.getApplicationInfo();
-            return mStorageManager.getCacheSizeBytes(volumeUuid, app.uid);
+            return mStorageManager.getCacheSizeBytes(convert(storageUuid), app.uid);
+        } catch (ParcelableException e) {
+            e.maybeRethrow(IOException.class);
+            throw new RuntimeException(e);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1507,25 +1586,31 @@
 
     /** @removed */
     @Deprecated
-    public long getCacheQuotaBytes() {
+    public long getCacheSizeBytes(@NonNull File path) throws IOException {
+        return getCacheSizeBytes(getUuidForPath(path));
+    }
+
+    /** @removed */
+    @Deprecated
+    public long getCacheQuotaBytes() throws IOException {
         return getCacheQuotaBytes(mContext.getCacheDir());
     }
 
     /** @removed */
     @Deprecated
-    public long getCacheSizeBytes() {
+    public long getCacheSizeBytes() throws IOException {
         return getCacheSizeBytes(mContext.getCacheDir());
     }
 
     /** @removed */
     @Deprecated
-    public long getExternalCacheQuotaBytes() {
+    public long getExternalCacheQuotaBytes() throws IOException {
         return getCacheQuotaBytes(mContext.getExternalCacheDir());
     }
 
     /** @removed */
     @Deprecated
-    public long getExternalCacheSizeBytes() {
+    public long getExternalCacheSizeBytes() throws IOException {
         return getCacheSizeBytes(mContext.getExternalCacheDir());
     }
 
@@ -1542,8 +1627,8 @@
      * this flag to take effect.
      * </p>
      *
-     * @see #getAllocatableBytes(File, int)
-     * @see #allocateBytes(File, long, int)
+     * @see #getAllocatableBytes(UUID, int)
+     * @see #allocateBytes(UUID, long, int)
      * @see #allocateBytes(FileDescriptor, long, int)
      */
     @RequiresPermission(android.Manifest.permission.ALLOCATE_AGGRESSIVE)
@@ -1558,32 +1643,43 @@
 
     /**
      * Return the maximum number of new bytes that your app can allocate for
-     * itself using {@link #allocateBytes(File, long, int)} at the given path.
-     * This value is typically larger than {@link File#getUsableSpace()}, since
-     * the system may be willing to delete cached files to satisfy an allocation
-     * request.
+     * itself on the given storage volume. This value is typically larger than
+     * {@link File#getUsableSpace()}, since the system may be willing to delete
+     * cached files to satisfy an allocation request. You can then allocate
+     * space for yourself using {@link #allocateBytes(UUID, long, int)} or
+     * {@link #allocateBytes(FileDescriptor, long, int)}.
      * <p>
      * This method is best used as a pre-flight check, such as deciding if there
      * is enough space to store an entire music album before you allocate space
      * for each audio file in the album. Attempts to allocate disk space beyond
      * the returned value will fail.
+     * <p>
+     * If the returned value is not large enough for the data you'd like to
+     * store, you can launch {@link #ACTION_MANAGE_STORAGE} with the
+     * {@link #EXTRA_UUID} and {@link #EXTRA_REQUESTED_BYTES} options to help
+     * involve the user in freeing up disk space.
      * <p class="note">
      * Note: if your app uses the {@code android:sharedUserId} manifest feature,
      * then allocatable space for all packages in your shared UID is tracked
      * together as a single unit.
      * </p>
      *
-     * @param path the path where you're considering allocating disk space,
-     *            since allocatable space can vary widely depending on the
-     *            underlying storage device.
+     * @param storageUuid the UUID of the storage volume where you're
+     *            considering allocating disk space, since allocatable space can
+     *            vary widely depending on the underlying storage device. The
+     *            UUID for a specific path can be obtained using
+     *            {@link #getUuidForPath(File)}.
      * @param flags to apply to the request.
      * @return the maximum number of new bytes that the calling app can allocate
-     *         using {@link #allocateBytes(File, long, int)}.
+     *         using {@link #allocateBytes(UUID, long, int)} or
+     *         {@link #allocateBytes(FileDescriptor, long, int)}.
+     * @throws IOException when the storage device isn't present, or when it
+     *             doesn't support allocating space.
      */
-    public long getAllocatableBytes(File path, @AllocateFlags int flags) throws IOException {
+    public long getAllocatableBytes(@NonNull UUID storageUuid, @AllocateFlags int flags)
+            throws IOException {
         try {
-            final String volumeUuid = findUuidForPath(path);
-            return mStorageManager.getAllocatableBytes(volumeUuid, flags);
+            return mStorageManager.getAllocatableBytes(convert(storageUuid), flags);
         } catch (ParcelableException e) {
             e.maybeRethrow(IOException.class);
             throw new RuntimeException(e);
@@ -1592,28 +1688,40 @@
         }
     }
 
+    /** @removed */
+    @Deprecated
+    public long getAllocatableBytes(@NonNull File path, @AllocateFlags int flags)
+            throws IOException {
+        return getAllocatableBytes(getUuidForPath(path), flags);
+    }
+
     /**
-     * Allocate the requested number of bytes for your application to use at the
-     * given path. This will cause the system to delete any cached files
-     * necessary to satisfy your request.
+     * Allocate the requested number of bytes for your application to use on the
+     * given storage volume. This will cause the system to delete any cached
+     * files necessary to satisfy your request.
      * <p>
      * Attempts to allocate disk space beyond the value returned by
-     * {@link #getAllocatableBytes(File, int)} will fail.
+     * {@link #getAllocatableBytes(UUID, int)} will fail.
      * <p>
      * Since multiple apps can be running simultaneously, this method may be
      * subject to race conditions. If possible, consider using
      * {@link #allocateBytes(FileDescriptor, long, int)} which will guarantee
      * that bytes are allocated to an opened file.
      *
-     * @param path the path where you'd like to allocate disk space.
+     * @param storageUuid the UUID of the storage volume where you'd like to
+     *            allocate disk space. The UUID for a specific path can be
+     *            obtained using {@link #getUuidForPath(File)}.
      * @param bytes the number of bytes to allocate.
      * @param flags to apply to the request.
-     * @see #getAllocatableBytes(File, int)
+     * @throws IOException when the storage device isn't present, or when it
+     *             doesn't support allocating space, or if the device had
+     *             trouble allocating the requested space.
+     * @see #getAllocatableBytes(UUID, int)
      */
-    public void allocateBytes(File path, long bytes, @AllocateFlags int flags) throws IOException {
+    public void allocateBytes(@NonNull UUID storageUuid, long bytes, @AllocateFlags int flags)
+            throws IOException {
         try {
-            final String volumeUuid = findUuidForPath(path);
-            mStorageManager.allocateBytes(volumeUuid, bytes, flags);
+            mStorageManager.allocateBytes(convert(storageUuid), bytes, flags);
         } catch (ParcelableException e) {
             e.maybeRethrow(IOException.class);
         } catch (RemoteException e) {
@@ -1621,13 +1729,20 @@
         }
     }
 
+    /** @removed */
+    @Deprecated
+    public void allocateBytes(@NonNull File path, long bytes, @AllocateFlags int flags)
+            throws IOException {
+        allocateBytes(getUuidForPath(path), bytes, flags);
+    }
+
     /**
      * Allocate the requested number of bytes for your application to use in the
      * given open file. This will cause the system to delete any cached files
      * necessary to satisfy your request.
      * <p>
      * Attempts to allocate disk space beyond the value returned by
-     * {@link #getAllocatableBytes(File, int)} will fail.
+     * {@link #getAllocatableBytes(UUID, int)} will fail.
      * <p>
      * This method guarantees that bytes have been allocated to the opened file,
      * otherwise it will throw if fast allocation is not possible. Fast
@@ -1636,9 +1751,15 @@
      *
      * @param fd the open file that you'd like to allocate disk space for.
      * @param bytes the number of bytes to allocate. This is the desired final
-     *            size of the open file.
+     *            size of the open file. If the open file is smaller than this
+     *            requested size, it will be extended without modifying any
+     *            existing contents. If the open file is larger than this
+     *            requested size, it will be truncated.
      * @param flags to apply to the request.
-     * @see #getAllocatableBytes(File, int)
+     * @throws IOException when the storage device isn't present, or when it
+     *             doesn't support allocating space, or if the device had
+     *             trouble allocating the requested space.
+     * @see #getAllocatableBytes(UUID, int)
      * @see Environment#isExternalStorageEmulated(File)
      */
     public void allocateBytes(FileDescriptor fd, long bytes, @AllocateFlags int flags)
@@ -1777,6 +1898,32 @@
         return isCacheBehavior(path, XATTR_CACHE_TOMBSTONE);
     }
 
+    /** {@hide} */
+    public static UUID convert(String uuid) {
+        if (Objects.equals(uuid, UUID_PRIVATE_INTERNAL)) {
+            return UUID_DEFAULT;
+        } else if (Objects.equals(uuid, UUID_PRIMARY_PHYSICAL)) {
+            return UUID_PRIMARY_PHYSICAL_;
+        } else if (Objects.equals(uuid, UUID_SYSTEM)) {
+            return UUID_SYSTEM_;
+        } else {
+            return UUID.fromString(uuid);
+        }
+    }
+
+    /** {@hide} */
+    public static String convert(UUID storageUuid) {
+        if (UUID_DEFAULT.equals(storageUuid)) {
+            return UUID_PRIVATE_INTERNAL;
+        } else if (UUID_PRIMARY_PHYSICAL_.equals(storageUuid)) {
+            return UUID_PRIMARY_PHYSICAL;
+        } else if (UUID_SYSTEM_.equals(storageUuid)) {
+            return UUID_SYSTEM;
+        } else {
+            return storageUuid.toString();
+        }
+    }
+
     private final Object mFuseAppLoopLock = new Object();
 
     @GuardedBy("mFuseAppLoopLock")
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 539559d..c6ea958 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8330,7 +8330,6 @@
          * enabled state.
          * @hide
          */
-        @SystemApi
         public static final String NETWORK_RECOMMENDATIONS_ENABLED =
                 "network_recommendations_enabled";
 
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index 258d257..7f960df 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -21,6 +21,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.assist.AssistStructure;
 import android.content.IntentSender;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -158,6 +159,7 @@
     private final AutofillId[] mRequiredIds;
     private final AutofillId[] mOptionalIds;
     private final CharSequence mDescription;
+    private final boolean mSaveOnAllViewsInvisible;
 
     private SaveInfo(Builder builder) {
         mType = builder.mType;
@@ -166,6 +168,7 @@
         mRequiredIds = builder.mRequiredIds;
         mOptionalIds = builder.mOptionalIds;
         mDescription = builder.mDescription;
+        mSaveOnAllViewsInvisible = builder.mSaveOnAllViewsInvisible;
     }
 
     /** @hide */
@@ -194,6 +197,11 @@
     }
 
     /** @hide */
+    public boolean saveOnAllViewsInvisible() {
+        return mSaveOnAllViewsInvisible;
+    }
+
+    /** @hide */
     public CharSequence getDescription() {
         return mDescription;
     }
@@ -211,6 +219,7 @@
         private AutofillId[] mOptionalIds;
         private CharSequence mDescription;
         private boolean mDestroyed;
+        private boolean mSaveOnAllViewsInvisible;
 
         /**
          * Creates a new builder.
@@ -259,6 +268,21 @@
         }
 
         /**
+         * Usually {@link AutofillService#onSaveRequest(AssistStructure, Bundle, SaveCallback)}
+         * is called once the activity finishes. If this property is set it is called once all
+         * autofillable or saved views become invisible.
+         *
+         * @param saveOnAllViewsInvisible Set to {@code true} if the data should be saved once
+         *                                all the views become invisible.
+         * @return This builder.
+         */
+        public @NonNull Builder setSaveOnAllViewsInvisible(boolean saveOnAllViewsInvisible) {
+            throwIfDestroyed();
+            mSaveOnAllViewsInvisible = saveOnAllViewsInvisible;
+            return this;
+        }
+
+        /**
          * Sets the ids of additional, optional views the service would be interested to save.
          *
          * <p>See {@link SaveInfo} for more info.
@@ -354,6 +378,7 @@
                 .append(", requiredIds=").append(Arrays.toString(mRequiredIds))
                 .append(", optionalIds=").append(Arrays.toString(mOptionalIds))
                 .append(", description=").append(mDescription)
+                .append(", saveOnNoVisibleTrackedViews=").append(mSaveOnAllViewsInvisible)
                 .append("]").toString();
     }
 
@@ -374,6 +399,7 @@
         parcel.writeParcelable(mNegativeActionListener, flags);
         parcel.writeParcelableArray(mOptionalIds, flags);
         parcel.writeCharSequence(mDescription);
+        parcel.writeBoolean(mSaveOnAllViewsInvisible);
     }
 
     public static final Parcelable.Creator<SaveInfo> CREATOR = new Parcelable.Creator<SaveInfo>() {
@@ -387,6 +413,7 @@
             builder.setNegativeAction(parcel.readCharSequence(), parcel.readParcelable(null));
             builder.setOptionalIds(parcel.readParcelableArray(null, AutofillId.class));
             builder.setDescription(parcel.readCharSequence());
+            builder.setSaveOnAllViewsInvisible(parcel.readBoolean());
             return builder.build();
         }
 
diff --git a/core/java/android/service/notification/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl
index dc1a70d..ed44f25 100644
--- a/core/java/android/service/notification/INotificationListener.aidl
+++ b/core/java/android/service/notification/INotificationListener.aidl
@@ -18,6 +18,7 @@
 
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
+import android.os.UserHandle;
 import android.service.notification.IStatusBarNotificationHolder;
 import android.service.notification.StatusBarNotification;
 import android.service.notification.NotificationRankingUpdate;
@@ -36,8 +37,8 @@
     void onInterruptionFilterChanged(int interruptionFilter);
 
     // companion device managers only
-    void onNotificationChannelModification(String pkgName, in NotificationChannel channel, int modificationType);
-    void onNotificationChannelGroupModification(String pkgName, in NotificationChannelGroup group, int modificationType);
+    void onNotificationChannelModification(String pkgName, in UserHandle user, in NotificationChannel channel, int modificationType);
+    void onNotificationChannelGroupModification(String pkgName, in UserHandle user, in NotificationChannelGroup group, int modificationType);
 
     // rankers only
     void onNotificationEnqueued(in IStatusBarNotificationHolder notificationHolder);
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 4833be3..00bd304 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -49,6 +49,7 @@
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
@@ -231,25 +232,25 @@
 
     /**
      * Channel or group modification reason provided to
-     * {@link #onNotificationChannelModified(String, NotificationChannel, int)} or
-     * {@link #onNotificationChannelGroupModified(String, NotificationChannelGroup, int)}- the
-     * provided object was created.
+     * {@link #onNotificationChannelModified(String, UserHandle,NotificationChannel, int)} or
+     * {@link #onNotificationChannelGroupModified(String, UserHandle, NotificationChannelGroup,
+     * int)}- the provided object was created.
      */
     public static final int NOTIFICATION_CHANNEL_OR_GROUP_ADDED = 1;
 
     /**
      * Channel or group modification reason provided to
-     * {@link #onNotificationChannelModified(String, NotificationChannel, int)} or
-     * {@link #onNotificationChannelGroupModified(String, NotificationChannelGroup, int)}- the
-     * provided object was updated.
+     * {@link #onNotificationChannelModified(String, UserHandle, NotificationChannel, int)} or
+     * {@link #onNotificationChannelGroupModified(String, UserHandle,NotificationChannelGroup, int)}
+     * - the provided object was updated.
      */
     public static final int NOTIFICATION_CHANNEL_OR_GROUP_UPDATED = 2;
 
     /**
      * Channel or group modification reason provided to
-     * {@link #onNotificationChannelModified(String, NotificationChannel, int)} or
-     * {@link #onNotificationChannelGroupModified(String, NotificationChannelGroup, int)}- the
-     * provided object was deleted.
+     * {@link #onNotificationChannelModified(String, UserHandle, NotificationChannel, int)} or
+     * {@link #onNotificationChannelGroupModified(String, UserHandle, NotificationChannelGroup,
+     * int)}- the provided object was deleted.
      */
     public static final int NOTIFICATION_CHANNEL_OR_GROUP_DELETED = 3;
 
@@ -432,13 +433,14 @@
      * device} in order to receive this callback.
      *
      * @param pkg The package the channel belongs to.
+     * @param user The user on which the change was made.
      * @param channel The channel that has changed.
      * @param modificationType One of {@link #NOTIFICATION_CHANNEL_OR_GROUP_ADDED},
      *                   {@link #NOTIFICATION_CHANNEL_OR_GROUP_UPDATED},
      *                   {@link #NOTIFICATION_CHANNEL_OR_GROUP_DELETED}.
      */
-    public void onNotificationChannelModified(String pkg, NotificationChannel channel,
-            @ChannelOrGroupModificationTypes int modificationType) {
+    public void onNotificationChannelModified(String pkg, UserHandle user,
+            NotificationChannel channel, @ChannelOrGroupModificationTypes int modificationType) {
         // optional
     }
 
@@ -449,13 +451,14 @@
      * device} in order to receive this callback.
      *
      * @param pkg The package the group belongs to.
+     * @param user The user on which the change was made.
      * @param group The group that has changed.
      * @param modificationType One of {@link #NOTIFICATION_CHANNEL_OR_GROUP_ADDED},
      *                   {@link #NOTIFICATION_CHANNEL_OR_GROUP_UPDATED},
      *                   {@link #NOTIFICATION_CHANNEL_OR_GROUP_DELETED}.
      */
-    public void onNotificationChannelGroupModified(String pkg, NotificationChannelGroup group,
-            @ChannelOrGroupModificationTypes int modificationType) {
+    public void onNotificationChannelGroupModified(String pkg, UserHandle user,
+            NotificationChannelGroup group, @ChannelOrGroupModificationTypes int modificationType) {
         // optional
     }
 
@@ -661,21 +664,24 @@
 
 
     /**
-     * Updates a notification channel for a given package. This should only be used to reflect
-     * changes a user has made to the channel via the listener's user interface.
+     * Updates a notification channel for a given package for a given user. This should only be used
+     * to reflect changes a user has made to the channel via the listener's user interface.
      *
+     * <p>This method will throw a security exception if you don't have access to notifications
+     * for the given user.</p>
      * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
      * device} in order to use this method.
      *
      * @param pkg The package the channel belongs to.
+     * @param user The user the channel belongs to.
      * @param channel the channel to update.
      */
-    public final void updateNotificationChannel(@NonNull String pkg,
+    public final void updateNotificationChannel(@NonNull String pkg, @NonNull UserHandle user,
             @NonNull NotificationChannel channel) {
         if (!isBound()) return;
         try {
             getNotificationInterface().updateNotificationChannelFromPrivilegedListener(
-                    mWrapper, pkg, channel);
+                    mWrapper, pkg, user, channel);
         } catch (RemoteException e) {
             Log.v(TAG, "Unable to contact notification manager", e);
             throw e.rethrowFromSystemServer();
@@ -683,19 +689,22 @@
     }
 
     /**
-     * Returns all notification channels belonging to the given package.
+     * Returns all notification channels belonging to the given package for a given user.
      *
+     * <p>This method will throw a security exception if you don't have access to notifications
+     * for the given user.</p>
      * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
      * device} in order to use this method.
      *
      * @param pkg The package to retrieve channels for.
      */
-    public final List<NotificationChannel> getNotificationChannels(@NonNull String pkg) {
+    public final List<NotificationChannel> getNotificationChannels(@NonNull String pkg,
+            @NonNull UserHandle user) {
         if (!isBound()) return null;
         try {
 
             return getNotificationInterface().getNotificationChannelsFromPrivilegedListener(
-                    mWrapper, pkg).getList();
+                    mWrapper, pkg, user).getList();
         } catch (RemoteException e) {
             Log.v(TAG, "Unable to contact notification manager", e);
             throw e.rethrowFromSystemServer();
@@ -703,19 +712,22 @@
     }
 
     /**
-     * Returns all notification channel groups belonging to the given package.
+     * Returns all notification channel groups belonging to the given package for a given user.
      *
+     * <p>This method will throw a security exception if you don't have access to notifications
+     * for the given user.</p>
      * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
      * device} in order to use this method.
      *
      * @param pkg The package to retrieve channel groups for.
      */
-    public final List<NotificationChannelGroup> getNotificationChannelGroups(@NonNull String pkg) {
+    public final List<NotificationChannelGroup> getNotificationChannelGroups(@NonNull String pkg,
+            @NonNull UserHandle user) {
         if (!isBound()) return null;
         try {
 
             return getNotificationInterface().getNotificationChannelGroupsFromPrivilegedListener(
-                    mWrapper, pkg).getList();
+                    mWrapper, pkg, user).getList();
         } catch (RemoteException e) {
             Log.v(TAG, "Unable to contact notification manager", e);
             throw e.rethrowFromSystemServer();
@@ -1252,24 +1264,27 @@
         }
 
         @Override
-        public void onNotificationChannelModification(String pkgName, NotificationChannel channel,
+        public void onNotificationChannelModification(String pkgName, UserHandle user,
+                NotificationChannel channel,
                 @ChannelOrGroupModificationTypes int modificationType) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = pkgName;
-            args.arg2 = channel;
-            args.arg3 = modificationType;
+            args.arg2 = user;
+            args.arg3 = channel;
+            args.arg4 = modificationType;
             mHandler.obtainMessage(
                     MyHandler.MSG_ON_NOTIFICATION_CHANNEL_MODIFIED, args).sendToTarget();
         }
 
         @Override
-        public void onNotificationChannelGroupModification(String pkgName,
+        public void onNotificationChannelGroupModification(String pkgName, UserHandle user,
                 NotificationChannelGroup group,
                 @ChannelOrGroupModificationTypes int modificationType) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = pkgName;
-            args.arg2 = group;
-            args.arg3 = modificationType;
+            args.arg2 = user;
+            args.arg3 = group;
+            args.arg4 = modificationType;
             mHandler.obtainMessage(
                     MyHandler.MSG_ON_NOTIFICATION_CHANNEL_GROUP_MODIFIED, args).sendToTarget();
         }
@@ -1841,17 +1856,19 @@
                 case MSG_ON_NOTIFICATION_CHANNEL_MODIFIED: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     String pkgName = (String) args.arg1;
-                    NotificationChannel channel = (NotificationChannel) args.arg2;
-                    int modificationType = (int) args.arg3;
-                    onNotificationChannelModified(pkgName, channel, modificationType);
+                    UserHandle user= (UserHandle) args.arg2;
+                    NotificationChannel channel = (NotificationChannel) args.arg3;
+                    int modificationType = (int) args.arg4;
+                    onNotificationChannelModified(pkgName, user, channel, modificationType);
                 } break;
 
                 case MSG_ON_NOTIFICATION_CHANNEL_GROUP_MODIFIED: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     String pkgName = (String) args.arg1;
-                    NotificationChannelGroup group = (NotificationChannelGroup) args.arg2;
-                    int modificationType = (int) args.arg3;
-                    onNotificationChannelGroupModified(pkgName, group, modificationType);
+                    UserHandle user = (UserHandle) args.arg2;
+                    NotificationChannelGroup group = (NotificationChannelGroup) args.arg3;
+                    int modificationType = (int) args.arg4;
+                    onNotificationChannelGroupModified(pkgName, user, group, modificationType);
                 } break;
             }
         }
diff --git a/core/java/android/view/IPinnedStackController.aidl b/core/java/android/view/IPinnedStackController.aidl
index 2fe98c0..dbeb747 100644
--- a/core/java/android/view/IPinnedStackController.aidl
+++ b/core/java/android/view/IPinnedStackController.aidl
@@ -28,4 +28,9 @@
      * Notifies the controller that the PiP is currently minimized.
      */
     oneway void setIsMinimized(boolean isMinimized);
+
+    /**
+     * @return what WM considers to be the current device rotation.
+     */
+    int getDisplayRotation();
 }
diff --git a/core/java/android/view/IPinnedStackListener.aidl b/core/java/android/view/IPinnedStackListener.aidl
index 782f349..9382741 100644
--- a/core/java/android/view/IPinnedStackListener.aidl
+++ b/core/java/android/view/IPinnedStackListener.aidl
@@ -41,9 +41,13 @@
      * current state with the aspect ratio applied.  The {@param animatingBounds} are provided
      * to indicate the current target bounds of the pinned stack (the final bounds if animating,
      * the current bounds if not), which may be helpful in calculating dependent animation bounds.
+     *
+     * The {@param displayRotation} is provided so that the client can verify when making certain
+     * calls that it will not provide stale information based on an old display rotation (ie. if
+     * the WM has changed in the mean time but the client has not received onMovementBoundsChanged).
      */
     void onMovementBoundsChanged(in Rect insetBounds, in Rect normalBounds, in Rect animatingBounds,
-            boolean fromImeAdjustement);
+            boolean fromImeAdjustement, int displayRotation);
 
     /**
      * Called when window manager decides to adjust the pinned stack bounds because of the IME, or
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 172ad8d..7d2d77e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -66,6 +66,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Message;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
@@ -4380,6 +4381,9 @@
     @Nullable
     private RoundScrollbarRenderer mRoundScrollbarRenderer;
 
+    /** Used to delay visibility updates sent to the autofill manager */
+    private Handler mVisibilityChangeForAutofillHandler;
+
     /**
      * Simple constructor to use when creating a view from code.
      *
@@ -11696,6 +11700,30 @@
         if (fg != null && isVisible != fg.isVisible()) {
             fg.setVisible(isVisible, false);
         }
+
+        if (isAutofillable()) {
+            AutofillManager afm = getAutofillManager();
+
+            if (afm != null && getAccessibilityViewId() > LAST_APP_ACCESSIBILITY_ID) {
+                if (mVisibilityChangeForAutofillHandler != null) {
+                    mVisibilityChangeForAutofillHandler.removeMessages(0);
+                }
+
+                // If the view is in the background but still part of the hierarchy this is called
+                // with isVisible=false. Hence visibility==false requires further checks
+                if (isVisible) {
+                    afm.notifyViewVisibilityChange(this, true);
+                } else {
+                    if (mVisibilityChangeForAutofillHandler == null) {
+                        mVisibilityChangeForAutofillHandler =
+                                new VisibilityChangeForAutofillHandler(afm, this);
+                    }
+                    // Let current operation (e.g. removal of the view from the hierarchy)
+                    // finish before checking state
+                    mVisibilityChangeForAutofillHandler.obtainMessage(0, this).sendToTarget();
+                }
+            }
+        }
     }
 
     /**
@@ -24492,6 +24520,27 @@
     }
 
     /**
+     * When a view becomes invisible checks if autofill considers the view invisible too. This
+     * happens after the regular removal operation to make sure the operation is finished by the
+     * time this is called.
+     */
+    private static class VisibilityChangeForAutofillHandler extends Handler {
+        private final AutofillManager mAfm;
+        private final View mView;
+
+        private VisibilityChangeForAutofillHandler(@NonNull AutofillManager afm,
+                @NonNull View view) {
+            mAfm = afm;
+            mView = view;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            mAfm.notifyViewVisibilityChange(mView, mView.isShown());
+        }
+    }
+
+    /**
      * Base class for derived classes that want to save and restore their own
      * state in {@link android.view.View#onSaveInstanceState()}.
      */
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a7ececf..080ffeb 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1561,6 +1561,16 @@
         host.dispatchApplyWindowInsets(getWindowInsets(true /* forceConstruct */));
     }
 
+    /**
+     * @return the last content insets for use in adjusting the source hint rect for the
+     * picture-in-picture transition.
+     *
+     * @hide
+     */
+    public Rect getLastContentInsets() {
+        return mAttachInfo.mContentInsets;
+    }
+
     private static boolean shouldUseDisplaySize(final WindowManager.LayoutParams lp) {
         return lp.type == TYPE_STATUS_BAR_PANEL
                 || lp.type == TYPE_INPUT_METHOD
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index 6dbc09c..bf0e10f 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -303,13 +303,16 @@
      *                         hidden, no matter how WindowManagerService will react / has reacted
      *                         to corresponding API calls.  Note that this state is not guaranteed
      *                         to be synchronized with state in WindowManagerService.
+     * @param dismissImeOnBackKeyPressed {@code true} if the software keyboard is shown and the back
+     *                                   key is expected to dismiss the software keyboard.
      * @param targetWindowToken token to identify the target window that the IME is associated with.
      *                          {@code null} when application, system, or the IME itself decided to
      *                          change its window visibility before being associated with any target
      *                          window.
      */
     public abstract void updateInputMethodWindowStatus(@NonNull IBinder imeToken,
-            boolean imeWindowVisible, @Nullable IBinder targetWindowToken);
+            boolean imeWindowVisible, boolean dismissImeOnBackKeyPressed,
+            @Nullable IBinder targetWindowToken);
 
     /**
       * Returns true when the hardware keyboard is available.
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index bb6e0ee..030c78b 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -1537,6 +1537,18 @@
     public void setLastInputMethodWindowLw(WindowState ime, WindowState target);
 
     /**
+     * An internal callback (from InputMethodManagerService) to notify a state change regarding
+     * whether the back key should dismiss the software keyboard (IME) or not.
+     *
+     * @param newValue {@code true} if the software keyboard is shown and the back key is expected
+     *                 to dismiss the software keyboard.
+     * @hide
+     */
+    default void setDismissImeOnBackKeyPressed(boolean newValue) {
+        // Default implementation does nothing.
+    }
+
+    /**
      * Show the recents task list app.
      * @hide
      */
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index ec6559c..f9f400d 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -32,6 +32,7 @@
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.View;
@@ -143,6 +144,10 @@
     @GuardedBy("mLock")
     @Nullable private ParcelableMap mLastAutofilledData;
 
+    /** If view tracking is enabled, contains the tracking state */
+    @GuardedBy("mLock")
+    @Nullable private TrackedViews mTrackedViews;
+
     /** @hide */
     public interface AutofillClient {
         /**
@@ -177,6 +182,20 @@
          * @return Whether the UI was hidden.
          */
         boolean autofillCallbackRequestHideFillUi();
+
+        /**
+         * Checks if the view is currently attached and visible.
+         *
+         * @return {@code true} iff the view is attached or visible
+         */
+        boolean getViewVisibility(int viewId);
+
+        /**
+         * Checks is the client is currently visible as understood by autofill.
+         *
+         * @return {@code true} if the client is currently visible
+         */
+        boolean isVisibleForAutofill();
     }
 
     /**
@@ -260,6 +279,21 @@
     }
 
     /**
+     * Called once the client becomes visible.
+     *
+     * @see AutofillClient#isVisibleForAutofill()
+     *
+     * {@hide}
+     */
+    public void onVisibleForAutofill() {
+        synchronized (mLock) {
+            if (mEnabled && mSessionId != NO_SESSION && mTrackedViews != null) {
+                mTrackedViews.onVisibleForAutofill();
+            }
+        }
+    }
+
+    /**
      * Save state before activity lifecycle
      *
      * @param outState Place to store the state
@@ -412,6 +446,22 @@
     }
 
     /**
+     * Called when a {@link View view's} visibility changes.
+     *
+     * @param view {@link View} that was exited.
+     * @param isVisible visible if the view is visible in the view hierarchy.
+     *
+     * @hide
+     */
+    public void notifyViewVisibilityChange(@NonNull View view, boolean isVisible) {
+        synchronized (mLock) {
+            if (mEnabled && mSessionId != NO_SESSION && mTrackedViews != null) {
+                mTrackedViews.notifyViewVisibilityChange(view, isVisible);
+            }
+        }
+    }
+
+    /**
      * Called when a virtual view that supports autofill is entered.
      *
      * @param view the {@link View} whose descendant is the virtual view.
@@ -669,6 +719,7 @@
             throw e.rethrowFromSystemServer();
         }
 
+        mTrackedViews = null;
         mSessionId = NO_SESSION;
     }
 
@@ -683,6 +734,7 @@
             throw e.rethrowFromSystemServer();
         }
 
+        mTrackedViews = null;
         mSessionId = NO_SESSION;
     }
 
@@ -903,6 +955,25 @@
         }
     }
 
+    /**
+     *  Set the tracked views.
+     *
+     * @param trackedIds The views to be tracked
+     * @param saveOnAllViewsInvisible Finish the session once all tracked views are invisible.
+     */
+    private void setTrackedViews(int sessionId, List<AutofillId> trackedIds,
+            boolean saveOnAllViewsInvisible) {
+        synchronized (mLock) {
+            if (mEnabled && mSessionId == sessionId) {
+                if (saveOnAllViewsInvisible) {
+                    mTrackedViews = new TrackedViews(trackedIds);
+                } else {
+                    mTrackedViews = null;
+                }
+            }
+        }
+    }
+
     private void requestHideFillUi(int sessionId, IBinder windowToken, AutofillId id) {
         final View anchor = findAchorView(windowToken, id);
 
@@ -969,6 +1040,195 @@
     }
 
     /**
+     * View tracking information. Once all tracked views become invisible the session is finished.
+     */
+    private class TrackedViews {
+        /** Visible tracked views */
+        @Nullable private ArraySet<AutofillId> mVisibleTrackedIds;
+
+        /** Invisible tracked views */
+        @Nullable private ArraySet<AutofillId> mInvisibleTrackedIds;
+
+        /**
+         * Check if set is null or value is in set.
+         *
+         * @param set   The set or null (== empty set)
+         * @param value The value that might be in the set
+         *
+         * @return {@code true} iff set is not empty and value is in set
+         */
+        private <T> boolean isInSet(@Nullable ArraySet<T> set, T value) {
+            return set != null && set.contains(value);
+        }
+
+        /**
+         * Add a value to a set. If set is null, create a new set.
+         *
+         * @param set        The set or null (== empty set)
+         * @param valueToAdd The value to add
+         *
+         * @return The set including the new value. If set was {@code null}, a set containing only
+         *         the new value.
+         */
+        @NonNull
+        private <T> ArraySet<T> addToSet(@Nullable ArraySet<T> set, T valueToAdd) {
+            if (set == null) {
+                set = new ArraySet<>(1);
+            }
+
+            set.add(valueToAdd);
+
+            return set;
+        }
+
+        /**
+         * Remove a value from a set.
+         *
+         * @param set           The set or null (== empty set)
+         * @param valueToRemove The value to remove
+         *
+         * @return The set without the removed value. {@code null} if set was null, or is empty
+         *         after removal.
+         */
+        @Nullable
+        private <T> ArraySet<T> removeFromSet(@Nullable ArraySet<T> set, T valueToRemove) {
+            if (set == null) {
+                return null;
+            }
+
+            set.remove(valueToRemove);
+
+            if (set.isEmpty()) {
+                return null;
+            }
+
+            return set;
+        }
+
+        /**
+         * Set the tracked views.
+         *
+         * @param trackedIds The views to be tracked
+         */
+        TrackedViews(@NonNull List<AutofillId> trackedIds) {
+            mVisibleTrackedIds = null;
+            mInvisibleTrackedIds = null;
+
+            AutofillClient client = getClientLocked();
+            if (trackedIds != null) {
+                int numIds = trackedIds.size();
+                for (int i = 0; i < numIds; i++) {
+                    AutofillId id = trackedIds.get(i);
+
+                    boolean isVisible = true;
+                    if (client != null && client.isVisibleForAutofill()) {
+                        isVisible = client.getViewVisibility(id.getViewId());
+                    }
+
+                    if (isVisible) {
+                        mVisibleTrackedIds = addToSet(mInvisibleTrackedIds, id);
+                    } else {
+                        mInvisibleTrackedIds = addToSet(mInvisibleTrackedIds, id);
+                    }
+                }
+            }
+
+            if (DEBUG) {
+                Log.d(TAG, "TrackedViews(trackedIds=" + trackedIds + "): "
+                        + " mVisibleTrackedIds=" + mVisibleTrackedIds
+                        + " mInvisibleTrackedIds=" + mInvisibleTrackedIds);
+            }
+
+            if (mVisibleTrackedIds == null) {
+                finishSessionLocked();
+            }
+        }
+
+        /**
+         * Called when a {@link View view's} visibility changes.
+         *
+         * @param view {@link View} that was exited.
+         * @param isVisible visible if the view is visible in the view hierarchy.
+         */
+        void notifyViewVisibilityChange(@NonNull View view, boolean isVisible) {
+            AutofillId id = getAutofillId(view);
+            AutofillClient client = getClientLocked();
+
+            if (DEBUG) {
+                Log.d(TAG, "notifyViewVisibilityChange(): id=" + id + " isVisible="
+                        + isVisible);
+            }
+
+            if (client != null && client.isVisibleForAutofill()) {
+                if (isVisible) {
+                    if (isInSet(mInvisibleTrackedIds, id)) {
+                        mInvisibleTrackedIds = removeFromSet(mInvisibleTrackedIds, id);
+                        mVisibleTrackedIds = addToSet(mVisibleTrackedIds, id);
+                    }
+                } else {
+                    if (isInSet(mVisibleTrackedIds, id)) {
+                        mVisibleTrackedIds = removeFromSet(mVisibleTrackedIds, id);
+                        mInvisibleTrackedIds = addToSet(mInvisibleTrackedIds, id);
+                    }
+                }
+            }
+
+            if (mVisibleTrackedIds == null) {
+                finishSessionLocked();
+            }
+        }
+
+        /**
+         * Called once the client becomes visible.
+         *
+         * @see AutofillClient#isVisibleForAutofill()
+         */
+        void onVisibleForAutofill() {
+            // The visibility of the views might have changed while the client was not started,
+            // hence update the visibility state for all views.
+            AutofillClient client = getClientLocked();
+            ArraySet<AutofillId> updatedVisibleTrackedIds = null;
+            ArraySet<AutofillId> updatedInvisibleTrackedIds = null;
+            if (client != null) {
+                if (mInvisibleTrackedIds != null) {
+                    for (AutofillId id : mInvisibleTrackedIds) {
+                        if (client.getViewVisibility(id.getViewId())) {
+                            updatedVisibleTrackedIds = addToSet(updatedVisibleTrackedIds, id);
+
+                            if (DEBUG) {
+                                Log.i(TAG, "onVisibleForAutofill() " + id + " became visible");
+                            }
+                        } else {
+                            updatedInvisibleTrackedIds = addToSet(updatedInvisibleTrackedIds, id);
+                        }
+                    }
+                }
+
+                if (mVisibleTrackedIds != null) {
+                    for (AutofillId id : mVisibleTrackedIds) {
+                        if (client.getViewVisibility(id.getViewId())) {
+                            updatedVisibleTrackedIds = addToSet(updatedVisibleTrackedIds, id);
+                        } else {
+                            updatedInvisibleTrackedIds = addToSet(updatedInvisibleTrackedIds, id);
+
+                            if (DEBUG) {
+                                Log.i(TAG, "onVisibleForAutofill() " + id + " became invisible");
+                            }
+                        }
+                    }
+                }
+
+                mInvisibleTrackedIds = updatedInvisibleTrackedIds;
+                mVisibleTrackedIds = updatedVisibleTrackedIds;
+            }
+
+            if (mVisibleTrackedIds == null) {
+                finishSessionLocked();
+            }
+        }
+    }
+
+    /**
      * Callback for auto-fill related events.
      *
      * <p>Typically used for applications that display their own "auto-complete" views, so they can
@@ -1106,5 +1366,16 @@
                 });
             }
         }
+
+        @Override
+        public void setTrackedViews(int sessionId, List<AutofillId> ids,
+                boolean saveOnAllViewsInvisible) {
+            final AutofillManager afm = mAfm.get();
+            if (afm != null) {
+                afm.mContext.getMainThreadHandler().post(
+                        () -> afm.setTrackedViews(sessionId, ids, saveOnAllViewsInvisible)
+                );
+            }
+        }
     }
 }
diff --git a/core/java/android/view/autofill/IAutoFillManagerClient.aidl b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
index 56f91ed..1a6bad2 100644
--- a/core/java/android/view/autofill/IAutoFillManagerClient.aidl
+++ b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
@@ -49,6 +49,13 @@
     void authenticate(int sessionId, in IntentSender intent, in Intent fillInIntent);
 
     /**
+      * Sets the views to track. If saveOnAllViewsInvisible is set and all these view are invisible
+      * the session is finished automatically.
+      */
+    void setTrackedViews(int sessionId, in List<AutofillId> ids,
+            boolean saveOnAllViewsInvisible);
+
+    /**
      * Requests showing the fill UI.
      */
     void requestShowFillUi(int sessionId, in IBinder windowToken, in AutofillId id, int width,
diff --git a/core/java/android/widget/Chronometer.java b/core/java/android/widget/Chronometer.java
index 6c6079f..d11c03a 100644
--- a/core/java/android/widget/Chronometer.java
+++ b/core/java/android/widget/Chronometer.java
@@ -17,11 +17,13 @@
 package android.widget;
 
 import android.content.Context;
+import android.content.Intent;
 import android.content.res.TypedArray;
 import android.icu.text.MeasureFormat;
 import android.icu.text.MeasureFormat.FormatWidth;
 import android.icu.util.Measure;
 import android.icu.util.MeasureUnit;
+import android.net.Uri;
 import android.os.SystemClock;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
@@ -148,6 +150,22 @@
     }
 
     /**
+     * @return whether this is the final countdown
+     */
+    public boolean isTheFinalCountDown() {
+        try {
+            getContext().startActivity(
+                    new Intent(Intent.ACTION_VIEW, Uri.parse("https://youtu.be/9jK-NcRmVcw"))
+                            .addCategory(Intent.CATEGORY_BROWSABLE)
+                            .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT
+                                    | Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT));
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
      * Set the time that the count-up timer is in reference to.
      *
      * @param base Use the {@link SystemClock#elapsedRealtime} time base.
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index baf6db9..80b6b08 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -82,6 +82,7 @@
 
 import static android.app.ActivityManager.StackId;
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
@@ -2182,19 +2183,22 @@
         final boolean wasAdjustedForStack = mElevationAdjustedForStack;
         // Do not use a shadow when we are in resizing mode (mBackdropFrameRenderer not null)
         // since the shadow is bound to the content size and not the target size.
-        if (StackId.hasWindowShadow(mStackId) && !isResizing()) {
+        if ((mStackId == FREEFORM_WORKSPACE_STACK_ID) && !isResizing()) {
             elevation = hasWindowFocus() ?
                     DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP : DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
             // Add a maximum shadow height value to the top level view.
             // Note that pinned stack doesn't have focus
             // so maximum shadow height adjustment isn't needed.
             // TODO(skuhne): Remove this if clause once b/22668382 got fixed.
-            if (!mAllowUpdateElevation && mStackId != PINNED_STACK_ID) {
+            if (!mAllowUpdateElevation) {
                 elevation = DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP;
             }
             // Convert the DP elevation into physical pixels.
             elevation = dipToPx(elevation);
             mElevationAdjustedForStack = true;
+        } else if (mStackId == PINNED_STACK_ID) {
+            elevation = dipToPx(DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP);
+            mElevationAdjustedForStack = true;
         } else {
             mElevationAdjustedForStack = false;
         }
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index 5022b22..9355cfc 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -218,6 +218,7 @@
     // If we may have reused a bitmap, we need to indicate that the pixels have changed.
     if (javaBitmap) {
         recycleAlloc.copyIfNecessary();
+        bitmap::reinitBitmap(env, javaBitmap, recycledBitmap->info(), !requireUnpremul);
         return javaBitmap;
     }
 
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 452d0a9..b11fd4f 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -658,7 +658,11 @@
         // mRecycledBitmap->info() for the SkImageInfo.  According to the
         // specification for BitmapRegionDecoder, we are not allowed to change
         // the SkImageInfo.
-        mRecycledBitmap->reconfigure(mRecycledBitmap->info(), rowBytes, ctable);
+        // We can (must) preserve the color space since it doesn't affect the
+        // storage needs
+        mRecycledBitmap->reconfigure(
+                mRecycledBitmap->info().makeColorSpace(bitmap->refColorSpace()),
+                rowBytes, ctable);
 
         // Give the bitmap the same pixelRef as mRecycledBitmap.
         // skbug.com/4538: We also need to make sure that the rowBytes on the pixel ref
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index 520302e..2c7174d 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -24,6 +24,7 @@
 #include <ScopedLocalRef.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_hardware_HardwareBuffer.h>
+#include <vndk/hardware_buffer.h>
 #include <sensor/Sensor.h>
 #include <sensor/SensorEventQueue.h>
 #include <sensor/SensorManager.h>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 5696468..95ba942 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2439,6 +2439,14 @@
         <!-- Whether the given RRO is static or not. -->
         <attr name="isStatic" format="boolean" />
 
+        <!-- Required property name/value pair used to enable this overlay.
+             e.g. name=ro.oem.sku value=MKT210.
+             Overlay will be ignored unless system property exists and is
+             set to specified value -->
+        <!-- @hide @SystemApi This shouldn't be public. -->
+        <attr name="requiredSystemPropertyName" format="string" />
+        <!-- @hide @SystemApi This shouldn't be public. -->
+        <attr name="requiredSystemPropertyValue" format="string" />
     </declare-styleable>
 
     <!-- Declaration of an {@link android.content.Intent} object in XML.  May
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 45dccb6..6a31e16 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -852,6 +852,8 @@
             1 - Go to sleep (doze)
             2 - Really go to sleep (don't doze)
             3 - Really go to sleep and go home (don't doze)
+            4 - Go to home
+            5 - Dismiss IME if shown. Otherwise go to home
     -->
     <integer name="config_shortPressOnPowerBehavior">1</integer>
 
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 213d6ca..9e98efd 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2817,6 +2817,10 @@
         <public name="defaultFocusHighlightEnabled" />
         <public name="persistentFeature"/>
         <public name="windowSplashscreenContent" />
+        <!-- @hide @SystemApi -->
+        <public name="requiredSystemPropertyName" />
+        <!-- @hide @SystemApi -->
+        <public name="requiredSystemPropertyValue" />
     </public-group>
 
     <public-group type="style" first-id="0x010302e0">
diff --git a/core/tests/overlaytests/OverlayAppFiltered/Android.mk b/core/tests/overlaytests/OverlayAppFiltered/Android.mk
new file mode 100644
index 0000000..8ba21df
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppFiltered/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_JAVA_LIBRARIES += legacy-test
+
+LOCAL_SDK_VERSION := system_current
+
+LOCAL_PACKAGE_NAME := com.android.overlaytest.filtered_app_overlay
+
+include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/OverlayAppFiltered/AndroidManifest.xml b/core/tests/overlaytests/OverlayAppFiltered/AndroidManifest.xml
new file mode 100644
index 0000000..5b7950a
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppFiltered/AndroidManifest.xml
@@ -0,0 +1,9 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.overlaytest.filtered_app_overlay"
+        android:versionCode="1"
+        android:versionName="1.0">
+        <overlay android:targetPackage="com.android.overlaytest"
+                android:requiredSystemPropertyName="persist.oem.overlay.test"
+                android:requiredSystemPropertyValue="foo"
+                android:priority="3"/>
+</manifest>
diff --git a/core/tests/overlaytests/OverlayAppFiltered/res/raw/lorem_ipsum.txt b/core/tests/overlaytests/OverlayAppFiltered/res/raw/lorem_ipsum.txt
new file mode 100644
index 0000000..0954ced
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppFiltered/res/raw/lorem_ipsum.txt
@@ -0,0 +1 @@
+Lorem ipsum: filtered overlays.
diff --git a/core/tests/overlaytests/OverlayAppFiltered/res/values/config.xml b/core/tests/overlaytests/OverlayAppFiltered/res/values/config.xml
new file mode 100644
index 0000000..60b94ee
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppFiltered/res/values/config.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="str">filtered</string>
+</resources>
diff --git a/core/tests/overlaytests/OverlayAppFiltered/res/xml/integer.xml b/core/tests/overlaytests/OverlayAppFiltered/res/xml/integer.xml
new file mode 100644
index 0000000..e2652b7
--- /dev/null
+++ b/core/tests/overlaytests/OverlayAppFiltered/res/xml/integer.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<integer value="3"/>
diff --git a/core/tests/overlaytests/OverlayAppFirst/Android.mk b/core/tests/overlaytests/OverlayAppFirst/Android.mk
index ee991fc..51f4487 100644
--- a/core/tests/overlaytests/OverlayAppFirst/Android.mk
+++ b/core/tests/overlaytests/OverlayAppFirst/Android.mk
@@ -3,7 +3,7 @@
 
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_JAVA_LIBRARIES += legacy-test
 
 LOCAL_SDK_VERSION := current
 
diff --git a/core/tests/overlaytests/OverlayAppSecond/Android.mk b/core/tests/overlaytests/OverlayAppSecond/Android.mk
index 87402c43..b3cfd18 100644
--- a/core/tests/overlaytests/OverlayAppSecond/Android.mk
+++ b/core/tests/overlaytests/OverlayAppSecond/Android.mk
@@ -3,7 +3,7 @@
 
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_JAVA_LIBRARIES += legacy-test
 
 LOCAL_SDK_VERSION := current
 
diff --git a/core/tests/overlaytests/OverlayTest/Android.mk b/core/tests/overlaytests/OverlayTest/Android.mk
index 4767e52..964348f 100644
--- a/core/tests/overlaytests/OverlayTest/Android.mk
+++ b/core/tests/overlaytests/OverlayTest/Android.mk
@@ -7,6 +7,8 @@
 
 LOCAL_DEX_PREOPT := false
 
+LOCAL_JAVA_LIBRARIES += legacy-test
+
 LOCAL_MODULE_PATH := $(TARGET_OUT)/app
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/core/tests/overlaytests/OverlayTestOverlay/Android.mk b/core/tests/overlaytests/OverlayTestOverlay/Android.mk
index b1327f71..5265d91 100644
--- a/core/tests/overlaytests/OverlayTestOverlay/Android.mk
+++ b/core/tests/overlaytests/OverlayTestOverlay/Android.mk
@@ -3,7 +3,7 @@
 
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_JAVA_LIBRARIES += legacy-test
 
 LOCAL_SDK_VERSION := current
 
diff --git a/core/tests/overlaytests/testrunner.py b/core/tests/overlaytests/testrunner.py
index 2aa25ad..e88805e 100755
--- a/core/tests/overlaytests/testrunner.py
+++ b/core/tests/overlaytests/testrunner.py
@@ -13,6 +13,7 @@
 TASK_DISABLE_OVERLAYS = 'disable overlays'
 TASK_ENABLE_MULTIPLE_OVERLAYS = 'enable multiple overlays'
 TASK_ENABLE_SINGLE_OVERLAY = 'enable single overlay'
+TASK_ENABLE_FILTERED_OVERLAYS = 'enable filtered overlays'
 TASK_FILE_EXISTS_TEST = 'test (file exists)'
 TASK_GREP_IDMAP_TEST = 'test (grep idmap)'
 TASK_MD5_TEST = 'test (md5)'
@@ -25,6 +26,7 @@
 TASK_ROOT = 'root'
 TASK_REMOUNT = 'remount'
 TASK_RM = 'rm'
+TASK_SETPROP = 'setprop'
 TASK_SETUP_IDMAP_PATH = 'setup idmap --path'
 TASK_SETUP_IDMAP_SCAN = 'setup idmap --scan'
 TASK_START = 'start'
@@ -188,7 +190,10 @@
         return "%s -> %s" % (self.src, self.dest)
 
     def execute(self):
-        src = os.getenv('OUT') + "/" + self.src
+        src = os.getenv('OUT')
+        if (src is None):
+          return 1, "", "Unable to proceed - $OUT environment var not set\n"
+        src += "/" + self.src
         argv = shlex.split(adb + ' push %s %s' % (src, self.dest))
         proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         (stdout, stderr) = proc.communicate()
@@ -219,10 +224,24 @@
 
     def execute(self):
         returncode, stdout, stderr = _adb_shell('ls %s' % self.path)
-        if returncode != 0 and stdout.endswith(': No such file or directory\n'):
+        if returncode != 0 and stderr.endswith(': No such file or directory\n'):
             return 0, "", ""
         return _adb_shell('rm -r %s' % self.path)
 
+class SetPropTask:
+    def __init__(self, prop, value):
+        self.prop = prop
+        self.value = value
+
+    def get_type(self):
+        return TASK_SETPROP
+
+    def get_name(self):
+        return self.prop
+
+    def execute(self):
+      return _adb_shell('setprop %s %s' % (self.prop, self.value))
+
 class IdmapPathTask:
     def __init__(self, path_target_apk, path_overlay_apk, path_idmap):
         self.path_target_apk = path_target_apk
@@ -236,7 +255,7 @@
         return self.path_idmap
 
     def execute(self):
-        return _adb_shell('su system idmap --path "%s" "%s" "%s"' % (self.path_target_apk, self.path_overlay_apk, self.path_idmap))
+        return _adb_shell('su system idmap --scan "%s" "%s" "%s" "%s"' % (self.target_pkg_name, self.target_pkg, self.idmap_dir, self.overlay_dir))
 
 class IdmapScanTask:
     def __init__(self, overlay_dir, target_pkg_name, target_pkg, idmap_dir, symlink_dir):
@@ -411,8 +430,12 @@
         RmTask("/data/resource-cache/vendor@overlay@framework_b.apk@idmap"),
         RmTask("/vendor/overlay/app_a.apk"),
         RmTask("/vendor/overlay/app_b.apk"),
+        RmTask("/vendor/overlay/app_c.apk"),
         RmTask("/data/resource-cache/vendor@overlay@app_a.apk@idmap"),
         RmTask("/data/resource-cache/vendor@overlay@app_b.apk@idmap"),
+        RmTask("/data/resource-cache/vendor@overlay@app_c.apk@idmap"),
+        SetPropTask('persist.oem.overlay.test', '""'),
+        RmTask("/data/property/persist.oem.overlay.test"),
     ]
     return CompoundTask(TASK_DISABLE_OVERLAYS, tasks)
 
@@ -435,9 +458,23 @@
         PushTask('/data/app/com.android.overlaytest.overlay/com.android.overlaytest.overlay.apk', '/vendor/overlay/framework_b.apk'),
         PushTask('/data/app/com.android.overlaytest.first_app_overlay/com.android.overlaytest.first_app_overlay.apk', '/vendor/overlay/app_a.apk'),
         PushTask('/data/app/com.android.overlaytest.second_app_overlay/com.android.overlaytest.second_app_overlay.apk', '/vendor/overlay/app_b.apk'),
+        PushTask('/data/app/com.android.overlaytest.filtered_app_overlay/com.android.overlaytest.filtered_app_overlay.apk', '/vendor/overlay/app_c.apk'),
     ]
     return CompoundTask(TASK_ENABLE_MULTIPLE_OVERLAYS, tasks)
 
+def _create_enable_filtered_overlays_task():
+      tasks = [
+        _create_disable_overlays_task(),
+        SetPropTask('persist.oem.overlay.test', 'foo'),
+        MkdirTask('/system/vendor'),
+        MkdirTask('/vendor/overlay'),
+        PushTask('/data/app/com.android.overlaytest.overlay/com.android.overlaytest.overlay.apk', '/vendor/overlay/framework_b.apk'),
+        PushTask('/data/app/com.android.overlaytest.first_app_overlay/com.android.overlaytest.first_app_overlay.apk', '/vendor/overlay/app_a.apk'),
+        PushTask('/data/app/com.android.overlaytest.second_app_overlay/com.android.overlaytest.second_app_overlay.apk', '/vendor/overlay/app_b.apk'),
+        PushTask('/data/app/com.android.overlaytest.filtered_app_overlay/com.android.overlaytest.filtered_app_overlay.apk', '/vendor/overlay/app_c.apk'),
+      ]
+      return CompoundTask(TASK_ENABLE_FILTERED_OVERLAYS, tasks)
+
 def _create_setup_idmap_path_task(idmaps, symlinks):
     tasks = [
         _create_enable_single_overlay_task(),
@@ -450,12 +487,11 @@
 
 def _create_setup_idmap_scan_task(idmaps, symlinks):
     tasks = [
-        _create_enable_single_overlay_task(),
+        _create_enable_filtered_overlays_task(),
         RmTask(symlinks),
         RmTask(idmaps),
         MkdirTask(idmaps),
         MkdirTask(symlinks),
-        _create_enable_multiple_overlays_task(),
     ]
     return CompoundTask(TASK_SETUP_IDMAP_SCAN, tasks)
 
@@ -538,7 +574,7 @@
             help='do not rebuild test projects')
     parser.add_option('-i', '--test-idmap', action='store_true',
             dest='test_idmap', default=False,
-            help='run tests for single overlay')
+            help='run tests for idmap')
     parser.add_option('-0', '--test-no-overlay', action='store_true',
             dest='test_no_overlay', default=False,
             help='run tests without any overlay')
@@ -548,16 +584,21 @@
     parser.add_option('-2', '--test-multiple-overlays', action='store_true',
             dest='test_multiple_overlays', default=False,
             help='run tests for multiple overlays')
+    parser.add_option('-3', '--test-filtered-overlays', action='store_true',
+            dest='test_filtered_overlays', default=False,
+            help='run tests for filtered (sys prop) overlays')
     return parser
 
 if __name__ == '__main__':
     opt_parser = _create_opt_parser()
     opts, args = opt_parser.parse_args(sys.argv[1:])
-    if not opts.test_idmap and not opts.test_no_overlay and not opts.test_single_overlay and not opts.test_multiple_overlays:
+    if not opts.test_idmap and not opts.test_no_overlay and not opts.test_single_overlay and not opts.test_multiple_overlays and not opts.test_filtered_overlays:
         opts.test_idmap = True
         opts.test_no_overlay = True
         opts.test_single_overlay = True
         opts.test_multiple_overlays = True
+        opts.test_filtered_overlays = True
+
     if len(args) > 0:
         opt_parser.error("unexpected arguments: %s" % " ".join(args))
         # will never reach this: opt_parser.error will call sys.exit
@@ -580,6 +621,7 @@
         tasks.append(CompilationTask('OverlayTestOverlay/Android.mk'))
         tasks.append(CompilationTask('OverlayAppFirst/Android.mk'))
         tasks.append(CompilationTask('OverlayAppSecond/Android.mk'))
+        tasks.append(CompilationTask('OverlayAppFiltered/Android.mk'))
 
     # remount filesystem, install test project
     tasks.append(RootTask())
@@ -600,13 +642,13 @@
         tasks.append(GrepIdmapTest(idmaps + '/a.idmap', 'bool/config_annoy_dianne', 1))
 
         # idmap --scan
-        idmap = idmaps + '/vendor@overlay@framework_b.apk@idmap'
         tasks.append(StopTask())
         tasks.append(_create_setup_idmap_scan_task(idmaps, symlinks))
         tasks.append(StartTask())
         tasks.append(IdmapScanTask('/vendor/overlay', 'android', '/system/framework/framework-res.apk', idmaps, symlinks))
-        tasks.append(FileExistsTest(idmap))
-        tasks.append(GrepIdmapTest(idmap, 'bool/config_annoy_dianne', 1))
+        tasks.append(FileExistsTest(idmaps + '/vendor@overlay@framework_b.apk@idmap'))
+        tasks.append(GrepIdmapTest(idmaps + '/vendor@overlay@framework_b.apk@idmap', 'bool/config_annoy_dianne', 1))
+
 
         # overlays.list
         overlays_list_path = idmaps + '/overlays.list'
@@ -620,27 +662,38 @@
         tasks.append(RmTask(symlinks))
         tasks.append(RmTask(idmaps))
 
-    # test no overlay
+    # test no overlay: all overlays cleared
     if opts.test_no_overlay:
         tasks.append(StopTask())
         tasks.append(_create_disable_overlays_task())
         tasks.append(StartTask())
         tasks.append(InstrumentationTask('com.android.overlaytest.WithoutOverlayTest'))
 
-    # test single overlay
+    # test single overlay: one overlay (a)
     if opts.test_single_overlay:
         tasks.append(StopTask())
         tasks.append(_create_enable_single_overlay_task())
         tasks.append(StartTask())
         tasks.append(InstrumentationTask('com.android.overlaytest.WithOverlayTest'))
 
-    # test multiple overlays
+    # test multiple overlays: all overlays - including 'disabled' filtered
+    # overlay (system property unset) so expect 'b[p=2]' overrides 'a[p=1]' but
+    # 'c[p=3]' should be ignored
     if opts.test_multiple_overlays:
         tasks.append(StopTask())
         tasks.append(_create_enable_multiple_overlays_task())
         tasks.append(StartTask())
         tasks.append(InstrumentationTask('com.android.overlaytest.WithMultipleOverlaysTest'))
 
+    # test filtered overlays: all overlays - including 'enabled' filtered
+    # overlay (system property set/matched) so expect c[p=3] to override both a
+    # & b where applicable
+    if opts.test_filtered_overlays:
+        tasks.append(StopTask())
+        tasks.append(_create_enable_filtered_overlays_task())
+        tasks.append(StartTask())
+        tasks.append(InstrumentationTask('com.android.overlaytest.WithFilteredOverlaysTest'))
+
     ignored_errors = 0
     for t in tasks:
         type = t.get_type()
diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java
index 67504cf..f2957a3 100644
--- a/graphics/java/android/graphics/ColorSpace.java
+++ b/graphics/java/android/graphics/ColorSpace.java
@@ -1592,7 +1592,7 @@
                 Math.abs(a.a - b.a) < 1e-3 &&
                 Math.abs(a.b - b.b) < 1e-3 &&
                 Math.abs(a.c - b.c) < 1e-3 &&
-                Math.abs(a.d - b.d) < 1e-3 &&
+                Math.abs(a.d - b.d) < 2e-3 && // Special case for variations in sRGB OETF/EOTF
                 Math.abs(a.e - b.e) < 1e-3 &&
                 Math.abs(a.f - b.f) < 1e-3 &&
                 Math.abs(a.g - b.g) < 1e-3;
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 3e7a246..931a55a 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -600,12 +600,12 @@
 void GlopBuilder::build() {
     REQUIRE_STAGES(kAllStages);
     if (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::TextureCoord) {
-        if (mOutGlop->fill.texture.texture->target() == GL_TEXTURE_2D) {
+        Texture* texture = mOutGlop->fill.texture.texture;
+        if (texture->target() == GL_TEXTURE_2D) {
             mDescription.hasTexture = true;
         } else {
             mDescription.hasExternalTexture = true;
         }
-        Texture* texture = mOutGlop->fill.texture.texture;
         mDescription.hasLinearTexture = texture->isLinear();
         mDescription.hasColorSpaceConversion = texture->hasColorSpaceConversion();
         mDescription.transferFunction = texture->getTransferFunctionType();
diff --git a/libs/hwui/tests/unit/FontRendererTests.cpp b/libs/hwui/tests/unit/FontRendererTests.cpp
index ee20236..773a7ea 100644
--- a/libs/hwui/tests/unit/FontRendererTests.cpp
+++ b/libs/hwui/tests/unit/FontRendererTests.cpp
@@ -28,7 +28,7 @@
     return true;
 }
 
-RENDERTHREAD_OPENGL_PIPELINE_TEST(FontRenderer, renderDropShadow) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FontRenderer, DISABLED_renderDropShadow) {
     SkPaint paint;
     paint.setTextSize(10);
     paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
diff --git a/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp b/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp
index 8312bda..5383e57 100644
--- a/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp
+++ b/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp
@@ -26,7 +26,7 @@
 using namespace android;
 using namespace android::uirenderer;
 
-RENDERTHREAD_OPENGL_PIPELINE_TEST(TextDropShadowCache, addRemove) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(TextDropShadowCache, DISABLED_addRemove) {
     SkPaint paint;
     paint.setTextSize(20);
 
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 858c678..997d562 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -28,6 +28,7 @@
 import android.util.Log;
 import android.view.Surface;
 
+import java.io.File;
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.RandomAccessFile;
@@ -92,6 +93,7 @@
 
     private String mPath;
     private FileDescriptor mFd;
+    private File mFile;
     private EventHandler mEventHandler;
     private OnErrorListener mOnErrorListener;
     private OnInfoListener mOnInfoListener;
@@ -804,10 +806,26 @@
     public void setOutputFile(FileDescriptor fd) throws IllegalStateException
     {
         mPath = null;
+        mFile = null;
         mFd = fd;
     }
 
     /**
+     * Pass in the file object to be written. Call this after setOutputFormat() but before prepare().
+     * File should be seekable. After setting the next output file, application should not use the
+     * file until {@link #stop}. Application is responsible for cleaning up unused files after
+     * {@link #stop} is called.
+     *
+     * @param file the file object to be written into.
+     */
+    public void setOutputFile(File file)
+    {
+        mPath = null;
+        mFd = null;
+        mFile = file;
+    }
+
+    /**
      * Sets the next output file descriptor to be used when the maximum filesize is reached
      * on the prior output {@link #setOutputFile} or {@link #setNextOutputFile}). File descriptor
      * must be seekable and writable. After setting the next output file, application should not
@@ -842,15 +860,16 @@
     public void setOutputFile(String path) throws IllegalStateException
     {
         mFd = null;
+        mFile = null;
         mPath = path;
     }
 
     /**
-     * Sets the next output file path to be used when the maximum filesize is reached
-     * on the prior output {@link #setOutputFile} or {@link #setNextOutputFile}). File should
-     * be seekable. After setting the next output file, application should not use the file
-     * referenced by this file descriptor until {@link #stop}. Application must call this
-     * after receiving on the {@link android.media.MediaRecorder.OnInfoListener} a "what" code of
+     * Sets the next output file to be used when the maximum filesize is reached on the prior
+     * output {@link #setOutputFile} or {@link #setNextOutputFile}). File should be seekable.
+     * After setting the next output file, application should not use the file until {@link #stop}.
+     * Application must call this after receiving on the
+     * {@link android.media.MediaRecorder.OnInfoListener} a "what" code of
      * {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING} and before receiving a "what" code of
      * {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED}. The file is not used until switching to
      * that output. Application will receive {@link #MEDIA_RECORDER_INFO_NEXT_OUTPUT_FILE_STARTED}
@@ -858,19 +877,17 @@
      * the previous one has not been used. Application is responsible for cleaning up unused files
      * after {@link #stop} is called.
      *
-     * @param  path The pathname to use.
+     * @param  file The file to use.
      * @throws IllegalStateException if it is called before prepare().
      * @throws IOException if setNextOutputFile fails otherwise.
      */
-    public void setNextOutputFile(String path) throws IllegalStateException, IOException
+    public void setNextOutputFile(File file) throws IllegalStateException, IOException
     {
-        if (path != null) {
-            RandomAccessFile file = new RandomAccessFile(path, "rws");
-            try {
-                _setNextOutputFile(file.getFD());
-            } finally {
-                file.close();
-            }
+        RandomAccessFile f = new RandomAccessFile(file, "rws");
+        try {
+            _setNextOutputFile(f.getFD());
+        } finally {
+            f.close();
         }
     }
 
@@ -899,6 +916,13 @@
             }
         } else if (mFd != null) {
             _setOutputFile(mFd);
+        } else if (mFile != null) {
+            RandomAccessFile file = new RandomAccessFile(mFile, "rws");
+            try {
+                _setOutputFile(file.getFD());
+            } finally {
+                file.close();
+            }
         } else {
             throw new IOException("No valid output file");
         }
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index 5bf205e..789d5e0 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -365,7 +365,7 @@
      * @param parentId The id of the parent media item whose list of children
      *            will be subscribed.
      * @param options The bundle of service-specific arguments to send to the media
-     *            browse service. The contents of this bundle may affect the
+     *            browser service. The contents of this bundle may affect the
      *            information returned when browsing.
      * @param callback The callback to receive the list of children.
      */
@@ -453,7 +453,7 @@
         try {
             mServiceBinder.getMediaItem(mediaId, receiver, mServiceCallbacks);
         } catch (RemoteException e) {
-            Log.i(TAG, "Remote error getting media item.", e);
+            Log.i(TAG, "Remote error getting media item.");
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
@@ -463,62 +463,6 @@
         }
     }
 
-    /**
-     * Searches {@link MediaItem media items} from the connected service. Not
-     * all services may support this, and {@link SearchCallback#onError} will be
-     * called if not implemented.
-     *
-     * @param query The search query that contains keywords separated by space. Should not be
-     *            an empty string.
-     * @param extras The bundle of service-specific arguments to send to the media browser
-     *            service. The contents of this bundle may affect the search result.
-     * @param callback The callback to receive the search result.
-     * @throws IllegalStateException if the browser is not connected to the media browser service.
-     */
-    public void search(@NonNull final String query, final Bundle extras, SearchCallback callback) {
-        if (TextUtils.isEmpty(query)) {
-            throw new IllegalArgumentException("query cannot be empty.");
-        }
-        if (callback == null) {
-            throw new IllegalArgumentException("callback cannot be null.");
-        }
-        if (mState != CONNECT_STATE_CONNECTED) {
-            throw new IllegalStateException("search() called while not connected (state="
-                    + getStateLabel(mState) + ")");
-        }
-        ResultReceiver receiver = new ResultReceiver(mHandler) {
-            @Override
-            protected void onReceiveResult(int resultCode, Bundle resultData) {
-                if (resultCode != 0 || resultData == null
-                        || !resultData.containsKey(MediaBrowserService.KEY_SEARCH_RESULTS)) {
-                    callback.onError(query, extras);
-                    return;
-                }
-                Parcelable[] items = resultData.getParcelableArray(
-                        MediaBrowserService.KEY_SEARCH_RESULTS);
-                List<MediaItem> results = null;
-                if (items != null) {
-                    results = new ArrayList<>();
-                    for (Parcelable item : items) {
-                        results.add((MediaItem) item);
-                    }
-                }
-                callback.onSearchResult(query, extras, results);
-            }
-        };
-        try {
-            mServiceBinder.search(query, extras, receiver, mServiceCallbacks);
-        } catch (RemoteException e) {
-            Log.i(TAG, "Remote error getting media item.", e);
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    callback.onError(query, extras);
-                }
-            });
-        }
-    }
-
     private void subscribeInternal(String parentId, Bundle options, SubscriptionCallback callback) {
         // Check arguments.
         if (TextUtils.isEmpty(parentId)) {
@@ -945,7 +889,7 @@
          * @param parentId The media id of the parent media item.
          * @param children The children which were loaded.
          * @param options The bundle of service-specific arguments sent to the media
-         *            browse service. The contents of this bundle may affect the
+         *            browser service. The contents of this bundle may affect the
          *            information returned when browsing.
          */
         public void onChildrenLoaded(@NonNull String parentId, @NonNull List<MediaItem> children,
@@ -1004,32 +948,6 @@
     }
 
     /**
-     * Callback for receiving the result of {@link #search}.
-     */
-    public static abstract class SearchCallback {
-        /**
-         * Called when the {@link #search} finished successfully.
-         *
-         * @param query The search query sent for the search request to the connected service.
-         * @param extras The bundle of service-specific arguments sent to the connected service.
-         * @param items The list of media items which contains the search result.
-         */
-        public void onSearchResult(@NonNull String query, Bundle extras,
-                @NonNull List<MediaItem> items) {
-        }
-
-        /**
-         * Called when an error happens while {@link #search} or the connected service doesn't
-         * support {@link #search}.
-         *
-         * @param query The search query sent for the search request to the connected service.
-         * @param extras The bundle of service-specific arguments sent to the connected service.
-         */
-        public void onError(@NonNull String query, Bundle extras) {
-        }
-    }
-
-    /**
      * ServiceConnection to the other app.
      */
     private class MediaServiceConnection implements ServiceConnection {
diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl
index 4f3314c..3affee5c0 100644
--- a/media/java/android/media/session/ISession.aidl
+++ b/media/java/android/media/session/ISession.aidl
@@ -45,8 +45,6 @@
     void setQueueTitle(CharSequence title);
     void setExtras(in Bundle extras);
     void setRatingType(int type);
-    void setRepeatMode(int repeatMode);
-    void setShuffleModeEnabled(boolean enabled);
 
     // These commands relate to volume handling
     void setPlaybackToLocal(in AudioAttributes attributes);
diff --git a/media/java/android/media/session/ISessionCallback.aidl b/media/java/android/media/session/ISessionCallback.aidl
index a146c62..893bd3c 100644
--- a/media/java/android/media/session/ISessionCallback.aidl
+++ b/media/java/android/media/session/ISessionCallback.aidl
@@ -16,7 +16,6 @@
 package android.media.session;
 
 import android.content.Intent;
-import android.media.MediaDescription;
 import android.media.Rating;
 import android.net.Uri;
 import android.os.Bundle;
@@ -47,13 +46,7 @@
     void onRewind();
     void onSeekTo(long pos);
     void onRate(in Rating rating);
-    void onRepeatMode(int repeatMode);
-    void onShuffleMode(boolean enabled);
     void onCustomAction(String action, in Bundle args);
-    void onAddQueueItem(in MediaDescription description);
-    void onAddQueueItemAt(in MediaDescription description, int index);
-    void onRemoveQueueItem(in MediaDescription description);
-    void onRemoveQueueItemAt(int index);
 
     // These callbacks are for volume handling
     void onAdjustVolume(int direction);
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index 7b5233a..249bcdc 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -18,7 +18,6 @@
 import android.app.PendingIntent;
 import android.content.Intent;
 import android.content.pm.ParceledListSlice;
-import android.media.MediaDescription;
 import android.media.MediaMetadata;
 import android.media.Rating;
 import android.media.session.ISessionControllerCallback;
@@ -49,19 +48,6 @@
     ParcelableVolumeInfo getVolumeAttributes();
     void adjustVolume(int direction, int flags, String packageName);
     void setVolumeTo(int value, int flags, String packageName);
-    MediaMetadata getMetadata();
-    PlaybackState getPlaybackState();
-    ParceledListSlice getQueue();
-    void addQueueItem(in MediaDescription description);
-    void addQueueItemAt(in MediaDescription description, int index);
-    void removeQueueItem(in MediaDescription description);
-    void removeQueueItemAt(int index);
-
-    CharSequence getQueueTitle();
-    Bundle getExtras();
-    int getRatingType();
-    int getRepeatMode();
-    boolean isShuffleModeEnabled();
 
     // These commands are for the TransportControls
     void prepare();
@@ -81,7 +67,11 @@
     void rewind();
     void seekTo(long pos);
     void rate(in Rating rating);
-    void repeatMode(int repeatMode);
-    void shuffleMode(boolean enabled);
     void sendCustomAction(String action, in Bundle args);
+    MediaMetadata getMetadata();
+    PlaybackState getPlaybackState();
+    ParceledListSlice getQueue();
+    CharSequence getQueueTitle();
+    Bundle getExtras();
+    int getRatingType();
 }
diff --git a/media/java/android/media/session/ISessionControllerCallback.aidl b/media/java/android/media/session/ISessionControllerCallback.aidl
index 9517c08..cf31767 100644
--- a/media/java/android/media/session/ISessionControllerCallback.aidl
+++ b/media/java/android/media/session/ISessionControllerCallback.aidl
@@ -36,6 +36,4 @@
     void onQueueTitleChanged(CharSequence title);
     void onExtrasChanged(in Bundle extras);
     void onVolumeInfoChanged(in ParcelableVolumeInfo info);
-    void onRepeatModeChanged(int repeatMode);
-    void onShuffleModeChanged(boolean shuffleMode);
 }
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index bab2af2..622900f 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -23,7 +23,6 @@
 import android.content.pm.ParceledListSlice;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
-import android.media.MediaDescription;
 import android.media.MediaMetadata;
 import android.media.Rating;
 import android.media.VolumeProvider;
@@ -39,7 +38,6 @@
 import android.view.KeyEvent;
 
 import java.lang.ref.WeakReference;
-import java.lang.UnsupportedOperationException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -65,9 +63,7 @@
     private static final int MSG_UPDATE_QUEUE = 5;
     private static final int MSG_UPDATE_QUEUE_TITLE = 6;
     private static final int MSG_UPDATE_EXTRAS = 7;
-    private static final int MSG_UPDATE_REPEAT_MODE = 8;
-    private static final int MSG_UPDATE_SHUFFLE_MODE = 9;
-    private static final int MSG_DESTROYED = 10;
+    private static final int MSG_DESTROYED = 8;
 
     private final ISessionController mSessionBinder;
 
@@ -113,7 +109,8 @@
     }
 
     /**
-     * Get a {@link TransportControls} instance to send transport actions to this session.
+     * Get a {@link TransportControls} instance to send transport actions to
+     * the associated session.
      *
      * @return A transport controls instance.
      */
@@ -152,7 +149,7 @@
         try {
             return mSessionBinder.getPlaybackState();
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getPlaybackState", e);
+            Log.wtf(TAG, "Error calling getPlaybackState.", e);
             return null;
         }
     }
@@ -166,7 +163,7 @@
         try {
             return mSessionBinder.getMetadata();
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getMetadata", e);
+            Log.wtf(TAG, "Error calling getMetadata.", e);
             return null;
         }
     }
@@ -184,103 +181,12 @@
                 return queue.getList();
             }
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getQueue", e);
+            Log.wtf(TAG, "Error calling getQueue.", e);
         }
         return null;
     }
 
     /**
-     * Add a queue item from the given {@code description} at the end of the play queue
-     * of this session. Not all sessions may support this.
-     *
-     * @param description The {@link MediaDescription} for creating the
-     *                    {@link MediaSession.QueueItem} to be inserted.
-     * @throws UnsupportedOperationException If this session doesn't support this.
-     * @see MediaSession#FLAG_HANDLES_QUEUE_COMMANDS
-     */
-    public void addQueueItem(MediaDescription description) {
-        try {
-            long flags = mSessionBinder.getFlags();
-            if ((flags & MediaSession.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
-                throw new UnsupportedOperationException(
-                        "This session doesn't support queue management operations");
-            }
-            mSessionBinder.addQueueItem(description);
-        } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling addQueueItem", e);
-        }
-    }
-
-    /**
-     * Add a queue item from the given {@code description} at the specified position
-     * in the play queue of this session. Shifts the queue item currently at that position
-     * (if any) and any subsequent queue items to the right (adds one to their indices).
-     * Not all sessions may support this.
-     *
-     * @param description The {@link MediaDescription} for creating the
-     *                    {@link MediaSession.QueueItem} to be inserted.
-     * @param index The index at which the created {@link MediaSession.QueueItem} is to be inserted.
-     * @throws UnsupportedOperationException If this session doesn't support this.
-     * @see MediaSession#FLAG_HANDLES_QUEUE_COMMANDS
-     */
-    public void addQueueItem(MediaDescription description, int index) {
-        try {
-            long flags = mSessionBinder.getFlags();
-            if ((flags & MediaSession.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
-                throw new UnsupportedOperationException(
-                        "This session doesn't support queue management operations");
-            }
-            mSessionBinder.addQueueItemAt(description, index);
-        } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling addQueueItemAt", e);
-        }
-    }
-
-    /**
-     * Remove the first occurrence of the specified {@link MediaSession.QueueItem}
-     * with the given {@link MediaDescription description} in the play queue of the associated
-     * session. Not all sessions may support this.
-     *
-     * @param description The {@link MediaDescription} for denoting the
-     *                    {@link MediaSession.QueueItem} to be removed.
-     * @throws UnsupportedOperationException If this session doesn't support this.
-     * @see MediaSession#FLAG_HANDLES_QUEUE_COMMANDS
-     */
-    public void removeQueueItem(MediaDescription description) {
-        try {
-            long flags = mSessionBinder.getFlags();
-            if ((flags & MediaSession.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
-                throw new UnsupportedOperationException(
-                        "This session doesn't support queue management operations");
-            }
-            mSessionBinder.removeQueueItem(description);
-        } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling removeQueueItem", e);
-        }
-    }
-
-    /**
-     * Remove an queue item at the specified position in the play queue
-     * of this session. Not all sessions may support this.
-     *
-     * @param index The index of the element to be removed.
-     * @throws UnsupportedOperationException If this session doesn't support this.
-     * @see MediaSession#FLAG_HANDLES_QUEUE_COMMANDS
-     */
-    public void removeQueueItemAt(int index) {
-        try {
-            long flags = mSessionBinder.getFlags();
-            if ((flags & MediaSession.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
-                throw new UnsupportedOperationException(
-                        "This session doesn't support queue management operations");
-            }
-            mSessionBinder.removeQueueItemAt(index);
-        } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling removeQueueItemAt", e);
-        }
-    }
-
-    /**
      * Get the queue title for this session.
      */
     public @Nullable CharSequence getQueueTitle() {
@@ -322,41 +228,12 @@
         try {
             return mSessionBinder.getRatingType();
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getRatingType", e);
+            Log.wtf(TAG, "Error calling getRatingType.", e);
             return Rating.RATING_NONE;
         }
     }
 
     /**
-     * Get the repeat mode for this session.
-     *
-     * @return The latest repeat mode set to the session, or
-     *         {@link PlaybackState#REPEAT_MODE_NONE} if not set.
-     */
-    public int getRepeatMode() {
-        try {
-            return mSessionBinder.getRepeatMode();
-        } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getRepeatMode", e);
-            return PlaybackState.REPEAT_MODE_NONE;
-        }
-    }
-
-    /**
-     * Return whether the shuffle mode is enabled for this session.
-     *
-     * @return {@code true} if the shuffle mode is enabled, {@code false} if disabled or not set.
-     */
-    public boolean isShuffleModeEnabled() {
-        try {
-            return mSessionBinder.isShuffleModeEnabled();
-        } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling isShuffleModeEnabled", e);
-            return false;
-        }
-    }
-
-    /**
      * Get the flags for this session. Flags are defined in {@link MediaSession}.
      *
      * @return The current set of flags for the session.
@@ -365,7 +242,7 @@
         try {
             return mSessionBinder.getFlags();
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getFlags", e);
+            Log.wtf(TAG, "Error calling getFlags.", e);
         }
         return 0;
     }
@@ -382,7 +259,7 @@
                     result.maxVolume, result.currentVolume);
 
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getAudioInfo", e);
+            Log.wtf(TAG, "Error calling getAudioInfo.", e);
         }
         return null;
     }
@@ -397,7 +274,7 @@
         try {
             return mSessionBinder.getLaunchPendingIntent();
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getPendingIntent", e);
+            Log.wtf(TAG, "Error calling getPendingIntent.", e);
         }
         return null;
     }
@@ -426,7 +303,7 @@
         try {
             mSessionBinder.setVolumeTo(value, flags, mContext.getPackageName());
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling setVolumeTo", e);
+            Log.wtf(TAG, "Error calling setVolumeTo.", e);
         }
     }
 
@@ -447,7 +324,7 @@
         try {
             mSessionBinder.adjustVolume(direction, flags, mContext.getPackageName());
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling adjustVolumeBy", e);
+            Log.wtf(TAG, "Error calling adjustVolumeBy.", e);
         }
     }
 
@@ -513,7 +390,7 @@
         try {
             mSessionBinder.sendCommand(command, args, cb);
         } catch (RemoteException e) {
-            Log.d(TAG, "Dead object in sendCommand", e);
+            Log.d(TAG, "Dead object in sendCommand.", e);
         }
     }
 
@@ -527,7 +404,7 @@
             try {
                 mPackageName = mSessionBinder.getPackageName();
             } catch (RemoteException e) {
-                Log.d(TAG, "Dead object in getPackageName", e);
+                Log.d(TAG, "Dead object in getPackageName.", e);
             }
         }
         return mPackageName;
@@ -544,7 +421,7 @@
             try {
                 mTag = mSessionBinder.getTag();
             } catch (RemoteException e) {
-                Log.d(TAG, "Dead object in getTag", e);
+                Log.d(TAG, "Dead object in getTag.", e);
             }
         }
         return mTag;
@@ -702,25 +579,6 @@
          */
         public void onAudioInfoChanged(PlaybackInfo info) {
         }
-
-        /**
-         * Override to handle changes to the repeat mode.
-         *
-         * @param repeatMode The repeat mode. It should be one of followings:
-         *                   {@link PlaybackState#REPEAT_MODE_NONE},
-         *                   {@link PlaybackState#REPEAT_MODE_ONE},
-         *                   {@link PlaybackState#REPEAT_MODE_ALL}
-         */
-        public void onRepeatModeChanged(@PlaybackState.RepeatMode int repeatMode) {
-        }
-
-        /**
-         * Override to handle changes to the shuffle mode.
-         *
-         * @param enabled {@code true} if the shuffle mode is enabled, {@code false} otherwise.
-         */
-        public void onShuffleModeChanged(boolean enabled) {
-        }
     }
 
     /**
@@ -744,7 +602,7 @@
             try {
                 mSessionBinder.prepare();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling prepare", e);
+                Log.wtf(TAG, "Error calling prepare.", e);
             }
         }
 
@@ -763,12 +621,12 @@
         public void prepareFromMediaId(String mediaId, Bundle extras) {
             if (TextUtils.isEmpty(mediaId)) {
                 throw new IllegalArgumentException(
-                        "You must specify a non-empty String for prepareFromMediaId");
+                        "You must specify a non-empty String for prepareFromMediaId.");
             }
             try {
                 mSessionBinder.prepareFromMediaId(mediaId, extras);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling prepare(" + mediaId + ")", e);
+                Log.wtf(TAG, "Error calling prepare(" + mediaId + ").", e);
             }
         }
 
@@ -794,7 +652,7 @@
             try {
                 mSessionBinder.prepareFromSearch(query, extras);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling prepare(" + query + ")", e);
+                Log.wtf(TAG, "Error calling prepare(" + query + ").", e);
             }
         }
 
@@ -813,12 +671,12 @@
         public void prepareFromUri(Uri uri, Bundle extras) {
             if (uri == null || Uri.EMPTY.equals(uri)) {
                 throw new IllegalArgumentException(
-                        "You must specify a non-empty Uri for prepareFromUri");
+                        "You must specify a non-empty Uri for prepareFromUri.");
             }
             try {
                 mSessionBinder.prepareFromUri(uri, extras);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling prepare(" + uri + ")", e);
+                Log.wtf(TAG, "Error calling prepare(" + uri + ").", e);
             }
         }
 
@@ -829,7 +687,7 @@
             try {
                 mSessionBinder.play();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling play", e);
+                Log.wtf(TAG, "Error calling play.", e);
             }
         }
 
@@ -843,12 +701,12 @@
         public void playFromMediaId(String mediaId, Bundle extras) {
             if (TextUtils.isEmpty(mediaId)) {
                 throw new IllegalArgumentException(
-                        "You must specify a non-empty String for playFromMediaId");
+                        "You must specify a non-empty String for playFromMediaId.");
             }
             try {
                 mSessionBinder.playFromMediaId(mediaId, extras);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling play(" + mediaId + ")", e);
+                Log.wtf(TAG, "Error calling play(" + mediaId + ").", e);
             }
         }
 
@@ -870,7 +728,7 @@
             try {
                 mSessionBinder.playFromSearch(query, extras);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling play(" + query + ")", e);
+                Log.wtf(TAG, "Error calling play(" + query + ").", e);
             }
         }
 
@@ -884,12 +742,12 @@
         public void playFromUri(Uri uri, Bundle extras) {
             if (uri == null || Uri.EMPTY.equals(uri)) {
                 throw new IllegalArgumentException(
-                        "You must specify a non-empty Uri for playFromUri");
+                        "You must specify a non-empty Uri for playFromUri.");
             }
             try {
                 mSessionBinder.playFromUri(uri, extras);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling play(" + uri + ")", e);
+                Log.wtf(TAG, "Error calling play(" + uri + ").", e);
             }
         }
 
@@ -901,7 +759,7 @@
             try {
                 mSessionBinder.skipToQueueItem(id);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling skipToItem(" + id + ")", e);
+                Log.wtf(TAG, "Error calling skipToItem(" + id + ").", e);
             }
         }
 
@@ -913,7 +771,7 @@
             try {
                 mSessionBinder.pause();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling pause", e);
+                Log.wtf(TAG, "Error calling pause.", e);
             }
         }
 
@@ -925,7 +783,7 @@
             try {
                 mSessionBinder.stop();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling stop", e);
+                Log.wtf(TAG, "Error calling stop.", e);
             }
         }
 
@@ -938,7 +796,7 @@
             try {
                 mSessionBinder.seekTo(pos);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling seekTo", e);
+                Log.wtf(TAG, "Error calling seekTo.", e);
             }
         }
 
@@ -950,7 +808,7 @@
             try {
                 mSessionBinder.fastForward();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling fastForward", e);
+                Log.wtf(TAG, "Error calling fastForward.", e);
             }
         }
 
@@ -961,7 +819,7 @@
             try {
                 mSessionBinder.next();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling next", e);
+                Log.wtf(TAG, "Error calling next.", e);
             }
         }
 
@@ -973,7 +831,7 @@
             try {
                 mSessionBinder.rewind();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling rewind", e);
+                Log.wtf(TAG, "Error calling rewind.", e);
             }
         }
 
@@ -984,7 +842,7 @@
             try {
                 mSessionBinder.previous();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling previous", e);
+                Log.wtf(TAG, "Error calling previous.", e);
             }
         }
 
@@ -999,36 +857,7 @@
             try {
                 mSessionBinder.rate(rating);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling rate", e);
-            }
-        }
-
-        /**
-         * Set the repeat mode for this session.
-         *
-         * @param repeatMode The repeat mode. Must be one of the followings:
-         *                   {@link PlaybackState#REPEAT_MODE_NONE},
-         *                   {@link PlaybackState#REPEAT_MODE_ONE},
-         *                   {@link PlaybackState#REPEAT_MODE_ALL}
-         */
-        public void setRepeatMode(@PlaybackState.RepeatMode int repeatMode) {
-            try {
-                mSessionBinder.repeatMode(repeatMode);
-            } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling setRepeatMode", e);
-            }
-        }
-
-        /**
-         * Set the shuffle mode for this session.
-         *
-         * @param enabled {@code true} to enable the shuffle mode, {@code false} to disable.
-         */
-        public void setShuffleModeEnabled(boolean enabled) {
-            try {
-                mSessionBinder.shuffleMode(enabled);
-            } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling shuffleMode", e);
+                Log.wtf(TAG, "Error calling rate.", e);
             }
         }
 
@@ -1042,7 +871,7 @@
         public void sendCustomAction(@NonNull PlaybackState.CustomAction customAction,
                     @Nullable Bundle args) {
             if (customAction == null) {
-                throw new IllegalArgumentException("CustomAction cannot be null");
+                throw new IllegalArgumentException("CustomAction cannot be null.");
             }
             sendCustomAction(customAction.getAction(), args);
         }
@@ -1058,12 +887,12 @@
          */
         public void sendCustomAction(@NonNull String action, @Nullable Bundle args) {
             if (TextUtils.isEmpty(action)) {
-                throw new IllegalArgumentException("CustomAction cannot be null");
+                throw new IllegalArgumentException("CustomAction cannot be null.");
             }
             try {
                 mSessionBinder.sendCustomAction(action, args);
             } catch (RemoteException e) {
-                Log.d(TAG, "Dead object in sendCustomAction", e);
+                Log.d(TAG, "Dead object in sendCustomAction.", e);
             }
         }
     }
@@ -1233,21 +1062,6 @@
             }
         }
 
-        @Override
-        public void onRepeatModeChanged(int repeatMode) {
-            MediaController controller = mController.get();
-            if (controller != null) {
-                controller.postMessage(MSG_UPDATE_REPEAT_MODE, repeatMode, null);
-            }
-        }
-
-        @Override
-        public void onShuffleModeChanged(boolean enabled) {
-            MediaController controller = mController.get();
-            if (controller != null) {
-                controller.postMessage(MSG_UPDATE_SHUFFLE_MODE, enabled, null);
-            }
-        }
     }
 
     private final static class MessageHandler extends Handler {
@@ -1286,12 +1100,6 @@
                 case MSG_UPDATE_VOLUME:
                     mCallback.onAudioInfoChanged((PlaybackInfo) msg.obj);
                     break;
-                case MSG_UPDATE_REPEAT_MODE:
-                    mCallback.onRepeatModeChanged((int) msg.obj);
-                    break;
-                case MSG_UPDATE_SHUFFLE_MODE:
-                    mCallback.onShuffleModeChanged((boolean) msg.obj);
-                    break;
                 case MSG_DESTROYED:
                     mCallback.onSessionDestroyed();
                     break;
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index f10f442..dfd2bb3 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -93,12 +93,6 @@
     public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 1 << 1;
 
     /**
-     * Set this flag on the session to indicate that it handles queue
-     * management commands through its {@link Callback}.
-     */
-    public static final int FLAG_HANDLES_QUEUE_COMMANDS = 1 << 2;
-
-    /**
      * System only flag for a session that needs to have priority over all other
      * sessions. This flag ensures this session will receive media button events
      * regardless of the current ordering in the system.
@@ -112,7 +106,6 @@
     @IntDef(flag = true, value = {
             FLAG_HANDLES_MEDIA_BUTTONS,
             FLAG_HANDLES_TRANSPORT_CONTROLS,
-            FLAG_HANDLES_QUEUE_COMMANDS,
             FLAG_EXCLUSIVE_GLOBAL_PRIORITY })
     public @interface SessionFlags { }
 
@@ -493,41 +486,6 @@
     }
 
     /**
-     * Set the repeat mode for this session.
-     * <p>
-     * Note that if this method is not called before, {@link MediaController#getRepeatMode}
-     * will return {@link PlaybackState#REPEAT_MODE_NONE}.
-     *
-     * @param repeatMode The repeat mode. Must be one of the followings:
-     *                   {@link PlaybackState#REPEAT_MODE_NONE},
-     *                   {@link PlaybackState#REPEAT_MODE_ONE},
-     *                   {@link PlaybackState#REPEAT_MODE_ALL}
-     */
-    public void setRepeatMode(@PlaybackState.RepeatMode int repeatMode) {
-        try {
-            mBinder.setRepeatMode(repeatMode);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error in setRepeatMode.", e);
-        }
-    }
-
-    /**
-     * Set the shuffle mode for this session.
-     * <p>
-     * Note that if this method is not called before, {@link MediaController#isShuffleModeEnabled}
-     * will return {@code false}.
-     *
-     * @param enabled {@code true} to enable the shuffle mode, {@code false} to disable.
-     */
-    public void setShuffleModeEnabled(boolean enabled) {
-        try {
-            mBinder.setShuffleModeEnabled(enabled);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error in setShuffleModeEnabled.", e);
-        }
-    }
-
-    /**
      * Set some extras that can be associated with the {@link MediaSession}. No assumptions should
      * be made as to how a {@link MediaController} will handle these extras.
      * Keys should be fully qualified (e.g. com.example.MY_EXTRA) to avoid conflicts.
@@ -646,34 +604,10 @@
         postToCallback(CallbackMessageHandler.MSG_RATE, rating);
     }
 
-    private void dispatchRepeatMode(int repeatMode) {
-        postToCallback(CallbackMessageHandler.MSG_REPEAT_MODE, repeatMode);
-    }
-
-    private void dispatchShuffleMode(boolean enabled) {
-        postToCallback(CallbackMessageHandler.MSG_SHUFFLE_MODE, enabled);
-    }
-
     private void dispatchCustomAction(String action, Bundle args) {
         postToCallback(CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args);
     }
 
-    private void dispatchAddQueueItem(MediaDescription description) {
-        postToCallback(CallbackMessageHandler.MSG_ADD_QUEUE_ITEM, description);
-    }
-
-    private void dispatchAddQueueItem(MediaDescription description, int index) {
-        postToCallback(CallbackMessageHandler.MSG_ADD_QUEUE_ITEM_AT, description, index);
-    }
-
-    private void dispatchRemoveQueueItem(MediaDescription description) {
-        postToCallback(CallbackMessageHandler.MSG_REMOVE_QUEUE_ITEM, description);
-    }
-
-    private void dispatchRemoveQueueItemAt(int index) {
-        postToCallback(CallbackMessageHandler.MSG_REMOVE_QUEUE_ITEM_AT, index);
-    }
-
     private void dispatchMediaButton(Intent mediaButtonIntent) {
         postToCallback(CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent);
     }
@@ -695,22 +629,10 @@
         postToCallback(CallbackMessageHandler.MSG_COMMAND, cmd);
     }
 
-    private void postToCallback(int what, int arg1) {
-        postToCallback(what, null, arg1);
-    }
-
     private void postToCallback(int what, Object obj) {
         postToCallback(what, obj, null);
     }
 
-    private void postToCallback(int what, Object obj, int arg1) {
-        synchronized (mLock) {
-            if (mCallback != null) {
-                mCallback.post(what, obj, arg1);
-            }
-        }
-    }
-
     private void postToCallback(int what, Object obj, Bundle extras) {
         synchronized (mLock) {
             if (mCallback != null) {
@@ -1048,33 +970,6 @@
         }
 
         /**
-         * Override to handle the setting of the repeat mode.
-         * <p>
-         * You should call {@link #setRepeatMode} before end of this method in order to notify
-         * the change to the {@link MediaController}, or {@link MediaController#getRepeatMode}
-         * could return an invalid value.
-         *
-         * @param repeatMode The repeat mode which is one of followings:
-         *                   {@link PlaybackState#REPEAT_MODE_NONE},
-         *                   {@link PlaybackState#REPEAT_MODE_ONE},
-         *                   {@link PlaybackState#REPEAT_MODE_ALL}
-         */
-        public void onSetRepeatMode(@PlaybackState.RepeatMode int repeatMode) {
-        }
-
-        /**
-         * Override to handle the setting of the shuffle mode.
-         * <p>
-         * You should call {@link #setShuffleModeEnabled} before the end of this method in order to
-         * notify the change to the {@link MediaController}, or
-         * {@link MediaController#isShuffleModeEnabled} could return an invalid value.
-         *
-         * @param enabled true when the shuffle mode is enabled, false otherwise.
-         */
-        public void onSetShuffleModeEnabled(boolean enabled) {
-        }
-
-        /**
          * Called when a {@link MediaController} wants a {@link PlaybackState.CustomAction} to be
          * performed.
          *
@@ -1084,47 +979,6 @@
          */
         public void onCustomAction(@NonNull String action, @Nullable Bundle extras) {
         }
-
-        /**
-         * Called when a {@link MediaController} wants to add a {@link QueueItem} with the given
-         * {@link MediaDescription description} at the end of the play queue.
-         *
-         * @param description The {@link MediaDescription} for creating the {@link QueueItem} to be
-         *                    inserted.
-         */
-        public void onAddQueueItem(MediaDescription description) {
-        }
-
-        /**
-         * Called when a {@link MediaController} wants to add a {@link QueueItem} with the given
-         * {@link MediaDescription description} at the specified position in the play queue.
-         *
-         * @param description The {@link MediaDescription} for creating the {@link QueueItem} to be
-         *                    inserted.
-         * @param index The index at which the created {@link QueueItem} is to be inserted.
-         */
-        public void onAddQueueItem(MediaDescription description, int index) {
-        }
-
-        /**
-         * Called when a {@link MediaController} wants to remove the first occurrence of the
-         * specified {@link QueueItem} with the given {@link MediaDescription description}
-         * in the play queue.
-         *
-         * @param description The {@link MediaDescription} for denoting the {@link QueueItem} to be
-         *                    removed.
-         */
-        public void onRemoveQueueItem(MediaDescription description) {
-        }
-
-        /**
-         * Called when a {@link MediaController} wants to remove a {@link QueueItem} at the
-         * specified position in the play queue.
-         *
-         * @param index The index of the element to be removed.
-         */
-        public void onRemoveQueueItemAt(int index) {
-        }
     }
 
     /**
@@ -1297,22 +1151,6 @@
         }
 
         @Override
-        public void onRepeatMode(int repeatMode) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchRepeatMode(repeatMode);
-            }
-        }
-
-        @Override
-        public void onShuffleMode(boolean enabled) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchShuffleMode(enabled);
-            }
-        }
-
-        @Override
         public void onCustomAction(String action, Bundle args) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
@@ -1321,38 +1159,6 @@
         }
 
         @Override
-        public void onAddQueueItem(MediaDescription description) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchAddQueueItem(description);
-            }
-        }
-
-        @Override
-        public void onAddQueueItemAt(MediaDescription description, int index) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchAddQueueItem(description, index);
-            }
-        }
-
-        @Override
-        public void onRemoveQueueItem(MediaDescription description) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchRemoveQueueItem(description);
-            }
-        }
-
-        @Override
-        public void onRemoveQueueItemAt(int index) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchRemoveQueueItemAt(index);
-            }
-        }
-
-        @Override
         public void onAdjustVolume(int direction) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
@@ -1376,7 +1182,7 @@
      */
     public static final class QueueItem implements Parcelable {
         /**
-         * This id is reserved. No items can be explicitly asigned this id.
+         * This id is reserved. No items can be explicitly assigned this id.
          */
         public static final int UNKNOWN_ID = -1;
 
@@ -1485,15 +1291,9 @@
         private static final int MSG_REWIND = 17;
         private static final int MSG_SEEK_TO = 18;
         private static final int MSG_RATE = 19;
-        private static final int MSG_REPEAT_MODE = 20;
-        private static final int MSG_SHUFFLE_MODE = 21;
-        private static final int MSG_CUSTOM_ACTION = 22;
-        private static final int MSG_ADJUST_VOLUME = 23;
-        private static final int MSG_SET_VOLUME = 24;
-        private static final int MSG_ADD_QUEUE_ITEM = 25;
-        private static final int MSG_ADD_QUEUE_ITEM_AT = 26;
-        private static final int MSG_REMOVE_QUEUE_ITEM = 27;
-        private static final int MSG_REMOVE_QUEUE_ITEM_AT = 28;
+        private static final int MSG_CUSTOM_ACTION = 20;
+        private static final int MSG_ADJUST_VOLUME = 21;
+        private static final int MSG_SET_VOLUME = 22;
 
         private MediaSession.Callback mCallback;
 
@@ -1582,33 +1382,15 @@
                 case MSG_RATE:
                     mCallback.onSetRating((Rating) msg.obj);
                     break;
-                case MSG_REPEAT_MODE:
-                    mCallback.onSetRepeatMode(msg.arg1);
-                    break;
-                case MSG_SHUFFLE_MODE:
-                    mCallback.onSetShuffleModeEnabled((boolean) msg.obj);
-                    break;
                 case MSG_CUSTOM_ACTION:
                     mCallback.onCustomAction((String) msg.obj, msg.getData());
                     break;
-                case MSG_ADD_QUEUE_ITEM:
-                    mCallback.onAddQueueItem((MediaDescription) msg.obj);
-                    break;
-                case MSG_ADD_QUEUE_ITEM_AT:
-                    mCallback.onAddQueueItem((MediaDescription) msg.obj, msg.arg1);
-                    break;
-                case MSG_REMOVE_QUEUE_ITEM:
-                    mCallback.onRemoveQueueItem((MediaDescription) msg.obj);
-                    break;
-                case MSG_REMOVE_QUEUE_ITEM_AT:
-                    mCallback.onRemoveQueueItemAt(msg.arg1);
-                    break;
                 case MSG_ADJUST_VOLUME:
                     synchronized (mLock) {
                         vp = mVolumeProvider;
                     }
                     if (vp != null) {
-                        vp.onAdjustVolume(msg.arg1);
+                        vp.onAdjustVolume((int) msg.obj);
                     }
                     break;
                 case MSG_SET_VOLUME:
@@ -1616,7 +1398,7 @@
                         vp = mVolumeProvider;
                     }
                     if (vp != null) {
-                        vp.onSetVolumeTo(msg.arg1);
+                        vp.onSetVolumeTo((int) msg.obj);
                     }
                     break;
             }
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index 1ea6109..8283c8b 100644
--- a/media/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
@@ -45,8 +45,7 @@
             ACTION_SKIP_TO_PREVIOUS, ACTION_SKIP_TO_NEXT, ACTION_FAST_FORWARD, ACTION_SET_RATING,
             ACTION_SEEK_TO, ACTION_PLAY_PAUSE, ACTION_PLAY_FROM_MEDIA_ID, ACTION_PLAY_FROM_SEARCH,
             ACTION_SKIP_TO_QUEUE_ITEM, ACTION_PLAY_FROM_URI, ACTION_PREPARE,
-            ACTION_PREPARE_FROM_MEDIA_ID, ACTION_PREPARE_FROM_SEARCH, ACTION_PREPARE_FROM_URI,
-            ACTION_SET_REPEAT_MODE, ACTION_SET_SHUFFLE_MODE_ENABLED})
+            ACTION_PREPARE_FROM_MEDIA_ID, ACTION_PREPARE_FROM_SEARCH, ACTION_PREPARE_FROM_URI})
     @Retention(RetentionPolicy.SOURCE)
     public @interface Actions {}
 
@@ -177,20 +176,6 @@
     public static final long ACTION_PREPARE_FROM_URI = 1 << 17;
 
     /**
-     * Indicates this session supports the set repeat mode command.
-     *
-     * @see Builder#setActions(long)
-     */
-    public static final long ACTION_SET_REPEAT_MODE = 1 << 18;
-
-    /**
-     * Indicates this session supports the set shuffle mode enabled command.
-     *
-     * @see Builder#setActions(long)
-     */
-    public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 1 << 19;
-
-    /**
      * @hide
      */
     @IntDef({STATE_NONE, STATE_STOPPED, STATE_PAUSED, STATE_PLAYING, STATE_FAST_FORWARDING,
@@ -296,30 +281,6 @@
      */
     public final static long PLAYBACK_POSITION_UNKNOWN = -1;
 
-    /**
-     * @hide
-     */
-    @IntDef({REPEAT_MODE_NONE, REPEAT_MODE_ONE, REPEAT_MODE_ALL})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface RepeatMode {}
-    /**
-     * Use this value with {@link MediaController.TransportControls#setRepeatMode}
-     * to indicate that the playback will be stopped at the end of the playing media list.
-     */
-    public final static int REPEAT_MODE_NONE = 0;
-
-    /**
-     * Use this value with {@link MediaController.TransportControls#setRepeatMode}
-     * to indicate that the playback of the current playing media item will be repeated.
-     */
-    public final static int REPEAT_MODE_ONE = 1;
-
-    /**
-     * Use this value with {@link MediaController.TransportControls#setRepeatMode}
-     * to indicate that the playback of the playing media list will be repeated.
-     */
-    public final static int REPEAT_MODE_ALL = 2;
-
     private final int mState;
     private final long mPosition;
     private final long mBufferedPosition;
@@ -466,8 +427,6 @@
      * <li> {@link PlaybackState#ACTION_PREPARE_FROM_MEDIA_ID}</li>
      * <li> {@link PlaybackState#ACTION_PREPARE_FROM_SEARCH}</li>
      * <li> {@link PlaybackState#ACTION_PREPARE_FROM_URI}</li>
-     * <li> {@link PlaybackState#ACTION_SET_REPEAT_MODE}</li>
-     * <li> {@link PlaybackState#ACTION_SET_SHUFFLE_MODE_ENABLED}</li>
      * </ul>
      */
     @Actions
@@ -1002,8 +961,6 @@
          * <li> {@link PlaybackState#ACTION_PREPARE_FROM_MEDIA_ID}</li>
          * <li> {@link PlaybackState#ACTION_PREPARE_FROM_SEARCH}</li>
          * <li> {@link PlaybackState#ACTION_PREPARE_FROM_URI}</li>
-         * <li> {@link PlaybackState#ACTION_SET_REPEAT_MODE}</li>
-         * <li> {@link PlaybackState#ACTION_SET_SHUFFLE_MODE_ENABLED}</li>
          * </ul>
          *
          * @param actions The set of actions allowed.
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 1b55380..71f9ba2 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -436,6 +436,14 @@
     public static final String PARAM_CANONICAL_GENRE = "canonical_genre";
 
     /**
+     * A query, update or delete URI parameter that allows the caller to operate only on preview or
+     * non-preview channels. If set to "true", the operation affects the rows for preview channels
+     * only. If set to "false", the operation affects the rows for non-preview channels only.
+     * @hide
+     */
+    public static final String PARAM_PREVIEW = "preview";
+
+    /**
      * Builds an ID that uniquely identifies a TV input service.
      *
      * @param name The {@link ComponentName} of the TV input service to build ID for.
diff --git a/media/java/android/service/media/IMediaBrowserService.aidl b/media/java/android/service/media/IMediaBrowserService.aidl
index e95154f..84f41f6 100644
--- a/media/java/android/service/media/IMediaBrowserService.aidl
+++ b/media/java/android/service/media/IMediaBrowserService.aidl
@@ -19,10 +19,8 @@
 
     void addSubscriptionDeprecated(String uri, IMediaBrowserServiceCallbacks callbacks);
     void removeSubscriptionDeprecated(String uri, IMediaBrowserServiceCallbacks callbacks);
-    void getMediaItem(String uri, in ResultReceiver cb, IMediaBrowserServiceCallbacks callbacks);
-    void search(String query, in Bundle extras, in ResultReceiver cb,
-            IMediaBrowserServiceCallbacks callbacks);
 
+    void getMediaItem(String uri, in ResultReceiver cb, IMediaBrowserServiceCallbacks callbacks);
     void addSubscription(String uri, in IBinder token, in Bundle options,
             IMediaBrowserServiceCallbacks callbacks);
     void removeSubscription(String uri, in IBinder token, IMediaBrowserServiceCallbacks callbacks);
diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java
index d372efb..b52906d 100644
--- a/media/java/android/service/media/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
@@ -89,15 +89,8 @@
      */
     public static final String KEY_MEDIA_ITEM = "media_item";
 
-    /**
-     * A key for passing the list of MediaItems to the ResultReceiver in search.
-     * @hide
-     */
-    public static final String KEY_SEARCH_RESULTS = "search_results";
-
     private static final int RESULT_FLAG_OPTION_NOT_HANDLED = 1 << 0;
     private static final int RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED = 1 << 1;
-    private static final int RESULT_FLAG_ON_SEARCH_NOT_IMPLEMENTED = 1 << 2;
 
     private static final int RESULT_ERROR = -1;
     private static final int RESULT_OK = 0;
@@ -105,7 +98,7 @@
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(flag=true, value = { RESULT_FLAG_OPTION_NOT_HANDLED,
-            RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED, RESULT_FLAG_ON_SEARCH_NOT_IMPLEMENTED })
+            RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED })
     private @interface ResultFlags { }
 
     private final ArrayMap<IBinder, ConnectionRecord> mConnections = new ArrayMap<>();
@@ -137,7 +130,6 @@
      *
      * @see #onLoadChildren
      * @see #onLoadItem
-     * @see #onSearch
      */
     public class Result<T> {
         private Object mDebug;
@@ -330,23 +322,6 @@
                 }
             });
         }
-
-        @Override
-        public void search(final String query, Bundle extras, ResultReceiver receiver,
-                final IMediaBrowserServiceCallbacks callbacks) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    final IBinder b = callbacks.asBinder();
-                    ConnectionRecord connection = mConnections.get(b);
-                    if (connection == null) {
-                        Log.w(TAG, "search for callback that isn't registered query=" + query);
-                        return;
-                    }
-                    performSearch(query, extras, connection, receiver);
-                }
-            });
-        }
     }
 
     @Override
@@ -472,32 +447,6 @@
     }
 
     /**
-     * Called to get the search result.
-     * <p>
-     * Implementations must call {@link Result#sendResult result.sendResult}. If
-     * the search will be an expensive operation {@link Result#detach result.detach}
-     * may be called before returning from this function, and then {@link Result#sendResult
-     * result.sendResult} called when the search has been completed.
-     * </p><p>
-     * In case there are no search results, call {@link Result#sendResult} with an empty list.
-     * In case there are some errors happened, call {@link Result#sendResult result.sendResult}
-     * with {@code null}, which will invoke {@link MediaBrowser.SearchCallback#onError}.
-     * </p><p>
-     * The default implementation will invoke {@link MediaBrowser.SearchCallback#onError}.
-     * </p>
-     *
-     * @param query The search query sent from the media browser. It contains keywords separated
-     *            by space.
-     * @param extras The bundle of service-specific arguments sent from the media browser.
-     * @param result The {@link Result} to send the search result.
-     */
-    public void onSearch(@NonNull String query, Bundle extras,
-            Result<List<MediaBrowser.MediaItem>> result) {
-        result.setFlags(RESULT_FLAG_ON_SEARCH_NOT_IMPLEMENTED);
-        result.sendResult(null);
-    }
-
-    /**
      * Call to set the media session.
      * <p>
      * This should be called as soon as possible during the service's startup.
@@ -545,16 +494,16 @@
      * media browser service when connecting and retrieving the root id for browsing, or null if
      * none. The contents of this bundle may affect the information returned when browsing.
      *
-     * @throws IllegalStateException If this method is called outside of {@link #onLoadChildren},
-     *             {@link #onLoadItem} or {@link #onSearch}.
+     * @throws IllegalStateException If this method is called outside of {@link #onLoadChildren} or
+     *             {@link #onLoadItem}.
      * @see MediaBrowserService.BrowserRoot#EXTRA_RECENT
      * @see MediaBrowserService.BrowserRoot#EXTRA_OFFLINE
      * @see MediaBrowserService.BrowserRoot#EXTRA_SUGGESTED
      */
     public final Bundle getBrowserRootHints() {
         if (mCurConnection == null) {
-            throw new IllegalStateException("This should be called inside of onLoadChildren,"
-                    + " onLoadItem or onSearch methods");
+            throw new IllegalStateException("This should be called inside of onLoadChildren or"
+                    + " onLoadItem methods");
         }
         return mCurConnection.rootHints == null ? null : new Bundle(mCurConnection.rootHints);
     }
@@ -771,34 +720,6 @@
         }
     }
 
-    private void performSearch(String query, Bundle extras, final ConnectionRecord connection,
-            final ResultReceiver receiver) {
-        final Result<List<MediaBrowser.MediaItem>> result =
-                new Result<List<MediaBrowser.MediaItem>>(query) {
-            @Override
-            void onResultSent(List<MediaBrowser.MediaItem> items, @ResultFlags int flag) {
-                if ((flag & RESULT_FLAG_ON_SEARCH_NOT_IMPLEMENTED) != 0
-                        || items == null) {
-                    receiver.send(RESULT_ERROR, null);
-                    return;
-                }
-                Bundle bundle = new Bundle();
-                bundle.putParcelableArray(KEY_SEARCH_RESULTS,
-                        items.toArray(new MediaBrowser.MediaItem[0]));
-                receiver.send(RESULT_OK, bundle);
-            }
-        };
-
-        mCurConnection = connection;
-        onSearch(query, extras, result);
-        mCurConnection = null;
-
-        if (!result.isDone()) {
-            throw new IllegalStateException("onSearch must call detach() or sendResult()"
-                    + " before returning for query=" + query);
-        }
-    }
-
     /**
      * Contains information that the browser service needs to send to the client
      * when first connected.
diff --git a/native/android/sensor.cpp b/native/android/sensor.cpp
index ae16949..8e58210 100644
--- a/native/android/sensor.cpp
+++ b/native/android/sensor.cpp
@@ -17,7 +17,6 @@
 #define LOG_TAG "sensor"
 #include <utils/Log.h>
 
-#include <android/hardware_buffer.h>
 #include <android/looper.h>
 #include <android/sensor.h>
 #include <android/sharedmem.h>
@@ -28,6 +27,7 @@
 #include <utils/Looper.h>
 #include <utils/RefBase.h>
 #include <utils/Timers.h>
+#include <vndk/hardware_buffer.h>
 
 #include <poll.h>
 
diff --git a/packages/SettingsLib/res/layout/settings_with_drawer.xml b/packages/SettingsLib/res/layout/settings_with_drawer.xml
index e9c175f..55c192d 100644
--- a/packages/SettingsLib/res/layout/settings_with_drawer.xml
+++ b/packages/SettingsLib/res/layout/settings_with_drawer.xml
@@ -25,17 +25,13 @@
         android:layout_height="match_parent"
         android:orientation="vertical"
         android:fitsSystemWindows="true">
-        <FrameLayout
+        <Toolbar
+            android:id="@+id/action_bar"
             style="?android:attr/actionBarStyle"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:theme="?android:attr/actionBarTheme">
-            <Toolbar
-                android:id="@+id/action_bar"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:navigationContentDescription="@*android:string/action_bar_up_description"/>
-        </FrameLayout>
+            android:theme="?android:attr/actionBarTheme"
+            android:navigationContentDescription="@*android:string/action_bar_up_description"/>
         <FrameLayout
             android:id="@+id/content_header_container"
             style="?android:attr/actionBarStyle"
diff --git a/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityButtonHelper.java b/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityButtonHelper.java
new file mode 100644
index 0000000..972ea34
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityButtonHelper.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.accessibility;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.content.Context;
+import android.content.res.Resources;
+import android.provider.Settings;
+import android.view.accessibility.AccessibilityManager;
+
+import java.util.List;
+
+/**
+ * A helper class to assist determining the state of the accessibility button that can appear
+ * within the software-rendered navigation area.
+ */
+public class AccessibilityButtonHelper {
+    public static boolean isRequestedByMagnification(Context ctx) {
+        return Settings.Secure.getInt(ctx.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 0) == 1;
+    }
+
+    public static boolean isRequestedByAccessibilityService(Context ctx) {
+        final AccessibilityManager accessibilityManager = ctx.getSystemService(
+                AccessibilityManager.class);
+        List<AccessibilityServiceInfo> services =
+                accessibilityManager.getEnabledAccessibilityServiceList(
+                        AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
+        if (services != null) {
+            for (int i = 0, size = services.size(); i < size; i++) {
+                if ((services.get(i).flags
+                        & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON)
+                        != 0) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public static boolean isRequested(Context ctx) {
+        return isRequestedByMagnification(ctx) || isRequestedByAccessibilityService(ctx);
+    }
+
+    public static boolean isDeviceSupported(Resources res) {
+        return res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index 8a86c13..10f3b63 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -29,6 +29,7 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.IPackageStatsObserver;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PackageStats;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
@@ -52,6 +53,7 @@
 import com.android.settingslib.R;
 
 import java.io.File;
+import java.io.IOException;
 import java.text.Collator;
 import java.text.Normalizer;
 import java.text.Normalizer.Form;
@@ -61,6 +63,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Objects;
+import java.util.UUID;
 import java.util.regex.Pattern;
 
 /**
@@ -114,7 +117,7 @@
     final ArrayList<AppEntry> mAppEntries = new ArrayList<AppEntry>();
     List<ApplicationInfo> mApplications = new ArrayList<ApplicationInfo>();
     long mCurId = 1;
-    String mCurComputingSizeUuid;
+    UUID mCurComputingSizeUuid;
     String mCurComputingSizePkg;
     int mCurComputingSizeUserId;
     boolean mSessionsChanged;
@@ -334,15 +337,23 @@
             AppEntry entry = mEntriesMap.get(userId).get(packageName);
             if (entry != null && (entry.info.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
                 mBackgroundHandler.post(() -> {
-                    final StorageStats stats = mStats.queryStatsForPackage(entry.info.volumeUuid,
-                            packageName, UserHandle.of(userId));
-                    final PackageStats legacyStats = new PackageStats(packageName, userId);
-                    legacyStats.codeSize = stats.getCodeBytes();
-                    legacyStats.dataSize = stats.getDataBytes();
-                    legacyStats.cacheSize = stats.getCacheBytes();
                     try {
-                        mBackgroundHandler.mStatsObserver.onGetStatsCompleted(legacyStats, true);
-                    } catch (RemoteException ignored) {
+                        final StorageStats stats = mStats.queryStatsForPackage(
+                                entry.info.storageUuid, packageName, UserHandle.of(userId));
+                        final PackageStats legacy = new PackageStats(packageName, userId);
+                        legacy.codeSize = stats.getCodeBytes();
+                        legacy.dataSize = stats.getDataBytes();
+                        legacy.cacheSize = stats.getCacheBytes();
+                        try {
+                            mBackgroundHandler.mStatsObserver.onGetStatsCompleted(legacy, true);
+                        } catch (RemoteException ignored) {
+                        }
+                    } catch (NameNotFoundException | IOException e) {
+                        Log.w(TAG, "Failed to query stats: " + e);
+                        try {
+                            mBackgroundHandler.mStatsObserver.onGetStatsCompleted(null, false);
+                        } catch (RemoteException ignored) {
+                        }
                     }
                 });
             }
@@ -979,7 +990,7 @@
                                         mMainHandler.sendMessage(m);
                                     }
                                     entry.sizeLoadStart = now;
-                                    mCurComputingSizeUuid = entry.info.volumeUuid;
+                                    mCurComputingSizeUuid = entry.info.storageUuid;
                                     mCurComputingSizePkg = entry.info.packageName;
                                     mCurComputingSizeUserId = UserHandle.getUserId(entry.info.uid);
 
@@ -988,17 +999,17 @@
                                             final StorageStats stats = mStats.queryStatsForPackage(
                                                     mCurComputingSizeUuid, mCurComputingSizePkg,
                                                     UserHandle.of(mCurComputingSizeUserId));
-                                            final PackageStats legacyStats = new PackageStats(
+                                            final PackageStats legacy = new PackageStats(
                                                     mCurComputingSizePkg, mCurComputingSizeUserId);
-                                            legacyStats.codeSize = stats.getCodeBytes();
-                                            legacyStats.dataSize = stats.getDataBytes();
-                                            legacyStats.cacheSize = stats.getCacheBytes();
+                                            legacy.codeSize = stats.getCodeBytes();
+                                            legacy.dataSize = stats.getDataBytes();
+                                            legacy.cacheSize = stats.getCacheBytes();
                                             try {
-                                                mStatsObserver.onGetStatsCompleted(legacyStats, true);
+                                                mStatsObserver.onGetStatsCompleted(legacy, true);
                                             } catch (RemoteException ignored) {
                                             }
-                                        } catch (IllegalStateException e) {
-                                            Log.e(TAG,"An exception occurred while fetching app size", e);
+                                        } catch (NameNotFoundException | IOException e) {
+                                            Log.w(TAG, "Failed to query stats: " + e);
                                             try {
                                                 mStatsObserver.onGetStatsCompleted(null, false);
                                             } catch (RemoteException ignored) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java b/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
index 2183573..34fdc9d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
@@ -19,9 +19,12 @@
 import android.app.usage.StorageStats;
 import android.app.usage.StorageStatsManager;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.os.UserHandle;
 import android.support.annotation.VisibleForTesting;
 
+import java.io.IOException;
+
 /**
  * StorageStatsSource wraps the StorageStatsManager for testability purposes.
  */
@@ -32,17 +35,21 @@
         mStorageStatsManager = context.getSystemService(StorageStatsManager.class);
     }
 
-    public StorageStatsSource.ExternalStorageStats getExternalStorageStats(String volumeUuid, UserHandle user) {
+    public StorageStatsSource.ExternalStorageStats getExternalStorageStats(String volumeUuid,
+            UserHandle user) throws IOException {
         return new StorageStatsSource.ExternalStorageStats(
                 mStorageStatsManager.queryExternalStatsForUser(volumeUuid, user));
     }
 
-    public StorageStatsSource.AppStorageStats getStatsForUid(String volumeUuid, int uid) {
-        return new StorageStatsSource.AppStorageStatsImpl(mStorageStatsManager.queryStatsForUid(volumeUuid, uid));
+    public StorageStatsSource.AppStorageStats getStatsForUid(String volumeUuid, int uid)
+            throws IOException {
+        return new StorageStatsSource.AppStorageStatsImpl(
+                mStorageStatsManager.queryStatsForUid(volumeUuid, uid));
     }
 
     public StorageStatsSource.AppStorageStats getStatsForPackage(
-            String volumeUuid, String packageName, UserHandle user) {
+            String volumeUuid, String packageName, UserHandle user)
+            throws PackageManager.NameNotFoundException, IOException {
         return new StorageStatsSource.AppStorageStatsImpl(
                 mStorageStatsManager.queryStatsForPackage(volumeUuid, packageName, user));
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java
index 88f133c..ccf7a0b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java
@@ -20,11 +20,16 @@
 import android.app.usage.StorageStatsManager;
 import android.content.Context;
 import android.os.storage.VolumeInfo;
+import android.util.Log;
+
+import java.io.IOException;
 
 /**
  * PrivateStorageInfo provides information about the total and free storage on the device.
  */
 public class PrivateStorageInfo {
+    private static final String TAG = "PrivateStorageInfo";
+
     public final long freeBytes;
     public final long totalBytes;
 
@@ -41,8 +46,12 @@
         long privateTotalBytes = 0;
         for (VolumeInfo info : sm.getVolumes()) {
             if (info.getType() == VolumeInfo.TYPE_PRIVATE && info.isMountedReadable()) {
-                privateTotalBytes += sm.getTotalBytes(stats, info);
-                privateFreeBytes += sm.getFreeBytes(stats, info);
+                try {
+                    privateTotalBytes += sm.getTotalBytes(stats, info);
+                    privateFreeBytes += sm.getFreeBytes(stats, info);
+                } catch (IOException e) {
+                    Log.w(TAG, e);
+                }
             }
         }
         return new PrivateStorageInfo(privateFreeBytes, privateTotalBytes);
@@ -51,6 +60,11 @@
     public static long getTotalSize(VolumeInfo info, long totalInternalStorage) {
         final Context context = AppGlobals.getInitialApplication();
         final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);
-        return stats.getTotalBytes(info.getFsUuid());
+        try {
+            return stats.getTotalBytes(info.getFsUuid());
+        } catch (IOException e) {
+            Log.w(TAG, e);
+            return 0;
+        }
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageManagerVolumeProvider.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageManagerVolumeProvider.java
index 11060e6..b57b6cc 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageManagerVolumeProvider.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageManagerVolumeProvider.java
@@ -20,6 +20,7 @@
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 
+import java.io.IOException;
 import java.util.List;
 
 /**
@@ -49,12 +50,12 @@
     }
 
     @Override
-    public long getTotalBytes(StorageStatsManager stats, VolumeInfo volume) {
+    public long getTotalBytes(StorageStatsManager stats, VolumeInfo volume) throws IOException {
         return stats.getTotalBytes(volume.getFsUuid());
     }
 
     @Override
-    public long getFreeBytes(StorageStatsManager stats, VolumeInfo volume) {
+    public long getFreeBytes(StorageStatsManager stats, VolumeInfo volume) throws IOException {
         return stats.getFreeBytes(volume.getFsUuid());
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
index 60e10a1..ea28fe6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
@@ -32,6 +32,7 @@
 import android.util.SparseArray;
 import android.util.SparseLongArray;
 
+import java.io.IOException;
 import java.lang.ref.WeakReference;
 import java.util.HashMap;
 import java.util.List;
@@ -154,7 +155,7 @@
         try {
             details.totalSize = mStats.getTotalBytes(mVolume.fsUuid);
             details.availSize = mStats.getFreeBytes(mVolume.fsUuid);
-        } catch (IllegalStateException e) {
+        } catch (IOException e) {
             // The storage volume became null while we were measuring it.
             Log.w(TAG, e);
             return details;
@@ -169,8 +170,14 @@
                 final HashMap<String, Long> mediaMap = new HashMap<>();
                 details.mediaSize.put(user.id, mediaMap);
 
-                final ExternalStorageStats stats = mStats
-                        .queryExternalStatsForUser(mSharedVolume.fsUuid, UserHandle.of(user.id));
+                final ExternalStorageStats stats;
+                try {
+                    stats = mStats.queryExternalStatsForUser(mSharedVolume.fsUuid,
+                            UserHandle.of(user.id));
+                } catch (IOException e) {
+                    Log.w(TAG, e);
+                    continue;
+                }
 
                 addValue(details.usersSize, user.id, stats.getTotalBytes());
 
@@ -190,8 +197,13 @@
 
         if ((mVolume.getType() == VolumeInfo.TYPE_PRIVATE) && mVolume.isMountedReadable()) {
             for (UserInfo user : users) {
-                final StorageStats stats = mStats.queryStatsForUser(mVolume.fsUuid,
-                        UserHandle.of(user.id));
+                final StorageStats stats;
+                try {
+                    stats = mStats.queryStatsForUser(mVolume.fsUuid, UserHandle.of(user.id));
+                } catch (IOException e) {
+                    Log.w(TAG, e);
+                    continue;
+                }
 
                 // Only count code once against current user
                 if (user.id == UserHandle.myUserId()) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageVolumeProvider.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageVolumeProvider.java
index e5d85d1..4c45413 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageVolumeProvider.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageVolumeProvider.java
@@ -19,6 +19,7 @@
 import android.app.usage.StorageStatsManager;
 import android.os.storage.VolumeInfo;
 
+import java.io.IOException;
 import java.util.List;
 
 /**
@@ -46,12 +47,12 @@
      *
      * @pre The volume is a private volume and is readable.
      */
-    long getTotalBytes(StorageStatsManager stats, VolumeInfo volume);
+    long getTotalBytes(StorageStatsManager stats, VolumeInfo volume) throws IOException;
 
     /**
      * Returns the free bytes for a given storage volume.
      *
      * @pre The volume is a private volume and is readable.
      */
-    long getFreeBytes(StorageStatsManager stats, VolumeInfo volume);
+    long getFreeBytes(StorageStatsManager stats, VolumeInfo volume) throws IOException;
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
index d6bde81..9d09737 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
@@ -40,6 +40,8 @@
             "com.android.settings.category.ia.language";
     public static final String CATEGORY_SYSTEM_DEVELOPMENT =
             "com.android.settings.category.ia.development";
+    public static final String CATEGORY_NOTIFICATIONS =
+            "com.android.settings.category.ia.notifications";
 
     public static final Map<String, String> KEY_COMPAT_MAP;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index f277165..314791e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -234,10 +234,19 @@
     }
 
     /**
-     * Forces an update of the wifi networks when not scanning.
+     * Synchronously update the list of access points with the latest information.
      */
     public void forceUpdate() {
+        mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
+
+        mLastInfo = mWifiManager.getConnectionInfo();
+        mLastNetworkInfo = mConnectivityManager.getNetworkInfo(mWifiManager.getCurrentNetwork());
         updateAccessPoints();
+
+        // Synchronously copy access points
+        mMainHandler.removeMessages(MainHandler.MSG_ACCESS_POINT_CHANGED);
+        mMainHandler.handleMessage(
+                Message.obtain(mMainHandler, MainHandler.MSG_ACCESS_POINT_CHANGED));
     }
 
     /**
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index f9e695d..b938fe2 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -20,7 +20,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.atLeast;
@@ -33,12 +32,13 @@
 import android.content.Context;
 import android.content.Intent;
 import android.net.ConnectivityManager;
+import android.net.Network;
 import android.net.NetworkBadging;
 import android.net.NetworkInfo;
 import android.net.NetworkKey;
 import android.net.NetworkScoreManager;
-import android.net.ScoredNetwork;
 import android.net.RssiCurve;
+import android.net.ScoredNetwork;
 import android.net.WifiKey;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
@@ -47,10 +47,10 @@
 import android.net.wifi.WifiNetworkScoreCache;
 import android.net.wifi.WifiSsid;
 import android.os.Bundle;
-import android.os.SystemClock;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
+import android.os.SystemClock;
 import android.provider.Settings;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
@@ -62,8 +62,8 @@
 import org.junit.runner.RunWith;
 
 import org.mockito.ArgumentCaptor;
-import org.mockito.Matchers;
 import org.mockito.Captor;
+import org.mockito.Matchers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
@@ -666,4 +666,29 @@
         verify(mockWifiManager, atLeast(2)).getConnectionInfo();
         assertThat(tracker.getAccessPoints().get(0).getRssi()).isEqualTo(newRssi);
     }
+
+    @Test
+    public void forceUpdateShouldSynchronouslyFetchLatestInformation() throws Exception {
+        when(mockWifiManager.getConnectionInfo()).thenReturn(CONNECTED_AP_1_INFO);
+
+        WifiConfiguration configuration = new WifiConfiguration();
+        configuration.SSID = SSID_1;
+        configuration.BSSID = BSSID_1;
+        configuration.networkId = CONNECTED_NETWORK_ID;
+        when(mockWifiManager.getConfiguredNetworks()).thenReturn(Arrays.asList(configuration));
+
+        NetworkInfo networkInfo = new NetworkInfo(
+                ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
+        networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "connected", "test");
+        when(mockConnectivityManager.getNetworkInfo(any(Network.class))).thenReturn(networkInfo);
+
+
+        WifiTracker tracker = createMockedWifiTracker();
+        startTracking(tracker);
+        tracker.forceUpdate();
+
+        verify(mockWifiListener).onAccessPointsChanged();
+        assertThat(tracker.getAccessPoints().size()).isEqualTo(2);
+        assertThat(tracker.getAccessPoints().get(0).isActive()).isTrue();
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/tv_pip_onboarding_background_enter_animation.xml b/packages/SystemUI/res/anim/tv_pip_onboarding_background_enter_animation.xml
deleted file mode 100644
index 9ab41d0..0000000
--- a/packages/SystemUI/res/anim/tv_pip_onboarding_background_enter_animation.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <objectAnimator
-        android:propertyName="alpha"
-        android:valueFrom="0"
-        android:valueTo="0.9"
-        android:interpolator="@android:interpolator/linear"
-        android:duration="@integer/tv_pip_onboarding_anim_duration" />
-</set>
diff --git a/packages/SystemUI/res/anim/tv_pip_onboarding_button_enter_animation.xml b/packages/SystemUI/res/anim/tv_pip_onboarding_button_enter_animation.xml
deleted file mode 100644
index 01c263b..0000000
--- a/packages/SystemUI/res/anim/tv_pip_onboarding_button_enter_animation.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <objectAnimator
-        android:propertyName="translationY"
-        android:valueFrom="114dp"
-        android:valueTo="0dp"
-        android:interpolator="@android:interpolator/fast_out_slow_in"
-        android:duration="@integer/tv_pip_onboarding_anim_duration" />
-    <objectAnimator
-        android:propertyName="alpha"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear"
-        android:duration="@integer/tv_pip_onboarding_anim_duration" />
-</set>
diff --git a/packages/SystemUI/res/anim/tv_pip_onboarding_description_enter_animation.xml b/packages/SystemUI/res/anim/tv_pip_onboarding_description_enter_animation.xml
deleted file mode 100644
index a12b3b6..0000000
--- a/packages/SystemUI/res/anim/tv_pip_onboarding_description_enter_animation.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <objectAnimator
-        android:propertyName="translationY"
-        android:valueFrom="84dp"
-        android:valueTo="0dp"
-        android:interpolator="@android:interpolator/fast_out_slow_in"
-        android:duration="@integer/tv_pip_onboarding_anim_duration" />
-    <objectAnimator
-        android:propertyName="alpha"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/linear"
-        android:duration="@integer/tv_pip_onboarding_anim_duration" />
-</set>
diff --git a/packages/SystemUI/res/anim/tv_pip_onboarding_image_enter_animation.xml b/packages/SystemUI/res/anim/tv_pip_onboarding_image_enter_animation.xml
deleted file mode 100644
index ae9677e..0000000
--- a/packages/SystemUI/res/anim/tv_pip_onboarding_image_enter_animation.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <objectAnimator
-        android:propertyName="translationY"
-        android:valueFrom="114dp"
-        android:valueTo="0dp"
-        android:interpolator="@android:interpolator/fast_out_slow_in"
-        android:duration="@integer/tv_pip_onboarding_anim_duration" />
-    <objectAnimator
-        android:propertyName="alpha"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/fast_out_slow_in"
-        android:duration="@integer/tv_pip_onboarding_anim_duration" />
-</set>
diff --git a/packages/SystemUI/res/anim/tv_pip_onboarding_title_enter_animation.xml b/packages/SystemUI/res/anim/tv_pip_onboarding_title_enter_animation.xml
deleted file mode 100644
index 4bde070..0000000
--- a/packages/SystemUI/res/anim/tv_pip_onboarding_title_enter_animation.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <objectAnimator
-        android:propertyName="translationY"
-        android:valueFrom="84dp"
-        android:valueTo="0dp"
-        android:interpolator="@android:interpolator/fast_out_slow_in"
-        android:duration="@integer/tv_pip_onboarding_anim_duration" />
-    <objectAnimator
-        android:propertyName="alpha"
-        android:valueTo="1"
-        android:interpolator="@android:interpolator/fast_out_slow_in"
-        android:duration="@integer/tv_pip_onboarding_anim_duration" />
-</set>
diff --git a/packages/SystemUI/res/anim/tv_pip_overlay_fade_in_animation.xml b/packages/SystemUI/res/anim/tv_pip_overlay_fade_in_animation.xml
deleted file mode 100644
index 33bceaa..0000000
--- a/packages/SystemUI/res/anim/tv_pip_overlay_fade_in_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:propertyName="alpha"
-    android:valueTo="1"
-    android:interpolator="@android:interpolator/fast_out_slow_in"
-    android:duration="350" />
diff --git a/packages/SystemUI/res/anim/tv_pip_overlay_fade_out_animation.xml b/packages/SystemUI/res/anim/tv_pip_overlay_fade_out_animation.xml
deleted file mode 100644
index a12ddff..0000000
--- a/packages/SystemUI/res/anim/tv_pip_overlay_fade_out_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:propertyName="alpha"
-    android:valueTo="0"
-    android:interpolator="@android:interpolator/fast_out_slow_in"
-    android:duration="500" />
diff --git a/packages/SystemUI/res/color/segmented_button_text_selector.xml b/packages/SystemUI/res/color/segmented_button_text_selector.xml
index 537cbb8..d4f0181 100644
--- a/packages/SystemUI/res/color/segmented_button_text_selector.xml
+++ b/packages/SystemUI/res/color/segmented_button_text_selector.xml
@@ -18,4 +18,4 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_selected="true" android:color="?android:attr/textColorPrimary"/>
     <item android:alpha="0.58" android:color="?android:attr/colorForeground"/>
-</selector>
\ No newline at end of file
+</selector>
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_0.png b/packages/SystemUI/res/drawable-xhdpi/remote_0.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_1.png b/packages/SystemUI/res/drawable-xhdpi/remote_1.png
deleted file mode 100644
index 252ff5e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_10.png b/packages/SystemUI/res/drawable-xhdpi/remote_10.png
deleted file mode 100644
index 5e52b37..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_10.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_100.png b/packages/SystemUI/res/drawable-xhdpi/remote_100.png
deleted file mode 100644
index f604808..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_101.png b/packages/SystemUI/res/drawable-xhdpi/remote_101.png
deleted file mode 100644
index 0272e45..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_101.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_102.png b/packages/SystemUI/res/drawable-xhdpi/remote_102.png
deleted file mode 100644
index aaa35c0..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_102.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_103.png b/packages/SystemUI/res/drawable-xhdpi/remote_103.png
deleted file mode 100644
index 20f95a5..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_103.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_104.png b/packages/SystemUI/res/drawable-xhdpi/remote_104.png
deleted file mode 100644
index 052f23e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_104.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_105.png b/packages/SystemUI/res/drawable-xhdpi/remote_105.png
deleted file mode 100644
index c5c8256..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_105.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_106.png b/packages/SystemUI/res/drawable-xhdpi/remote_106.png
deleted file mode 100644
index 4e804fe..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_106.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_107.png b/packages/SystemUI/res/drawable-xhdpi/remote_107.png
deleted file mode 100644
index 76669cc..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_107.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_108.png b/packages/SystemUI/res/drawable-xhdpi/remote_108.png
deleted file mode 100644
index c1b2f3b..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_108.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_109.png b/packages/SystemUI/res/drawable-xhdpi/remote_109.png
deleted file mode 100644
index 79e1d7b..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_109.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_11.png b/packages/SystemUI/res/drawable-xhdpi/remote_11.png
deleted file mode 100644
index cfec6cb..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_11.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_110.png b/packages/SystemUI/res/drawable-xhdpi/remote_110.png
deleted file mode 100644
index d902297..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_110.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_111.png b/packages/SystemUI/res/drawable-xhdpi/remote_111.png
deleted file mode 100644
index e48ed0b..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_111.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_112.png b/packages/SystemUI/res/drawable-xhdpi/remote_112.png
deleted file mode 100644
index 90dd1a2..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_112.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_113.png b/packages/SystemUI/res/drawable-xhdpi/remote_113.png
deleted file mode 100644
index 8fb4ad2..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_113.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_114.png b/packages/SystemUI/res/drawable-xhdpi/remote_114.png
deleted file mode 100644
index 76873fb..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_114.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_115.png b/packages/SystemUI/res/drawable-xhdpi/remote_115.png
deleted file mode 100644
index e923d4c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_115.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_116.png b/packages/SystemUI/res/drawable-xhdpi/remote_116.png
deleted file mode 100644
index 41d5124..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_116.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_117.png b/packages/SystemUI/res/drawable-xhdpi/remote_117.png
deleted file mode 100644
index eacde64..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_117.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_118.png b/packages/SystemUI/res/drawable-xhdpi/remote_118.png
deleted file mode 100644
index 5dc1fb0..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_118.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_119.png b/packages/SystemUI/res/drawable-xhdpi/remote_119.png
deleted file mode 100644
index a16f037..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_119.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_12.png b/packages/SystemUI/res/drawable-xhdpi/remote_12.png
deleted file mode 100644
index 28bb387..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_12.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_120.png b/packages/SystemUI/res/drawable-xhdpi/remote_120.png
deleted file mode 100644
index fe3ef41..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_120.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_121.png b/packages/SystemUI/res/drawable-xhdpi/remote_121.png
deleted file mode 100644
index ef2b892..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_121.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_122.png b/packages/SystemUI/res/drawable-xhdpi/remote_122.png
deleted file mode 100644
index 5342976..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_122.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_123.png b/packages/SystemUI/res/drawable-xhdpi/remote_123.png
deleted file mode 100644
index bb8a53a..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_123.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_124.png b/packages/SystemUI/res/drawable-xhdpi/remote_124.png
deleted file mode 100644
index b68337e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_124.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_125.png b/packages/SystemUI/res/drawable-xhdpi/remote_125.png
deleted file mode 100644
index 81fa3a7..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_125.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_126.png b/packages/SystemUI/res/drawable-xhdpi/remote_126.png
deleted file mode 100644
index 2339d74..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_126.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_127.png b/packages/SystemUI/res/drawable-xhdpi/remote_127.png
deleted file mode 100644
index 90d1e0b..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_127.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_128.png b/packages/SystemUI/res/drawable-xhdpi/remote_128.png
deleted file mode 100644
index 6de4eb8..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_128.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_129.png b/packages/SystemUI/res/drawable-xhdpi/remote_129.png
deleted file mode 100644
index 9086074..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_129.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_13.png b/packages/SystemUI/res/drawable-xhdpi/remote_13.png
deleted file mode 100644
index a1e212d..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_13.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_130.png b/packages/SystemUI/res/drawable-xhdpi/remote_130.png
deleted file mode 100644
index 2bc9698..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_130.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_131.png b/packages/SystemUI/res/drawable-xhdpi/remote_131.png
deleted file mode 100644
index d18d2c6..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_131.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_132.png b/packages/SystemUI/res/drawable-xhdpi/remote_132.png
deleted file mode 100644
index 10a00cd..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_132.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_133.png b/packages/SystemUI/res/drawable-xhdpi/remote_133.png
deleted file mode 100644
index 6f495b4..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_133.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_134.png b/packages/SystemUI/res/drawable-xhdpi/remote_134.png
deleted file mode 100644
index 703f2c6..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_134.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_135.png b/packages/SystemUI/res/drawable-xhdpi/remote_135.png
deleted file mode 100644
index f4105b0..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_135.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_136.png b/packages/SystemUI/res/drawable-xhdpi/remote_136.png
deleted file mode 100644
index 0c3a5bc..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_136.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_137.png b/packages/SystemUI/res/drawable-xhdpi/remote_137.png
deleted file mode 100644
index cbebc05..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_137.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_138.png b/packages/SystemUI/res/drawable-xhdpi/remote_138.png
deleted file mode 100644
index 6dfefb0..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_138.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_139.png b/packages/SystemUI/res/drawable-xhdpi/remote_139.png
deleted file mode 100644
index 1acfdd6..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_139.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_14.png b/packages/SystemUI/res/drawable-xhdpi/remote_14.png
deleted file mode 100644
index a503cdf..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_14.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_140.png b/packages/SystemUI/res/drawable-xhdpi/remote_140.png
deleted file mode 100644
index 70d27c1..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_140.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_141.png b/packages/SystemUI/res/drawable-xhdpi/remote_141.png
deleted file mode 100644
index d523a0c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_141.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_142.png b/packages/SystemUI/res/drawable-xhdpi/remote_142.png
deleted file mode 100644
index ed6a65d..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_142.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_143.png b/packages/SystemUI/res/drawable-xhdpi/remote_143.png
deleted file mode 100644
index 9b048e6..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_143.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_144.png b/packages/SystemUI/res/drawable-xhdpi/remote_144.png
deleted file mode 100644
index 9e2337d..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_144.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_145.png b/packages/SystemUI/res/drawable-xhdpi/remote_145.png
deleted file mode 100644
index 3f30629..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_145.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_146.png b/packages/SystemUI/res/drawable-xhdpi/remote_146.png
deleted file mode 100644
index 1288039..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_146.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_147.png b/packages/SystemUI/res/drawable-xhdpi/remote_147.png
deleted file mode 100644
index d060539..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_147.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_148.png b/packages/SystemUI/res/drawable-xhdpi/remote_148.png
deleted file mode 100644
index 5be839d..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_148.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_149.png b/packages/SystemUI/res/drawable-xhdpi/remote_149.png
deleted file mode 100644
index 39d31ba..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_149.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_15.png b/packages/SystemUI/res/drawable-xhdpi/remote_15.png
deleted file mode 100644
index 5695595..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_15.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_150.png b/packages/SystemUI/res/drawable-xhdpi/remote_150.png
deleted file mode 100644
index ec2667c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_150.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_151.png b/packages/SystemUI/res/drawable-xhdpi/remote_151.png
deleted file mode 100644
index ec2667c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_151.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_152.png b/packages/SystemUI/res/drawable-xhdpi/remote_152.png
deleted file mode 100644
index a5d58c8..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_152.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_153.png b/packages/SystemUI/res/drawable-xhdpi/remote_153.png
deleted file mode 100644
index a5d58c8..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_153.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_154.png b/packages/SystemUI/res/drawable-xhdpi/remote_154.png
deleted file mode 100644
index a5d58c8..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_154.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_155.png b/packages/SystemUI/res/drawable-xhdpi/remote_155.png
deleted file mode 100644
index 793d411..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_155.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_156.png b/packages/SystemUI/res/drawable-xhdpi/remote_156.png
deleted file mode 100644
index 793d411..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_156.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_157.png b/packages/SystemUI/res/drawable-xhdpi/remote_157.png
deleted file mode 100644
index f9d6cdc..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_157.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_158.png b/packages/SystemUI/res/drawable-xhdpi/remote_158.png
deleted file mode 100644
index da8d5d7..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_158.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_159.png b/packages/SystemUI/res/drawable-xhdpi/remote_159.png
deleted file mode 100644
index 1e0b097..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_159.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_16.png b/packages/SystemUI/res/drawable-xhdpi/remote_16.png
deleted file mode 100644
index 4ae106c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_16.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_160.png b/packages/SystemUI/res/drawable-xhdpi/remote_160.png
deleted file mode 100644
index 8aa68ad..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_160.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_161.png b/packages/SystemUI/res/drawable-xhdpi/remote_161.png
deleted file mode 100644
index e49fdd9..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_161.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_162.png b/packages/SystemUI/res/drawable-xhdpi/remote_162.png
deleted file mode 100644
index 69257a0..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_162.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_163.png b/packages/SystemUI/res/drawable-xhdpi/remote_163.png
deleted file mode 100644
index 8f0c3d5..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_163.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_164.png b/packages/SystemUI/res/drawable-xhdpi/remote_164.png
deleted file mode 100644
index a4c3229..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_164.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_165.png b/packages/SystemUI/res/drawable-xhdpi/remote_165.png
deleted file mode 100644
index 46fae23..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_165.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_166.png b/packages/SystemUI/res/drawable-xhdpi/remote_166.png
deleted file mode 100644
index 40d5a9b..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_166.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_167.png b/packages/SystemUI/res/drawable-xhdpi/remote_167.png
deleted file mode 100644
index 6bd0380..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_167.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_168.png b/packages/SystemUI/res/drawable-xhdpi/remote_168.png
deleted file mode 100644
index 03904bf..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_168.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_169.png b/packages/SystemUI/res/drawable-xhdpi/remote_169.png
deleted file mode 100644
index 564a161..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_169.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_17.png b/packages/SystemUI/res/drawable-xhdpi/remote_17.png
deleted file mode 100644
index 0703e1a..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_17.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_170.png b/packages/SystemUI/res/drawable-xhdpi/remote_170.png
deleted file mode 100644
index 0411f94..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_170.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_171.png b/packages/SystemUI/res/drawable-xhdpi/remote_171.png
deleted file mode 100644
index ec141e9..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_171.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_172.png b/packages/SystemUI/res/drawable-xhdpi/remote_172.png
deleted file mode 100644
index cb9ecaf..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_172.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_173.png b/packages/SystemUI/res/drawable-xhdpi/remote_173.png
deleted file mode 100644
index 484ee51..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_173.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_174.png b/packages/SystemUI/res/drawable-xhdpi/remote_174.png
deleted file mode 100644
index 85a3135..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_174.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_175.png b/packages/SystemUI/res/drawable-xhdpi/remote_175.png
deleted file mode 100644
index edd6507..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_175.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_176.png b/packages/SystemUI/res/drawable-xhdpi/remote_176.png
deleted file mode 100644
index d95a68b..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_176.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_177.png b/packages/SystemUI/res/drawable-xhdpi/remote_177.png
deleted file mode 100644
index 305641f..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_177.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_178.png b/packages/SystemUI/res/drawable-xhdpi/remote_178.png
deleted file mode 100644
index 59de0e5..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_178.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_179.png b/packages/SystemUI/res/drawable-xhdpi/remote_179.png
deleted file mode 100644
index 414e548..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_179.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_18.png b/packages/SystemUI/res/drawable-xhdpi/remote_18.png
deleted file mode 100644
index 74df1e4..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_18.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_180.png b/packages/SystemUI/res/drawable-xhdpi/remote_180.png
deleted file mode 100644
index b5d925c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_180.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_181.png b/packages/SystemUI/res/drawable-xhdpi/remote_181.png
deleted file mode 100644
index e8a7127..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_181.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_182.png b/packages/SystemUI/res/drawable-xhdpi/remote_182.png
deleted file mode 100644
index 29c7037..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_182.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_183.png b/packages/SystemUI/res/drawable-xhdpi/remote_183.png
deleted file mode 100644
index 9491d94..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_183.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_184.png b/packages/SystemUI/res/drawable-xhdpi/remote_184.png
deleted file mode 100644
index 4aa0e32..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_184.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_185.png b/packages/SystemUI/res/drawable-xhdpi/remote_185.png
deleted file mode 100644
index 2a0dde8..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_185.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_186.png b/packages/SystemUI/res/drawable-xhdpi/remote_186.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_186.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_187.png b/packages/SystemUI/res/drawable-xhdpi/remote_187.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_187.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_188.png b/packages/SystemUI/res/drawable-xhdpi/remote_188.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_188.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_189.png b/packages/SystemUI/res/drawable-xhdpi/remote_189.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_189.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_19.png b/packages/SystemUI/res/drawable-xhdpi/remote_19.png
deleted file mode 100644
index 222ea31..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_19.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_190.png b/packages/SystemUI/res/drawable-xhdpi/remote_190.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_190.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_191.png b/packages/SystemUI/res/drawable-xhdpi/remote_191.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_191.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_192.png b/packages/SystemUI/res/drawable-xhdpi/remote_192.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_192.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_193.png b/packages/SystemUI/res/drawable-xhdpi/remote_193.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_193.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_194.png b/packages/SystemUI/res/drawable-xhdpi/remote_194.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_194.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_195.png b/packages/SystemUI/res/drawable-xhdpi/remote_195.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_195.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_196.png b/packages/SystemUI/res/drawable-xhdpi/remote_196.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_196.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_197.png b/packages/SystemUI/res/drawable-xhdpi/remote_197.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_197.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_198.png b/packages/SystemUI/res/drawable-xhdpi/remote_198.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_198.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_199.png b/packages/SystemUI/res/drawable-xhdpi/remote_199.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_199.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_2.png b/packages/SystemUI/res/drawable-xhdpi/remote_2.png
deleted file mode 100644
index fb3f7ef..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_20.png b/packages/SystemUI/res/drawable-xhdpi/remote_20.png
deleted file mode 100644
index 646587c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_20.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_200.png b/packages/SystemUI/res/drawable-xhdpi/remote_200.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_200.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_201.png b/packages/SystemUI/res/drawable-xhdpi/remote_201.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_201.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_202.png b/packages/SystemUI/res/drawable-xhdpi/remote_202.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_202.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_203.png b/packages/SystemUI/res/drawable-xhdpi/remote_203.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_203.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_204.png b/packages/SystemUI/res/drawable-xhdpi/remote_204.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_204.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_205.png b/packages/SystemUI/res/drawable-xhdpi/remote_205.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_205.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_206.png b/packages/SystemUI/res/drawable-xhdpi/remote_206.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_206.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_207.png b/packages/SystemUI/res/drawable-xhdpi/remote_207.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_207.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_208.png b/packages/SystemUI/res/drawable-xhdpi/remote_208.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_208.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_209.png b/packages/SystemUI/res/drawable-xhdpi/remote_209.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_209.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_21.png b/packages/SystemUI/res/drawable-xhdpi/remote_21.png
deleted file mode 100644
index 5858ba92..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_21.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_210.png b/packages/SystemUI/res/drawable-xhdpi/remote_210.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_210.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_211.png b/packages/SystemUI/res/drawable-xhdpi/remote_211.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_211.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_212.png b/packages/SystemUI/res/drawable-xhdpi/remote_212.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_212.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_213.png b/packages/SystemUI/res/drawable-xhdpi/remote_213.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_213.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_214.png b/packages/SystemUI/res/drawable-xhdpi/remote_214.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_214.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_215.png b/packages/SystemUI/res/drawable-xhdpi/remote_215.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_215.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_216.png b/packages/SystemUI/res/drawable-xhdpi/remote_216.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_216.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_217.png b/packages/SystemUI/res/drawable-xhdpi/remote_217.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_217.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_218.png b/packages/SystemUI/res/drawable-xhdpi/remote_218.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_218.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_219.png b/packages/SystemUI/res/drawable-xhdpi/remote_219.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_219.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_22.png b/packages/SystemUI/res/drawable-xhdpi/remote_22.png
deleted file mode 100644
index 1974802..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_22.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_220.png b/packages/SystemUI/res/drawable-xhdpi/remote_220.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_220.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_221.png b/packages/SystemUI/res/drawable-xhdpi/remote_221.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_221.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_222.png b/packages/SystemUI/res/drawable-xhdpi/remote_222.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_222.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_223.png b/packages/SystemUI/res/drawable-xhdpi/remote_223.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_223.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_224.png b/packages/SystemUI/res/drawable-xhdpi/remote_224.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_224.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_225.png b/packages/SystemUI/res/drawable-xhdpi/remote_225.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_225.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_226.png b/packages/SystemUI/res/drawable-xhdpi/remote_226.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_226.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_227.png b/packages/SystemUI/res/drawable-xhdpi/remote_227.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_227.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_228.png b/packages/SystemUI/res/drawable-xhdpi/remote_228.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_228.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_229.png b/packages/SystemUI/res/drawable-xhdpi/remote_229.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_229.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_23.png b/packages/SystemUI/res/drawable-xhdpi/remote_23.png
deleted file mode 100644
index 96b7c35..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_23.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_230.png b/packages/SystemUI/res/drawable-xhdpi/remote_230.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_230.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_231.png b/packages/SystemUI/res/drawable-xhdpi/remote_231.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_231.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_232.png b/packages/SystemUI/res/drawable-xhdpi/remote_232.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_232.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_233.png b/packages/SystemUI/res/drawable-xhdpi/remote_233.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_233.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_234.png b/packages/SystemUI/res/drawable-xhdpi/remote_234.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_234.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_235.png b/packages/SystemUI/res/drawable-xhdpi/remote_235.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_235.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_236.png b/packages/SystemUI/res/drawable-xhdpi/remote_236.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_236.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_237.png b/packages/SystemUI/res/drawable-xhdpi/remote_237.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_237.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_238.png b/packages/SystemUI/res/drawable-xhdpi/remote_238.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_238.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_239.png b/packages/SystemUI/res/drawable-xhdpi/remote_239.png
deleted file mode 100644
index 5bda52e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_239.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_24.png b/packages/SystemUI/res/drawable-xhdpi/remote_24.png
deleted file mode 100644
index 0437200..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_24.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_25.png b/packages/SystemUI/res/drawable-xhdpi/remote_25.png
deleted file mode 100644
index 60b0f15..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_25.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_26.png b/packages/SystemUI/res/drawable-xhdpi/remote_26.png
deleted file mode 100644
index c34ed97..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_26.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_27.png b/packages/SystemUI/res/drawable-xhdpi/remote_27.png
deleted file mode 100644
index 1a83664..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_27.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_28.png b/packages/SystemUI/res/drawable-xhdpi/remote_28.png
deleted file mode 100644
index a3685ad..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_28.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_29.png b/packages/SystemUI/res/drawable-xhdpi/remote_29.png
deleted file mode 100644
index f7135eb..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_29.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_3.png b/packages/SystemUI/res/drawable-xhdpi/remote_3.png
deleted file mode 100644
index 937da65..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_30.png b/packages/SystemUI/res/drawable-xhdpi/remote_30.png
deleted file mode 100644
index 718cf52..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_30.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_31.png b/packages/SystemUI/res/drawable-xhdpi/remote_31.png
deleted file mode 100644
index c0b55df..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_31.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_32.png b/packages/SystemUI/res/drawable-xhdpi/remote_32.png
deleted file mode 100644
index 7a1ce9f..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_32.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_33.png b/packages/SystemUI/res/drawable-xhdpi/remote_33.png
deleted file mode 100644
index 5428bcf..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_33.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_34.png b/packages/SystemUI/res/drawable-xhdpi/remote_34.png
deleted file mode 100644
index 264efe8..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_34.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_35.png b/packages/SystemUI/res/drawable-xhdpi/remote_35.png
deleted file mode 100644
index a5c450f..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_35.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_36.png b/packages/SystemUI/res/drawable-xhdpi/remote_36.png
deleted file mode 100644
index 3e469e4..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_36.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_37.png b/packages/SystemUI/res/drawable-xhdpi/remote_37.png
deleted file mode 100644
index 124ebe4..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_37.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_38.png b/packages/SystemUI/res/drawable-xhdpi/remote_38.png
deleted file mode 100644
index b2b4844..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_38.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_39.png b/packages/SystemUI/res/drawable-xhdpi/remote_39.png
deleted file mode 100644
index a6d1733..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_39.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_4.png b/packages/SystemUI/res/drawable-xhdpi/remote_4.png
deleted file mode 100644
index c282f40..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_40.png b/packages/SystemUI/res/drawable-xhdpi/remote_40.png
deleted file mode 100644
index 4cd615c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_40.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_41.png b/packages/SystemUI/res/drawable-xhdpi/remote_41.png
deleted file mode 100644
index c746ae0..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_41.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_42.png b/packages/SystemUI/res/drawable-xhdpi/remote_42.png
deleted file mode 100644
index a93f198..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_42.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_43.png b/packages/SystemUI/res/drawable-xhdpi/remote_43.png
deleted file mode 100644
index 966e563..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_43.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_44.png b/packages/SystemUI/res/drawable-xhdpi/remote_44.png
deleted file mode 100644
index beb7031..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_44.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_45.png b/packages/SystemUI/res/drawable-xhdpi/remote_45.png
deleted file mode 100644
index 718e167..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_45.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_46.png b/packages/SystemUI/res/drawable-xhdpi/remote_46.png
deleted file mode 100644
index aa54ddb..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_46.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_47.png b/packages/SystemUI/res/drawable-xhdpi/remote_47.png
deleted file mode 100644
index 1d11270..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_47.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_48.png b/packages/SystemUI/res/drawable-xhdpi/remote_48.png
deleted file mode 100644
index ab31163..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_48.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_49.png b/packages/SystemUI/res/drawable-xhdpi/remote_49.png
deleted file mode 100644
index 219b7f6..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_49.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_5.png b/packages/SystemUI/res/drawable-xhdpi/remote_5.png
deleted file mode 100644
index 15f69e1..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_5.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_50.png b/packages/SystemUI/res/drawable-xhdpi/remote_50.png
deleted file mode 100644
index 8a9725f..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_50.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_51.png b/packages/SystemUI/res/drawable-xhdpi/remote_51.png
deleted file mode 100644
index bc839cf..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_51.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_52.png b/packages/SystemUI/res/drawable-xhdpi/remote_52.png
deleted file mode 100644
index 7bab6e5..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_52.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_53.png b/packages/SystemUI/res/drawable-xhdpi/remote_53.png
deleted file mode 100644
index 34ab855..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_53.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_54.png b/packages/SystemUI/res/drawable-xhdpi/remote_54.png
deleted file mode 100644
index 5bd9f59..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_54.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_55.png b/packages/SystemUI/res/drawable-xhdpi/remote_55.png
deleted file mode 100644
index 1ff17f4..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_55.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_56.png b/packages/SystemUI/res/drawable-xhdpi/remote_56.png
deleted file mode 100644
index d57e067..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_56.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_57.png b/packages/SystemUI/res/drawable-xhdpi/remote_57.png
deleted file mode 100644
index a1bdae1..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_57.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_58.png b/packages/SystemUI/res/drawable-xhdpi/remote_58.png
deleted file mode 100644
index c8bc6a4..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_58.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_59.png b/packages/SystemUI/res/drawable-xhdpi/remote_59.png
deleted file mode 100644
index 526a24e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_59.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_6.png b/packages/SystemUI/res/drawable-xhdpi/remote_6.png
deleted file mode 100644
index 2b6732f..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_6.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_60.png b/packages/SystemUI/res/drawable-xhdpi/remote_60.png
deleted file mode 100644
index 080619e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_60.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_61.png b/packages/SystemUI/res/drawable-xhdpi/remote_61.png
deleted file mode 100644
index 5932a8c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_61.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_62.png b/packages/SystemUI/res/drawable-xhdpi/remote_62.png
deleted file mode 100644
index d1233dd..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_62.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_63.png b/packages/SystemUI/res/drawable-xhdpi/remote_63.png
deleted file mode 100644
index 4f230c7..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_63.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_64.png b/packages/SystemUI/res/drawable-xhdpi/remote_64.png
deleted file mode 100644
index 6b89fcb..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_64.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_65.png b/packages/SystemUI/res/drawable-xhdpi/remote_65.png
deleted file mode 100644
index 87597b1..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_65.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_66.png b/packages/SystemUI/res/drawable-xhdpi/remote_66.png
deleted file mode 100644
index 0ee8c1e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_66.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_67.png b/packages/SystemUI/res/drawable-xhdpi/remote_67.png
deleted file mode 100644
index 9aca8fd..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_67.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_68.png b/packages/SystemUI/res/drawable-xhdpi/remote_68.png
deleted file mode 100644
index 5f263ae..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_68.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_69.png b/packages/SystemUI/res/drawable-xhdpi/remote_69.png
deleted file mode 100644
index 1a22b61..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_69.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_7.png b/packages/SystemUI/res/drawable-xhdpi/remote_7.png
deleted file mode 100644
index 9d9d699..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_7.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_70.png b/packages/SystemUI/res/drawable-xhdpi/remote_70.png
deleted file mode 100644
index 0372c50..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_70.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_71.png b/packages/SystemUI/res/drawable-xhdpi/remote_71.png
deleted file mode 100644
index 854e3e2..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_71.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_72.png b/packages/SystemUI/res/drawable-xhdpi/remote_72.png
deleted file mode 100644
index 6919624..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_72.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_73.png b/packages/SystemUI/res/drawable-xhdpi/remote_73.png
deleted file mode 100644
index d8e9ae1..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_73.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_74.png b/packages/SystemUI/res/drawable-xhdpi/remote_74.png
deleted file mode 100644
index 24e5b6a..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_74.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_75.png b/packages/SystemUI/res/drawable-xhdpi/remote_75.png
deleted file mode 100644
index 369a3a9..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_75.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_76.png b/packages/SystemUI/res/drawable-xhdpi/remote_76.png
deleted file mode 100644
index 96824c6..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_76.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_77.png b/packages/SystemUI/res/drawable-xhdpi/remote_77.png
deleted file mode 100644
index dd60cca..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_77.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_78.png b/packages/SystemUI/res/drawable-xhdpi/remote_78.png
deleted file mode 100644
index aa3460b..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_78.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_79.png b/packages/SystemUI/res/drawable-xhdpi/remote_79.png
deleted file mode 100644
index 9a60e3c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_79.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_8.png b/packages/SystemUI/res/drawable-xhdpi/remote_8.png
deleted file mode 100644
index b73c7ef..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_8.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_80.png b/packages/SystemUI/res/drawable-xhdpi/remote_80.png
deleted file mode 100644
index cbf883c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_80.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_81.png b/packages/SystemUI/res/drawable-xhdpi/remote_81.png
deleted file mode 100644
index 11a6add..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_81.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_82.png b/packages/SystemUI/res/drawable-xhdpi/remote_82.png
deleted file mode 100644
index e05105d..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_82.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_83.png b/packages/SystemUI/res/drawable-xhdpi/remote_83.png
deleted file mode 100644
index 57813aa..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_83.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_84.png b/packages/SystemUI/res/drawable-xhdpi/remote_84.png
deleted file mode 100644
index 0f6f0fe..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_84.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_85.png b/packages/SystemUI/res/drawable-xhdpi/remote_85.png
deleted file mode 100644
index ada83ec..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_85.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_86.png b/packages/SystemUI/res/drawable-xhdpi/remote_86.png
deleted file mode 100644
index 442dd51..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_86.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_87.png b/packages/SystemUI/res/drawable-xhdpi/remote_87.png
deleted file mode 100644
index bdb4962..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_87.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_88.png b/packages/SystemUI/res/drawable-xhdpi/remote_88.png
deleted file mode 100644
index b318002..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_88.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_89.png b/packages/SystemUI/res/drawable-xhdpi/remote_89.png
deleted file mode 100644
index c4ed874..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_89.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_9.png b/packages/SystemUI/res/drawable-xhdpi/remote_9.png
deleted file mode 100644
index ce5041f..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_90.png b/packages/SystemUI/res/drawable-xhdpi/remote_90.png
deleted file mode 100644
index 6a662f9..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_90.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_91.png b/packages/SystemUI/res/drawable-xhdpi/remote_91.png
deleted file mode 100644
index 21be887..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_91.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_92.png b/packages/SystemUI/res/drawable-xhdpi/remote_92.png
deleted file mode 100644
index 1bc5361..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_92.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_93.png b/packages/SystemUI/res/drawable-xhdpi/remote_93.png
deleted file mode 100644
index 76495ac..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_93.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_94.png b/packages/SystemUI/res/drawable-xhdpi/remote_94.png
deleted file mode 100644
index 081c84b..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_94.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_95.png b/packages/SystemUI/res/drawable-xhdpi/remote_95.png
deleted file mode 100644
index e9c27a8..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_95.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_96.png b/packages/SystemUI/res/drawable-xhdpi/remote_96.png
deleted file mode 100644
index 1369603..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_96.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_97.png b/packages/SystemUI/res/drawable-xhdpi/remote_97.png
deleted file mode 100644
index fbd1458..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_97.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_98.png b/packages/SystemUI/res/drawable-xhdpi/remote_98.png
deleted file mode 100644
index ccdd7a7..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_98.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/remote_99.png b/packages/SystemUI/res/drawable-xhdpi/remote_99.png
deleted file mode 100644
index f3cb4db..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/remote_99.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_dnd.xml b/packages/SystemUI/res/drawable/ic_dnd.xml
index 17ecf21..e658e68 100644
--- a/packages/SystemUI/res/drawable/ic_dnd.xml
+++ b/packages/SystemUI/res/drawable/ic_dnd.xml
@@ -17,7 +17,8 @@
     android:height="24dp"
     android:viewportHeight="48.0"
     android:viewportWidth="48.0"
-    android:width="24dp" >
+    android:width="24dp"
+    android:tint="?android:attr/colorControlNormal">
 
     <path
         android:fillColor="#FFFFFFFF"
diff --git a/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml b/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml
index 4875974..0515b35 100644
--- a/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml
+++ b/packages/SystemUI/res/drawable/ic_dnd_total_silence.xml
@@ -17,7 +17,8 @@
     android:height="24dp"
     android:viewportHeight="24.0"
     android:viewportWidth="24.0"
-    android:width="24dp" >
+    android:width="24dp"
+    android:tint="?android:attr/colorControlNormal">
 
     <path
         android:fillColor="#FFFFFFFF"
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml b/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml
index 5aeceba..169cc71 100644
--- a/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml
+++ b/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml
@@ -16,7 +16,6 @@
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:name="root"
-    android:alpha="0.3"
     android:height="48dp"
     android:width="48dp"
     android:viewportHeight="48"
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_in.xml b/packages/SystemUI/res/drawable/ic_qs_signal_in.xml
index 236fdac..5e7cd97 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_in.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_in.xml
@@ -17,7 +17,8 @@
         android:width="6.0dp"
         android:height="32dp"
         android:viewportWidth="6.0"
-        android:viewportHeight="24.0">
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/textColorSecondary">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M6.000000,15.700000l-3.000000,5.599999 -3.000000,-5.599999z"/>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_out.xml b/packages/SystemUI/res/drawable/ic_qs_signal_out.xml
index c510972..0dca1db 100644
--- a/packages/SystemUI/res/drawable/ic_qs_signal_out.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_signal_out.xml
@@ -17,7 +17,8 @@
         android:width="6.0dp"
         android:height="32dp"
         android:viewportWidth="6.0"
-        android:viewportHeight="24.0">
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/textColorSecondary">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M0.000000,13.700000l3.000000,-5.700000 3.000000,5.700000z"/>
diff --git a/packages/SystemUI/res/drawable/segmented_buttons_background.xml b/packages/SystemUI/res/drawable/segmented_buttons_background.xml
index b243dc7c..755c917 100644
--- a/packages/SystemUI/res/drawable/segmented_buttons_background.xml
+++ b/packages/SystemUI/res/drawable/segmented_buttons_background.xml
@@ -17,6 +17,6 @@
 
       <corners android:radius="@dimen/borderless_button_radius" />
 
-      <solid android:color="@color/segmented_buttons_background" />
+      <solid android:color="?android:attr/colorPrimaryDark" />
 
-</shape>
\ No newline at end of file
+</shape>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml
index d7463a4..be9a7e2 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_1x.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="8.5dp"
-        android:height="17dp"
-        android:viewportWidth="12.0"
-        android:viewportHeight="24.0">
+    android:width="17dp"
+    android:height="17dp"
+    android:viewportWidth="12.0"
+    android:viewportHeight="12.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M3.500000,11.000000L1.800000,11.000000L1.800000,4.400000L0.200000,5.100000L0.200000,3.700000l3.100000,-1.300000l0.200000,0.000000L3.500000,11.000000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml
index 6309b6d..fd7a658 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_3g.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="9.208dp"
+        android:width="17dp"
         android:height="17dp"
         android:viewportWidth="13.0"
-        android:viewportHeight="24.0">
+        android:viewportHeight="13.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M2.000000,6.000000l0.800000,0.000000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000s0.200000,-0.500000 0.200000,-0.900000c0.000000,-0.300000 -0.100000,-0.600000 -0.200000,-0.800000S3.200000,3.700000 2.900000,3.700000C2.700000,3.700000 2.500000,3.800000 2.300000,4.000000S2.100000,4.400000 2.100000,4.700000L0.500000,4.700000C0.500000,4.000000 0.700000,3.400000 1.100000,3.000000s1.000000,-0.600000 1.700000,-0.600000c0.800000,0.000000 1.400000,0.200000 1.900000,0.600000s0.700000,1.000000 0.700000,1.800000c0.000000,0.400000 -0.100000,0.700000 -0.300000,1.100000S4.600000,6.500000 4.300000,6.600000C4.700000,6.800000 5.000000,7.100000 5.200000,7.400000s0.300000,0.700000 0.300000,1.200000c0.000000,0.800000 -0.200000,1.400000 -0.700000,1.800000s-1.100000,0.700000 -1.900000,0.700000c-0.700000,0.000000 -1.300000,-0.200000 -1.800000,-0.600000s-0.700000,-1.000000 -0.700000,-1.800000L2.000000,8.700000C2.000000,9.000000 2.100000,9.300000 2.300000,9.500000s0.400000,0.300000 0.600000,0.300000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000S3.900000,9.000000 3.900000,8.600000c0.000000,-0.500000 -0.100000,-0.800000 -0.300000,-1.000000S3.200000,7.300000 2.800000,7.300000L2.000000,7.300000L2.000000,6.000000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml
index 4067ae5..02c4ab6 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="8.5dp"
+        android:width="17dp"
         android:height="17dp"
         android:viewportWidth="12.0"
-        android:viewportHeight="24.0">
+        android:viewportHeight="12.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M4.600000,7.800000l0.700000,0.000000l0.000000,1.300000L4.600000,9.100000L4.600000,11.000000L3.000000,11.000000L3.000000,9.200000L0.100000,9.200000L0.000000,8.100000L3.000000,2.500000l1.700000,0.000000L4.700000,7.800000zM1.600000,7.800000L3.000000,7.800000l0.000000,-3.000000L2.900000,5.000000L1.600000,7.800000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
index 3cdd3e1..daf4061 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_4g_plus.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17.0dp"
+        android:width="25.5dp"
         android:height="17.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
+        android:viewportWidth="18.0"
+        android:viewportHeight="12.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M4.6,7.8l0.7,0.0l0.0,1.3L4.6,9.1L4.6,11.0L3.0,11.0L3.0,9.2L0.1,9.2L0.0,8.2l3.0,-5.7l1.7,0.0L4.6,7.8L4.6,7.8zM1.7,7.8L3.0,7.8l0.0,-3.0L2.9,5.0L1.7,7.8z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml
index acaa9b1..cd0cc65 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_e.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="3.541dp"
+        android:width="7.083dp"
         android:height="17dp"
         android:viewportWidth="5.0"
-        android:viewportHeight="24.0">
+        android:viewportHeight="12.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M4.400000,7.300000L1.700000,7.300000l0.000000,2.400000l3.300000,0.000000L5.000000,11.000000L0.000000,11.000000L0.000000,2.500000l4.900000,0.000000l0.000000,1.300000L1.700000,3.800000l0.000000,2.100000l2.800000,0.000000L4.500000,7.300000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml
index 7985237..92ed49c 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_g.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="4.958dp"
+        android:width="9.154dp"
         android:height="17dp"
         android:viewportWidth="7.0"
-        android:viewportHeight="24.0">
+        android:viewportHeight="13">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M6.500000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S0.700000,9.000000 0.700000,7.900000L0.700000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000L4.700000,5.200000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000S4.000000,3.700000 3.600000,3.700000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S2.300000,5.000000 2.300000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L4.700000,7.800000L3.500000,7.800000L3.500000,6.600000l2.900000,0.000000L6.400000,9.900000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml
index fda8761..ca61b6f 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_h.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="4.25dp"
+        android:width="9.5dp"
         android:height="17dp"
         android:viewportWidth="6.0"
-        android:viewportHeight="24.0">
+        android:viewportHeight="12.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M6.000000,11.000000L4.400000,11.000000L4.400000,7.500000L1.700000,7.500000L1.700000,11.000000L0.000000,11.000000L0.000000,2.500000l1.700000,0.000000l0.000000,3.700000l2.700000,0.000000L4.400000,2.500000L6.000000,2.500000L6.000000,11.000000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml
index c08ff20..add96b4 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="9.208dp"
+        android:width="18.417dp"
         android:height="17dp"
-        android:viewportWidth="13.0"
-        android:viewportHeight="24.0">
+        android:viewportWidth="13"
+        android:viewportHeight="12.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M2.000000,9.700000l2.000000,0.000000L4.000000,11.000000L0.300000,11.000000L0.300000,2.500000L2.000000,2.500000L2.000000,9.700000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml
index db18fad..8811d2f 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_fully_connected_lte_plus.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17.0dp"
+        android:width="25.0dp"
         android:height="17.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
+        android:viewportWidth="18.0"
+        android:viewportHeight="12.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M2.0,9.7l2.0,0.0L4.0,11.0L0.4,11.0L0.4,2.5L2.0,2.5L2.0,9.7z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_roaming.xml b/packages/SystemUI/res/drawable/stat_sys_roaming.xml
index 4baa472..363e231 100644
--- a/packages/SystemUI/res/drawable/stat_sys_roaming.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_roaming.xml
@@ -14,10 +14,10 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="8.5dp"
+        android:width="4.25dp"
         android:height="17dp"
         android:viewportWidth="6.0"
-        android:viewportHeight="12.0">
+        android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
         android:pathData="M2.800000,7.900000l-1.000000,0.000000L1.800000,11.000000L0.200000,11.000000L0.200000,2.500000l2.700000,0.000000c0.900000,0.000000 1.500000,0.200000 2.000000,0.700000s0.700000,1.100000 0.700000,1.900000c0.000000,0.600000 -0.100000,1.100000 -0.300000,1.500000S4.800000,7.200000 4.400000,7.400000l1.500000,3.500000L5.900000,11.000000L4.100000,11.000000L2.800000,7.900000zM1.800000,6.500000l1.100000,0.000000c0.400000,0.000000 0.600000,-0.100000 0.800000,-0.400000S4.000000,5.600000 4.000000,5.200000c0.000000,-0.400000 -0.100000,-0.800000 -0.300000,-1.000000S3.300000,3.800000 2.900000,3.800000L1.800000,3.800000L1.800000,6.500000z"/>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_disconnected.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_disconnected.xml
new file mode 100644
index 0000000..f4e8af4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_disconnected.xml
@@ -0,0 +1,42 @@
+<!--
+    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="18.41dp"
+        android:height="17dp"
+        android:viewportWidth="26.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="?attr/backgroundColor"
+        android:pathData="M21.0,8.5
+        c0.85,0.0 1.6,0.23 2.3,0.62l2.24,-2.79
+        C25.1,5.96 20.26,2.0 13.0,2.0
+        S0.9,5.9 0.42,6.32
+        l12.57,15.6 4.21,-5.17
+        c-0.76,-0.87 -1.22,-2.0 -1.22,-3.25
+        c0.0,-2.76 2.24,-5.0 5.0,-5.0z"
+        android:fillAlpha=".3"/>
+    <path
+        android:fillColor="?attr/backgroundColor"
+        android:pathData="M21.0,10.0
+        c-1.93,0.0 -3.5,1.57 -3.5,3.5l1.75,0.0
+        c0.0,-0.9 0.78,-1.75 1.75,-1.75s1.7,0.78 1.75,1.75
+        c0.0,0.48 -0.2,0.92 -0.51,1.24l-1.09,1.1
+        c-0.6,0.63 -1.02,1.51 -1.02,2.47l0.0,0.44l1.75,0.0
+        c0.0,-1.3 0.39,-1.84 1.03,-2.47l0.78,-0.8
+        c0.5,-0.5 0.82,-1.2 0.82,-1.97
+        C24.5,11.57 22.93,10.0 21.0,10.0z
+        m-0.95,11.95l1.9,0.0l0.0,-1.9l-1.9,0.0l0.0,1.9z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_null.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_null.xml
index 5169de4..c1856fa 100644
--- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_null.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_null.xml
@@ -20,5 +20,8 @@
         android:viewportHeight="24.0">
     <path
         android:fillColor="?attr/backgroundColor"
-        android:pathData="M13.000000,2.000000C7.700000,2.000000 3.700000,3.900000 0.400000,6.400000L13.000000,22.000000L25.600000,6.500000C22.299999,4.000000 18.299999,2.000000 13.000000,2.000000zM13.000000,18.600000L3.300000,7.000000l0.000000,0.000000l0.000000,0.000000C6.000000,5.300000 8.700000,4.000000 13.000000,4.000000s7.000000,1.400000 9.700000,3.000000l0.000000,0.000000l0.000000,0.000000L13.000000,18.600000z"/>
+        android:pathData="M17.500000,16.500000L5.800000,3.400000c0.000000,0.000000 0.000000,0.000000 0.000000,0.000000l-2.700000,-3.000000L1.600000,1.800000l2.200000,2.500000c-2.000000,1.000000 -3.200000,2.000000 -3.400000,2.200000L13.000000,22.000000l0.000000,0.000000l0.000000,0.000000l0.000000,0.000000l0.000000,0.000000l3.200000,-3.900000l2.400000,2.700000l1.500000,-1.400000L17.500000,16.500000L17.500000,16.500000z"/>
+    <path
+        android:fillColor="?attr/backgroundColor"
+        android:pathData="M25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000c-1.900000,0.000000 -3.600000,0.300000 -5.200000,0.700000L18.700001,15.000000L25.600000,6.500000z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/tv_pip_onboarding_remote.xml b/packages/SystemUI/res/drawable/tv_pip_onboarding_remote.xml
deleted file mode 100644
index d46108a..0000000
--- a/packages/SystemUI/res/drawable/tv_pip_onboarding_remote.xml
+++ /dev/null
@@ -1,259 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
-    android:oneshot="false">
-
-    <item android:drawable="@drawable/remote_0" android:duration="13" />
-    <item android:drawable="@drawable/remote_1" android:duration="13" />
-    <item android:drawable="@drawable/remote_2" android:duration="13" />
-    <item android:drawable="@drawable/remote_3" android:duration="13" />
-    <item android:drawable="@drawable/remote_4" android:duration="13" />
-    <item android:drawable="@drawable/remote_5" android:duration="13" />
-    <item android:drawable="@drawable/remote_6" android:duration="13" />
-    <item android:drawable="@drawable/remote_7" android:duration="13" />
-    <item android:drawable="@drawable/remote_8" android:duration="13" />
-    <item android:drawable="@drawable/remote_9" android:duration="13" />
-    <item android:drawable="@drawable/remote_10" android:duration="13" />
-    <item android:drawable="@drawable/remote_11" android:duration="13" />
-    <item android:drawable="@drawable/remote_12" android:duration="13" />
-    <item android:drawable="@drawable/remote_13" android:duration="13" />
-    <item android:drawable="@drawable/remote_14" android:duration="13" />
-    <item android:drawable="@drawable/remote_15" android:duration="13" />
-    <item android:drawable="@drawable/remote_16" android:duration="13" />
-    <item android:drawable="@drawable/remote_17" android:duration="13" />
-    <item android:drawable="@drawable/remote_18" android:duration="13" />
-    <item android:drawable="@drawable/remote_19" android:duration="13" />
-    <item android:drawable="@drawable/remote_20" android:duration="13" />
-    <item android:drawable="@drawable/remote_21" android:duration="13" />
-    <item android:drawable="@drawable/remote_22" android:duration="13" />
-    <item android:drawable="@drawable/remote_23" android:duration="13" />
-    <item android:drawable="@drawable/remote_24" android:duration="13" />
-    <item android:drawable="@drawable/remote_25" android:duration="13" />
-    <item android:drawable="@drawable/remote_26" android:duration="13" />
-    <item android:drawable="@drawable/remote_27" android:duration="13" />
-    <item android:drawable="@drawable/remote_28" android:duration="13" />
-    <item android:drawable="@drawable/remote_29" android:duration="13" />
-    <item android:drawable="@drawable/remote_30" android:duration="13" />
-    <item android:drawable="@drawable/remote_31" android:duration="13" />
-    <item android:drawable="@drawable/remote_32" android:duration="13" />
-    <item android:drawable="@drawable/remote_33" android:duration="13" />
-    <item android:drawable="@drawable/remote_34" android:duration="13" />
-    <item android:drawable="@drawable/remote_35" android:duration="13" />
-    <item android:drawable="@drawable/remote_36" android:duration="13" />
-    <item android:drawable="@drawable/remote_37" android:duration="13" />
-    <item android:drawable="@drawable/remote_38" android:duration="13" />
-    <item android:drawable="@drawable/remote_39" android:duration="13" />
-    <item android:drawable="@drawable/remote_40" android:duration="13" />
-    <item android:drawable="@drawable/remote_41" android:duration="13" />
-    <item android:drawable="@drawable/remote_42" android:duration="13" />
-    <item android:drawable="@drawable/remote_43" android:duration="13" />
-    <item android:drawable="@drawable/remote_44" android:duration="13" />
-    <item android:drawable="@drawable/remote_45" android:duration="13" />
-    <item android:drawable="@drawable/remote_46" android:duration="13" />
-    <item android:drawable="@drawable/remote_47" android:duration="13" />
-    <item android:drawable="@drawable/remote_48" android:duration="13" />
-    <item android:drawable="@drawable/remote_49" android:duration="13" />
-    <item android:drawable="@drawable/remote_50" android:duration="13" />
-    <item android:drawable="@drawable/remote_51" android:duration="13" />
-    <item android:drawable="@drawable/remote_52" android:duration="13" />
-    <item android:drawable="@drawable/remote_53" android:duration="13" />
-    <item android:drawable="@drawable/remote_54" android:duration="13" />
-    <item android:drawable="@drawable/remote_55" android:duration="13" />
-    <item android:drawable="@drawable/remote_56" android:duration="13" />
-    <item android:drawable="@drawable/remote_57" android:duration="13" />
-    <item android:drawable="@drawable/remote_58" android:duration="13" />
-    <item android:drawable="@drawable/remote_59" android:duration="13" />
-    <item android:drawable="@drawable/remote_60" android:duration="13" />
-    <item android:drawable="@drawable/remote_61" android:duration="13" />
-    <item android:drawable="@drawable/remote_62" android:duration="13" />
-    <item android:drawable="@drawable/remote_63" android:duration="13" />
-    <item android:drawable="@drawable/remote_64" android:duration="13" />
-    <item android:drawable="@drawable/remote_65" android:duration="13" />
-    <item android:drawable="@drawable/remote_66" android:duration="13" />
-    <item android:drawable="@drawable/remote_67" android:duration="13" />
-    <item android:drawable="@drawable/remote_68" android:duration="13" />
-    <item android:drawable="@drawable/remote_69" android:duration="13" />
-    <item android:drawable="@drawable/remote_70" android:duration="13" />
-    <item android:drawable="@drawable/remote_71" android:duration="13" />
-    <item android:drawable="@drawable/remote_72" android:duration="13" />
-    <item android:drawable="@drawable/remote_73" android:duration="13" />
-    <item android:drawable="@drawable/remote_74" android:duration="13" />
-    <item android:drawable="@drawable/remote_75" android:duration="13" />
-    <item android:drawable="@drawable/remote_76" android:duration="13" />
-    <item android:drawable="@drawable/remote_77" android:duration="13" />
-    <item android:drawable="@drawable/remote_78" android:duration="13" />
-    <item android:drawable="@drawable/remote_79" android:duration="13" />
-    <item android:drawable="@drawable/remote_80" android:duration="13" />
-    <item android:drawable="@drawable/remote_81" android:duration="13" />
-    <item android:drawable="@drawable/remote_82" android:duration="13" />
-    <item android:drawable="@drawable/remote_83" android:duration="13" />
-    <item android:drawable="@drawable/remote_84" android:duration="13" />
-    <item android:drawable="@drawable/remote_85" android:duration="13" />
-    <item android:drawable="@drawable/remote_86" android:duration="13" />
-    <item android:drawable="@drawable/remote_87" android:duration="13" />
-    <item android:drawable="@drawable/remote_88" android:duration="13" />
-    <item android:drawable="@drawable/remote_89" android:duration="13" />
-    <item android:drawable="@drawable/remote_90" android:duration="13" />
-    <item android:drawable="@drawable/remote_91" android:duration="13" />
-    <item android:drawable="@drawable/remote_92" android:duration="13" />
-    <item android:drawable="@drawable/remote_93" android:duration="13" />
-    <item android:drawable="@drawable/remote_94" android:duration="13" />
-    <item android:drawable="@drawable/remote_95" android:duration="13" />
-    <item android:drawable="@drawable/remote_96" android:duration="13" />
-    <item android:drawable="@drawable/remote_97" android:duration="13" />
-    <item android:drawable="@drawable/remote_98" android:duration="13" />
-    <item android:drawable="@drawable/remote_99" android:duration="13" />
-    <item android:drawable="@drawable/remote_100" android:duration="13" />
-    <item android:drawable="@drawable/remote_101" android:duration="13" />
-    <item android:drawable="@drawable/remote_102" android:duration="13" />
-    <item android:drawable="@drawable/remote_103" android:duration="13" />
-    <item android:drawable="@drawable/remote_104" android:duration="13" />
-    <item android:drawable="@drawable/remote_105" android:duration="13" />
-    <item android:drawable="@drawable/remote_106" android:duration="13" />
-    <item android:drawable="@drawable/remote_107" android:duration="13" />
-    <item android:drawable="@drawable/remote_108" android:duration="13" />
-    <item android:drawable="@drawable/remote_109" android:duration="13" />
-    <item android:drawable="@drawable/remote_110" android:duration="13" />
-    <item android:drawable="@drawable/remote_111" android:duration="13" />
-    <item android:drawable="@drawable/remote_112" android:duration="13" />
-    <item android:drawable="@drawable/remote_113" android:duration="13" />
-    <item android:drawable="@drawable/remote_114" android:duration="13" />
-    <item android:drawable="@drawable/remote_115" android:duration="13" />
-    <item android:drawable="@drawable/remote_116" android:duration="13" />
-    <item android:drawable="@drawable/remote_117" android:duration="13" />
-    <item android:drawable="@drawable/remote_118" android:duration="13" />
-    <item android:drawable="@drawable/remote_119" android:duration="13" />
-    <item android:drawable="@drawable/remote_120" android:duration="13" />
-    <item android:drawable="@drawable/remote_121" android:duration="13" />
-    <item android:drawable="@drawable/remote_122" android:duration="13" />
-    <item android:drawable="@drawable/remote_123" android:duration="13" />
-    <item android:drawable="@drawable/remote_124" android:duration="13" />
-    <item android:drawable="@drawable/remote_125" android:duration="13" />
-    <item android:drawable="@drawable/remote_126" android:duration="13" />
-    <item android:drawable="@drawable/remote_127" android:duration="13" />
-    <item android:drawable="@drawable/remote_128" android:duration="13" />
-    <item android:drawable="@drawable/remote_129" android:duration="13" />
-    <item android:drawable="@drawable/remote_130" android:duration="13" />
-    <item android:drawable="@drawable/remote_131" android:duration="13" />
-    <item android:drawable="@drawable/remote_132" android:duration="13" />
-    <item android:drawable="@drawable/remote_133" android:duration="13" />
-    <item android:drawable="@drawable/remote_134" android:duration="13" />
-    <item android:drawable="@drawable/remote_135" android:duration="13" />
-    <item android:drawable="@drawable/remote_136" android:duration="13" />
-    <item android:drawable="@drawable/remote_137" android:duration="13" />
-    <item android:drawable="@drawable/remote_138" android:duration="13" />
-    <item android:drawable="@drawable/remote_139" android:duration="13" />
-    <item android:drawable="@drawable/remote_140" android:duration="13" />
-    <item android:drawable="@drawable/remote_141" android:duration="13" />
-    <item android:drawable="@drawable/remote_142" android:duration="13" />
-    <item android:drawable="@drawable/remote_143" android:duration="13" />
-    <item android:drawable="@drawable/remote_144" android:duration="13" />
-    <item android:drawable="@drawable/remote_145" android:duration="13" />
-    <item android:drawable="@drawable/remote_146" android:duration="13" />
-    <item android:drawable="@drawable/remote_147" android:duration="13" />
-    <item android:drawable="@drawable/remote_148" android:duration="13" />
-    <item android:drawable="@drawable/remote_149" android:duration="13" />
-    <item android:drawable="@drawable/remote_150" android:duration="13" />
-    <item android:drawable="@drawable/remote_151" android:duration="13" />
-    <item android:drawable="@drawable/remote_152" android:duration="13" />
-    <item android:drawable="@drawable/remote_153" android:duration="13" />
-    <item android:drawable="@drawable/remote_154" android:duration="13" />
-    <item android:drawable="@drawable/remote_155" android:duration="13" />
-    <item android:drawable="@drawable/remote_156" android:duration="13" />
-    <item android:drawable="@drawable/remote_157" android:duration="13" />
-    <item android:drawable="@drawable/remote_158" android:duration="13" />
-    <item android:drawable="@drawable/remote_159" android:duration="13" />
-    <item android:drawable="@drawable/remote_160" android:duration="13" />
-    <item android:drawable="@drawable/remote_161" android:duration="13" />
-    <item android:drawable="@drawable/remote_162" android:duration="13" />
-    <item android:drawable="@drawable/remote_163" android:duration="13" />
-    <item android:drawable="@drawable/remote_164" android:duration="13" />
-    <item android:drawable="@drawable/remote_165" android:duration="13" />
-    <item android:drawable="@drawable/remote_166" android:duration="13" />
-    <item android:drawable="@drawable/remote_167" android:duration="13" />
-    <item android:drawable="@drawable/remote_168" android:duration="13" />
-    <item android:drawable="@drawable/remote_169" android:duration="13" />
-    <item android:drawable="@drawable/remote_170" android:duration="13" />
-    <item android:drawable="@drawable/remote_171" android:duration="13" />
-    <item android:drawable="@drawable/remote_172" android:duration="13" />
-    <item android:drawable="@drawable/remote_173" android:duration="13" />
-    <item android:drawable="@drawable/remote_174" android:duration="13" />
-    <item android:drawable="@drawable/remote_175" android:duration="13" />
-    <item android:drawable="@drawable/remote_176" android:duration="13" />
-    <item android:drawable="@drawable/remote_177" android:duration="13" />
-    <item android:drawable="@drawable/remote_178" android:duration="13" />
-    <item android:drawable="@drawable/remote_179" android:duration="13" />
-    <item android:drawable="@drawable/remote_180" android:duration="13" />
-    <item android:drawable="@drawable/remote_181" android:duration="13" />
-    <item android:drawable="@drawable/remote_182" android:duration="13" />
-    <item android:drawable="@drawable/remote_183" android:duration="13" />
-    <item android:drawable="@drawable/remote_184" android:duration="13" />
-    <item android:drawable="@drawable/remote_185" android:duration="13" />
-    <item android:drawable="@drawable/remote_186" android:duration="13" />
-    <item android:drawable="@drawable/remote_187" android:duration="13" />
-    <item android:drawable="@drawable/remote_188" android:duration="13" />
-    <item android:drawable="@drawable/remote_189" android:duration="13" />
-    <item android:drawable="@drawable/remote_190" android:duration="13" />
-    <item android:drawable="@drawable/remote_191" android:duration="13" />
-    <item android:drawable="@drawable/remote_192" android:duration="13" />
-    <item android:drawable="@drawable/remote_193" android:duration="13" />
-    <item android:drawable="@drawable/remote_194" android:duration="13" />
-    <item android:drawable="@drawable/remote_195" android:duration="13" />
-    <item android:drawable="@drawable/remote_196" android:duration="13" />
-    <item android:drawable="@drawable/remote_197" android:duration="13" />
-    <item android:drawable="@drawable/remote_198" android:duration="13" />
-    <item android:drawable="@drawable/remote_199" android:duration="13" />
-    <item android:drawable="@drawable/remote_200" android:duration="13" />
-    <item android:drawable="@drawable/remote_201" android:duration="13" />
-    <item android:drawable="@drawable/remote_202" android:duration="13" />
-    <item android:drawable="@drawable/remote_203" android:duration="13" />
-    <item android:drawable="@drawable/remote_204" android:duration="13" />
-    <item android:drawable="@drawable/remote_205" android:duration="13" />
-    <item android:drawable="@drawable/remote_206" android:duration="13" />
-    <item android:drawable="@drawable/remote_207" android:duration="13" />
-    <item android:drawable="@drawable/remote_208" android:duration="13" />
-    <item android:drawable="@drawable/remote_209" android:duration="13" />
-    <item android:drawable="@drawable/remote_210" android:duration="13" />
-    <item android:drawable="@drawable/remote_211" android:duration="13" />
-    <item android:drawable="@drawable/remote_212" android:duration="13" />
-    <item android:drawable="@drawable/remote_213" android:duration="13" />
-    <item android:drawable="@drawable/remote_214" android:duration="13" />
-    <item android:drawable="@drawable/remote_215" android:duration="13" />
-    <item android:drawable="@drawable/remote_216" android:duration="13" />
-    <item android:drawable="@drawable/remote_217" android:duration="13" />
-    <item android:drawable="@drawable/remote_218" android:duration="13" />
-    <item android:drawable="@drawable/remote_219" android:duration="13" />
-    <item android:drawable="@drawable/remote_220" android:duration="13" />
-    <item android:drawable="@drawable/remote_221" android:duration="13" />
-    <item android:drawable="@drawable/remote_222" android:duration="13" />
-    <item android:drawable="@drawable/remote_223" android:duration="13" />
-    <item android:drawable="@drawable/remote_224" android:duration="13" />
-    <item android:drawable="@drawable/remote_225" android:duration="13" />
-    <item android:drawable="@drawable/remote_226" android:duration="13" />
-    <item android:drawable="@drawable/remote_227" android:duration="13" />
-    <item android:drawable="@drawable/remote_228" android:duration="13" />
-    <item android:drawable="@drawable/remote_229" android:duration="13" />
-    <item android:drawable="@drawable/remote_230" android:duration="13" />
-    <item android:drawable="@drawable/remote_231" android:duration="13" />
-    <item android:drawable="@drawable/remote_232" android:duration="13" />
-    <item android:drawable="@drawable/remote_233" android:duration="13" />
-    <item android:drawable="@drawable/remote_234" android:duration="13" />
-    <item android:drawable="@drawable/remote_235" android:duration="13" />
-    <item android:drawable="@drawable/remote_236" android:duration="13" />
-    <item android:drawable="@drawable/remote_237" android:duration="13" />
-    <item android:drawable="@drawable/remote_238" android:duration="13" />
-    <item android:drawable="@drawable/remote_239" android:duration="13" />
-</animation-list>
diff --git a/packages/SystemUI/res/drawable/tv_pip_overlay_background.xml b/packages/SystemUI/res/drawable/tv_pip_overlay_background.xml
deleted file mode 100644
index 2b58fc5..0000000
--- a/packages/SystemUI/res/drawable/tv_pip_overlay_background.xml
+++ /dev/null
@@ -1,20 +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.
--->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-
-    <stroke android:width="1dp" android:color="#33FFFFFF" />
-</shape>
diff --git a/packages/SystemUI/res/drawable/tv_pip_overlay_text_background.xml b/packages/SystemUI/res/drawable/tv_pip_overlay_text_background.xml
deleted file mode 100644
index e247dec..0000000
--- a/packages/SystemUI/res/drawable/tv_pip_overlay_text_background.xml
+++ /dev/null
@@ -1,23 +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.
--->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-
-    <gradient
-        android:startColor="#B2000000"
-        android:endColor="#00000000"
-        android:angle="90"/>
-</shape>
diff --git a/packages/SystemUI/res/drawable/tv_pip_recents_overlay_scrim.xml b/packages/SystemUI/res/drawable/tv_pip_recents_overlay_scrim.xml
deleted file mode 100644
index 57bee75..0000000
--- a/packages/SystemUI/res/drawable/tv_pip_recents_overlay_scrim.xml
+++ /dev/null
@@ -1,23 +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.
--->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-
-    <gradient
-        android:startColor="#80000000"
-        android:endColor="#00000000"
-        android:angle="90"/>
-</shape>
diff --git a/packages/SystemUI/res/layout/mobile_signal_group.xml b/packages/SystemUI/res/layout/mobile_signal_group.xml
index 33effba..6d4365c 100644
--- a/packages/SystemUI/res/layout/mobile_signal_group.xml
+++ b/packages/SystemUI/res/layout/mobile_signal_group.xml
@@ -63,20 +63,21 @@
             systemui:hasOverlappingRendering="false"
             />
         <ImageView
-            android:id="@+id/mobile_type"
+            android:id="@+id/mobile_roaming"
             android:layout_height="wrap_content"
             android:layout_width="wrap_content"
+            android:src="@drawable/stat_sys_roaming"
+            android:contentDescription="@string/accessibility_data_connection_roaming"
+            android:visibility="gone"
             />
         <ImageView
-            android:id="@+id/mobile_roaming"
+            android:id="@+id/mobile_type"
             android:layout_width="wrap_content"
             android:layout_height="17dp"
-            android:paddingStart="22dp"
+            android:paddingStart="19dp"
             android:paddingTop="1.5dp"
             android:paddingBottom="3dp"
             android:scaleType="fitCenter"
-            android:src="@drawable/stat_sys_roaming"
-            android:contentDescription="@string/accessibility_data_connection_roaming"
             android:visibility="gone" />
     </FrameLayout>
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index ff22ffb..0c9858d 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -114,6 +114,7 @@
             android:layout_height="wrap_content"
             android:layout_gravity="end|center_vertical"
             android:layout_weight="1"
+            android:contentDescription="@string/notification_channel_switch_accessibility"
             android:background="@null" />
     </LinearLayout>
 
diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml
index da7e4d7..5766dc1 100644
--- a/packages/SystemUI/res/layout/signal_cluster_view.xml
+++ b/packages/SystemUI/res/layout/signal_cluster_view.xml
@@ -52,9 +52,54 @@
             android:alpha="0.0"
             />
     </FrameLayout>
+    <ViewStub
+        android:id="@+id/connected_device_signals_stub"
+        android:layout="@layout/connected_device_signal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+    <LinearLayout
+        android:id="@+id/mobile_signal_group"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        >
+    </LinearLayout>
+    <View
+        android:id="@+id/wifi_signal_spacer"
+        android:layout_width="@dimen/status_bar_wifi_signal_spacer_width"
+        android:layout_height="4dp"
+        android:visibility="gone"
+        />
+    <FrameLayout
+        android:id="@+id/no_sims_combo"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:contentDescription="@string/accessibility_no_sims">
+        <com.android.systemui.statusbar.AlphaOptimizedImageView
+            android:theme="@style/DualToneLightTheme"
+            android:id="@+id/no_sims"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:src="@drawable/stat_sys_no_sims"
+            />
+        <com.android.systemui.statusbar.AlphaOptimizedImageView
+            android:theme="@style/DualToneDarkTheme"
+            android:id="@+id/no_sims_dark"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:src="@drawable/stat_sys_no_sims"
+            android:alpha="0.0"
+            />
+    </FrameLayout>
+    <View
+        android:id="@+id/wifi_airplane_spacer"
+        android:layout_width="@dimen/status_bar_airplane_spacer_width"
+        android:layout_height="4dp"
+        android:visibility="gone"
+        />
     <FrameLayout
         android:layout_height="17dp"
-        android:layout_width="wrap_content">
+        android:layout_width="wrap_content"
+        android:paddingStart="2dp">
         <ImageView
             android:id="@+id/wifi_in"
             android:layout_height="wrap_content"
@@ -96,50 +141,6 @@
             android:layout_width="wrap_content"
             />
     </FrameLayout>
-    <View
-        android:id="@+id/wifi_signal_spacer"
-        android:layout_width="@dimen/status_bar_wifi_signal_spacer_width"
-        android:layout_height="4dp"
-        android:visibility="gone"
-        />
-    <ViewStub
-        android:id="@+id/connected_device_signals_stub"
-        android:layout="@layout/connected_device_signal"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content" />
-    <LinearLayout
-        android:id="@+id/mobile_signal_group"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        >
-    </LinearLayout>
-    <FrameLayout
-        android:id="@+id/no_sims_combo"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:contentDescription="@string/accessibility_no_sims">
-        <com.android.systemui.statusbar.AlphaOptimizedImageView
-            android:theme="@style/DualToneLightTheme"
-            android:id="@+id/no_sims"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:src="@drawable/stat_sys_no_sims"
-            />
-        <com.android.systemui.statusbar.AlphaOptimizedImageView
-            android:theme="@style/DualToneDarkTheme"
-            android:id="@+id/no_sims_dark"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:src="@drawable/stat_sys_no_sims"
-            android:alpha="0.0"
-            />
-    </FrameLayout>
-    <View
-        android:id="@+id/wifi_airplane_spacer"
-        android:layout_width="@dimen/status_bar_airplane_spacer_width"
-        android:layout_height="4dp"
-        android:visibility="gone"
-        />
     <ImageView
         android:id="@+id/airplane"
         android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/layout/tv_pip_onboarding.xml b/packages/SystemUI/res/layout/tv_pip_onboarding.xml
deleted file mode 100644
index fe80b94..0000000
--- a/packages/SystemUI/res/layout/tv_pip_onboarding.xml
+++ /dev/null
@@ -1,102 +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.
-*/
--->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/pip_onboarding"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-    <View
-        android:id="@+id/background"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:background="#000000"
-        android:alpha="0" />
-
-    <ImageView
-        android:id="@+id/remote"
-        android:layout_width="72dp"
-        android:layout_height="273dp"
-        android:layout_marginTop="136dp"
-        android:layout_marginStart="304dp"
-        android:layout_alignParentTop="true"
-        android:layout_alignParentStart="true"
-        android:adjustViewBounds="true"
-        android:src="@drawable/remote"
-        android:alpha="0" />
-    <ImageView
-        android:id="@+id/remote_button"
-        android:layout_width="50dp"
-        android:layout_height="50dp"
-        android:layout_marginTop="256dp"
-        android:layout_marginStart="315dp"
-        android:layout_alignParentTop="true"
-        android:layout_alignParentStart="true"
-        android:scaleType="fitXY"
-        android:src="@drawable/tv_pip_onboarding_remote"
-        android:alpha="0" />
-    <TextView
-        android:id="@+id/title"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="188dp"
-        android:layout_marginStart="406dp"
-        android:layout_alignParentTop="true"
-        android:layout_alignParentStart="true"
-        android:fontFamily="sans-serif"
-        android:textSize="24sp"
-        android:textColor="#EEEEEE"
-        android:text="@string/pip_onboarding_title"
-        android:alpha="0" />
-    <TextView
-        android:id="@+id/description"
-        android:layout_width="200dp"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="4dp"
-        android:layout_marginStart="408dp"
-        android:layout_below="@id/title"
-        android:layout_alignParentStart="true"
-        android:fontFamily="sans-serif"
-        android:textSize="14sp"
-        android:textColor="#EEEEEE"
-        android:lineSpacingMultiplier="1.46286"
-        android:text="@string/pip_onboarding_description"
-        android:alpha="0" />
-    <Button
-        android:id="@+id/button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="16dp"
-        android:layout_marginStart="408dp"
-        android:layout_below="@id/description"
-        android:layout_alignParentStart="true"
-        android:gravity="center"
-        android:paddingTop="10dp"
-        android:paddingBottom="10dp"
-        android:paddingStart="24dp"
-        android:paddingEnd="24dp"
-        android:fontFamily="sans-serif-condensed"
-        android:textSize="16sp"
-        android:textColor="#FFFFFF"
-        android:textAllCaps="true"
-        android:text="@string/pip_onboarding_button"
-        android:alpha="0"
-        android:background="#009688"
-        android:elevation="4dp" />
-</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/tv_pip_overlay.xml b/packages/SystemUI/res/layout/tv_pip_overlay.xml
deleted file mode 100644
index 608680c..0000000
--- a/packages/SystemUI/res/layout/tv_pip_overlay.xml
+++ /dev/null
@@ -1,42 +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.
-*/
--->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@drawable/tv_pip_overlay_background">
-
-    <TextView
-        android:id="@+id/guide_overlay"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:paddingTop="6dp"
-        android:paddingBottom="6dp"
-        android:paddingStart="10dp"
-        android:paddingEnd="10dp"
-        android:textSize="14sp"
-        android:textColor="#EEEEEE"
-        android:fontFamily="sans-serif"
-        android:background="@drawable/tv_pip_overlay_text_background"
-        android:lineSpacingMultiplier="1.465"
-        android:gravity="center"
-        android:maxLines="2"
-        android:text="@string/pip_hold_home" />
-</RelativeLayout>
diff --git a/packages/SystemUI/res/values/colors_tv.xml b/packages/SystemUI/res/values/colors_tv.xml
index 3817da0..6e56d4a 100644
--- a/packages/SystemUI/res/values/colors_tv.xml
+++ b/packages/SystemUI/res/values/colors_tv.xml
@@ -21,4 +21,4 @@
     <color name="recents_tv_card_title_text_color">#CCEEEEEE</color>
     <color name="recents_tv_dismiss_text_color">#7FEEEEEE</color>
     <color name="recents_tv_text_shadow_color">#7F000000</color>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/packages/SystemUI/res/values/dimens_tv.xml b/packages/SystemUI/res/values/dimens_tv.xml
deleted file mode 100644
index 30355d4..0000000
--- a/packages/SystemUI/res/values/dimens_tv.xml
+++ /dev/null
@@ -1,22 +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.
- */
--->
-<resources>
-    <!-- Extra space around the PIP and its outline in PIP onboarding activity  -->
-    <dimen name="tv_pip_bounds_space">3dp</dimen>
-</resources>
diff --git a/packages/SystemUI/res/values/integers_tv.xml b/packages/SystemUI/res/values/integers_tv.xml
deleted file mode 100644
index 09547da..0000000
--- a/packages/SystemUI/res/values/integers_tv.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-    <!-- Delay of the onboarding animation start after it launches -->
-    <integer name="tv_pip_onboarding_anim_start_delay">1000</integer>
-    <!-- Duration of the onboarding animation duration -->
-    <integer name="tv_pip_onboarding_anim_duration">1000</integer>
-</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index eeb28c8..33b1dd4 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1466,6 +1466,15 @@
         <item quantity="other"><xliff:g id="channel_name_1">%1$s</xliff:g>, <xliff:g id="channel_name_2">%2$s</xliff:g>, and <xliff:g id="number">%3$d</xliff:g> others</item>
     </plurals>
 
+    <!-- Notification: Control panel: Accessibility description for expanded inline controls view, used
+        to control settings about notifications related to the current notification.  -->
+    <string name="notification_channel_controls_opened_accessibility">Notification controls for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g> opened</string>
+    <!-- Notification: Control panel: Accessibility description for announcing the closing of the
+        inline controls view.  -->
+    <string name="notification_channel_controls_closed_accessibility">Notification controls for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g> closed</string>
+    <!-- Notification: Control panel: Accessibility description for switch that is used to enable
+        or disable notifications from this channel -->
+    <string name="notification_channel_switch_accessibility">Allow notifications from this channel</string>
     <!-- Notification: Control panel: Label for button that launches notification settings. Used
         when this app has defined more than a single channel for notifications. -->
     <string name="notification_all_categories">All Categories</string>
diff --git a/packages/SystemUI/res/values/strings_tv.xml b/packages/SystemUI/res/values/strings_tv.xml
index fb9e1f2..41626fc 100644
--- a/packages/SystemUI/res/values/strings_tv.xml
+++ b/packages/SystemUI/res/values/strings_tv.xml
@@ -27,14 +27,4 @@
     <string name="pip_play">Play</string>
     <!-- Button to pause the current media on picture-in-picture (PIP) [CHAR LIMIT=30] -->
     <string name="pip_pause">Pause</string>
-    <!-- Overlay text on picture-in-picture (PIP) to indicate that longpress HOME key to control PIP [CHAR LIMIT=52] -->
-    <string name="pip_hold_home">Hold <b>HOME</b> to control PIP</string>
-    <!-- Picture-in-Picture (PIP) onboarding screen -->
-    <eat-comment />
-    <!-- Title for picture-in-picture (PIP) onboarding screen to indicate that an user is in PIP mode. [CHAR LIMIT=NONE] -->
-    <string name="pip_onboarding_title">Picture-in-picture</string>
-    <!-- Description for picture-in-picture (PIP) onboarding screen to indicate that longpress HOME key to control PIP. [CHAR LIMIT=NONE] -->
-    <string name="pip_onboarding_description">This keeps your video in view until you play another one. Press and hold <b>HOME</b> to control it.</string>
-    <!-- Button to close picture-in-picture (PIP) onboarding screen. -->
-    <string name="pip_onboarding_button">Got it</string>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index c9479b8..e5f04c6 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -299,13 +299,13 @@
 
     <style name="TextAppearance.Volume">
         <item name="android:textStyle">normal</item>
-        <item name="android:textColor">#ffffffff</item>
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
         <item name="android:fontFamily">sans-serif</item>
     </style>
 
     <style name="TextAppearance.Volume.Header">
         <item name="android:textSize">12sp</item>
-        <item name="android:textColor">@color/volume_slider_inactive</item>
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
     </style>
 
     <style name="TextAppearance.Volume.ZenSummary">
@@ -316,7 +316,7 @@
     <style name="TextAppearance.Volume.ZenDetail">
         <item name="android:textSize">14sp</item>
         <item name="android:fontFamily">sans-serif</item>
-        <item name="android:textColor">@*android:color/quaternary_device_default_settings</item>
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
     </style>
 
     <style name="VolumeButtons" parent="@android:style/Widget.Material.Button.Borderless">
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index b447979..616e5b9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -15,6 +15,7 @@
  */
 package com.android.keyguard;
 
+import android.R.style;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.admin.DevicePolicyManager;
@@ -23,6 +24,7 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Slog;
+import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
@@ -73,7 +75,8 @@
     }
 
     public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+        super(new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault), attrs,
+                defStyle);
         mSecurityModel = new KeyguardSecurityModel(context);
         mLockPatternUtils = new LockPatternUtils(context);
         mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index e1aaaa3..1e9cbdc 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -41,7 +41,6 @@
         Key.DND_FAVORITE_BUCKET_INDEX,
         Key.DND_NONE_SELECTED,
         Key.DND_FAVORITE_ZEN,
-        Key.TV_PICTURE_IN_PICTURE_ONBOARDING_SHOWN,
         Key.QS_HOTSPOT_ADDED,
         Key.QS_DATA_SAVER_ADDED,
         Key.QS_DATA_SAVER_DIALOG_SHOWN,
@@ -62,7 +61,6 @@
         String DND_FAVORITE_BUCKET_INDEX = "DndCountdownMinuteIndex";
         String DND_NONE_SELECTED = "DndNoneSelected";
         String DND_FAVORITE_ZEN = "DndFavoriteZen";
-        String TV_PICTURE_IN_PICTURE_ONBOARDING_SHOWN = "TvPictureInPictureOnboardingShown";
         String QS_HOTSPOT_ADDED = "QsHotspotAdded";
         String QS_DATA_SAVER_ADDED = "QsDataSaverAdded";
         String QS_DATA_SAVER_DIALOG_SHOWN = "QsDataSaverDialogShown";
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index 870d4d1..90e1c07 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -145,6 +145,11 @@
         log("screenOff why=" + why);
     }
 
+    public static void traceMissedTick(String delay) {
+        if (!ENABLED) return;
+        log("missedTick by=" + delay);
+    }
+
     public static void traceKeyguard(boolean showing) {
         if (!ENABLED) return;
         log("keyguard " + showing);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 6098a20..03076cc 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -20,6 +20,8 @@
 import android.content.Context;
 import android.os.Handler;
 import android.os.SystemClock;
+import android.text.format.Formatter;
+import android.util.Log;
 
 import com.android.systemui.util.wakelock.WakeLock;
 
@@ -31,6 +33,7 @@
  */
 public class DozeUi implements DozeMachine.Part {
 
+    private static final long TIME_TICK_DEADLINE_MILLIS = 90 * 1000; // 1.5min
     private final Context mContext;
     private final AlarmManager mAlarmManager;
     private final DozeHost mHost;
@@ -40,6 +43,7 @@
     private final AlarmManager.OnAlarmListener mTimeTick;
 
     private boolean mTimeTickScheduled = false;
+    private long mLastTimeTickElapsed = 0;
 
     public DozeUi(Context context, AlarmManager alarmManager, DozeMachine machine,
             WakeLock wakeLock, DozeHost host, Handler handler) {
@@ -103,15 +107,26 @@
                 SystemClock.elapsedRealtime() + delta, "doze_time_tick", mTimeTick, mHandler);
 
         mTimeTickScheduled = true;
+        mLastTimeTickElapsed = SystemClock.elapsedRealtime();
     }
 
     private void unscheduleTimeTick() {
         if (!mTimeTickScheduled) {
             return;
         }
+        verifyLastTimeTick();
         mAlarmManager.cancel(mTimeTick);
     }
 
+    private void verifyLastTimeTick() {
+        long millisSinceLastTick = SystemClock.elapsedRealtime() - mLastTimeTickElapsed;
+        if (millisSinceLastTick > TIME_TICK_DEADLINE_MILLIS) {
+            String delay = Formatter.formatShortElapsedTime(mContext, millisSinceLastTick);
+            DozeLog.traceMissedTick(delay);
+            Log.e(DozeMachine.TAG, "Missed AOD time tick by " + delay);
+        }
+    }
+
     private long roundToNextMinute(long timeInMillis) {
         Calendar calendar = GregorianCalendar.getInstance();
         calendar.setTimeInMillis(timeInMillis);
@@ -127,6 +142,7 @@
             // Alarm was canceled, but we still got the callback. Ignore.
             return;
         }
+        verifyLastTimeTick();
 
         mHost.dozeTimeTick();
 
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index c565373..28bd23c 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -143,10 +143,10 @@
 
         @Override
         public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds,
-                Rect animatingBounds, boolean fromImeAdjustement) {
+                Rect animatingBounds, boolean fromImeAdjustement, int displayRotation) {
             mHandler.post(() -> {
                 mTouchHandler.onMovementBoundsChanged(insetBounds, normalBounds, animatingBounds,
-                        fromImeAdjustement);
+                        fromImeAdjustement, displayRotation);
             });
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index ac06703..982b808 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -221,6 +221,13 @@
     }
 
     @Override
+    protected void onStop() {
+        super.onStop();
+
+        cancelDelayedFinish();
+    }
+
+    @Override
     protected void onDestroy() {
         super.onDestroy();
 
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index 127296cd..67255d3 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -316,7 +316,8 @@
      * Animates the PiP from the expanded state to the normal state after the menu is hidden.
      */
     void animateToUnexpandedState(Rect normalBounds, float savedSnapFraction,
-            Rect normalMovementBounds, Rect currentMovementBounds, boolean minimized) {
+            Rect normalMovementBounds, Rect currentMovementBounds, boolean minimized,
+            boolean immediate) {
         if (savedSnapFraction < 0f) {
             // If there are no saved snap fractions, then just use the current bounds
             savedSnapFraction = mSnapAlgorithm.getSnapFraction(new Rect(mBounds),
@@ -326,7 +327,11 @@
         if (minimized) {
             normalBounds = getClosestMinimizedBounds(normalBounds, normalMovementBounds);
         }
-        resizeAndAnimatePipUnchecked(normalBounds, SHRINK_STACK_FROM_MENU_DURATION);
+        if (immediate) {
+            movePip(normalBounds);
+        } else {
+            resizeAndAnimatePipUnchecked(normalBounds, SHRINK_STACK_FROM_MENU_DURATION);
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 3f26fdd..fbf7ff2 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -78,6 +78,7 @@
     private final PipDismissViewController mDismissViewController;
     private final PipSnapAlgorithm mSnapAlgorithm;
     private final AccessibilityManager mAccessibilityManager;
+    private boolean mShowPipMenuOnAnimationEnd = false;
 
     // The current movement bounds
     private Rect mMovementBounds = new Rect();
@@ -89,6 +90,11 @@
     private Rect mExpandedMovementBounds = new Rect();
     private int mExpandedShortestEdgeSize;
 
+    // Used to workaround an issue where the WM rotation happens before we are notified, allowing
+    // us to send stale bounds
+    private int mDeferResizeToNormalBoundsUntilRotation = -1;
+    private int mDisplayRotation;
+
     private Handler mHandler = new Handler();
     private Runnable mShowDismissAffordance = new Runnable() {
         @Override
@@ -216,13 +222,18 @@
             setMinimizedStateInternal(false);
         }
         mDismissViewController.destroyDismissTarget();
-        mMenuController.showMenu(MENU_STATE_CLOSE, mMotionHelper.getBounds(),
-                mMovementBounds, true /* allowMenuTimeout */);
+        mShowPipMenuOnAnimationEnd = true;
     }
 
     public void onPinnedStackAnimationEnded() {
         // Always synchronize the motion helper bounds once PiP animations finish
         mMotionHelper.synchronizePinnedStackBounds();
+
+        if (mShowPipMenuOnAnimationEnd) {
+            mMenuController.showMenu(MENU_STATE_CLOSE, mMotionHelper.getBounds(),
+                    mMovementBounds, true /* allowMenuTimeout */);
+            mShowPipMenuOnAnimationEnd = false;
+        }
     }
 
     @Override
@@ -250,7 +261,7 @@
     }
 
     public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds, Rect animatingBounds,
-            boolean fromImeAdjustement) {
+            boolean fromImeAdjustement, int displayRotation) {
         // Re-calculate the expanded bounds
         mNormalBounds = normalBounds;
         Rect normalMovementBounds = new Rect();
@@ -304,7 +315,17 @@
         // above
         mNormalMovementBounds = normalMovementBounds;
         mExpandedMovementBounds = expandedMovementBounds;
+        mDisplayRotation = displayRotation;
         updateMovementBounds(mMenuState);
+
+        // If we have a deferred resize, apply it now
+        if (mDeferResizeToNormalBoundsUntilRotation == displayRotation) {
+            mMotionHelper.animateToUnexpandedState(normalBounds, mSavedSnapFraction,
+                    mNormalMovementBounds, mMovementBounds, mIsMinimized,
+                    true /* immediate */);
+            mSavedSnapFraction = -1f;
+            mDeferResizeToNormalBoundsUntilRotation = -1;
+        }
     }
 
     private void onRegistrationChanged(boolean isRegistered) {
@@ -474,11 +495,34 @@
             // Try and restore the PiP to the closest edge, using the saved snap fraction
             // if possible
             if (resize) {
-                Rect normalBounds = new Rect(mNormalBounds);
-                mMotionHelper.animateToUnexpandedState(normalBounds, mSavedSnapFraction,
-                        mNormalMovementBounds, mMovementBounds, mIsMinimized);
+                // This is a very special case: when the menu is expanded and visible, navigating to
+                // another activity can trigger auto-enter PiP, and if the revealed activity has a
+                // forced rotation set, then the controller will get updated with the new rotation
+                // of the display. However, at the same time, SystemUI will try to hide the menu by
+                // creating an animation to the normal bounds which are now stale.  In such a case
+                // we defer the animation to the normal bounds until after the next
+                // onMovementBoundsChanged() call to get the bounds in the new orientation
+                if (mDeferResizeToNormalBoundsUntilRotation == -1) {
+                    try {
+                        int displayRotation = mPinnedStackController.getDisplayRotation();
+                        if (mDisplayRotation != displayRotation) {
+                            mDeferResizeToNormalBoundsUntilRotation = displayRotation;
+                        }
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Could not get display rotation from controller");
+                    }
+                }
+
+                if (mDeferResizeToNormalBoundsUntilRotation == -1) {
+                    Rect normalBounds = new Rect(mNormalBounds);
+                    mMotionHelper.animateToUnexpandedState(normalBounds, mSavedSnapFraction,
+                            mNormalMovementBounds, mMovementBounds, mIsMinimized,
+                            false /* immediate */);
+                    mSavedSnapFraction = -1f;
+                }
+            } else {
+                mSavedSnapFraction = -1f;
             }
-            mSavedSnapFraction = -1f;
         }
         mMenuState = menuState;
         updateMovementBounds(menuState);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index ad290c3..657f08b 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -56,16 +56,12 @@
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.view.Display.DEFAULT_DISPLAY;
 
-import static com.android.systemui.Prefs.Key.TV_PICTURE_IN_PICTURE_ONBOARDING_SHOWN;
-
 /**
  * Manages the picture-in-picture (PIP) UI and states.
  */
 public class PipManager implements BasePipManager {
     private static final String TAG = "PipManager";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-    private static final boolean DEBUG_FORCE_ONBOARDING =
-            SystemProperties.getBoolean("debug.tv.pip_force_onboarding", false);
     private static final String SETTINGS_PACKAGE_AND_CLASS_DELIMITER = "/";
 
     private static PipManager sPipManager;
@@ -76,10 +72,9 @@
      */
     public static final int STATE_NO_PIP = 0;
     /**
-     * State when PIP is shown with an overlay message on top of it.
-     * This is used as default PIP state.
+     * State when PIP is shown. This is used as default PIP state.
      */
-    public static final int STATE_PIP_OVERLAY = 1;
+    public static final int STATE_PIP = 1;
     /**
      * State when PIP menu dialog is shown.
      */
@@ -126,7 +121,6 @@
     private int mPipTaskId = TASK_ID_NO_PIP;
     private ComponentName mPipComponentName;
     private MediaController mPipMediaController;
-    private boolean mOnboardingShown;
     private String[] mLastPackagesResourceGranted;
 
     private final PinnedStackListener mPinnedStackListener = new PinnedStackListener();
@@ -184,7 +178,7 @@
 
         @Override
         public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds,
-                Rect animatingBounds, boolean fromImeAdjustement) {
+                Rect animatingBounds, boolean fromImeAdjustement, int displayRotation) {
             mHandler.post(() -> {
                 mDefaultPipBounds.set(normalBounds);
             });
@@ -212,8 +206,6 @@
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_MEDIA_RESOURCE_GRANTED);
         mContext.registerReceiver(mBroadcastReceiver, intentFilter);
-        mOnboardingShown = Prefs.getBoolean(
-                mContext, TV_PICTURE_IN_PICTURE_ONBOARDING_SHOWN, false);
 
         if (sSettingsPackageAndClassNamePairList == null) {
             String[] settings = mContext.getResources().getStringArray(
@@ -267,7 +259,7 @@
         //   1. Configuration changed due to the language change (RTL <-> RTL)
         //   2. SystemUI restarts after the crash
         mPipBounds = isSettingsShown() ? mSettingsPipBounds : mDefaultPipBounds;
-        resizePinnedStack(getPinnedStackInfo() == null ? STATE_NO_PIP : STATE_PIP_OVERLAY);
+        resizePinnedStack(getPinnedStackInfo() == null ? STATE_NO_PIP : STATE_PIP);
     }
 
     /**
@@ -281,7 +273,7 @@
      * Shows the picture-in-picture menu if an activity is in picture-in-picture mode.
      */
     public void showPictureInPictureMenu() {
-        if (mState == STATE_PIP_OVERLAY) {
+        if (mState == STATE_PIP) {
             resizePinnedStack(STATE_PIP_MENU);
         }
     }
@@ -325,16 +317,6 @@
     }
 
     /**
-     * Shows PIP overlay UI by launching {@link PipOverlayActivity}. It also locates the pinned
-     * stack to the default PIP bound {@link com.android.internal.R.string
-     * .config_defaultPictureInPictureBounds}.
-     */
-    private void showPipOverlay() {
-        if (DEBUG) Log.d(TAG, "showPipOverlay()");
-        PipOverlayActivity.showPipOverlay(mContext);
-    }
-
-    /**
      * Suspends resizing operation on the Pip until {@link #resumePipResizing} is called
      * @param reason The reason for suspending resizing operations on the Pip.
      */
@@ -388,7 +370,7 @@
             case STATE_PIP_MENU:
                 mCurrentPipBounds = mMenuModePipBounds;
                 break;
-            case STATE_PIP_OVERLAY:
+            case STATE_PIP:
                 mCurrentPipBounds = mPipBounds;
                 break;
             default:
@@ -454,17 +436,6 @@
         mMediaListeners.remove(listener);
     }
 
-    private void launchPipOnboardingActivityIfNeeded() {
-        if (DEBUG_FORCE_ONBOARDING || !mOnboardingShown) {
-            mOnboardingShown = true;
-            Prefs.putBoolean(mContext, TV_PICTURE_IN_PICTURE_ONBOARDING_SHOWN, true);
-
-            Intent intent = new Intent(mContext, PipOnboardingActivity.class);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            mContext.startActivity(intent);
-        }
-    }
-
     /**
      * Returns {@code true} if PIP is shown.
      */
@@ -617,11 +588,11 @@
                     return;
                 }
             }
-            if (mState == STATE_PIP_OVERLAY) {
+            if (mState == STATE_PIP) {
                 Rect bounds = isSettingsShown() ? mSettingsPipBounds : mDefaultPipBounds;
                 if (mPipBounds != bounds) {
                     mPipBounds = bounds;
-                    resizePinnedStack(STATE_PIP_OVERLAY);
+                    resizePinnedStack(STATE_PIP);
                 }
             }
         }
@@ -641,10 +612,9 @@
             mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1];
             mPipComponentName = ComponentName.unflattenFromString(
                     stackInfo.taskNames[stackInfo.taskNames.length - 1]);
-            // Set state to overlay so we show it when the pinned stack animation ends.
-            mState = STATE_PIP_OVERLAY;
+            // Set state to STATE_PIP so we show it when the pinned stack animation ends.
+            mState = STATE_PIP;
             mCurrentPipBounds = mPipBounds;
-            launchPipOnboardingActivityIfNeeded();
             mMediaSessionManager.addOnActiveSessionsChangedListener(
                     mActiveMediaSessionListener, null);
             updateMediaController(mMediaSessionManager.getActiveSessions(null));
@@ -671,9 +641,6 @@
                 return;
             }
             switch (mState) {
-                case STATE_PIP_OVERLAY:
-                    showPipOverlay();
-                    break;
                 case STATE_PIP_MENU:
                     showPipMenu();
                     break;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
index 9945079..ce1bea1 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
@@ -56,7 +56,7 @@
     private void restorePipAndFinish() {
         if (mRestorePipSizeWhenClose) {
             // When PIP menu activity is closed, restore to the default position.
-            mPipManager.resizePinnedStack(PipManager.STATE_PIP_OVERLAY);
+            mPipManager.resizePinnedStack(PipManager.STATE_PIP);
         }
         finish();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipOnboardingActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipOnboardingActivity.java
deleted file mode 100644
index 423530a..0000000
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipOnboardingActivity.java
+++ /dev/null
@@ -1,131 +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.pip.tv;
-
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.app.Activity;
-import android.graphics.drawable.AnimationDrawable;
-import android.os.Bundle;
-import android.view.View;
-import android.view.KeyEvent;
-import android.widget.ImageView;
-
-import com.android.systemui.R;
-
-/**
- * Activity to show an overlay on top of PIP activity to show how to pop up PIP menu.
- */
-public class PipOnboardingActivity extends Activity implements PipManager.Listener {
-    private final PipManager mPipManager = PipManager.getInstance();
-    private AnimatorSet mEnterAnimator;
-
-    @Override
-    protected void onCreate(Bundle bundle) {
-        super.onCreate(bundle);
-        setContentView(R.layout.tv_pip_onboarding);
-        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                finish();
-            }
-        });
-
-        mPipManager.addListener(this);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        mEnterAnimator = new AnimatorSet();
-        mEnterAnimator.playTogether(
-                loadAnimator(R.id.background, R.anim.tv_pip_onboarding_background_enter_animation),
-                loadAnimator(R.id.remote, R.anim.tv_pip_onboarding_image_enter_animation),
-                loadAnimator(R.id.remote_button, R.anim.tv_pip_onboarding_image_enter_animation),
-                loadAnimator(R.id.title, R.anim.tv_pip_onboarding_title_enter_animation),
-                loadAnimator(R.id.description,
-                        R.anim.tv_pip_onboarding_description_enter_animation),
-                loadAnimator(R.id.button, R.anim.tv_pip_onboarding_button_enter_animation));
-        mEnterAnimator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationStart(Animator animation) {
-                ImageView button = findViewById(R.id.remote_button);
-                ((AnimationDrawable) button.getDrawable()).start();
-            }
-        });
-        int delay = getResources().getInteger(R.integer.tv_pip_onboarding_anim_start_delay);
-        mEnterAnimator.setStartDelay(delay);
-        mEnterAnimator.start();
-    }
-
-    private Animator loadAnimator(int viewResId, int animResId) {
-        Animator animator = AnimatorInflater.loadAnimator(this, animResId);
-        animator.setTarget(findViewById(viewResId));
-        return animator;
-    }
-
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        if (mEnterAnimator.isStarted()) {
-            return true;
-        }
-        return super.onKeyUp(keyCode, event);
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (mEnterAnimator.isStarted()) {
-            return true;
-        }
-        return super.onKeyDown(keyCode, event);
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        finish();
-    }
-
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        mPipManager.removeListener(this);
-    }
-
-    @Override
-    public void onPipEntered() { }
-
-    @Override
-    public void onPipActivityClosed() {
-        finish();
-    }
-
-    @Override
-    public void onShowPipMenu() {
-        finish();
-    }
-
-    @Override
-    public void onMoveToFullscreen() {
-        finish();
-    }
-
-    @Override
-    public void onPipResizeAboutToStart() { }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipOverlayActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipOverlayActivity.java
deleted file mode 100644
index f52121f..0000000
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipOverlayActivity.java
+++ /dev/null
@@ -1,138 +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.pip.tv;
-
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.app.Activity;
-import android.app.ActivityOptions;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.view.View;
-import android.widget.ImageView;
-
-import com.android.systemui.R;
-
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-
-/**
- * Activity to show an overlay on top of PIP activity to show how to pop up PIP menu.
- */
-public class PipOverlayActivity extends Activity implements PipManager.Listener {
-    private static final long SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS = 4000;
-
-    /**
-     * A flag to ensure the single instance of PipOverlayActivity to prevent it from restarting.
-     * Note that {@link PipManager} moves the PIPed activity to fullscreen if the activity is
-     * restarted. It's because the activity may be started by the Launcher or an intent again,
-     * but we don't want do so for the PipOverlayActivity.
-     */
-    private static boolean sActivityCreated;
-
-    private final PipManager mPipManager = PipManager.getInstance();
-    private final Handler mHandler = new Handler();
-    private View mGuideOverlayView;
-    private View mGuideButtonsView;
-    private ImageView mGuideButtonPlayPauseImageView;
-    private final Runnable mHideGuideOverlayRunnable = new Runnable() {
-        public void run() {
-            mFadeOutAnimation.start();
-        }
-    };
-    private Animator mFadeInAnimation;
-    private Animator mFadeOutAnimation;
-
-    /**
-     * Shows PIP overlay UI only if it's not there.
-     */
-    static void showPipOverlay(Context context) {
-        if (!sActivityCreated) {
-            Intent intent = new Intent(context, PipOverlayActivity.class);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            final ActivityOptions options = ActivityOptions.makeBasic();
-            options.setLaunchStackId(PINNED_STACK_ID);
-            context.startActivity(intent, options.toBundle());
-        }
-    }
-
-    @Override
-    protected void onCreate(Bundle bundle) {
-        super.onCreate(bundle);
-        sActivityCreated = true;
-        setContentView(R.layout.tv_pip_overlay);
-        mGuideOverlayView = findViewById(R.id.guide_overlay);
-        mPipManager.addListener(this);
-        mFadeInAnimation = AnimatorInflater.loadAnimator(
-                this, R.anim.tv_pip_overlay_fade_in_animation);
-        mFadeInAnimation.setTarget(mGuideOverlayView);
-        mFadeOutAnimation = AnimatorInflater.loadAnimator(
-                this, R.anim.tv_pip_overlay_fade_out_animation);
-        mFadeOutAnimation.setTarget(mGuideOverlayView);
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        mFadeInAnimation.start();
-        mHandler.removeCallbacks(mHideGuideOverlayRunnable);
-        mHandler.postDelayed(mHideGuideOverlayRunnable, SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS);
-    }
-
-    @Override
-    protected void onStop() {
-        super.onStop();
-        mHandler.removeCallbacks(mHideGuideOverlayRunnable);
-        finish();
-    }
-
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        sActivityCreated = false;
-        mHandler.removeCallbacksAndMessages(null);
-        mPipManager.removeListener(this);
-        mPipManager.resumePipResizing(
-                PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_OVERLAY_ACTIVITY_FINISH);
-    }
-
-    @Override
-    public void onPipEntered() { }
-
-    @Override
-    public void onPipActivityClosed() {
-        finish();
-    }
-
-    @Override
-    public void onShowPipMenu() {
-        finish();
-    }
-
-    @Override
-    public void onMoveToFullscreen() {
-        finish();
-    }
-
-    @Override
-    public void onPipResizeAboutToStart() {
-        finish();
-        mPipManager.suspendPipResizing(
-                PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_OVERLAY_ACTIVITY_FINISH);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index d51fe8a..53c36e6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -167,6 +167,9 @@
         if (mAlarmShowing) {
             builder.addFloat(mDate, "alpha", 1, 0)
                     .addFloat(mDateTimeGroup, "translationX", 0, -mDate.getWidth());
+        } else {
+            mDate.setAlpha(1);
+            mDateTimeGroup.setTranslationX(0);
         }
         mAnimator = builder.build();
         setExpansion(mExpansionAmount);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 7518527..e457d72 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -77,6 +77,9 @@
 
         BatteryMeterView battery = findViewById(R.id.battery);
         battery.setForceShowPercent(true);
+        // Don't show the Wi-Fi indicator here, because it is shown just below in the tile.
+        SignalClusterView signalCluster = findViewById(R.id.signal_cluster);
+        signalCluster.setForceBlockWifi();
 
         mActivityStarter = Dependency.get(ActivityStarter.class);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 92ff17a1..d74e3ac 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -128,7 +128,7 @@
         state.value = mDataController.isMobileDataSupported()
                 && mDataController.isMobileDataEnabled();
         state.icon = ResourceIcon.get(R.drawable.ic_data_unavailable);
-        state.state = cb.airplaneModeEnabled || !cb.enabled ? Tile.STATE_UNAVAILABLE
+        state.state = cb.airplaneModeEnabled || !cb.enabled || cb.noSim ? Tile.STATE_UNAVAILABLE
                 : state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         if (state.state == Tile.STATE_ACTIVE) {
             state.icon = ResourceIcon.get(R.drawable.ic_data_on);
@@ -161,44 +161,27 @@
 
     private static final class CallbackInfo {
         boolean enabled;
-        boolean wifiEnabled;
         boolean airplaneModeEnabled;
-        String signalContentDescription;
-        int dataTypeIconId;
-        String dataContentDescription;
         boolean activityIn;
         boolean activityOut;
-        String enabledDesc;
         boolean noSim;
-        boolean isDataTypeIconWide;
         boolean roaming;
     }
 
     private final class CellSignalCallback implements SignalCallback {
         private final CallbackInfo mInfo = new CallbackInfo();
-        @Override
-        public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
-                boolean activityIn, boolean activityOut, String description, boolean isTransient) {
-            mInfo.wifiEnabled = enabled;
-            refreshState(mInfo);
-        }
 
         @Override
-        public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
-                int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
-                String description, boolean isWide, int subId, boolean roaming) {
-            if (qsIcon == null) {
+        public void setMobileDataIndicators(IconState statusIcon, int statusType,
+                boolean activityIn, boolean activityOut, String typeContentDescription,
+                int subId, boolean roaming, boolean isEmergency) {
+            if (statusIcon == null) {
                 // Not data sim, don't display.
                 return;
             }
-            mInfo.enabled = qsIcon.visible;
-            mInfo.signalContentDescription = qsIcon.contentDescription;
-            mInfo.dataTypeIconId = qsType;
-            mInfo.dataContentDescription = typeContentDescription;
+            mInfo.enabled = statusIcon.visible;
             mInfo.activityIn = activityIn;
             mInfo.activityOut = activityOut;
-            mInfo.enabledDesc = description;
-            mInfo.isDataTypeIconWide = qsType != 0 && isWide;
             mInfo.roaming = roaming;
             refreshState(mInfo);
         }
@@ -206,15 +189,6 @@
         @Override
         public void setNoSims(boolean show) {
             mInfo.noSim = show;
-            if (mInfo.noSim) {
-                // Make sure signal gets cleared out when no sims.
-                mInfo.dataTypeIconId = 0;
-                // Show a No SIMs description to avoid emergency calls message.
-                mInfo.enabled = true;
-                mInfo.enabledDesc = mContext.getString(
-                        R.string.keyguard_missing_sim_message_short);
-                mInfo.signalContentDescription = mInfo.enabledDesc;
-            }
             refreshState(mInfo);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 397b78d..ccebd7c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -82,7 +82,6 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.R;
 import com.android.systemui.pip.tv.PipMenuActivity;
-import com.android.systemui.pip.tv.PipOnboardingActivity;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.RecentsImpl;
@@ -113,7 +112,6 @@
     final static List<String> sRecentsBlacklist;
     static {
         sRecentsBlacklist = new ArrayList<>();
-        sRecentsBlacklist.add(PipOnboardingActivity.class.getName());
         sRecentsBlacklist.add(PipMenuActivity.class.getName());
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 677642e..cc91753 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -1115,6 +1115,10 @@
         mNotificationInflater.setInflateExceptionHandler(inflateExceptionHandler);
     }
 
+    public void setNeedsRedaction(boolean needsRedaction) {
+        mNotificationInflater.setRedactAmbient(needsRedaction);
+    }
+
     public interface ExpansionLogger {
         public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 8f160dc..6098565 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -428,6 +428,9 @@
             mAmbientChild.animate().cancel();
             removeView(mAmbientChild);
         }
+        if (child == null) {
+            return;
+        }
         addView(child);
         mAmbientChild = child;
         mAmbientWrapper = NotificationViewWrapper.wrap(getContext(), child,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 2713f58..0a99ee6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -39,6 +39,7 @@
 import android.view.View;
 import android.view.ViewAnimationUtils;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -255,6 +256,7 @@
     }
 
     public void setExposed(boolean exposed, boolean needsFalsingProtection) {
+        final boolean wasExposed = mExposed;
         mExposed = exposed;
         mNeedsFalsingProtection = needsFalsingProtection;
         if (mExposed && mNeedsFalsingProtection) {
@@ -262,6 +264,13 @@
         } else {
             mHandler.removeCallbacks(mFalsingCheck);
         }
+        if (wasExposed != mExposed && mGutsContent != null) {
+            final View contentView = mGutsContent.getContentView();
+            contentView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+            if (mExposed) {
+                contentView.requestAccessibilityFocus();
+            }
+        }
     }
 
     public boolean willBeRemoved() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 7928575..8925189 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -35,6 +35,7 @@
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.Switch;
@@ -57,6 +58,7 @@
 
     private INotificationManager mINotificationManager;
     private String mPkg;
+    private String mAppName;
     private int mAppUid;
     private List<NotificationChannel> mNotificationChannels;
     private NotificationChannel mSingleNotificationChannel;
@@ -125,7 +127,7 @@
             }
         }
 
-        String appName = mPkg;
+        mAppName = mPkg;
         Drawable pkgicon = null;
         CharSequence channelNameText = "";
         ApplicationInfo info = null;
@@ -137,7 +139,7 @@
                             | PackageManager.MATCH_DIRECT_BOOT_AWARE);
             if (info != null) {
                 mAppUid = info.uid;
-                appName = String.valueOf(pm.getApplicationLabel(info));
+                mAppName = String.valueOf(pm.getApplicationLabel(info));
                 pkgicon = pm.getApplicationIcon(info);
             }
         } catch (PackageManager.NameNotFoundException e) {
@@ -189,7 +191,7 @@
         } else {
             channelNameText = mSingleNotificationChannel.getName();
         }
-        ((TextView) findViewById(R.id.pkgname)).setText(appName);
+        ((TextView) findViewById(R.id.pkgname)).setText(mAppName);
         ((TextView) findViewById(R.id.channel_name)).setText(channelNameText);
 
         // Set group information if this channel has an associated group.
@@ -309,6 +311,21 @@
         });
     }
 
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        if (mGutsContainer != null &&
+                event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+            if (mGutsContainer.isExposed()) {
+                event.getText().add(mContext.getString(
+                        R.string.notification_channel_controls_opened_accessibility, mAppName));
+            } else {
+                event.getText().add(mContext.getString(
+                        R.string.notification_channel_controls_closed_accessibility, mAppName));
+            }
+        }
+    }
+
     private void updateSecondaryText() {
         final boolean disabled = mSingleNotificationChannel != null &&
                 getSelectedImportance() == IMPORTANCE_NONE;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index fee24b7..802925a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -227,6 +227,7 @@
                 if (mShouldShowMenu
                         && !NotificationStackScrollLayout.isPinnedHeadsUp(view)
                         && !mParent.areGutsExposed()
+                        && !mParent.isDark()
                         && (mCheckForDrag == null || !mHandler.hasCallbacks(mCheckForDrag))) {
                     // Only show the menu if we're not a heads up view and guts aren't exposed.
                     mCheckForDrag = new CheckForDrag();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index dc254f9..b01d9cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -24,8 +24,6 @@
 import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.Rect;
-import android.graphics.drawable.Animatable;
-import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.LayerDrawable;
 import android.telephony.SubscriptionInfo;
@@ -120,6 +118,7 @@
     private boolean mBlockWifi;
     private boolean mBlockEthernet;
     private boolean mActivityEnabled;
+    private boolean mForceBlockWifi;
 
     public SignalClusterView(Context context) {
         this(context, null);
@@ -151,6 +150,16 @@
         updateActivityEnabled();
     }
 
+    public void setForceBlockWifi() {
+        mForceBlockWifi = true;
+        mBlockWifi = true;
+        if (isAttachedToWindow()) {
+            // Re-register to get new callbacks.
+            mNetworkController.removeCallback(this);
+            mNetworkController.addCallback(this);
+        }
+    }
+
     @Override
     public void onTuningChanged(String key, String newValue) {
         if (!StatusBarIconController.ICON_BLACKLIST.equals(key)) {
@@ -167,7 +176,7 @@
             mBlockAirplane = blockAirplane;
             mBlockMobile = blockMobile;
             mBlockEthernet = blockEthernet;
-            mBlockWifi = blockWifi;
+            mBlockWifi = blockWifi || mForceBlockWifi;
             // Re-register to get new callbacks.
             mNetworkController.removeCallback(this);
             mNetworkController.addCallback(this);
@@ -288,9 +297,9 @@
     }
 
     @Override
-    public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
-            int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
-            String description, boolean isWide, int subId, boolean roaming) {
+    public void setMobileDataIndicators(IconState statusIcon, int statusType,
+            boolean activityIn, boolean activityOut, String typeContentDescription,
+            int subId, boolean roaming, boolean isEmergency) {
         PhoneState state = getState(subId);
         if (state == null) {
             return;
@@ -300,7 +309,6 @@
         state.mMobileTypeId = statusType;
         state.mMobileDescription = statusIcon.contentDescription;
         state.mMobileTypeDescription = typeContentDescription;
-        state.mIsMobileTypeIconWide = statusType != 0 && isWide;
         state.mRoaming = roaming;
         state.mActivityIn = activityIn && mActivityEnabled;
         state.mActivityOut = activityOut && mActivityEnabled;
@@ -525,7 +533,7 @@
             mWifiAirplaneSpacer.setVisibility(View.GONE);
         }
 
-        if (((anyMobileVisible && firstMobileTypeId != 0) || mNoSimsVisible) && mWifiVisible) {
+        if (((anyMobileVisible && firstMobileTypeId == 0) || mNoSimsVisible) && mWifiVisible) {
             mWifiSignalSpacer.setVisibility(View.VISIBLE);
         } else {
             mWifiSignalSpacer.setVisibility(View.GONE);
@@ -636,7 +644,6 @@
         private int mMobileStrengthId = 0, mMobileTypeId = 0;
         private int mLastMobileStrengthId = -1;
         private int mLastMobileTypeId = -1;
-        private boolean mIsMobileTypeIconWide;
         private String mMobileDescription, mMobileTypeDescription;
 
         private ViewGroup mMobileGroup;
@@ -692,12 +699,8 @@
             // When this isn't next to wifi, give it some extra padding between the signals.
             mMobileGroup.setPaddingRelative(isSecondaryIcon ? mSecondaryTelephonyPadding : 0,
                     0, 0, 0);
-            mMobile.setPaddingRelative(
-                    mIsMobileTypeIconWide ? mWideTypeIconStartPadding : mMobileDataIconStartPadding,
-                    0, 0, 0);
-            mMobileDark.setPaddingRelative(
-                    mIsMobileTypeIconWide ? mWideTypeIconStartPadding : mMobileDataIconStartPadding,
-                    0, 0, 0);
+            mMobile.setPaddingRelative(mMobileDataIconStartPadding, 0, 0, 0);
+            mMobileDark.setPaddingRelative(mMobileDataIconStartPadding, 0, 0, 0);
 
             if (DEBUG) Log.d(TAG, String.format("mobile: %s sig=%d typ=%d",
                         (mMobileVisible ? "VISIBLE" : "GONE"), mMobileStrengthId, mMobileTypeId));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 92bfae9..ec15d10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -499,12 +499,18 @@
     }
 
     private void setColorInternal(int color) {
-        if (color != NO_COLOR) {
-            setImageTintList(ColorStateList.valueOf(color));
+        mCurrentSetColor = color;
+        updateIconColor();
+    }
+
+    private void updateIconColor() {
+        if (mCurrentSetColor != NO_COLOR) {
+            setImageTintList(ColorStateList.valueOf(NotificationUtils.interpolateColors(
+                    mCurrentSetColor, Color.WHITE, mDarkAmount)));
         } else {
             setImageTintList(null);
+            mDozer.updateGrayscale(this, mDarkAmount);
         }
-        mCurrentSetColor = color;
     }
 
     public void setIconColor(int iconColor, boolean animate) {
@@ -669,10 +675,10 @@
     }
 
     public void setDark(boolean dark, boolean fade, long delay) {
-        mDozer.setImageDark(this, dark, fade, delay, mIconColor == NO_COLOR);
         mDozer.setIntensityDark(f -> {
             mDarkAmount = f;
             updateDecorColor();
+            updateIconColor();
         }, dark, fade, delay);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
index d592c5f..0b3b3cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
@@ -35,8 +35,7 @@
         startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
             @Override
             public void onAnimationUpdate(ValueAnimator animation) {
-                updateGrayscaleMatrix((float) animation.getAnimatedValue());
-                target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
+                updateGrayscale(target, (float) animation.getAnimatedValue());
             }
         }, dark, delay, new AnimatorListenerAdapter() {
             @Override
@@ -49,8 +48,12 @@
     }
 
     public void updateGrayscale(ImageView target, boolean dark) {
-        if (dark) {
-            updateGrayscaleMatrix(1f);
+        updateGrayscale(target, dark ? 1 : 0);
+    }
+
+    public void updateGrayscale(ImageView target, float darkAmount) {
+        if (darkAmount > 0) {
+            updateGrayscaleMatrix(darkAmount);
             target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
         } else {
             target.setColorFilter(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
index 73eecbb..2e34f24 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
@@ -21,6 +21,8 @@
 import android.service.notification.StatusBarNotification;
 import android.util.Log;
 import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
 import android.widget.RemoteViews;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -49,6 +51,7 @@
     private RemoteViews.OnClickHandler mRemoteViewClickHandler;
     private boolean mIsChildInGroup;
     private InflationExceptionHandler mInflateExceptionHandler;
+    private boolean mRedactAmbient;
 
     public NotificationInflater(ExpandableNotificationRow row) {
         mRow = row;
@@ -92,6 +95,21 @@
         mRemoteViewClickHandler = remoteViewClickHandler;
     }
 
+    public void setRedactAmbient(boolean redactAmbient) {
+        if (mRedactAmbient != redactAmbient) {
+            mRedactAmbient = redactAmbient;
+            if (mRow.getEntry() == null) {
+                return;
+            }
+            try {
+                inflateNotificationViews(FLAG_REINFLATE_AMBIENT_VIEW);
+            } catch (InflationException e) {
+                mInflateExceptionHandler.handleInflationException(
+                        mRow.getStatusBarNotification(), e);
+            }
+        }
+    }
+
     public void inflateNotificationViews() throws InflationException {
         inflateNotificationViews(FLAG_REINFLATE_ALL);
     }
@@ -123,6 +141,8 @@
             Notification.Builder builder, Context packageContext) {
         NotificationData.Entry entry = mRow.getEntry();
         NotificationContentView privateLayout = mRow.getPrivateLayout();
+        NotificationContentView publicLayout = mRow.getPublicLayout();
+
         boolean isLowPriority = mIsLowPriority && !mIsChildInGroup;
         if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) {
             final RemoteViews newContentView = createContentView(builder,
@@ -190,7 +210,6 @@
         }
 
         if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) {
-            NotificationContentView publicLayout = mRow.getPublicLayout();
             final RemoteViews newPublicNotification
                     = builder.makePublicContentView();
             if (!compareRemoteViews(newPublicNotification, entry.cachedPublicContentView)) {
@@ -209,18 +228,24 @@
         }
 
         if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) {
-            final RemoteViews newAmbientNotification
-                    = builder.makeAmbientNotification();
-            if (!compareRemoteViews(newAmbientNotification, entry.cachedAmbientContentView)) {
+            final RemoteViews newAmbientNotification = mRedactAmbient
+                    ? builder.makePublicAmbientNotification()
+                    : builder.makeAmbientNotification();
+            NotificationContentView newParent = mRedactAmbient ? publicLayout : privateLayout;
+            NotificationContentView otherParent = !mRedactAmbient ? publicLayout : privateLayout;
+
+            if (newParent.getAmbientChild() == null ||
+                    !compareRemoteViews(newAmbientNotification, entry.cachedAmbientContentView)) {
                 View ambientContentView = newAmbientNotification.apply(
                         packageContext,
-                        privateLayout,
+                        newParent,
                         mRemoteViewClickHandler);
                 ambientContentView.setIsRootNamespace(true);
-                privateLayout.setAmbientChild(ambientContentView);
+                newParent.setAmbientChild(ambientContentView);
+                otherParent.setAmbientChild(null);
             } else {
                 newAmbientNotification.reapply(packageContext,
-                        privateLayout.getAmbientChild(),
+                        newParent.getAmbientChild(),
                         mRemoteViewClickHandler);
             }
             entry.cachedAmbientContentView = newAmbientNotification;
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 be16266..dd99749 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -23,6 +23,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewStub;
 import android.widget.LinearLayout;
 
 import com.android.systemui.Dependency;
@@ -36,6 +37,7 @@
 import com.android.systemui.statusbar.policy.EncryptionHelper;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
 
 /**
  * Contains the collapsed status bar and handles hiding/showing based on disable flags
@@ -56,6 +58,13 @@
     private DarkIconManager mDarkIconManager;
     private SignalClusterView mSignalClusterView;
 
+    private SignalCallback mSignalCallback = new SignalCallback() {
+        @Override
+        public void setIsAirplaneMode(NetworkController.IconState icon) {
+            mStatusBarComponent.recomputeDisableFlags(true /* animate */);
+        }
+    };
+
     @Override
     public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -84,6 +93,7 @@
         Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mSignalClusterView);
         // Default to showing until we know otherwise.
         showSystemIconArea(false);
+        initEmergencyCryptkeeperText();
     }
 
     @Override
@@ -109,6 +119,9 @@
         super.onDestroyView();
         Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(mSignalClusterView);
         Dependency.get(StatusBarIconController.class).removeIconGroup(mDarkIconManager);
+        if (mNetworkController.hasEmergencyCryptKeeperText()) {
+            mNetworkController.removeCallback(mSignalCallback);
+        }
     }
 
     public void initNotificationIconArea(NotificationIconAreaController
@@ -233,4 +246,17 @@
                     .start();
         }
     }
+
+    private void initEmergencyCryptkeeperText() {
+        View emergencyViewStub = mStatusBar.findViewById(R.id.emergency_cryptkeeper_text);
+        if (mNetworkController.hasEmergencyCryptKeeperText()) {
+            if (emergencyViewStub != null) {
+                ((ViewStub) emergencyViewStub).inflate();
+            }
+            mNetworkController.addCallback(mSignalCallback);
+        } else if (emergencyViewStub != null) {
+            ViewGroup parent = (ViewGroup) emergencyViewStub.getParent();
+            parent.removeView(emergencyViewStub);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index dadb749..67d5b6a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -57,6 +57,7 @@
     private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target;
     private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
     private static final int TAG_END_ALPHA = R.id.scrim_alpha_end;
+    private static final float NOT_INITIALIZED = -1;
 
     private final LightBarController mLightBarController;
     protected final ScrimView mScrimBehind;
@@ -87,9 +88,9 @@
     private boolean mDozing;
     private float mDozeInFrontAlpha;
     private float mDozeBehindAlpha;
-    private float mCurrentInFrontAlpha;
-    private float mCurrentBehindAlpha;
-    private float mCurrentHeadsUpAlpha = 1;
+    private float mCurrentInFrontAlpha  = NOT_INITIALIZED;
+    private float mCurrentBehindAlpha = NOT_INITIALIZED;
+    private float mCurrentHeadsUpAlpha = NOT_INITIALIZED;
     private int mPinnedHeadsUpCount;
     private float mTopHeadsUpDragAmount;
     private View mDraggedHeadsUpView;
@@ -111,6 +112,7 @@
         mScrimBehindAlpha = context.getResources().getFloat(R.dimen.scrim_behind_alpha);
 
         updateHeadsUpScrim(false);
+        updateScrims();
     }
 
     public void setKeyguardShowing(boolean showing) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
index a9eb20b..6361eb6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
@@ -57,12 +57,12 @@
     private static final int LEVEL_MASK = 0xff;
     private static final int NUM_LEVEL_SHIFT = 8;
     private static final int NUM_LEVEL_MASK = 0xff << NUM_LEVEL_SHIFT;
-    private static final int STATE_SHIFT = 16;
-    private static final int STATE_MASK = 0xff << STATE_SHIFT;
-    private static final int STATE_NONE = 0;
-    private static final int STATE_EMPTY = 1;
-    private static final int STATE_CUT = 2;
-    private static final int STATE_CARRIER_CHANGE = 3;
+    public static final int STATE_SHIFT = 16;
+    public static final int STATE_MASK = 0xff << STATE_SHIFT;
+    public static final int STATE_NONE = 0;
+    public static final int STATE_EMPTY = 1;
+    public static final int STATE_CUT = 2;
+    public static final int STATE_CARRIER_CHANGE = 3;
 
     private static final long DOT_DELAY = 1000;
 
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 fbf53e3..79191f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -31,6 +31,7 @@
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
 
+import android.R.style;
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.annotation.NonNull;
@@ -48,10 +49,8 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.IntentSender;
-import android.content.pm.ActivityInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
@@ -95,6 +94,7 @@
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
+import android.view.ContextThemeWrapper;
 import android.view.Display;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -139,7 +139,6 @@
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.PluginFragmentListener;
 import com.android.systemui.keyguard.KeyguardViewMediator;
-import com.android.systemui.pip.phone.PipManager;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
@@ -1119,8 +1118,6 @@
         // Other icons
         mVolumeComponent = getComponent(VolumeComponent.class);
 
-        initEmergencyCryptkeeperText();
-
         mKeyguardBottomArea.setStatusBar(this);
         mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
         if (UserManager.get(mContext).isUserSwitcherEnabled()) {
@@ -1230,24 +1227,6 @@
         });
     }
 
-    private void initEmergencyCryptkeeperText() {
-        View emergencyViewStub = mStatusBarWindow.findViewById(R.id.emergency_cryptkeeper_text);
-        if (mNetworkController.hasEmergencyCryptKeeperText()) {
-            if (emergencyViewStub != null) {
-                ((ViewStub) emergencyViewStub).inflate();
-            }
-            mNetworkController.addCallback(new NetworkController.SignalCallback() {
-                @Override
-                public void setIsAirplaneMode(NetworkController.IconState icon) {
-                    recomputeDisableFlags(true /* animate */);
-                }
-            });
-        } else if (emergencyViewStub != null) {
-            ViewGroup parent = (ViewGroup) emergencyViewStub.getParent();
-            parent.removeView(emergencyViewStub);
-        }
-    }
-
     /**
      * Returns the {@link android.view.View.OnTouchListener} that will be invoked when the
      * background window of the status bar is clicked.
@@ -1357,7 +1336,10 @@
     }
 
     private void inflateDismissView() {
-        mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
+        // Always inflate with a dark theme, since this sits on the scrim.
+        ContextThemeWrapper themedContext = new ContextThemeWrapper(mContext,
+                style.Theme_DeviceDefault);
+        mDismissView = (DismissView) LayoutInflater.from(themedContext).inflate(
                 R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
         mDismissView.setOnButtonClickListener(new View.OnClickListener() {
             @Override
@@ -1829,6 +1811,7 @@
                 updatePublicContentView(ent, ent.notification);
             }
             ent.row.setSensitive(sensitive, deviceSensitive);
+            ent.row.setNeedsRedaction(needsRedaction(ent));
             if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) {
                 ExpandableNotificationRow summary = mGroupManager.getGroupSummary(
                         ent.row.getStatusBarNotification());
@@ -1917,6 +1900,21 @@
         mNotificationIconAreaController.updateNotificationIcons(mNotificationData);
     }
 
+    /** @return true if the entry needs redaction when on the lockscreen. */
+    private boolean needsRedaction(Entry ent) {
+        int userId = ent.notification.getUserId();
+
+        boolean currentUserWantsRedaction = !userAllowsPrivateNotificationsInPublic(mCurrentUserId);
+        boolean notiUserWantsRedaction = !userAllowsPrivateNotificationsInPublic(userId);
+        boolean redactedLockscreen = currentUserWantsRedaction || notiUserWantsRedaction;
+
+        boolean notificationRequestsRedaction =
+                ent.notification.getNotification().visibility == Notification.VISIBILITY_PRIVATE;
+        boolean userForcesRedaction = packageHasVisibilityOverride(ent.notification.getKey());
+
+        return userForcesRedaction || notificationRequestsRedaction && redactedLockscreen;
+    }
+
     /**
      * Disable QS if device not provisioned.
      * If the user switcher is simple then disable QS during setup because
@@ -1927,6 +1925,7 @@
                 && (mUserSetup || mUserSwitcherController == null
                         || !mUserSwitcherController.isSimpleUserSwitcher())
                 && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
+                && !mDozing
                 && !ONLY_CORE_APPS);
     }
 
@@ -4332,6 +4331,7 @@
         mScrimController.setDozing(mDozing);
         mKeyguardIndicationController.setDozing(mDozing);
         mNotificationPanel.setDark(mDozing);
+        updateQsExpansionEnabled();
 
         // Immediately abort the dozing from the doze scrim controller in case of wake-and-unlock
         // for pulsing so the Keyguard fade-out animation scrim can take over.
@@ -5875,6 +5875,9 @@
                 }
 
                 final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
+                if (row.isDark()) {
+                    return false;
+                }
                 bindGuts(row, item);
                 NotificationGuts guts = row.getGuts();
 
@@ -5922,8 +5925,10 @@
                             }
                         });
                         a.start();
-                        guts.setExposed(true /* exposed */,
-                                mState == StatusBarState.KEYGUARD /* needsFalsingProtection */);
+                        final boolean needsFalsingProtection =
+                                (mState == StatusBarState.KEYGUARD &&
+                                !mAccessibilityManager.isTouchExplorationEnabled());
+                        guts.setExposed(true /* exposed */, needsFalsingProtection);
                         row.closeRemoteInput();
                         mStackScroller.onHeightChanged(row, true /* needsAnimation */);
                         mNotificationGutsExposed = guts;
@@ -6174,6 +6179,7 @@
             }
         }
 
+        row.setNeedsRedaction(needsRedaction(entry));
         boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey());
         row.setIsLowPriority(isLowPriority);
         // bind the click event to the content area
@@ -6538,7 +6544,6 @@
         NotificationData.Entry entry = new NotificationData.Entry(sbn);
         Dependency.get(LeakDetector.class).trackInstance(entry);
         entry.createIcons(mContext, sbn);
-
         // Construct the expanded view.
         inflateViews(entry, mStackScroller);
         return entry;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
index a456786..e98dc98 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
@@ -110,30 +110,24 @@
     public void setWifiIndicators(final boolean enabled, final IconState statusIcon,
             final IconState qsIcon, final boolean activityIn, final boolean activityOut,
             final String description, boolean isTransient) {
-        post(new Runnable() {
-            @Override
-            public void run() {
-                for (SignalCallback callback : mSignalCallbacks) {
-                    callback.setWifiIndicators(enabled, statusIcon, qsIcon, activityIn, activityOut,
-                            description, isTransient);
-                }
+        post(() -> {
+            for (SignalCallback callback : mSignalCallbacks) {
+                callback.setWifiIndicators(enabled, statusIcon, qsIcon, activityIn, activityOut,
+                        description, isTransient);
             }
         });
     }
 
     @Override
-    public void setMobileDataIndicators(final IconState statusIcon, final IconState qsIcon,
-            final int statusType, final int qsType,final boolean activityIn,
+    public void setMobileDataIndicators(final IconState statusIcon,
+            final int statusType, final boolean activityIn,
             final boolean activityOut, final String typeContentDescription,
-            final String description, final boolean isWide, final int subId, boolean roaming) {
-        post(new Runnable() {
-            @Override
-            public void run() {
-                for (SignalCallback signalCluster : mSignalCallbacks) {
-                    signalCluster.setMobileDataIndicators(statusIcon, qsIcon, statusType, qsType,
-                            activityIn, activityOut, typeContentDescription, description, isWide,
-                            subId, roaming);
-                }
+            final int subId, boolean roaming, boolean isEmergency) {
+        post(() -> {
+            for (SignalCallback signalCluster : mSignalCallbacks) {
+                signalCluster.setMobileDataIndicators(statusIcon, statusType,
+                        activityIn, activityOut, typeContentDescription,
+                        subId, roaming, isEmergency);
             }
         });
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 67b5596..4421a6a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -244,7 +244,8 @@
             return SignalDrawable.getCarrierChangeState(getNumLevels());
         } else if (mCurrentState.connected) {
             return SignalDrawable.getState(mCurrentState.level, getNumLevels(),
-                    mCurrentState.inetCondition == 0);
+                    mCurrentState.inetCondition == 0 ||
+                            (mCurrentState.dataDisabled && mCurrentState.userSetup));
         } else if (mCurrentState.enabled) {
             return SignalDrawable.getEmptyState(getNumLevels());
         } else {
@@ -263,24 +264,14 @@
 
         String contentDescription = getStringIfExists(getContentDescription());
         String dataContentDescription = getStringIfExists(icons.mDataContentDescription);
-        final boolean dataDisabled = mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED
+        final boolean dataDisabled = mCurrentState.dataDisabled
                 && mCurrentState.userSetup;
 
         // Show icon in QS when we are connected or data is disabled.
-        boolean showDataIcon = mCurrentState.dataConnected || dataDisabled;
+        boolean showDataIcon = mCurrentState.dataConnected;
         IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode,
                 getCurrentIconId(), contentDescription);
 
-        int qsTypeIcon = 0;
-        IconState qsIcon = null;
-        String description = null;
-        // Only send data sim callbacks to QS.
-        if (mCurrentState.dataSim) {
-            qsTypeIcon = showDataIcon ? icons.mQsDataType : 0;
-            qsIcon = new IconState(mCurrentState.enabled
-                    && !mCurrentState.isEmergency, getQsCurrentIconId(), contentDescription);
-            description = mCurrentState.isEmergency ? null : mCurrentState.networkName;
-        }
         boolean activityIn = mCurrentState.dataConnected
                 && !mCurrentState.carrierNetworkChangeMode
                 && mCurrentState.activityIn;
@@ -289,9 +280,10 @@
                 && mCurrentState.activityOut;
         showDataIcon &= mCurrentState.isDefault || dataDisabled;
         int typeIcon = showDataIcon ? icons.mDataType : 0;
-        callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,
-                activityIn, activityOut, dataContentDescription, description, icons.mIsWide,
-                mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming);
+        callback.setMobileDataIndicators(statusIcon, typeIcon,
+                activityIn, activityOut, dataContentDescription,
+                mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming,
+                mCurrentState.isEmergency);
     }
 
     @Override
@@ -438,14 +430,14 @@
         } else {
             mCurrentState.iconGroup = mDefaultIcons;
         }
+        mCurrentState.dataDisabled = isDataDisabled();
         mCurrentState.dataConnected = mCurrentState.connected
-                && mDataState == TelephonyManager.DATA_CONNECTED;
+                && mDataState == TelephonyManager.DATA_CONNECTED
+                && !mCurrentState.dataDisabled;
 
         mCurrentState.roaming = isRoaming();
         if (isCarrierNetworkChangeActive()) {
             mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE;
-        } else if (isDataDisabled()) {
-            mCurrentState.iconGroup = TelephonyIcons.DATA_DISABLED;
         }
         if (isEmergencyOnly() != mCurrentState.isEmergency) {
             mCurrentState.isEmergency = isEmergencyOnly();
@@ -577,6 +569,7 @@
         boolean isDefault;
         boolean userSetup;
         boolean roaming;
+        boolean dataDisabled;
 
         @Override
         public void copyFrom(State s) {
@@ -592,6 +585,7 @@
             carrierNetworkChangeMode = state.carrierNetworkChangeMode;
             userSetup = state.userSetup;
             roaming = state.roaming;
+            dataDisabled = state.dataDisabled;
         }
 
         @Override
@@ -609,6 +603,7 @@
             builder.append("carrierNetworkChangeMode=").append(carrierNetworkChangeMode)
                     .append(',');
             builder.append("userSetup=").append(userSetup);
+            builder.append("dataDisabled=").append(dataDisabled);
         }
 
         @Override
@@ -623,6 +618,7 @@
                     && ((MobileState) o).carrierNetworkChangeMode == carrierNetworkChangeMode
                     && ((MobileState) o).userSetup == userSetup
                     && ((MobileState) o).isDefault == isDefault
+                    && ((MobileState) o).dataDisabled == dataDisabled
                     && ((MobileState) o).roaming == roaming;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index c02ce0e..ab4a8f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -48,9 +48,9 @@
         default void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
                 boolean activityIn, boolean activityOut, String description, boolean isTransient) {}
 
-        default void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
-                int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
-                String description, boolean isWide, int subId, boolean roaming) {}
+        default void setMobileDataIndicators(IconState statusIcon, int statusType,
+                boolean activityIn, boolean activityOut, String typeContentDescription,
+                int subId, boolean roaming, boolean isEmergency) {}
         default void setSubs(List<SubscriptionInfo> subs) {}
         default void setNoSims(boolean show) {}
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index c21f444..60f4ab8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -867,7 +867,6 @@
                             datatype.equals("h") ? TelephonyIcons.H :
                             datatype.equals("lte") ? TelephonyIcons.LTE :
                             datatype.equals("lte+") ? TelephonyIcons.LTE_PLUS :
-                            datatype.equals("dis") ? TelephonyIcons.DATA_DISABLED :
                             TelephonyIcons.UNKNOWN;
                 }
                 if (args.containsKey("roam")) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
index aaa0568..ec7e557 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -44,10 +44,6 @@
     static final int ICON_4G_PLUS = R.drawable.stat_sys_data_fully_connected_4g_plus;
     static final int ICON_1X = R.drawable.stat_sys_data_fully_connected_1x;
 
-    static final int ICON_DATA_DISABLED = R.drawable.stat_sys_data_disabled;
-
-    static final int QS_ICON_DATA_DISABLED = R.drawable.ic_qs_data_disabled;
-
     static final MobileIconGroup CARRIER_NETWORK_CHANGE = new MobileIconGroup(
             "CARRIER_NETWORK_CHANGE",
             null,
@@ -221,20 +217,5 @@
             true,
             TelephonyIcons.QS_DATA_LTE_PLUS
             );
-
-    static final MobileIconGroup DATA_DISABLED = new MobileIconGroup(
-            "DataDisabled",
-            null,
-            null,
-            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH,
-            0, 0,
-            0,
-            0,
-            AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0],
-            R.string.accessibility_cell_data_off,
-            TelephonyIcons.ICON_DATA_DISABLED,
-            false,
-            TelephonyIcons.QS_ICON_DATA_DISABLED
-            );
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
index 374408d..dfc3591 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
@@ -47,6 +47,7 @@
 
     static final int QS_WIFI_NO_NETWORK = R.drawable.ic_qs_wifi_no_network;
     static final int WIFI_NO_NETWORK = R.drawable.stat_sys_wifi_signal_null;
+    static final int WIFI_DISCONNECTED = R.drawable.stat_sys_wifi_signal_disconnected;
 
     static final int WIFI_LEVEL_COUNT = WIFI_SIGNAL_STRENGTH[0].length;
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index 2104cb1..a773acf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -80,7 +80,7 @@
                 AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH,
                 WifiIcons.WIFI_NO_NETWORK,
                 WifiIcons.QS_WIFI_NO_NETWORK,
-                WifiIcons.WIFI_NO_NETWORK,
+                WifiIcons.WIFI_DISCONNECTED,
                 WifiIcons.QS_WIFI_NO_NETWORK,
                 AccessibilityContentDescriptions.WIFI_NO_CONNECTION
                 );
@@ -133,8 +133,7 @@
     @Override
     public void notifyListeners(SignalCallback callback) {
         // only show wifi in the cluster if connected or if wifi-only
-        boolean wifiVisible = mCurrentState.enabled
-                && (mCurrentState.connected || !mHasMobileData);
+        boolean wifiVisible = true;
         String wifiDesc = wifiVisible ? mCurrentState.ssid : null;
         boolean ssidPresent = wifiVisible && mCurrentState.ssid != null;
         String contentDescription = getStringIfExists(getContentDescription());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
index 3ed1681..f6c75a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
@@ -114,33 +114,26 @@
         boolean wide = true;
         int subId = 5;
         boolean roaming = true;
-        mHandler.setMobileDataIndicators(status, qs, type, qsType, in, out, typeDescription,
-                description, wide, subId, roaming);
+        boolean isEmergency = true;
+        mHandler.setMobileDataIndicators(status, type, in, out, typeDescription,
+                subId, roaming, isEmergency);
         waitForCallbacks();
 
         ArgumentCaptor<IconState> statusArg = ArgumentCaptor.forClass(IconState.class);
-        ArgumentCaptor<IconState> qsArg = ArgumentCaptor.forClass(IconState.class);
         ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
-        ArgumentCaptor<Integer> qsTypeIconArg = ArgumentCaptor.forClass(Integer.class);
         ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class);
         ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class);
         ArgumentCaptor<String> typeContentArg = ArgumentCaptor.forClass(String.class);
-        ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class);
-        ArgumentCaptor<Boolean> wideArg = ArgumentCaptor.forClass(Boolean.class);
         ArgumentCaptor<Integer> subIdArg = ArgumentCaptor.forClass(Integer.class);
         Mockito.verify(mSignalCallback).setMobileDataIndicators(statusArg.capture(),
-                qsArg.capture(), typeIconArg.capture(), qsTypeIconArg.capture(), inArg.capture(),
-                outArg.capture(), typeContentArg.capture(), descArg.capture(), wideArg.capture(),
-                subIdArg.capture(), eq(roaming));
+                typeIconArg.capture(), inArg.capture(),
+                outArg.capture(), typeContentArg.capture(),
+                subIdArg.capture(), eq(roaming), eq(isEmergency));
         assertEquals(status, statusArg.getValue());
-        assertEquals(qs, qsArg.getValue());
         assertEquals(type, (int) typeIconArg.getValue());
-        assertEquals(qsType, (int) qsTypeIconArg.getValue());
         assertEquals(in, (boolean) inArg.getValue());
         assertEquals(out, (boolean) outArg.getValue());
         assertEquals(typeDescription, typeContentArg.getValue());
-        assertEquals(description, descArg.getValue());
-        assertEquals(wide, (boolean) wideArg.getValue());
         assertEquals(subId, (int) subIdArg.getValue());
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 505e1d8..b39171e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -29,6 +29,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.Log;
+
 import com.android.internal.telephony.cdma.EriInfo;
 import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.statusbar.phone.SignalDrawable;
@@ -45,8 +46,6 @@
 import org.junit.runner.Description;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -70,7 +69,7 @@
     protected static final int DEFAULT_SIGNAL_STRENGTH = DEFAULT_LEVEL;
     protected static final int DEFAULT_QS_SIGNAL_STRENGTH = DEFAULT_LEVEL;
     protected static final int DEFAULT_ICON = TelephonyIcons.ICON_3G;
-    protected static final int DEFAULT_QS_ICON = TelephonyIcons.QS_DATA_3G;
+    protected static final int DEFAULT_QS_ICON = DEFAULT_ICON;
 
     protected NetworkControllerImpl mNetworkController;
     protected MobileSignalController mMobileSignalController;
@@ -117,7 +116,7 @@
 
         when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true);
         when(mMockCm.getDefaultNetworkCapabilitiesForUser(0)).thenReturn(
-                new NetworkCapabilities[] { mNetCapabilities });
+                new NetworkCapabilities[]{mNetCapabilities});
 
         mSignalStrength = mock(SignalStrength.class);
         mServiceState = mock(ServiceState.class);
@@ -175,17 +174,17 @@
     }
 
     protected NetworkControllerImpl setUpNoMobileData() {
-      when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
-      NetworkControllerImpl networkControllerNoMobile
-              = new NetworkControllerImpl(mContext, mMockCm, mMockNetworkScoreManager, mMockTm,
-                        mMockWm, mMockSm, mConfig, mContext.getMainLooper(), mCallbackHandler,
-                        mock(AccessPointControllerImpl.class),
-                        mock(DataUsageController.class), mMockSubDefaults,
-                        mock(DeviceProvisionedController.class));
+        when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
+        NetworkControllerImpl networkControllerNoMobile
+                = new NetworkControllerImpl(mContext, mMockCm, mMockNetworkScoreManager, mMockTm,
+                mMockWm, mMockSm, mConfig, mContext.getMainLooper(), mCallbackHandler,
+                mock(AccessPointControllerImpl.class),
+                mock(DataUsageController.class), mMockSubDefaults,
+                mock(DeviceProvisionedController.class));
 
-      setupNetworkController();
+        setupNetworkController();
 
-      return networkControllerNoMobile;
+        return networkControllerNoMobile;
 
     }
 
@@ -308,11 +307,10 @@
         ArgumentCaptor<Boolean> dataOutArg = ArgumentCaptor.forClass(Boolean.class);
 
         Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
-                    any(),
-                    iconArg.capture(),
-                    anyInt(),
-                    typeIconArg.capture(), dataInArg.capture(), dataOutArg.capture(),
-                    anyString(), anyString(), anyBoolean(), anyInt(), anyBoolean());
+                iconArg.capture(),
+                typeIconArg.capture(),
+                dataInArg.capture(), dataOutArg.capture(),
+                anyString(), anyInt(), anyBoolean(), anyBoolean());
         IconState iconState = iconArg.getValue();
         int state = SignalDrawable.getState(icon, SignalStrength.NUM_SIGNAL_STRENGTH_BINS,
                 false);
@@ -335,17 +333,16 @@
     }
 
     protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon,
-        boolean roaming, boolean inet) {
+            boolean roaming, boolean inet) {
         ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
         ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
 
         // TODO: Verify all fields.
         Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
                 iconArg.capture(),
-                any(),
                 typeIconArg.capture(),
-                anyInt(), anyBoolean(), anyBoolean(), anyString(), anyString(), anyBoolean(),
-                anyInt(), eq(roaming));
+                anyBoolean(), anyBoolean(), anyString(),
+                anyInt(), eq(roaming), anyBoolean());
         IconState iconState = iconArg.getValue();
 
         int state = icon == -1 ? 0
@@ -356,22 +353,18 @@
     }
 
     protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon,
-            boolean qsVisible, int qsIcon, int qsTypeIcon, boolean dataIn, boolean dataOut) {
+            boolean qsVisible, boolean dataIn, boolean dataOut) {
         ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
         ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
-        ArgumentCaptor<IconState> qsIconArg = ArgumentCaptor.forClass(IconState.class);
-        ArgumentCaptor<Integer> qsTypeIconArg = ArgumentCaptor.forClass(Integer.class);
         ArgumentCaptor<Boolean> dataInArg = ArgumentCaptor.forClass(Boolean.class);
         ArgumentCaptor<Boolean> dataOutArg = ArgumentCaptor.forClass(Boolean.class);
 
         Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
                 iconArg.capture(),
-                qsIconArg.capture(),
                 typeIconArg.capture(),
-                qsTypeIconArg.capture(),
                 dataInArg.capture(),
                 dataOutArg.capture(),
-                anyString(), anyString(), anyBoolean(), anyInt(), anyBoolean());
+                anyString(), anyInt(), anyBoolean(), anyBoolean());
 
         IconState iconState = iconArg.getValue();
 
@@ -381,17 +374,15 @@
         assertEquals("Signal icon in status bar", state, iconState.icon);
         assertEquals("Visibility in status bar", visible, iconState.visible);
 
-        iconState = qsIconArg.getValue();
         assertEquals("Visibility in quick settings", qsVisible, iconState.visible);
         assertEquals("Signal icon in quick settings", state, iconState.icon);
-        assertEquals("Data icon in quick settings", qsTypeIcon, (int) qsTypeIconArg.getValue());
         assertEquals("Data direction in in quick settings", dataIn,
                 (boolean) dataInArg.getValue());
         assertEquals("Data direction out in quick settings", dataOut,
                 (boolean) dataOutArg.getValue());
     }
 
-   protected void assertNetworkNameEquals(String expected) {
-       assertEquals("Network name", expected, mMobileSignalController.getState().networkName);
-   }
+    protected void assertNetworkNameEquals(String expected) {
+        assertEquals("Network name", expected, mMobileSignalController.getState().networkName);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index dfe00f9..6470c11 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -1,5 +1,9 @@
 package com.android.systemui.statusbar.policy;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -11,10 +15,14 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.settingslib.net.DataUsageController;
+import com.android.systemui.statusbar.phone.SignalDrawable;
+import com.android.systemui.statusbar.policy.NetworkController.IconState;
 
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -116,8 +124,11 @@
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
         setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
 
-        verifyDataIndicators(TelephonyIcons.ICON_DATA_DISABLED,
-                TelephonyIcons.QS_ICON_DATA_DISABLED);
+        ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
+        Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
+                iconArg.capture(), anyInt(), anyBoolean(), anyBoolean(), any(), anyInt(),
+                anyBoolean(), anyBoolean());
+        assertEquals(SignalDrawable.STATE_CUT, SignalDrawable.getState(iconArg.getValue().icon));
     }
 
     @Test
@@ -129,9 +140,14 @@
         setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
         when(mMockProvisionController.isUserSetup(anyInt())).thenReturn(false);
         mUserCallback.onUserSetupChanged();
+        waitForIdleSync();
 
         // Don't show the X until the device is setup.
-        verifyDataIndicators(0, 0);
+        ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
+        Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
+                iconArg.capture(), anyInt(), anyBoolean(), anyBoolean(), any(), anyInt(),
+                anyBoolean(), anyBoolean());
+        assertNotEquals(SignalDrawable.STATE_CUT, SignalDrawable.getState(iconArg.getValue().icon));
     }
 
     @Test
@@ -181,12 +197,12 @@
         updateDataActivity(direction);
 
         verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, DEFAULT_ICON, true,
-                DEFAULT_QS_SIGNAL_STRENGTH, DEFAULT_QS_ICON, in, out);
+                in, out);
     }
 
     private void verifyDataIndicators(int dataIcon, int qsDataIcon) {
         verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, dataIcon,
-                true, DEFAULT_QS_SIGNAL_STRENGTH, qsDataIcon, false,
+                true, false,
                 false);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 1627925..e542c37 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -214,7 +214,7 @@
 
             verifyLastQsMobileDataIndicators(true,
                     testStrength,
-                    TelephonyIcons.QS_DATA_1X, false, false);
+                    TelephonyIcons.ICON_1X, false, false);
         }
     }
 
@@ -434,7 +434,7 @@
 
       verifyLastQsMobileDataIndicators(true /* visible */,
               DEFAULT_LEVEL /* icon */,
-              DEFAULT_QS_ICON /* typeIcon */,
+              DEFAULT_ICON /* typeIcon */,
               false /* dataIn */,
               true /* dataOut */);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
index 73fa5aa1..edfa326 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -62,7 +62,7 @@
     public void testWifiIcon() {
         String testSsid = "Test SSID";
         setWifiEnabled(true);
-        verifyLastWifiIcon(false, WifiIcons.WIFI_NO_NETWORK);
+        verifyLastWifiIcon(true, WifiIcons.WIFI_DISCONNECTED);
 
         setWifiState(true, testSsid);
         verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[0][0]);
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 5feb81d..7c3f324 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -68,6 +68,7 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Map;
 import java.util.Map.Entry;
 
@@ -220,6 +221,9 @@
         synchronized (mLock) {
             mActivityToken = newActivity;
             mClient = IAutoFillManagerClient.Stub.asInterface(newClient);
+
+            // The tracked id are not persisted in the client, hence update them
+            updateTrackedIdsLocked();
         }
     }
 
@@ -749,6 +753,38 @@
         }
     }
 
+    private void updateTrackedIdsLocked() {
+        if (mResponses == null || mResponses.size() == 0) {
+            return;
+        }
+
+        // Only track the views of the last response as only those are reported back to the
+        // service, see #showSaveLocked
+        ArrayList<AutofillId> trackedViews = new ArrayList<>();
+        boolean saveOnAllViewsInvisible = false;
+        SaveInfo saveInfo = mResponses.valueAt(getLastResponseIndex()).getSaveInfo();
+        if (saveInfo != null) {
+            saveOnAllViewsInvisible = saveInfo.saveOnAllViewsInvisible();
+
+            // We only need to track views if we want to save once they become invisible.
+            if (saveOnAllViewsInvisible) {
+                if (saveInfo.getRequiredIds() != null) {
+                    Collections.addAll(trackedViews, saveInfo.getRequiredIds());
+                }
+
+                if (saveInfo.getOptionalIds() != null) {
+                    Collections.addAll(trackedViews, saveInfo.getOptionalIds());
+                }
+            }
+        }
+
+        try {
+            mClient.setTrackedViews(id, trackedViews, saveOnAllViewsInvisible);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Cannot set tracked ids", e);
+        }
+    }
+
     private void processResponseLocked(FillResponse response, int requestId) {
         if (DEBUG) {
             Slog.d(TAG, "processResponseLocked(mCurrentViewId=" + mCurrentViewId + "):" + response);
@@ -763,6 +799,7 @@
         }
 
         setViewStatesLocked(response, ViewState.STATE_FILLABLE);
+        updateTrackedIdsLocked();
 
         if (mCurrentViewId == null) {
             return;
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index d647c63..aa5083d 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -798,6 +798,19 @@
         return ((app.flags & ApplicationInfo.FLAG_STOPPED) != 0);
     }
 
+    // We also avoid backups of 'disabled' apps
+    private static boolean appIsDisabled(ApplicationInfo app, PackageManager pm) {
+        switch (pm.getApplicationEnabledSetting(app.packageName)) {
+            case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
+            case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
+            case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
     /* does *not* check overall backup eligibility policy! */
     private static boolean appGetsFullBackup(PackageInfo pkg) {
         if (pkg.applicationInfo.backupAgentName != null) {
@@ -10774,7 +10787,8 @@
             PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName,
                     PackageManager.GET_SIGNATURES);
             if (!appIsEligibleForBackup(packageInfo.applicationInfo) ||
-                    appIsStopped(packageInfo.applicationInfo)) {
+                    appIsStopped(packageInfo.applicationInfo) ||
+                    appIsDisabled(packageInfo.applicationInfo, mPackageManager)) {
                 return false;
             }
             IBackupTransport transport = mTransportManager.getCurrentTransportBinder();
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 39bfeda..8ad3d23 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -49,6 +49,7 @@
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
 
+import android.annotation.BinderThread;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -2146,6 +2147,7 @@
         return mKeyguardManager != null && mKeyguardManager.isKeyguardLocked();
     }
 
+    @BinderThread
     @SuppressWarnings("deprecation")
     @Override
     public void setImeWindowStatus(IBinder token, IBinder startInputToken, int vis,
@@ -2161,9 +2163,23 @@
             mBackDisposition = backDisposition;
             updateSystemUiLocked(token, vis, backDisposition);
         }
+
+        final boolean dismissImeOnBackKeyPressed;
+        switch (backDisposition) {
+            case InputMethodService.BACK_DISPOSITION_WILL_DISMISS:
+                dismissImeOnBackKeyPressed = true;
+                break;
+            case InputMethodService.BACK_DISPOSITION_WILL_NOT_DISMISS:
+                dismissImeOnBackKeyPressed = false;
+                break;
+            default:
+            case InputMethodService.BACK_DISPOSITION_DEFAULT:
+                dismissImeOnBackKeyPressed = ((vis & InputMethodService.IME_VISIBLE) != 0);
+                break;
+        }
         mWindowManagerInternal.updateInputMethodWindowStatus(token,
                 (vis & InputMethodService.IME_VISIBLE) != 0,
-                info != null ? info.mTargetWindow : null);
+                dismissImeOnBackKeyPressed, info != null ? info.mTargetWindow : null);
     }
 
     private void updateSystemUi(IBinder token, int vis, int backDisposition) {
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index d796098..452fe1d 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3272,6 +3272,8 @@
         try {
             return mContext.getSystemService(StorageStatsManager.class)
                     .queryStatsForUid(volumeUuid, uid).getCacheBytes();
+        } catch (IOException e) {
+            throw new ParcelableException(e);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -3312,6 +3314,8 @@
                     return Math.max(0, path.getUsableSpace() - storage.getStorageLowBytes(path));
                 }
             }
+        } catch (IOException e) {
+            throw new ParcelableException(e);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -3329,13 +3333,13 @@
                     + " because only " + allocatableBytes + " allocatable"));
         }
 
-        // Free up enough disk space to satisfy both the requested allocation
-        // and our low disk warning space.
-        final File path = storage.findPathForUuid(volumeUuid);
-        bytes += storage.getStorageLowBytes(path);
-
         final long token = Binder.clearCallingIdentity();
         try {
+            // Free up enough disk space to satisfy both the requested allocation
+            // and our low disk warning space.
+            final File path = storage.findPathForUuid(volumeUuid);
+            bytes += storage.getStorageLowBytes(path);
+
             mPms.freeStorage(volumeUuid, bytes, flags);
         } catch (IOException e) {
             throw new ParcelableException(e);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index c77820b..2cd14e9 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -312,8 +312,7 @@
     }
 
     ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
-            int id, Notification notification, int callingPid, int callingUid,
-            boolean fgRequired, String callingPackage, final int userId)
+            int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
             throws TransactionTooLargeException {
         if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
                 + " type=" + resolvedType + " args=" + service.getExtras());
@@ -464,10 +463,6 @@
         }
 
         ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
-        // STOPSHIP deprecated; remove when NotificationManager.startServiceInForeground is retired
-        if (notification != null) {
-            setServiceForegroundInnerLocked(r, id, notification, 0);
-        }
         return cmp;
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6b0a73b..d43fa01 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1230,6 +1230,20 @@
      */
     int[] mDeviceIdleTempWhitelist = new int[0];
 
+    static final class PendingTempWhitelist {
+        final int targetUid;
+        final long duration;
+        final String tag;
+
+        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
+            targetUid = _targetUid;
+            duration = _duration;
+            tag = _tag;
+        }
+    }
+
+    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
+
     /**
      * Information about and control over application operations
      */
@@ -1688,6 +1702,7 @@
     static final int NOTIFY_VR_SLEEPING_MSG = 65;
     static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
     static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
+    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
     static final int START_USER_SWITCH_FG_MSG = 712;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
@@ -1921,6 +1936,9 @@
             case DISPATCH_UIDS_CHANGED_UI_MSG: {
                 dispatchUidsChanged();
             } break;
+            case PUSH_TEMP_WHITELIST_UI_MSG: {
+                pushTempWhitelist();
+            } break;
             }
         }
     }
@@ -6493,7 +6511,8 @@
             // This is the first appearance of the uid, report it now!
             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
                     "Creating new process uid: " + uidRec);
-            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0) {
+            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
+                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
                 uidRec.setWhitelist = uidRec.curWhitelist = true;
             }
             uidRec.updateHasInternetPermission();
@@ -7487,43 +7506,6 @@
         }
     }
 
-    /**
-     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
-     */
-    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
-        if (DEBUG_WHITELISTS) {
-            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
-                    + targetUid + ", " + duration + ")");
-        }
-
-        if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
-                != PackageManager.PERMISSION_GRANTED) {
-            synchronized (mPidsSelfLocked) {
-                final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
-                if (pr == null) {
-                    Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid "
-                            + callerPid);
-                    return;
-                }
-                if (!pr.whitelistManager) {
-                    if (DEBUG_WHITELISTS) {
-                        Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid
-                                + ": pid " + callerPid + " is not allowed");
-                    }
-                    return;
-                }
-            }
-        }
-
-        final long token = Binder.clearCallingIdentity();
-        try {
-            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
-                    true, "pe from uid:" + callerUid);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
     @Override
     public void cancelIntentSender(IIntentSender sender) {
         if (!(sender instanceof PendingIntentRecord)) {
@@ -7863,7 +7845,14 @@
                     r.pictureInPictureArgs.copyOnlySet(args);
                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
-                    final Rect sourceBounds = r.pictureInPictureArgs.getSourceRectHint();
+                    // Adjust the source bounds by the insets for the transition down
+                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
+                    final Rect insets = r.pictureInPictureArgs.getSourceRectHintInsets();
+                    if (insets != null) {
+                        sourceBounds.offsetTo(Math.max(0, sourceBounds.left - insets.left),
+                                Math.max(0, sourceBounds.top - insets.top));
+                    }
+
                     mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
                             true /* moveHomeStackToFront */, "enterPictureInPictureMode");
                     final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
@@ -8412,7 +8401,8 @@
     boolean isOnDeviceIdleWhitelistLocked(int uid) {
         final int appId = UserHandle.getAppId(uid);
         return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
-                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0;
+                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
+                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
     }
 
     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
@@ -10535,8 +10525,9 @@
                         final PinnedActivityStack pinnedStack =
                                 mStackSupervisor.getStack(PINNED_STACK_ID);
                         if (pinnedStack != null) {
-                            pinnedStack.animateResizePinnedStack(null /* sourceBounds */,
-                                    destBounds, animationDuration);
+                            pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
+                                    destBounds, animationDuration,
+                                    false /* schedulePipModeChangedOnAnimationEnd */);
                         }
                     } else {
                         throw new IllegalArgumentException("Stack: " + stackId
@@ -15587,6 +15578,18 @@
             }
             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
+            if (mPendingTempWhitelist.size() > 0) {
+                pw.println("  mPendingTempWhitelist:");
+                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
+                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
+                    pw.print("    ");
+                    UserHandle.formatUid(pw, ptw.targetUid);
+                    pw.print(": ");
+                    TimeUtils.formatDuration(ptw.duration, pw);
+                    pw.print(" ");
+                    pw.println(ptw.tag);
+                }
+            }
         }
         if (dumpPackage == null) {
             pw.println("  mWakefulness="
@@ -17928,8 +17931,7 @@
 
     @Override
     public ComponentName startService(IApplicationThread caller, Intent service,
-            String resolvedType, int id, Notification notification, boolean requireForeground,
-            String callingPackage, int userId)
+            String resolvedType, boolean requireForeground, String callingPackage, int userId)
             throws TransactionTooLargeException {
         enforceNotIsolatedCaller("startService");
         // Refuse possible leaked file descriptors
@@ -17950,7 +17952,7 @@
             ComponentName res;
             try {
                 res = mServices.startServiceLocked(caller, service,
-                        resolvedType, id, notification, callingPid, callingUid,
+                        resolvedType, callingPid, callingUid,
                         requireForeground, callingPackage, userId);
             } finally {
                 Binder.restoreCallingIdentity(origId);
@@ -17969,7 +17971,7 @@
             ComponentName res;
             try {
                 res = mServices.startServiceLocked(null, service,
-                        resolvedType, 0, null, -1, uid, fgRequired, callingPackage, userId);
+                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
             } finally {
                 Binder.restoreCallingIdentity(origId);
             }
@@ -22699,6 +22701,80 @@
         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
     }
 
+    /**
+     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
+     */
+    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
+            long duration, String tag) {
+        if (DEBUG_WHITELISTS) {
+            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
+                    + targetUid + ", " + duration + ")");
+        }
+
+        synchronized (mPidsSelfLocked) {
+            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
+            if (pr == null) {
+                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
+                        + callerPid);
+                return;
+            }
+            if (!pr.whitelistManager) {
+                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
+                        != PackageManager.PERMISSION_GRANTED) {
+                    if (DEBUG_WHITELISTS) {
+                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
+                                + ": pid " + callerPid + " is not allowed");
+                    }
+                    return;
+                }
+            }
+        }
+
+        tempWhitelistUidLocked(targetUid, duration, tag);
+    }
+
+    /**
+     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
+     */
+    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
+        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
+        setUidTempWhitelistStateLocked(targetUid, true);
+        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
+    }
+
+    void pushTempWhitelist() {
+        final int N;
+        final PendingTempWhitelist[] list;
+
+        // First copy out the pending changes...  we need to leave them in the map for now,
+        // in case someone needs to check what is coming up while we don't have the lock held.
+        synchronized(this) {
+            N = mPendingTempWhitelist.size();
+            list = new PendingTempWhitelist[N];
+            for (int i = 0; i < N; i++) {
+                list[i] = mPendingTempWhitelist.valueAt(i);
+            }
+        }
+
+        // Now safely dispatch changes to device idle controller.
+        for (int i = 0; i < N; i++) {
+            PendingTempWhitelist ptw = list[i];
+            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
+                    ptw.duration, true, ptw.tag);
+        }
+
+        // And now we can safely remove them from the map.
+        synchronized(this) {
+            for (int i = 0; i < N; i++) {
+                PendingTempWhitelist ptw = list[i];
+                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
+                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
+                    mPendingTempWhitelist.removeAt(index);
+                }
+            }
+        }
+    }
+
     final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
         boolean changed = false;
         for (int i=mActiveUids.size()-1; i>=0; i--) {
@@ -22713,6 +22789,15 @@
         }
     }
 
+    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
+        boolean changed = false;
+        final UidRecord uidRec = mActiveUids.get(uid);
+        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
+            uidRec.curWhitelist = onWhitelist;
+            updateOomAdjLocked();
+        }
+    }
+
     final void trimApplications() {
         synchronized (this) {
             int i;
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 0fcf3e6..b6bfb00 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -524,7 +524,7 @@
         pw.println("Starting service: " + intent);
         pw.flush();
         ComponentName cn = mInterface.startService(null, intent, intent.getType(),
-                -1, null, asForeground, SHELL_PACKAGE_NAME, mUserId);
+                asForeground, SHELL_PACKAGE_NAME, mUserId);
         if (cn == null) {
             err.println("Error: Not found; no service started.");
             return -1;
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index 2881787..494aaa7 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -314,7 +314,8 @@
             builder.setPackageName(info.launchedActivity.packageName);
             builder.setType(type);
             builder.addTaggedData(FIELD_CLASS_NAME, info.launchedActivity.info.name);
-            if (info.launchedActivity.launchedFromPackage != null) {
+            final boolean isInstantApp = info.launchedActivity.info.applicationInfo.isInstantApp();
+            if (isInstantApp && info.launchedActivity.launchedFromPackage != null) {
                 builder.addTaggedData(APP_TRANSITION_CALLING_PACKAGE_NAME,
                         info.launchedActivity.launchedFromPackage);
             }
@@ -323,8 +324,7 @@
                         info.launchedActivity.info.launchToken);
                 info.launchedActivity.info.launchToken = null;
             }
-            builder.addTaggedData(APP_TRANSITION_IS_EPHEMERAL,
-                    info.launchedActivity.info.applicationInfo.isInstantApp() ? 1 : 0);
+            builder.addTaggedData(APP_TRANSITION_IS_EPHEMERAL, isInstantApp ? 1 : 0);
             builder.addTaggedData(APP_TRANSITION_DEVICE_UPTIME_SECONDS,
                     mCurrentTransitionDeviceUptime);
             builder.addTaggedData(APP_TRANSITION_DELAY_MS, mCurrentTransitionDelayMs);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 4c84d98..825e8ac 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -589,6 +589,13 @@
     }
 
     /**
+     * Returns whether to defer the scheduling of the multi-window mode.
+     */
+    boolean deferScheduleMultiWindowModeChanged() {
+        return false;
+    }
+
+    /**
      * Defers updating the bounds of the stack. If the stack was resized/repositioned while
      * deferring, the bounds will update in {@link #continueUpdateBounds()}.
      */
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 4d16e33..43ae4b2 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2504,7 +2504,7 @@
         // incorrect if AMS.resizeStackWithBoundsFromWindowManager() is already called while waiting
         // for the AMS lock to be freed. So check and make sure these bounds are still good.
         final PinnedStackWindowController stackController = stack.getWindowContainerController();
-        if (stackController.pinnedStackResizeAllowed()) {
+        if (stackController.pinnedStackResizeDisallowed()) {
             return;
         }
 
@@ -2873,7 +2873,7 @@
         return true;
     }
 
-    void moveActivityToPinnedStackLocked(ActivityRecord r, Rect sourceBounds, float aspectRatio,
+    void moveActivityToPinnedStackLocked(ActivityRecord r, Rect sourceHintBounds, float aspectRatio,
             boolean moveHomeStackToFront, String reason) {
 
         mWindowManager.deferSurfaceLayout();
@@ -2948,11 +2948,8 @@
         final Rect destBounds = mWindowManager.getPictureInPictureBounds(DEFAULT_DISPLAY,
                 aspectRatio, false /* useExistingStackBounds */);
 
-        // TODO(b/36099777): Schedule the PiP mode change here immediately until we can defer all
-        // callbacks until after the bounds animation
-        scheduleUpdatePictureInPictureModeIfNeeded(r.getTask(), destBounds, true /* immediate */);
-
-        stack.animateResizePinnedStack(sourceBounds, destBounds, -1 /* animationDuration */);
+        stack.animateResizePinnedStack(sourceHintBounds, destBounds, -1 /* animationDuration */,
+                true /* schedulePipModeChangedOnAnimationEnd */);
         mService.mTaskChangeNotificationController.notifyActivityPinned(r.packageName);
     }
 
@@ -4179,6 +4176,12 @@
     }
 
     void scheduleUpdateMultiWindowMode(TaskRecord task) {
+        // If the stack is animating in a way where we will be forcing a multi-mode change at the
+        // end, then ensure that we defer all in between multi-window mode changes
+        if (task.getStack().deferScheduleMultiWindowModeChanged()) {
+            return;
+        }
+
         for (int i = task.mActivities.size() - 1; i >= 0; i--) {
             final ActivityRecord r = task.mActivities.get(i);
             if (r.app != null && r.app.thread != null) {
diff --git a/services/core/java/com/android/server/am/AppErrorDialog.java b/services/core/java/com/android/server/am/AppErrorDialog.java
index 02ec075..c9c1d00 100644
--- a/services/core/java/com/android/server/am/AppErrorDialog.java
+++ b/services/core/java/com/android/server/am/AppErrorDialog.java
@@ -148,18 +148,7 @@
 
     private final Handler mHandler = new Handler() {
         public void handleMessage(Message msg) {
-            final int result = msg.what;
-
-            synchronized (mService) {
-                if (mProc != null && mProc.crashDialog == AppErrorDialog.this) {
-                    mProc.crashDialog = null;
-                }
-            }
-            mResult.set(result);
-
-            // Make sure we don't have time timeout still hanging around.
-            removeMessages(TIMEOUT);
-
+            setResult(msg.what);
             dismiss();
         }
     };
@@ -168,11 +157,23 @@
     public void dismiss() {
         if (!mResult.mHasResult) {
             // We are dismissing and the result has not been set...go ahead and set.
-            mResult.set(FORCE_QUIT);
+            setResult(FORCE_QUIT);
         }
         super.dismiss();
     }
 
+    private void setResult(int result) {
+        synchronized (mService) {
+            if (mProc != null && mProc.crashDialog == AppErrorDialog.this) {
+                mProc.crashDialog = null;
+            }
+        }
+        mResult.set(result);
+
+        // Make sure we don't have time timeout still hanging around.
+        mHandler.removeMessages(TIMEOUT);
+    }
+
     @Override
     public void onClick(View v) {
         switch (v.getId()) {
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index baa71d7..349180f 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -155,8 +155,6 @@
 
     static final int BROADCAST_INTENT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG;
     static final int BROADCAST_TIMEOUT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG + 1;
-    static final int SCHEDULE_TEMP_WHITELIST_MSG
-            = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG + 2;
 
     final BroadcastHandler mHandler;
 
@@ -178,13 +176,6 @@
                         broadcastTimeoutLocked(true);
                     }
                 } break;
-                case SCHEDULE_TEMP_WHITELIST_MSG: {
-                    DeviceIdleController.LocalService dic = mService.mLocalDeviceIdleController;
-                    if (dic != null) {
-                        dic.addPowerSaveTempWhitelistAppDirect(UserHandle.getAppId(msg.arg1),
-                                msg.arg2, true, (String)msg.obj);
-                    }
-                } break;
             }
         }
     }
@@ -789,12 +780,11 @@
         if (r.intent.getAction() != null) {
             b.append(r.intent.getAction());
         } else if (r.intent.getComponent() != null) {
-            b.append(r.intent.getComponent().flattenToShortString());
+            r.intent.getComponent().appendShortString(b);
         } else if (r.intent.getData() != null) {
             b.append(r.intent.getData());
         }
-        mHandler.obtainMessage(SCHEDULE_TEMP_WHITELIST_MSG, uid, (int)duration, b.toString())
-                .sendToTarget();
+        mService.tempWhitelistUidLocked(uid, duration, b.toString());
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index c697f28..a580d4b 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -237,14 +237,6 @@
         if (intent != null) intent.setDefusable(true);
         if (options != null) options.setDefusable(true);
 
-        if (whitelistDuration > 0 && !canceled) {
-            // Must call before acquiring the lock. It's possible the method return before sending
-            // the intent due to some validations inside the lock, in which case the UID shouldn't
-            // be whitelisted, but since the whitelist is temporary, that would be ok.
-            owner.tempWhitelistAppForPowerSave(Binder.getCallingPid(), Binder.getCallingUid(), uid,
-                    whitelistDuration);
-        }
-
         synchronized (owner) {
             final ActivityContainer activityContainer = (ActivityContainer)container;
             if (activityContainer != null && activityContainer.mParentActivity != null &&
@@ -279,6 +271,22 @@
                     resolvedType = key.requestResolvedType;
                 }
 
+                if (whitelistDuration > 0) {
+                    StringBuilder tag = new StringBuilder(64);
+                    tag.append("pendingintent:");
+                    UserHandle.formatUid(tag, Binder.getCallingUid());
+                    tag.append(":");
+                    if (finalIntent.getAction() != null) {
+                        tag.append(finalIntent.getAction());
+                    } else if (finalIntent.getComponent() != null) {
+                        finalIntent.getComponent().appendShortString(tag);
+                    } else if (finalIntent.getData() != null) {
+                        tag.append(finalIntent.getData());
+                    }
+                    owner.tempWhitelistForPendingIntentLocked(Binder.getCallingPid(),
+                            Binder.getCallingUid(), uid, whitelistDuration, tag.toString());
+                }
+
                 final long origId = Binder.clearCallingIdentity();
 
                 boolean sendFinish = finishedReceiver != null;
diff --git a/services/core/java/com/android/server/am/PinnedActivityStack.java b/services/core/java/com/android/server/am/PinnedActivityStack.java
index cd9c42c..a4932bb 100644
--- a/services/core/java/com/android/server/am/PinnedActivityStack.java
+++ b/services/core/java/com/android/server/am/PinnedActivityStack.java
@@ -43,9 +43,10 @@
         return new PinnedStackWindowController(mStackId, this, displayId, onTop, outBounds);
     }
 
-    void animateResizePinnedStack(Rect sourceBounds, Rect destBounds, int animationDuration) {
-        getWindowContainerController().animateResizePinnedStack(sourceBounds, destBounds,
-                animationDuration);
+    void animateResizePinnedStack(Rect sourceHintBounds, Rect toBounds, int animationDuration,
+            boolean schedulePipModeChangedOnAnimationEnd) {
+        getWindowContainerController().animateResizePinnedStack(toBounds, sourceHintBounds,
+                animationDuration, schedulePipModeChangedOnAnimationEnd);
     }
 
     void setPictureInPictureAspectRatio(float aspectRatio) {
@@ -60,7 +61,18 @@
         return getWindowContainerController().isAnimatingBoundsToFullscreen();
     }
 
-    @Override
+    /**
+     * Returns whether to defer the scheduling of the multi-window mode.
+     */
+    boolean deferScheduleMultiWindowModeChanged() {
+        // For the pinned stack, the deferring of the multi-window mode changed is tied to the
+        // transition animation into picture-in-picture, and is called once the animation completes,
+        // or is interrupted in a way that would leave the stack in a non-fullscreen state.
+        // @see BoundsAnimationController
+        // @see BoundsAnimationControllerTests
+        return mWindowContainerController.deferScheduleMultiWindowModeChanged();
+    }
+
     public void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {
         // It is guaranteed that the activities requiring the update will be in the pinned stack at
         // this point (either reparented before the animation into PiP, or before reparenting after
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 2687242..e7617f5 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -929,11 +929,8 @@
         synchronized (VolumeStreamState.class) {
             int numStreamTypes = AudioSystem.getNumStreamTypes();
             for (int streamType = 0; streamType < numStreamTypes; streamType++) {
-                if (streamType != mStreamVolumeAlias[streamType]) {
-                    mStreamStates[streamType].
-                                    setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]],
-                                            TAG);
-                }
+                mStreamStates[streamType]
+                        .setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]], TAG);
                 // apply stream volume
                 if (!mStreamStates[streamType].mIsMuted) {
                     mStreamStates[streamType].applyAllVolumes();
@@ -1022,20 +1019,21 @@
         }
 
         mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
-        final int oldStreamA11yAlias = mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY];
-        if (oldStreamA11yAlias != a11yStreamAlias) {
-            mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias;
-            mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].mVolumeIndexSettingName =
-                    System.VOLUME_SETTINGS_INT[a11yStreamAlias];
-            // restore the value from the settings when the alias changes
-            mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].readSettings();
-        }
+        mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias;
 
         if (updateVolumes) {
             mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias],
                     caller);
+
+            mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].mVolumeIndexSettingName =
+                    System.VOLUME_SETTINGS_INT[a11yStreamAlias];
             mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes(
                     mStreamStates[a11yStreamAlias], caller);
+            if (sIndependentA11yVolume) {
+                // restore the a11y values from the settings
+                mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].readSettings();
+            }
+
             // apply stream mute states according to new value of mRingerModeAffectedStreams
             setRingerModeInt(getRingerModeInternal(), false);
             sendMsg(mAudioHandler,
@@ -4228,7 +4226,17 @@
             return mIndexMin;
         }
 
+        /**
+         * Copies all device/index pairs from the given VolumeStreamState after initializing
+         * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState
+         * has the same stream type as this instance.
+         * @param srcStream
+         * @param caller
+         */
         public void setAllIndexes(VolumeStreamState srcStream, String caller) {
+            if (mStreamType == srcStream.mStreamType) {
+                return;
+            }
             synchronized (VolumeStreamState.class) {
                 int srcStreamType = srcStream.getStreamType();
                 // apply default device volume from source stream to all devices first in case
diff --git a/services/core/java/com/android/server/job/GrantedUriPermissions.java b/services/core/java/com/android/server/job/GrantedUriPermissions.java
new file mode 100644
index 0000000..e413d8d
--- /dev/null
+++ b/services/core/java/com/android/server/job/GrantedUriPermissions.java
@@ -0,0 +1,156 @@
+/*
+ * 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.server.job;
+
+import android.app.IActivityManager;
+import android.content.ClipData;
+import android.content.ContentProvider;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+public class GrantedUriPermissions {
+    private final int mGrantFlags;
+    private final int mSourceUserId;
+    private final String mTag;
+    private final IBinder mPermissionOwner;
+    private final ArrayList<Uri> mUris = new ArrayList<>();
+
+    private GrantedUriPermissions(IActivityManager am, int grantFlags, int uid, String tag)
+            throws RemoteException {
+        mGrantFlags = grantFlags;
+        mSourceUserId = UserHandle.getUserId(uid);
+        mTag = tag;
+        mPermissionOwner = am.newUriPermissionOwner("job: " + tag);
+    }
+
+    public void revoke(IActivityManager am) {
+        for (int i = mUris.size()-1; i >= 0; i--) {
+            try {
+                am.revokeUriPermissionFromOwner(mPermissionOwner, mUris.get(i),
+                        mGrantFlags, mSourceUserId);
+            } catch (RemoteException e) {
+            }
+        }
+        mUris.clear();
+    }
+
+    public static boolean checkGrantFlags(int grantFlags) {
+        return (grantFlags & (Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+                |Intent.FLAG_GRANT_READ_URI_PERMISSION)) != 0;
+    }
+
+    public static GrantedUriPermissions createFromIntent(IActivityManager am, Intent intent,
+            int sourceUid, String targetPackage, int targetUserId, String tag) {
+        int grantFlags = intent.getFlags();
+        if (!checkGrantFlags(grantFlags)) {
+            return null;
+        }
+
+        GrantedUriPermissions perms = null;
+
+        Uri data = intent.getData();
+        if (data != null) {
+            perms = grantUri(am, data, sourceUid, targetPackage, targetUserId, grantFlags, tag,
+                    perms);
+        }
+
+        ClipData clip = intent.getClipData();
+        if (clip != null) {
+            perms = grantClip(am, clip, sourceUid, targetPackage, targetUserId, grantFlags, tag,
+                    perms);
+        }
+
+        return perms;
+    }
+
+    public static GrantedUriPermissions createFromClip(IActivityManager am, ClipData clip,
+            int sourceUid, String targetPackage, int targetUserId, int grantFlags, String tag) {
+        if (!checkGrantFlags(grantFlags)) {
+            return null;
+        }
+        GrantedUriPermissions perms = null;
+        if (clip != null) {
+            perms = grantClip(am, clip, sourceUid, targetPackage, targetUserId, grantFlags,
+                    tag, perms);
+        }
+        return perms;
+    }
+
+    private static GrantedUriPermissions grantClip(IActivityManager am, ClipData clip,
+            int sourceUid, String targetPackage, int targetUserId, int grantFlags, String tag,
+            GrantedUriPermissions curPerms) {
+        final int N = clip.getItemCount();
+        for (int i = 0; i < N; i++) {
+            curPerms = grantItem(am, clip.getItemAt(i), sourceUid, targetPackage, targetUserId,
+                    grantFlags, tag, curPerms);
+        }
+        return curPerms;
+    }
+
+    private static GrantedUriPermissions grantUri(IActivityManager am, Uri uri,
+            int sourceUid, String targetPackage, int targetUserId, int grantFlags, String tag,
+            GrantedUriPermissions curPerms) {
+        try {
+            int sourceUserId = ContentProvider.getUserIdFromUri(uri,
+                    UserHandle.getUserId(sourceUid));
+            uri = ContentProvider.getUriWithoutUserId(uri);
+            if (curPerms == null) {
+                curPerms = new GrantedUriPermissions(am, grantFlags, sourceUid, tag);
+            }
+            am.grantUriPermissionFromOwner(curPerms.mPermissionOwner, sourceUid, targetPackage,
+                    uri, grantFlags, sourceUserId, targetUserId);
+            curPerms.mUris.add(uri);
+        } catch (RemoteException e) {
+            Slog.e("JobScheduler", "AM dead");
+        }
+        return curPerms;
+    }
+
+    private static GrantedUriPermissions grantItem(IActivityManager am, ClipData.Item item,
+            int sourceUid, String targetPackage, int targetUserId, int grantFlags, String tag,
+            GrantedUriPermissions curPerms) {
+        if (item.getUri() != null) {
+            curPerms = grantUri(am, item.getUri(), sourceUid, targetPackage, targetUserId,
+                    grantFlags, tag, curPerms);
+        }
+        Intent intent = item.getIntent();
+        if (intent != null && intent.getData() != null) {
+            curPerms = grantUri(am, intent.getData(), sourceUid, targetPackage, targetUserId,
+                    grantFlags, tag, curPerms);
+        }
+        return curPerms;
+    }
+
+    // Dumpsys infrastructure
+    public void dump(PrintWriter pw, String prefix) {
+        pw.print(prefix); pw.print("mGrantFlags=0x"); pw.print(Integer.toHexString(mGrantFlags));
+        pw.print(" mSourceUserId="); pw.println(mSourceUserId);
+        pw.print(prefix); pw.print("mTag="); pw.println(mTag);
+        pw.print(prefix); pw.print("mPermissionOwner="); pw.println(mPermissionOwner);
+        for (int i = 0; i < mUris.size(); i++) {
+            pw.print(prefix); pw.print("#"); pw.print(i); pw.print(": ");
+            pw.println(mUris.get(i));
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index d01de3c..c8bfa34 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -601,7 +601,7 @@
                 // Fast path: we are adding work to an existing job, and the JobInfo is not
                 // changing.  We can just directly enqueue this work in to the job.
                 if (toCancel.getJob().equals(job)) {
-                    toCancel.enqueueWorkLocked(work);
+                    toCancel.enqueueWorkLocked(ActivityManager.getService(), work);
                     return JobScheduler.RESULT_SUCCESS;
                 }
             }
@@ -625,7 +625,7 @@
             }
             if (work != null) {
                 // If work has been supplied, enqueue it into the new job.
-                jobStatus.enqueueWorkLocked(work);
+                jobStatus.enqueueWorkLocked(ActivityManager.getService(), work);
             }
             startTrackingJobLocked(jobStatus, toCancel);
             mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
@@ -758,7 +758,7 @@
                     final JobStatus executing = jsc.getRunningJob();
                     if (executing != null
                             && (executing.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) == 0) {
-                        jsc.cancelExecutingJob(JobParameters.REASON_DEVICE_IDLE);
+                        jsc.cancelExecutingJobLocked(JobParameters.REASON_DEVICE_IDLE);
                     }
                 }
             } else {
@@ -921,7 +921,7 @@
     private boolean stopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
             boolean writeBack) {
         // Deal with any remaining work items in the old job.
-        jobStatus.stopTrackingJobLocked(incomingJob);
+        jobStatus.stopTrackingJobLocked(ActivityManager.getService(), incomingJob);
 
         // Remove from store as well as controllers.
         final boolean removed = mJobs.remove(jobStatus, writeBack);
@@ -939,7 +939,7 @@
             JobServiceContext jsc = mActiveServices.get(i);
             final JobStatus executing = jsc.getRunningJob();
             if (executing != null && executing.matches(job.getUid(), job.getJobId())) {
-                jsc.cancelExecutingJob(reason);
+                jsc.cancelExecutingJobLocked(reason);
                 return true;
             }
         }
@@ -1071,9 +1071,16 @@
         if (DEBUG) {
             Slog.d(TAG, "Completed " + jobStatus + ", reschedule=" + needsReschedule);
         }
+
+        // If the job wants to be rescheduled, we first need to make the next upcoming
+        // job so we can transfer any appropriate state over from the previous job when
+        // we stop it.
+        final JobStatus rescheduledJob = needsReschedule
+                ? getRescheduleJobForFailureLocked(jobStatus) : null;
+
         // Do not write back immediately if this is a periodic job. The job may get lost if system
         // shuts down before it is added back.
-        if (!stopTrackingJobLocked(jobStatus, null, !jobStatus.getJob().isPeriodic())) {
+        if (!stopTrackingJobLocked(jobStatus, rescheduledJob, !jobStatus.getJob().isPeriodic())) {
             if (DEBUG) {
                 Slog.d(TAG, "Could not find job to remove. Was job removed while executing?");
             }
@@ -1082,18 +1089,14 @@
             mHandler.obtainMessage(MSG_CHECK_JOB_GREEDY).sendToTarget();
             return;
         }
-        // Note: there is a small window of time in here where, when rescheduling a job,
-        // we will stop monitoring its content providers.  This should be fixed by stopping
-        // the old job after scheduling the new one, but since we have no lock held here
-        // that may cause ordering problems if the app removes jobStatus while in here.
-        if (needsReschedule) {
-            JobStatus rescheduled = getRescheduleJobForFailureLocked(jobStatus);
+
+        if (rescheduledJob != null) {
             try {
-                rescheduled.prepareLocked(ActivityManager.getService());
+                rescheduledJob.prepareLocked(ActivityManager.getService());
             } catch (SecurityException e) {
-                Slog.w(TAG, "Unable to regrant job permissions for " + rescheduled);
+                Slog.w(TAG, "Unable to regrant job permissions for " + rescheduledJob);
             }
-            startTrackingJobLocked(rescheduled, jobStatus);
+            startTrackingJobLocked(rescheduledJob, jobStatus);
         } else if (jobStatus.getJob().isPeriodic()) {
             JobStatus rescheduledPeriodic = getRescheduleJobForPeriodic(jobStatus);
             try {
@@ -1561,7 +1564,7 @@
                         Slog.d(TAG, "preempting job: " + mActiveServices.get(i).getRunningJob());
                     }
                     // preferredUid will be set to uid of currently running job.
-                    mActiveServices.get(i).preemptExecutingJob();
+                    mActiveServices.get(i).preemptExecutingJobLocked();
                     preservePreferredUid = true;
                 } else {
                     final JobStatus pendingJob = contextIdToJobMap[i];
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index c7ef0e2..9144966 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -44,8 +44,6 @@
 import com.android.internal.app.IBatteryStats;
 import com.android.server.job.controllers.JobStatus;
 
-import java.util.concurrent.atomic.AtomicBoolean;
-
 /**
  * Handles client binding and lifecycle of a job. Jobs execute one at a time on an instance of this
  * class.
@@ -56,19 +54,15 @@
  * job lands, and again when it is complete.
  * - Cancelling is trickier, because there are also interactions from the client. It's possible
  * the {@link com.android.server.job.JobServiceContext.JobServiceHandler} tries to process a
- * {@link #MSG_CANCEL} after the client has already finished. This is handled by having
- * {@link com.android.server.job.JobServiceContext.JobServiceHandler#handleCancelH} check whether
+ * {@link #doCancelLocked(int)} after the client has already finished. This is handled by having
+ * {@link com.android.server.job.JobServiceContext.JobServiceHandler#handleCancelLocked} check whether
  * the context is still valid.
- * To mitigate this, tearing down the context removes all messages from the handler, including any
- * tardy {@link #MSG_CANCEL}s. Additionally, we avoid sending duplicate onStopJob()
+ * To mitigate this, we avoid sending duplicate onStopJob()
  * calls to the client after they've specified jobFinished().
  */
 public class JobServiceContext extends IJobCallback.Stub implements ServiceConnection {
     private static final boolean DEBUG = JobSchedulerService.DEBUG;
     private static final String TAG = "JobServiceContext";
-    /** Define the maximum # of jobs allowed to run on a service at once. */
-    private static final int defaultMaxActiveJobsPerService =
-            ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
     /** Amount of time a job is allowed to execute for before being considered timed-out. */
     private static final long EXECUTING_TIMESLICE_MILLIS = 10 * 60 * 1000;  // 10mins.
     /** Amount of time the JobScheduler waits for the initial service launch+bind. */
@@ -90,14 +84,6 @@
     // Messages that result from interactions with the client service.
     /** System timed out waiting for a response. */
     private static final int MSG_TIMEOUT = 0;
-    /** Received a callback from client. */
-    private static final int MSG_CALLBACK = 1;
-    /** Run through list and start any ready jobs.*/
-    private static final int MSG_SERVICE_BOUND = 2;
-    /** Cancel a job. */
-    private static final int MSG_CANCEL = 3;
-    /** Shutdown the job. Used when the client crashes and we can't die gracefully.*/
-    private static final int MSG_SHUTDOWN_EXECUTION = 4;
 
     public static final int NO_PREFERRED_UID = -1;
 
@@ -115,7 +101,7 @@
     private JobParameters mParams;
     @VisibleForTesting
     int mVerb;
-    private AtomicBoolean mCancelled = new AtomicBoolean();
+    private boolean mCancelled;
 
     /**
      * All the information maintained about the job currently being executed.
@@ -245,14 +231,12 @@
     }
 
     /** Called externally when a job that was scheduled for execution should be cancelled. */
-    void cancelExecutingJob(int reason) {
-        mCallbackHandler.obtainMessage(MSG_CANCEL, reason, 0 /* unused */).sendToTarget();
+    void cancelExecutingJobLocked(int reason) {
+        doCancelLocked(reason);
     }
 
-    void preemptExecutingJob() {
-        Message m = mCallbackHandler.obtainMessage(MSG_CANCEL);
-        m.arg1 = JobParameters.REASON_PREEMPT;
-        m.sendToTarget();
+    void preemptExecutingJobLocked() {
+        doCancelLocked(JobParameters.REASON_PREEMPT);
     }
 
     int getPreferredUid() {
@@ -273,59 +257,54 @@
 
     @Override
     public void jobFinished(int jobId, boolean reschedule) {
-        if (!verifyCallingUid()) {
-            return;
-        }
-        mCallbackHandler.obtainMessage(MSG_CALLBACK, jobId, reschedule ? 1 : 0)
-                .sendToTarget();
+        doCallback(reschedule);
     }
 
     @Override
     public void acknowledgeStopMessage(int jobId, boolean reschedule) {
-        if (!verifyCallingUid()) {
-            return;
-        }
-        mCallbackHandler.obtainMessage(MSG_CALLBACK, jobId, reschedule ? 1 : 0)
-                .sendToTarget();
+        doCallback(reschedule);
     }
 
     @Override
     public void acknowledgeStartMessage(int jobId, boolean ongoing) {
-        if (!verifyCallingUid()) {
-            return;
-        }
-        mCallbackHandler.obtainMessage(MSG_CALLBACK, jobId, ongoing ? 1 : 0).sendToTarget();
+        doCallback(ongoing);
     }
 
     @Override
     public JobWorkItem dequeueWork(int jobId) {
-        if (!verifyCallingUid()) {
-            throw new SecurityException("Bad calling uid: " + Binder.getCallingUid());
-        }
-        JobWorkItem work = null;
-        boolean stillWorking = false;
-        synchronized (mLock) {
-            if (mRunningJob != null) {
-                work = mRunningJob.dequeueWorkLocked();
-                stillWorking = mRunningJob.hasExecutingWorkLocked();
+        final int callingUid = Binder.getCallingUid();
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                if (!verifyCallingUidLocked(callingUid)) {
+                    throw new SecurityException("Bad calling uid: " + callingUid);
+                }
+
+                final JobWorkItem work = mRunningJob.dequeueWorkLocked();
+                if (work == null && !mRunningJob.hasExecutingWorkLocked()) {
+                    // This will finish the job.
+                    doCallbackLocked(false);
+                }
+                return work;
             }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
-        if (work == null && !stillWorking) {
-            jobFinished(jobId, false);
-        }
-        return work;
     }
 
     @Override
     public boolean completeWork(int jobId, int workId) {
-        if (!verifyCallingUid()) {
-            throw new SecurityException("Bad calling uid: " + Binder.getCallingUid());
-        }
-        synchronized (mLock) {
-            if (mRunningJob != null) {
-                return mRunningJob.completeWorkLocked(workId);
+        final int callingUid = Binder.getCallingUid();
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                if (!verifyCallingUidLocked(callingUid)) {
+                    throw new SecurityException("Bad calling uid: " + callingUid);
+                }
+                return mRunningJob.completeWorkLocked(ActivityManager.getService(), workId);
             }
-            return false;
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
     }
 
@@ -344,20 +323,20 @@
             // looper and at this point we can't get any binder callbacks from the client. Better
             // safe than sorry.
             runningJob = mRunningJob;
-        }
-        if (runningJob == null || !name.equals(runningJob.getServiceComponent())) {
-            mCallbackHandler.obtainMessage(MSG_SHUTDOWN_EXECUTION).sendToTarget();
-            return;
-        }
-        this.service = IJobService.Stub.asInterface(service);
-        final PowerManager pm =
-                (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
-                runningJob.getTag());
-        wl.setWorkSource(new WorkSource(runningJob.getSourceUid()));
-        wl.setReferenceCounted(false);
-        wl.acquire();
-        synchronized (mLock) {
+
+            if (runningJob == null || !name.equals(runningJob.getServiceComponent())) {
+                closeAndCleanupJobLocked(true /* needsReschedule */);
+                return;
+            }
+            this.service = IJobService.Stub.asInterface(service);
+            final PowerManager pm =
+                    (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+            PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                    runningJob.getTag());
+            wl.setWorkSource(new WorkSource(runningJob.getSourceUid()));
+            wl.setReferenceCounted(false);
+            wl.acquire();
+
             // We use a new wakelock instance per job.  In rare cases there is a race between
             // teardown following job completion/cancellation and new job service spin-up
             // such that if we simply assign mWakeLock to be the new instance, we orphan
@@ -369,14 +348,16 @@
                 mWakeLock.release();
             }
             mWakeLock = wl;
+            doServiceBoundLocked();
         }
-        mCallbackHandler.obtainMessage(MSG_SERVICE_BOUND).sendToTarget();
     }
 
     /** If the client service crashes we reschedule this job and clean up. */
     @Override
     public void onServiceDisconnected(ComponentName name) {
-        mCallbackHandler.obtainMessage(MSG_SHUTDOWN_EXECUTION).sendToTarget();
+        synchronized (mLock) {
+            closeAndCleanupJobLocked(true /* needsReschedule */);
+        }
     }
 
     /**
@@ -384,22 +365,18 @@
      * whether the client exercising the callback is the client we expect.
      * @return True if the binder calling is coming from the client we expect.
      */
-    private boolean verifyCallingUid() {
-        synchronized (mLock) {
-            if (mRunningJob == null || Binder.getCallingUid() != mRunningJob.getUid()) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Stale callback received, ignoring.");
-                }
-                return false;
+    private boolean verifyCallingUidLocked(final int callingUid) {
+        if (mRunningJob == null || callingUid != mRunningJob.getUid()) {
+            if (DEBUG) {
+                Slog.d(TAG, "Stale callback received, ignoring.");
             }
-            return true;
+            return false;
         }
+        return true;
     }
 
     /**
-     * Handles the lifecycle of the JobService binding/callbacks, etc. The convention within this
-     * class is to append 'H' to each function name that can only be called on this handler. This
-     * isn't strictly necessary because all of these functions are private, but helps clarity.
+     * Scheduling of async messages (basically timeouts at this point).
      */
     private class JobServiceHandler extends Handler {
         JobServiceHandler(Looper looper) {
@@ -409,296 +386,280 @@
         @Override
         public void handleMessage(Message message) {
             switch (message.what) {
-                case MSG_SERVICE_BOUND:
-                    doServiceBound();
-                    break;
-                case MSG_CALLBACK:
-                    doCallback(message.arg2);
-                    break;
-                case MSG_CANCEL:
-                    doCancel(message.arg1);
-                    break;
                 case MSG_TIMEOUT:
                     synchronized (mLock) {
-                        handleOpTimeoutH();
+                        handleOpTimeoutLocked();
                     }
                     break;
-                case MSG_SHUTDOWN_EXECUTION:
-                    closeAndCleanupJobH(true /* needsReschedule */);
-                    break;
                 default:
                     Slog.e(TAG, "Unrecognised message: " + message);
             }
         }
+    }
 
-        void doServiceBound() {
+    void doServiceBoundLocked() {
+        removeOpTimeOutLocked();
+        handleServiceBoundLocked();
+    }
+
+    void doCallback(boolean reschedule) {
+        final int callingUid = Binder.getCallingUid();
+        final long ident = Binder.clearCallingIdentity();
+        try {
             synchronized (mLock) {
-                removeOpTimeOutLocked();
-                handleServiceBoundH();
-            }
-        }
-
-        void doCallback(int arg2) {
-            synchronized (mLock) {
-                if (DEBUG) {
-                    Slog.d(TAG, "MSG_CALLBACK of : " + mRunningJob
-                            + " v:" + VERB_STRINGS[mVerb]);
-                }
-                removeOpTimeOutLocked();
-
-                if (mVerb == VERB_STARTING) {
-                    final boolean workOngoing = arg2 == 1;
-                    handleStartedH(workOngoing);
-                } else if (mVerb == VERB_EXECUTING ||
-                        mVerb == VERB_STOPPING) {
-                    final boolean reschedule = arg2 == 1;
-                    handleFinishedH(reschedule);
-                } else {
-                    if (DEBUG) {
-                        Slog.d(TAG, "Unrecognised callback: " + mRunningJob);
-                    }
-                }
-            }
-        }
-
-        void doCancel(int arg1) {
-            synchronized (mLock) {
-                if (mVerb == VERB_FINISHED) {
-                    if (DEBUG) {
-                        Slog.d(TAG,
-                                "Trying to process cancel for torn-down context, ignoring.");
-                    }
+                if (!verifyCallingUidLocked(callingUid)) {
                     return;
                 }
-                mParams.setStopReason(arg1);
-                if (arg1 == JobParameters.REASON_PREEMPT) {
-                    mPreferredUid = mRunningJob != null ? mRunningJob.getUid() :
-                            NO_PREFERRED_UID;
-                }
-                handleCancelH();
+                doCallbackLocked(reschedule);
             }
-
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
+    }
 
-        /** Start the job on the service. */
-        private void handleServiceBoundH() {
+    void doCallbackLocked(boolean reschedule) {
+        if (DEBUG) {
+            Slog.d(TAG, "doCallback of : " + mRunningJob
+                    + " v:" + VERB_STRINGS[mVerb]);
+        }
+        removeOpTimeOutLocked();
+
+        if (mVerb == VERB_STARTING) {
+            handleStartedLocked(reschedule);
+        } else if (mVerb == VERB_EXECUTING ||
+                mVerb == VERB_STOPPING) {
+            handleFinishedLocked(reschedule);
+        } else {
             if (DEBUG) {
-                Slog.d(TAG, "MSG_SERVICE_BOUND for " + mRunningJob.toShortString());
-            }
-            if (mVerb != VERB_BINDING) {
-                Slog.e(TAG, "Sending onStartJob for a job that isn't pending. "
-                        + VERB_STRINGS[mVerb]);
-                closeAndCleanupJobH(false /* reschedule */);
-                return;
-            }
-            if (mCancelled.get()) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Job cancelled while waiting for bind to complete. "
-                            + mRunningJob);
-                }
-                closeAndCleanupJobH(true /* reschedule */);
-                return;
-            }
-            try {
-                mVerb = VERB_STARTING;
-                scheduleOpTimeOutLocked();
-                service.startJob(mParams);
-            } catch (Exception e) {
-                // We catch 'Exception' because client-app malice or bugs might induce a wide
-                // range of possible exception-throw outcomes from startJob() and its handling
-                // of the client's ParcelableBundle extras.
-                Slog.e(TAG, "Error sending onStart message to '" +
-                        mRunningJob.getServiceComponent().getShortClassName() + "' ", e);
+                Slog.d(TAG, "Unrecognised callback: " + mRunningJob);
             }
         }
+    }
 
-        /**
-         * State behaviours.
-         * VERB_STARTING   -> Successful start, change job to VERB_EXECUTING and post timeout.
-         *     _PENDING    -> Error
-         *     _EXECUTING  -> Error
-         *     _STOPPING   -> Error
-         */
-        private void handleStartedH(boolean workOngoing) {
-            switch (mVerb) {
-                case VERB_STARTING:
-                    mVerb = VERB_EXECUTING;
-                    if (!workOngoing) {
-                        // Job is finished already so fast-forward to handleFinished.
-                        handleFinishedH(false);
-                        return;
-                    }
-                    if (mCancelled.get()) {
-                        if (DEBUG) {
-                            Slog.d(TAG, "Job cancelled while waiting for onStartJob to complete.");
-                        }
-                        // Cancelled *while* waiting for acknowledgeStartMessage from client.
-                        handleCancelH();
-                        return;
-                    }
-                    scheduleOpTimeOutLocked();
-                    break;
-                default:
-                    Slog.e(TAG, "Handling started job but job wasn't starting! Was "
-                            + VERB_STRINGS[mVerb] + ".");
-                    return;
+    void doCancelLocked(int arg1) {
+        if (mVerb == VERB_FINISHED) {
+            if (DEBUG) {
+                Slog.d(TAG,
+                        "Trying to process cancel for torn-down context, ignoring.");
             }
+            return;
         }
-
-        /**
-         * VERB_EXECUTING  -> Client called jobFinished(), clean up and notify done.
-         *     _STOPPING   -> Successful finish, clean up and notify done.
-         *     _STARTING   -> Error
-         *     _PENDING    -> Error
-         */
-        private void handleFinishedH(boolean reschedule) {
-            switch (mVerb) {
-                case VERB_EXECUTING:
-                case VERB_STOPPING:
-                    closeAndCleanupJobH(reschedule);
-                    break;
-                default:
-                    Slog.e(TAG, "Got an execution complete message for a job that wasn't being" +
-                            "executed. Was " + VERB_STRINGS[mVerb] + ".");
-            }
+        mParams.setStopReason(arg1);
+        if (arg1 == JobParameters.REASON_PREEMPT) {
+            mPreferredUid = mRunningJob != null ? mRunningJob.getUid() :
+                    NO_PREFERRED_UID;
         }
+        handleCancelLocked();
+    }
 
-        /**
-         * A job can be in various states when a cancel request comes in:
-         * VERB_BINDING    -> Cancelled before bind completed. Mark as cancelled and wait for
-         *                    {@link #onServiceConnected(android.content.ComponentName, android.os.IBinder)}
-         *     _STARTING   -> Mark as cancelled and wait for
-         *                    {@link JobServiceContext#acknowledgeStartMessage(int, boolean)}
-         *     _EXECUTING  -> call {@link #sendStopMessageH}}, but only if there are no callbacks
-         *                      in the message queue.
-         *     _ENDING     -> No point in doing anything here, so we ignore.
-         */
-        private void handleCancelH() {
-            if (JobSchedulerService.DEBUG) {
-                Slog.d(TAG, "Handling cancel for: " + mRunningJob.getJobId() + " "
-                        + VERB_STRINGS[mVerb]);
-            }
-            switch (mVerb) {
-                case VERB_BINDING:
-                case VERB_STARTING:
-                    mCancelled.set(true);
-                    break;
-                case VERB_EXECUTING:
-                    if (hasMessages(MSG_CALLBACK)) {
-                        // If the client has called jobFinished, ignore this cancel.
-                        return;
-                    }
-                    sendStopMessageH();
-                    break;
-                case VERB_STOPPING:
-                    // Nada.
-                    break;
-                default:
-                    Slog.e(TAG, "Cancelling a job without a valid verb: " + mVerb);
-                    break;
-            }
+    /** Start the job on the service. */
+    private void handleServiceBoundLocked() {
+        if (DEBUG) {
+            Slog.d(TAG, "handleServiceBound for " + mRunningJob.toShortString());
         }
-
-        /** Process MSG_TIMEOUT here. */
-        private void handleOpTimeoutH() {
-            switch (mVerb) {
-                case VERB_BINDING:
-                    Slog.e(TAG, "Time-out while trying to bind " + mRunningJob.toShortString() +
-                            ", dropping.");
-                    closeAndCleanupJobH(false /* needsReschedule */);
-                    break;
-                case VERB_STARTING:
-                    // Client unresponsive - wedged or failed to respond in time. We don't really
-                    // know what happened so let's log it and notify the JobScheduler
-                    // FINISHED/NO-RETRY.
-                    Slog.e(TAG, "No response from client for onStartJob '" +
-                            mRunningJob.toShortString());
-                    closeAndCleanupJobH(false /* needsReschedule */);
-                    break;
-                case VERB_STOPPING:
-                    // At least we got somewhere, so fail but ask the JobScheduler to reschedule.
-                    Slog.e(TAG, "No response from client for onStopJob, '" +
-                            mRunningJob.toShortString());
-                    closeAndCleanupJobH(true /* needsReschedule */);
-                    break;
-                case VERB_EXECUTING:
-                    // Not an error - client ran out of time.
-                    Slog.i(TAG, "Client timed out while executing (no jobFinished received)." +
-                            " sending onStop. "  + mRunningJob.toShortString());
-                    mParams.setStopReason(JobParameters.REASON_TIMEOUT);
-                    sendStopMessageH();
-                    break;
-                default:
-                    Slog.e(TAG, "Handling timeout for an invalid job state: " +
-                            mRunningJob.toShortString() + ", dropping.");
-                    closeAndCleanupJobH(false /* needsReschedule */);
-            }
+        if (mVerb != VERB_BINDING) {
+            Slog.e(TAG, "Sending onStartJob for a job that isn't pending. "
+                    + VERB_STRINGS[mVerb]);
+            closeAndCleanupJobLocked(false /* reschedule */);
+            return;
         }
-
-        /**
-         * Already running, need to stop. Will switch {@link #mVerb} from VERB_EXECUTING ->
-         * VERB_STOPPING.
-         */
-        private void sendStopMessageH() {
-            removeOpTimeOutLocked();
-            if (mVerb != VERB_EXECUTING) {
-                Slog.e(TAG, "Sending onStopJob for a job that isn't started. " + mRunningJob);
-                closeAndCleanupJobH(false /* reschedule */);
-                return;
+        if (mCancelled) {
+            if (DEBUG) {
+                Slog.d(TAG, "Job cancelled while waiting for bind to complete. "
+                        + mRunningJob);
             }
-            try {
-                mVerb = VERB_STOPPING;
-                scheduleOpTimeOutLocked();
-                service.stopJob(mParams);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Error sending onStopJob to client.", e);
-                // The job's host app apparently crashed during the job, so we should reschedule.
-                closeAndCleanupJobH(true /* reschedule */);
-            }
+            closeAndCleanupJobLocked(true /* reschedule */);
+            return;
         }
+        try {
+            mVerb = VERB_STARTING;
+            scheduleOpTimeOutLocked();
+            service.startJob(mParams);
+        } catch (Exception e) {
+            // We catch 'Exception' because client-app malice or bugs might induce a wide
+            // range of possible exception-throw outcomes from startJob() and its handling
+            // of the client's ParcelableBundle extras.
+            Slog.e(TAG, "Error sending onStart message to '" +
+                    mRunningJob.getServiceComponent().getShortClassName() + "' ", e);
+        }
+    }
 
-        /**
-         * The provided job has finished, either by calling
-         * {@link android.app.job.JobService#jobFinished(android.app.job.JobParameters, boolean)}
-         * or from acknowledging the stop message we sent. Either way, we're done tracking it and
-         * we want to clean up internally.
-         */
-        private void closeAndCleanupJobH(boolean reschedule) {
-            final JobStatus completedJob;
-            synchronized (mLock) {
-                if (mVerb == VERB_FINISHED) {
+    /**
+     * State behaviours.
+     * VERB_STARTING   -> Successful start, change job to VERB_EXECUTING and post timeout.
+     *     _PENDING    -> Error
+     *     _EXECUTING  -> Error
+     *     _STOPPING   -> Error
+     */
+    private void handleStartedLocked(boolean workOngoing) {
+        switch (mVerb) {
+            case VERB_STARTING:
+                mVerb = VERB_EXECUTING;
+                if (!workOngoing) {
+                    // Job is finished already so fast-forward to handleFinished.
+                    handleFinishedLocked(false);
                     return;
                 }
-                completedJob = mRunningJob;
-                mJobPackageTracker.noteInactive(completedJob);
-                try {
-                    mBatteryStats.noteJobFinish(mRunningJob.getBatteryName(),
-                            mRunningJob.getSourceUid());
-                } catch (RemoteException e) {
-                    // Whatever.
+                if (mCancelled) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "Job cancelled while waiting for onStartJob to complete.");
+                    }
+                    // Cancelled *while* waiting for acknowledgeStartMessage from client.
+                    handleCancelLocked();
+                    return;
                 }
-                if (mWakeLock != null) {
-                    mWakeLock.release();
-                }
-                mContext.unbindService(JobServiceContext.this);
-                mWakeLock = null;
-                mRunningJob = null;
-                mParams = null;
-                mVerb = VERB_FINISHED;
-                mCancelled.set(false);
-                service = null;
-                mAvailable = true;
-                removeOpTimeOutLocked();
-                removeMessages(MSG_CALLBACK);
-                removeMessages(MSG_SERVICE_BOUND);
-                removeMessages(MSG_CANCEL);
-                removeMessages(MSG_SHUTDOWN_EXECUTION);
-                mCompletedListener.onJobCompletedLocked(completedJob, reschedule);
-            }
+                scheduleOpTimeOutLocked();
+                break;
+            default:
+                Slog.e(TAG, "Handling started job but job wasn't starting! Was "
+                        + VERB_STRINGS[mVerb] + ".");
+                return;
         }
     }
 
     /**
+     * VERB_EXECUTING  -> Client called jobFinished(), clean up and notify done.
+     *     _STOPPING   -> Successful finish, clean up and notify done.
+     *     _STARTING   -> Error
+     *     _PENDING    -> Error
+     */
+    private void handleFinishedLocked(boolean reschedule) {
+        switch (mVerb) {
+            case VERB_EXECUTING:
+            case VERB_STOPPING:
+                closeAndCleanupJobLocked(reschedule);
+                break;
+            default:
+                Slog.e(TAG, "Got an execution complete message for a job that wasn't being" +
+                        "executed. Was " + VERB_STRINGS[mVerb] + ".");
+        }
+    }
+
+    /**
+     * A job can be in various states when a cancel request comes in:
+     * VERB_BINDING    -> Cancelled before bind completed. Mark as cancelled and wait for
+     *                    {@link #onServiceConnected(android.content.ComponentName, android.os.IBinder)}
+     *     _STARTING   -> Mark as cancelled and wait for
+     *                    {@link JobServiceContext#acknowledgeStartMessage(int, boolean)}
+     *     _EXECUTING  -> call {@link #sendStopMessageLocked}}, but only if there are no callbacks
+     *                      in the message queue.
+     *     _ENDING     -> No point in doing anything here, so we ignore.
+     */
+    private void handleCancelLocked() {
+        if (JobSchedulerService.DEBUG) {
+            Slog.d(TAG, "Handling cancel for: " + mRunningJob.getJobId() + " "
+                    + VERB_STRINGS[mVerb]);
+        }
+        switch (mVerb) {
+            case VERB_BINDING:
+            case VERB_STARTING:
+                mCancelled = true;
+                break;
+            case VERB_EXECUTING:
+                sendStopMessageLocked();
+                break;
+            case VERB_STOPPING:
+                // Nada.
+                break;
+            default:
+                Slog.e(TAG, "Cancelling a job without a valid verb: " + mVerb);
+                break;
+        }
+    }
+
+    /** Process MSG_TIMEOUT here. */
+    private void handleOpTimeoutLocked() {
+        switch (mVerb) {
+            case VERB_BINDING:
+                Slog.e(TAG, "Time-out while trying to bind " + mRunningJob.toShortString() +
+                        ", dropping.");
+                closeAndCleanupJobLocked(false /* needsReschedule */);
+                break;
+            case VERB_STARTING:
+                // Client unresponsive - wedged or failed to respond in time. We don't really
+                // know what happened so let's log it and notify the JobScheduler
+                // FINISHED/NO-RETRY.
+                Slog.e(TAG, "No response from client for onStartJob '" +
+                        mRunningJob.toShortString());
+                closeAndCleanupJobLocked(false /* needsReschedule */);
+                break;
+            case VERB_STOPPING:
+                // At least we got somewhere, so fail but ask the JobScheduler to reschedule.
+                Slog.e(TAG, "No response from client for onStopJob, '" +
+                        mRunningJob.toShortString());
+                closeAndCleanupJobLocked(true /* needsReschedule */);
+                break;
+            case VERB_EXECUTING:
+                // Not an error - client ran out of time.
+                Slog.i(TAG, "Client timed out while executing (no jobFinished received)." +
+                        " sending onStop. "  + mRunningJob.toShortString());
+                mParams.setStopReason(JobParameters.REASON_TIMEOUT);
+                sendStopMessageLocked();
+                break;
+            default:
+                Slog.e(TAG, "Handling timeout for an invalid job state: " +
+                        mRunningJob.toShortString() + ", dropping.");
+                closeAndCleanupJobLocked(false /* needsReschedule */);
+        }
+    }
+
+    /**
+     * Already running, need to stop. Will switch {@link #mVerb} from VERB_EXECUTING ->
+     * VERB_STOPPING.
+     */
+    private void sendStopMessageLocked() {
+        removeOpTimeOutLocked();
+        if (mVerb != VERB_EXECUTING) {
+            Slog.e(TAG, "Sending onStopJob for a job that isn't started. " + mRunningJob);
+            closeAndCleanupJobLocked(false /* reschedule */);
+            return;
+        }
+        try {
+            mVerb = VERB_STOPPING;
+            scheduleOpTimeOutLocked();
+            service.stopJob(mParams);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Error sending onStopJob to client.", e);
+            // The job's host app apparently crashed during the job, so we should reschedule.
+            closeAndCleanupJobLocked(true /* reschedule */);
+        }
+    }
+
+    /**
+     * The provided job has finished, either by calling
+     * {@link android.app.job.JobService#jobFinished(android.app.job.JobParameters, boolean)}
+     * or from acknowledging the stop message we sent. Either way, we're done tracking it and
+     * we want to clean up internally.
+     */
+    private void closeAndCleanupJobLocked(boolean reschedule) {
+        final JobStatus completedJob;
+        if (mVerb == VERB_FINISHED) {
+            return;
+        }
+        completedJob = mRunningJob;
+        mJobPackageTracker.noteInactive(completedJob);
+        try {
+            mBatteryStats.noteJobFinish(mRunningJob.getBatteryName(),
+                    mRunningJob.getSourceUid());
+        } catch (RemoteException e) {
+            // Whatever.
+        }
+        if (mWakeLock != null) {
+            mWakeLock.release();
+        }
+        mContext.unbindService(JobServiceContext.this);
+        mWakeLock = null;
+        mRunningJob = null;
+        mParams = null;
+        mVerb = VERB_FINISHED;
+        mCancelled = false;
+        service = null;
+        mAvailable = true;
+        removeOpTimeOutLocked();
+        mCompletedListener.onJobCompletedLocked(completedJob, reschedule);
+    }
+
+    /**
      * Called when sending a message to the client, over whose execution we have no control. If
      * we haven't received a response in a certain amount of time, we want to give up and carry
      * on with life.
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index e8cc078..1ab66b9 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -26,7 +26,6 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Binder;
-import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -35,6 +34,8 @@
 import android.util.Slog;
 import android.util.TimeUtils;
 
+import com.android.server.job.GrantedUriPermissions;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -103,7 +104,7 @@
 
     final String tag;
 
-    private IBinder permissionOwner;
+    private GrantedUriPermissions uriPerms;
     private boolean prepared;
 
     /**
@@ -284,12 +285,17 @@
                 earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis);
     }
 
-    public void enqueueWorkLocked(JobWorkItem work) {
+    public void enqueueWorkLocked(IActivityManager am, JobWorkItem work) {
         if (pendingWork == null) {
             pendingWork = new ArrayList<>();
         }
         work.setWorkId(nextPendingWorkId);
         nextPendingWorkId++;
+        if (work.getIntent() != null
+                && GrantedUriPermissions.checkGrantFlags(work.getIntent().getFlags())) {
+            work.setGrants(GrantedUriPermissions.createFromIntent(am, work.getIntent(), sourceUid,
+                    sourcePackageName, sourceUserId, toShortString()));
+        }
         pendingWork.add(work);
     }
 
@@ -311,12 +317,20 @@
         return executingWork != null && executingWork.size() > 0;
     }
 
-    public boolean completeWorkLocked(int workId) {
+    private static void ungrantWorkItem(IActivityManager am, JobWorkItem work) {
+        if (work.getGrants() != null) {
+            ((GrantedUriPermissions)work.getGrants()).revoke(am);
+        }
+    }
+
+    public boolean completeWorkLocked(IActivityManager am, int workId) {
         if (executingWork != null) {
             final int N = executingWork.size();
             for (int i = 0; i < N; i++) {
-                if (executingWork.get(i).getWorkId() == workId) {
+                JobWorkItem work = executingWork.get(i);
+                if (work.getWorkId() == workId) {
                     executingWork.remove(i);
+                    ungrantWorkItem(am, work);
                     return true;
                 }
             }
@@ -324,15 +338,36 @@
         return false;
     }
 
-    public void stopTrackingJobLocked(JobStatus incomingJob) {
+    private static void ungrantWorkList(IActivityManager am, ArrayList<JobWorkItem> list) {
+        if (list != null) {
+            final int N = list.size();
+            for (int i = 0; i < N; i++) {
+                ungrantWorkItem(am, list.get(i));
+            }
+        }
+    }
+
+    public void stopTrackingJobLocked(IActivityManager am, JobStatus incomingJob) {
         if (incomingJob != null) {
-            // We are replacing with a new job -- transfer the work!
-            incomingJob.pendingWork = pendingWork;
+            // We are replacing with a new job -- transfer the work!  We do any executing
+            // work first, since that was originally at the front of the pending work.
+            if (executingWork != null && executingWork.size() > 0) {
+                incomingJob.pendingWork = executingWork;
+            }
+            if (incomingJob.pendingWork == null) {
+                incomingJob.pendingWork = pendingWork;
+            } else if (pendingWork != null && pendingWork.size() > 0) {
+                incomingJob.pendingWork.addAll(pendingWork);
+            }
             pendingWork = null;
+            executingWork = null;
             incomingJob.nextPendingWorkId = nextPendingWorkId;
         } else {
             // We are completely stopping the job...  need to clean up work.
-            // XXX remove perms when that is impl.
+            ungrantWorkList(am, pendingWork);
+            pendingWork = null;
+            ungrantWorkList(am, executingWork);
+            executingWork = null;
         }
     }
 
@@ -344,10 +379,8 @@
         prepared = true;
         final ClipData clip = job.getClipData();
         if (clip != null) {
-            final int N = clip.getItemCount();
-            for (int i = 0; i < N; i++) {
-                grantItemLocked(am, clip.getItemAt(i), sourceUid, sourcePackageName, sourceUserId);
-            }
+            uriPerms = GrantedUriPermissions.createFromClip(am, clip, sourceUid, sourcePackageName,
+                    sourceUserId, job.getClipGrantFlags(), toShortString());
         }
     }
 
@@ -357,14 +390,9 @@
             return;
         }
         prepared = false;
-        if (permissionOwner != null) {
-            final ClipData clip = job.getClipData();
-            if (clip != null) {
-                final int N = clip.getItemCount();
-                for (int i = 0; i < N; i++) {
-                    revokeItemLocked(am, clip.getItemAt(i));
-                }
-            }
+        if (uriPerms != null) {
+            uriPerms.revoke(am);
+            uriPerms = null;
         }
     }
 
@@ -372,57 +400,6 @@
         return prepared;
     }
 
-    private final void grantUriLocked(IActivityManager am, Uri uri, int sourceUid,
-            String targetPackage, int targetUserId) {
-        try {
-            int sourceUserId = ContentProvider.getUserIdFromUri(uri,
-                    UserHandle.getUserId(sourceUid));
-            uri = ContentProvider.getUriWithoutUserId(uri);
-            if (permissionOwner == null) {
-                permissionOwner = am.newUriPermissionOwner("job: " + toShortString());
-            }
-            am.grantUriPermissionFromOwner(permissionOwner, sourceUid, targetPackage,
-                    uri, job.getClipGrantFlags(), sourceUserId, targetUserId);
-        } catch (RemoteException e) {
-            Slog.e("JobScheduler", "AM dead");
-        }
-    }
-
-    private final void grantItemLocked(IActivityManager am, ClipData.Item item, int sourceUid,
-            String targetPackage, int targetUserId) {
-        if (item.getUri() != null) {
-            grantUriLocked(am, item.getUri(), sourceUid, targetPackage, targetUserId);
-        }
-        Intent intent = item.getIntent();
-        if (intent != null && intent.getData() != null) {
-            grantUriLocked(am, intent.getData(), sourceUid, targetPackage, targetUserId);
-        }
-    }
-
-    private final void revokeUriLocked(IActivityManager am, Uri uri) {
-        int userId = ContentProvider.getUserIdFromUri(uri,
-                UserHandle.getUserId(Binder.getCallingUid()));
-        long ident = Binder.clearCallingIdentity();
-        try {
-            uri = ContentProvider.getUriWithoutUserId(uri);
-            am.revokeUriPermissionFromOwner(permissionOwner, uri,
-                    job.getClipGrantFlags(), userId);
-        } catch (RemoteException e) {
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    private final void revokeItemLocked(IActivityManager am, ClipData.Item item) {
-        if (item.getUri() != null) {
-            revokeUriLocked(am, item.getUri());
-        }
-        Intent intent = item.getIntent();
-        if (intent != null && intent.getData() != null) {
-            revokeUriLocked(am, intent.getData());
-        }
-    }
-
     public JobInfo getJob() {
         return job;
     }
@@ -833,6 +810,15 @@
         }
     }
 
+    private void dumpJobWorkItem(PrintWriter pw, String prefix, JobWorkItem work, int index) {
+        pw.print(prefix); pw.print("  #"); pw.print(index); pw.print(": #");
+        pw.print(work.getWorkId()); pw.print(" "); pw.println(work.getIntent());
+        if (work.getGrants() != null) {
+            pw.print(prefix); pw.println("  URI grants:");
+            ((GrantedUriPermissions)work.getGrants()).dump(pw, prefix + "    ");
+        }
+    }
+
     // Dumpsys infrastructure
     public void dump(PrintWriter pw, String prefix, boolean full) {
         pw.print(prefix); UserHandle.formatUid(pw, callingUid);
@@ -898,6 +884,10 @@
                 job.getClipData().toShortString(b);
                 pw.println(b);
             }
+            if (uriPerms != null) {
+                pw.print(prefix); pw.println("  Granted URI permissions:");
+                uriPerms.dump(pw, prefix + "  ");
+            }
             if (job.getNetworkType() != JobInfo.NETWORK_TYPE_NONE) {
                 pw.print(prefix); pw.print("  Network type: "); pw.println(job.getNetworkType());
             }
@@ -950,17 +940,13 @@
         if (pendingWork != null && pendingWork.size() > 0) {
             pw.print(prefix); pw.println("Pending work:");
             for (int i = 0; i < pendingWork.size(); i++) {
-                JobWorkItem work = pendingWork.get(i);
-                pw.print(prefix); pw.print("  #"); pw.print(i); pw.print(": #");
-                pw.print(work.getWorkId()); pw.print(" "); pw.println(work.getIntent());
+                dumpJobWorkItem(pw, prefix, pendingWork.get(i), i);
             }
         }
         if (executingWork != null && executingWork.size() > 0) {
             pw.print(prefix); pw.println("Executing work:");
             for (int i = 0; i < executingWork.size(); i++) {
-                JobWorkItem work = executingWork.get(i);
-                pw.print(prefix); pw.print("  #"); pw.print(i); pw.print(": #");
-                pw.print(work.getWorkId()); pw.print(" "); pw.println(work.getIntent());
+                dumpJobWorkItem(pw, prefix, executingWork.get(i), i);
             }
         }
         pw.print(prefix); pw.print("Earliest run time: ");
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 53a8092..ee348cf 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -101,8 +101,6 @@
     private ParceledListSlice mQueue;
     private CharSequence mQueueTitle;
     private int mRatingType;
-    private int mRepeatMode;
-    private boolean mShuffleModeEnabled;
     // End TransportPerformer fields
 
     // Volume handling fields
@@ -622,47 +620,6 @@
         }
     }
 
-    private void pushRepeatModeUpdate() {
-        synchronized (mLock) {
-            if (mDestroyed) {
-                return;
-            }
-            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
-                try {
-                    holder.mCallback.onRepeatModeChanged(mRepeatMode);
-                } catch (DeadObjectException e) {
-                    mControllerCallbackHolders.remove(i);
-                    logCallbackException("Removed dead callback in pushRepeatModeUpdate",
-                            holder, e);
-                } catch (RemoteException e) {
-                    logCallbackException("unexpected exception in pushRepeatModeUpdate", holder, e);
-                }
-            }
-        }
-    }
-
-    private void pushShuffleModeUpdate() {
-        synchronized (mLock) {
-            if (mDestroyed) {
-                return;
-            }
-            for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
-                try {
-                    holder.mCallback.onShuffleModeChanged(mShuffleModeEnabled);
-                } catch (DeadObjectException e) {
-                    mControllerCallbackHolders.remove(i);
-                    logCallbackException("Removed dead callback in pushShuffleModeUpdate",
-                            holder, e);
-                } catch (RemoteException e) {
-                    logCallbackException("unexpected exception in pushShuffleModeUpdate",
-                            holder, e);
-                }
-            }
-        }
-    }
-
     private void pushSessionDestroyed() {
         synchronized (mLock) {
             // This is the only method that may be (and can only be) called
@@ -887,30 +844,6 @@
         }
 
         @Override
-        public void setRepeatMode(int repeatMode) {
-            boolean changed;
-            synchronized (mLock) {
-                changed = mRepeatMode != repeatMode;
-                mRepeatMode = repeatMode;
-            }
-            if (changed) {
-                mHandler.post(MessageHandler.MSG_UPDATE_REPEAT_MODE);
-            }
-        }
-
-        @Override
-        public void setShuffleModeEnabled(boolean enabled) {
-            boolean changed;
-            synchronized (mLock) {
-                changed = mShuffleModeEnabled != enabled;
-                mShuffleModeEnabled = enabled;
-            }
-            if (changed) {
-                mHandler.post(MessageHandler.MSG_UPDATE_SHUFFLE_MODE);
-            }
-        }
-
-        @Override
         public void setCurrentVolume(int volume) {
             mCurrentVolume = volume;
             mHandler.post(MessageHandler.MSG_UPDATE_VOLUME);
@@ -1126,54 +1059,6 @@
             }
         }
 
-        public void repeatMode(int repeatMode) {
-            try {
-                mCb.onRepeatMode(repeatMode);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Remote failure in repeatMode.", e);
-            }
-        }
-
-        public void shuffleMode(boolean enabled) {
-            try {
-                mCb.onShuffleMode(enabled);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Remote failure in shuffleMode.", e);
-            }
-        }
-
-        public void addQueueItem(MediaDescription description) {
-            try {
-                mCb.onAddQueueItem(description);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Remote failure in addQueueItem.", e);
-            }
-        }
-
-        public void addQueueItemAt(MediaDescription description, int index) {
-            try {
-                mCb.onAddQueueItemAt(description, index);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Remote failure in addQueueItemAt.", e);
-            }
-        }
-
-        public void removeQueueItem(MediaDescription description) {
-            try {
-                mCb.onRemoveQueueItem(description);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Remote failure in removeQueueItem.", e);
-            }
-        }
-
-        public void removeQueueItemAt(int index) {
-            try {
-                mCb.onRemoveQueueItemAt(index);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Remote failure in removeQueueItem.", e);
-            }
-        }
-
         public void adjustVolume(int direction) {
             try {
                 mCb.onAdjustVolume(direction);
@@ -1410,25 +1295,13 @@
         }
 
         @Override
-        public void repeatMode(int repeatMode) {
-            updateCallingPackage();
-            mSessionCb.repeatMode(repeatMode);
-        }
-
-        @Override
-        public void shuffleMode(boolean enabled) throws RemoteException {
-            updateCallingPackage();
-            mSessionCb.shuffleMode(enabled);
-        }
-
-
-        @Override
         public void sendCustomAction(String action, Bundle args)
                 throws RemoteException {
             updateCallingPackage();
             mSessionCb.sendCustomAction(action, args);
         }
 
+
         @Override
         public MediaMetadata getMetadata() {
             synchronized (mLock) {
@@ -1449,30 +1322,6 @@
         }
 
         @Override
-        public void addQueueItem(MediaDescription description) {
-            updateCallingPackage();
-            mSessionCb.addQueueItem(description);
-        }
-
-        @Override
-        public void addQueueItemAt(MediaDescription description, int index) {
-            updateCallingPackage();
-            mSessionCb.addQueueItemAt(description, index);
-        }
-
-        @Override
-        public void removeQueueItem(MediaDescription description) {
-            updateCallingPackage();
-            mSessionCb.removeQueueItem(description);
-        }
-
-        @Override
-        public void removeQueueItemAt(int index) {
-            updateCallingPackage();
-            mSessionCb.removeQueueItemAt(index);
-        }
-
-        @Override
         public CharSequence getQueueTitle() {
             return mQueueTitle;
         }
@@ -1490,16 +1339,6 @@
         }
 
         @Override
-        public int getRepeatMode() {
-            return mRepeatMode;
-        }
-
-        @Override
-        public boolean isShuffleModeEnabled() {
-            return mShuffleModeEnabled;
-        }
-
-        @Override
         public boolean isTransportControlEnabled() {
             return MediaSessionRecord.this.isTransportControlEnabled();
         }
@@ -1524,9 +1363,7 @@
         private static final int MSG_SEND_EVENT = 6;
         private static final int MSG_UPDATE_SESSION_STATE = 7;
         private static final int MSG_UPDATE_VOLUME = 8;
-        private static final int MSG_UPDATE_REPEAT_MODE = 9;
-        private static final int MSG_UPDATE_SHUFFLE_MODE = 10;
-        private static final int MSG_DESTROYED = 11;
+        private static final int MSG_DESTROYED = 9;
 
         public MessageHandler(Looper looper) {
             super(looper);
@@ -1558,12 +1395,6 @@
                 case MSG_UPDATE_VOLUME:
                     pushVolumeUpdate();
                     break;
-                case MSG_UPDATE_REPEAT_MODE:
-                    pushRepeatModeUpdate();
-                    break;
-                case MSG_UPDATE_SHUFFLE_MODE:
-                    pushShuffleModeUpdate();
-                    break;
                 case MSG_DESTROYED:
                     pushSessionDestroyed();
             }
diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java
index b0d8adc..2f82915 100644
--- a/services/core/java/com/android/server/media/MediaSessionStack.java
+++ b/services/core/java/com/android/server/media/MediaSessionStack.java
@@ -23,6 +23,7 @@
 import android.os.UserHandle;
 import android.util.IntArray;
 import android.util.Log;
+import android.util.SparseArray;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -38,7 +39,7 @@
     private static final String TAG = "MediaSessionStack";
 
     /**
-     * Listens the change in the media button session.
+     * Listen the change in the media button session.
      */
     interface OnMediaButtonSessionChangedListener {
         /**
@@ -85,7 +86,12 @@
 
     private MediaSessionRecord mCachedDefault;
     private MediaSessionRecord mCachedVolumeDefault;
-    private ArrayList<MediaSessionRecord> mCachedActiveList;
+
+    /**
+     * Cache the result of the {@link #getActiveSessions} per user.
+     */
+    private final SparseArray<ArrayList<MediaSessionRecord>> mCachedActiveLists =
+            new SparseArray<>();
 
     MediaSessionStack(AudioPlaybackMonitor monitor, OnMediaButtonSessionChangedListener listener) {
         mAudioPlaybackMonitor = monitor;
@@ -99,7 +105,7 @@
      */
     public void addSession(MediaSessionRecord record) {
         mSessions.add(record);
-        clearCache();
+        clearCache(record.getUserId());
 
         // Update the media button session.
         // The added session could be the session from the package with the audio playback.
@@ -119,7 +125,7 @@
             // in the media button session app.
             onMediaSessionChangeInMediaButtonSessionApp();
         }
-        clearCache();
+        clearCache(record.getUserId());
     }
 
     /**
@@ -140,7 +146,7 @@
         if (shouldUpdatePriority(oldState, newState)) {
             mSessions.remove(record);
             mSessions.add(0, record);
-            clearCache();
+            clearCache(record.getUserId());
         } else if (!MediaSession.isActiveState(newState)) {
             // Just clear the volume cache when a state goes inactive
             mCachedVolumeDefault = null;
@@ -163,7 +169,7 @@
     public void onSessionStateChange(MediaSessionRecord record) {
         // For now just clear the cache. Eventually we'll selectively clear
         // depending on what changed.
-        clearCache();
+        clearCache(record.getUserId());
     }
 
     /**
@@ -245,14 +251,17 @@
      * Get the current priority sorted list of active sessions. The most
      * important session is at index 0 and the least important at size - 1.
      *
-     * @param userId The user to check.
+     * @param userId The user to check. It can be {@link UserHandle#USER_ALL} to get all sessions
+     *    for all users in this {@link MediaSessionStack}.
      * @return All the active sessions in priority order.
      */
     public ArrayList<MediaSessionRecord> getActiveSessions(int userId) {
-        if (mCachedActiveList == null) {
-            mCachedActiveList = getPriorityList(true, userId);
+        ArrayList<MediaSessionRecord> cachedActiveList = mCachedActiveLists.get(userId);
+        if (cachedActiveList == null) {
+            cachedActiveList = getPriorityList(true, userId);
+            mCachedActiveLists.put(userId, cachedActiveList);
         }
-        return mCachedActiveList;
+        return cachedActiveList;
     }
 
     /**
@@ -382,9 +391,12 @@
         return false;
     }
 
-    private void clearCache() {
+    private void clearCache(int userId) {
         mCachedDefault = null;
         mCachedVolumeDefault = null;
-        mCachedActiveList = null;
+        mCachedActiveLists.remove(userId);
+        // mCachedActiveLists may also include the list of sessions for UserHandle.USER_ALL,
+        // so they also need to be cleared.
+        mCachedActiveLists.remove(UserHandle.USER_ALL);
     }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index f334ba4..cc3948e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -97,6 +97,7 @@
 import android.media.IRingtonePlayer;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
@@ -1322,7 +1323,8 @@
 
         if (!fromListener) {
             mListeners.notifyNotificationChannelChanged(
-                    pkg, modifiedChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
+                    pkg, UserHandle.getUserHandleForUid(uid),
+                    modifiedChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
         }
 
         synchronized (mNotificationLock) {
@@ -1647,7 +1649,8 @@
                 Preconditions.checkNotNull(group, "group in list is null");
                 mRankingHelper.createNotificationChannelGroup(pkg, Binder.getCallingUid(), group,
                         true /* fromTargetApp */);
-                mListeners.notifyNotificationChannelGroupChanged(pkg, group,
+                mListeners.notifyNotificationChannelGroupChanged(pkg,
+                        UserHandle.of(UserHandle.getCallingUserId()), group,
                         NOTIFICATION_CHANNEL_OR_GROUP_ADDED);
             }
             savePolicyFile();
@@ -1663,6 +1666,7 @@
                 mRankingHelper.createNotificationChannel(pkg, uid, channel,
                         true /* fromTargetApp */);
                 mListeners.notifyNotificationChannelChanged(pkg,
+                        UserHandle.getUserHandleForUid(uid),
                         mRankingHelper.getNotificationChannel(pkg, uid, channel.getId(), false),
                         NOTIFICATION_CHANNEL_OR_GROUP_ADDED);
             }
@@ -1708,6 +1712,7 @@
                     UserHandle.getUserId(callingUid), REASON_CHANNEL_BANNED, null);
             mRankingHelper.deleteNotificationChannel(pkg, callingUid, channelId);
             mListeners.notifyNotificationChannelChanged(pkg,
+                    UserHandle.getUserHandleForUid(callingUid),
                     mRankingHelper.getNotificationChannel(pkg, callingUid, channelId, true),
                     NOTIFICATION_CHANNEL_OR_GROUP_DELETED);
             savePolicyFile();
@@ -1737,11 +1742,14 @@
                             true,
                             UserHandle.getUserId(Binder.getCallingUid()), REASON_CHANNEL_BANNED,
                             null);
-                    mListeners.notifyNotificationChannelChanged(pkg, deletedChannel,
+                    mListeners.notifyNotificationChannelChanged(pkg,
+                            UserHandle.getUserHandleForUid(callingUid),
+                            deletedChannel,
                             NOTIFICATION_CHANNEL_OR_GROUP_DELETED);
                 }
                 mListeners.notifyNotificationChannelGroupChanged(
-                        pkg, groupToDelete, NOTIFICATION_CHANNEL_OR_GROUP_DELETED);
+                        pkg, UserHandle.getUserHandleForUid(callingUid), groupToDelete,
+                        NOTIFICATION_CHANNEL_OR_GROUP_DELETED);
                 savePolicyFile();
             }
         }
@@ -2691,43 +2699,59 @@
 
         @Override
         public void updateNotificationChannelFromPrivilegedListener(INotificationListener token,
-                String pkg, NotificationChannel channel) throws RemoteException {
+                String pkg, UserHandle user, NotificationChannel channel) throws RemoteException {
             Preconditions.checkNotNull(channel);
+            Preconditions.checkNotNull(pkg);
+            Preconditions.checkNotNull(user);
 
-            ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
-            if (!hasCompanionDevice(info)) {
-                throw new SecurityException(info + " does not have access");
-            }
-
-            int uid = mPackageManager.getPackageUid(pkg, 0, info.userid);
-            updateNotificationChannelInt(pkg, uid, channel, true);
+            verifyPrivilegedListener(token, user);
+            updateNotificationChannelInt(pkg, getUidForPackageAndUser(pkg, user), channel, true);
         }
 
         @Override
         public ParceledListSlice<NotificationChannel> getNotificationChannelsFromPrivilegedListener(
-                INotificationListener token, String pkg) throws RemoteException {
-            ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
-            if (!hasCompanionDevice(info)) {
-                throw new SecurityException(info + " does not have access");
-            }
+                INotificationListener token, String pkg, UserHandle user) throws RemoteException {
+            Preconditions.checkNotNull(pkg);
+            Preconditions.checkNotNull(user);
+            verifyPrivilegedListener(token, user);
 
-            int uid = mPackageManager.getPackageUid(pkg, 0, info.userid);
-            return mRankingHelper.getNotificationChannels(pkg, uid, false /* includeDeleted */);
+            return mRankingHelper.getNotificationChannels(pkg, getUidForPackageAndUser(pkg, user),
+                    false /* includeDeleted */);
         }
 
         @Override
         public ParceledListSlice<NotificationChannelGroup>
                 getNotificationChannelGroupsFromPrivilegedListener(
-                INotificationListener token, String pkg) throws RemoteException {
+                INotificationListener token, String pkg, UserHandle user) throws RemoteException {
+            Preconditions.checkNotNull(pkg);
+            Preconditions.checkNotNull(user);
+            verifyPrivilegedListener(token, user);
+
+            List<NotificationChannelGroup> groups = new ArrayList<>();
+            groups.addAll(mRankingHelper.getNotificationChannelGroups(
+                    pkg, getUidForPackageAndUser(pkg, user)));
+            return new ParceledListSlice<>(groups);
+        }
+
+        private void verifyPrivilegedListener(INotificationListener token, UserHandle user) {
             ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
             if (!hasCompanionDevice(info)) {
                 throw new SecurityException(info + " does not have access");
             }
+            if (!info.enabledAndUserMatches(user.getIdentifier())) {
+                throw new SecurityException(info + " does not have access");
+            }
+        }
 
-            List<NotificationChannelGroup> groups = new ArrayList<>();
-            int uid = mPackageManager.getPackageUid(pkg, 0, info.userid);
-            groups.addAll(mRankingHelper.getNotificationChannelGroups(pkg, uid));
-            return new ParceledListSlice<>(groups);
+        private int getUidForPackageAndUser(String pkg, UserHandle user) throws RemoteException {
+            int uid = 0;
+            long identity = Binder.clearCallingIdentity();
+            try {
+                uid = mPackageManager.getPackageUid(pkg, 0, user.getIdentifier());
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+            return uid;
         }
     };
 
@@ -3162,16 +3186,16 @@
             // STOPSHIP TODO: should throw instead of logging or toasting.
             // throw new IllegalArgumentException(noChannelStr);
             Log.e(TAG, noChannelStr);
-
-            final String noChannelToastStr =
-                    "Developer warning for package \"" + pkg + "\"\n" +
+            doDebugOnlyToast("Developer warning for package \"" + pkg + "\"\n" +
                     "Failed to post notification on channel \"" + channelId + "\"\n" +
-                    "See log for more details";
-            Toast noChannelToast =
-                    Toast.makeText(getContext(), noChannelToastStr, Toast.LENGTH_LONG);
-            noChannelToast.show();
+                    "See log for more details");
             return;
+        } else if (channelId == null && shouldWarnUseChannels(pkg, notificationUid)) {
+            // STOPSHIP TODO: remove once default channel is removed for all apps that target O.
+            doDebugOnlyToast("Developer warning for package \"" + pkg + "\"\n" +
+                    "Posted notification should specify a channel");
         }
+
         final StatusBarNotification n = new StatusBarNotification(
                 pkg, opPkg, id, tag, notificationUid, callingPid, notification,
                 user, null, System.currentTimeMillis());
@@ -3203,6 +3227,26 @@
         idOut[0] = id;
     }
 
+    private void doDebugOnlyToast(CharSequence toastText) {
+        if (Build.IS_DEBUGGABLE) {
+            Toast toast = Toast.makeText(getContext(), toastText, Toast.LENGTH_LONG);
+            toast.show();
+        }
+    }
+
+    // STOPSHIP - Remove once RankingHelper deletes default channel for all apps targeting O.
+    private boolean shouldWarnUseChannels(String pkg, int uid) {
+        try {
+            final int userId = UserHandle.getUserId(uid);
+            final ApplicationInfo applicationInfo =
+                    mPackageManagerClient.getApplicationInfoAsUser(pkg, 0, userId);
+            return applicationInfo.targetSdkVersion > Build.VERSION_CODES.N_MR1;
+        } catch (NameNotFoundException e) {
+            Slog.e(TAG, e.toString());
+            return false;
+        }
+    }
+
     private int resolveNotificationUid(String opPackageName, int callingUid, int userId) {
         // The system can post notifications on behalf of any package it wants
         if (isCallerSystem() && opPackageName != null && !"android".equals(opPackageName)) {
@@ -5019,7 +5063,7 @@
             }
         }
 
-        protected void notifyNotificationChannelChanged(final String pkg,
+        protected void notifyNotificationChannelChanged(final String pkg, final UserHandle user,
                 final NotificationChannel channel, final int modificationType) {
             if (channel == null) {
                 return;
@@ -5034,15 +5078,16 @@
                 mHandler.post(new Runnable() {
                     @Override
                     public void run() {
-                        notifyNotificationChannelChanged(serviceInfo, pkg, channel,
-                                modificationType);
+                        notifyNotificationChannelChanged(
+                                serviceInfo, pkg, user, channel, modificationType);
                     }
                 });
             }
         }
 
-        protected void notifyNotificationChannelGroupChanged(final String pkg,
-                final NotificationChannelGroup group, final int modificationType) {
+        protected void notifyNotificationChannelGroupChanged(
+                final String pkg, final UserHandle user, final NotificationChannelGroup group,
+                final int modificationType) {
             if (group == null) {
                 return;
             }
@@ -5056,8 +5101,8 @@
                 mHandler.post(new Runnable() {
                     @Override
                     public void run() {
-                        notifyNotificationChannelGroupChanged(serviceInfo, pkg, group,
-                                modificationType);
+                        notifyNotificationChannelGroupChanged(
+                                serviceInfo, pkg, user, group, modificationType);
                     }
                 });
             }
@@ -5118,22 +5163,22 @@
         }
 
         void notifyNotificationChannelChanged(ManagedServiceInfo info,
-                final String pkg, final NotificationChannel channel,
+                final String pkg, final UserHandle user, final NotificationChannel channel,
                 final int modificationType) {
             final INotificationListener listener = (INotificationListener) info.service;
             try {
-                listener.onNotificationChannelModification(pkg, channel, modificationType);
+                listener.onNotificationChannelModification(pkg, user, channel, modificationType);
             } catch (RemoteException ex) {
                 Log.e(TAG, "unable to notify listener (channel changed): " + listener, ex);
             }
         }
 
         private void notifyNotificationChannelGroupChanged(ManagedServiceInfo info,
-                final String pkg, final NotificationChannelGroup group,
+                final String pkg, final UserHandle user, final NotificationChannelGroup group,
                 final int modificationType) {
             final INotificationListener listener = (INotificationListener) info.service;
             try {
-                listener.onNotificationChannelGroupModification(pkg, group, modificationType);
+                listener.onNotificationChannelGroupModification(pkg, user, group, modificationType);
             } catch (RemoteException ex) {
                 Log.e(TAG, "unable to notify listener (channel group changed): " + listener, ex);
             }
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index b7d3173..b48fd5c 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -172,7 +172,7 @@
             final boolean useDefaultSound = (n.defaults & Notification.DEFAULT_SOUND) != 0;
             if (useDefaultSound) {
                 sound = Settings.System.DEFAULT_NOTIFICATION_URI;
-            } else if (n.sound != null) {
+            } else {
                 sound = n.sound;
             }
         }
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 7b86542..2e4b49a 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -274,23 +274,56 @@
         // Intercept and collect dexopt requests
         final List<String> commands = new ArrayList<String>();
         final Installer collectingInstaller = new Installer(mContext, true) {
+            /**
+             * Encode the dexopt command into a string.
+             *
+             * Note: If you have to change the signature of this function, increase the version
+             *       number, and update the counterpart in
+             *       frameworks/native/cmds/installd/otapreopt.cpp.
+             */
             @Override
             public void dexopt(String apkPath, int uid, @Nullable String pkgName,
                     String instructionSet, int dexoptNeeded, @Nullable String outputPath,
                     int dexFlags, String compilerFilter, @Nullable String volumeUuid,
                     @Nullable String sharedLibraries, @Nullable String seInfo) throws InstallerException {
-                commands.add(buildCommand("dexopt",
-                        apkPath,
-                        uid,
-                        pkgName,
-                        instructionSet,
-                        dexoptNeeded,
-                        outputPath,
-                        dexFlags,
-                        compilerFilter,
-                        volumeUuid,
-                        sharedLibraries,
-                        seInfo));
+                final StringBuilder builder = new StringBuilder();
+
+                // The version. Right now it's 2.
+                builder.append("2 ");
+
+                builder.append("dexopt");
+
+                encodeParameter(builder, apkPath);
+                encodeParameter(builder, uid);
+                encodeParameter(builder, pkgName);
+                encodeParameter(builder, instructionSet);
+                encodeParameter(builder, dexoptNeeded);
+                encodeParameter(builder, outputPath);
+                encodeParameter(builder, dexFlags);
+                encodeParameter(builder, compilerFilter);
+                encodeParameter(builder, volumeUuid);
+                encodeParameter(builder, sharedLibraries);
+                encodeParameter(builder, seInfo);
+
+                commands.add(builder.toString());
+            }
+
+            /**
+             * Encode a parameter as necessary for the commands string.
+             */
+            private void encodeParameter(StringBuilder builder, Object arg) {
+                builder.append(' ');
+
+                if (arg == null) {
+                    builder.append('!');
+                }
+
+                String txt = String.valueOf(arg);
+                if (txt.indexOf('\0') != -1 || txt.indexOf(' ') != -1 || "!".equals(txt)) {
+                    throw new IllegalArgumentException(
+                            "Invalid argument while executing " + arg);
+                }
+                builder.append(txt);
             }
         };
 
@@ -430,28 +463,4 @@
             super(installer, installLock, context, "*otadexopt*");
         }
     }
-
-    /**
-     * Cook up argument list in the format that {@code installd} expects.
-     */
-    private static String buildCommand(Object... args) {
-        final StringBuilder builder = new StringBuilder();
-        for (Object arg : args) {
-            String escaped;
-            if (arg == null) {
-                escaped = "";
-            } else {
-                escaped = String.valueOf(arg);
-            }
-            if (escaped.indexOf('\0') != -1 || escaped.indexOf(' ') != -1 || "!".equals(escaped)) {
-                throw new IllegalArgumentException(
-                        "Invalid argument while executing " + Arrays.toString(args));
-            }
-            if (TextUtils.isEmpty(escaped)) {
-                escaped = "!";
-            }
-            builder.append(' ').append(escaped);
-        }
-        return builder.toString();
-    }
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 650d2f6..312c310 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -364,7 +364,8 @@
  * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
  * </pre>
  */
-public class PackageManagerService extends IPackageManager.Stub {
+public class PackageManagerService extends IPackageManager.Stub
+        implements PackageSender {
     static final String TAG = "PackageManager";
     static final boolean DEBUG_SETTINGS = false;
     static final boolean DEBUG_PREFERRED = false;
@@ -13083,7 +13084,7 @@
         }
     };
 
-    final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
+    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
             final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
             final int[] userIds) {
         mHandler.post(new Runnable() {
@@ -13201,7 +13202,7 @@
                 if (dcsUid > 0) {
                     am.backgroundWhitelistUid(dcsUid);
                 }
-                am.startService(null, intent, null, -1, null, false, mContext.getOpPackageName(),
+                am.startService(null, intent, null, false, mContext.getOpPackageName(),
                         UserHandle.USER_SYSTEM);
             } catch (RemoteException e) {
             }
@@ -13386,8 +13387,7 @@
         sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId);
     }
 
-    private void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
-            int appId, int... userIds) {
+    public void sendPackageAddedForNewUsers(String packageName, boolean isSystem, int appId, int... userIds) {
         if (ArrayUtils.isEmpty(userIds)) {
             return;
         }
@@ -13514,7 +13514,7 @@
 
     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
             int userId) {
-        final PackageRemovedInfo info = new PackageRemovedInfo();
+        final PackageRemovedInfo info = new PackageRemovedInfo(this);
         info.removedPackage = packageName;
         info.removedUsers = new int[] {userId};
         info.broadcastUsers = new int[] {userId};
@@ -16150,7 +16150,7 @@
         }
 
         // Update what is removed
-        res.removedInfo = new PackageRemovedInfo();
+        res.removedInfo = new PackageRemovedInfo(this);
         res.removedInfo.uid = oldPackage.applicationInfo.uid;
         res.removedInfo.removedPackage = oldPackage.packageName;
         res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
@@ -16180,7 +16180,7 @@
                 }
             }
             if (!childPackageUpdated) {
-                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo();
+                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
                 childRemovedRes.removedPackage = childPkg.packageName;
                 childRemovedRes.isUpdate = false;
                 childRemovedRes.dataRemoved = true;
@@ -16870,7 +16870,7 @@
                                 sUserManager.getUserIds(), true);
                     }
                     if ((mPackages.containsKey(childPkg.packageName))) {
-                        childRes.removedInfo = new PackageRemovedInfo();
+                        childRes.removedInfo = new PackageRemovedInfo(this);
                         childRes.removedInfo.removedPackage = childPkg.packageName;
                     }
                     if (res.addedChildPackages == null) {
@@ -17716,7 +17716,7 @@
      *  sending a broadcast if necessary
      */
     private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
-        final PackageRemovedInfo info = new PackageRemovedInfo();
+        final PackageRemovedInfo info = new PackageRemovedInfo(this);
         final boolean res;
 
         final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
@@ -17816,7 +17816,8 @@
         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
     }
 
-    class PackageRemovedInfo {
+    static class PackageRemovedInfo {
+        final PackageSender packageSender;
         String removedPackage;
         int uid = -1;
         int removedAppId = -1;
@@ -17834,6 +17835,10 @@
         ArrayMap<String, PackageRemovedInfo> removedChildPackages;
         ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
 
+        PackageRemovedInfo(PackageSender packageSender) {
+            this.packageSender = packageSender;
+        }
+
         void sendPackageRemovedBroadcasts(boolean killApp) {
             sendPackageRemovedBroadcastInternal(killApp);
             final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
@@ -17862,8 +17867,9 @@
                     ? appearedChildPackages.size() : 0;
             for (int i = 0; i < packageCount; i++) {
                 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
-                sendPackageAddedForNewUsers(installedInfo.name, true,
-                        UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers);
+                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
+                    true, UserHandle.getAppId(installedInfo.uid),
+                    installedInfo.newUsers);
             }
         }
 
@@ -17871,12 +17877,12 @@
             Bundle extras = new Bundle(2);
             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
             extras.putBoolean(Intent.EXTRA_REPLACING, true);
-            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage,
-                    extras, 0, null, null, null);
-            sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
-                    extras, 0, null, null, null);
-            sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
-                    null, 0, removedPackage, null, null);
+            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
+                removedPackage, extras, 0, null, null, null);
+            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
+                removedPackage, extras, 0, null, null, null);
+            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
+                null, null, 0, removedPackage, null, null);
         }
 
         private void sendPackageRemovedBroadcastInternal(boolean killApp) {
@@ -17895,17 +17901,35 @@
             }
             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
             if (removedPackage != null) {
-                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
-                        extras, 0, null, null, broadcastUsers);
+                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
+                    removedPackage, extras, 0, null, null, broadcastUsers);
                 if (dataRemoved && !isRemovedPackageSystemUpdate) {
-                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
-                            removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
-                            null, null, broadcastUsers);
+                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
+                        removedPackage, extras,
+                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
+                        null, null, broadcastUsers);
                 }
             }
             if (removedAppId >= 0) {
-                sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null,
-                        broadcastUsers);
+                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras,
+                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, broadcastUsers);
+            }
+        }
+
+        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
+            removedUsers = userIds;
+            if (removedUsers == null) {
+                broadcastUsers = null;
+                return;
+            }
+
+            broadcastUsers = EMPTY_INT_ARRAY;
+            for (int i = userIds.length - 1; i >= 0; --i) {
+                final int userId = userIds[i];
+                if (deletedPackageSetting.getInstantApp(userId)) {
+                    continue;
+                }
+                broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
             }
         }
     }
@@ -17931,23 +17955,8 @@
                 outInfo.removedPackage = packageName;
                 outInfo.isStaticSharedLib = deletedPkg != null
                         && deletedPkg.staticSharedLibName != null;
-                outInfo.removedUsers = deletedPs != null
-                        ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
-                        : null;
-                if (outInfo.removedUsers == null) {
-                    outInfo.broadcastUsers = null;
-                } else {
-                    outInfo.broadcastUsers = EMPTY_INT_ARRAY;
-                    int[] allUsers = outInfo.removedUsers;
-                    for (int i = allUsers.length - 1; i >= 0; --i) {
-                        final int userId = allUsers[i];
-                        if (deletedPs.getInstantApp(userId)) {
-                            continue;
-                        }
-                        outInfo.broadcastUsers =
-                                ArrayUtils.appendInt(outInfo.broadcastUsers, userId);
-                    }
-                }
+                outInfo.populateUsers(deletedPs == null ? null
+                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
             }
         }
 
@@ -18430,7 +18439,7 @@
                 outInfo.removedChildPackages = new ArrayMap<>(childCount);
                 for (int i = 0; i < childCount; i++) {
                     String childPackageName = ps.childPackageNames.get(i);
-                    PackageRemovedInfo childInfo = new PackageRemovedInfo();
+                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
                     childInfo.removedPackage = childPackageName;
                     outInfo.removedChildPackages.put(childPackageName, childInfo);
                     PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
@@ -21692,7 +21701,7 @@
             if (DEBUG_SD_INSTALL)
                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
             // Delete package internally
-            PackageRemovedInfo outInfo = new PackageRemovedInfo();
+            PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
             synchronized (mInstallLock) {
                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
                 final boolean res;
@@ -21859,7 +21868,7 @@
 
                 final ApplicationInfo info = ps.pkg.applicationInfo;
                 final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
-                final PackageRemovedInfo outInfo = new PackageRemovedInfo();
+                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
 
                 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
                         "unloadPrivatePackagesInner")) {
@@ -23636,4 +23645,18 @@
     public ComponentName getInstantAppResolverSettingsComponent() {
         return mInstantAppResolverSettingsComponent;
     }
+
+    @Override
+    public ComponentName getInstantAppInstallerComponent() {
+        return mInstantAppInstallerActivity == null
+                ? null : mInstantAppInstallerActivity.getComponentName();
+    }
+}
+
+interface PackageSender {
+    void sendPackageBroadcast(final String action, final String pkg,
+        final Bundle extras, final int flags, final String targetPkg,
+        final IIntentReceiver finishedReceiver, final int[] userIds);
+    void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
+        int appId, int... userIds);
 }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 4f29bfa..bcb4121 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -222,9 +222,10 @@
 import android.view.animation.Animation;
 import android.view.animation.AnimationSet;
 import android.view.animation.AnimationUtils;
+import android.view.inputmethod.InputMethodManagerInternal;
 import android.widget.ImageView;
-
 import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.policy.IShortcutService;
@@ -279,6 +280,7 @@
     static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP = 2;
     static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME = 3;
     static final int SHORT_PRESS_POWER_GO_HOME = 4;
+    static final int SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME = 5;
 
     static final int LONG_PRESS_POWER_NOTHING = 0;
     static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
@@ -407,6 +409,7 @@
     PowerManager mPowerManager;
     ActivityManagerInternal mActivityManagerInternal;
     InputManagerInternal mInputManagerInternal;
+    InputMethodManagerInternal mInputMethodManagerInternal;
     DreamManagerInternal mDreamManagerInternal;
     PowerManagerInternal mPowerManagerInternal;
     IStatusBarService mStatusBarService;
@@ -494,6 +497,9 @@
     WindowState mLastInputMethodWindow = null;
     WindowState mLastInputMethodTargetWindow = null;
 
+    @GuardedBy("mLock")
+    private boolean mDismissImeOnBackKeyPressed;
+
     // FIXME This state is shared between the input reader and handler thread.
     // Technically it's broken and buggy but it has been like this for many years
     // and we have not yet seen any problems.  Someday we'll rewrite this logic
@@ -1396,6 +1402,27 @@
                 case SHORT_PRESS_POWER_GO_HOME:
                     launchHomeFromHotKey(true /* awakenFromDreams */, false /*respectKeyguard*/);
                     break;
+                case SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME: {
+                    final boolean dismissImeOnBackKeyPressed;
+                    // We can be here on both the main thread (via mHandler) and native callback
+                    // thread (from interceptPowerKeyUp via WindowManagerCallbacks).
+                    synchronized (mLock) {
+                        dismissImeOnBackKeyPressed = mDismissImeOnBackKeyPressed;
+                    }
+                    if (dismissImeOnBackKeyPressed) {
+                        if (mInputMethodManagerInternal == null) {
+                            mInputMethodManagerInternal =
+                                    LocalServices.getService(InputMethodManagerInternal.class);
+                        }
+                        if (mInputMethodManagerInternal != null) {
+                            mInputMethodManagerInternal.hideCurrentInputMethod();
+                        }
+                    } else {
+                        launchHomeFromHotKey(true /* awakenFromDreams */,
+                                false /*respectKeyguard*/);
+                    }
+                    break;
+                }
             }
         }
     }
@@ -7955,6 +7982,13 @@
     }
 
     @Override
+    public void setDismissImeOnBackKeyPressed(boolean newValue) {
+        synchronized (mLock) {
+            mDismissImeOnBackKeyPressed = newValue;
+        }
+    }
+
+    @Override
     public int getInputMethodWindowVisibleHeightLw() {
         return mDockBottom - mCurBottom;
     }
@@ -8170,6 +8204,8 @@
             pw.print(prefix); pw.print("mLastInputMethodTargetWindow=");
                     pw.println(mLastInputMethodTargetWindow);
         }
+        pw.print(prefix); pw.print("mDismissImeOnBackKeyPressed=");
+                pw.println(mDismissImeOnBackKeyPressed);
         if (mStatusBar != null) {
             pw.print(prefix); pw.print("mStatusBar=");
                     pw.print(mStatusBar); pw.print(" isStatusBarKeyguard=");
diff --git a/services/core/java/com/android/server/storage/AppCollector.java b/services/core/java/com/android/server/storage/AppCollector.java
index a77d33f..03b754f 100644
--- a/services/core/java/com/android/server/storage/AppCollector.java
+++ b/services/core/java/com/android/server/storage/AppCollector.java
@@ -21,22 +21,21 @@
 import android.app.usage.StorageStatsManager;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageStatsObserver;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PackageStats;
 import android.content.pm.UserInfo;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Process;
-import android.os.RemoteException;
 import android.os.UserManager;
 import android.os.storage.VolumeInfo;
 import android.util.Log;
+
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.Preconditions;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -44,7 +43,6 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * AppCollector asynchronously collects package sizes.
@@ -132,7 +130,7 @@
 
                             try {
                                 StorageStats storageStats =
-                                        mStorageStatsManager.queryStatsForPackage(app.volumeUuid,
+                                        mStorageStatsManager.queryStatsForPackage(app.storageUuid,
                                                 app.packageName, user.getUserHandle());
                                 PackageStats packageStats = new PackageStats(app.packageName,
                                         user.id);
@@ -140,7 +138,7 @@
                                 packageStats.codeSize = storageStats.getCodeBytes();
                                 packageStats.dataSize = storageStats.getDataBytes();
                                 stats.add(packageStats);
-                            } catch (IllegalStateException e) {
+                            } catch (NameNotFoundException | IOException e) {
                                 Log.e(TAG, "An exception occurred while fetching app size", e);
                             }
                         }
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index f41eed5..e634552 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -22,6 +22,7 @@
 
 import android.animation.Animator;
 import android.animation.ValueAnimator;
+import android.annotation.IntDef;
 import android.content.Context;
 import android.graphics.Rect;
 import android.os.Handler;
@@ -35,6 +36,9 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Enables animating bounds of objects.
  *
@@ -43,7 +47,7 @@
  * relaunching it would cause poorer experience), these class provides a way to directly animate
  * the bounds of the resized object.
  *
- * The object that is resized needs to implement {@link AnimateBoundsUser} interface.
+ * The object that is resized needs to implement {@link BoundsAnimationTarget} interface.
  *
  * NOTE: All calls to methods in this class should be done on the UI thread
  */
@@ -56,8 +60,19 @@
 
     private static final int DEFAULT_TRANSITION_DURATION = 425;
 
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({NO_PIP_MODE_CHANGED_CALLBACKS, SCHEDULE_PIP_MODE_CHANGED_ON_START,
+        SCHEDULE_PIP_MODE_CHANGED_ON_END})
+    public @interface SchedulePipModeChangedState {}
+    /** Do not schedule any PiP mode changed callbacks as a part of this animation. */
+    public static final int NO_PIP_MODE_CHANGED_CALLBACKS = 0;
+    /** Schedule a PiP mode changed callback when this animation starts. */
+    public static final int SCHEDULE_PIP_MODE_CHANGED_ON_START = 1;
+    /** Schedule a PiP mode changed callback when this animation ends. */
+    public static final int SCHEDULE_PIP_MODE_CHANGED_ON_END = 2;
+
     // Only accessed on UI thread.
-    private ArrayMap<AnimateBoundsUser, BoundsAnimator> mRunningAnimations = new ArrayMap<>();
+    private ArrayMap<BoundsAnimationTarget, BoundsAnimator> mRunningAnimations = new ArrayMap<>();
 
     private final class AppTransitionNotifier
             extends WindowManagerInternal.AppTransitionListener implements Runnable {
@@ -108,40 +123,42 @@
     @VisibleForTesting
     final class BoundsAnimator extends ValueAnimator
             implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener {
-        private final AnimateBoundsUser mTarget;
+        private final BoundsAnimationTarget mTarget;
         private final Rect mFrom = new Rect();
         private final Rect mTo = new Rect();
         private final Rect mTmpRect = new Rect();
         private final Rect mTmpTaskBounds = new Rect();
-        private final boolean mMoveToFullScreen;
-        // True if this this animation was cancelled and will be replaced the another animation from
-        // the same {@link #AnimateBoundsUser} target.
+
+        // True if this this animation was canceled and will be replaced the another animation from
+        // the same {@link #BoundsAnimationTarget} target.
         private boolean mSkipFinalResize;
         // True if this animation replaced a previous animation of the same
-        // {@link #AnimateBoundsUser} target.
+        // {@link #BoundsAnimationTarget} target.
         private final boolean mSkipAnimationStart;
-        // True if this animation was cancelled by the user, not as a part of a replacing animation
+        // True if this animation was canceled by the user, not as a part of a replacing animation
         private boolean mSkipAnimationEnd;
-        // True if this animation is not replacing a previous animation, or if the previous
-        // animation is animating to a different fullscreen state than the current animation.
-        // We use this to ensure that we always provide a consistent set/order of callbacks when we
-        // transition to/from PiP.
-        private final boolean mAnimatingToNewFullscreenState;
+        // True if the animation target should be moved to the fullscreen stack at the end of this
+        // animation
+        private boolean mMoveToFullscreen;
+
+        // Whether to schedule PiP mode changes on animation start/end
+        private @SchedulePipModeChangedState int mSchedulePipModeChangedState;
 
         // Depending on whether we are animating from
         // a smaller to a larger size
         private final int mFrozenTaskWidth;
         private final int mFrozenTaskHeight;
 
-        BoundsAnimator(AnimateBoundsUser target, Rect from, Rect to, boolean moveToFullScreen,
-                boolean replacingExistingAnimation, boolean animatingToNewFullscreenState) {
+        BoundsAnimator(BoundsAnimationTarget target, Rect from, Rect to,
+                @SchedulePipModeChangedState int schedulePipModeChangedState,
+                boolean moveToFullscreen, boolean replacingExistingAnimation) {
             super();
             mTarget = target;
             mFrom.set(from);
             mTo.set(to);
-            mMoveToFullScreen = moveToFullScreen;
             mSkipAnimationStart = replacingExistingAnimation;
-            mAnimatingToNewFullscreenState = animatingToNewFullscreenState;
+            mSchedulePipModeChangedState = schedulePipModeChangedState;
+            mMoveToFullscreen = moveToFullscreen;
             addUpdateListener(this);
             addListener(this);
 
@@ -161,7 +178,8 @@
         @Override
         public void onAnimationStart(Animator animation) {
             if (DEBUG) Slog.d(TAG, "onAnimationStart: mTarget=" + mTarget
-                    + " mSkipAnimationStart=" + mSkipAnimationStart);
+                    + " mSkipAnimationStart=" + mSkipAnimationStart
+                    + " mSchedulePipModeChangedState=" + mSchedulePipModeChangedState);
             mFinishAnimationAfterTransition = false;
             mTmpRect.set(mFrom.left, mFrom.top, mFrom.left + mFrozenTaskWidth,
                     mFrom.top + mFrozenTaskHeight);
@@ -170,13 +188,8 @@
             // we trigger any size changes, so it can swap surfaces
             // in to appropriate modes, or do as it wishes otherwise.
             if (!mSkipAnimationStart) {
-                mTarget.onAnimationStart(mMoveToFullScreen);
-            }
-
-            // If we are animating to a new fullscreen state (either to/from fullscreen), then
-            // notify the target of the change with the new frozen task bounds
-            if (mAnimatingToNewFullscreenState && mMoveToFullScreen) {
-                mTarget.updatePictureInPictureMode(null);
+                mTarget.onAnimationStart(mSchedulePipModeChangedState ==
+                        SCHEDULE_PIP_MODE_CHANGED_ON_START);
             }
 
             // Immediately update the task bounds if they have to become larger, but preserve
@@ -206,20 +219,26 @@
                 // any further animation.
                 if (DEBUG) Slog.d(TAG, "animateUpdate: cancelled");
 
+                // If we have already scheduled a PiP mode changed at the start of the animation,
+                // then we need to clean up and schedule one at the end, since we have canceled the
+                // animation to the final state.
+                if (mSchedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START) {
+                    mSchedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_END;
+                }
+
                 // Since we are cancelling immediately without a replacement animation, send the
                 // animation end to maintain callback parity, but also skip any further resizes
-                prepareCancel(false /* skipAnimationEnd */, true /* skipFinalResize */);
-                cancel();
+                cancelAndCallAnimationEnd();
             }
         }
 
         @Override
         public void onAnimationEnd(Animator animation) {
             if (DEBUG) Slog.d(TAG, "onAnimationEnd: mTarget=" + mTarget
-                    + " mMoveToFullScreen=" + mMoveToFullScreen
                     + " mSkipFinalResize=" + mSkipFinalResize
                     + " mFinishAnimationAfterTransition=" + mFinishAnimationAfterTransition
-                    + " mAppTransitionIsRunning=" + mAppTransition.isRunning());
+                    + " mAppTransitionIsRunning=" + mAppTransition.isRunning()
+                    + " callers=" + Debug.getCallers(2));
 
             // There could be another animation running. For example in the
             // move to fullscreen case, recents will also be closing while the
@@ -231,58 +250,57 @@
                 return;
             }
 
-            if (!mSkipFinalResize) {
-                // If not cancelled, resize the pinned stack to the final size. All calls to
-                // setPinnedStackSize() must be done between onAnimationStart() and onAnimationEnd()
-                mTarget.setPinnedStackSize(mTo, null);
+            if (!mSkipAnimationEnd) {
+                // If this animation has already scheduled the picture-in-picture mode on start, and
+                // we are not skipping the final resize due to being canceled, then move the PiP to
+                // fullscreen once the animation ends
+                if (DEBUG) Slog.d(TAG, "onAnimationEnd: mTarget=" + mTarget
+                        + " moveToFullscreen=" + mMoveToFullscreen);
+                mTarget.onAnimationEnd(mSchedulePipModeChangedState ==
+                        SCHEDULE_PIP_MODE_CHANGED_ON_END, !mSkipFinalResize ? mTo : null,
+                                mMoveToFullscreen);
             }
 
-            finishAnimation();
-
-            if (mMoveToFullScreen && !mSkipFinalResize) {
-                mTarget.moveToFullscreen();
-            }
+            // Clean up this animation
+            removeListener(this);
+            removeUpdateListener(this);
+            mRunningAnimations.remove(mTarget);
         }
 
         @Override
         public void onAnimationCancel(Animator animation) {
-            finishAnimation();
+            // Always skip the final resize when the animation is canceled
+            mSkipFinalResize = true;
+            mMoveToFullscreen = false;
         }
 
-        public void prepareCancel(boolean skipAnimationEnd, boolean skipFinalResize) {
-            if (DEBUG) Slog.d(TAG, "prepareCancel: skipAnimationEnd=" + skipAnimationEnd
-                    + " skipFinalResize=" + skipFinalResize);
-            mSkipAnimationEnd = skipAnimationEnd;
-            mSkipFinalResize = skipFinalResize;
+        private void cancelAndCallAnimationEnd() {
+            if (DEBUG) Slog.d(TAG, "cancelAndCallAnimationEnd: mTarget=" + mTarget);
+            mSkipAnimationEnd = false;
+            super.cancel();
         }
 
         @Override
         public void cancel() {
             if (DEBUG) Slog.d(TAG, "cancel: mTarget=" + mTarget);
+            mSkipAnimationEnd = true;
             super.cancel();
         }
 
-        /** Returns true if the animation target is the same as the input bounds. */
+        /**
+         * @return true if the animation target is the same as the input bounds.
+         */
         boolean isAnimatingTo(Rect bounds) {
             return mTo.equals(bounds);
         }
 
-        private boolean animatingToLargerSize() {
-            if (mFrom.width() * mFrom.height() > mTo.width() * mTo.height()) {
-                return false;
-            }
-            return true;
-        }
-
-        private void finishAnimation() {
-            if (DEBUG) Slog.d(TAG, "finishAnimation: mTarget=" + mTarget
-                    + " callers" + Debug.getCallers(2));
-            if (!mSkipAnimationEnd) {
-                mTarget.onAnimationEnd();
-            }
-            removeListener(this);
-            removeUpdateListener(this);
-            mRunningAnimations.remove(mTarget);
+        /**
+         * @return true if we are animating to a larger surface size
+         */
+        @VisibleForTesting
+        boolean animatingToLargerSize() {
+            // TODO: Fix this check for aspect ratio changes
+            return (mFrom.width() * mFrom.height() <= mTo.width() * mTo.height());
         }
 
         @Override
@@ -291,63 +309,23 @@
         }
     }
 
-    public interface AnimateBoundsUser {
-        /**
-         * Sets the size of the target (without any intermediate steps, like scheduling animation)
-         * but freezes the bounds of any tasks in the target at taskBounds,
-         * to allow for more flexibility during resizing. Only works for the pinned stack at the
-         * moment.
-         *
-         * @return Whether the target should continue to be animated and this call was successful.
-         * If false, the animation will be cancelled because the user has determined that the
-         * animation is now invalid and not required. In such a case, the cancel will trigger the
-         * animation end callback as well, but will not send any further size changes.
-         */
-        boolean setPinnedStackSize(Rect bounds, Rect taskBounds);
-
-        /**
-         * Callback for the target to inform it that the animation has started, so it can do some
-         * necessary preparation.
-         */
-        void onAnimationStart(boolean toFullscreen);
-
-        /**
-         * Callback for the target to inform it that the animation is going to a new fullscreen
-         * state and should update the picture-in-picture mode accordingly.
-         *
-         * @param targetStackBounds the target stack bounds we are animating to, can be null if
-         *                          we are animating to fullscreen
-         */
-        void updatePictureInPictureMode(Rect targetStackBounds);
-
-        /**
-         * Callback for the target to inform it that the animation has ended, so it can do some
-         * necessary cleanup.
-         */
-        void onAnimationEnd();
-
-        /**
-         * Callback for the target to inform it to reparent to the fullscreen stack.
-         */
-        void moveToFullscreen();
-    }
-
-    public void animateBounds(final AnimateBoundsUser target, Rect from, Rect to,
-            int animationDuration, boolean moveToFullscreen) {
-        animateBoundsImpl(target, from, to, animationDuration, moveToFullscreen);
+    public void animateBounds(final BoundsAnimationTarget target, Rect from, Rect to,
+            int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState,
+            boolean moveToFullscreen) {
+        animateBoundsImpl(target, from, to, animationDuration, schedulePipModeChangedState,
+                moveToFullscreen);
     }
 
     @VisibleForTesting
-    BoundsAnimator animateBoundsImpl(final AnimateBoundsUser target, Rect from, Rect to,
-            int animationDuration, boolean moveToFullscreen) {
+    BoundsAnimator animateBoundsImpl(final BoundsAnimationTarget target, Rect from, Rect to,
+            int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState,
+            boolean moveToFullscreen) {
         final BoundsAnimator existing = mRunningAnimations.get(target);
         final boolean replacing = existing != null;
-        final boolean animatingToNewFullscreenState = (existing == null) ||
-                (existing.mMoveToFullScreen != moveToFullscreen);
 
         if (DEBUG) Slog.d(TAG, "animateBounds: target=" + target + " from=" + from + " to=" + to
-                + " moveToFullscreen=" + moveToFullscreen + " replacing=" + replacing
-                + " animatingToNewFullscreenState=" + animatingToNewFullscreenState);
+                + " schedulePipModeChangedState=" + schedulePipModeChangedState
+                + " replacing=" + replacing);
 
         if (replacing) {
             if (existing.isAnimatingTo(to)) {
@@ -355,15 +333,36 @@
                 // one we are trying to start.
                 if (DEBUG) Slog.d(TAG, "animateBounds: same destination as existing=" + existing
                         + " ignoring...");
+
                 return existing;
             }
-            // Since we are replacing, we skip both animation start and end callbacks, and don't
-            // animate to the final bounds when cancelling
-            existing.prepareCancel(true /* skipAnimationEnd */, true /* skipFinalResize */);
+
+            // Update the PiP callback states if we are replacing the animation
+            if (existing.mSchedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START) {
+                if (schedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START) {
+                    if (DEBUG) Slog.d(TAG, "animateBounds: still animating to fullscreen, keep"
+                            + " existing deferred state");
+                } else {
+                    if (DEBUG) Slog.d(TAG, "animateBounds: fullscreen animation canceled, callback"
+                            + " on start already processed, schedule deferred update on end");
+                    schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_END;
+                }
+            } else if (existing.mSchedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_END) {
+                if (schedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START) {
+                    if (DEBUG) Slog.d(TAG, "animateBounds: non-fullscreen animation canceled,"
+                            + " callback on start will be processed");
+                } else {
+                    if (DEBUG) Slog.d(TAG, "animateBounds: still animating from fullscreen, keep"
+                            + " existing deferred state");
+                    schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_END;
+                }
+            }
+
+            // Since we are replacing, we skip both animation start and end callbacks
             existing.cancel();
         }
-        final BoundsAnimator animator = new BoundsAnimator(target, from, to, moveToFullscreen,
-                replacing, animatingToNewFullscreenState);
+        final BoundsAnimator animator = new BoundsAnimator(target, from, to,
+                schedulePipModeChangedState, moveToFullscreen, replacing);
         mRunningAnimations.put(target, animator);
         animator.setFloatValues(0f, 1f);
         animator.setDuration((animationDuration != -1 ? animationDuration
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationTarget.java b/services/core/java/com/android/server/wm/BoundsAnimationTarget.java
new file mode 100644
index 0000000..8b1bf7b
--- /dev/null
+++ b/services/core/java/com/android/server/wm/BoundsAnimationTarget.java
@@ -0,0 +1,62 @@
+/*
+ * 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.server.wm;
+
+import android.graphics.Rect;
+
+/**
+ * The target for a BoundsAnimation.
+ * @see BoundsAnimationController
+ */
+interface BoundsAnimationTarget {
+
+    /**
+     * Callback for the target to inform it that the animation has started, so it can do some
+     * necessary preparation.
+     *
+     * @param schedulePipModeChangedCallback whether or not to schedule the PiP mode changed
+     * callbacks
+     */
+    void onAnimationStart(boolean schedulePipModeChangedCallback);
+
+    /**
+     * Sets the size of the target (without any intermediate steps, like scheduling animation)
+     * but freezes the bounds of any tasks in the target at taskBounds, to allow for more
+     * flexibility during resizing. Only works for the pinned stack at the moment.  This will
+     * only be called between onAnimationStart() and onAnimationEnd().
+     *
+     * @return Whether the target should continue to be animated and this call was successful.
+     * If false, the animation will be cancelled because the user has determined that the
+     * animation is now invalid and not required. In such a case, the cancel will trigger the
+     * animation end callback as well, but will not send any further size changes.
+     */
+    boolean setPinnedStackSize(Rect stackBounds, Rect taskBounds);
+
+    /**
+     * Callback for the target to inform it that the animation has ended, so it can do some
+     * necessary cleanup.
+     *
+     * @param schedulePipModeChangedCallback whether or not to schedule the PiP mode changed
+     * callbacks
+     * @param finalStackSize the final stack bounds to set on the target (can be to indicate that
+     * the animation was cancelled and the target does not need to update to the final stack bounds)
+     * @param moveToFullscreen whether or the target should reparent itself to the fullscreen stack
+     * when the animation completes
+     */
+    void onAnimationEnd(boolean schedulePipModeChangedCallback, Rect finalStackSize,
+            boolean moveToFullscreen);
+}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 058fdae..1823610 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -125,6 +125,7 @@
 import android.view.SurfaceControl;
 import android.view.WindowManagerPolicy;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ToBooleanFunction;
 import com.android.internal.view.IInputMethodClient;
 
@@ -1396,6 +1397,22 @@
         return null;
     }
 
+    @VisibleForTesting
+    int getStackCount() {
+        return mTaskStackContainers.size();
+    }
+
+    @VisibleForTesting
+    int getStaskPosById(int stackId) {
+        for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
+            final TaskStack stack = mTaskStackContainers.get(i);
+            if (stack.mStackId == stackId) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
     @Override
     void onConfigurationChanged(Configuration newParentConfig) {
         super.onConfigurationChanged(newParentConfig);
@@ -3274,8 +3291,9 @@
                     : requestedPosition >= topChildPosition;
             int targetPosition = requestedPosition;
 
-            if (toTop && isStackVisible(PINNED_STACK_ID) && stack.mStackId != PINNED_STACK_ID) {
-                // The pinned stack is always the top most stack (always-on-top) when it is visible.
+            if (toTop && stack.mStackId != PINNED_STACK_ID
+                    && getStackById(PINNED_STACK_ID) != null) {
+                // The pinned stack is always the top most stack (always-on-top) when it is present.
                 TaskStack topStack = mChildren.get(topChildPosition);
                 if (topStack.mStackId != PINNED_STACK_ID) {
                     throw new IllegalStateException("Pinned stack isn't top stack??? " + mChildren);
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 1684878..82416ec 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -26,7 +26,6 @@
 import android.content.pm.ParceledListSlice;
 import android.content.res.Resources;
 import android.graphics.Point;
-import android.graphics.PointF;
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.IBinder;
@@ -123,6 +122,13 @@
                 mSnapAlgorithm.setMinimized(isMinimized);
             });
         }
+
+        @Override
+        public int getDisplayRotation() {
+            synchronized (mService.mWindowMap) {
+                return mDisplayInfo.rotation;
+            }
+        }
     }
 
     /**
@@ -221,22 +227,26 @@
      * @return the size of the PIP based on the given {@param aspectRatio}.
      */
     Size getSize(float aspectRatio) {
-        return mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, mMinSize,
-                mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
+        synchronized (mService.mWindowMap) {
+            return mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, mMinSize,
+                    mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
+        }
     }
 
     /**
      * @return the default bounds to show the PIP when there is no active PIP.
      */
     Rect getDefaultBounds() {
-        final Rect insetBounds = new Rect();
-        getInsetBounds(insetBounds);
+        synchronized (mService.mWindowMap) {
+            final Rect insetBounds = new Rect();
+            getInsetBounds(insetBounds);
 
-        final Rect defaultBounds = new Rect();
-        final Size size = getSize(mDefaultAspectRatio);
-        Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds,
-                0, mIsImeShowing ? mImeHeight : 0, defaultBounds);
-        return defaultBounds;
+            final Rect defaultBounds = new Rect();
+            final Size size = getSize(mDefaultAspectRatio);
+            Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds,
+                    0, mIsImeShowing ? mImeHeight : 0, defaultBounds);
+            return defaultBounds;
+        }
     }
 
     /**
@@ -254,42 +264,44 @@
      * new orientation of the device if necessary.
      */
     boolean onTaskStackBoundsChanged(Rect targetBounds, Rect outBounds) {
-        final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
-        if (mDisplayInfo.equals(displayInfo)) {
-            // We are already in the right orientation, ignore
-            outBounds.setEmpty();
-            return false;
-        } else if (targetBounds.isEmpty()) {
-            // The stack is null, we are just initializing the stack, so just store the display info
-            // and ignore
+        synchronized (mService.mWindowMap) {
+            final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
+            if (mDisplayInfo.equals(displayInfo)) {
+                // We are already in the right orientation, ignore
+                outBounds.setEmpty();
+                return false;
+            } else if (targetBounds.isEmpty()) {
+                // The stack is null, we are just initializing the stack, so just store the display
+                // info and ignore
+                mDisplayInfo.copyFrom(displayInfo);
+                outBounds.setEmpty();
+                return false;
+            }
+
+            mTmpRect.set(targetBounds);
+            final Rect postChangeStackBounds = mTmpRect;
+
+            // Calculate the snap fraction of the current stack along the old movement bounds
+            final Rect preChangeMovementBounds = getMovementBounds(postChangeStackBounds);
+            final float snapFraction = mSnapAlgorithm.getSnapFraction(postChangeStackBounds,
+                    preChangeMovementBounds);
             mDisplayInfo.copyFrom(displayInfo);
-            outBounds.setEmpty();
-            return false;
+
+            // Calculate the stack bounds in the new orientation to the same same fraction along the
+            // rotated movement bounds.
+            final Rect postChangeMovementBounds = getMovementBounds(postChangeStackBounds,
+                    false /* adjustForIme */);
+            mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
+                    snapFraction);
+            if (mIsMinimized) {
+                applyMinimizedOffset(postChangeStackBounds, postChangeMovementBounds);
+            }
+
+            notifyMovementBoundsChanged(false /* fromImeAdjustment */);
+
+            outBounds.set(postChangeStackBounds);
+            return true;
         }
-
-        mTmpRect.set(targetBounds);
-        final Rect postChangeStackBounds = mTmpRect;
-
-        // Calculate the snap fraction of the current stack along the old movement bounds
-        final Rect preChangeMovementBounds = getMovementBounds(postChangeStackBounds);
-        final float snapFraction = mSnapAlgorithm.getSnapFraction(postChangeStackBounds,
-                preChangeMovementBounds);
-        mDisplayInfo.copyFrom(displayInfo);
-
-        // Calculate the stack bounds in the new orientation to the same same fraction along the
-        // rotated movement bounds.
-        final Rect postChangeMovementBounds = getMovementBounds(postChangeStackBounds,
-                false /* adjustForIme */);
-        mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
-                snapFraction);
-        if (mIsMinimized) {
-            applyMinimizedOffset(postChangeStackBounds, postChangeMovementBounds);
-        }
-
-        notifyMovementBoundsChanged(false /* fromImeAdjustment */);
-
-        outBounds.set(postChangeStackBounds);
-        return true;
     }
 
     /**
@@ -378,25 +390,27 @@
      * Notifies listeners that the PIP movement bounds have changed.
      */
     private void notifyMovementBoundsChanged(boolean fromImeAdjustement) {
-        if (mPinnedStackListener != null) {
-            try {
-                final Rect insetBounds = new Rect();
-                getInsetBounds(insetBounds);
-                final Rect normalBounds = getDefaultBounds();
-                if (isValidPictureInPictureAspectRatio(mAspectRatio)) {
-                    transformBoundsToAspectRatio(normalBounds, mAspectRatio);
+        synchronized (mService.mWindowMap) {
+            if (mPinnedStackListener != null) {
+                try {
+                    final Rect insetBounds = new Rect();
+                    getInsetBounds(insetBounds);
+                    final Rect normalBounds = getDefaultBounds();
+                    if (isValidPictureInPictureAspectRatio(mAspectRatio)) {
+                        transformBoundsToAspectRatio(normalBounds, mAspectRatio);
+                    }
+                    final Rect animatingBounds = mTmpAnimatingBoundsRect;
+                    final TaskStack pinnedStack = mDisplayContent.getStackById(PINNED_STACK_ID);
+                    if (pinnedStack != null) {
+                        pinnedStack.getAnimationOrCurrentBounds(animatingBounds);
+                    } else {
+                        animatingBounds.set(normalBounds);
+                    }
+                    mPinnedStackListener.onMovementBoundsChanged(insetBounds, normalBounds,
+                            animatingBounds, fromImeAdjustement, mDisplayInfo.rotation);
+                } catch (RemoteException e) {
+                    Slog.e(TAG_WM, "Error delivering actions changed event.", e);
                 }
-                final Rect animatingBounds = mTmpAnimatingBoundsRect;
-                final TaskStack pinnedStack = mDisplayContent.getStackById(PINNED_STACK_ID);
-                if (pinnedStack != null) {
-                    pinnedStack.getAnimationOrCurrentBounds(animatingBounds);
-                } else {
-                    animatingBounds.set(normalBounds);
-                }
-                mPinnedStackListener.onMovementBoundsChanged(insetBounds, normalBounds,
-                        animatingBounds, fromImeAdjustement);
-            } catch (RemoteException e) {
-                Slog.e(TAG_WM, "Error delivering actions changed event.", e);
             }
         }
     }
@@ -405,11 +419,13 @@
      * @return the bounds on the screen that the PIP can be visible in.
      */
     private void getInsetBounds(Rect outRect) {
-        mService.mPolicy.getStableInsetsLw(mDisplayInfo.rotation, mDisplayInfo.logicalWidth,
-                mDisplayInfo.logicalHeight, mTmpInsets);
-        outRect.set(mTmpInsets.left + mScreenEdgeInsets.x, mTmpInsets.top + mScreenEdgeInsets.y,
-                mDisplayInfo.logicalWidth - mTmpInsets.right - mScreenEdgeInsets.x,
-                mDisplayInfo.logicalHeight - mTmpInsets.bottom - mScreenEdgeInsets.y);
+        synchronized (mService.mWindowMap) {
+            mService.mPolicy.getStableInsetsLw(mDisplayInfo.rotation, mDisplayInfo.logicalWidth,
+                    mDisplayInfo.logicalHeight, mTmpInsets);
+            outRect.set(mTmpInsets.left + mScreenEdgeInsets.x, mTmpInsets.top + mScreenEdgeInsets.y,
+                    mDisplayInfo.logicalWidth - mTmpInsets.right - mScreenEdgeInsets.x,
+                    mDisplayInfo.logicalHeight - mTmpInsets.bottom - mScreenEdgeInsets.y);
+        }
     }
 
     /**
@@ -417,7 +433,9 @@
      *         controller.
      */
     private Rect getMovementBounds(Rect stackBounds) {
-        return getMovementBounds(stackBounds, true /* adjustForIme */);
+        synchronized (mService.mWindowMap) {
+            return getMovementBounds(stackBounds, true /* adjustForIme */);
+        }
     }
 
     /**
@@ -425,23 +443,27 @@
      *         controller.
      */
     private Rect getMovementBounds(Rect stackBounds, boolean adjustForIme) {
-        final Rect movementBounds = new Rect();
-        getInsetBounds(movementBounds);
+        synchronized (mService.mWindowMap) {
+            final Rect movementBounds = new Rect();
+            getInsetBounds(movementBounds);
 
-        // Apply the movement bounds adjustments based on the current state
-        mSnapAlgorithm.getMovementBounds(stackBounds, movementBounds, movementBounds,
-                (adjustForIme && mIsImeShowing) ? mImeHeight : 0);
-        return movementBounds;
+            // Apply the movement bounds adjustments based on the current state
+            mSnapAlgorithm.getMovementBounds(stackBounds, movementBounds, movementBounds,
+                    (adjustForIme && mIsImeShowing) ? mImeHeight : 0);
+            return movementBounds;
+        }
     }
 
     /**
      * Applies the minimized offsets to the given stack bounds.
      */
     private void applyMinimizedOffset(Rect stackBounds, Rect movementBounds) {
-        mTmpDisplaySize.set(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
-        mService.getStableInsetsLocked(mDisplayContent.getDisplayId(), mStableInsets);
-        mSnapAlgorithm.applyMinimizedOffset(stackBounds, movementBounds, mTmpDisplaySize,
-                mStableInsets);
+        synchronized (mService.mWindowMap) {
+            mTmpDisplaySize.set(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
+            mService.getStableInsetsLocked(mDisplayContent.getDisplayId(), mStableInsets);
+            mSnapAlgorithm.applyMinimizedOffset(stackBounds, movementBounds, mTmpDisplaySize,
+                    mStableInsets);
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/PinnedStackWindowController.java b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
index 135832e..5b9c16c 100644
--- a/services/core/java/com/android/server/wm/PinnedStackWindowController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
@@ -17,6 +17,10 @@
 package com.android.server.wm;
 
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
+import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
+import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
+import static com.android.server.wm.BoundsAnimationController.SchedulePipModeChangedState;
 
 import android.app.RemoteAction;
 import android.graphics.Rect;
@@ -40,36 +44,53 @@
     /**
      * Animates the pinned stack.
      */
-    public void animateResizePinnedStack(Rect sourceBounds, Rect destBounds,
-            int animationDuration) {
+    public void animateResizePinnedStack(Rect toBounds, Rect sourceHintBounds,
+            int animationDuration, boolean schedulePipModeChangedOnAnimationEnd) {
         synchronized (mWindowMap) {
             if (mContainer == null) {
                 throw new IllegalArgumentException("Pinned stack container not found :(");
             }
 
-            // Get non-null fullscreen bounds if the bounds are null
-            final boolean moveToFullscreen = destBounds == null;
-            destBounds = getPinnedStackAnimationBounds(destBounds);
+            // Get the from-bounds
+            final Rect fromBounds = new Rect();
+            mContainer.getBounds(fromBounds);
 
-            // If the bounds are truly null, then there was no fullscreen stack at this time, so
-            // animate this to the full display bounds
-            final Rect toBounds;
-            if (destBounds == null) {
-                toBounds = new Rect();
-                mContainer.getDisplayContent().getLogicalDisplayRect(toBounds);
-            } else {
-                toBounds = destBounds;
+            // Get non-null fullscreen to-bounds for animating if the bounds are null
+            @SchedulePipModeChangedState int schedulePipModeChangedState =
+                NO_PIP_MODE_CHANGED_CALLBACKS;
+            final boolean toFullscreen = toBounds == null;
+            if (toFullscreen) {
+                if (schedulePipModeChangedOnAnimationEnd) {
+                    throw new IllegalArgumentException("Should not defer scheduling PiP mode"
+                            + " change on animation to fullscreen.");
+                }
+                schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_START;
+
+                mService.getStackBounds(FULLSCREEN_WORKSPACE_STACK_ID, mTmpBoundsRect);
+                if (!mTmpBoundsRect.isEmpty()) {
+                    // If there is a fullscreen bounds, use that
+                    toBounds = new Rect(mTmpBoundsRect);
+                } else {
+                    // Otherwise, use the display bounds
+                    toBounds = new Rect();
+                    mContainer.getDisplayContent().getLogicalDisplayRect(toBounds);
+                }
+            } else if (schedulePipModeChangedOnAnimationEnd) {
+                schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_END;
             }
 
-            final Rect originalBounds = new Rect();
-            mContainer.getBounds(originalBounds);
-            mContainer.setAnimationFinalBounds(sourceBounds, toBounds);
+            mContainer.setAnimationFinalBounds(sourceHintBounds, toBounds, toFullscreen);
+
+            final Rect finalToBounds = toBounds;
+            final @SchedulePipModeChangedState int finalSchedulePipModeChangedState =
+                schedulePipModeChangedState;
             UiThread.getHandler().post(() -> {
                 if (mContainer == null) {
                     return;
                 }
-                mService.mBoundsAnimationController.animateBounds(mContainer, originalBounds,
-                        toBounds, animationDuration, moveToFullscreen);
+                mService.mBoundsAnimationController.animateBounds(mContainer, fromBounds,
+                        finalToBounds, animationDuration, finalSchedulePipModeChangedState,
+                        toFullscreen);
             });
         }
     }
@@ -93,7 +114,8 @@
 
             if (Float.compare(aspectRatio, pinnedStackController.getAspectRatio()) != 0) {
                 if (!toBounds.equals(targetBounds)) {
-                    animateResizePinnedStack(null /* sourceBounds */, toBounds, -1 /* duration */);
+                    animateResizePinnedStack(toBounds, null /* sourceHintBounds */,
+                            -1 /* duration */, false /* schedulePipModeChangedOnAnimationEnd */);
                 }
                 pinnedStackController.setAspectRatio(
                         pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio)
@@ -116,26 +138,31 @@
     }
 
     /**
-     * @return whether the bounds are currently animating to fullscreen.
+     * @return whether the multi-window mode change should be deferred as a part of a transition
+     * from fullscreen to non-fullscreen bounds.
      */
-    public boolean isAnimatingBoundsToFullscreen() {
-        return mContainer.isAnimatingBoundsToFullscreen();
-    }
-
-    public boolean pinnedStackResizeAllowed() {
-        return mContainer.pinnedStackResizeAllowed();
+    public boolean deferScheduleMultiWindowModeChanged() {
+        synchronized(mWindowMap) {
+            return mContainer.deferScheduleMultiWindowModeChanged();
+        }
     }
 
     /**
-     * Checks the {@param bounds} and retirms non-null fullscreen bounds for the pinned stack
-     * animation if necessary.
+     * @return whether the bounds are currently animating to fullscreen.
      */
-    private Rect getPinnedStackAnimationBounds(Rect bounds) {
-        mService.getStackBounds(FULLSCREEN_WORKSPACE_STACK_ID, mTmpBoundsRect);
-        if (bounds == null && !mTmpBoundsRect.isEmpty()) {
-            bounds = new Rect(mTmpBoundsRect);
+    public boolean isAnimatingBoundsToFullscreen() {
+        synchronized (mWindowMap) {
+            return mContainer.isAnimatingBoundsToFullscreen();
         }
-        return bounds;
+    }
+
+    /**
+     * @return whether the stack can be resized from the bounds animation.
+     */
+    public boolean pinnedStackResizeDisallowed() {
+        synchronized (mWindowMap) {
+            return mContainer.pinnedStackResizeDisallowed();
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index d7c41d3..d141f7c 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -56,7 +56,7 @@
 import java.io.PrintWriter;
 
 public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLayerUser,
-        BoundsAnimationController.AnimateBoundsUser {
+        BoundsAnimationTarget {
     /** Minimum size of an adjusted stack bounds relative to original stack bounds. Used to
      * restrict IME adjustment so that a min portion of top stack remains visible.*/
     private static final float ADJUSTED_STACK_FRACTION_MIN = 0.3f;
@@ -132,7 +132,7 @@
     private boolean mBoundsAnimatingToFullscreen = false;
     private boolean mCancelCurrentBoundsAnimation = false;
     private Rect mBoundsAnimationTarget = new Rect();
-    private Rect mBoundsAnimationSourceBounds = new Rect();
+    private Rect mBoundsAnimationSourceHintBounds = new Rect();
 
     // Temporary storage for the new bounds that should be used after the configuration change.
     // Will be cleared once the client retrieves the new bounds via getBoundsForNewConfiguration().
@@ -322,18 +322,19 @@
      * Sets the bounds animation target bounds ahead of an animation.  This can't currently be done
      * in onAnimationStart() since that is started on the UiThread.
      */
-    void setAnimationFinalBounds(Rect sourceBounds, Rect destBounds) {
+    void setAnimationFinalBounds(Rect sourceHintBounds, Rect destBounds, boolean toFullscreen) {
         mBoundsAnimatingRequested = true;
-        if (sourceBounds != null) {
-            mBoundsAnimationSourceBounds.set(sourceBounds);
-        } else {
-            mBoundsAnimationSourceBounds.setEmpty();
-        }
+        mBoundsAnimatingToFullscreen = toFullscreen;
         if (destBounds != null) {
             mBoundsAnimationTarget.set(destBounds);
         } else {
             mBoundsAnimationTarget.setEmpty();
         }
+        if (sourceHintBounds != null) {
+            mBoundsAnimationSourceHintBounds.set(sourceHintBounds);
+        } else {
+            mBoundsAnimationSourceHintBounds.setEmpty();
+        }
     }
 
     /**
@@ -346,8 +347,8 @@
     /**
      * @return the final source bounds for the bounds animation.
      */
-    void getFinalAnimationSourceBounds(Rect outBounds) {
-        outBounds.set(mBoundsAnimationSourceBounds);
+    void getFinalAnimationSourceHintBounds(Rect outBounds) {
+        outBounds.set(mBoundsAnimationSourceHintBounds);
     }
 
     /**
@@ -413,7 +414,7 @@
                 // orientation, clear the animation target bounds since they are obsolete, and
                 // cancel any currently running animations
                 mBoundsAnimationTarget.setEmpty();
-                mBoundsAnimationSourceBounds.setEmpty();
+                mBoundsAnimationSourceHintBounds.setEmpty();
                 mCancelCurrentBoundsAnimation = true;
                 return true;
             }
@@ -1458,13 +1459,16 @@
         }
     }
 
-    public boolean setPinnedStackSize(Rect bounds, Rect tempTaskBounds) {
-        if (mCancelCurrentBoundsAnimation) {
-            return false;
+    public boolean setPinnedStackSize(Rect stackBounds, Rect tempTaskBounds) {
+        // Hold the lock since this is called from the BoundsAnimator running on the UiThread
+        synchronized (mService.mWindowMap) {
+            if (mCancelCurrentBoundsAnimation) {
+                return false;
+            }
         }
 
         try {
-            mService.mActivityManager.resizePinnedStack(bounds, tempTaskBounds);
+            mService.mActivityManager.resizePinnedStack(stackBounds, tempTaskBounds);
         } catch (RemoteException e) {
             // I don't believe you.
         }
@@ -1472,11 +1476,11 @@
     }
 
     @Override  // AnimatesBounds
-    public void onAnimationStart(boolean toFullscreen) {
+    public void onAnimationStart(boolean schedulePipModeChangedCallback) {
+        // Hold the lock since this is called from the BoundsAnimator running on the UiThread
         synchronized (mService.mWindowMap) {
             mBoundsAnimatingRequested = false;
             mBoundsAnimating = true;
-            mBoundsAnimatingToFullscreen = toFullscreen;
             mCancelCurrentBoundsAnimation = false;
         }
 
@@ -1486,41 +1490,63 @@
             } catch (RemoteException e) {
                 // I don't believe you...
             }
+
+            final PinnedStackWindowController controller =
+                    (PinnedStackWindowController) getController();
+            if (schedulePipModeChangedCallback && controller != null) {
+                // We need to schedule the PiP mode change after the animation down, so use the
+                // final bounds
+                controller.updatePictureInPictureModeForPinnedStackAnimation(null);
+            }
         }
     }
 
     @Override  // AnimatesBounds
-    public void updatePictureInPictureMode(Rect targetStackBounds) {
-        final PinnedStackWindowController controller =
-                (PinnedStackWindowController) getController();
-        if (controller != null) {
-            controller.updatePictureInPictureModeForPinnedStackAnimation(targetStackBounds);
-        }
-    }
-
-    @Override  // AnimatesBounds
-    public void onAnimationEnd() {
+    public void onAnimationEnd(boolean schedulePipModeChangedCallback, Rect finalStackSize,
+            boolean moveToFullscreen) {
+        // Hold the lock since this is called from the BoundsAnimator running on the UiThread
         synchronized (mService.mWindowMap) {
             mBoundsAnimating = false;
             mService.requestTraversal();
         }
 
         if (mStackId == PINNED_STACK_ID) {
+            final PinnedStackWindowController controller =
+                    (PinnedStackWindowController) getController();
+            if (schedulePipModeChangedCallback && controller != null) {
+                // We need to schedule the PiP mode change after the animation down, so use the
+                // final bounds
+                controller.updatePictureInPictureModeForPinnedStackAnimation(
+                        mBoundsAnimationTarget);
+            }
+
+            // Update to the final bounds if requested. This is done here instead of in the bounds
+            // animator to allow us to coordinate this after we notify the PiP mode changed
+            if (finalStackSize != null) {
+                setPinnedStackSize(finalStackSize, null);
+            }
+
             try {
                 mService.mActivityManager.notifyPinnedStackAnimationEnded();
+                if (moveToFullscreen) {
+                    mService.mActivityManager.moveTasksToFullscreenStack(mStackId,
+                            true /* onTop */);
+                }
             } catch (RemoteException e) {
                 // I don't believe you...
             }
         }
     }
 
-    @Override
-    public void moveToFullscreen() {
-        try {
-            mService.mActivityManager.moveTasksToFullscreenStack(mStackId, true);
-        } catch (RemoteException e) {
-            e.printStackTrace();
+    /**
+     * @return True if we are currently animating the pinned stack from fullscreen to non-fullscreen
+     *         bounds and we have a deferred PiP mode changed callback set with the animation.
+     */
+    public boolean deferScheduleMultiWindowModeChanged() {
+        if (mStackId == PINNED_STACK_ID) {
+            return (mBoundsAnimatingRequested || mBoundsAnimating);
         }
+        return false;
     }
 
     public boolean hasMovementAnimations() {
@@ -1539,7 +1565,7 @@
         return mBoundsAnimating && mBoundsAnimatingToFullscreen;
     }
 
-    public boolean pinnedStackResizeAllowed() {
+    public boolean pinnedStackResizeDisallowed() {
         if (mBoundsAnimating && mCancelCurrentBoundsAnimation) {
             return true;
         }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0049585..252b4d4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7267,13 +7267,16 @@
 
         @Override
         public void updateInputMethodWindowStatus(@NonNull IBinder imeToken,
-                boolean imeWindowVisible, @Nullable IBinder targetWindowToken) {
+                boolean imeWindowVisible, boolean dismissImeOnBackKeyPressed,
+                @Nullable IBinder targetWindowToken) {
             // TODO (b/34628091): Use this method to address the window animation issue.
             if (DEBUG_INPUT_METHOD) {
                 Slog.w(TAG_WM, "updateInputMethodWindowStatus: imeToken=" + imeToken
+                        + " dismissImeOnBackKeyPressed=" + dismissImeOnBackKeyPressed
                         + " imeWindowVisible=" + imeWindowVisible
                         + " targetWindowToken=" + targetWindowToken);
             }
+            mPolicy.setDismissImeOnBackKeyPressed(dismissImeOnBackKeyPressed);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 0b96f3f..9555c8d 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -4365,9 +4365,12 @@
         // When we change the Surface size, in scenarios which may require changing
         // the surface position in sync with the resize, we use a preserved surface
         // so we can freeze it while waiting for the client to report draw on the newly
-        // sized surface.
+        // sized surface.  Don't preserve surfaces if the insets change while animating the pinned
+        // stack since it can lead to issues if a new surface is created while calculating the
+        // scale for the animation using the source hint rect
+        // (see WindowStateAnimator#setSurfaceBoundariesLocked()).
         if (isDragResizeChanged() || isResizedWhileNotDragResizing()
-                || surfaceInsetsChanging()) {
+                || (surfaceInsetsChanging() && !inPinnedWorkspace())) {
             mLastSurfaceInsets.set(mAttrs.surfaceInsets);
 
             setDragResizing();
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index fa35336..a2889b1 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1360,7 +1360,7 @@
             int posX = mTmpSize.left;
             int posY = mTmpSize.top;
             task.mStack.getDimBounds(mTmpStackBounds);
-            task.mStack.getFinalAnimationSourceBounds(mTmpSourceBounds);
+            task.mStack.getFinalAnimationSourceHintBounds(mTmpSourceBounds);
             if (!mTmpSourceBounds.isEmpty()) {
                 // Get the final target stack bounds, if we are not animating, this is just the
                 // current stack bounds
diff --git a/services/core/jni/com_android_server_location_ContextHubService.cpp b/services/core/jni/com_android_server_location_ContextHubService.cpp
index d834e25..20466eb 100644
--- a/services/core/jni/com_android_server_location_ContextHubService.cpp
+++ b/services/core/jni/com_android_server_location_ContextHubService.cpp
@@ -1129,6 +1129,8 @@
         if (appInstanceHandle == OS_APP_ID) {
             if (msgType == CONTEXT_HUB_LOAD_APP) {
                 result = sendLoadNanoAppRequest(hubId, data, dataBufferLength);
+            } else if (msgType == CONTEXT_HUB_QUERY_APPS) {
+                result = db.hubInfo.contextHub->queryApps(hubId);
             } else {
                 ALOGD("Dropping OS addresses message of type - %" PRIu32, msgType);
                 result = Result::BAD_PARAMS;
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 86662b9..74ecd11 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -68,12 +68,15 @@
 
 using android::OK;
 using android::sp;
+using android::wp;
 using android::status_t;
 using android::String16;
 
 using android::hardware::Return;
 using android::hardware::Void;
 using android::hardware::hidl_vec;
+using android::hardware::hidl_death_recipient;
+using android::hidl::base::V1_0::IBase;
 
 using android::hardware::gnss::V1_0::IAGnss;
 using android::hardware::gnss::V1_0::IAGnssCallback;
@@ -97,7 +100,18 @@
 using android::hardware::gnss::V1_0::IGnssXtra;
 using android::hardware::gnss::V1_0::IGnssXtraCallback;
 
+struct GnssDeathRecipient : virtual public hidl_death_recipient
+{
+    // hidl_death_recipient interface
+    virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
+      // TODO(gomo): implement a better death recovery mechanism without
+      // crashing system server process as described in go//treble-gnss-death
+      LOG_ALWAYS_FATAL("Abort due to IGNSS hidl service failure,"
+            " restarting system server");
+    }
+};
 
+sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
 sp<IGnss> gnssHal = nullptr;
 sp<IGnssXtra> gnssXtraIface = nullptr;
 sp<IAGnssRil> agnssRilIface = nullptr;
@@ -1038,6 +1052,18 @@
     // TODO(b/31632518)
     gnssHal = IGnss::getService();
     if (gnssHal != nullptr) {
+      gnssHalDeathRecipient = new GnssDeathRecipient();
+      hardware::Return<bool> linked = gnssHal->linkToDeath(
+          gnssHalDeathRecipient, /*cookie*/ 0);
+        if (!linked.isOk()) {
+            ALOGE("Transaction error in linking to GnssHAL death: %s",
+                    linked.description().c_str());
+        } else if (!linked) {
+            ALOGW("Unable to link to GnssHal death notifications");
+        } else {
+            ALOGD("Link to death notification successful");
+        }
+
         auto gnssXtra = gnssHal->getExtensionXtra();
         if (!gnssXtra.isOk()) {
             ALOGD("Unable to get a handle to Xtra");
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
index f666727..57ee928 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -49,6 +49,7 @@
 import android.content.pm.ParceledListSlice;
 import android.graphics.Color;
 import android.os.Binder;
+import android.os.Process;
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
@@ -460,10 +461,10 @@
         mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(mTestNotificationChannel, channel2)));
         verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
-                eq(mTestNotificationChannel),
+                eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
         verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
-                eq(channel2),
+                eq(Process.myUserHandle()), eq(channel2),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
     }
 
@@ -481,10 +482,10 @@
         mBinderService.createNotificationChannelGroups(PKG,
                 new ParceledListSlice(Arrays.asList(group1, group2)));
         verify(mNotificationListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
-                eq(group1),
+                eq(Process.myUserHandle()), eq(group1),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
         verify(mNotificationListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
-                eq(group2),
+                eq(Process.myUserHandle()), eq(group2),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
     }
 
@@ -503,7 +504,7 @@
         reset(mNotificationListeners);
         mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
         verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
-                eq(mTestNotificationChannel),
+                eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
     }
 
@@ -520,7 +521,7 @@
         reset(mNotificationListeners);
         mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
         verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
-                eq(mTestNotificationChannel),
+                eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
     }
 
@@ -537,7 +538,7 @@
         reset(mNotificationListeners);
         mBinderService.deleteNotificationChannelGroup(PKG, ncg.getId());
         verify(mNotificationListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
-                eq(ncg),
+                eq(Process.myUserHandle()), eq(ncg),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
     }
 
@@ -550,12 +551,12 @@
         when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
 
         mBinderService.updateNotificationChannelFromPrivilegedListener(
-                null, PKG, mTestNotificationChannel);
+                null, PKG, Process.myUserHandle(), mTestNotificationChannel);
 
         verify(mRankingHelper, times(1)).updateNotificationChannel(anyString(), anyInt(), any());
 
         verify(mNotificationListeners, never()).notifyNotificationChannelChanged(eq(PKG),
-                eq(mTestNotificationChannel),
+                eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
     }
 
@@ -568,7 +569,7 @@
 
         try {
             mBinderService.updateNotificationChannelFromPrivilegedListener(
-                    null, PKG, mTestNotificationChannel);
+                    null, PKG, Process.myUserHandle(), mTestNotificationChannel);
             fail("listeners that don't have a companion device shouldn't be able to call this");
         } catch (SecurityException e) {
             // pass
@@ -577,7 +578,33 @@
         verify(mRankingHelper, never()).updateNotificationChannel(anyString(), anyInt(), any());
 
         verify(mNotificationListeners, never()).notifyNotificationChannelChanged(eq(PKG),
-                eq(mTestNotificationChannel),
+                eq(Process.myUserHandle()), eq(mTestNotificationChannel),
+                eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
+    }
+
+    @Test
+    @UiThreadTest
+    public void testUpdateNotificationChannelFromPrivilegedListener_badUser() throws Exception {
+        mNotificationManagerService.setRankingHelper(mRankingHelper);
+        List<String> associations = new ArrayList<>();
+        associations.add("a");
+        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        mListener = mock(ManagedServices.ManagedServiceInfo.class);
+        when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
+        when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
+
+        try {
+            mBinderService.updateNotificationChannelFromPrivilegedListener(
+                    null, PKG, UserHandle.ALL, mTestNotificationChannel);
+            fail("incorrectly allowed a change to a user listener cannot see");
+        } catch (SecurityException e) {
+            // pass
+        }
+
+        verify(mRankingHelper, never()).updateNotificationChannel(anyString(), anyInt(), any());
+
+        verify(mNotificationListeners, never()).notifyNotificationChannelChanged(eq(PKG),
+                eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
     }
 
@@ -589,7 +616,8 @@
         associations.add("a");
         when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
 
-        mBinderService.getNotificationChannelsFromPrivilegedListener(null, PKG);
+        mBinderService.getNotificationChannelsFromPrivilegedListener(
+                null, PKG, Process.myUserHandle());
 
         verify(mRankingHelper, times(1)).getNotificationChannels(
                 anyString(), anyInt(), anyBoolean());
@@ -603,7 +631,8 @@
         when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
 
         try {
-            mBinderService.getNotificationChannelsFromPrivilegedListener(null, PKG);
+            mBinderService.getNotificationChannelsFromPrivilegedListener(
+                    null, PKG, Process.myUserHandle());
             fail("listeners that don't have a companion device shouldn't be able to call this");
         } catch (SecurityException e) {
             // pass
@@ -615,13 +644,37 @@
 
     @Test
     @UiThreadTest
+    public void testGetNotificationChannelFromPrivilegedListener_badUser() throws Exception {
+        mNotificationManagerService.setRankingHelper(mRankingHelper);
+        List<String> associations = new ArrayList<>();
+        associations.add("a");
+        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        mListener = mock(ManagedServices.ManagedServiceInfo.class);
+        when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
+        when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
+
+        try {
+            mBinderService.getNotificationChannelsFromPrivilegedListener(
+                    null, PKG, Process.myUserHandle());
+            fail("listener getting channels from a user they cannot see");
+        } catch (SecurityException e) {
+            // pass
+        }
+
+        verify(mRankingHelper, never()).getNotificationChannels(
+                anyString(), anyInt(), anyBoolean());
+    }
+
+    @Test
+    @UiThreadTest
     public void testGetNotificationChannelGroupsFromPrivilegedListener_success() throws Exception {
         mNotificationManagerService.setRankingHelper(mRankingHelper);
         List<String> associations = new ArrayList<>();
         associations.add("a");
         when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
 
-        mBinderService.getNotificationChannelGroupsFromPrivilegedListener(null, PKG);
+        mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
+                null, PKG, Process.myUserHandle());
 
         verify(mRankingHelper, times(1)).getNotificationChannelGroups(anyString(), anyInt());
     }
@@ -634,7 +687,29 @@
         when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
 
         try {
-            mBinderService.getNotificationChannelGroupsFromPrivilegedListener(null, PKG);
+            mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
+                    null, PKG, Process.myUserHandle());
+            fail("listeners that don't have a companion device shouldn't be able to call this");
+        } catch (SecurityException e) {
+            // pass
+        }
+
+        verify(mRankingHelper, never()).getNotificationChannelGroups(anyString(), anyInt());
+    }
+
+    @Test
+    @UiThreadTest
+    public void testGetNotificationChannelGroupsFromPrivilegedListener_badUser() throws Exception {
+        mNotificationManagerService.setRankingHelper(mRankingHelper);
+        List<String> associations = new ArrayList<>();
+        when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
+        mListener = mock(ManagedServices.ManagedServiceInfo.class);
+        when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
+        when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
+
+        try {
+            mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
+                    null, PKG, Process.myUserHandle());
             fail("listeners that don't have a companion device shouldn't be able to call this");
         } catch (SecurityException e) {
             // pass
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
index 946044d..b2e6ef9 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
@@ -124,6 +124,9 @@
                 builder.setSound(CUSTOM_SOUND, CUSTOM_ATTRIBUTES);
                 channel.setSound(CUSTOM_SOUND, CUSTOM_ATTRIBUTES);
             }
+        } else {
+            channel.setSound(null, null);
+            builder.setSound(null, null);
         }
         if (buzzy) {
             if (defaultVibration) {
@@ -206,6 +209,18 @@
     }
 
     @Test
+    public void testSound_noSound_preUpgrade() throws Exception {
+        // pre upgrade, default sound.
+        StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
+                false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+                false /* lights */, false /*defaultLights */);
+
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
+        assertEquals(null, record.getSound());
+        assertEquals(Notification.AUDIO_ATTRIBUTES_DEFAULT, record.getAudioAttributes());
+    }
+
+    @Test
     public void testSound_default_upgradeUsesChannel() throws Exception {
         channel.setSound(CUSTOM_SOUND, CUSTOM_ATTRIBUTES);
         // post upgrade, default sound.
diff --git a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
new file mode 100644
index 0000000..243c1b3
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.server.am;
+
+import android.content.Context;
+import android.os.Handler;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.server.AppOpsService;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+
+/**
+ * runtest -c com.android.server.am.AppErrorDialogTest frameworks-services
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class AppErrorDialogTest {
+
+    private Context mContext;
+    private ActivityManagerService mService;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mService = new ActivityManagerService(new ActivityManagerService.Injector() {
+            @Override
+            public AppOpsService getAppOpsService(File file, Handler handler) {
+                return null;
+            }
+
+            @Override
+            public Handler getUiHandler(ActivityManagerService service) {
+                return null;
+            }
+
+            @Override
+            public boolean isNetworkRestrictedForUid(int uid) {
+                return false;
+            }
+        });
+    }
+
+    @Test
+    @UiThreadTest
+    public void testCreateWorks() throws Exception {
+        AppErrorDialog.Data data = new AppErrorDialog.Data();
+        data.proc = new ProcessRecord(null, mContext.getApplicationInfo(), "name", 12345);
+        data.result = new AppErrorResult();
+
+        AppErrorDialog dialog = new AppErrorDialog(mContext, mService, data);
+
+        dialog.create();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
new file mode 100644
index 0000000..8f2f34e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.server.pm;
+
+import android.content.IIntentReceiver;
+
+import android.os.Bundle;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.io.File;
+
+// runtest -c com.android.server.pm.PackageManagerServiceTest frameworks-services
+
+@SmallTest
+public class PackageManagerServiceTest extends AndroidTestCase {
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testPackageRemoval() throws Exception {
+      class PackageSenderImpl implements PackageSender {
+        public void sendPackageBroadcast(final String action, final String pkg,
+            final Bundle extras, final int flags, final String targetPkg,
+            final IIntentReceiver finishedReceiver, final int[] userIds) {
+        }
+
+        public void sendPackageAddedForNewUsers(String packageName,
+            boolean isSystem, int appId, int... userIds) {
+        }
+      }
+
+      PackageSenderImpl sender = new PackageSenderImpl();
+      PackageSetting setting = null;
+      PackageManagerService.PackageRemovedInfo pri =
+          new PackageManagerService.PackageRemovedInfo(sender);
+
+      // Initial conditions: nothing there
+      assertNull(pri.removedUsers);
+      assertNull(pri.broadcastUsers);
+
+      // populateUsers with nothing leaves nothing
+      pri.populateUsers(null, setting);
+      assertNull(pri.broadcastUsers);
+
+      // Create a real (non-null) PackageSetting and confirm that the removed
+      // users are copied properly
+      setting = new PackageSetting("name", "realName", new File("codePath"),
+          new File("resourcePath"), "legacyNativeLibraryPathString",
+          "primaryCpuAbiString", "secondaryCpuAbiString",
+          "cpuAbiOverrideString", 0, 0, 0, "parentPackageName", null, 0,
+          null, null);
+      pri.populateUsers(new int[] {1, 2, 3, 4, 5}, setting);
+      assertNotNull(pri.broadcastUsers);
+      assertEquals(5, pri.broadcastUsers.length);
+
+      // Exclude a user
+      pri.broadcastUsers = null;
+      final int EXCLUDED_USER_ID = 4;
+      setting.setInstantApp(true, EXCLUDED_USER_ID);
+      pri.populateUsers(new int[] {1, 2, 3, EXCLUDED_USER_ID, 5}, setting);
+      assertNotNull(pri.broadcastUsers);
+      assertEquals(5 - 1, pri.broadcastUsers.length);
+
+      // TODO: test that sendApplicationHiddenForUser() actually fills in
+      // broadcastUsers
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
index 85dc712..7f150a2 100644
--- a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
@@ -16,6 +16,11 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
+import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
+import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
+import static com.android.server.wm.BoundsAnimationController.SchedulePipModeChangedState;
+
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Rect;
@@ -47,6 +52,12 @@
  * Test class for {@link BoundsAnimationController} to ensure that it sends the right callbacks
  * depending on the various interactions.
  *
+ * We are really concerned about only three of the transition states [F = fullscreen, !F = floating]
+ * F->!F, !F->!F, and !F->F. Each animation can only be cancelled from the target mid-transition,
+ * or if a new animation starts on the same target.  The tests below verifies that the target is
+ * notified of all the cases where it is animating and cancelled so that it can respond
+ * appropriately.
+ *
  * Build/Install/Run:
  *  bit FrameworksServicesTests:com.android.server.wm.BoundsAnimationControllerTests
  */
@@ -109,47 +120,46 @@
     /**
      * A test animate bounds user to track callbacks from the bounds animation.
      */
-    private class TestAnimateBoundsUser implements BoundsAnimationController.AnimateBoundsUser {
+    private class TestBoundsAnimationTarget implements BoundsAnimationTarget {
 
+        boolean mAwaitingAnimationStart;
         boolean mMovedToFullscreen;
         boolean mAnimationStarted;
-        boolean mAnimationStartedToFullscreen;
+        boolean mSchedulePipModeChangedOnStart;
         boolean mAnimationEnded;
-        boolean mUpdatedPictureInPictureModeWithBounds;
+        Rect mAnimationEndFinalStackBounds;
+        boolean mSchedulePipModeChangedOnEnd;
         boolean mBoundsUpdated;
+        boolean mCancelRequested;
         Rect mStackBounds;
         Rect mTaskBounds;
 
-        boolean mRequestCancelAnimation = false;
-
-        void reinitialize(Rect stackBounds, Rect taskBounds) {
+        void initialize(Rect from) {
+            mAwaitingAnimationStart = true;
             mMovedToFullscreen = false;
             mAnimationStarted = false;
-            mAnimationStartedToFullscreen = false;
             mAnimationEnded = false;
-            mUpdatedPictureInPictureModeWithBounds = false;
-            mStackBounds = stackBounds;
-            mTaskBounds = taskBounds;
+            mAnimationEndFinalStackBounds = null;
+            mSchedulePipModeChangedOnStart = false;
+            mSchedulePipModeChangedOnEnd = false;
+            mStackBounds = from;
+            mTaskBounds = null;
             mBoundsUpdated = false;
-            mRequestCancelAnimation = false;
         }
 
         @Override
-        public void onAnimationStart(boolean toFullscreen) {
+        public void onAnimationStart(boolean schedulePipModeChangedCallback) {
+            mAwaitingAnimationStart = false;
             mAnimationStarted = true;
-            mAnimationStartedToFullscreen = toFullscreen;
-        }
-
-        @Override
-        public void updatePictureInPictureMode(Rect targetStackBounds) {
-            mUpdatedPictureInPictureModeWithBounds = true;
+            mSchedulePipModeChangedOnStart = schedulePipModeChangedCallback;
         }
 
         @Override
         public boolean setPinnedStackSize(Rect stackBounds, Rect taskBounds) {
             // TODO: Once we break the runs apart, we should fail() here if this is called outside
             //       of onAnimationStart() and onAnimationEnd()
-            if (mRequestCancelAnimation) {
+            if (mCancelRequested) {
+                mCancelRequested = false;
                 return false;
             } else {
                 mBoundsUpdated = true;
@@ -160,32 +170,206 @@
         }
 
         @Override
-        public void onAnimationEnd() {
+        public void onAnimationEnd(boolean schedulePipModeChangedCallback, Rect finalStackBounds,
+                boolean moveToFullscreen) {
             mAnimationEnded = true;
+            mAnimationEndFinalStackBounds = finalStackBounds;
+            mSchedulePipModeChangedOnEnd = schedulePipModeChangedCallback;
+            mMovedToFullscreen = moveToFullscreen;
+            mTaskBounds = null;
+        }
+    }
+
+    /**
+     * Drives the animations, makes common assertions along the way.
+     */
+    private class BoundsAnimationDriver {
+
+        private BoundsAnimationController mController;
+        private TestBoundsAnimationTarget mTarget;
+        private BoundsAnimator mAnimator;
+
+        private Rect mFrom;
+        private Rect mTo;
+        private Rect mLargerBounds;
+        private Rect mExpectedFinalBounds;
+
+        BoundsAnimationDriver(BoundsAnimationController controller,
+                TestBoundsAnimationTarget target) {
+            mController = controller;
+            mTarget = target;
         }
 
-        @Override
-        public void moveToFullscreen() {
-            mMovedToFullscreen = true;
+        BoundsAnimationDriver start(Rect from, Rect to) {
+            if (mAnimator != null) {
+                throw new IllegalArgumentException("Call restart() to restart an animation");
+            }
+
+            mTarget.initialize(from);
+
+            // Started, not running
+            assertTrue(mTarget.mAwaitingAnimationStart);
+            assertTrue(!mTarget.mAnimationStarted);
+
+            startImpl(from, to);
+
+            // Started and running
+            assertTrue(!mTarget.mAwaitingAnimationStart);
+            assertTrue(mTarget.mAnimationStarted);
+
+            return this;
+        }
+
+        BoundsAnimationDriver restart(Rect to) {
+            if (mAnimator == null) {
+                throw new IllegalArgumentException("Call start() to start a new animation");
+            }
+
+            BoundsAnimator oldAnimator = mAnimator;
+            boolean toSameBounds = mAnimator.isStarted() && to.equals(mTo);
+
+            // Reset the animation start state
+            mTarget.mAnimationStarted = false;
+
+            // Start animation
+            startImpl(mTarget.mStackBounds, to);
+
+            if (toSameBounds) {
+                // Same animator if same final bounds
+                assertSame(oldAnimator, mAnimator);
+            }
+
+            // No animation start for replacing animation
+            assertTrue(!mTarget.mAnimationStarted);
+            mTarget.mAnimationStarted = true;
+            return this;
+        }
+
+        private BoundsAnimationDriver startImpl(Rect from, Rect to) {
+            boolean fromFullscreen = from.equals(BOUNDS_FULL);
+            boolean toFullscreen = to.equals(BOUNDS_FULL);
+            mFrom = new Rect(from);
+            mTo = new Rect(to);
+            mExpectedFinalBounds = new Rect(to);
+            mLargerBounds = getLargerBounds(mFrom, mTo);
+
+            // Start animation
+            final @SchedulePipModeChangedState int schedulePipModeChangedState = toFullscreen
+                    ? SCHEDULE_PIP_MODE_CHANGED_ON_START
+                    : fromFullscreen
+                            ? SCHEDULE_PIP_MODE_CHANGED_ON_END
+                            : NO_PIP_MODE_CHANGED_CALLBACKS;
+            mAnimator = mController.animateBoundsImpl(mTarget, from, to, DURATION,
+                    schedulePipModeChangedState, toFullscreen);
+
+            // Original stack bounds, frozen task bounds
+            assertEquals(mFrom, mTarget.mStackBounds);
+            assertEqualSizeAtOffset(mLargerBounds, mTarget.mTaskBounds);
+
+            // Animating to larger size
+            if (mFrom.equals(mLargerBounds)) {
+                assertTrue(!mAnimator.animatingToLargerSize());
+            } else if (mTo.equals(mLargerBounds)) {
+                assertTrue(mAnimator.animatingToLargerSize());
+            }
+
+            return this;
+        }
+
+        BoundsAnimationDriver expectStarted(boolean schedulePipModeChanged) {
+            // Callback made
+            assertTrue(mTarget.mAnimationStarted);
+
+            assertEquals(schedulePipModeChanged, mTarget.mSchedulePipModeChangedOnStart);
+            return this;
+        }
+
+        BoundsAnimationDriver update(float t) {
+            mAnimator.onAnimationUpdate(mMockAnimator.getWithValue(t));
+
+            // Temporary stack bounds, frozen task bounds
+            if (t == 0f) {
+                assertEquals(mFrom, mTarget.mStackBounds);
+            } else if (t == 1f) {
+                assertEquals(mTo, mTarget.mStackBounds);
+            } else {
+                assertNotEquals(mFrom, mTarget.mStackBounds);
+                assertNotEquals(mTo, mTarget.mStackBounds);
+            }
+            assertEqualSizeAtOffset(mLargerBounds, mTarget.mTaskBounds);
+            return this;
+        }
+
+        BoundsAnimationDriver cancel() {
+            // Cancel
+            mTarget.mCancelRequested = true;
+            mTarget.mBoundsUpdated = false;
+            mExpectedFinalBounds = null;
+
+            // Update
+            mAnimator.onAnimationUpdate(mMockAnimator.getWithValue(0.5f));
+
+            // Not started, not running, cancel reset
+            assertTrue(!mTarget.mCancelRequested);
+
+            // Stack/task bounds not updated
+            assertTrue(!mTarget.mBoundsUpdated);
+
+            // Callback made
+            assertTrue(mTarget.mAnimationEnded);
+            assertNull(mTarget.mAnimationEndFinalStackBounds);
+
+            return this;
+        }
+
+        BoundsAnimationDriver end() {
+            mAnimator.end();
+
+            // Final stack bounds
+            assertEquals(mTo, mTarget.mStackBounds);
+            assertEquals(mExpectedFinalBounds, mTarget.mAnimationEndFinalStackBounds);
+            assertNull(mTarget.mTaskBounds);
+
+            return this;
+        }
+
+        BoundsAnimationDriver expectEnded(boolean schedulePipModeChanged,
+                boolean moveToFullscreen) {
+            // Callback made
+            assertTrue(mTarget.mAnimationEnded);
+
+            assertEquals(schedulePipModeChanged, mTarget.mSchedulePipModeChangedOnEnd);
+            assertEquals(moveToFullscreen, mTarget.mMovedToFullscreen);
+            return this;
+        }
+
+        private Rect getLargerBounds(Rect r1, Rect r2) {
+            int r1Area = r1.width() * r1.height();
+            int r2Area = r2.width() * r2.height();
+            if (r1Area <= r2Area) {
+                return r2;
+            } else {
+                return r1;
+            }
         }
     }
 
     // Constants
+    private static final boolean SCHEDULE_PIP_MODE_CHANGED = true;
     private static final boolean MOVE_TO_FULLSCREEN = true;
+    private static final int DURATION = 100;
 
     // Some dummy bounds to represent fullscreen and floating bounds
     private static final Rect BOUNDS_FULL = new Rect(0, 0, 100, 100);
-    private static final Rect BOUNDS_FLOATING = new Rect(80, 80, 95, 95);
-    private static final Rect BOUNDS_ALT_FLOATING = new Rect(60, 60, 95, 95);
-
-    // Some dummy duration
-    private static final int DURATION = 100;
+    private static final Rect BOUNDS_FLOATING = new Rect(60, 60, 95, 95);
+    private static final Rect BOUNDS_SMALLER_FLOATING = new Rect(80, 80, 95, 95);
 
     // Common
-    private MockAppTransition mAppTransition;
-    private MockValueAnimator mAnimator;
-    private TestAnimateBoundsUser mTarget;
+    private MockAppTransition mMockAppTransition;
+    private MockValueAnimator mMockAnimator;
+    private TestBoundsAnimationTarget mTarget;
     private BoundsAnimationController mController;
+    private BoundsAnimationDriver mDriver;
 
     // Temp
     private Rect mTmpRect = new Rect();
@@ -196,153 +380,184 @@
 
         final Context context = InstrumentationRegistry.getTargetContext();
         final Handler handler = new Handler(Looper.getMainLooper());
-        mAppTransition = new MockAppTransition(context);
-        mAnimator = new MockValueAnimator();
-        mTarget = new TestAnimateBoundsUser();
-        mController = new BoundsAnimationController(context, mAppTransition, handler);
+        mMockAppTransition = new MockAppTransition(context);
+        mMockAnimator = new MockValueAnimator();
+        mTarget = new TestBoundsAnimationTarget();
+        mController = new BoundsAnimationController(context, mMockAppTransition, handler);
+        mDriver = new BoundsAnimationDriver(mController, mTarget);
     }
 
+    /** BASE TRANSITIONS **/
+
     @UiThreadTest
     @Test
     public void testFullscreenToFloatingTransition() throws Exception {
-        // Create and start the animation
-        mTarget.reinitialize(BOUNDS_FULL, null);
-        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
-                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
-
-        // Assert that when we are started, and that we are not going to fullscreen
-        assertTrue(mTarget.mAnimationStarted);
-        assertFalse(mTarget.mAnimationStartedToFullscreen);
-        // Ensure we are not triggering a PiP mode change
-        assertFalse(mTarget.mUpdatedPictureInPictureModeWithBounds);
-        // Ensure that the task stack bounds are already frozen to the larger source stack bounds
-        assertEquals(BOUNDS_FULL, mTarget.mStackBounds);
-        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
-
-        // Drive some animation updates, ensure that only the stack bounds change and the task
-        // bounds are frozen to the original stack bounds (adjusted for the offset)
-        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
-        assertNotEquals(BOUNDS_FULL, mTarget.mStackBounds);
-        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
-        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(1f));
-        assertNotEquals(BOUNDS_FULL, mTarget.mStackBounds);
-        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
-
-        // Finish the animation, ensure that it reaches the final bounds with the given state
-        boundsAnimator.end();
-        assertTrue(mTarget.mAnimationEnded);
-        assertEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
-        assertNull(mTarget.mTaskBounds);
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0f)
+                .update(0.5f)
+                .update(1f)
+                .end()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
     }
 
     @UiThreadTest
     @Test
     public void testFloatingToFullscreenTransition() throws Exception {
-        // Create and start the animation
-        mTarget.reinitialize(BOUNDS_FULL, null);
-        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FLOATING,
-                BOUNDS_FULL, DURATION, MOVE_TO_FULLSCREEN);
-
-        // Assert that when we are started, and that we are going to fullscreen
-        assertTrue(mTarget.mAnimationStarted);
-        assertTrue(mTarget.mAnimationStartedToFullscreen);
-        // Ensure that we update the PiP mode change with the new fullscreen bounds
-        assertTrue(mTarget.mUpdatedPictureInPictureModeWithBounds);
-        // Ensure that the task stack bounds are already frozen to the larger target stack bounds
-        assertEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
-        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
-
-        // Drive some animation updates, ensure that only the stack bounds change and the task
-        // bounds are frozen to the original stack bounds (adjusted for the offset)
-        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
-        assertNotEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
-        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
-        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(1f));
-        assertNotEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
-        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
-
-        // Finish the animation, ensure that it reaches the final bounds with the given state
-        boundsAnimator.end();
-        assertTrue(mTarget.mAnimationEnded);
-        assertEquals(BOUNDS_FULL, mTarget.mStackBounds);
-        assertNull(mTarget.mTaskBounds);
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
+                .expectStarted(SCHEDULE_PIP_MODE_CHANGED)
+                .update(0f)
+                .update(0.5f)
+                .update(1f)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, MOVE_TO_FULLSCREEN);
     }
 
     @UiThreadTest
     @Test
-    public void testInterruptAnimationFromUser() throws Exception {
-        // Create and start the animation
-        mTarget.reinitialize(BOUNDS_FULL, null);
-        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
-                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
-
-        // Cancel the animation on the next update from the user
-        mTarget.mRequestCancelAnimation = true;
-        mTarget.mBoundsUpdated = false;
-        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
-        // Ensure that we got no more updates after returning false and the bounds are not updated
-        // to the end value
-        assertFalse(mTarget.mBoundsUpdated);
-        assertNotEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
-        assertNotEquals(BOUNDS_FLOATING, mTarget.mTaskBounds);
-        // Ensure that we received the animation end call
-        assertTrue(mTarget.mAnimationEnded);
+    public void testFloatingToSmallerFloatingTransition() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_SMALLER_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0f)
+                .update(0.5f)
+                .update(1f)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
     }
 
     @UiThreadTest
     @Test
-    public void testCancelAnimationFromNewAnimationToExistingBounds() throws Exception {
-        // Create and start the animation
-        mTarget.reinitialize(BOUNDS_FULL, null);
-        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
-                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
+    public void testFloatingToLargerFloatingTransition() throws Exception {
+        mDriver.start(BOUNDS_SMALLER_FLOATING, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0f)
+                .update(0.5f)
+                .update(1f)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
 
-        // Drive some animation updates
-        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
+    /** F->!F w/ CANCEL **/
 
-        // Cancel the animation as a restart to the same bounds
-        mTarget.reinitialize(null, null);
-        final BoundsAnimator altBoundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
-                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
-        // Ensure the animator is the same
-        assertSame(boundsAnimator, altBoundsAnimator);
-        // Ensure we haven't restarted or finished the animation
-        assertFalse(mTarget.mAnimationStarted);
-        assertFalse(mTarget.mAnimationEnded);
-        // Ensure that we haven't tried to update the PiP mode
-        assertFalse(mTarget.mUpdatedPictureInPictureModeWithBounds);
+    @UiThreadTest
+    @Test
+    public void testFullscreenToFloatingCancelFromTarget() throws Exception {
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .cancel()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
     }
 
     @UiThreadTest
     @Test
-    public void testCancelAnimationFromNewAnimationToNewBounds() throws Exception {
-        // Create and start the animation
-        mTarget.reinitialize(BOUNDS_FULL, null);
-        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
-                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
+    public void testFullscreenToFloatingCancelFromAnimationToSameBounds() throws Exception {
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_FLOATING)
+                .end()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
 
-        // Drive some animation updates
-        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
+    @UiThreadTest
+    @Test
+    public void testFullscreenToFloatingCancelFromAnimationToFloatingBounds() throws Exception {
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_SMALLER_FLOATING)
+                .end()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
 
-        // Cancel the animation as a restart to new bounds
-        mTarget.reinitialize(null, null);
-        final BoundsAnimator altBoundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
-                BOUNDS_ALT_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
-        // Ensure the animator is not the same
-        assertNotSame(boundsAnimator, altBoundsAnimator);
-        // Ensure that we did not get an animation start/end callback
-        assertFalse(mTarget.mAnimationStarted);
-        assertFalse(mTarget.mAnimationEnded);
-        // Ensure that we haven't tried to update the PiP mode
-        assertFalse(mTarget.mUpdatedPictureInPictureModeWithBounds);
+    @UiThreadTest
+    @Test
+    public void testFullscreenToFloatingCancelFromAnimationToFullscreenBounds() throws Exception {
+        mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_FULL)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, MOVE_TO_FULLSCREEN);
+    }
+
+    /** !F->F w/ CANCEL **/
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToFullscreenCancelFromTarget() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
+                .expectStarted(SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .cancel()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToFullscreenCancelFromAnimationToSameBounds() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
+                .expectStarted(SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_FULL)
+                .end()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToFullscreenCancelFromAnimationToFloatingBounds() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
+                .expectStarted(SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .restart(BOUNDS_SMALLER_FLOATING)
+                .end()
+                .expectEnded(SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    /** !F->!F w/ CANCEL **/
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToSmallerFloatingCancelFromTarget() throws Exception {
+        mDriver.start(BOUNDS_FLOATING, BOUNDS_SMALLER_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .cancel()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToLargerFloatingCancelFromTarget() throws Exception {
+        mDriver.start(BOUNDS_SMALLER_FLOATING, BOUNDS_FLOATING)
+                .expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
+                .update(0.25f)
+                .cancel()
+                .expectEnded(!SCHEDULE_PIP_MODE_CHANGED, !MOVE_TO_FULLSCREEN);
+    }
+
+    /** MISC **/
+
+    @UiThreadTest
+    @Test
+    public void testBoundsAreCopied() throws Exception {
+        Rect from = new Rect(0, 0, 100, 100);
+        Rect to = new Rect(25, 25, 75, 75);
+        mDriver.start(from, to)
+                .update(0.25f)
+                .end();
+        assertEquals(new Rect(0, 0, 100, 100), from);
+        assertEquals(new Rect(25, 25, 75, 75), to);
     }
 
     /**
-     * @return the bounds offset to zero/zero.
+     * @return whether the task and stack bounds would be the same if they were at the same offset.
      */
-    private Rect offsetToZero(Rect bounds) {
-        mTmpRect.set(bounds);
-        mTmpRect.offsetTo(0, 0);
-        return mTmpRect;
+    private boolean assertEqualSizeAtOffset(Rect stackBounds, Rect taskBounds) {
+        mTmpRect.set(taskBounds);
+        mTmpRect.offsetTo(stackBounds.left, stackBounds.top);
+        return stackBounds.equals(mTmpRect);
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 0270bb9..837ce56 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
@@ -289,6 +290,24 @@
         verifySizes(sDisplayContent, smallerWidth, smallerHeight, smallerDensity);
     }
 
+    /**
+     * This test enforces that the pinned stack is always kept as the top stack.
+     */
+    @Test
+    public void testPinnedStackLocation() {
+        createStackControllerOnStackOnDisplay(PINNED_STACK_ID, sDisplayContent);
+        final int initialStackCount = sDisplayContent.getStackCount();
+        // Ensure that the pinned stack was placed at the end
+        assertEquals(initialStackCount - 1, sDisplayContent.getStaskPosById(PINNED_STACK_ID));
+        // By default, this should try to create a new stack on top
+        createTaskStackOnDisplay(sDisplayContent);
+        final int afterStackCount = sDisplayContent.getStackCount();
+        // Make sure the stack count has increased
+        assertEquals(initialStackCount + 1, afterStackCount);
+        // Ensure that the pinned stack is still on top
+        assertEquals(afterStackCount - 1, sDisplayContent.getStaskPosById(PINNED_STACK_ID));
+    }
+
     private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
                              int expectedBaseHeight, int expectedBaseDensity) {
         assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth);
diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java
index 5ad7f80..094c7bd 100644
--- a/services/usage/java/com/android/server/usage/StorageStatsService.java
+++ b/services/usage/java/com/android/server/usage/StorageStatsService.java
@@ -35,6 +35,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.ParcelableException;
 import android.os.StatFs;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -150,7 +151,7 @@
         try {
             return mInstaller.isQuotaSupported(volumeUuid);
         } catch (InstallerException e) {
-            throw new IllegalStateException(e);
+            throw new ParcelableException(new IOException(e.getMessage()));
         }
     }
 
@@ -163,7 +164,8 @@
         } else {
             final VolumeInfo vol = mStorage.findVolumeByUuid(volumeUuid);
             if (vol == null) {
-                throw new IllegalStateException("Volume was unexpected null");
+                throw new ParcelableException(
+                        new IOException("Failed to find storage device for UUID " + volumeUuid));
             }
             return FileUtils.roundStorageSize(vol.disk.size);
         }
@@ -189,7 +191,8 @@
         } else {
             final VolumeInfo vol = mStorage.findVolumeByUuid(volumeUuid);
             if (vol == null) {
-                throw new IllegalStateException("Volume was unexpected null");
+                throw new ParcelableException(
+                        new IOException("Failed to find storage device for UUID " + volumeUuid));
             }
             return vol.getPath().getUsableSpace() + cacheBytes;
         }
@@ -221,7 +224,7 @@
             appInfo = mPackage.getApplicationInfoAsUser(packageName,
                     PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
         } catch (NameNotFoundException e) {
-            throw new IllegalStateException(e);
+            throw new ParcelableException(e);
         }
 
         if (mPackage.getPackagesForUid(appInfo.uid).length == 1) {
@@ -239,7 +242,7 @@
                 mInstaller.getAppSize(volumeUuid, packageNames, userId, 0,
                         appId, ceDataInodes, codePaths, stats);
             } catch (InstallerException e) {
-                throw new IllegalStateException(e);
+                throw new ParcelableException(new IOException(e.getMessage()));
             }
             return translate(stats);
         }
@@ -265,7 +268,7 @@
                 codePaths[i] = mPackage.getApplicationInfoAsUser(packageNames[i],
                         PackageManager.MATCH_UNINSTALLED_PACKAGES, userId).getCodePath();
             } catch (NameNotFoundException e) {
-                throw new IllegalStateException(e);
+                throw new ParcelableException(e);
             }
         }
 
@@ -281,7 +284,7 @@
                 checkEquals("UID " + uid, manualStats, stats);
             }
         } catch (InstallerException e) {
-            throw new IllegalStateException(e);
+            throw new ParcelableException(new IOException(e.getMessage()));
         }
         return translate(stats);
     }
@@ -313,7 +316,7 @@
                 checkEquals("User " + userId, manualStats, stats);
             }
         } catch (InstallerException e) {
-            throw new IllegalStateException(e);
+            throw new ParcelableException(new IOException(e.getMessage()));
         }
         return translate(stats);
     }
@@ -336,7 +339,7 @@
                 checkEquals("External " + userId, manualStats, stats);
             }
         } catch (InstallerException e) {
-            throw new IllegalStateException(e);
+            throw new ParcelableException(new IOException(e.getMessage()));
         }
 
         final ExternalStorageStats res = new ExternalStorageStats();
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 1874d8d..0342da7 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -112,20 +112,26 @@
             "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
 
     /**
-     * The {@link android.content.Intent} action used indicate that a new phone account was
-     * just registered.
-     * @hide
+     * {@link android.content.Intent} action used indicate that a new phone account was just
+     * registered.
+     * <p>
+     * The Intent {@link Intent#getExtras() extras} will contain {@link #EXTRA_PHONE_ACCOUNT_HANDLE}
+     * to indicate which {@link PhoneAccount} was registered.
+     * <p>
+     * Will only be sent to the default dialer app (see {@link #getDefaultDialerPackage()}).
      */
-    @SystemApi
     public static final String ACTION_PHONE_ACCOUNT_REGISTERED =
             "android.telecom.action.PHONE_ACCOUNT_REGISTERED";
 
     /**
-     * The {@link android.content.Intent} action used indicate that a phone account was
-     * just unregistered.
-     * @hide
+     * {@link android.content.Intent} action used indicate that a phone account was just
+     * unregistered.
+     * <p>
+     * The Intent {@link Intent#getExtras() extras} will contain {@link #EXTRA_PHONE_ACCOUNT_HANDLE}
+     * to indicate which {@link PhoneAccount} was unregistered.
+     * <p>
+     * Will only be sent to the default dialer app (see {@link #getDefaultDialerPackage()}).
      */
-    @SystemApi
     public static final String ACTION_PHONE_ACCOUNT_UNREGISTERED =
             "android.telecom.action.PHONE_ACCOUNT_UNREGISTERED";
 
diff --git a/telephony/java/android/telephony/Telephony.java b/telephony/java/android/telephony/Telephony.java
index 943a6ca..eeaf2c1 100644
--- a/telephony/java/android/telephony/Telephony.java
+++ b/telephony/java/android/telephony/Telephony.java
@@ -19,18 +19,21 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.TestApi;
+import android.app.job.JobService;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.database.Cursor;
+import android.database.ContentObserver;
 import android.database.sqlite.SqliteWrapper;
 import android.net.Uri;
+import android.telephony.Rlog;
+import android.telephony.ServiceState;
 import android.telephony.SmsMessage;
 import android.telephony.SubscriptionManager;
 import android.text.TextUtils;
-import android.telephony.Rlog;
 import android.util.Patterns;
 
 import com.android.internal.telephony.PhoneConstants;
@@ -44,7 +47,7 @@
 
 /**
  * The Telephony provider contains data related to phone operation, specifically SMS and MMS
- * messages and access to the APN list, including the MMSC to use.
+ * messages, access to the APN list, including the MMSC to use, and the service state.
  *
  * <p class="note"><strong>Note:</strong> These APIs are not available on all Android-powered
  * devices. If your app depends on telephony features such as for managing SMS messages, include
@@ -2972,4 +2975,272 @@
                 CMAS_CERTAINTY
         };
     }
+
+    /**
+     * Constants for interfacing with the ServiceStateProvider and the different fields of the
+     * {@link ServiceState} class accessible through the provider.
+     */
+    public static final class ServiceStateTable {
+
+        /**
+         * Not instantiable.
+         * @hide
+         */
+        private ServiceStateTable() {}
+
+        /**
+         * The authority string for the ServiceStateProvider
+         */
+        public static final String AUTHORITY = "service-state";
+
+        /**
+         * The {@code content://} style URL for the ServiceStateProvider
+         */
+        public static final Uri CONTENT_URI = Uri.parse("content://service-state/");
+
+        /**
+         * Generates a content {@link Uri} used to receive updates on a specific field in the
+         * ServiceState provider.
+         * <p>
+         * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
+         * {@link ServiceState} while your app is running.  You can also use a {@link JobService} to
+         * ensure your app is notified of changes to the {@link Uri} even when it is not running.
+         * Note, however, that using a {@link JobService} does not guarantee timely delivery of
+         * updates to the {@link Uri}.
+         *
+         * @param subId the subId to receive updates on
+         * @param field the ServiceState field to receive updates on
+         * @return the Uri used to observe {@link ServiceState} changes
+         */
+        public static Uri getUriForSubIdAndField(int subId, String field) {
+            return CONTENT_URI.buildUpon().appendEncodedPath(String.valueOf(subId))
+                    .appendEncodedPath(field).build();
+        }
+
+        /**
+         * Generates a content {@link Uri} used to receive updates on every field in the
+         * ServiceState provider.
+         * <p>
+         * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
+         * {@link ServiceState} while your app is running.  You can also use a {@link JobService} to
+         * ensure your app is notified of changes to the {@link Uri} even when it is not running.
+         * Note, however, that using a {@link JobService} does not guarantee timely delivery of
+         * updates to the {@link Uri}.
+         *
+         * @param subId the subId to receive updates on
+         * @return the Uri used to observe {@link ServiceState} changes
+         */
+        public static Uri getUriForSubId(int subId) {
+            return CONTENT_URI.buildUpon().appendEncodedPath(String.valueOf(subId)).build();
+        }
+
+        /**
+         * Used to insert a ServiceState into the ServiceStateProvider as a ContentValues instance.
+         *
+         * @param state the ServiceState to convert into ContentValues
+         * @return the convertedContentValues instance
+         * @hide
+         */
+        public static ContentValues getContentValuesForServiceState(ServiceState state) {
+            ContentValues values = new ContentValues();
+            values.put(VOICE_REG_STATE, state.getVoiceRegState());
+            values.put(DATA_REG_STATE, state.getDataRegState());
+            values.put(VOICE_ROAMING_TYPE, state.getVoiceRoamingType());
+            values.put(DATA_ROAMING_TYPE, state.getDataRoamingType());
+            values.put(VOICE_OPERATOR_ALPHA_LONG, state.getVoiceOperatorAlphaLong());
+            values.put(VOICE_OPERATOR_ALPHA_SHORT, state.getVoiceOperatorAlphaShort());
+            values.put(VOICE_OPERATOR_NUMERIC, state.getVoiceOperatorNumeric());
+            values.put(DATA_OPERATOR_ALPHA_LONG, state.getDataOperatorAlphaLong());
+            values.put(DATA_OPERATOR_ALPHA_SHORT, state.getDataOperatorAlphaShort());
+            values.put(DATA_OPERATOR_NUMERIC, state.getDataOperatorNumeric());
+            values.put(IS_MANUAL_NETWORK_SELECTION, state.getIsManualSelection());
+            values.put(RIL_VOICE_RADIO_TECHNOLOGY, state.getRilVoiceRadioTechnology());
+            values.put(RIL_DATA_RADIO_TECHNOLOGY, state.getRilDataRadioTechnology());
+            values.put(CSS_INDICATOR, state.getCssIndicator());
+            values.put(NETWORK_ID, state.getNetworkId());
+            values.put(SYSTEM_ID, state.getSystemId());
+            values.put(CDMA_ROAMING_INDICATOR, state.getCdmaRoamingIndicator());
+            values.put(CDMA_DEFAULT_ROAMING_INDICATOR, state.getCdmaDefaultRoamingIndicator());
+            values.put(CDMA_ERI_ICON_INDEX, state.getCdmaEriIconIndex());
+            values.put(CDMA_ERI_ICON_MODE, state.getCdmaEriIconMode());
+            values.put(IS_EMERGENCY_ONLY, state.isEmergencyOnly());
+            values.put(IS_DATA_ROAMING_FROM_REGISTRATION, state.getDataRoamingFromRegistration());
+            values.put(IS_USING_CARRIER_AGGREGATION, state.isUsingCarrierAggregation());
+            return values;
+        }
+
+        /**
+         * An integer value indicating the current voice service state.
+         * <p>
+         * Valid values: {@link ServiceState#STATE_IN_SERVICE},
+         * {@link ServiceState#STATE_OUT_OF_SERVICE}, {@link ServiceState#STATE_EMERGENCY_ONLY},
+         * {@link ServiceState#STATE_POWER_OFF}.
+         * <p>
+         * This is the same as {@link ServiceState#getState()}.
+         */
+        public static final String VOICE_REG_STATE = "voice_reg_state";
+
+        /**
+         * An integer value indicating the current data service state.
+         * <p>
+         * Valid values: {@link ServiceState#STATE_IN_SERVICE},
+         * {@link ServiceState#STATE_OUT_OF_SERVICE}, {@link ServiceState#STATE_EMERGENCY_ONLY},
+         * {@link ServiceState#STATE_POWER_OFF}.
+         * <p>
+         * This is the same as {@link ServiceState#getDataRegState()}.
+         * @hide
+         */
+        public static final String DATA_REG_STATE = "data_reg_state";
+
+        /**
+         * An integer value indicating the current voice roaming type.
+         * <p>
+         * This is the same as {@link ServiceState#getVoiceRoamingType()}.
+         * @hide
+         */
+        public static final String VOICE_ROAMING_TYPE = "voice_roaming_type";
+
+        /**
+         * An integer value indicating the current data roaming type.
+         * <p>
+         * This is the same as {@link ServiceState#getDataRoamingType()}.
+         * @hide
+         */
+        public static final String DATA_ROAMING_TYPE = "data_roaming_type";
+
+        /**
+         * The current registered voice network operator name in long alphanumeric format.
+         * <p>
+         * This is the same as {@link ServiceState#getVoiceOperatorAlphaLong()}.
+         * @hide
+         */
+        public static final String VOICE_OPERATOR_ALPHA_LONG = "voice_operator_alpha_long";
+
+        /**
+         * The current registered operator name in short alphanumeric format.
+         * <p>
+         * In GSM/UMTS, short format can be up to 8 characters long. The current registered voice
+         * network operator name in long alphanumeric format.
+         * <p>
+         * This is the same as {@link ServiceState#getVoiceOperatorAlphaShort()}.
+         * @hide
+         */
+        public static final String VOICE_OPERATOR_ALPHA_SHORT = "voice_operator_alpha_short";
+
+
+        /**
+         * The current registered operator numeric id.
+         * <p>
+         * In GSM/UMTS, numeric format is 3 digit country code plus 2 or 3 digit
+         * network code.
+         * <p>
+         * This is the same as {@link ServiceState#getOperatorNumeric()}.
+         */
+        public static final String VOICE_OPERATOR_NUMERIC = "voice_operator_numeric";
+
+        /**
+         * The current registered data network operator name in long alphanumeric format.
+         * <p>
+         * This is the same as {@link ServiceState#getDataOperatorAlphaLong()}.
+         * @hide
+         */
+        public static final String DATA_OPERATOR_ALPHA_LONG = "data_operator_alpha_long";
+
+        /**
+         * The current registered data network operator name in short alphanumeric format.
+         * <p>
+         * This is the same as {@link ServiceState#getDataOperatorAlphaShort()}.
+         * @hide
+         */
+        public static final String DATA_OPERATOR_ALPHA_SHORT = "data_operator_alpha_short";
+
+        /**
+         * The current registered data network operator numeric id.
+         * <p>
+         * This is the same as {@link ServiceState#getDataOperatorNumeric()}.
+         * @hide
+         */
+        public static final String DATA_OPERATOR_NUMERIC = "data_operator_numeric";
+
+        /**
+         * The current network selection mode.
+         * <p>
+         * This is the same as {@link ServiceState#getIsManualSelection()}.
+         */
+        public static final String IS_MANUAL_NETWORK_SELECTION = "is_manual_network_selection";
+
+        /**
+         * This is the same as {@link ServiceState#getRilVoiceRadioTechnology()}.
+         * @hide
+         */
+        public static final String RIL_VOICE_RADIO_TECHNOLOGY = "ril_voice_radio_technology";
+
+        /**
+         * This is the same as {@link ServiceState#getRilDataRadioTechnology()}.
+         * @hide
+         */
+        public static final String RIL_DATA_RADIO_TECHNOLOGY = "ril_data_radio_technology";
+
+        /**
+         * This is the same as {@link ServiceState#getCssIndicator()}.
+         * @hide
+         */
+        public static final String CSS_INDICATOR = "css_indicator";
+
+        /**
+         * This is the same as {@link ServiceState#getNetworkId()}.
+         * @hide
+         */
+        public static final String NETWORK_ID = "network_id";
+
+        /**
+         * This is the same as {@link ServiceState#getSystemId()}.
+         * @hide
+         */
+        public static final String SYSTEM_ID = "system_id";
+
+        /**
+         * This is the same as {@link ServiceState#getCdmaRoamingIndicator()}.
+         * @hide
+         */
+        public static final String CDMA_ROAMING_INDICATOR = "cdma_roaming_indicator";
+
+        /**
+         * This is the same as {@link ServiceState#getCdmaDefaultRoamingIndicator()}.
+         * @hide
+         */
+        public static final String CDMA_DEFAULT_ROAMING_INDICATOR =
+                "cdma_default_roaming_indicator";
+
+        /**
+         * This is the same as {@link ServiceState#getCdmaEriIconIndex()}.
+         * @hide
+         */
+        public static final String CDMA_ERI_ICON_INDEX = "cdma_eri_icon_index";
+
+        /**
+         * This is the same as {@link ServiceState#getCdmaEriIconMode()}.
+         * @hide
+         */
+        public static final String CDMA_ERI_ICON_MODE = "cdma_eri_icon_mode";
+
+        /**
+         * This is the same as {@link ServiceState#isEmergencyOnly()}.
+         * @hide
+         */
+        public static final String IS_EMERGENCY_ONLY = "is_emergency_only";
+
+        /**
+         * This is the same as {@link ServiceState#getDataRoamingFromRegistration()}.
+         * @hide
+         */
+        public static final String IS_DATA_ROAMING_FROM_REGISTRATION =
+                "is_data_roaming_from_registration";
+
+        /**
+         * This is the same as {@link ServiceState#isUsingCarrierAggregation()}.
+         * @hide
+         */
+        public static final String IS_USING_CARRIER_AGGREGATION = "is_using_carrier_aggregation";
+    }
 }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 397aa00..3d51c4c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -4393,7 +4393,7 @@
      * Returns null if the query fails.
      *
      *
-     * <p>Requires that the caller has READ_PRIVILEGED_PHONE_STATE
+     * <p>Requires that the caller has READ_PHONE_STATE
      *
      * @return an array of forbidden PLMNs or null if not available
      */
@@ -4406,7 +4406,7 @@
      * Returns null if the query fails.
      *
      *
-     * <p>Requires that the calling app has READ_PRIVILEGED_PHONE_STATE
+     * <p>Requires that the calling app has READ_PHONE_STATE
      *
      * @param subId subscription ID used for authentication
      * @param appType the icc application type, like {@link #APPTYPE_USIM}
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index a8eb986..b4e3a47 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -530,13 +530,6 @@
         throw new UnsupportedOperationException();
     }
 
-    /** STOPSHIP remove when trial API is turned down */
-    @Override
-    public ComponentName startServiceInForeground(Intent service,
-            int id, Notification notification) {
-        throw new UnsupportedOperationException();
-    }
-
     @Override
     public boolean stopService(Intent service) {
         throw new UnsupportedOperationException();
@@ -554,13 +547,6 @@
         throw new UnsupportedOperationException();
     }
 
-    /** @hide STOPSHIP removed when trial API is turned down */
-    @Override
-    public ComponentName startServiceInForegroundAsUser(Intent service,
-            int id, Notification notification, UserHandle user) {
-        throw new UnsupportedOperationException();
-    }
-
     /** @hide */
     @Override
     public boolean stopServiceAsUser(Intent service, UserHandle user) {
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 960a2d9..20392e7 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -1126,4 +1126,12 @@
     public ComponentName getInstantAppResolverSettingsComponent() {
         throw new UnsupportedOperationException();
     }
+
+    /**
+     * @hide
+     */
+    @Override
+    public ComponentName getInstantAppInstallerComponent() {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 328fc0a..1e77ac1 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -1865,13 +1865,6 @@
     }
 
     @Override
-    public ComponentName startServiceInForeground(Intent service,
-            int id, Notification notification) {
-        // pass
-        return null;
-    }
-
-    @Override
     public boolean stopService(Intent arg0) {
         // pass
         return false;
@@ -1884,13 +1877,6 @@
     }
 
     @Override
-    public ComponentName startServiceInForegroundAsUser(Intent service,
-            int id, Notification notification, UserHandle user) {
-        // pass
-        return null;
-    }
-
-    @Override
     public boolean stopServiceAsUser(Intent arg0, UserHandle arg1) {
         // pass
         return false;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
index 5a239e1..ad26bc8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
@@ -923,4 +923,9 @@
     public ComponentName getInstantAppResolverSettingsComponent() {
         return null;
     }
+
+    @Override
+    public ComponentName getInstantAppInstallerComponent() {
+        return null;
+    }
 }