Merge "Force pinned windows to always be scaleable." into nyc-dev
diff --git a/Android.mk b/Android.mk
index f875be2..da53db7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -331,7 +331,7 @@
 	core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl \
 	core/java/com/android/internal/textservice/ITextServicesManager.aidl \
 	core/java/com/android/internal/textservice/ITextServicesSessionListener.aidl \
-	core/java/com/android/internal/view/IDropPermissions.aidl \
+	core/java/com/android/internal/view/IDragAndDropPermissions.aidl \
 	core/java/com/android/internal/view/IInputContext.aidl \
 	core/java/com/android/internal/view/IInputContextCallback.aidl \
 	core/java/com/android/internal/view/IInputMethod.aidl \
diff --git a/api/current.txt b/api/current.txt
index 00a2b7a..b8b9079 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3424,6 +3424,7 @@
     method public void closeOptionsMenu();
     method public android.app.PendingIntent createPendingResult(int, android.content.Intent, int);
     method public final deprecated void dismissDialog(int);
+    method public final void dismissKeyboardShortcutsHelper();
     method public boolean dispatchGenericMotionEvent(android.view.MotionEvent);
     method public boolean dispatchKeyEvent(android.view.KeyEvent);
     method public boolean dispatchKeyShortcutEvent(android.view.KeyEvent);
@@ -3580,7 +3581,7 @@
     method public boolean releaseInstance();
     method public final deprecated void removeDialog(int);
     method public void reportFullyDrawn();
-    method public android.view.DropPermissions requestDropPermissions(android.view.DragEvent);
+    method public android.view.DragAndDropPermissions requestDragAndDropPermissions(android.view.DragEvent);
     method public final void requestKeyboardShortcutsHelper();
     method public final void requestPermissions(java.lang.String[], int);
     method public boolean requestVisibleBehind(boolean);
@@ -4926,6 +4927,7 @@
     field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
     field public static final java.lang.String EXTRA_CHRONOMETER_COUNTS_DOWN = "android.chronometerCountsDown";
     field public static final java.lang.String EXTRA_COMPACT_ACTIONS = "android.compactActions";
+    field public static final java.lang.String EXTRA_CONVERSATION_TITLE = "android.conversationTitle";
     field public static final java.lang.String EXTRA_INFO_TEXT = "android.infoText";
     field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
     field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
@@ -4946,7 +4948,6 @@
     field public static final java.lang.String EXTRA_TEMPLATE = "android.template";
     field public static final java.lang.String EXTRA_TEXT = "android.text";
     field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
-    field public static final java.lang.String EXTRA_THREAD_TITLE = "android.threadTitle";
     field public static final java.lang.String EXTRA_TITLE = "android.title";
     field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
     field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
@@ -5199,17 +5200,14 @@
     field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
   }
 
-  public static final class Notification.MessagingStyle.Message implements android.os.Parcelable {
+  public static final class Notification.MessagingStyle.Message {
     ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
-    method public int describeContents();
     method public java.lang.String getDataMimeType();
     method public android.net.Uri getDataUri();
     method public java.lang.CharSequence getSender();
     method public java.lang.CharSequence getText();
     method public long getTimestamp();
     method public android.app.Notification.MessagingStyle.Message setData(java.lang.String, android.net.Uri);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.app.Notification.MessagingStyle.Message> CREATOR;
   }
 
   public static abstract class Notification.Style {
@@ -5244,6 +5242,7 @@
     method public int getCustomSizePreset();
     method public android.app.PendingIntent getDisplayIntent();
     method public int getGravity();
+    method public boolean getHintAmbientBigPicture();
     method public boolean getHintAvoidBackgroundClipping();
     method public boolean getHintContentIntentLaunchesActivity();
     method public boolean getHintHideIcon();
@@ -5260,6 +5259,7 @@
     method public android.app.Notification.WearableExtender setCustomSizePreset(int);
     method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent);
     method public android.app.Notification.WearableExtender setGravity(int);
+    method public android.app.Notification.WearableExtender setHintAmbientBigPicture(boolean);
     method public android.app.Notification.WearableExtender setHintAvoidBackgroundClipping(boolean);
     method public android.app.Notification.WearableExtender setHintContentIntentLaunchesActivity(boolean);
     method public android.app.Notification.WearableExtender setHintHideIcon(boolean);
@@ -23024,6 +23024,7 @@
     method public boolean isRatingBlocked(android.media.tv.TvContentRating);
     method public void registerCallback(android.media.tv.TvInputManager.TvInputCallback, android.os.Handler);
     method public void unregisterCallback(android.media.tv.TvInputManager.TvInputCallback);
+    method public void updateTvInputInfo(android.media.tv.TvInputInfo);
     field public static final java.lang.String ACTION_BLOCKED_RATINGS_CHANGED = "android.media.tv.action.BLOCKED_RATINGS_CHANGED";
     field public static final java.lang.String ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED = "android.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED";
     field public static final java.lang.String ACTION_QUERY_CONTENT_RATING_SYSTEMS = "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS";
@@ -23061,7 +23062,6 @@
     method public final android.os.IBinder onBind(android.content.Intent);
     method public android.media.tv.TvInputService.RecordingSession onCreateRecordingSession(java.lang.String);
     method public abstract android.media.tv.TvInputService.Session onCreateSession(java.lang.String);
-    method public static final void updateTvInputInfo(android.content.Context, android.media.tv.TvInputInfo);
     field public static final java.lang.String SERVICE_INTERFACE = "android.media.tv.TvInputService";
     field public static final java.lang.String SERVICE_META_DATA = "android.media.tv.input";
   }
@@ -23243,24 +23243,6 @@
     ctor public MtpConstants();
     method public static boolean isAbstractObject(int);
     field public static final int ASSOCIATION_TYPE_GENERIC_FOLDER = 1; // 0x1
-    field public static final int EVENT_CANCEL_TRANSACTION = 16385; // 0x4001
-    field public static final int EVENT_CAPTURE_COMPLETE = 16397; // 0x400d
-    field public static final int EVENT_DEVICE_INFO_CHANGED = 16392; // 0x4008
-    field public static final int EVENT_DEVICE_PROP_CHANGED = 16390; // 0x4006
-    field public static final int EVENT_DEVICE_RESET = 16395; // 0x400b
-    field public static final int EVENT_OBJECT_ADDED = 16386; // 0x4002
-    field public static final int EVENT_OBJECT_INFO_CHANGED = 16391; // 0x4007
-    field public static final int EVENT_OBJECT_PROP_CHANGED = 51201; // 0xc801
-    field public static final int EVENT_OBJECT_PROP_DESC_CHANGED = 51202; // 0xc802
-    field public static final int EVENT_OBJECT_REFERENCES_CHANGED = 51203; // 0xc803
-    field public static final int EVENT_OBJECT_REMOVED = 16387; // 0x4003
-    field public static final int EVENT_REQUEST_OBJECT_TRANSFER = 16393; // 0x4009
-    field public static final int EVENT_STORAGE_INFO_CHANGED = 16396; // 0x400c
-    field public static final int EVENT_STORE_ADDED = 16388; // 0x4004
-    field public static final int EVENT_STORE_FULL = 16394; // 0x400a
-    field public static final int EVENT_STORE_REMOVED = 16389; // 0x4005
-    field public static final int EVENT_UNDEFINED = 16384; // 0x4000
-    field public static final int EVENT_UNREPORTED_STATUS = 16398; // 0x400e
     field public static final int FORMAT_3GP_CONTAINER = 47492; // 0xb984
     field public static final int FORMAT_AAC = 47363; // 0xb903
     field public static final int FORMAT_ABSTRACT_AUDIO_ALBUM = 47619; // 0xba03
@@ -23381,7 +23363,7 @@
     method public boolean importFile(int, java.lang.String);
     method public boolean importFile(int, android.os.ParcelFileDescriptor);
     method public boolean open(android.hardware.usb.UsbDeviceConnection);
-    method public android.mtp.MtpEvent readEvent(android.os.CancellationSignal);
+    method public android.mtp.MtpEvent readEvent(android.os.CancellationSignal) throws java.io.IOException;
     method public boolean sendObject(int, long, android.os.ParcelFileDescriptor);
     method public android.mtp.MtpObjectInfo sendObjectInfo(android.mtp.MtpObjectInfo);
   }
@@ -23393,10 +23375,11 @@
     method public final int[] getOperationsSupported();
     method public final java.lang.String getSerialNumber();
     method public final java.lang.String getVersion();
+    method public boolean isEventSupported(int);
+    method public boolean isOperationSupported(int);
   }
 
   public class MtpEvent {
-    ctor public MtpEvent();
     method public int getDevicePropCode();
     method public int getEventCode();
     method public int getObjectFormatCode();
@@ -23407,6 +23390,24 @@
     method public int getParameter3();
     method public int getStorageId();
     method public int getTransactionId();
+    field public static final int EVENT_CANCEL_TRANSACTION = 16385; // 0x4001
+    field public static final int EVENT_CAPTURE_COMPLETE = 16397; // 0x400d
+    field public static final int EVENT_DEVICE_INFO_CHANGED = 16392; // 0x4008
+    field public static final int EVENT_DEVICE_PROP_CHANGED = 16390; // 0x4006
+    field public static final int EVENT_DEVICE_RESET = 16395; // 0x400b
+    field public static final int EVENT_OBJECT_ADDED = 16386; // 0x4002
+    field public static final int EVENT_OBJECT_INFO_CHANGED = 16391; // 0x4007
+    field public static final int EVENT_OBJECT_PROP_CHANGED = 51201; // 0xc801
+    field public static final int EVENT_OBJECT_PROP_DESC_CHANGED = 51202; // 0xc802
+    field public static final int EVENT_OBJECT_REFERENCES_CHANGED = 51203; // 0xc803
+    field public static final int EVENT_OBJECT_REMOVED = 16387; // 0x4003
+    field public static final int EVENT_REQUEST_OBJECT_TRANSFER = 16393; // 0x4009
+    field public static final int EVENT_STORAGE_INFO_CHANGED = 16396; // 0x400c
+    field public static final int EVENT_STORE_ADDED = 16388; // 0x4004
+    field public static final int EVENT_STORE_FULL = 16394; // 0x400a
+    field public static final int EVENT_STORE_REMOVED = 16389; // 0x4005
+    field public static final int EVENT_UNDEFINED = 16384; // 0x4000
+    field public static final int EVENT_UNREPORTED_STATUS = 16398; // 0x400e
   }
 
   public final class MtpObjectInfo {
@@ -40973,6 +40974,10 @@
     field public static final android.os.Parcelable.Creator<android.view.Display.Mode> CREATOR;
   }
 
+  public final class DragAndDropPermissions {
+    method public void release();
+  }
+
   public class DragEvent implements android.os.Parcelable {
     method public int describeContents();
     method public int getAction();
@@ -40992,10 +40997,6 @@
     field public static final android.os.Parcelable.Creator<android.view.DragEvent> CREATOR;
   }
 
-  public final class DropPermissions {
-    method public void release();
-  }
-
   public class FocusFinder {
     method public android.view.View findNearestTouchable(android.view.ViewGroup, int, int, int, int[]);
     method public final android.view.View findNextFocus(android.view.ViewGroup, android.view.View, int);
@@ -43529,7 +43530,7 @@
     ctor public Window(android.content.Context);
     method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public void addFlags(int);
-    method public final void addFrameMetricsListener(android.view.Window.FrameMetricsListener, android.os.Handler);
+    method public final void addOnFrameMetricsAvailableListener(android.view.Window.OnFrameMetricsAvailableListener, android.os.Handler);
     method public void clearFlags(int);
     method public abstract void closeAllPanels();
     method public abstract void closePanel(int);
@@ -43581,7 +43582,7 @@
     method public abstract boolean performContextMenuIdentifierAction(int, int);
     method public abstract boolean performPanelIdentifierAction(int, int, int);
     method public abstract boolean performPanelShortcut(int, int, android.view.KeyEvent, int);
-    method public final void removeFrameMetricsListener(android.view.Window.FrameMetricsListener);
+    method public final void removeOnFrameMetricsAvailableListener(android.view.Window.OnFrameMetricsAvailableListener);
     method public boolean requestFeature(int);
     method public abstract void restoreHierarchyState(android.os.Bundle);
     method public abstract android.os.Bundle saveHierarchyState();
@@ -43708,8 +43709,8 @@
     method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback, int);
   }
 
-  public static abstract interface Window.FrameMetricsListener {
-    method public abstract void onMetricsAvailable(android.view.Window, android.view.FrameMetrics, int);
+  public static abstract interface Window.OnFrameMetricsAvailableListener {
+    method public abstract void onFrameMetricsAvailable(android.view.Window, android.view.FrameMetrics, int);
   }
 
   public static abstract interface Window.OnRestrictedCaptionAreaChangedListener {
@@ -47463,7 +47464,7 @@
     method public void setChar(int, java.lang.String, char);
     method public void setCharSequence(int, java.lang.String, java.lang.CharSequence);
     method public void setChronometer(int, long, java.lang.String, boolean);
-    method public void setChronometerCountsDown(int, boolean);
+    method public void setChronometerCountDown(int, boolean);
     method public void setContentDescription(int, java.lang.CharSequence);
     method public void setDisplayedChild(int, int);
     method public void setDouble(int, java.lang.String, double);
diff --git a/api/removed.txt b/api/removed.txt
index 8c6abdc..de8a724 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -165,6 +165,31 @@
 
 }
 
+package android.mtp {
+
+  public final class MtpConstants {
+    field public static final int EVENT_CANCEL_TRANSACTION = 16385; // 0x4001
+    field public static final int EVENT_CAPTURE_COMPLETE = 16397; // 0x400d
+    field public static final int EVENT_DEVICE_INFO_CHANGED = 16392; // 0x4008
+    field public static final int EVENT_DEVICE_PROP_CHANGED = 16390; // 0x4006
+    field public static final int EVENT_DEVICE_RESET = 16395; // 0x400b
+    field public static final int EVENT_OBJECT_ADDED = 16386; // 0x4002
+    field public static final int EVENT_OBJECT_INFO_CHANGED = 16391; // 0x4007
+    field public static final int EVENT_OBJECT_PROP_CHANGED = 51201; // 0xc801
+    field public static final int EVENT_OBJECT_PROP_DESC_CHANGED = 51202; // 0xc802
+    field public static final int EVENT_OBJECT_REFERENCES_CHANGED = 51203; // 0xc803
+    field public static final int EVENT_OBJECT_REMOVED = 16387; // 0x4003
+    field public static final int EVENT_REQUEST_OBJECT_TRANSFER = 16393; // 0x4009
+    field public static final int EVENT_STORAGE_INFO_CHANGED = 16396; // 0x400c
+    field public static final int EVENT_STORE_ADDED = 16388; // 0x4004
+    field public static final int EVENT_STORE_FULL = 16394; // 0x400a
+    field public static final int EVENT_STORE_REMOVED = 16389; // 0x4005
+    field public static final int EVENT_UNDEFINED = 16384; // 0x4000
+    field public static final int EVENT_UNREPORTED_STATUS = 16398; // 0x400e
+  }
+
+}
+
 package android.net {
 
   public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
diff --git a/api/system-current.txt b/api/system-current.txt
index f017bb0..06d95ef 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3541,6 +3541,7 @@
     method public boolean convertToTranslucent(android.app.Activity.TranslucentConversionListener, android.app.ActivityOptions);
     method public android.app.PendingIntent createPendingResult(int, android.content.Intent, int);
     method public final deprecated void dismissDialog(int);
+    method public final void dismissKeyboardShortcutsHelper();
     method public boolean dispatchGenericMotionEvent(android.view.MotionEvent);
     method public boolean dispatchKeyEvent(android.view.KeyEvent);
     method public boolean dispatchKeyShortcutEvent(android.view.KeyEvent);
@@ -3699,7 +3700,7 @@
     method public boolean releaseInstance();
     method public final deprecated void removeDialog(int);
     method public void reportFullyDrawn();
-    method public android.view.DropPermissions requestDropPermissions(android.view.DragEvent);
+    method public android.view.DragAndDropPermissions requestDragAndDropPermissions(android.view.DragEvent);
     method public final void requestKeyboardShortcutsHelper();
     method public final void requestPermissions(java.lang.String[], int);
     method public boolean requestVisibleBehind(boolean);
@@ -5060,6 +5061,7 @@
     field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
     field public static final java.lang.String EXTRA_CHRONOMETER_COUNTS_DOWN = "android.chronometerCountsDown";
     field public static final java.lang.String EXTRA_COMPACT_ACTIONS = "android.compactActions";
+    field public static final java.lang.String EXTRA_CONVERSATION_TITLE = "android.conversationTitle";
     field public static final java.lang.String EXTRA_INFO_TEXT = "android.infoText";
     field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
     field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
@@ -5080,7 +5082,6 @@
     field public static final java.lang.String EXTRA_TEMPLATE = "android.template";
     field public static final java.lang.String EXTRA_TEXT = "android.text";
     field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
-    field public static final java.lang.String EXTRA_THREAD_TITLE = "android.threadTitle";
     field public static final java.lang.String EXTRA_TITLE = "android.title";
     field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
     field public static final int FLAG_AUTOGROUP_SUMMARY = 1024; // 0x400
@@ -5334,17 +5335,14 @@
     field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
   }
 
-  public static final class Notification.MessagingStyle.Message implements android.os.Parcelable {
+  public static final class Notification.MessagingStyle.Message {
     ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
-    method public int describeContents();
     method public java.lang.String getDataMimeType();
     method public android.net.Uri getDataUri();
     method public java.lang.CharSequence getSender();
     method public java.lang.CharSequence getText();
     method public long getTimestamp();
     method public android.app.Notification.MessagingStyle.Message setData(java.lang.String, android.net.Uri);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.app.Notification.MessagingStyle.Message> CREATOR;
   }
 
   public static abstract class Notification.Style {
@@ -5379,6 +5377,7 @@
     method public int getCustomSizePreset();
     method public android.app.PendingIntent getDisplayIntent();
     method public int getGravity();
+    method public boolean getHintAmbientBigPicture();
     method public boolean getHintAvoidBackgroundClipping();
     method public boolean getHintContentIntentLaunchesActivity();
     method public boolean getHintHideIcon();
@@ -5395,6 +5394,7 @@
     method public android.app.Notification.WearableExtender setCustomSizePreset(int);
     method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent);
     method public android.app.Notification.WearableExtender setGravity(int);
+    method public android.app.Notification.WearableExtender setHintAmbientBigPicture(boolean);
     method public android.app.Notification.WearableExtender setHintAvoidBackgroundClipping(boolean);
     method public android.app.Notification.WearableExtender setHintContentIntentLaunchesActivity(boolean);
     method public android.app.Notification.WearableExtender setHintHideIcon(boolean);
@@ -24710,6 +24710,7 @@
     method public void removeBlockedRating(android.media.tv.TvContentRating);
     method public void setParentalControlsEnabled(boolean);
     method public void unregisterCallback(android.media.tv.TvInputManager.TvInputCallback);
+    method public void updateTvInputInfo(android.media.tv.TvInputInfo);
     field public static final java.lang.String ACTION_BLOCKED_RATINGS_CHANGED = "android.media.tv.action.BLOCKED_RATINGS_CHANGED";
     field public static final java.lang.String ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED = "android.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED";
     field public static final java.lang.String ACTION_QUERY_CONTENT_RATING_SYSTEMS = "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS";
@@ -24764,7 +24765,6 @@
     method public java.lang.String onHardwareRemoved(android.media.tv.TvInputHardwareInfo);
     method public android.media.tv.TvInputInfo onHdmiDeviceAdded(android.hardware.hdmi.HdmiDeviceInfo);
     method public java.lang.String onHdmiDeviceRemoved(android.hardware.hdmi.HdmiDeviceInfo);
-    method public static final void updateTvInputInfo(android.content.Context, android.media.tv.TvInputInfo);
     field public static final java.lang.String SERVICE_INTERFACE = "android.media.tv.TvInputService";
     field public static final java.lang.String SERVICE_META_DATA = "android.media.tv.input";
   }
@@ -24979,24 +24979,6 @@
     ctor public MtpConstants();
     method public static boolean isAbstractObject(int);
     field public static final int ASSOCIATION_TYPE_GENERIC_FOLDER = 1; // 0x1
-    field public static final int EVENT_CANCEL_TRANSACTION = 16385; // 0x4001
-    field public static final int EVENT_CAPTURE_COMPLETE = 16397; // 0x400d
-    field public static final int EVENT_DEVICE_INFO_CHANGED = 16392; // 0x4008
-    field public static final int EVENT_DEVICE_PROP_CHANGED = 16390; // 0x4006
-    field public static final int EVENT_DEVICE_RESET = 16395; // 0x400b
-    field public static final int EVENT_OBJECT_ADDED = 16386; // 0x4002
-    field public static final int EVENT_OBJECT_INFO_CHANGED = 16391; // 0x4007
-    field public static final int EVENT_OBJECT_PROP_CHANGED = 51201; // 0xc801
-    field public static final int EVENT_OBJECT_PROP_DESC_CHANGED = 51202; // 0xc802
-    field public static final int EVENT_OBJECT_REFERENCES_CHANGED = 51203; // 0xc803
-    field public static final int EVENT_OBJECT_REMOVED = 16387; // 0x4003
-    field public static final int EVENT_REQUEST_OBJECT_TRANSFER = 16393; // 0x4009
-    field public static final int EVENT_STORAGE_INFO_CHANGED = 16396; // 0x400c
-    field public static final int EVENT_STORE_ADDED = 16388; // 0x4004
-    field public static final int EVENT_STORE_FULL = 16394; // 0x400a
-    field public static final int EVENT_STORE_REMOVED = 16389; // 0x4005
-    field public static final int EVENT_UNDEFINED = 16384; // 0x4000
-    field public static final int EVENT_UNREPORTED_STATUS = 16398; // 0x400e
     field public static final int FORMAT_3GP_CONTAINER = 47492; // 0xb984
     field public static final int FORMAT_AAC = 47363; // 0xb903
     field public static final int FORMAT_ABSTRACT_AUDIO_ALBUM = 47619; // 0xba03
@@ -25117,7 +25099,7 @@
     method public boolean importFile(int, java.lang.String);
     method public boolean importFile(int, android.os.ParcelFileDescriptor);
     method public boolean open(android.hardware.usb.UsbDeviceConnection);
-    method public android.mtp.MtpEvent readEvent(android.os.CancellationSignal);
+    method public android.mtp.MtpEvent readEvent(android.os.CancellationSignal) throws java.io.IOException;
     method public boolean sendObject(int, long, android.os.ParcelFileDescriptor);
     method public android.mtp.MtpObjectInfo sendObjectInfo(android.mtp.MtpObjectInfo);
   }
@@ -25129,10 +25111,11 @@
     method public final int[] getOperationsSupported();
     method public final java.lang.String getSerialNumber();
     method public final java.lang.String getVersion();
+    method public boolean isEventSupported(int);
+    method public boolean isOperationSupported(int);
   }
 
   public class MtpEvent {
-    ctor public MtpEvent();
     method public int getDevicePropCode();
     method public int getEventCode();
     method public int getObjectFormatCode();
@@ -25143,6 +25126,24 @@
     method public int getParameter3();
     method public int getStorageId();
     method public int getTransactionId();
+    field public static final int EVENT_CANCEL_TRANSACTION = 16385; // 0x4001
+    field public static final int EVENT_CAPTURE_COMPLETE = 16397; // 0x400d
+    field public static final int EVENT_DEVICE_INFO_CHANGED = 16392; // 0x4008
+    field public static final int EVENT_DEVICE_PROP_CHANGED = 16390; // 0x4006
+    field public static final int EVENT_DEVICE_RESET = 16395; // 0x400b
+    field public static final int EVENT_OBJECT_ADDED = 16386; // 0x4002
+    field public static final int EVENT_OBJECT_INFO_CHANGED = 16391; // 0x4007
+    field public static final int EVENT_OBJECT_PROP_CHANGED = 51201; // 0xc801
+    field public static final int EVENT_OBJECT_PROP_DESC_CHANGED = 51202; // 0xc802
+    field public static final int EVENT_OBJECT_REFERENCES_CHANGED = 51203; // 0xc803
+    field public static final int EVENT_OBJECT_REMOVED = 16387; // 0x4003
+    field public static final int EVENT_REQUEST_OBJECT_TRANSFER = 16393; // 0x4009
+    field public static final int EVENT_STORAGE_INFO_CHANGED = 16396; // 0x400c
+    field public static final int EVENT_STORE_ADDED = 16388; // 0x4004
+    field public static final int EVENT_STORE_FULL = 16394; // 0x400a
+    field public static final int EVENT_STORE_REMOVED = 16389; // 0x4005
+    field public static final int EVENT_UNDEFINED = 16384; // 0x4000
+    field public static final int EVENT_UNREPORTED_STATUS = 16398; // 0x400e
   }
 
   public final class MtpObjectInfo {
@@ -26011,29 +26012,6 @@
 
 package android.net.metrics {
 
-  public final class CaptivePortalCheckResultEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
-    method public int describeContents();
-    method public static void logEvent(int, int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.net.metrics.CaptivePortalCheckResultEvent> CREATOR;
-    field public final int netId;
-    field public final int result;
-  }
-
-  public final class CaptivePortalStateChangeEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
-    ctor public CaptivePortalStateChangeEvent(int, int);
-    ctor public CaptivePortalStateChangeEvent(android.os.Parcel);
-    method public int describeContents();
-    method public static void logEvent(int, int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.net.metrics.CaptivePortalStateChangeEvent> CREATOR;
-    field public static final int NETWORK_MONITOR_CONNECTED = 0; // 0x0
-    field public static final int NETWORK_MONITOR_DISCONNECTED = 1; // 0x1
-    field public static final int NETWORK_MONITOR_VALIDATED = 2; // 0x2
-    field public final int netId;
-    field public final int state;
-  }
-
   public final class DefaultNetworkEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
     method public int describeContents();
     method public static void logEvent(int, int[], int, boolean, boolean);
@@ -26147,16 +26125,35 @@
     field public final java.lang.String ifName;
   }
 
-  public final class NetworkMonitorEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
-    ctor public NetworkMonitorEvent(android.os.Parcel);
+  public final class NetworkEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
     method public int describeContents();
     method public static void logCaptivePortalFound(int, long);
-    method public static void logPortalProbeEvent(int, long, int);
+    method public static void logEvent(int, int);
     method public static void logValidated(int, long);
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.net.metrics.NetworkMonitorEvent> CREATOR;
+    field public static final android.os.Parcelable.Creator<android.net.metrics.NetworkEvent> CREATOR;
+    field public static final int NETWORK_CAPTIVE_PORTAL_FOUND = 4; // 0x4
+    field public static final int NETWORK_CONNECTED = 1; // 0x1
+    field public static final int NETWORK_DISCONNECTED = 7; // 0x7
+    field public static final int NETWORK_LINGER = 5; // 0x5
+    field public static final int NETWORK_UNLINGER = 6; // 0x6
+    field public static final int NETWORK_VALIDATED = 2; // 0x2
+    field public static final int NETWORK_VALIDATION_FAILED = 3; // 0x3
+    field public final long durationMs;
+    field public final int eventType;
+    field public final int netId;
+  }
+
+  public final class ValidationProbeEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
+    method public int describeContents();
+    method public static void logEvent(int, long, int, int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.metrics.ValidationProbeEvent> CREATOR;
+    field public static final int PROBE_HTTP = 0; // 0x0
+    field public static final int PROBE_HTTPS = 1; // 0x1
     field public final long durationMs;
     field public final int netId;
+    field public final int probeType;
     field public final int returnCode;
   }
 
@@ -43924,6 +43921,10 @@
     field public static final android.os.Parcelable.Creator<android.view.Display.Mode> CREATOR;
   }
 
+  public final class DragAndDropPermissions {
+    method public void release();
+  }
+
   public class DragEvent implements android.os.Parcelable {
     method public int describeContents();
     method public int getAction();
@@ -43943,10 +43944,6 @@
     field public static final android.os.Parcelable.Creator<android.view.DragEvent> CREATOR;
   }
 
-  public final class DropPermissions {
-    method public void release();
-  }
-
   public class FocusFinder {
     method public android.view.View findNearestTouchable(android.view.ViewGroup, int, int, int, int[]);
     method public final android.view.View findNextFocus(android.view.ViewGroup, android.view.View, int);
@@ -46480,7 +46477,7 @@
     ctor public Window(android.content.Context);
     method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public void addFlags(int);
-    method public final void addFrameMetricsListener(android.view.Window.FrameMetricsListener, android.os.Handler);
+    method public final void addOnFrameMetricsAvailableListener(android.view.Window.OnFrameMetricsAvailableListener, android.os.Handler);
     method public void clearFlags(int);
     method public abstract void closeAllPanels();
     method public abstract void closePanel(int);
@@ -46532,7 +46529,7 @@
     method public abstract boolean performContextMenuIdentifierAction(int, int);
     method public abstract boolean performPanelIdentifierAction(int, int, int);
     method public abstract boolean performPanelShortcut(int, int, android.view.KeyEvent, int);
-    method public final void removeFrameMetricsListener(android.view.Window.FrameMetricsListener);
+    method public final void removeOnFrameMetricsAvailableListener(android.view.Window.OnFrameMetricsAvailableListener);
     method public boolean requestFeature(int);
     method public abstract void restoreHierarchyState(android.os.Bundle);
     method public abstract android.os.Bundle saveHierarchyState();
@@ -46660,8 +46657,8 @@
     method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback, int);
   }
 
-  public static abstract interface Window.FrameMetricsListener {
-    method public abstract void onMetricsAvailable(android.view.Window, android.view.FrameMetrics, int);
+  public static abstract interface Window.OnFrameMetricsAvailableListener {
+    method public abstract void onFrameMetricsAvailable(android.view.Window, android.view.FrameMetrics, int);
   }
 
   public static abstract interface Window.OnRestrictedCaptionAreaChangedListener {
@@ -50772,7 +50769,7 @@
     method public void setChar(int, java.lang.String, char);
     method public void setCharSequence(int, java.lang.String, java.lang.CharSequence);
     method public void setChronometer(int, long, java.lang.String, boolean);
-    method public void setChronometerCountsDown(int, boolean);
+    method public void setChronometerCountDown(int, boolean);
     method public void setContentDescription(int, java.lang.CharSequence);
     method public void setDisplayedChild(int, int);
     method public void setDouble(int, java.lang.String, double);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 95734c1..844604c 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -163,6 +163,31 @@
 
 }
 
+package android.mtp {
+
+  public final class MtpConstants {
+    field public static final int EVENT_CANCEL_TRANSACTION = 16385; // 0x4001
+    field public static final int EVENT_CAPTURE_COMPLETE = 16397; // 0x400d
+    field public static final int EVENT_DEVICE_INFO_CHANGED = 16392; // 0x4008
+    field public static final int EVENT_DEVICE_PROP_CHANGED = 16390; // 0x4006
+    field public static final int EVENT_DEVICE_RESET = 16395; // 0x400b
+    field public static final int EVENT_OBJECT_ADDED = 16386; // 0x4002
+    field public static final int EVENT_OBJECT_INFO_CHANGED = 16391; // 0x4007
+    field public static final int EVENT_OBJECT_PROP_CHANGED = 51201; // 0xc801
+    field public static final int EVENT_OBJECT_PROP_DESC_CHANGED = 51202; // 0xc802
+    field public static final int EVENT_OBJECT_REFERENCES_CHANGED = 51203; // 0xc803
+    field public static final int EVENT_OBJECT_REMOVED = 16387; // 0x4003
+    field public static final int EVENT_REQUEST_OBJECT_TRANSFER = 16393; // 0x4009
+    field public static final int EVENT_STORAGE_INFO_CHANGED = 16396; // 0x400c
+    field public static final int EVENT_STORE_ADDED = 16388; // 0x4004
+    field public static final int EVENT_STORE_FULL = 16394; // 0x400a
+    field public static final int EVENT_STORE_REMOVED = 16389; // 0x4005
+    field public static final int EVENT_UNDEFINED = 16384; // 0x4000
+    field public static final int EVENT_UNREPORTED_STATUS = 16398; // 0x400e
+  }
+
+}
+
 package android.net {
 
   public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
diff --git a/api/test-current.txt b/api/test-current.txt
index d5ecfd1..a1047cb 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3424,6 +3424,7 @@
     method public void closeOptionsMenu();
     method public android.app.PendingIntent createPendingResult(int, android.content.Intent, int);
     method public final deprecated void dismissDialog(int);
+    method public final void dismissKeyboardShortcutsHelper();
     method public boolean dispatchGenericMotionEvent(android.view.MotionEvent);
     method public boolean dispatchKeyEvent(android.view.KeyEvent);
     method public boolean dispatchKeyShortcutEvent(android.view.KeyEvent);
@@ -3580,7 +3581,7 @@
     method public boolean releaseInstance();
     method public final deprecated void removeDialog(int);
     method public void reportFullyDrawn();
-    method public android.view.DropPermissions requestDropPermissions(android.view.DragEvent);
+    method public android.view.DragAndDropPermissions requestDragAndDropPermissions(android.view.DragEvent);
     method public final void requestKeyboardShortcutsHelper();
     method public final void requestPermissions(java.lang.String[], int);
     method public boolean requestVisibleBehind(boolean);
@@ -4926,6 +4927,7 @@
     field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
     field public static final java.lang.String EXTRA_CHRONOMETER_COUNTS_DOWN = "android.chronometerCountsDown";
     field public static final java.lang.String EXTRA_COMPACT_ACTIONS = "android.compactActions";
+    field public static final java.lang.String EXTRA_CONVERSATION_TITLE = "android.conversationTitle";
     field public static final java.lang.String EXTRA_INFO_TEXT = "android.infoText";
     field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
     field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
@@ -4946,7 +4948,6 @@
     field public static final java.lang.String EXTRA_TEMPLATE = "android.template";
     field public static final java.lang.String EXTRA_TEXT = "android.text";
     field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
-    field public static final java.lang.String EXTRA_THREAD_TITLE = "android.threadTitle";
     field public static final java.lang.String EXTRA_TITLE = "android.title";
     field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
     field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
@@ -5199,17 +5200,14 @@
     field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
   }
 
-  public static final class Notification.MessagingStyle.Message implements android.os.Parcelable {
+  public static final class Notification.MessagingStyle.Message {
     ctor public Notification.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
-    method public int describeContents();
     method public java.lang.String getDataMimeType();
     method public android.net.Uri getDataUri();
     method public java.lang.CharSequence getSender();
     method public java.lang.CharSequence getText();
     method public long getTimestamp();
     method public android.app.Notification.MessagingStyle.Message setData(java.lang.String, android.net.Uri);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.app.Notification.MessagingStyle.Message> CREATOR;
   }
 
   public static abstract class Notification.Style {
@@ -5244,6 +5242,7 @@
     method public int getCustomSizePreset();
     method public android.app.PendingIntent getDisplayIntent();
     method public int getGravity();
+    method public boolean getHintAmbientBigPicture();
     method public boolean getHintAvoidBackgroundClipping();
     method public boolean getHintContentIntentLaunchesActivity();
     method public boolean getHintHideIcon();
@@ -5260,6 +5259,7 @@
     method public android.app.Notification.WearableExtender setCustomSizePreset(int);
     method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent);
     method public android.app.Notification.WearableExtender setGravity(int);
+    method public android.app.Notification.WearableExtender setHintAmbientBigPicture(boolean);
     method public android.app.Notification.WearableExtender setHintAvoidBackgroundClipping(boolean);
     method public android.app.Notification.WearableExtender setHintContentIntentLaunchesActivity(boolean);
     method public android.app.Notification.WearableExtender setHintHideIcon(boolean);
@@ -23092,6 +23092,7 @@
     method public boolean isRatingBlocked(android.media.tv.TvContentRating);
     method public void registerCallback(android.media.tv.TvInputManager.TvInputCallback, android.os.Handler);
     method public void unregisterCallback(android.media.tv.TvInputManager.TvInputCallback);
+    method public void updateTvInputInfo(android.media.tv.TvInputInfo);
     field public static final java.lang.String ACTION_BLOCKED_RATINGS_CHANGED = "android.media.tv.action.BLOCKED_RATINGS_CHANGED";
     field public static final java.lang.String ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED = "android.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED";
     field public static final java.lang.String ACTION_QUERY_CONTENT_RATING_SYSTEMS = "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS";
@@ -23129,7 +23130,6 @@
     method public final android.os.IBinder onBind(android.content.Intent);
     method public android.media.tv.TvInputService.RecordingSession onCreateRecordingSession(java.lang.String);
     method public abstract android.media.tv.TvInputService.Session onCreateSession(java.lang.String);
-    method public static final void updateTvInputInfo(android.content.Context, android.media.tv.TvInputInfo);
     field public static final java.lang.String SERVICE_INTERFACE = "android.media.tv.TvInputService";
     field public static final java.lang.String SERVICE_META_DATA = "android.media.tv.input";
   }
@@ -23311,24 +23311,6 @@
     ctor public MtpConstants();
     method public static boolean isAbstractObject(int);
     field public static final int ASSOCIATION_TYPE_GENERIC_FOLDER = 1; // 0x1
-    field public static final int EVENT_CANCEL_TRANSACTION = 16385; // 0x4001
-    field public static final int EVENT_CAPTURE_COMPLETE = 16397; // 0x400d
-    field public static final int EVENT_DEVICE_INFO_CHANGED = 16392; // 0x4008
-    field public static final int EVENT_DEVICE_PROP_CHANGED = 16390; // 0x4006
-    field public static final int EVENT_DEVICE_RESET = 16395; // 0x400b
-    field public static final int EVENT_OBJECT_ADDED = 16386; // 0x4002
-    field public static final int EVENT_OBJECT_INFO_CHANGED = 16391; // 0x4007
-    field public static final int EVENT_OBJECT_PROP_CHANGED = 51201; // 0xc801
-    field public static final int EVENT_OBJECT_PROP_DESC_CHANGED = 51202; // 0xc802
-    field public static final int EVENT_OBJECT_REFERENCES_CHANGED = 51203; // 0xc803
-    field public static final int EVENT_OBJECT_REMOVED = 16387; // 0x4003
-    field public static final int EVENT_REQUEST_OBJECT_TRANSFER = 16393; // 0x4009
-    field public static final int EVENT_STORAGE_INFO_CHANGED = 16396; // 0x400c
-    field public static final int EVENT_STORE_ADDED = 16388; // 0x4004
-    field public static final int EVENT_STORE_FULL = 16394; // 0x400a
-    field public static final int EVENT_STORE_REMOVED = 16389; // 0x4005
-    field public static final int EVENT_UNDEFINED = 16384; // 0x4000
-    field public static final int EVENT_UNREPORTED_STATUS = 16398; // 0x400e
     field public static final int FORMAT_3GP_CONTAINER = 47492; // 0xb984
     field public static final int FORMAT_AAC = 47363; // 0xb903
     field public static final int FORMAT_ABSTRACT_AUDIO_ALBUM = 47619; // 0xba03
@@ -23449,7 +23431,7 @@
     method public boolean importFile(int, java.lang.String);
     method public boolean importFile(int, android.os.ParcelFileDescriptor);
     method public boolean open(android.hardware.usb.UsbDeviceConnection);
-    method public android.mtp.MtpEvent readEvent(android.os.CancellationSignal);
+    method public android.mtp.MtpEvent readEvent(android.os.CancellationSignal) throws java.io.IOException;
     method public boolean sendObject(int, long, android.os.ParcelFileDescriptor);
     method public android.mtp.MtpObjectInfo sendObjectInfo(android.mtp.MtpObjectInfo);
   }
@@ -23461,10 +23443,11 @@
     method public final int[] getOperationsSupported();
     method public final java.lang.String getSerialNumber();
     method public final java.lang.String getVersion();
+    method public boolean isEventSupported(int);
+    method public boolean isOperationSupported(int);
   }
 
   public class MtpEvent {
-    ctor public MtpEvent();
     method public int getDevicePropCode();
     method public int getEventCode();
     method public int getObjectFormatCode();
@@ -23475,6 +23458,24 @@
     method public int getParameter3();
     method public int getStorageId();
     method public int getTransactionId();
+    field public static final int EVENT_CANCEL_TRANSACTION = 16385; // 0x4001
+    field public static final int EVENT_CAPTURE_COMPLETE = 16397; // 0x400d
+    field public static final int EVENT_DEVICE_INFO_CHANGED = 16392; // 0x4008
+    field public static final int EVENT_DEVICE_PROP_CHANGED = 16390; // 0x4006
+    field public static final int EVENT_DEVICE_RESET = 16395; // 0x400b
+    field public static final int EVENT_OBJECT_ADDED = 16386; // 0x4002
+    field public static final int EVENT_OBJECT_INFO_CHANGED = 16391; // 0x4007
+    field public static final int EVENT_OBJECT_PROP_CHANGED = 51201; // 0xc801
+    field public static final int EVENT_OBJECT_PROP_DESC_CHANGED = 51202; // 0xc802
+    field public static final int EVENT_OBJECT_REFERENCES_CHANGED = 51203; // 0xc803
+    field public static final int EVENT_OBJECT_REMOVED = 16387; // 0x4003
+    field public static final int EVENT_REQUEST_OBJECT_TRANSFER = 16393; // 0x4009
+    field public static final int EVENT_STORAGE_INFO_CHANGED = 16396; // 0x400c
+    field public static final int EVENT_STORE_ADDED = 16388; // 0x4004
+    field public static final int EVENT_STORE_FULL = 16394; // 0x400a
+    field public static final int EVENT_STORE_REMOVED = 16389; // 0x4005
+    field public static final int EVENT_UNDEFINED = 16384; // 0x4000
+    field public static final int EVENT_UNREPORTED_STATUS = 16398; // 0x400e
   }
 
   public final class MtpObjectInfo {
@@ -41050,6 +41051,10 @@
     field public static final android.os.Parcelable.Creator<android.view.Display.Mode> CREATOR;
   }
 
+  public final class DragAndDropPermissions {
+    method public void release();
+  }
+
   public class DragEvent implements android.os.Parcelable {
     method public int describeContents();
     method public int getAction();
@@ -41069,10 +41074,6 @@
     field public static final android.os.Parcelable.Creator<android.view.DragEvent> CREATOR;
   }
 
-  public final class DropPermissions {
-    method public void release();
-  }
-
   public class FocusFinder {
     method public android.view.View findNearestTouchable(android.view.ViewGroup, int, int, int, int[]);
     method public final android.view.View findNextFocus(android.view.ViewGroup, android.view.View, int);
@@ -43606,7 +43607,7 @@
     ctor public Window(android.content.Context);
     method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public void addFlags(int);
-    method public final void addFrameMetricsListener(android.view.Window.FrameMetricsListener, android.os.Handler);
+    method public final void addOnFrameMetricsAvailableListener(android.view.Window.OnFrameMetricsAvailableListener, android.os.Handler);
     method public void clearFlags(int);
     method public abstract void closeAllPanels();
     method public abstract void closePanel(int);
@@ -43658,7 +43659,7 @@
     method public abstract boolean performContextMenuIdentifierAction(int, int);
     method public abstract boolean performPanelIdentifierAction(int, int, int);
     method public abstract boolean performPanelShortcut(int, int, android.view.KeyEvent, int);
-    method public final void removeFrameMetricsListener(android.view.Window.FrameMetricsListener);
+    method public final void removeOnFrameMetricsAvailableListener(android.view.Window.OnFrameMetricsAvailableListener);
     method public boolean requestFeature(int);
     method public abstract void restoreHierarchyState(android.os.Bundle);
     method public abstract android.os.Bundle saveHierarchyState();
@@ -43785,8 +43786,8 @@
     method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback, int);
   }
 
-  public static abstract interface Window.FrameMetricsListener {
-    method public abstract void onMetricsAvailable(android.view.Window, android.view.FrameMetrics, int);
+  public static abstract interface Window.OnFrameMetricsAvailableListener {
+    method public abstract void onFrameMetricsAvailable(android.view.Window, android.view.FrameMetrics, int);
   }
 
   public static abstract interface Window.OnRestrictedCaptionAreaChangedListener {
@@ -47540,7 +47541,7 @@
     method public void setChar(int, java.lang.String, char);
     method public void setCharSequence(int, java.lang.String, java.lang.CharSequence);
     method public void setChronometer(int, long, java.lang.String, boolean);
-    method public void setChronometerCountsDown(int, boolean);
+    method public void setChronometerCountDown(int, boolean);
     method public void setContentDescription(int, java.lang.CharSequence);
     method public void setDisplayedChild(int, int);
     method public void setDouble(int, java.lang.String, double);
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 8c6abdc..de8a724 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -165,6 +165,31 @@
 
 }
 
+package android.mtp {
+
+  public final class MtpConstants {
+    field public static final int EVENT_CANCEL_TRANSACTION = 16385; // 0x4001
+    field public static final int EVENT_CAPTURE_COMPLETE = 16397; // 0x400d
+    field public static final int EVENT_DEVICE_INFO_CHANGED = 16392; // 0x4008
+    field public static final int EVENT_DEVICE_PROP_CHANGED = 16390; // 0x4006
+    field public static final int EVENT_DEVICE_RESET = 16395; // 0x400b
+    field public static final int EVENT_OBJECT_ADDED = 16386; // 0x4002
+    field public static final int EVENT_OBJECT_INFO_CHANGED = 16391; // 0x4007
+    field public static final int EVENT_OBJECT_PROP_CHANGED = 51201; // 0xc801
+    field public static final int EVENT_OBJECT_PROP_DESC_CHANGED = 51202; // 0xc802
+    field public static final int EVENT_OBJECT_REFERENCES_CHANGED = 51203; // 0xc803
+    field public static final int EVENT_OBJECT_REMOVED = 16387; // 0x4003
+    field public static final int EVENT_REQUEST_OBJECT_TRANSFER = 16393; // 0x4009
+    field public static final int EVENT_STORAGE_INFO_CHANGED = 16396; // 0x400c
+    field public static final int EVENT_STORE_ADDED = 16388; // 0x4004
+    field public static final int EVENT_STORE_FULL = 16394; // 0x400a
+    field public static final int EVENT_STORE_REMOVED = 16389; // 0x4005
+    field public static final int EVENT_UNDEFINED = 16384; // 0x4000
+    field public static final int EVENT_UNREPORTED_STATUS = 16398; // 0x400e
+  }
+
+}
+
 package android.net {
 
   public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 9bd648f..0149952 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -85,8 +85,8 @@
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
 import android.view.ContextThemeWrapper;
+import android.view.DragAndDropPermissions;
 import android.view.DragEvent;
-import android.view.DropPermissions;
 import android.view.InputDevice;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
@@ -721,6 +721,10 @@
 
     private static final String REQUEST_PERMISSIONS_WHO_PREFIX = "@android:requestPermissions:";
 
+    private static final String KEYBOARD_SHORTCUTS_RECEIVER_PKG_NAME = "com.android.systemui";
+    private static final String KEYBOARD_SHORTCUTS_RECEIVER_CLASS_NAME =
+            "com.android.systemui.statusbar.KeyboardShortcutsReceiver";
+
     private static class ManagedDialog {
         Dialog mDialog;
         Bundle mArgs;
@@ -1682,8 +1686,18 @@
      */
     public final void requestKeyboardShortcutsHelper() {
         Intent intent = new Intent(Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS);
-        intent.setComponent(new ComponentName("com.android.systemui",
-                "com.android.systemui.statusbar.KeyboardShortcutsReceiver"));
+        intent.setComponent(new ComponentName(KEYBOARD_SHORTCUTS_RECEIVER_PKG_NAME,
+                KEYBOARD_SHORTCUTS_RECEIVER_CLASS_NAME));
+        sendBroadcast(intent);
+    }
+
+    /**
+     * Dismiss the Keyboard Shortcuts screen.
+     */
+    public final void dismissKeyboardShortcutsHelper() {
+        Intent intent = new Intent(Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS);
+        intent.setComponent(new ComponentName(KEYBOARD_SHORTCUTS_RECEIVER_PKG_NAME,
+                KEYBOARD_SHORTCUTS_RECEIVER_CLASS_NAME));
         sendBroadcast(intent);
     }
 
@@ -1693,11 +1707,6 @@
         if (menu == null) {
           return;
         }
-        final InputDevice inputDevice = InputManager.getInstance().getInputDevice(deviceId);
-        if (inputDevice == null) {
-            return;
-        }
-        final KeyCharacterMap keyCharacterMap = inputDevice.getKeyCharacterMap();
         KeyboardShortcutGroup group = null;
         int menuSize = menu.size();
         for (int i = 0; i < menuSize; ++i) {
@@ -6505,16 +6514,16 @@
     }
 
     /**
-     * Create {@link DropPermissions} object bound to this activity and controlling the access
-     * permissions for content URIs associated with the {@link DragEvent}.
+     * Create {@link DragAndDropPermissions} object bound to this activity and controlling the
+     * access permissions for content URIs associated with the {@link DragEvent}.
      * @param event Drag event
-     * @return The DropPermissions object used to control access to the content URIs. Null if
-     * no content URIs are associated with the event or if permissions could not be granted.
+     * @return The {@link DragAndDropPermissions} object used to control access to the content URIs.
+     * Null if no content URIs are associated with the event or if permissions could not be granted.
      */
-    public DropPermissions requestDropPermissions(DragEvent event) {
-        DropPermissions dropPermissions = DropPermissions.obtain(event);
-        if (dropPermissions != null && dropPermissions.take(getActivityToken())) {
-            return dropPermissions;
+    public DragAndDropPermissions requestDragAndDropPermissions(DragEvent event) {
+        DragAndDropPermissions dragAndDropPermissions = DragAndDropPermissions.obtain(event);
+        if (dragAndDropPermissions != null && dragAndDropPermissions.take(getActivityToken())) {
+            return dragAndDropPermissions;
         }
         return null;
     }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index f4e5ddf..7edc6b7 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -31,7 +31,6 @@
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 
-import android.util.Log;
 import com.android.internal.app.procstats.ProcessStats;
 import com.android.internal.os.TransferPipe;
 import com.android.internal.util.FastPrintWriter;
@@ -63,7 +62,6 @@
 import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.Size;
-import android.util.Slog;
 
 import org.xmlpull.v1.XmlSerializer;
 
@@ -2368,8 +2366,10 @@
         public String[] taskNames;
         public Rect[] taskBounds;
         public int[] taskUserIds;
+        public ComponentName topActivity;
         public int displayId;
         public int userId;
+        public boolean visible;
 
         @Override
         public int describeContents() {
@@ -2396,6 +2396,13 @@
             dest.writeIntArray(taskUserIds);
             dest.writeInt(displayId);
             dest.writeInt(userId);
+            dest.writeInt(visible ? 1 : 0);
+            if (topActivity != null) {
+                dest.writeInt(1);
+                topActivity.writeToParcel(dest, 0);
+            } else {
+                dest.writeInt(0);
+            }
         }
 
         public void readFromParcel(Parcel source) {
@@ -2418,6 +2425,10 @@
             taskUserIds = source.createIntArray();
             displayId = source.readInt();
             userId = source.readInt();
+            visible = source.readInt() > 0;
+            if (source.readInt() > 0) {
+                topActivity = ComponentName.readFromParcel(source);
+            }
         }
 
         public static final Creator<StackInfo> CREATOR = new Creator<StackInfo>() {
@@ -2453,6 +2464,10 @@
                             sb.append(" bounds="); sb.append(taskBounds[i].toShortString());
                         }
                         sb.append(" userId=").append(taskUserIds[i]);
+                        sb.append(" visible=").append(visible);
+                        if (topActivity != null) {
+                            sb.append(" topActivity=").append(topActivity);
+                        }
                         sb.append("\n");
             }
             return sb.toString();
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index e4fff9d..02dcc5c 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -33,7 +33,6 @@
 import libcore.util.ZoneInfoDB;
 
 import java.io.IOException;
-import java.lang.ref.WeakReference;
 import java.util.WeakHashMap;
 
 /**
@@ -245,12 +244,7 @@
 
     // Tracking of the OnAlarmListener -> wrapper mapping, for cancel() support.
     // Access is synchronized on the AlarmManager class object.
-    //
-    // These are weak references so that we don't leak listener references if, for
-    // example, the pending-alarm messages are posted to a HandlerThread that is
-    // disposed of prior to alarm delivery.  The underlying messages will be GC'd
-    // but this static reference would still persist, orphaned, never deallocated.
-    private static WeakHashMap<OnAlarmListener, WeakReference<ListenerWrapper>> sWrappers;
+    private static WeakHashMap<OnAlarmListener, ListenerWrapper> sWrappers;
 
     /**
      * package private on purpose
@@ -637,16 +631,14 @@
         if (listener != null) {
             synchronized (AlarmManager.class) {
                 if (sWrappers == null) {
-                    sWrappers = new WeakHashMap<OnAlarmListener, WeakReference<ListenerWrapper>>();
+                    sWrappers = new WeakHashMap<OnAlarmListener, ListenerWrapper>();
                 }
 
-                WeakReference<ListenerWrapper> wrapperRef = sWrappers.get(listener);
-                // no existing wrapper *or* we've lost our weak ref to it => build a new one
-                if (wrapperRef == null ||
-                        (recipientWrapper = wrapperRef.get()) == null) {
+                recipientWrapper = sWrappers.get(listener);
+                // no existing wrapper => build a new one
+                if (recipientWrapper == null) {
                     recipientWrapper = new ListenerWrapper(listener);
-                    wrapperRef = new WeakReference<ListenerWrapper>(recipientWrapper);
-                    sWrappers.put(listener, wrapperRef);
+                    sWrappers.put(listener, recipientWrapper);
                 }
             }
 
@@ -906,11 +898,7 @@
         ListenerWrapper wrapper = null;
         synchronized (AlarmManager.class) {
             if (sWrappers != null) {
-                final WeakReference<ListenerWrapper> wrapperRef;
-                wrapperRef = sWrappers.get(listener);
-                if (wrapperRef != null) {
-                    wrapper = wrapperRef.get();
-                }
+                wrapper = sWrappers.get(listener);
             }
         }
 
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index a221c98..f4fe1eb 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.animation.Animator;
+import android.annotation.CallSuper;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StringRes;
@@ -1335,6 +1336,7 @@
      * @deprecated Use {@link #onInflate(Context, AttributeSet, Bundle)} instead.
      */
     @Deprecated
+    @CallSuper
     public void onInflate(AttributeSet attrs, Bundle savedInstanceState) {
         mCalled = true;
     }
@@ -1381,6 +1383,7 @@
      * @param savedInstanceState If the fragment is being re-created from
      * a previous saved state, this is the state.
      */
+    @CallSuper
     public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState) {
         onInflate(attrs, savedInstanceState);
         mCalled = true;
@@ -1421,6 +1424,7 @@
      * @deprecated Use {@link #onInflate(Context, AttributeSet, Bundle)} instead.
      */
     @Deprecated
+    @CallSuper
     public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
         mCalled = true;
     }
@@ -1429,6 +1433,7 @@
      * Called when a fragment is first attached to its context.
      * {@link #onCreate(Bundle)} will be called after this.
      */
+    @CallSuper
     public void onAttach(Context context) {
         mCalled = true;
         final Activity hostActivity = mHost == null ? null : mHost.getActivity();
@@ -1442,6 +1447,7 @@
      * @deprecated Use {@link #onAttach(Context)} instead.
      */
     @Deprecated
+    @CallSuper
     public void onAttach(Activity activity) {
         mCalled = true;
     }
@@ -1473,6 +1479,7 @@
      * @param savedInstanceState If the fragment is being re-created from
      * a previous saved state, this is the state.
      */
+    @CallSuper
     public void onCreate(@Nullable Bundle savedInstanceState) {
         mCalled = true;
         final Context context = getContext();
@@ -1558,6 +1565,7 @@
      * @param savedInstanceState If the fragment is being re-created from
      * a previous saved state, this is the state.
      */
+    @CallSuper
     public void onActivityCreated(@Nullable Bundle savedInstanceState) {
         mCalled = true;
     }
@@ -1573,6 +1581,7 @@
      * @param savedInstanceState If the fragment is being re-created from
      * a previous saved state, this is the state.
      */
+    @CallSuper
     public void onViewStateRestored(Bundle savedInstanceState) {
         mCalled = true;
     }
@@ -1582,6 +1591,7 @@
      * tied to {@link Activity#onStart() Activity.onStart} of the containing
      * Activity's lifecycle.
      */
+    @CallSuper
     public void onStart() {
         mCalled = true;
 
@@ -1603,6 +1613,7 @@
      * tied to {@link Activity#onResume() Activity.onResume} of the containing
      * Activity's lifecycle.
      */
+    @CallSuper
     public void onResume() {
         mCalled = true;
     }
@@ -1648,6 +1659,7 @@
     public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
     }
 
+    @CallSuper
     public void onConfigurationChanged(Configuration newConfig) {
         mCalled = true;
     }
@@ -1657,6 +1669,7 @@
      * tied to {@link Activity#onPause() Activity.onPause} of the containing
      * Activity's lifecycle.
      */
+    @CallSuper
     public void onPause() {
         mCalled = true;
     }
@@ -1666,14 +1679,17 @@
      * tied to {@link Activity#onStop() Activity.onStop} of the containing
      * Activity's lifecycle.
      */
+    @CallSuper
     public void onStop() {
         mCalled = true;
     }
 
+    @CallSuper
     public void onLowMemory() {
         mCalled = true;
     }
 
+    @CallSuper
     public void onTrimMemory(int level) {
         mCalled = true;
     }
@@ -1687,6 +1703,7 @@
      * non-null view.  Internally it is called after the view's state has
      * been saved but before it has been removed from its parent.
      */
+    @CallSuper
     public void onDestroyView() {
         mCalled = true;
     }
@@ -1695,6 +1712,7 @@
      * Called when the fragment is no longer in use.  This is called
      * after {@link #onStop()} and before {@link #onDetach()}.
      */
+    @CallSuper
     public void onDestroy() {
         mCalled = true;
         //Log.v("foo", "onDestroy: mCheckedForLoaderManager=" + mCheckedForLoaderManager
@@ -1743,20 +1761,9 @@
      * Activity re-creation (see {@link #setRetainInstance(boolean)}), in which case it is called
      * after {@link #onStop()}.
      */
+    @CallSuper
     public void onDetach() {
         mCalled = true;
-
-        // Destroy the child FragmentManager if we still have it here.
-        // We won't unless we're retaining our instance and if we do,
-        // our child FragmentManager instance state will have already been saved.
-        if (mChildFragmentManager != null) {
-            if (!mRetaining) {
-                throw new IllegalStateException("Child FragmentManager of " + this + " was not "
-                        + " destroyed and this fragment is not retaining instance");
-            }
-            mChildFragmentManager.dispatchDestroy();
-            mChildFragmentManager = null;
-        }
     }
 
     /**
@@ -2568,6 +2575,27 @@
         mChildFragmentManager = null;
     }
 
+    void performDetach() {
+        mCalled = false;
+        onDetach();
+        if (!mCalled) {
+            throw new SuperNotCalledException("Fragment " + this
+                    + " did not call through to super.onDetach()");
+        }
+
+        // Destroy the child FragmentManager if we still have it here.
+        // We won't unless we're retaining our instance and if we do,
+        // our child FragmentManager instance state will have already been saved.
+        if (mChildFragmentManager != null) {
+            if (!mRetaining) {
+                throw new IllegalStateException("Child FragmentManager of " + this + " was not "
+                        + " destroyed and this fragment is not retaining instance");
+            }
+            mChildFragmentManager.dispatchDestroy();
+            mChildFragmentManager = null;
+        }
+    }
+
     private static Transition loadTransition(Context context, TypedArray typedArray,
             Transition currentValue, Transition defaultValue, int id) {
         if (currentValue != defaultValue) {
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index b1dda7f..d795385 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1117,12 +1117,7 @@
                                 f.mState = Fragment.INITIALIZING;
                             }
 
-                            f.mCalled = false;
-                            f.onDetach();
-                            if (!f.mCalled) {
-                                throw new SuperNotCalledException("Fragment " + f
-                                        + " did not call through to super.onDetach()");
-                            }
+                            f.performDetach();
                             if (!keepActive) {
                                 if (!f.mRetaining) {
                                     makeInactive(f);
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 849636f..0cfa009 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -432,7 +432,8 @@
         if (!Objects.equals(mPackageName, ActivityThread.currentPackageName())) {
             VMRuntime.getRuntime().vmInstructionSet();
             try {
-                ActivityThread.getPackageManager().notifyPackageUse(mPackageName);
+                ActivityThread.getPackageManager().notifyPackageUse(mPackageName,
+                        PackageManager.NOTIFY_PACKAGE_USE_CROSS_PACKAGE);
             } catch (RemoteException re) {
                 throw re.rethrowFromSystemServer();
             }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 400a313..43c6ca5 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -25,7 +25,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.ColorStateList;
@@ -186,6 +185,11 @@
     public long when;
 
     /**
+     * The creation time of the notification
+     */
+    private long creationTime;
+
+    /**
      * The resource id of a drawable to use as the icon in the status bar.
      *
      * @deprecated Use {@link Builder#setSmallIcon(Icon)} instead.
@@ -943,10 +947,10 @@
     public static final String EXTRA_ALLOW_GENERATED_REPLIES = "android.allowGeneratedReplies";
 
     /**
-     * {@link #extras} key: a {@link String} to be displayed as the title to a thread represented by
-     * a {@link android.app.Notification.MessagingStyle}
+     * {@link #extras} key: a {@link String} to be displayed as the title to a conversation
+     * represented by a {@link android.app.Notification.MessagingStyle}
      */
-    public static final String EXTRA_THREAD_TITLE = "android.threadTitle";
+    public static final String EXTRA_CONVERSATION_TITLE = "android.conversationTitle";
 
     /**
      * {@link #extras} key: an array of {@link android.app.Notification.MessagingStyle.Message}
@@ -1480,6 +1484,7 @@
     public Notification()
     {
         this.when = System.currentTimeMillis();
+        this.creationTime = System.currentTimeMillis();
         this.priority = PRIORITY_DEFAULT;
     }
 
@@ -1517,6 +1522,7 @@
         this.icon = icon;
         this.tickerText = tickerText;
         this.when = when;
+        this.creationTime = System.currentTimeMillis();
     }
 
     /**
@@ -1527,6 +1533,7 @@
         int version = parcel.readInt();
 
         when = parcel.readLong();
+        creationTime = parcel.readLong();
         if (parcel.readInt() != 0) {
             mSmallIcon = Icon.CREATOR.createFromParcel(parcel);
             if (mSmallIcon.getType() == Icon.TYPE_RESOURCE) {
@@ -1615,6 +1622,7 @@
      */
     public void cloneInto(Notification that, boolean heavy) {
         that.when = this.when;
+        that.creationTime = this.creationTime;
         that.mSmallIcon = this.mSmallIcon;
         that.number = this.number;
 
@@ -1795,6 +1803,7 @@
         parcel.writeInt(1);
 
         parcel.writeLong(when);
+        parcel.writeLong(creationTime);
         if (mSmallIcon == null && icon != 0) {
             // you snuck an icon in here without using the builder; let's try to keep it
             mSmallIcon = Icon.createWithResource("", icon);
@@ -3130,6 +3139,7 @@
             contentView.setViewVisibility(R.id.header_text, View.GONE);
             contentView.setViewVisibility(R.id.header_text_divider, View.GONE);
             contentView.setViewVisibility(R.id.time_divider, View.GONE);
+            contentView.setViewVisibility(R.id.time, View.GONE);
             contentView.setImageViewIcon(R.id.profile_badge, null);
             contentView.setViewVisibility(R.id.profile_badge, View.GONE);
         }
@@ -3260,11 +3270,15 @@
                             mN.when + (SystemClock.elapsedRealtime() - System.currentTimeMillis()));
                     contentView.setBoolean(R.id.chronometer, "setStarted", true);
                     boolean countsDown = mN.extras.getBoolean(EXTRA_CHRONOMETER_COUNTS_DOWN);
-                    contentView.setChronometerCountsDown(R.id.chronometer, countsDown);
+                    contentView.setChronometerCountDown(R.id.chronometer, countsDown);
                 } else {
                     contentView.setViewVisibility(R.id.time, View.VISIBLE);
                     contentView.setLong(R.id.time, "setTime", mN.when);
                 }
+            } else {
+                // We still want a time to be set but gone, such that we can show and hide it
+                // on demand in case it's a child notification without anything in the header
+                contentView.setLong(R.id.time, "setTime", mN.when != 0 ? mN.when : mN.creationTime);
             }
         }
 
@@ -3332,7 +3346,7 @@
          *         otherwise
          */
         private boolean showsTimeOrChronometer() {
-            return mN.when != 0 && mN.extras.getBoolean(EXTRA_SHOW_WHEN);
+            return mN.showsTimeOrChronometer();
         }
 
         private void resetStandardTemplateWithActions(RemoteViews big) {
@@ -3694,6 +3708,8 @@
                 mN.extras = getAllExtras();
             }
 
+            mN.creationTime = System.currentTimeMillis();
+
             // lazy stuff from mContext; see comment in Builder(Context, Notification)
             Notification.addFieldsFromContext(mContext, mN);
 
@@ -3827,6 +3843,15 @@
     }
 
     /**
+     * @return true if the notification will show the time or the chronometer; false
+     *         otherwise
+     * @hide
+     */
+    public boolean showsTimeOrChronometer() {
+        return when != 0 && extras.getBoolean(EXTRA_SHOW_WHEN);
+    }
+
+    /**
      * An object that can apply a rich notification style to a {@link Notification.Builder}
      * object.
      */
@@ -4301,7 +4326,7 @@
         CharSequence mUserDisplayName;
         CharSequence mConversationTitle;
         boolean mAllowGeneratedReplies = true;
-        ArrayList<Message> mMessages = new ArrayList<>();
+        List<Message> mMessages = new ArrayList<>();
 
         MessagingStyle() {
         }
@@ -4414,11 +4439,11 @@
                 extras.putCharSequence(EXTRA_SELF_DISPLAY_NAME, mUserDisplayName);
             }
             if (mConversationTitle != null) {
-                extras.putCharSequence(EXTRA_THREAD_TITLE, mConversationTitle);
+                extras.putCharSequence(EXTRA_CONVERSATION_TITLE, mConversationTitle);
             }
             extras.putBoolean(EXTRA_ALLOW_GENERATED_REPLIES, mAllowGeneratedReplies);
-            if (!mMessages.isEmpty()) {
-                extras.putParcelableArrayList(EXTRA_MESSAGES, mMessages);
+            if (!mMessages.isEmpty()) { extras.putParcelableArray(EXTRA_MESSAGES,
+                    Message.getBundleArrayForMessages(mMessages));
             }
         }
 
@@ -4431,12 +4456,12 @@
 
             mMessages.clear();
             mUserDisplayName = extras.getString(EXTRA_SELF_DISPLAY_NAME);
-            mConversationTitle = extras.getString(EXTRA_THREAD_TITLE);
+            mConversationTitle = extras.getString(EXTRA_CONVERSATION_TITLE);
             mAllowGeneratedReplies = extras.getBoolean(EXTRA_ALLOW_GENERATED_REPLIES,
                     mAllowGeneratedReplies);
-            List<Message> messages = extras.getParcelableArrayList(EXTRA_MESSAGES);
-            if (messages != null) {
-                mMessages.addAll(messages);
+            Parcelable[] parcelables = extras.getParcelableArray(EXTRA_MESSAGES);
+            if (parcelables != null && parcelables instanceof Bundle[]) {
+                mMessages = Message.getMessagesFromBundleArray((Bundle[]) parcelables);
             }
         }
 
@@ -4537,7 +4562,13 @@
                     ColorStateList.valueOf(color), null);
         }
 
-        public static final class Message implements Parcelable {
+        public static final class Message {
+
+            static final String KEY_TEXT = "text";
+            static final String KEY_TIMESTAMP = "time";
+            static final String KEY_SENDER = "sender";
+            static final String KEY_DATA_MIME_TYPE = "type";
+            static final String KEY_DATA_URI= "uri";
 
             private final CharSequence mText;
             private final long mTimestamp;
@@ -4595,26 +4626,6 @@
                 return this;
             }
 
-            private Message(Parcel in) {
-                if (in.readInt() != 0) {
-                    mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
-                } else {
-                    mText = null;
-                }
-                mTimestamp = in.readLong();
-                if (in.readInt() != 0) {
-                    mSender = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
-                } else {
-                    mSender = null;
-                }
-                if (in.readInt() != 0) {
-                    mDataMimeType = in.readString();
-                }
-                if (in.readInt() != 0) {
-                    mDataUri = in.readParcelable(Uri.class.getClassLoader());
-                }
-            }
-
             /**
              * Get the text to be used for this message, or the fallback text if a type and content
              * Uri have been set
@@ -4652,49 +4663,64 @@
                 return mDataUri;
             }
 
-            @Override
-            public int describeContents() {
-                return 0;
-            }
-
-            @Override
-            public void writeToParcel(Parcel out, int flags) {
+            private Bundle toBundle() {
+                Bundle bundle = new Bundle();
                 if (mText != null) {
-                    out.writeInt(1);
-                    TextUtils.writeToParcel(mText, out, flags);
-                } else {
-                    out.writeInt(0);
+                    bundle.putCharSequence(KEY_TEXT, mText);
                 }
-                out.writeLong(mTimestamp);
+                bundle.putLong(KEY_TIMESTAMP, mTimestamp);
                 if (mSender != null) {
-                    out.writeInt(1);
-                    TextUtils.writeToParcel(mSender, out, flags);
-                } else {
-                    out.writeInt(0);
+                    bundle.putCharSequence(KEY_SENDER, mSender);
                 }
                 if (mDataMimeType != null) {
-                    out.writeInt(1);
-                    out.writeString(mDataMimeType);
-                } else {
-                    out.writeInt(0);
+                    bundle.putString(KEY_DATA_MIME_TYPE, mDataMimeType);
                 }
                 if (mDataUri != null) {
-                    out.writeInt(1);
-                    out.writeParcelable(mDataUri, flags);
-                } else {
-                    out.writeInt(0);
+                    bundle.putParcelable(KEY_DATA_URI, mDataUri);
                 }
+                return bundle;
             }
 
-            public static final Parcelable.Creator<Message> CREATOR =
-                    new Parcelable.Creator<Message>() {
-                        public Message createFromParcel(Parcel in) {
-                            return new Message(in);
+            static Bundle[] getBundleArrayForMessages(List<Message> messages) {
+                Bundle[] bundles = new Bundle[messages.size()];
+                final int N = messages.size();
+                for (int i = 0; i < N; i++) {
+                    bundles[i] = messages.get(i).toBundle();
+                }
+                return bundles;
+            }
+
+            static List<Message> getMessagesFromBundleArray(Bundle[] bundles) {
+                List<Message> messages = new ArrayList<>(bundles.length);
+                for (int i = 0; i < bundles.length; i++) {
+                    Message message = getMessageFromBundle(bundles[i]);
+                    if (message != null) {
+                        messages.add(message);
+                    }
+                }
+                return messages;
+            }
+
+            static Message getMessageFromBundle(Bundle bundle) {
+                try {
+                    if (!bundle.containsKey(KEY_TEXT) || !bundle.containsKey(KEY_TIMESTAMP) ||
+                            !bundle.containsKey(KEY_SENDER)) {
+                        return null;
+                    } else {
+                        Message message = new Message(bundle.getCharSequence(KEY_TEXT),
+                                bundle.getLong(KEY_TIMESTAMP), bundle.getCharSequence(KEY_SENDER));
+                        if (bundle.containsKey(KEY_DATA_MIME_TYPE) &&
+                                bundle.containsKey(KEY_DATA_URI)) {
+
+                            message.setData(bundle.getString(KEY_DATA_MIME_TYPE),
+                                    (Uri) bundle.getParcelable(KEY_DATA_URI));
                         }
-                        public Message[] newArray(int size) {
-                            return new Message[size];
-                        }
-                    };
+                        return message;
+                    }
+                } catch (ClassCastException e) {
+                    return null;
+                }
+            }
         }
     }
 
@@ -5436,6 +5462,7 @@
         private static final int FLAG_HINT_SHOW_BACKGROUND_ONLY = 1 << 2;
         private static final int FLAG_START_SCROLL_BOTTOM = 1 << 3;
         private static final int FLAG_HINT_AVOID_BACKGROUND_CLIPPING = 1 << 4;
+        private static final int FLAG_BIG_PICTURE_AMBIENT = 1 << 5;
         private static final int FLAG_HINT_CONTENT_INTENT_LAUNCHES_ACTIVITY = 1 << 6;
 
         // Default value for flags integer
@@ -6004,6 +6031,29 @@
         }
 
         /**
+         * Set a hint that this notification's {@link BigPictureStyle} (if present) should be
+         * converted to low-bit and displayed in ambient mode, especially useful for barcodes and
+         * qr codes, as well as other simple black-and-white tickets.
+         * @param hintAmbientBigPicture {@code true} to enable converstion and ambient.
+         * @return this object for method chaining
+         */
+        public WearableExtender setHintAmbientBigPicture(boolean hintAmbientBigPicture) {
+            setFlag(FLAG_BIG_PICTURE_AMBIENT, hintAmbientBigPicture);
+            return this;
+        }
+
+        /**
+         * Get a hint that this notification's {@link BigPictureStyle} (if present) should be
+         * converted to low-bit and displayed in ambient mode, especially useful for barcodes and
+         * qr codes, as well as other simple black-and-white tickets.
+         * @return {@code true} if it should be displayed in ambient, false otherwise
+         * otherwise. The default value is {@code false} if this was never set.
+         */
+        public boolean getHintAmbientBigPicture() {
+            return (mFlags & FLAG_BIG_PICTURE_AMBIENT) != 0;
+        }
+
+        /**
          * Set a hint that this notification's content intent will launch an {@link Activity}
          * directly, telling the platform that it can generate the appropriate transitions.
          * @param hintContentIntentLaunchesActivity {@code true} if the content intent will launch
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 996ccba..8d29dac 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1427,6 +1427,16 @@
             "android.intent.action.SHOW_KEYBOARD_SHORTCUTS";
 
     /**
+     * Activity Action: Dismiss the Keyboard Shortcuts Helper screen.
+     * <p>Input: Nothing.
+     * <p>Output: Nothing.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_DISMISS_KEYBOARD_SHORTCUTS =
+            "android.intent.action.DISMISS_KEYBOARD_SHORTCUTS";
+
+    /**
      * Activity Action: Show settings for managing network data usage of a
      * specific application. Applications should define an activity that offers
      * options to control data usage.
@@ -3078,10 +3088,6 @@
     public static final String ACTION_MANAGED_PROFILE_UNLOCKED =
             "android.intent.action.MANAGED_PROFILE_UNLOCKED";
 
-    /** @hide */
-    public static final String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED =
-            "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED";
-
     /**
      * Broadcast sent to the primary user when an associated managed profile has become available.
      * Currently this includes when the user disables quiet mode for the profile. Carries an extra
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 0526815..0e0be20 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -451,9 +451,11 @@
     void updatePackagesIfNeeded();
 
     /**
-     * Notify the package manager that a package is going to be used.
+     * Notify the package manager that a package is going to be used and why.
+     *
+     * See PackageManager.NOTIFY_PACKAGE_USE_* for reasons.
      */
-    void notifyPackageUse(String packageName);
+    void notifyPackageUse(String packageName, int reason);
 
     /**
      * Ask the package manager to perform dex-opt (if needed) on the given
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 496bae4..3d2ab95 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2456,6 +2456,69 @@
     public static final String SYSTEM_SHARED_LIBRARY_SHARED = "android.ext.shared";
 
     /**
+     * Used when starting a process for an Activity.
+     *
+     * @hide
+     */
+    public static final int NOTIFY_PACKAGE_USE_ACTIVITY = 0;
+
+    /**
+     * Used when starting a process for a Service.
+     *
+     * @hide
+     */
+    public static final int NOTIFY_PACKAGE_USE_SERVICE = 1;
+
+    /**
+     * Used when moving a Service to the foreground.
+     *
+     * @hide
+     */
+    public static final int NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE = 2;
+
+    /**
+     * Used when starting a process for a BroadcastReceiver.
+     *
+     * @hide
+     */
+    public static final int NOTIFY_PACKAGE_USE_BROADCAST_RECEIVER = 3;
+
+    /**
+     * Used when starting a process for a ContentProvider.
+     *
+     * @hide
+     */
+    public static final int NOTIFY_PACKAGE_USE_CONTENT_PROVIDER = 4;
+
+    /**
+     * Used when starting a process for a BroadcastReceiver.
+     *
+     * @hide
+     */
+    public static final int NOTIFY_PACKAGE_USE_BACKUP = 5;
+
+    /**
+     * Used with Context.getClassLoader() across Android packages.
+     *
+     * @hide
+     */
+    public static final int NOTIFY_PACKAGE_USE_CROSS_PACKAGE = 6;
+
+    /**
+     * Used when starting a package within a process for Instrumentation.
+     *
+     * @hide
+     */
+    public static final int NOTIFY_PACKAGE_USE_INSTRUMENTATION = 7;
+
+    /**
+     * Total number of usage reasons.
+     *
+     * @hide
+     */
+    public static final int NOTIFY_PACKAGE_USE_REASONS_COUNT = 8;
+
+    /**
      * Retrieve overall information about an application package that is
      * installed on the system.
      *
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index bb8bca4..4613800 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -4756,7 +4756,8 @@
         public int mPreferredOrder = 0;
 
         // For use by package manager to keep track of when a package was last used.
-        public long mLastPackageUsageTimeInMills;
+        public long[] mLastPackageUsageTimeInMills =
+                new long[PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT];
 
         // // User set enabled state.
         // public int mSetEnabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
@@ -5086,6 +5087,14 @@
             return true;
         }
 
+        public long getLatestPackageUseTimeInMills() {
+            long latestUse = 0L;
+            for (long use : mLastPackageUsageTimeInMills) {
+                latestUse = Math.max(latestUse, use);
+            }
+            return latestUse;
+        }
+
         public String toString() {
             return "Package{"
                 + Integer.toHexString(System.identityHashCode(this))
diff --git a/core/java/android/net/metrics/CaptivePortalCheckResultEvent.java b/core/java/android/net/metrics/CaptivePortalCheckResultEvent.java
deleted file mode 100644
index 02ab63e..0000000
--- a/core/java/android/net/metrics/CaptivePortalCheckResultEvent.java
+++ /dev/null
@@ -1,64 +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 android.net.metrics;
-
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * {@hide}
- */
-@SystemApi
-public final class CaptivePortalCheckResultEvent extends IpConnectivityEvent implements Parcelable {
-    public final int netId;
-    public final int result;
-
-    private CaptivePortalCheckResultEvent(int netId, int result) {
-        this.netId = netId;
-        this.result = result;
-    }
-
-    private CaptivePortalCheckResultEvent(Parcel in) {
-        this.netId = in.readInt();
-        this.result = in.readInt();
-    }
-
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(netId);
-        out.writeInt(result);
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<CaptivePortalCheckResultEvent> CREATOR
-        = new Parcelable.Creator<CaptivePortalCheckResultEvent>() {
-            public CaptivePortalCheckResultEvent createFromParcel(Parcel in) {
-                return new CaptivePortalCheckResultEvent(in);
-            }
-
-            public CaptivePortalCheckResultEvent[] newArray(int size) {
-                return new CaptivePortalCheckResultEvent[size];
-            }
-        };
-
-    public static void logEvent(int netId, int result) {
-        logEvent(IPCE_NETMON_CHECK_RESULT, new CaptivePortalCheckResultEvent(netId, result));
-    }
-};
diff --git a/core/java/android/net/metrics/CaptivePortalStateChangeEvent.java b/core/java/android/net/metrics/CaptivePortalStateChangeEvent.java
deleted file mode 100644
index a67589a..0000000
--- a/core/java/android/net/metrics/CaptivePortalStateChangeEvent.java
+++ /dev/null
@@ -1,68 +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 android.net.metrics;
-
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * {@hide}
- */
-@SystemApi
-public final class CaptivePortalStateChangeEvent extends IpConnectivityEvent implements Parcelable {
-    public static final int NETWORK_MONITOR_CONNECTED    = 0;
-    public static final int NETWORK_MONITOR_DISCONNECTED = 1;
-    public static final int NETWORK_MONITOR_VALIDATED    = 2;
-
-    public final int netId;
-    public final int state;
-
-    public CaptivePortalStateChangeEvent(int netId, int state) {
-        this.netId = netId;
-        this.state = state;
-    }
-
-    public CaptivePortalStateChangeEvent(Parcel in) {
-        netId = in.readInt();
-        state = in.readInt();
-    }
-
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(netId);
-        out.writeInt(state);
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<CaptivePortalStateChangeEvent> CREATOR
-        = new Parcelable.Creator<CaptivePortalStateChangeEvent>() {
-        public CaptivePortalStateChangeEvent createFromParcel(Parcel in) {
-            return new CaptivePortalStateChangeEvent(in);
-        }
-
-        public CaptivePortalStateChangeEvent[] newArray(int size) {
-            return new CaptivePortalStateChangeEvent[size];
-        }
-    };
-
-    public static void logEvent(int netId, int state) {
-        logEvent(IPCE_NETMON_STATE_CHANGE, new CaptivePortalStateChangeEvent(netId, state));
-    }
-};
diff --git a/core/java/android/net/metrics/NetworkEvent.java b/core/java/android/net/metrics/NetworkEvent.java
new file mode 100644
index 0000000..b15dcee
--- /dev/null
+++ b/core/java/android/net/metrics/NetworkEvent.java
@@ -0,0 +1,86 @@
+/*
+ * 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 android.net.metrics;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * {@hide}
+ */
+@SystemApi
+public final class NetworkEvent extends IpConnectivityEvent implements Parcelable {
+
+    public static final int NETWORK_CONNECTED            = 1;
+    public static final int NETWORK_VALIDATED            = 2;
+    public static final int NETWORK_VALIDATION_FAILED    = 3;
+    public static final int NETWORK_CAPTIVE_PORTAL_FOUND = 4;
+    public static final int NETWORK_LINGER               = 5;
+    public static final int NETWORK_UNLINGER             = 6;
+    public static final int NETWORK_DISCONNECTED         = 7;
+
+    public final int netId;
+    public final int eventType;
+    public final long durationMs;
+
+    private NetworkEvent(int netId, int eventType, long durationMs) {
+        this.netId = netId;
+        this.eventType = eventType;
+        this.durationMs = durationMs;
+    }
+
+    private NetworkEvent(Parcel in) {
+        netId = in.readInt();
+        eventType = in.readInt();
+        durationMs = in.readLong();
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(netId);
+        out.writeInt(eventType);
+        out.writeLong(durationMs);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<NetworkEvent> CREATOR
+        = new Parcelable.Creator<NetworkEvent>() {
+        public NetworkEvent createFromParcel(Parcel in) {
+            return new NetworkEvent(in);
+        }
+
+        public NetworkEvent[] newArray(int size) {
+            return new NetworkEvent[size];
+        }
+    };
+
+    public static void logEvent(int netId, int eventType) {
+        logEvent(IPCE_NETMON_STATE_CHANGE, new NetworkEvent(netId, eventType, 0));
+    }
+
+    public static void logValidated(int netId, long durationMs) {
+        logEvent(IPCE_NETMON_VALIDATED, new NetworkEvent(netId, NETWORK_VALIDATED, durationMs));
+    }
+
+    public static void logCaptivePortalFound(int netId, long durationMs) {
+        final NetworkEvent ev = new NetworkEvent(netId, NETWORK_CAPTIVE_PORTAL_FOUND, durationMs);
+        logEvent(IPCE_NETMON_CAPPORT_FOUND, ev);
+    }
+};
diff --git a/core/java/android/net/metrics/NetworkMonitorEvent.java b/core/java/android/net/metrics/NetworkMonitorEvent.java
deleted file mode 100644
index 2371266..0000000
--- a/core/java/android/net/metrics/NetworkMonitorEvent.java
+++ /dev/null
@@ -1,80 +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 android.net.metrics;
-
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * {@hide}
- */
-@SystemApi
-public final class NetworkMonitorEvent extends IpConnectivityEvent implements Parcelable {
-    public final int netId;
-    public final long durationMs;
-    public final int returnCode;
-
-    private NetworkMonitorEvent(int netId, long durationMs, int returnCode) {
-        this.netId = netId;
-        this.durationMs = durationMs;
-        this.returnCode = returnCode;
-    }
-
-    public NetworkMonitorEvent(Parcel in) {
-        netId = in.readInt();
-        durationMs = in.readLong();
-        returnCode = in.readInt();
-    }
-
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(netId);
-        out.writeLong(durationMs);
-        out.writeInt(returnCode);
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<NetworkMonitorEvent> CREATOR
-        = new Parcelable.Creator<NetworkMonitorEvent>() {
-        public NetworkMonitorEvent createFromParcel(Parcel in) {
-            return new NetworkMonitorEvent(in);
-        }
-
-        public NetworkMonitorEvent[] newArray(int size) {
-            return new NetworkMonitorEvent[size];
-        }
-    };
-
-    private static void logEvent(int eventType, int netId, long durationMs, int returnCode) {
-        logEvent(eventType, new NetworkMonitorEvent(netId, durationMs, returnCode));
-    }
-
-    public static void logValidated(int netId, long durationMs) {
-        logEvent(IPCE_NETMON_VALIDATED, netId, durationMs, 0);
-    }
-
-    public static void logPortalProbeEvent(int netId, long durationMs, int returnCode) {
-        logEvent(IPCE_NETMON_PORTAL_PROBE, netId, durationMs, returnCode);
-    }
-
-    public static void logCaptivePortalFound(int netId, long durationMs) {
-        logEvent(IPCE_NETMON_CAPPORT_FOUND, netId, durationMs, 0);
-    }
-};
diff --git a/core/java/android/net/metrics/ValidationProbeEvent.java b/core/java/android/net/metrics/ValidationProbeEvent.java
new file mode 100644
index 0000000..0a524c6
--- /dev/null
+++ b/core/java/android/net/metrics/ValidationProbeEvent.java
@@ -0,0 +1,77 @@
+/*
+ * 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 android.net.metrics;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * {@hide}
+ */
+@SystemApi
+public final class ValidationProbeEvent extends IpConnectivityEvent implements Parcelable {
+
+    public static final int PROBE_HTTP  = 0;
+    public static final int PROBE_HTTPS = 1;
+
+    public final int netId;
+    public final long durationMs;
+    public final int probeType;
+    public final int returnCode;
+
+    private ValidationProbeEvent(int netId, long durationMs, int probeType, int returnCode) {
+        this.netId = netId;
+        this.durationMs = durationMs;
+        this.probeType = probeType;
+        this.returnCode = returnCode;
+    }
+
+    private ValidationProbeEvent(Parcel in) {
+        netId = in.readInt();
+        durationMs = in.readLong();
+        probeType = in.readInt();
+        returnCode = in.readInt();
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(netId);
+        out.writeLong(durationMs);
+        out.writeInt(probeType);
+        out.writeInt(returnCode);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<ValidationProbeEvent> CREATOR
+        = new Parcelable.Creator<ValidationProbeEvent>() {
+        public ValidationProbeEvent createFromParcel(Parcel in) {
+            return new ValidationProbeEvent(in);
+        }
+
+        public ValidationProbeEvent[] newArray(int size) {
+            return new ValidationProbeEvent[size];
+        }
+    };
+
+    public static void logEvent(int netId, long durationMs, int probeType, int returnCode) {
+        logEvent(IPCE_NETMON_PORTAL_PROBE,
+                 new ValidationProbeEvent(netId, durationMs, probeType, returnCode));
+    }
+};
diff --git a/core/java/android/print/PrintAttributes.java b/core/java/android/print/PrintAttributes.java
index 721c94e..17942ae 100644
--- a/core/java/android/print/PrintAttributes.java
+++ b/core/java/android/print/PrintAttributes.java
@@ -805,8 +805,8 @@
          * @param id The unique media size id.
          * @param packageName The name of the creating package.
          * @param labelResId The resource if of a human readable label.
-         * @param widthMils The width in mils (thousands of an inch).
-         * @param heightMils The height in mils (thousands of an inch).
+         * @param widthMils The width in mils (thousandths of an inch).
+         * @param heightMils The height in mils (thousandths of an inch).
          *
          * @throws IllegalArgumentException If the id is empty or the label
          * is empty or the widthMils is less than or equal to zero or the
@@ -828,8 +828,8 @@
          * @param id The unique media size id. It is unique amongst other media sizes
          *        supported by the printer.
          * @param label The <strong>localized</strong> human readable label.
-         * @param widthMils The width in mils (thousands of an inch).
-         * @param heightMils The height in mils (thousands of an inch).
+         * @param widthMils The width in mils (thousandths of an inch).
+         * @param heightMils The height in mils (thousandths of an inch).
          *
          * @throws IllegalArgumentException If the id is empty or the label is empty
          * or the widthMils is less than or equal to zero or the heightMils is less
@@ -864,8 +864,8 @@
          *        supported by the printer.
          * @param label The <strong>localized</strong> human readable label.
          * @param packageName The name of the creating package.
-         * @param widthMils The width in mils (thousands of an inch).
-         * @param heightMils The height in mils (thousands of an inch).
+         * @param widthMils The width in mils (thousandths of an inch).
+         * @param heightMils The height in mils (thousandths of an inch).
          * @param labelResId The resource if of a human readable label.
          *
          * @throws IllegalArgumentException If the id is empty or the label is unset
@@ -924,7 +924,7 @@
         }
 
         /**
-         * Gets the media width in mils (thousands of an inch).
+         * Gets the media width in mils (thousandths of an inch).
          *
          * @return The media width.
          */
@@ -933,7 +933,7 @@
         }
 
         /**
-         * Gets the media height in mils (thousands of an inch).
+         * Gets the media height in mils (thousandths of an inch).
          *
          * @return The media height.
          */
@@ -1225,10 +1225,10 @@
         /**
          * Creates a new instance.
          *
-         * @param leftMils The left margin in mils (thousands of an inch).
-         * @param topMils The top margin in mils (thousands of an inch).
-         * @param rightMils The right margin in mils (thousands of an inch).
-         * @param bottomMils The bottom margin in mils (thousands of an inch).
+         * @param leftMils The left margin in mils (thousandths of an inch).
+         * @param topMils The top margin in mils (thousandths of an inch).
+         * @param rightMils The right margin in mils (thousandths of an inch).
+         * @param bottomMils The bottom margin in mils (thousandths of an inch).
          */
         public Margins(int leftMils, int topMils, int rightMils, int bottomMils) {
             mTopMils = topMils;
@@ -1238,7 +1238,7 @@
         }
 
         /**
-         * Gets the left margin in mils (thousands of an inch).
+         * Gets the left margin in mils (thousandths of an inch).
          *
          * @return The left margin.
          */
@@ -1247,7 +1247,7 @@
         }
 
         /**
-         * Gets the top margin in mils (thousands of an inch).
+         * Gets the top margin in mils (thousandths of an inch).
          *
          * @return The top margin.
          */
@@ -1256,7 +1256,7 @@
         }
 
         /**
-         * Gets the right margin in mils (thousands of an inch).
+         * Gets the right margin in mils (thousandths of an inch).
          *
          * @return The right margin.
          */
@@ -1265,7 +1265,7 @@
         }
 
         /**
-         * Gets the bottom margin in mils (thousands of an inch).
+         * Gets the bottom margin in mils (thousandths of an inch).
          *
          * @return The bottom margin.
          */
diff --git a/core/java/android/view/DropPermissions.java b/core/java/android/view/DragAndDropPermissions.java
similarity index 69%
rename from core/java/android/view/DropPermissions.java
rename to core/java/android/view/DragAndDropPermissions.java
index 5411dad..a3dbdb1 100644
--- a/core/java/android/view/DropPermissions.java
+++ b/core/java/android/view/DragAndDropPermissions.java
@@ -19,51 +19,52 @@
 import android.app.ActivityManagerNative;
 import android.os.IBinder;
 import android.os.RemoteException;
-import com.android.internal.view.IDropPermissions;
+import com.android.internal.view.IDragAndDropPermissions;
 import dalvik.system.CloseGuard;
 
 
 /**
- * {@link DropPermissions} controls the access permissions for the content URIs associated with a
- * {@link DragEvent}.
+ * {@link DragAndDropPermissions} controls the access permissions for the content URIs associated
+ * with a {@link DragEvent}.
  * <p>
  * Permission are granted when this object is created by {@link
- * android.app.Activity#requestDropPermissions(DragEvent) Activity.requestDropPermissions}.
+ * android.app.Activity#requestDragAndDropPermissions(DragEvent)
+ * Activity.requestDragAndDropPermissions}.
  * Which permissions are granted is defined by the set of flags passed to {@link
  * View#startDragAndDrop(android.content.ClipData, View.DragShadowBuilder, Object, int)
  * View.startDragAndDrop} by the app that started the drag operation.
  * <p>
  * The life cycle of the permissions is bound to the activity used to call {@link
- * android.app.Activity#requestDropPermissions(DragEvent) requestDropPermissions}. The
+ * android.app.Activity#requestDragAndDropPermissions(DragEvent) requestDragAndDropPermissions}. The
  * permissions are revoked when this activity is destroyed, or when {@link #release()} is called,
  * whichever occurs first.
  */
-public final class DropPermissions {
+public final class DragAndDropPermissions {
 
-    private final IDropPermissions mDropPermissions;
+    private final IDragAndDropPermissions mDragAndDropPermissions;
 
     private IBinder mPermissionOwnerToken;
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
 
     /**
-     * Create a new {@link DropPermissions} object to control the access permissions for content
-     * URIs associated with {@link DragEvent}.
+     * Create a new {@link DragAndDropPermissions} object to control the access permissions for
+     * content URIs associated with {@link DragEvent}.
      * @param dragEvent Drag event
-     * @return {@link DropPermissions} object or null if there are no content URIs associated with
-     * the {@link DragEvent}.
+     * @return {@link DragAndDropPermissions} object or null if there are no content URIs associated
+     * with the {@link DragEvent}.
      * @hide
      */
-    public static DropPermissions obtain(DragEvent dragEvent) {
-        if (dragEvent.getDropPermissions() == null) {
+    public static DragAndDropPermissions obtain(DragEvent dragEvent) {
+        if (dragEvent.getDragAndDropPermissions() == null) {
             return null;
         }
-        return new DropPermissions(dragEvent.getDropPermissions());
+        return new DragAndDropPermissions(dragEvent.getDragAndDropPermissions());
     }
 
     /** @hide */
-    private DropPermissions(IDropPermissions dropPermissions) {
-        mDropPermissions = dropPermissions;
+    private DragAndDropPermissions(IDragAndDropPermissions dragAndDropPermissions) {
+        mDragAndDropPermissions = dragAndDropPermissions;
     }
 
     /**
@@ -74,7 +75,7 @@
      */
     public boolean take(IBinder activityToken) {
         try {
-            mDropPermissions.take(activityToken);
+            mDragAndDropPermissions.take(activityToken);
         } catch (RemoteException e) {
             return false;
         }
@@ -91,7 +92,7 @@
         try {
             mPermissionOwnerToken = ActivityManagerNative.getDefault().
                     newUriPermissionOwner("drop");
-            mDropPermissions.takeTransient(mPermissionOwnerToken);
+            mDragAndDropPermissions.takeTransient(mPermissionOwnerToken);
         } catch (RemoteException e) {
             return false;
         }
@@ -104,7 +105,7 @@
      */
     public void release() {
         try {
-            mDropPermissions.release();
+            mDragAndDropPermissions.release();
             mPermissionOwnerToken = null;
         } catch (RemoteException e) {
         }
diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java
index 71db0b5..0dfbe70 100644
--- a/core/java/android/view/DragEvent.java
+++ b/core/java/android/view/DragEvent.java
@@ -21,7 +21,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import com.android.internal.view.IDropPermissions;
+import com.android.internal.view.IDragAndDropPermissions;
 
 //TODO: Improve Javadoc
 /**
@@ -130,7 +130,7 @@
     float mX, mY;
     ClipDescription mClipDescription;
     ClipData mClipData;
-    IDropPermissions mDropPermissions;
+    IDragAndDropPermissions mDragAndDropPermissions;
 
     Object mLocalState;
     boolean mDragResult;
@@ -257,13 +257,13 @@
     }
 
     private void init(int action, float x, float y, ClipDescription description, ClipData data,
-            IDropPermissions dropPermissions, Object localState, boolean result) {
+            IDragAndDropPermissions dragAndDropPermissions, Object localState, boolean result) {
         mAction = action;
         mX = x;
         mY = y;
         mClipDescription = description;
         mClipData = data;
-        mDropPermissions = dropPermissions;
+        this.mDragAndDropPermissions = dragAndDropPermissions;
         mLocalState = localState;
         mDragResult = result;
     }
@@ -274,13 +274,14 @@
 
     /** @hide */
     public static DragEvent obtain(int action, float x, float y, Object localState,
-            ClipDescription description, ClipData data, IDropPermissions dropPermissions,
-            boolean result) {
+            ClipDescription description, ClipData data,
+            IDragAndDropPermissions dragAndDropPermissions, boolean result) {
         final DragEvent ev;
         synchronized (gRecyclerLock) {
             if (gRecyclerTop == null) {
                 ev = new DragEvent();
-                ev.init(action, x, y, description, data, dropPermissions, localState, result);
+                ev.init(action, x, y, description, data, dragAndDropPermissions, localState,
+                        result);
                 return ev;
             }
             ev = gRecyclerTop;
@@ -291,7 +292,7 @@
         ev.mRecycled = false;
         ev.mNext = null;
 
-        ev.init(action, x, y, description, data, dropPermissions, localState, result);
+        ev.init(action, x, y, description, data, dragAndDropPermissions, localState, result);
 
         return ev;
     }
@@ -299,7 +300,7 @@
     /** @hide */
     public static DragEvent obtain(DragEvent source) {
         return obtain(source.mAction, source.mX, source.mY, source.mLocalState,
-                source.mClipDescription, source.mClipData, source.mDropPermissions,
+                source.mClipDescription, source.mClipData, source.mDragAndDropPermissions,
                 source.mDragResult);
     }
 
@@ -365,8 +366,8 @@
     }
 
     /** @hide */
-    public IDropPermissions getDropPermissions() {
-        return mDropPermissions;
+    public IDragAndDropPermissions getDragAndDropPermissions() {
+        return mDragAndDropPermissions;
     }
 
     /**
@@ -489,11 +490,11 @@
             dest.writeInt(1);
             mClipDescription.writeToParcel(dest, flags);
         }
-        if (mDropPermissions == null) {
+        if (mDragAndDropPermissions == null) {
             dest.writeInt(0);
         } else {
             dest.writeInt(1);
-            dest.writeStrongBinder(mDropPermissions.asBinder());
+            dest.writeStrongBinder(mDragAndDropPermissions.asBinder());
         }
     }
 
@@ -515,7 +516,8 @@
                 event.mClipDescription = ClipDescription.CREATOR.createFromParcel(in);
             }
             if (in.readInt() != 0) {
-                event.mDropPermissions = IDropPermissions.Stub.asInterface(in.readStrongBinder());;
+                event.mDragAndDropPermissions =
+                        IDragAndDropPermissions.Stub.asInterface(in.readStrongBinder());;
             }
             return event;
         }
diff --git a/core/java/android/view/FrameMetrics.java b/core/java/android/view/FrameMetrics.java
index 8e66f86..5c4450a 100644
--- a/core/java/android/view/FrameMetrics.java
+++ b/core/java/android/view/FrameMetrics.java
@@ -234,7 +234,8 @@
      * Constructs a FrameMetrics object as a copy.
      * <p>
      * Use this method to copy out metrics reported by
-     * {@link Window.FrameMetricsListener#onMetricsAvailable(Window, FrameMetrics, int)}
+     * {@link Window.OnFrameMetricsAvailableListener#onFrameMetricsAvailable(
+     * Window, FrameMetrics, int)}
      * </p>
      * @param other the FrameMetrics object to copy.
      */
diff --git a/core/java/android/view/FrameMetricsObserver.java b/core/java/android/view/FrameMetricsObserver.java
index f38f8b7..6331357 100644
--- a/core/java/android/view/FrameMetricsObserver.java
+++ b/core/java/android/view/FrameMetricsObserver.java
@@ -40,7 +40,7 @@
 
     private FrameMetrics mFrameMetrics;
 
-    /* package */ Window.FrameMetricsListener mListener;
+    /* package */ Window.OnFrameMetricsAvailableListener mListener;
     /* package */ VirtualRefBasePtr mNative;
 
     /**
@@ -49,7 +49,7 @@
      * @param looper the looper to use when invoking callbacks
      */
     FrameMetricsObserver(@NonNull Window window, @NonNull Looper looper,
-            @NonNull Window.FrameMetricsListener listener) {
+            @NonNull Window.OnFrameMetricsAvailableListener listener) {
         if (looper == null) {
             throw new NullPointerException("looper cannot be null");
         }
@@ -69,7 +69,7 @@
     private void notifyDataAvailable(int dropCount) {
         final Window window = mWindow.get();
         if (window != null) {
-            mListener.onMetricsAvailable(window, mFrameMetrics, dropCount);
+            mListener.onFrameMetricsAvailable(window, mFrameMetrics, dropCount);
         }
     }
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1781d9d..6e0175f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5513,7 +5513,8 @@
      *
      * @hide
      */
-    public void addFrameMetricsListener(Window window, Window.FrameMetricsListener listener,
+    public void addFrameMetricsListener(Window window,
+            Window.OnFrameMetricsAvailableListener listener,
             Handler handler) {
         if (mAttachInfo != null) {
             if (mAttachInfo.mHardwareRenderer != null) {
@@ -5544,11 +5545,13 @@
      *
      * @hide
      */
-    public void removeFrameMetricsListener(Window.FrameMetricsListener listener) {
+    public void removeFrameMetricsListener(
+            Window.OnFrameMetricsAvailableListener listener) {
         ThreadedRenderer renderer = getHardwareRenderer();
         FrameMetricsObserver fmo = findFrameMetricsObserver(listener);
         if (fmo == null) {
-            throw new IllegalArgumentException("attempt to remove FrameMetricsListener that was never added");
+            throw new IllegalArgumentException(
+                    "attempt to remove OnFrameMetricsAvailableListener that was never added");
         }
 
         if (mFrameMetricsObservers != null) {
@@ -5572,7 +5575,8 @@
         }
     }
 
-    private FrameMetricsObserver findFrameMetricsObserver(Window.FrameMetricsListener listener) {
+    private FrameMetricsObserver findFrameMetricsObserver(
+            Window.OnFrameMetricsAvailableListener listener) {
         for (int i = 0; i < mFrameMetricsObservers.size(); i++) {
             FrameMetricsObserver observer = mFrameMetricsObservers.get(i);
             if (observer.mListener == listener) {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 5135657..e3abb5d 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -43,6 +43,8 @@
 import android.transition.TransitionManager;
 import android.view.accessibility.AccessibilityEvent;
 
+import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+
 import java.util.List;
 
 /**
@@ -610,7 +612,7 @@
      * Callback for clients that want frame timing information for each
      * frame rendered by the Window.
      */
-    public interface FrameMetricsListener {
+    public interface OnFrameMetricsAvailableListener {
         /**
          * Called when information is available for the previously rendered frame.
          *
@@ -629,7 +631,7 @@
          * @param dropCountSinceLastInvocation the number of reports dropped since the last time
          * this callback was invoked.
          */
-        void onMetricsAvailable(Window window, FrameMetrics frameMetrics,
+        void onFrameMetricsAvailable(Window window, FrameMetrics frameMetrics,
                 int dropCountSinceLastInvocation);
     }
 
@@ -792,8 +794,9 @@
         if (wp.packageName == null) {
             wp.packageName = mContext.getPackageName();
         }
-        if (mHardwareAccelerated) {
-            wp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+        if (mHardwareAccelerated ||
+                (mWindowAttributes.flags & FLAG_HARDWARE_ACCELERATED) != 0) {
+            wp.flags |= FLAG_HARDWARE_ACCELERATED;
         }
     }
 
@@ -829,7 +832,8 @@
      *
      * Must be in hardware rendering mode.
      */
-    public final void addFrameMetricsListener(@NonNull FrameMetricsListener listener,
+    public final void addOnFrameMetricsAvailableListener(
+            @NonNull OnFrameMetricsAvailableListener listener,
             Handler handler) {
         final View decorView = getDecorView();
         if (decorView == null) {
@@ -846,7 +850,7 @@
     /**
      * Remove observer and stop listening to frame stats for this window.
      */
-    public final void removeFrameMetricsListener(FrameMetricsListener listener) {
+    public final void removeOnFrameMetricsAvailableListener(OnFrameMetricsAvailableListener listener) {
         final View decorView = getDecorView();
         if (decorView != null) {
             getDecorView().removeFrameMetricsListener(listener);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 54e9942..9b74fc0 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1251,7 +1251,7 @@
          * the device supports it.
          * @hide
          */
-        public static final int PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE = 0x00020000;
+        public static final int PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE = 0x00040000;
 
         /**
          * Control flags that are private to the platform.
diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java
index 2b54875..85d7cd0 100644
--- a/core/java/android/webkit/WebViewDelegate.java
+++ b/core/java/android/webkit/WebViewDelegate.java
@@ -74,9 +74,7 @@
      * and false otherwise.
      */
     public boolean canInvokeDrawGlFunctor(View containerView) {
-        ViewRootImpl viewRootImpl = containerView.getViewRootImpl();
-         // viewRootImpl can be null during teardown when window is leaked.
-        return viewRootImpl != null;
+        return true;
     }
 
     /**
diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
index d20b924..d2ee866 100644
--- a/core/java/android/widget/DateTimeView.java
+++ b/core/java/android/widget/DateTimeView.java
@@ -16,21 +16,32 @@
 
 package android.widget;
 
+import static android.text.format.DateUtils.DAY_IN_MILLIS;
+import static android.text.format.DateUtils.HOUR_IN_MILLIS;
+import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+import static android.text.format.DateUtils.YEAR_IN_MILLIS;
+import static android.text.format.Time.getJulianDay;
+
 import android.app.ActivityThread;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.BroadcastReceiver;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
 import android.database.ContentObserver;
+import android.icu.util.Calendar;
 import android.os.Handler;
 import android.text.format.Time;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.widget.RemoteViews.RemoteView;
 
+import com.android.internal.R;
+
 import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.TimeZone;
 
 //
 // TODO
@@ -46,11 +57,6 @@
  */
 @RemoteView
 public class DateTimeView extends TextView {
-    private static final String TAG = "DateTimeView";
-
-    private static final long TWELVE_HOURS_IN_MINUTES = 12 * 60;
-    private static final long TWENTY_FOUR_HOURS_IN_MILLIS = 24 * 60 * 60 * 1000;
-
     private static final int SHOW_TIME = 0;
     private static final int SHOW_MONTH_DAY_YEAR = 1;
 
@@ -62,13 +68,30 @@
 
     private long mUpdateTimeMillis;
     private static final ThreadLocal<ReceiverInfo> sReceiverInfo = new ThreadLocal<ReceiverInfo>();
+    private String mNowText;
+    private boolean mShowRelativeTime;
 
     public DateTimeView(Context context) {
-        super(context);
+        this(context, null);
     }
 
     public DateTimeView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.DateTimeView, 0,
+                0);
+
+        final int N = a.getIndexCount();
+        for (int i = 0; i < N; i++) {
+            int attr = a.getIndex(i);
+            switch (attr) {
+                case R.styleable.DateTimeView_showRelative:
+                    boolean relative = a.getBoolean(i, false);
+                    setShowRelativeTime(relative);
+                    break;
+            }
+        }
+        a.recycle();
     }
 
     @Override
@@ -101,12 +124,31 @@
         update();
     }
 
+    @android.view.RemotableViewMethod
+    public void setShowRelativeTime(boolean showRelativeTime) {
+        mShowRelativeTime = showRelativeTime;
+        updateNowText();
+        update();
+    }
+
+    @Override
+    @android.view.RemotableViewMethod
+    public void setVisibility(@Visibility int visibility) {
+        boolean gotVisible = visibility != GONE && getVisibility() == GONE;
+        super.setVisibility(visibility);
+        if (gotVisible) {
+            update();
+        }
+    }
+
     void update() {
-        if (mTime == null) {
+        if (mTime == null || getVisibility() == GONE) {
             return;
         }
-
-        long start = System.nanoTime();
+        if (mShowRelativeTime) {
+            updateRelativeTime();
+            return;
+        }
 
         int display;
         Date time = mTime;
@@ -181,12 +223,105 @@
                         ? twelveHoursBefore : midnightBefore;
             }
         }
-        if (false) {
-            Log.d(TAG, "update needed for '" + time + "' at '" + new Date(mUpdateTimeMillis)
-                    + "' - text=" + text);
-        }
+    }
 
-        long finish = System.nanoTime();
+    private void updateRelativeTime() {
+        long now = System.currentTimeMillis();
+        long duration = Math.abs(now - mTimeMillis);
+        int count;
+        long millisIncrease;
+        boolean past = (now >= mTimeMillis);
+        String result;
+        if (duration < MINUTE_IN_MILLIS) {
+            setText(mNowText);
+            mUpdateTimeMillis = mTimeMillis + MINUTE_IN_MILLIS + 1;
+            return;
+        } else if (duration < HOUR_IN_MILLIS) {
+            count = (int)(duration / MINUTE_IN_MILLIS);
+            result = String.format(getContext().getResources().getQuantityString(past
+                            ? com.android.internal.R.plurals.duration_minutes_shortest
+                            : com.android.internal.R.plurals.duration_minutes_shortest_future,
+                            count),
+                    count);
+            millisIncrease = MINUTE_IN_MILLIS;
+        } else if (duration < DAY_IN_MILLIS) {
+            count = (int)(duration / HOUR_IN_MILLIS);
+            result = String.format(getContext().getResources().getQuantityString(past
+                            ? com.android.internal.R.plurals.duration_hours_shortest
+                            : com.android.internal.R.plurals.duration_hours_shortest_future,
+                            count),
+                    count);
+            millisIncrease = HOUR_IN_MILLIS;
+        } else if (duration < YEAR_IN_MILLIS) {
+            // In weird cases it can become 0 because of daylight savings
+            TimeZone timeZone = TimeZone.getDefault();
+            count = Math.max(Math.abs(dayDistance(timeZone, mTimeMillis, now)), 1);
+            result = String.format(getContext().getResources().getQuantityString(past
+                            ? com.android.internal.R.plurals.duration_days_shortest
+                            : com.android.internal.R.plurals.duration_days_shortest_future,
+                            count),
+                    count);
+            if (past || count != 1) {
+                mUpdateTimeMillis = computeNextMidnight(timeZone);
+                millisIncrease = -1;
+            } else {
+                millisIncrease = DAY_IN_MILLIS;
+            }
+
+        } else {
+            count = (int)(duration / YEAR_IN_MILLIS);
+            result = String.format(getContext().getResources().getQuantityString(past
+                            ? com.android.internal.R.plurals.duration_years_shortest
+                            : com.android.internal.R.plurals.duration_years_shortest_future,
+                            count),
+                    count);
+            millisIncrease = YEAR_IN_MILLIS;
+        }
+        if (millisIncrease != -1) {
+            if (past) {
+                mUpdateTimeMillis = mTimeMillis + millisIncrease * (count + 1) + 1;
+            } else {
+                mUpdateTimeMillis = mTimeMillis - millisIncrease * count + 1;
+            }
+        }
+        setText(result);
+    }
+
+    /**
+     * @param timeZone the timezone we are in
+     * @return the timepoint in millis at UTC at midnight in the current timezone
+     */
+    private long computeNextMidnight(TimeZone timeZone) {
+        Calendar c = Calendar.getInstance();
+        c.setTimeZone(libcore.icu.DateUtilsBridge.icuTimeZone(timeZone));
+        c.add(Calendar.DAY_OF_MONTH, 1);
+        c.set(Calendar.HOUR_OF_DAY, 0);
+        c.set(Calendar.MINUTE, 0);
+        c.set(Calendar.SECOND, 0);
+        c.set(Calendar.MILLISECOND, 0);
+        return c.getTimeInMillis();
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        updateNowText();
+        update();
+    }
+
+    private void updateNowText() {
+        if (!mShowRelativeTime) {
+            return;
+        }
+        mNowText = getContext().getResources().getString(
+                com.android.internal.R.string.now_string_shortest);
+    }
+
+    // Return the date difference for the two times in a given timezone.
+    private static int dayDistance(TimeZone timeZone, long startTime,
+            long endTime) {
+        return getJulianDay(endTime, timeZone.getOffset(endTime) / 1000)
+                - getJulianDay(startTime, timeZone.getOffset(startTime) / 1000);
     }
 
     private DateFormat getTimeFormat() {
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 440ef21..5d2683f 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -77,8 +77,8 @@
 import android.view.ActionMode.Callback;
 import android.view.ContextMenu;
 import android.view.DisplayListCanvas;
+import android.view.DragAndDropPermissions;
 import android.view.DragEvent;
-import android.view.DropPermissions;
 import android.view.Gravity;
 import android.view.InputDevice;
 import android.view.LayoutInflater;
@@ -2379,9 +2379,9 @@
     void onDrop(DragEvent event) {
         StringBuilder content = new StringBuilder("");
 
-        final DropPermissions dropPermissions = DropPermissions.obtain(event);
-        if (dropPermissions != null) {
-            dropPermissions.takeTransient();
+        final DragAndDropPermissions permissions = DragAndDropPermissions.obtain(event);
+        if (permissions != null) {
+            permissions.takeTransient();
         }
 
         try {
@@ -2393,8 +2393,8 @@
             }
         }
         finally {
-            if (dropPermissions != null) {
-                dropPermissions.release();
+            if (permissions != null) {
+                permissions.release();
             }
         }
 
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 9c9784b..3c967ac 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -1397,6 +1397,10 @@
     /**
      * Sets the current progress to the specified value. Does not do anything
      * if the progress bar is in indeterminate mode.
+     * <p>
+     * This method will immediately update the visual position of the progress
+     * indicator. To animate the visual position to the target value, use
+     * {@link #setProgress(int, boolean)}}.
      *
      * @param progress the new progress, between 0 and {@link #getMax()}
      *
@@ -1412,7 +1416,7 @@
 
     /**
      * Sets the current progress to the specified value, optionally animating
-     * between the current and target values.
+     * the visual position between the current and target values.
      * <p>
      * Animation does not affect the result of {@link #getProgress()}, which
      * will return the target value immediately after this method is called.
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index a9b7f4e..6dc5ff7 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -2600,7 +2600,7 @@
      *               simply display the timer value.
      * @param started True if you want the clock to be started, false if not.
      *
-     * @see #setChronometerCountsDown(int, boolean)
+     * @see #setChronometerCountDown(int, boolean)
      */
     public void setChronometer(int viewId, long base, String format, boolean started) {
         setLong(viewId, "setBase", base);
@@ -2616,7 +2616,7 @@
      * @param isCountDown True if you want the chronometer to count down to base instead of
      *                    counting up.
      */
-    public void setChronometerCountsDown(int viewId, boolean isCountDown) {
+    public void setChronometerCountDown(int viewId, boolean isCountDown) {
         setBoolean(viewId, "setCountDown", isCountDown);
     }
 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 8097d7a..3216fba 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1591,6 +1591,7 @@
         }
     }
 
+    @android.view.RemotableViewMethod
     @Override
     public void setEnabled(boolean enabled) {
         if (enabled == isEnabled()) {
diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java
index 7803e52..e3fce51 100644
--- a/core/java/com/android/internal/app/LocaleStore.java
+++ b/core/java/com/android/internal/app/LocaleStore.java
@@ -126,12 +126,18 @@
             return mFullCountryNameNative;
         }
 
+        String getFullCountryNameInUiLanguage() {
+            // We don't cache the UI name because the default locale keeps changing
+            return LocaleHelper.getDisplayCountry(mLocale);
+        }
+
         /** Returns the name of the locale in the language of the UI.
          * It is used for search, but never shown.
          * For instance German will show as "Deutsch" in the list, but we will also search for
          * "allemand" if the system UI is in French.
          */
         public String getFullNameInUiLanguage() {
+            // We don't cache the UI name because the default locale keeps changing
             return LocaleHelper.getDisplayName(mLocale, true /* sentence case */);
         }
 
@@ -154,6 +160,14 @@
             }
         }
 
+        String getContentDescription(boolean countryMode) {
+            if (countryMode) {
+                return getFullCountryNameInUiLanguage();
+            } else {
+                return getFullNameInUiLanguage();
+            }
+        }
+
         public boolean getChecked() {
             return mIsChecked;
         }
diff --git a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
index e2d29e3..a4b5a8e 100644
--- a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
+++ b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
@@ -159,6 +159,7 @@
                 LocaleStore.LocaleInfo item = (LocaleStore.LocaleInfo) getItem(position);
                 text.setText(item.getLabel(mCountryMode));
                 text.setTextLocale(item.getLocale());
+                text.setContentDescription(item.getContentDescription(mCountryMode));
                 if (mCountryMode) {
                     int layoutDir = TextUtils.getLayoutDirectionFromLocale(item.getParent());
                     //noinspection ResourceType
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index fcf65f2..5cbe1ce 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -65,6 +65,7 @@
     void cancelPreloadRecentApps();
     void showScreenPinningRequest(int taskId);
 
+    void dismissKeyboardShortcutsMenu();
     void toggleKeyboardShortcutsMenu(int deviceId);
 
     /**
diff --git a/core/java/com/android/internal/view/IDropPermissions.aidl b/core/java/com/android/internal/view/IDragAndDropPermissions.aidl
similarity index 96%
rename from core/java/com/android/internal/view/IDropPermissions.aidl
rename to core/java/com/android/internal/view/IDragAndDropPermissions.aidl
index 74ff4b4..64c2d04 100644
--- a/core/java/com/android/internal/view/IDropPermissions.aidl
+++ b/core/java/com/android/internal/view/IDragAndDropPermissions.aidl
@@ -22,7 +22,7 @@
  * Interface to allow a drop receiver to request permissions for URIs passed along with ClipData
  * contained in DragEvent.
  */
-interface IDropPermissions {
+interface IDragAndDropPermissions {
     void take(IBinder activityToken);
     void takeTransient(IBinder permissionOwnerToken);
     void release();
diff --git a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
index 5cb307f..72ed9d0 100644
--- a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
@@ -181,8 +181,10 @@
     private View mAnchorView;
     private View mShownAnchorView;
     private int mLastPosition;
-    private int mInitXOffset;
-    private int mInitYOffset;
+    private boolean mHasXOffset;
+    private boolean mHasYOffset;
+    private int mXOffset;
+    private int mYOffset;
     private boolean mForceShowIcon;
     private boolean mShowTitle;
     private Callback mPresenterCallback;
@@ -379,9 +381,6 @@
             parentView = null;
         }
 
-        final int x;
-        final int y;
-        final Rect epicenterBounds;
         if (parentView != null) {
             // This menu is a cascading submenu anchored to a parent view.
             popupWindow.setTouchModal(false);
@@ -401,6 +400,7 @@
 
             // By now, mDropDownGravity is the resolved absolute gravity, so
             // this should work in both LTR and RTL.
+            final int x;
             if ((mDropDownGravity & Gravity.RIGHT) == Gravity.RIGHT) {
                 if (showOnRight) {
                     x = parentOffsetLeft + menuWidth;
@@ -415,17 +415,21 @@
                 }
             }
 
-            y = parentOffsetTop;
-            epicenterBounds = null;
+            popupWindow.setHorizontalOffset(x);
+
+            final int y = parentOffsetTop;
+            popupWindow.setVerticalOffset(y);
         } else {
-            x = mInitXOffset;
-            y = mInitYOffset;
-            epicenterBounds = getEpicenterBounds();
+            if (mHasXOffset) {
+                popupWindow.setHorizontalOffset(mXOffset);
+            }
+            if (mHasYOffset) {
+                popupWindow.setVerticalOffset(mYOffset);
+            }
+            final Rect epicenterBounds = getEpicenterBounds();
+            popupWindow.setEpicenterBounds(epicenterBounds);
         }
 
-        popupWindow.setHorizontalOffset(x);
-        popupWindow.setVerticalOffset(y);
-        popupWindow.setEpicenterBounds(epicenterBounds);
 
         final CascadingMenuInfo menuInfo = new CascadingMenuInfo(popupWindow, menu, mLastPosition);
         mShowingMenus.add(menuInfo);
@@ -712,12 +716,14 @@
 
     @Override
     public void setHorizontalOffset(int x) {
-        mInitXOffset = x;
+        mHasXOffset = true;
+        mXOffset = x;
     }
 
     @Override
     public void setVerticalOffset(int y) {
-        mInitYOffset = y;
+        mHasYOffset = true;
+        mYOffset = y;
     }
 
     @Override
diff --git a/core/java/com/android/internal/view/menu/StandardMenuPopup.java b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
index 339c2bf..169caa5 100644
--- a/core/java/com/android/internal/view/menu/StandardMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
@@ -108,8 +108,6 @@
 
     private int mDropDownGravity = Gravity.NO_GRAVITY;
 
-    private int mXOffset;
-    private int mYOffset;
     private boolean mShowTitle;
 
     public StandardMenuPopup(Context context, MenuBuilder menu, View anchorView, int popupStyleAttr,
@@ -177,8 +175,6 @@
 
         mPopup.setContentWidth(mContentWidth);
         mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
-        mPopup.setHorizontalOffset(mXOffset);
-        mPopup.setVerticalOffset(mYOffset);
         mPopup.setEpicenterBounds(getEpicenterBounds());
         mPopup.show();
 
@@ -276,7 +272,9 @@
             mMenu.close(false /* closeAllMenus */);
 
             // Show the new sub-menu popup at the same location as this popup.
-            if (subPopup.tryShow(mXOffset, mYOffset)) {
+            final int horizontalOffset = mPopup.getHorizontalOffset();
+            final int verticalOffset = mPopup.getVerticalOffset();
+            if (subPopup.tryShow(horizontalOffset, verticalOffset)) {
                 if (mPresenterCallback != null) {
                     mPresenterCallback.onOpenSubMenu(subMenu);
                 }
@@ -338,12 +336,12 @@
 
     @Override
     public void setHorizontalOffset(int x) {
-        mXOffset = x;
+        mPopup.setHorizontalOffset(x);
     }
 
     @Override
     public void setVerticalOffset(int y) {
-        mYOffset = y;
+        mPopup.setVerticalOffset(y);
     }
 
     @Override
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a598096..eb0c742 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -347,10 +347,6 @@
     <protected-broadcast android:name="android.app.action.SYSTEM_UPDATE_POLICY_CHANGED" />
     <protected-broadcast android:name="android.app.action.DEVICE_OWNER_CHANGED" />
 
-    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED" />
-    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_AVAILABLE" />
-    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_UNAVAILABLE" />
-
     <!-- Added in N -->
     <protected-broadcast android:name="android.intent.action.ANR" />
     <protected-broadcast android:name="android.intent.action.CALL" />
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 992e88e..d16dcc6 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -69,15 +69,17 @@
         android:text="@string/notification_header_divider_symbol"
         android:singleLine="true"
         android:visibility="gone"/>
-    <ViewStub
+    <DateTimeView
         android:id="@+id/time"
+        android:textAppearance="@style/TextAppearance.Material.Notification.Time"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_gravity="center"
         android:layout_marginStart="2dp"
         android:layout_marginEnd="2dp"
-        android:layout="@layout/notification_template_part_time"
-        android:visibility="gone"
-        />
+        android:showRelative="true"
+        android:singleLine="true"
+        android:visibility="gone" />
     <ViewStub
         android:id="@+id/chronometer"
         android:layout_width="wrap_content"
diff --git a/core/res/res/layout/notification_template_part_time.xml b/core/res/res/layout/notification_template_part_time.xml
deleted file mode 100644
index 442ff8c..0000000
--- a/core/res/res/layout/notification_template_part_time.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-
-<DateTimeView android:id="@+id/time" xmlns:android="http://schemas.android.com/apk/res/android"
-    android:textAppearance="@style/TextAppearance.Material.Notification.Time"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_gravity="center"
-    android:layout_marginEnd="4dp"
-    android:layout_weight="0"
-    android:singleLine="true"
-    />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 5bfa2d4..6af9ef2 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -8083,11 +8083,11 @@
         <attr name="settingsActivity" />
         <!-- Attribute whether the TV input service can record programs. This value can be changed
              at runtime by calling
-             {@link android.media.tv.TvInputService#updateTvInputInfo(android.content.Context, android.media.tv.TvInputInfo)}. -->
+             {@link android.media.tv.TvInputManager#updateTvInputInfo(android.media.tv.TvInputInfo)}. -->
         <attr name="canRecord" format="boolean" />
         <!-- The number of tuners that the TV input service is associated with. This value can be
              changed at runtime by calling
-             {@link android.media.tv.TvInputService#updateTvInputInfo(android.content.Context, android.media.tv.TvInputInfo)}. -->
+             {@link android.media.tv.TvInputManager#updateTvInputInfo(android.media.tv.TvInputInfo)}. -->
         <attr name="tunerCount" format="integer" />
     </declare-styleable>
 
@@ -8134,6 +8134,10 @@
         <attr name="spacing" />
     </declare-styleable>
 
+    <declare-styleable name="DateTimeView">
+        <attr name="showRelative" format="boolean" />
+    </declare-styleable>
+
     <declare-styleable name="ResolverDrawerLayout_LayoutParams">
         <attr name="layout_alwaysShow" format="boolean" />
         <attr name="layout_ignoreOffset" format="boolean" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2040d7d..03c6048 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2423,6 +2423,49 @@
         <item quantity="other"><xliff:g id="count">%d</xliff:g> hours</item>
     </plurals>
 
+    <!-- A string denoting the current point in time that should be as short as possible. Abbreviations are preferred to full strings as this might be shown repetitively. It is used in the header of notifications. [CHAR LIMIT=8]-->
+    <string name="now_string_shortest">now</string>
+
+    <!-- Phrase describing a time duration using minutes that is as short as possible, preferrably one character. If the language needs a space in between the integer and the unit, please also integrate it in the string, but preferably it should not have a space in between.[CHAR LIMIT=6] -->
+    <plurals name="duration_minutes_shortest">
+        <item quantity="other"><xliff:g example="2" id="count">%d</xliff:g>m</item>
+    </plurals>
+
+    <!-- Phrase describing a time duration using hours that is as short as possible, preferrably one character. If the language needs a space in between the integer and the unit, please also integrate it in the string, but preferably it should not have a space in between.[CHAR LIMIT=6] -->
+    <plurals name="duration_hours_shortest">
+        <item quantity="other"><xliff:g example="2" id="count">%d</xliff:g>h</item>
+    </plurals>
+
+    <!-- Phrase describing a time duration using days that is as short as possible, preferrably one character. If the language needs a space in between the integer and the unit, please also integrate it in the string, but preferably it should not have a space in between.[CHAR LIMIT=6] -->
+    <plurals name="duration_days_shortest">
+        <item quantity="other"><xliff:g example="2" id="count">%d</xliff:g>d</item>
+    </plurals>
+
+    <!-- Phrase describing a time duration using years that is as short as possible, preferrably one character. If the language needs a space in between the integer and the unit, please also integrate it in the string, but preferably it should not have a space in between.[CHAR LIMIT=6] -->
+    <plurals name="duration_years_shortest">
+        <item quantity="other"><xliff:g example="2" id="count">%d</xliff:g>y</item>
+    </plurals>
+
+    <!-- Phrase describing a time duration using minutes that is as short as possible, preferrably one character. This version should be a future point in time. If the language needs a space in between the integer and the unit, please also integrate it in the string, but preferably it should not have a space in between.[CHAR LIMIT=14] -->
+    <plurals name="duration_minutes_shortest_future">
+        <item quantity="other">in <xliff:g example="2" id="count">%d</xliff:g>m</item>
+    </plurals>
+
+    <!-- Phrase describing a time duration using hours that is as short as possible, preferrably one character. This version should be a future point in time. If the language needs a space in between the integer and the unit, please also integrate it in the string, but preferably it should not have a space in between.[CHAR LIMIT=14] -->
+    <plurals name="duration_hours_shortest_future">
+        <item quantity="other">in <xliff:g example="2" id="count">%d</xliff:g>h</item>
+    </plurals>
+
+    <!-- Phrase describing a time duration using days that is as short as possible, preferrably one character. This version should be a future point in time. If the language needs a space in between the integer and the unit, please also integrate it in the string, but preferably it should not have a space in between.[CHAR LIMIT=14] -->
+    <plurals name="duration_days_shortest_future">
+        <item quantity="other">in <xliff:g example="2" id="count">%d</xliff:g>d</item>
+    </plurals>
+
+    <!-- Phrase describing a time duration using years that is as short as possible, preferrably one character. This version should be a future point in time. If the language needs a space in between the integer and the unit, please also integrate it in the string, but preferably it should not have a space in between.[CHAR LIMIT=14] -->
+    <plurals name="duration_years_shortest_future">
+        <item quantity="other">in <xliff:g example="2" id="count">%d</xliff:g>y</item>
+    </plurals>
+
     <!-- Title for error alert when a video cannot be played.  it can be used by any app. -->
     <string name="VideoView_error_title">Video problem</string>
     <!-- Text for error alert when a video container is not valid for progressive download/playback. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 60060a3..adeaa63 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2508,6 +2508,17 @@
 
   <java-symbol type="id" name="notification_content_container" />
 
+  <java-symbol type="plurals" name="duration_minutes_shortest" />
+  <java-symbol type="plurals" name="duration_hours_shortest" />
+  <java-symbol type="plurals" name="duration_days_shortest" />
+  <java-symbol type="plurals" name="duration_years_shortest" />
+  <java-symbol type="plurals" name="duration_minutes_shortest_future" />
+  <java-symbol type="plurals" name="duration_hours_shortest_future" />
+  <java-symbol type="plurals" name="duration_days_shortest_future" />
+  <java-symbol type="plurals" name="duration_years_shortest_future" />
+
+  <java-symbol type="string" name="now_string_shortest" />
+
   <!-- Encryption notification while accounts are locked by credential encryption -->
   <java-symbol type="string" name="user_encrypted_title" />
   <java-symbol type="string" name="user_encrypted_message" />
diff --git a/docs/html/training/tv/playback/browse.jd b/docs/html/training/tv/playback/browse.jd
index fee6a74..4621389 100644
--- a/docs/html/training/tv/playback/browse.jd
+++ b/docs/html/training/tv/playback/browse.jd
@@ -166,7 +166,7 @@
   shown in figures 1 and 2. This method replaces the title string with the
   drawable resource, if {@code setTitle()} is also called. The drawable resource should be 52dps
   tall.</li>
-  <li>{@link android.support.v17.leanback.app.BrowseFragment#setTitle(java.lang.String) setTitle()}
+  <li>{@link android.support.v17.leanback.app.BrowseFragment#setTitle(java.lang.CharSequence) setTitle()}
   sets the title string in the upper-right corner of the browse fragment, unless
   {@code setBadgeDrawable()} is called.</li>
   <li>{@link android.support.v17.leanback.app.BrowseFragment#setHeadersState(int) setHeadersState()}
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 15cb684..c3dfb89 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -562,7 +562,7 @@
 
         if ((mHeader->flags&ResStringPool_header::UTF8_FLAG &&
                 ((uint8_t*)mStrings)[mStringPoolSize-1] != 0) ||
-                (!mHeader->flags&ResStringPool_header::UTF8_FLAG &&
+                (!(mHeader->flags&ResStringPool_header::UTF8_FLAG) &&
                 ((uint16_t*)mStrings)[mStringPoolSize-1] != 0)) {
             ALOGW("Bad string block: last string is not 0-terminated\n");
             return (mError=BAD_TYPE);
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index bfd938e..5c9d2b2 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -191,7 +191,9 @@
     /**
      * Error for {@link TvInputService.RecordingSession#notifyError(int)} and
      * {@link TvRecordingClient.RecordingCallback#onError(int)}: The requested operation cannot be
-     * completed due to a problem that does not fit under any other error codes.
+     * completed due to a problem that does not fit under any other error codes, or the error code
+     * for the problem is defined on the higher version than application's
+     * <code>android:targetSdkVersion</code>.
      */
     public static final int RECORDING_ERROR_UNKNOWN = 0;
 
@@ -1181,14 +1183,23 @@
     }
 
     /**
-     * Updates information about an existing TV input.
+     * Updates the <code>TvInputInfo</code> for an existing TV input. A TV input service
+     * implementation may call this method to pass the application and system an up-to-date
+     * <code>TvInputInfo</code> object that describes itself.
      *
-     * <p>This is called internally only by {@link TvInputService}.
+     * <p>The system automatically creates a <code>TvInputInfo</code> object for each TV input,
+     * based on the information collected from the <code>AndroidManifest.xml</code>, thus it is not
+     * necessary to call this method unless such information has changed dynamically.
+     * Use {@link TvInputInfo.Builder} to build a new <code>TvInputInfo</code> object.
+     *
+     * <p>Attempting to change information about a TV input that the calling package does not own
+     * does nothing.
      *
      * @param inputInfo The <code>TvInputInfo</code> object that contains new information.
      * @throws IllegalArgumentException if the argument is {@code null}.
+     * @see TvInputCallback#onTvInputInfoUpdated(TvInputInfo)
      */
-    void updateTvInputInfo(@NonNull TvInputInfo inputInfo) {
+    public void updateTvInputInfo(@NonNull TvInputInfo inputInfo) {
         Preconditions.checkNotNull(inputInfo);
         try {
             mService.updateTvInputInfo(inputInfo, mUserId);
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 21211d7..7ae8da0 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -256,31 +256,6 @@
         return null;
     }
 
-    /**
-     * Updates the <code>TvInputInfo</code> for an existing TV input. A TV input service
-     * implementation may call this method to pass the application and system an up-to-date
-     * <code>TvInputInfo</code> object that describes itself.
-     *
-     * <p>The system automatically creates a <code>TvInputInfo</code> object for each TV input,
-     * based on the information collected from the <code>AndroidManifest.xml</code>, thus it is not
-     * necessary to call this method unless such information has changed dynamically.
-     * Use {@link TvInputInfo.Builder} to build a new <code>TvInputInfo</code> object.
-     *
-     * <p>Attempting to change information about a TV input that the calling package does not own
-     * does nothing.
-     *
-     * @param context The application context.
-     * @param inputInfo The <code>TvInputInfo</code> object that contains new information.
-     * @see TvInputManager.TvInputCallback#onTvInputInfoUpdated(TvInputInfo)
-     */
-    public static final void updateTvInputInfo(Context context, TvInputInfo inputInfo) {
-        TvInputManager manager = (TvInputManager) context.getSystemService(
-                Context.TV_INPUT_SERVICE);
-        if (manager != null) {
-            manager.updateTvInputInfo(inputInfo);
-        }
-    }
-
     private boolean isPassthroughInput(String inputId) {
         if (mTvInputManager == null) {
             mTvInputManager = (TvInputManager) getSystemService(Context.TV_INPUT_SERVICE);
diff --git a/media/java/android/mtp/MtpConstants.java b/media/java/android/mtp/MtpConstants.java
index 0dcc718..5bbf2ec 100644
--- a/media/java/android/mtp/MtpConstants.java
+++ b/media/java/android/mtp/MtpConstants.java
@@ -583,41 +583,41 @@
      */
     public static final int ASSOCIATION_TYPE_GENERIC_FOLDER = 0x0001;
 
-    /** Event code for UNDEFINED event */
+    /** @removed */
     public static final int EVENT_UNDEFINED = 0x4000;
-    /** Event code for CANCEL_TRANSACTION event */
+    /** @removed */
     public static final int EVENT_CANCEL_TRANSACTION = 0x4001;
-    /** Event code for OBJECT_ADDED event */
+    /** @removed */
     public static final int EVENT_OBJECT_ADDED = 0x4002;
-    /** Event code for OBJECT_REMOVED event */
+    /** @removed */
     public static final int EVENT_OBJECT_REMOVED = 0x4003;
-    /** Event code for STORE_ADDED event */
+    /** @removed */
     public static final int EVENT_STORE_ADDED = 0x4004;
-    /** Event code for STORE_REMOVED event */
+    /** @removed */
     public static final int EVENT_STORE_REMOVED = 0x4005;
-    /** Event code for DEVICE_PROP_CHANGED event */
+    /** @removed */
     public static final int EVENT_DEVICE_PROP_CHANGED = 0x4006;
-    /** Event code for OBJECT_INFO_CHANGED event */
+    /** @removed */
     public static final int EVENT_OBJECT_INFO_CHANGED = 0x4007;
-    /** Event code for DEVICE_INFO_CHANGED event */
+    /** @removed */
     public static final int EVENT_DEVICE_INFO_CHANGED = 0x4008;
-    /** Event code for REQUEST_OBJECT_TRANSFER event */
+    /** @removed */
     public static final int EVENT_REQUEST_OBJECT_TRANSFER = 0x4009;
-    /** Event code for STORE_FULL event */
+    /** @removed */
     public static final int EVENT_STORE_FULL = 0x400A;
-    /** Event code for DEVICE_RESET event */
+    /** @removed */
     public static final int EVENT_DEVICE_RESET = 0x400B;
-    /** Event code for STORAGE_INFO_CHANGED event */
+    /** @removed */
     public static final int EVENT_STORAGE_INFO_CHANGED = 0x400C;
-    /** Event code for CAPTURE_COMPLETE event */
+    /** @removed */
     public static final int EVENT_CAPTURE_COMPLETE = 0x400D;
-    /** Event code for UNREPORTED_STATUS event */
+    /** @removed */
     public static final int EVENT_UNREPORTED_STATUS = 0x400E;
-    /** Event code for OBJECT_PROP_CHANGED event */
+    /** @removed */
     public static final int EVENT_OBJECT_PROP_CHANGED = 0xC801;
-    /** Event code for OBJECT_PROP_DESC_CHANGED event */
+    /** @removed */
     public static final int EVENT_OBJECT_PROP_DESC_CHANGED = 0xC802;
-    /** Event code for OBJECT_REFERENCES_CHANGED event */
+    /** @removed */
     public static final int EVENT_OBJECT_REFERENCES_CHANGED = 0xC803;
 
     /** Operation code for GetDeviceInfo */
diff --git a/media/java/android/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java
index d0ef37c..4082778 100644
--- a/media/java/android/mtp/MtpDevice.java
+++ b/media/java/android/mtp/MtpDevice.java
@@ -16,6 +16,8 @@
 
 package android.mtp;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.hardware.usb.UsbDevice;
 import android.hardware.usb.UsbDeviceConnection;
 import android.os.CancellationSignal;
@@ -169,8 +171,8 @@
      * @param objectHandle handle of the object to read
      * @param offset Start index of reading range. It must be a non-negative value at most
      *     0xffffffff.
-     * @param size Size of reading range. It must be a non-negative value at most 0xffffffff. If
-     *     0xffffffff is specified, the method obtains the full bytes of object.
+     * @param size Size of reading range. It must be a non-negative value at most Integer.MAX_VALUE
+     *     or 0xffffffff. If 0xffffffff is specified, the method obtains the full bytes of object.
      * @param buffer Array to write data.
      * @return Size of bytes that are actually read.
      */
@@ -190,7 +192,7 @@
      *
      * @param objectHandle handle of the object to read
      * @param offset Start index of reading range. It must be a non-negative value.
-     * @param size Size of reading range. It must be a non-negative value at most 0xffffffff.
+     * @param size Size of reading range. It must be a non-negative value at most Integer.MAX_VALUE.
      * @param buffer Array to write data.
      * @return Size of bytes that are actually read.
      * @see MtpConstants#OPERATION_GET_PARTIAL_OBJECT_64
@@ -317,7 +319,7 @@
      * The returned {@link MtpObjectInfo} has the new object handle field filled in.
      *
      * @param info metadata of the entry
-     * @return object info of the created entry
+     * @return object info of the created entry or null if the operation failed.
      */
     public MtpObjectInfo sendObjectInfo(MtpObjectInfo info) {
         return native_send_object_info(info);
@@ -329,13 +331,11 @@
      *
      * @param signal signal for cancellation
      * @return obtained event
+     * @throws IOException
      */
-    public MtpEvent readEvent(CancellationSignal signal) {
+    public @NonNull MtpEvent readEvent(@Nullable CancellationSignal signal) throws IOException {
         final int handle = native_submit_event_request();
-
-        if (handle < 0) {
-            throw new IllegalStateException("Other thread is reading an event.");
-        }
+        Preconditions.checkState(handle >= 0, "Other thread is reading an event.");
 
         if (signal != null) {
             signal.setOnCancelListener(new CancellationSignal.OnCancelListener() {
@@ -391,8 +391,8 @@
     private native boolean native_import_file(int objectHandle, int fd);
     private native boolean native_send_object(int objectHandle, long size, int fd);
     private native MtpObjectInfo native_send_object_info(MtpObjectInfo info);
-    private native int native_submit_event_request();
-    private native MtpEvent native_reap_event_request(int handle);
+    private native int native_submit_event_request() throws IOException;
+    private native MtpEvent native_reap_event_request(int handle) throws IOException;
     private native void native_discard_event_request(int handle);
     private native long native_get_object_size_long(int handle, int format) throws IOException;
 }
diff --git a/media/java/android/mtp/MtpDeviceInfo.java b/media/java/android/mtp/MtpDeviceInfo.java
index 2e4f451..86bd599 100644
--- a/media/java/android/mtp/MtpDeviceInfo.java
+++ b/media/java/android/mtp/MtpDeviceInfo.java
@@ -16,8 +16,6 @@
 
 package android.mtp;
 
-import android.annotation.Nullable;
-
 /**
  * This class encapsulates information about an MTP device.
  * This corresponds to the DeviceInfo Dataset described in
@@ -112,7 +110,7 @@
      * @see MtpConstants#OPERATION_SET_OBJECT_REFERENCES
      * @see MtpConstants#OPERATION_SKIP
      */
-    public final @Nullable int[] getOperationsSupported() {
+    public final int[] getOperationsSupported() {
         return mOperationsSupported;
     }
 
@@ -120,26 +118,57 @@
      * Returns event code supported by the device.
      *
      * @return supported event code. Can be null if device does not provide the property.
-     * @see MtpConstants#EVENT_UNDEFINED
-     * @see MtpConstants#EVENT_CANCEL_TRANSACTION
-     * @see MtpConstants#EVENT_OBJECT_ADDED
-     * @see MtpConstants#EVENT_OBJECT_REMOVED
-     * @see MtpConstants#EVENT_STORE_ADDED
-     * @see MtpConstants#EVENT_STORE_REMOVED
-     * @see MtpConstants#EVENT_DEVICE_PROP_CHANGED
-     * @see MtpConstants#EVENT_OBJECT_INFO_CHANGED
-     * @see MtpConstants#EVENT_DEVICE_INFO_CHANGED
-     * @see MtpConstants#EVENT_REQUEST_OBJECT_TRANSFER
-     * @see MtpConstants#EVENT_STORE_FULL
-     * @see MtpConstants#EVENT_DEVICE_RESET
-     * @see MtpConstants#EVENT_STORAGE_INFO_CHANGED
-     * @see MtpConstants#EVENT_CAPTURE_COMPLETE
-     * @see MtpConstants#EVENT_UNREPORTED_STATUS
-     * @see MtpConstants#EVENT_OBJECT_PROP_CHANGED
-     * @see MtpConstants#EVENT_OBJECT_PROP_DESC_CHANGED
-     * @see MtpConstants#EVENT_OBJECT_REFERENCES_CHANGED
+     * @see MtpEvent#EVENT_UNDEFINED
+     * @see MtpEvent#EVENT_CANCEL_TRANSACTION
+     * @see MtpEvent#EVENT_OBJECT_ADDED
+     * @see MtpEvent#EVENT_OBJECT_REMOVED
+     * @see MtpEvent#EVENT_STORE_ADDED
+     * @see MtpEvent#EVENT_STORE_REMOVED
+     * @see MtpEvent#EVENT_DEVICE_PROP_CHANGED
+     * @see MtpEvent#EVENT_OBJECT_INFO_CHANGED
+     * @see MtpEvent#EVENT_DEVICE_INFO_CHANGED
+     * @see MtpEvent#EVENT_REQUEST_OBJECT_TRANSFER
+     * @see MtpEvent#EVENT_STORE_FULL
+     * @see MtpEvent#EVENT_DEVICE_RESET
+     * @see MtpEvent#EVENT_STORAGE_INFO_CHANGED
+     * @see MtpEvent#EVENT_CAPTURE_COMPLETE
+     * @see MtpEvent#EVENT_UNREPORTED_STATUS
+     * @see MtpEvent#EVENT_OBJECT_PROP_CHANGED
+     * @see MtpEvent#EVENT_OBJECT_PROP_DESC_CHANGED
+     * @see MtpEvent#EVENT_OBJECT_REFERENCES_CHANGED
      */
-    public final @Nullable int[] getEventsSupported() {
+    public final int[] getEventsSupported() {
         return mEventsSupported;
     }
+
+    /**
+     * Returns if the given operation is supported by the device or not.
+     * @param code Operation code.
+     * @return If the given operation is supported by the device or not.
+     */
+    public boolean isOperationSupported(int code) {
+        return isSupported(mOperationsSupported, code);
+    }
+
+    /**
+     * Returns if the given event is supported by the device or not.
+     * @param code Event code.
+     * @return If the given event is supported by the device or not.
+     */
+    public boolean isEventSupported(int code) {
+        return isSupported(mEventsSupported, code);
+    }
+
+    /**
+     * Returns if the code set contains code.
+     * @hide
+     */
+    private static boolean isSupported(int[] set, int code) {
+        for (final int element : set) {
+            if (element == code) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/media/java/android/mtp/MtpEvent.java b/media/java/android/mtp/MtpEvent.java
index dc89a56..9ca00e1 100644
--- a/media/java/android/mtp/MtpEvent.java
+++ b/media/java/android/mtp/MtpEvent.java
@@ -21,7 +21,44 @@
  * This corresponds to the events described in appendix G of the MTP specification.
  */
 public class MtpEvent {
-    private int mEventCode = MtpConstants.EVENT_UNDEFINED;
+    /** Event code for UNDEFINED event */
+    public static final int EVENT_UNDEFINED = 0x4000;
+    /** Event code for CANCEL_TRANSACTION event */
+    public static final int EVENT_CANCEL_TRANSACTION = 0x4001;
+    /** Event code for OBJECT_ADDED event */
+    public static final int EVENT_OBJECT_ADDED = 0x4002;
+    /** Event code for OBJECT_REMOVED event */
+    public static final int EVENT_OBJECT_REMOVED = 0x4003;
+    /** Event code for STORE_ADDED event */
+    public static final int EVENT_STORE_ADDED = 0x4004;
+    /** Event code for STORE_REMOVED event */
+    public static final int EVENT_STORE_REMOVED = 0x4005;
+    /** Event code for DEVICE_PROP_CHANGED event */
+    public static final int EVENT_DEVICE_PROP_CHANGED = 0x4006;
+    /** Event code for OBJECT_INFO_CHANGED event */
+    public static final int EVENT_OBJECT_INFO_CHANGED = 0x4007;
+    /** Event code for DEVICE_INFO_CHANGED event */
+    public static final int EVENT_DEVICE_INFO_CHANGED = 0x4008;
+    /** Event code for REQUEST_OBJECT_TRANSFER event */
+    public static final int EVENT_REQUEST_OBJECT_TRANSFER = 0x4009;
+    /** Event code for STORE_FULL event */
+    public static final int EVENT_STORE_FULL = 0x400A;
+    /** Event code for DEVICE_RESET event */
+    public static final int EVENT_DEVICE_RESET = 0x400B;
+    /** Event code for STORAGE_INFO_CHANGED event */
+    public static final int EVENT_STORAGE_INFO_CHANGED = 0x400C;
+    /** Event code for CAPTURE_COMPLETE event */
+    public static final int EVENT_CAPTURE_COMPLETE = 0x400D;
+    /** Event code for UNREPORTED_STATUS event */
+    public static final int EVENT_UNREPORTED_STATUS = 0x400E;
+    /** Event code for OBJECT_PROP_CHANGED event */
+    public static final int EVENT_OBJECT_PROP_CHANGED = 0xC801;
+    /** Event code for OBJECT_PROP_DESC_CHANGED event */
+    public static final int EVENT_OBJECT_PROP_DESC_CHANGED = 0xC802;
+    /** Event code for OBJECT_REFERENCES_CHANGED event */
+    public static final int EVENT_OBJECT_REFERENCES_CHANGED = 0xC803;
+
+    private int mEventCode = EVENT_UNDEFINED;
 
     // Parameters for event. The interpretation of event parameters depends upon mEventCode.
     private int mParameter1;
@@ -29,6 +66,11 @@
     private int mParameter3;
 
     /**
+     * MtpEvent is instantiated by JNI.
+     */
+    private MtpEvent() {}
+
+    /**
      * Returns event code of MTP event.
      * See the USB-IF MTP specification for the details of event constants.
      * @return event code
@@ -53,26 +95,26 @@
     /**
      * Obtains objectHandle event parameter.
      *
-     * @see MtpConstants#EVENT_OBJECT_ADDED
-     * @see MtpConstants#EVENT_OBJECT_REMOVED
-     * @see MtpConstants#EVENT_OBJECT_INFO_CHANGED
-     * @see MtpConstants#EVENT_REQUEST_OBJECT_TRANSFER
-     * @see MtpConstants#EVENT_OBJECT_PROP_CHANGED
-     * @see MtpConstants#EVENT_OBJECT_REFERENCES_CHANGED
+     * @see #EVENT_OBJECT_ADDED
+     * @see #EVENT_OBJECT_REMOVED
+     * @see #EVENT_OBJECT_INFO_CHANGED
+     * @see #EVENT_REQUEST_OBJECT_TRANSFER
+     * @see #EVENT_OBJECT_PROP_CHANGED
+     * @see #EVENT_OBJECT_REFERENCES_CHANGED
      */
     public int getObjectHandle() {
         switch (mEventCode) {
-            case MtpConstants.EVENT_OBJECT_ADDED:
+            case EVENT_OBJECT_ADDED:
                 return mParameter1;
-            case MtpConstants.EVENT_OBJECT_REMOVED:
+            case EVENT_OBJECT_REMOVED:
                 return mParameter1;
-            case MtpConstants.EVENT_OBJECT_INFO_CHANGED:
+            case EVENT_OBJECT_INFO_CHANGED:
                 return mParameter1;
-            case MtpConstants.EVENT_REQUEST_OBJECT_TRANSFER:
+            case EVENT_REQUEST_OBJECT_TRANSFER:
                 return mParameter1;
-            case MtpConstants.EVENT_OBJECT_PROP_CHANGED:
+            case EVENT_OBJECT_PROP_CHANGED:
                 return mParameter1;
-            case MtpConstants.EVENT_OBJECT_REFERENCES_CHANGED:
+            case EVENT_OBJECT_REFERENCES_CHANGED:
                 return mParameter1;
             default:
                 throw new IllegalParameterAccess("objectHandle", mEventCode);
@@ -82,20 +124,20 @@
     /**
      * Obtains storageID event parameter.
      *
-     * @see MtpConstants#EVENT_STORE_ADDED
-     * @see MtpConstants#EVENT_STORE_REMOVED
-     * @see MtpConstants#EVENT_STORE_FULL
-     * @see MtpConstants#EVENT_STORAGE_INFO_CHANGED
+     * @see #EVENT_STORE_ADDED
+     * @see #EVENT_STORE_REMOVED
+     * @see #EVENT_STORE_FULL
+     * @see #EVENT_STORAGE_INFO_CHANGED
      */
     public int getStorageId() {
         switch (mEventCode) {
-            case MtpConstants.EVENT_STORE_ADDED:
+            case EVENT_STORE_ADDED:
                 return mParameter1;
-            case MtpConstants.EVENT_STORE_REMOVED:
+            case EVENT_STORE_REMOVED:
                 return mParameter1;
-            case MtpConstants.EVENT_STORE_FULL:
+            case EVENT_STORE_FULL:
                 return mParameter1;
-            case MtpConstants.EVENT_STORAGE_INFO_CHANGED:
+            case EVENT_STORAGE_INFO_CHANGED:
                 return mParameter1;
             default:
                 throw new IllegalParameterAccess("storageID", mEventCode);
@@ -105,11 +147,11 @@
     /**
      * Obtains devicePropCode event parameter.
      *
-     * @see MtpConstants#EVENT_DEVICE_PROP_CHANGED
+     * @see #EVENT_DEVICE_PROP_CHANGED
      */
     public int getDevicePropCode() {
         switch (mEventCode) {
-            case MtpConstants.EVENT_DEVICE_PROP_CHANGED:
+            case EVENT_DEVICE_PROP_CHANGED:
                 return mParameter1;
             default:
                 throw new IllegalParameterAccess("devicePropCode", mEventCode);
@@ -119,11 +161,11 @@
     /**
      * Obtains transactionID event parameter.
      *
-     * @see MtpConstants#EVENT_CAPTURE_COMPLETE
+     * @see #EVENT_CAPTURE_COMPLETE
      */
     public int getTransactionId() {
         switch (mEventCode) {
-            case MtpConstants.EVENT_CAPTURE_COMPLETE:
+            case EVENT_CAPTURE_COMPLETE:
                 return mParameter1;
             default:
                 throw new IllegalParameterAccess("transactionID", mEventCode);
@@ -133,14 +175,14 @@
     /**
      * Obtains objectPropCode event parameter.
      *
-     * @see MtpConstants#EVENT_OBJECT_PROP_CHANGED
-     * @see MtpConstants#EVENT_OBJECT_PROP_DESC_CHANGED
+     * @see #EVENT_OBJECT_PROP_CHANGED
+     * @see #EVENT_OBJECT_PROP_DESC_CHANGED
      */
     public int getObjectPropCode() {
         switch (mEventCode) {
-            case MtpConstants.EVENT_OBJECT_PROP_CHANGED:
+            case EVENT_OBJECT_PROP_CHANGED:
                 return mParameter2;
-            case MtpConstants.EVENT_OBJECT_PROP_DESC_CHANGED:
+            case EVENT_OBJECT_PROP_DESC_CHANGED:
                 return mParameter1;
             default:
                 throw new IllegalParameterAccess("objectPropCode", mEventCode);
@@ -150,11 +192,11 @@
     /**
      * Obtains objectFormatCode event parameter.
      *
-     * @see MtpConstants#EVENT_OBJECT_PROP_DESC_CHANGED
+     * @see #EVENT_OBJECT_PROP_DESC_CHANGED
      */
     public int getObjectFormatCode() {
         switch (mEventCode) {
-            case MtpConstants.EVENT_OBJECT_PROP_DESC_CHANGED:
+            case EVENT_OBJECT_PROP_DESC_CHANGED:
                 return mParameter2;
             default:
                 throw new IllegalParameterAccess("objectFormatCode", mEventCode);
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index 6e434b2..1faa0c4 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -244,7 +244,8 @@
     if (deviceInfo->mSerial)
         env->SetObjectField(info, field_deviceInfo_serialNumber,
             env->NewStringUTF(deviceInfo->mSerial));
-    if (deviceInfo->mOperations) {
+    assert(deviceInfo->mOperations);
+    {
         const size_t size = deviceInfo->mOperations->size();
         ScopedLocalRef<jintArray> operations(env, static_cast<jintArray>(env->NewIntArray(size)));
         {
@@ -259,7 +260,8 @@
             env->SetObjectField(info, field_deviceInfo_operationsSupported, operations.get());
         }
     }
-    if (deviceInfo->mEvents) {
+    assert(deviceInfo->mEvents);
+    {
         const size_t size = deviceInfo->mEvents->size();
         ScopedLocalRef<jintArray> events(env, static_cast<jintArray>(env->NewIntArray(size)));
         {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 297fbc7..b67f6a2 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -1174,8 +1174,10 @@
             view.setOnDragListener(mOnDragListener);
         }
 
-        // Make all items draggable.
-        view.setOnLongClickListener(onLongClickListener);
+        if (mTuner.allowDragNDrop()) {
+            // Make all items draggable.
+            view.setOnLongClickListener(onLongClickListener);
+        }
     }
 
     private View.OnDragListener mOnDragListener = new View.OnDragListener() {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
index 32fdb64..9e2b86a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
@@ -82,6 +82,11 @@
     abstract boolean enableManagedMode();
 
     /**
+     * Whether drag n' drop is allowed in this context
+     */
+    abstract boolean allowDragNDrop();
+
+    /**
      * Provides support for Platform specific specializations of DirectoryFragment.
      */
     private static final class DocumentsTuner extends FragmentTuner {
@@ -191,6 +196,11 @@
         public boolean enableManagedMode() {
             return false;
         }
+
+        @Override
+        public boolean allowDragNDrop() {
+            return false;
+        }
     }
 
     /**
@@ -255,6 +265,11 @@
                     && mState.stack.root.isDownloads()
                     && mState.stack.size() == 1;
         }
+
+        @Override
+        public boolean allowDragNDrop() {
+            return true;
+        }
     }
 
     private static boolean isDirectory(String mimeType) {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
index 9b1ab0e..ae4519e 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
@@ -497,6 +497,20 @@
         }
     }
 
+    /**
+     * Notify all interested parties that a print job has been updated.
+     *
+     * @param printJob The updated print job.
+     */
+    private void notifyPrintJobUpdated(PrintJobInfo printJob) {
+        Message message = mHandlerCaller.obtainMessageO(
+                HandlerCallerCallback.MSG_ON_PRINT_JOB_STATE_CHANGED,
+                printJob);
+        mHandlerCaller.executeOrSendMessage(message);
+
+        mNotificationController.onUpdateNotifications(mPrintJobs);
+    }
+
     public boolean setPrintJobState(PrintJobId printJobId, int state, String error) {
         boolean success = false;
 
@@ -549,12 +563,7 @@
                     notifyOnAllPrintJobsHandled();
                 }
 
-                Message message = mHandlerCaller.obtainMessageO(
-                        HandlerCallerCallback.MSG_ON_PRINT_JOB_STATE_CHANGED,
-                        printJob);
-                mHandlerCaller.executeOrSendMessage(message);
-
-                mNotificationController.onUpdateNotifications(mPrintJobs);
+                notifyPrintJobUpdated(printJob);
             }
         }
 
@@ -584,9 +593,12 @@
      */
     public void setStatus(@NonNull PrintJobId printJobId, @Nullable CharSequence status) {
         synchronized (mLock) {
-            getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY).setStatus(status);
+            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
 
-            mNotificationController.onUpdateNotifications(mPrintJobs);
+            if (printJob != null) {
+                printJob.setStatus(status);
+                notifyPrintJobUpdated(printJob);
+            }
         }
     }
 
@@ -600,9 +612,12 @@
     public void setStatus(@NonNull PrintJobId printJobId, @StringRes int status,
             @Nullable CharSequence appPackageName) {
         synchronized (mLock) {
-            getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY).setStatus(status, appPackageName);
+            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
 
-            mNotificationController.onUpdateNotifications(mPrintJobs);
+            if (printJob != null) {
+                printJob.setStatus(status, appPackageName);
+                notifyPrintJobUpdated(printJob);
+            }
         }
     }
 
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index c248adf..70c8957 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -508,6 +508,7 @@
         <receiver
             android:name=".statusbar.KeyboardShortcutsReceiver">
             <intent-filter>
+                <action android:name="android.intent.action.DISMISS_KEYBOARD_SHORTCUTS" />
                 <action android:name="android.intent.action.SHOW_KEYBOARD_SHORTCUTS" />
             </intent-filter>
         </receiver>
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index ef15195..751f181 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -20,7 +20,8 @@
         android:layout_height="wrap_content"
         android:background="@drawable/qs_background_primary"
         android:clipToPadding="false"
-        android:clipChildren="false">
+        android:clipChildren="false"
+        android:elevation="4dp">
 
     <com.android.systemui.qs.QSPanel
             android:id="@+id/quick_settings_panel"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 981b2dd..f6c3dd4 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -286,6 +286,9 @@
     <!-- Content description of the bluetooth label showing what we are connected to. [CHAR LIMIT=NONE] -->
     <string name="accessibility_bluetooth_name">Connected to <xliff:g id="bluetooth" example="Car Audio">%s</xliff:g>.</string>
 
+    <!-- Content description of the cast label showing what we are connected to. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_cast_name">Connected to <xliff:g id="cast" example="TV">%s</xliff:g>.</string>
+
 
     <!-- Content description of the WiMAX signal when no signal for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_no_wimax">No WiMAX.</string>
@@ -363,6 +366,12 @@
     <!-- Content description of the data connection with no SIM for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_no_sim">No SIM.</string>
 
+    <!-- Content description of the cell data. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_cell_data">Cellular Data</string>
+
+    <!-- Content description of the cell data being enabled. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_cell_data_on">Cellular Data On</string>
+
     <!-- Content description of the cell data being disabled. [CHAR LIMIT=NONE] -->
     <string name="accessibility_cell_data_off">Cellular Data Off</string>
 
@@ -378,6 +387,9 @@
     <!-- Content description of the carrier network changing icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_carrier_network_change_mode">Carrier network changing.</string>
 
+    <!-- Content description of button to open battery details icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_battery_details">Open battery details</string>
+
     <!-- Content description of the battery level icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_battery_level">Battery <xliff:g id="number">%d</xliff:g> percent.</string>
 
@@ -468,12 +480,16 @@
     <string name="accessibility_quick_settings_dnd_none_on">Do not disturb on, total silence.</string>
     <!-- Content description of the do not disturb tile in quick settings when on in alarms only (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_dnd_alarms_on">Do not disturb on, alarms only.</string>
+     <!-- Content description of the do not disturb tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_dnd">Do not disturb.</string>
      <!-- Content description of the do not disturb tile in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_dnd_off">Do not disturb off.</string>
     <!-- Announcement made when do not disturb changes to off (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_dnd_changed_off">Do not disturb turned off.</string>
     <!-- Announcement made when do not disturb changes to on (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_dnd_changed_on">Do not disturb turned on.</string>
+    <!-- Content description of the bluetooth tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_bluetooth">Bluetooth.</string>
     <!-- Content description of the bluetooth tile in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_bluetooth_off">Bluetooth off.</string>
     <!-- Content description of the bluetooth tile in quick settings when on (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -633,6 +649,10 @@
     <string name="quick_settings_brightness_label">Brightness</string>
     <!-- QuickSettings: Rotation Unlocked [CHAR LIMIT=NONE] -->
     <string name="quick_settings_rotation_unlocked_label">Auto-rotate</string>
+    <!-- Accessibility label for Auto-ratate QuickSettings tile [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_rotation">Auto-rotate screen</string>
+    <!-- Accessibility label for value of Auto-ratate QuickSettings tile [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_rotation_value">Set to <xliff:g name="rotation" example="Portrait">%s</xliff:g></string>
     <!-- QuickSettings: Rotation Locked [CHAR LIMIT=NONE] -->
     <string name="quick_settings_rotation_locked_label">Rotation locked</string>
     <!-- QuickSettings: Locked to Portrait [CHAR LIMIT=NONE] -->
@@ -669,6 +689,8 @@
     <string name="quick_settings_wifi_no_network">No Network</string>
     <!-- QuickSettings: Wifi (Off) [CHAR LIMIT=NONE] -->
     <string name="quick_settings_wifi_off_label">Wi-Fi Off</string>
+    <!-- QuickSettings: Wifi (On) [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_wifi_on_label">Wi-Fi On</string>
     <!-- QuickSettings: Wifi detail panel, text when there are no items [CHAR LIMIT=NONE] -->
     <string name="quick_settings_wifi_detail_empty_text">No Wi-Fi networks available</string>
     <!-- QuickSettings: Cast title [CHAR LIMIT=NONE] -->
@@ -1089,6 +1111,9 @@
     <string name="volume_stream_content_description_vibrate">%1$s. Tap to set to vibrate. Accessibility services may be muted.</string>
     <string name="volume_stream_content_description_mute">%1$s. Tap to mute. Accessibility services may be muted.</string>
 
+    <string name="volume_dialog_accessibility_shown_message">%s volume controls shown. Swipe up to dismiss.</string>
+    <string name="volume_dialog_accessibility_dismissed_message">Volume controls hidden</string>
+
     <!-- Name of special SystemUI debug settings -->
     <string name="system_ui_tuner">System UI Tuner</string>
 
@@ -1638,8 +1663,32 @@
     <!-- Warning message when we try to dock a non-resizeble tasks and launch it in fullscreen instead. -->
     <string name="dock_non_resizeble_failed_to_dock_text">App does not support split-screen.</string>
 
+    <!-- accessibility label for button to open settings [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_settings">Open settings.</string>
+
     <!-- accessibility label for button to expand quick settings [CHAR LIMIT=NONE] -->
-    <string name="accessibility_quick_settings_expand">Expand quick settings.</string>
+    <string name="accessibility_quick_settings_expand">Open quick settings.</string>
+
+    <!-- accessibility label for button to collapse quick settings [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_collapse">Close quick settings.</string>
+
+    <!-- accessibility label for alarm icon [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_alarm_set">Alarm set.</string>
+
+    <!-- accessibility label for button to select user [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_user">Signed in as <xliff:g name="user" example="John">%s</xliff:g></string>
+
+    <!-- accessibility label for no internet [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_no_internet">No internet.</string>
+
+    <!-- accessibility label for quick settings items that open a details page [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_open_details">Open details.</string>
+
+    <!-- accessibility label for quick settings items that open a details page [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_open_settings">Open <xliff:g name="page" example="Bluetooth">%s</xliff:g> settings.</string>
+
+    <!-- accessibility label for button to edit quick settings [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_edit">Edit order of settings.</string>
 
     <!-- accessibility label for paging indicator in quick settings [CHAR LIMITi=NONE] -->
     <string name="accessibility_quick_settings_page">Page <xliff:g name="current_page" example="1">%1$d</xliff:g> of <xliff:g name="num_pages" example="2">%2$d</xliff:g></string>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index 9bc85c8..fb76918 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -54,7 +54,7 @@
         // TODO: Live?
     }
 
-    private void addSystemTiles(QSTileHost host) {
+    private void addSystemTiles(final QSTileHost host) {
         String possible = mContext.getString(R.string.quick_settings_tiles_default)
                 + ",hotspot,inversion,saver,work,cast,night";
         String[] possibleTiles = possible.split(",");
@@ -93,7 +93,7 @@
                 mainHandler.post(new Runnable() {
                     @Override
                     public void run() {
-                        new QueryTilesTask().execute();
+                        new QueryTilesTask().execute(host.getTiles());
                     }
                 });
             }
@@ -133,9 +133,10 @@
         public boolean isSystem;
     }
 
-    private class QueryTilesTask extends AsyncTask<Void, Void, Collection<TileInfo>> {
+    private class QueryTilesTask extends
+            AsyncTask<Collection<QSTile<?>>, Void, Collection<TileInfo>> {
         @Override
-        protected Collection<TileInfo> doInBackground(Void... params) {
+        protected Collection<TileInfo> doInBackground(Collection<QSTile<?>>... params) {
             List<TileInfo> tiles = new ArrayList<>();
             PackageManager pm = mContext.getPackageManager();
             List<ResolveInfo> services = pm.queryIntentServicesAsUser(
@@ -143,7 +144,13 @@
             for (ResolveInfo info : services) {
                 String packageName = info.serviceInfo.packageName;
                 ComponentName componentName = new ComponentName(packageName, info.serviceInfo.name);
+                final CharSequence appLabel = info.serviceInfo.applicationInfo.loadLabel(pm);
                 String spec = CustomTile.toSpec(componentName);
+                State state = getState(params[0], spec);
+                if (state != null) {
+                    addTile(spec, appLabel, state, false);
+                    continue;
+                }
                 if (info.serviceInfo.icon == 0) {
                     continue;
                 }
@@ -157,12 +164,22 @@
                 icon.mutate();
                 icon.setTint(mContext.getColor(android.R.color.white));
                 CharSequence label = info.serviceInfo.loadLabel(pm);
-                final CharSequence appLabel = info.serviceInfo.applicationInfo.loadLabel(pm);
                 addTile(spec, icon, label != null ? label.toString() : "null", appLabel, mContext);
             }
             return tiles;
         }
 
+        private State getState(Collection<QSTile<?>> tiles, String spec) {
+            for (QSTile<?> tile : tiles) {
+                if (spec.equals(tile.getTileSpec())) {
+                    final QSTile.State state = tile.newTileState();
+                    tile.getState().copyTo(state);
+                    return state;
+                }
+            }
+            return null;
+        }
+
         @Override
         protected void onPostExecute(Collection<TileInfo> result) {
             mTiles.addAll(result);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 630cb66..e117bfe 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -423,25 +423,26 @@
 
         int currentUser = sSystemServicesProxy.getCurrentUser();
         SystemServicesProxy ssp = Recents.getSystemServices();
-        ActivityManager.RunningTaskInfo topTask = ssp.getTopMostTask();
+        ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
         boolean screenPinningActive = ssp.isScreenPinningActive();
-        boolean isTopTaskHome = topTask != null && SystemServicesProxy.isHomeStack(topTask.stackId);
-        if (topTask != null && !isTopTaskHome && !screenPinningActive) {
-            logDockAttempt(mContext, topTask.topActivity, topTask.resizeMode);
-            if (topTask.isDockable) {
+        boolean isRunningTaskInHomeStack = runningTask != null &&
+                SystemServicesProxy.isHomeStack(runningTask.stackId);
+        if (runningTask != null && !isRunningTaskInHomeStack && !screenPinningActive) {
+            logDockAttempt(mContext, runningTask.topActivity, runningTask.resizeMode);
+            if (runningTask.isDockable) {
                 if (metricsDockAction != -1) {
                     MetricsLogger.action(mContext, metricsDockAction,
-                            topTask.topActivity.flattenToShortString());
+                            runningTask.topActivity.flattenToShortString());
                 }
                 if (sSystemServicesProxy.isSystemUser(currentUser)) {
-                    mImpl.dockTopTask(topTask.id, dragMode, stackCreateMode, initialBounds);
+                    mImpl.dockTopTask(runningTask.id, dragMode, stackCreateMode, initialBounds);
                 } else {
                     if (mSystemToUserCallbacks != null) {
                         IRecentsNonSystemUserCallbacks callbacks =
                                 mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
                         if (callbacks != null) {
                             try {
-                                callbacks.dockTopTask(topTask.id, dragMode, stackCreateMode,
+                                callbacks.dockTopTask(runningTask.id, dragMode, stackCreateMode,
                                         initialBounds);
                             } catch (RemoteException e) {
                                 Log.e(TAG, "Callback failed", e);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 2040833..e082f20 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -169,7 +169,7 @@
      */
     boolean dismissRecentsToFocusedTask(int logCategory) {
         SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
+        if (ssp.isRecentsActivityVisible()) {
             // If we have a focused Task, launch that Task now
             if (mRecentsView.launchFocusedTask(logCategory)) return true;
         }
@@ -181,7 +181,7 @@
      */
     boolean dismissRecentsToLaunchTargetTaskOrHome() {
         SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
+        if (ssp.isRecentsActivityVisible()) {
             // If we have a focused Task, launch that Task now
             if (mRecentsView.launchPreviousTask()) return true;
             // If none of the other cases apply, then just go Home
@@ -195,7 +195,7 @@
      */
     boolean dismissRecentsToFocusedTaskOrHome() {
         SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
+        if (ssp.isRecentsActivityVisible()) {
             // If we have a focused Task, launch that Task now
             if (mRecentsView.launchFocusedTask(0 /* logCategory */)) return true;
             // If none of the other cases apply, then just go Home
@@ -236,7 +236,7 @@
     /** Dismisses Recents directly to Home if we currently aren't transitioning. */
     boolean dismissRecentsToHomeIfVisible(boolean animated) {
         SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
+        if (ssp.isRecentsActivityVisible()) {
             // Return to Home
             dismissRecentsToHome(animated);
             return true;
@@ -448,7 +448,7 @@
         RecentsActivityLaunchState launchState = config.getLaunchState();
         RecentsTaskLoader loader = Recents.getTaskLoader();
         RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
-        loader.preloadTasks(loadPlan, -1 /* topTaskId */, false /* isTopTaskHome */);
+        loader.preloadTasks(loadPlan, -1 /* runningTaskId */, false /* isHomeStackVisible */);
 
         RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
         loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
@@ -777,6 +777,7 @@
     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
         super.dump(prefix, fd, writer, args);
         EventBus.getDefault().dump(prefix, writer);
+        Recents.getTaskLoader().dump(prefix, writer);
 
         String id = Integer.toHexString(System.identityHashCode(this));
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index f961390..e62c86e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -108,11 +108,11 @@
             if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
                 RecentsTaskLoader loader = Recents.getTaskLoader();
                 SystemServicesProxy ssp = Recents.getSystemServices();
-                ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getTopMostTask();
+                ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getRunningTask();
 
                 // Load the next task only if we aren't svelte
                 RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
-                loader.preloadTasks(plan, -1, true /* isTopTaskHome */);
+                loader.preloadTasks(plan, -1, true /* isHomeStackVisible */);
                 RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
                 // This callback is made when a new activity is launched and the old one is paused
                 // so ignore the current activity and try and preload the thumbnail for the
@@ -189,7 +189,7 @@
         // We can use a new plan since the caches will be the same.
         RecentsTaskLoader loader = Recents.getTaskLoader();
         RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
-        loader.preloadTasks(plan, -1, true /* isTopTaskHome */);
+        loader.preloadTasks(plan, -1, true /* isHomeStackVisible */);
         RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
         launchOpts.numVisibleTasks = loader.getIconCacheSize();
         launchOpts.numVisibleTaskThumbnails = loader.getThumbnailCacheSize();
@@ -262,10 +262,11 @@
         try {
             // Check if the top task is in the home stack, and start the recents activity
             SystemServicesProxy ssp = Recents.getSystemServices();
-            ActivityManager.RunningTaskInfo topTask = ssp.getTopMostTask();
-            MutableBoolean isTopTaskHome = new MutableBoolean(true);
-            if (topTask == null || !ssp.isRecentsTopMost(topTask, isTopTaskHome)) {
-                startRecentsActivity(topTask, isTopTaskHome.value || fromHome, animate, growTarget);
+            MutableBoolean isHomeStackVisible = new MutableBoolean(false);
+            if (!ssp.isRecentsActivityVisible(isHomeStackVisible)) {
+                ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
+                startRecentsActivity(runningTask, isHomeStackVisible.value || fromHome, animate,
+                        growTarget);
             }
         } catch (ActivityNotFoundException e) {
             Log.e(TAG, "Failed to launch RecentsActivity", e);
@@ -301,11 +302,10 @@
 
         try {
             SystemServicesProxy ssp = Recents.getSystemServices();
-            ActivityManager.RunningTaskInfo topTask = ssp.getTopMostTask();
-            MutableBoolean isTopTaskHome = new MutableBoolean(true);
+            MutableBoolean isHomeStackVisible = new MutableBoolean(true);
             long elapsedTime = SystemClock.elapsedRealtime() - mLastToggleTime;
 
-            if (topTask != null && ssp.isRecentsTopMost(topTask, isTopTaskHome)) {
+            if (ssp.isRecentsActivityVisible(isHomeStackVisible)) {
                 RecentsDebugFlags debugFlags = Recents.getDebugFlags();
                 RecentsConfiguration config = Recents.getConfiguration();
                 RecentsActivityLaunchState launchState = config.getLaunchState();
@@ -343,7 +343,9 @@
                 }
 
                 // Otherwise, start the recents activity
-                startRecentsActivity(topTask, isTopTaskHome.value, true /* animate */, growTarget);
+                ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
+                startRecentsActivity(runningTask, isHomeStackVisible.value, true /* animate */,
+                        growTarget);
 
                 // Only close the other system windows if we are actually showing recents
                 ssp.sendCloseSystemWindows(BaseStatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS);
@@ -358,18 +360,18 @@
         // Preload only the raw task list into a new load plan (which will be consumed by the
         // RecentsActivity) only if there is a task to animate to.
         SystemServicesProxy ssp = Recents.getSystemServices();
-        ActivityManager.RunningTaskInfo topTask = ssp.getTopMostTask();
-        MutableBoolean topTaskHome = new MutableBoolean(true);
-        if (topTask != null && !ssp.isRecentsTopMost(topTask, topTaskHome)) {
+        MutableBoolean isHomeStackVisible = new MutableBoolean(true);
+        if (!ssp.isRecentsActivityVisible(isHomeStackVisible)) {
+            ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
             RecentsTaskLoader loader = Recents.getTaskLoader();
             sInstanceLoadPlan = loader.createLoadPlan(mContext);
-            sInstanceLoadPlan.preloadRawTasks(topTaskHome.value);
-            loader.preloadTasks(sInstanceLoadPlan, topTask.id, topTaskHome.value);
+            sInstanceLoadPlan.preloadRawTasks(isHomeStackVisible.value);
+            loader.preloadTasks(sInstanceLoadPlan, runningTask.id, isHomeStackVisible.value);
             TaskStack stack = sInstanceLoadPlan.getTaskStack();
             if (stack.getTaskCount() > 0) {
                 // Only preload the icon (but not the thumbnail since it may not have been taken for
                 // the pausing activity)
-                preloadIcon(topTask);
+                preloadIcon(runningTask);
 
                 // At this point, we don't know anything about the stack state.  So only calculate
                 // the dimensions of the thumbnail that we need for the transition into Recents, but
@@ -398,25 +400,25 @@
         SystemServicesProxy ssp = Recents.getSystemServices();
         RecentsTaskLoader loader = Recents.getTaskLoader();
         RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
-        loader.preloadTasks(plan, -1, true /* isTopTaskHome */);
+        loader.preloadTasks(plan, -1, true /* isHomeStackVisible */);
         TaskStack focusedStack = plan.getTaskStack();
 
         // Return early if there are no tasks in the focused stack
         if (focusedStack == null || focusedStack.getTaskCount() == 0) return;
 
-        ActivityManager.RunningTaskInfo runningTask = ssp.getTopMostTask();
         // Return early if there is no running task
+        ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
         if (runningTask == null) return;
 
         // Find the task in the recents list
-        boolean isTopTaskHome = SystemServicesProxy.isHomeStack(runningTask.stackId);
+        boolean isRunningTaskInHomeStack = SystemServicesProxy.isHomeStack(runningTask.stackId);
         ArrayList<Task> tasks = focusedStack.getStackTasks();
         Task toTask = null;
         ActivityOptions launchOpts = null;
         int taskCount = tasks.size();
         for (int i = taskCount - 1; i >= 1; i--) {
             Task task = tasks.get(i);
-            if (isTopTaskHome) {
+            if (isRunningTaskInHomeStack) {
                 toTask = tasks.get(i - 1);
                 launchOpts = ActivityOptions.makeCustomAnimation(mContext,
                         R.anim.recents_launch_next_affiliated_task_target,
@@ -450,14 +452,14 @@
         SystemServicesProxy ssp = Recents.getSystemServices();
         RecentsTaskLoader loader = Recents.getTaskLoader();
         RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
-        loader.preloadTasks(plan, -1, true /* isTopTaskHome */);
+        loader.preloadTasks(plan, -1, true /* isHomeStackVisible */);
         TaskStack focusedStack = plan.getTaskStack();
 
         // Return early if there are no tasks in the focused stack
         if (focusedStack == null || focusedStack.getTaskCount() == 0) return;
 
-        ActivityManager.RunningTaskInfo runningTask = ssp.getTopMostTask();
         // Return early if there is no running task (can't determine affiliated tasks in this case)
+        ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
         if (runningTask == null) return;
         // Return early if the running task is in the home stack (optimization)
         if (SystemServicesProxy.isHomeStack(runningTask.stackId)) return;
@@ -693,9 +695,9 @@
      * Creates the activity options for an app->recents transition.
      */
     private ActivityOptions getThumbnailTransitionActivityOptions(
-            ActivityManager.RunningTaskInfo topTask, TaskStackView stackView,
-            Rect windowOverrideRect) {
-        if (topTask.stackId == FREEFORM_WORKSPACE_STACK_ID) {
+            ActivityManager.RunningTaskInfo runningTask, TaskStackView stackView,
+                    Rect windowOverrideRect) {
+        if (runningTask.stackId == FREEFORM_WORKSPACE_STACK_ID) {
             ArrayList<AppTransitionAnimationSpec> specs = new ArrayList<>();
             ArrayList<Task> tasks = stackView.getStack().getStackTasks();
             TaskStackLayoutAlgorithm stackLayout = stackView.getStackAlgorithm();
@@ -801,8 +803,8 @@
     /**
      * Shows the recents activity
      */
-    protected void startRecentsActivity(ActivityManager.RunningTaskInfo topTask,
-            boolean isTopTaskHome, boolean animate, int growTarget) {
+    protected void startRecentsActivity(ActivityManager.RunningTaskInfo runningTask,
+            boolean isHomeStackVisible, boolean animate, int growTarget) {
         RecentsTaskLoader loader = Recents.getTaskLoader();
         RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
 
@@ -814,24 +816,24 @@
             sInstanceLoadPlan = loader.createLoadPlan(mContext);
         }
         if (mLaunchedWhileDocking || mTriggeredFromAltTab || !sInstanceLoadPlan.hasTasks()) {
-            loader.preloadTasks(sInstanceLoadPlan, topTask.id, isTopTaskHome);
+            loader.preloadTasks(sInstanceLoadPlan, runningTask.id, isHomeStackVisible);
         }
 
         TaskStack stack = sInstanceLoadPlan.getTaskStack();
         boolean hasRecentTasks = stack.getTaskCount() > 0;
-        boolean useThumbnailTransition = (topTask != null) && !isTopTaskHome && hasRecentTasks;
+        boolean useThumbnailTransition = (runningTask != null) && !isHomeStackVisible && hasRecentTasks;
 
         // Update the launch state that we need in updateHeaderBarLayout()
         launchState.launchedFromHome = !useThumbnailTransition;
         launchState.launchedFromApp = useThumbnailTransition || mLaunchedWhileDocking;
         launchState.launchedViaDockGesture = mLaunchedWhileDocking;
         launchState.launchedViaDragGesture = mDraggingInRecents;
-        launchState.launchedToTaskId = (topTask != null) ? topTask.id : -1;
+        launchState.launchedToTaskId = (runningTask != null) ? runningTask.id : -1;
         launchState.launchedWithAltTab = mTriggeredFromAltTab;
 
         // Preload the icon (this will be a null-op if we have preloaded the icon already in
         // preloadRecents())
-        preloadIcon(topTask);
+        preloadIcon(runningTask);
 
         // Update the header bar if necessary
         Rect windowOverrideRect = getWindowRectOverride(growTarget);
@@ -853,7 +855,7 @@
         ActivityOptions opts;
         if (useThumbnailTransition) {
             // Try starting with a thumbnail transition
-            opts = getThumbnailTransitionActivityOptions(topTask, mDummyStackView,
+            opts = getThumbnailTransitionActivityOptions(runningTask, mDummyStackView,
                     windowOverrideRect);
         } else {
             // If there is no thumbnail transition, but is launching from home into recents, then
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 6f1a69c..be06ad0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -38,7 +38,6 @@
 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.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -251,9 +250,14 @@
         return sSystemServicesProxy;
     }
 
-    /** Returns a list of the recents tasks */
+    /**
+     * Returns a list of the recents tasks.
+     *
+     * @param isHomeStackVisible whether or not the home stack is currently visible.  If it is
+     *                           visible, then we ignore all excluded tasks (even the first one).
+     */
     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int numLatestTasks, int userId,
-            boolean isTopTaskHome, ArraySet<Integer> quietProfileIds) {
+            boolean isHomeStackVisible, ArraySet<Integer> quietProfileIds) {
         if (mAm == null) return null;
 
         // If we are mocking, then create some recent tasks
@@ -320,7 +324,7 @@
             boolean isBlackListed = sRecentsBlacklist.contains(t.realActivity.getClassName());
             // Filter out recent tasks from managed profiles which are in quiet mode.
             isExcluded |= quietProfileIds.contains(t.userId);
-            if (isBlackListed || (isExcluded && (isTopTaskHome || !isFirstValidTask))) {
+            if (isBlackListed || (isExcluded && (isHomeStackVisible || !isFirstValidTask))) {
                 iter.remove();
                 continue;
             }
@@ -330,15 +334,11 @@
         return tasks.subList(0, Math.min(tasks.size(), numLatestTasks));
     }
 
-    /** Returns a list of the running tasks */
-    private List<ActivityManager.RunningTaskInfo> getRunningTasks(int numTasks) {
-        if (mAm == null) return null;
-        return mAm.getRunningTasks(numTasks);
-    }
-
-    /** Returns the top task. */
-    public ActivityManager.RunningTaskInfo getTopMostTask() {
-        List<ActivityManager.RunningTaskInfo> tasks = getRunningTasks(1);
+    /**
+     * Returns the top running task.
+     */
+    public ActivityManager.RunningTaskInfo getRunningTask() {
+        List<ActivityManager.RunningTaskInfo> tasks = mAm.getRunningTasks(1);
         if (tasks != null && !tasks.isEmpty()) {
             return tasks.get(0);
         }
@@ -346,6 +346,39 @@
     }
 
     /**
+     * Returns whether the recents activity is currently visible.
+     */
+    public boolean isRecentsActivityVisible() {
+        return isRecentsActivityVisible(null);
+    }
+
+    /**
+     * Returns whether the recents activity is currently visible.
+     *
+     * @param isHomeStackVisible if provided, will return whether the home stack is visible
+     *                           regardless of the recents visibility
+     */
+    public boolean isRecentsActivityVisible(MutableBoolean isHomeStackVisible) {
+        if (mIam == null) return false;
+
+        try {
+            ActivityManager.StackInfo stackInfo = mIam.getStackInfo(
+                    ActivityManager.StackId.HOME_STACK_ID);
+            ComponentName topActivity = stackInfo.topActivity;
+            if (isHomeStackVisible != null) {
+                isHomeStackVisible.value = stackInfo.visible;
+            }
+            return (stackInfo.visible && topActivity != null
+                    && topActivity.getPackageName().equals(RecentsImpl.RECENTS_PACKAGE)
+                    && (topActivity.getClassName().equals(RecentsImpl.RECENTS_ACTIVITY)
+                        || topActivity.getClassName().equals(RecentsTvImpl.RECENTS_TV_ACTIVITY)));
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    /**
      * Returns whether this device has freeform workspaces.
      */
     public boolean hasFreeformWorkspaceSupport() {
@@ -359,56 +392,6 @@
         return mIsSafeMode;
     }
 
-    /** Returns whether the recents is currently running */
-    public boolean isRecentsTopMost(ActivityManager.RunningTaskInfo topTask,
-            MutableBoolean isHomeTopMost) {
-        if (topTask != null) {
-            ComponentName topActivity = topTask.topActivity;
-
-            // Check if the front most activity is recents
-            if ((topActivity.getPackageName().equals(RecentsImpl.RECENTS_PACKAGE) &&
-                    (topActivity.getClassName().equals(RecentsImpl.RECENTS_ACTIVITY) ||
-                    topActivity.getClassName().equals(RecentsTvImpl.RECENTS_TV_ACTIVITY)))) {
-                if (isHomeTopMost != null) {
-                    isHomeTopMost.value = false;
-                }
-                return true;
-            }
-
-            // Note, this is only valid because we currently only allow the recents and home
-            // activities in the home stack
-            if (isHomeTopMost != null) {
-                isHomeTopMost.value = SystemServicesProxy.isHomeStack(topTask.stackId);
-            }
-        }
-        return false;
-    }
-
-    /** Get the bounds of a task. */
-    public Rect getTaskBounds(int taskId) {
-        if (mIam == null) return null;
-
-        try {
-            return mIam.getTaskBounds(taskId);
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    /**
-     * Resizes the given task to the new bounds.
-     */
-    public void resizeTask(int taskId, Rect bounds) {
-        if (mIam == null) return;
-
-        try {
-            mIam.resizeTask(taskId, bounds, ActivityManager.RESIZE_MODE_FORCED);
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        }
-    }
-
     /** Docks a task to the side of the screen and starts it. */
     public void startTaskInDockedMode(int taskId, int createMode) {
         if (mIam == null) return;
@@ -439,18 +422,6 @@
         return false;
     }
 
-    /** Returns the focused stack id. */
-    public int getFocusedStack() {
-        if (mIam == null) return -1;
-
-        try {
-            return mIam.getFocusedStackId();
-        } catch (RemoteException e) {
-            e.printStackTrace();
-            return -1;
-        }
-    }
-
     /**
      * Returns whether the given stack id is the home stack id.
      */
@@ -516,6 +487,16 @@
     }
 
     /**
+     * Returns whether the device has a transposed nav bar (on the right of the screen) in the
+     * current display orientation.
+     */
+    public boolean hasTransposedNavigationBar() {
+        Rect insets = new Rect();
+        getStableInsets(insets);
+        return insets.right > 0;
+    }
+
+    /**
      * Cancels the current window transtion to/from Recents for the given task id.
      */
     public void cancelWindowTransition(int taskId) {
@@ -613,19 +594,6 @@
         }
     }
 
-    /** Moves a task to the front with the specified activity options. */
-    public void moveTaskToFront(int taskId, ActivityOptions opts) {
-        if (mAm == null) return;
-        if (RecentsDebugFlags.Static.EnableMockTasks) return;
-
-        if (opts != null) {
-            mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME,
-                    opts.toBundle());
-        } else {
-            mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME);
-        }
-    }
-
     /** Removes the task */
     public void removeTask(final int taskId) {
         if (mAm == null) return;
@@ -1082,16 +1050,6 @@
         }
     }
 
-    /**
-     * Returns whether the device has a transposed nav bar (on the right of the screen) in the
-     * current display orientation.
-     */
-    public boolean hasTransposedNavBar() {
-        Rect insets = new Rect();
-        getStableInsets(insets);
-        return insets.right > 0;
-    }
-
     private final class H extends Handler {
         private static final int ON_TASK_STACK_CHANGED = 1;
         private static final int ON_ACTIVITY_PINNED = 2;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index af1628b..3979095 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -100,12 +100,12 @@
      * An optimization to preload the raw list of tasks. The raw tasks are saved in least-recent
      * to most-recent order.
      */
-    public synchronized void preloadRawTasks(boolean isTopTaskHome) {
+    public synchronized void preloadRawTasks(boolean isHomeStackVisible) {
         int currentUserId = UserHandle.USER_CURRENT;
         updateCurrentQuietProfilesCache(currentUserId);
         SystemServicesProxy ssp = Recents.getSystemServices();
         mRawTasks = ssp.getRecentTasks(ActivityManager.getMaxRecentTasksStatic(),
-                currentUserId, isTopTaskHome, mCurrentQuietProfiles);
+                currentUserId, isHomeStackVisible, mCurrentQuietProfiles);
 
         // Since the raw tasks are given in most-recent to least-recent order, we need to reverse it
         Collections.reverse(mRawTasks);
@@ -120,12 +120,12 @@
      * - least-recent to most-recent stack tasks
      * - least-recent to most-recent freeform tasks
      */
-    public synchronized void preloadPlan(RecentsTaskLoader loader, int topTaskId,
-            boolean isTopTaskHome) {
+    public synchronized void preloadPlan(RecentsTaskLoader loader, int runningTaskId,
+            boolean isHomeStackVisible) {
         Resources res = mContext.getResources();
         ArrayList<Task> allTasks = new ArrayList<>();
         if (mRawTasks == null) {
-            preloadRawTasks(isTopTaskHome);
+            preloadRawTasks(isHomeStackVisible);
         }
 
         SparseArray<Task.TaskKey> affiliatedTasks = new SparseArray<>();
@@ -182,7 +182,7 @@
             boolean isFreeformTask = SystemServicesProxy.isFreeformStack(t.stackId);
             boolean isStackTask = isFreeformTask || (!isHistoricalTask(t) ||
                     (t.lastActiveTime >= lastStackActiveTime && i >= (taskCount - MIN_NUM_TASKS)));
-            boolean isLaunchTarget = taskKey.id == topTaskId;
+            boolean isLaunchTarget = taskKey.id == runningTaskId;
             if (isStackTask && newLastStackActiveTime < 0) {
                 newLastStackActiveTime = t.lastActiveTime;
             }
@@ -196,7 +196,7 @@
             Drawable icon = isStackTask
                     ? loader.getAndUpdateActivityIcon(taskKey, t.taskDescription, res, false)
                     : null;
-            Bitmap thumbnail = loader.getAndUpdateThumbnail(taskKey, false);
+            Bitmap thumbnail = loader.getAndUpdateThumbnail(taskKey, false /* loadIfNotCached */);
             int activityColor = loader.getActivityPrimaryColor(t.taskDescription);
             int backgroundColor = loader.getActivityBackgroundColor(t.taskDescription);
             boolean isSystemApp = (info != null) &&
@@ -256,7 +256,8 @@
             if (opts.loadThumbnails && (isRunningTask || isVisibleThumbnail)) {
                 if (task.thumbnail == null || isRunningTask) {
                     if (config.svelteLevel <= RecentsConfiguration.SVELTE_LIMIT_CACHE) {
-                        task.thumbnail = loader.getAndUpdateThumbnail(taskKey, true);
+                        task.thumbnail = loader.getAndUpdateThumbnail(taskKey,
+                                true /* loadIfNotCached */);
                     } else if (config.svelteLevel == RecentsConfiguration.SVELTE_DISABLE_CACHE) {
                         loadQueue.addTask(task);
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index fb92971..9460b64 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -36,7 +36,9 @@
 import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.events.activity.PackagesChangedEvent;
 import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.misc.Utilities;
 
+import java.io.PrintWriter;
 import java.util.Map;
 import java.util.concurrent.ConcurrentLinkedQueue;
 
@@ -331,8 +333,9 @@
     }
 
     /** Preloads recents tasks using the specified plan to store the output. */
-    public void preloadTasks(RecentsTaskLoadPlan plan, int topTaskId, boolean isTopTaskHome) {
-        plan.preloadPlan(this, topTaskId, isTopTaskHome);
+    public void preloadTasks(RecentsTaskLoadPlan plan, int runningTaskId,
+            boolean isHomeStackVisible) {
+        plan.preloadPlan(this, runningTaskId, isHomeStackVisible);
     }
 
     /** Begins loading the heavy task data according to the specified options. */
@@ -624,4 +627,14 @@
             }
         }
     }
+
+    public void dump(String prefix, PrintWriter writer) {
+        String innerPrefix = prefix + "  ";
+
+        writer.print(prefix); writer.println(TAG);
+        writer.print(prefix); writer.println("Icon Cache");
+        mIconCache.dump(innerPrefix, writer);
+        writer.print(prefix); writer.println("Thumbnail Cache");
+        mThumbnailCache.dump(innerPrefix, writer);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index 68c46a9..c6528a1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -338,9 +338,18 @@
 
     public void dump(String prefix, PrintWriter writer) {
         writer.print(prefix); writer.print(key);
-        if (affiliationTaskId != key.id) {
+        if (isAffiliatedTask()) {
             writer.print(" "); writer.print("affTaskId=" + affiliationTaskId);
         }
+        if (!isDockable) {
+            writer.print(" dockable=N");
+        }
+        if (isLaunchTarget) {
+            writer.print(" launchTarget=Y");
+        }
+        if (isFreeformTask()) {
+            writer.print(" freeform=Y");
+        }
         writer.print(" "); writer.print(title);
         writer.println();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskKeyLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskKeyLruCache.java
index 748d8ed..c63a494 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskKeyLruCache.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskKeyLruCache.java
@@ -20,6 +20,9 @@
 import android.util.LruCache;
 import android.util.SparseArray;
 
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
 /**
  * A mapping of {@link Task.TaskKey} to value, with additional LRU functionality where the least
  * recently referenced key/values will be evicted as more values than the given cache size are
@@ -112,4 +115,16 @@
     final void trimToSize(int cacheSize) {
         mCache.trimToSize(cacheSize);
     }
+
+    public void dump(String prefix, PrintWriter writer) {
+        String innerPrefix = prefix + "  ";
+
+        writer.print(prefix); writer.print(TAG);
+        writer.print(" numEntries="); writer.print(mKeys.size());
+        writer.println();
+        int keyCount = mKeys.size();
+        for (int i = 0; i < keyCount; i++) {
+            writer.print(innerPrefix); writer.println(mKeys.get(mKeys.keyAt(i)));
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
index 4a8abf7..9dc9c4c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -217,7 +217,7 @@
 
     boolean dismissRecentsToLaunchTargetTaskOrHome(boolean animate) {
         SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
+        if (ssp.isRecentsActivityVisible()) {
             // If we have a focused Task, launch that Task now
             if (mRecentsView.launchPreviousTask(animate)) {
               return true;
@@ -230,7 +230,7 @@
 
     boolean dismissRecentsToFocusedTaskOrHome() {
         SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
+        if (ssp.isRecentsActivityVisible()) {
             // If we have a focused Task, launch that Task now
             if (mRecentsView.launchFocusedTask()) return true;
             // If none of the other cases apply, then just go Home
@@ -263,7 +263,7 @@
 
     boolean dismissRecentsToHomeIfVisible(boolean animated) {
         SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
+        if (ssp.isRecentsActivityVisible()) {
             // Return to Home
             dismissRecentsToHome(animated);
             return true;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
index 18b9263..59ea358 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
@@ -48,8 +48,8 @@
     }
 
     @Override
-    protected void startRecentsActivity(ActivityManager.RunningTaskInfo topTask,
-            boolean isTopTaskHome, boolean animate, int growTarget) {
+    protected void startRecentsActivity(ActivityManager.RunningTaskInfo runningTask,
+            boolean isHomeStackVisible, boolean animate, int growTarget) {
         RecentsTaskLoader loader = Recents.getTaskLoader();
 
         // In the case where alt-tab is triggered, we never get a preloadRecents() call, so we
@@ -60,25 +60,25 @@
             sInstanceLoadPlan = loader.createLoadPlan(mContext);
         }
         if (mTriggeredFromAltTab || !sInstanceLoadPlan.hasTasks()) {
-            loader.preloadTasks(sInstanceLoadPlan, topTask.id, isTopTaskHome);
+            loader.preloadTasks(sInstanceLoadPlan, runningTask.id, isHomeStackVisible);
         }
         TaskStack stack = sInstanceLoadPlan.getTaskStack();
 
         if (!animate) {
             ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext, -1, -1);
-            startRecentsActivity(topTask, opts, false /* fromHome */, false /* fromThumbnail*/);
+            startRecentsActivity(runningTask, opts, false /* fromHome */, false /* fromThumbnail*/);
             return;
         }
 
         boolean hasRecentTasks = stack.getTaskCount() > 0;
-        boolean useThumbnailTransition = (topTask != null) && !isTopTaskHome && hasRecentTasks;
+        boolean useThumbnailTransition = (runningTask != null) && !isHomeStackVisible && hasRecentTasks;
 
         if (useThumbnailTransition) {
             // Try starting with a thumbnail transition
-            ActivityOptions opts = getThumbnailTransitionActivityOptionsForTV(topTask,
+            ActivityOptions opts = getThumbnailTransitionActivityOptionsForTV(runningTask,
                     stack.getTaskCount());
             if (opts != null) {
-                startRecentsActivity(topTask, opts, false /* fromHome */, true /* fromThumbnail */);
+                startRecentsActivity(runningTask, opts, false /* fromHome */, true /* fromThumbnail */);
             } else {
                 // Fall through below to the non-thumbnail transition
                 useThumbnailTransition = false;
@@ -86,19 +86,19 @@
         }
 
         if (!useThumbnailTransition) {
-            startRecentsActivity(topTask, null, true /* fromHome */, false /* fromThumbnail */);
+            startRecentsActivity(runningTask, null, true /* fromHome */, false /* fromThumbnail */);
         }
         mLastToggleTime = SystemClock.elapsedRealtime();
     }
 
-    protected void startRecentsActivity(ActivityManager.RunningTaskInfo topTask,
+    protected void startRecentsActivity(ActivityManager.RunningTaskInfo runningTask,
             ActivityOptions opts, boolean fromHome, boolean fromThumbnail) {
         // Update the configuration based on the launch options
         RecentsConfiguration config = Recents.getConfiguration();
         RecentsActivityLaunchState launchState = config.getLaunchState();
         launchState.launchedFromHome = fromHome;
         launchState.launchedFromApp = fromThumbnail;
-        launchState.launchedToTaskId = (topTask != null) ? topTask.id : -1;
+        launchState.launchedToTaskId = (runningTask != null) ? runningTask.id : -1;
         launchState.launchedWithAltTab = mTriggeredFromAltTab;
 
         Intent intent = new Intent();
@@ -119,10 +119,10 @@
      * Creates the activity options for an app->recents transition on TV.
      */
     private ActivityOptions getThumbnailTransitionActivityOptionsForTV(
-            ActivityManager.RunningTaskInfo topTask, int numTasks) {
+            ActivityManager.RunningTaskInfo runningTask, int numTasks) {
         Rect rect = TaskCardView.getStartingCardThumbnailRect(mContext, numTasks);
         SystemServicesProxy ssp = Recents.getSystemServices();
-        ThumbnailData thumbnailData = ssp.getTaskThumbnail(topTask.id);
+        ThumbnailData thumbnailData = ssp.getTaskThumbnail(runningTask.id);
         if (thumbnailData.thumbnail != null) {
             Bitmap thumbnail = Bitmap.createScaledBitmap(thumbnailData.thumbnail, rect.width(),
                     rect.height(), false);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/ViewFocusAnimator.java b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/ViewFocusAnimator.java
index be69552..c3efe64 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/ViewFocusAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/ViewFocusAnimator.java
@@ -36,6 +36,7 @@
     private final float mSelectedZDelta;
     private final float mUnselectedSpacing;
     private final float mSelectedSpacingDelta;
+    private final float mDismissIconAlpha;
     private final int mAnimDuration;
     private final Interpolator mFocusInterpolator;
 
@@ -71,6 +72,8 @@
         mFocusAnimation.setDuration(mAnimDuration);
         mFocusAnimation.setInterpolator(mFocusInterpolator);
 
+        mDismissIconAlpha = res.getFloat(R.integer.dismiss_unselected_alpha);
+
         setFocusProgress(0.0f);
 
         mFocusAnimation.addListener(new AnimatorListenerAdapter() {
@@ -99,7 +102,7 @@
         mTargetView.setPadding((int) spacing, mTargetView.getPaddingTop(),
                 (int) spacing, mTargetView.getPaddingBottom());
 
-
+        mTargetView.getDismissIconView().setAlpha(mDismissIconAlpha * level);
         mTargetView.getThumbnailView().setZ(z);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
index 235b782..ef8a54b7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
@@ -47,6 +47,7 @@
 
     private static final String TAG = "TaskCardView";
     private View mThumbnailView;
+    private View mDismissIconView;
     private TextView mTitleTextView;
     private ImageView mBadgeView;
     private Task mTask;
@@ -78,6 +79,7 @@
         mThumbnailView = findViewById(R.id.card_view_thumbnail);
         mTitleTextView = (TextView) findViewById(R.id.card_title_text);
         mBadgeView = (ImageView) findViewById(R.id.card_extra_badge);
+        mDismissIconView = findViewById(R.id.dismiss_icon);
         mDismissAnimationsHolder = new DismissAnimationsHolder(this);
         View title = findViewById(R.id.card_info_field);
         mCornerRadius = getResources().getDimensionPixelSize(
@@ -316,4 +318,8 @@
     public View getThumbnailView() {
         return mThumbnailView;
     }
+
+    public View getDismissIconView() {
+        return mDismissIconView;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
index 6115aa8..2ec180d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -202,8 +202,8 @@
      * Handles dragging touch events
      */
     private void handleTouchEvent(MotionEvent ev) {
-        int action = ev.getAction();
-        switch (action & MotionEvent.ACTION_MASK) {
+        int action = ev.getActionMasked();
+        switch (action) {
             case MotionEvent.ACTION_DOWN:
                 mDownPos.set((int) ev.getX(), (int) ev.getY());
                 break;
@@ -258,7 +258,7 @@
             case MotionEvent.ACTION_CANCEL: {
                 if (mDragRequested) {
                     EventBus.getDefault().send(new DragEndEvent(mDragTask, mTaskView,
-                            mLastDropTarget));
+                            action == MotionEvent.ACTION_UP ? mLastDropTarget : null));
                     break;
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
index 2f3019c..995f9f7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
@@ -28,7 +28,6 @@
 import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
 import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
 import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 
 /** Manages the scrims for the various system bars. */
 public class SystemBarScrimViews {
@@ -51,7 +50,7 @@
         mNavBarScrimView.forceHasOverlappingRendering(false);
         mNavBarScrimEnterDuration = activity.getResources().getInteger(
                 R.integer.recents_nav_bar_scrim_enter_duration);
-        mHasNavBarScrim = Recents.getSystemServices().hasTransposedNavBar();
+        mHasNavBarScrim = Recents.getSystemServices().hasTransposedNavigationBar();
         mHasDockedTasks = Recents.getSystemServices().hasDockedTask();
     }
 
@@ -145,7 +144,7 @@
 
     public final void onBusEvent(ConfigurationChangedEvent event) {
         if (event.fromDeviceOrientationChange) {
-            mHasNavBarScrim = Recents.getSystemServices().hasTransposedNavBar();
+            mHasNavBarScrim = Recents.getSystemServices().hasTransposedNavigationBar();
         }
         animateScrimToCurrentNavBarState(event.hasStackTasks);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 9fd4b05..7379706 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -277,7 +277,7 @@
                     updateDockSide();
                     SystemServicesProxy ssp = Recents.getSystemServices();
                     if (mDockSide != WindowManager.DOCKED_INVALID
-                            && !ssp.isRecentsTopMost(ssp.getTopMostTask(), null /* isTopHome */)) {
+                            && !ssp.isRecentsActivityVisible()) {
                         mWindowManagerProxy.swapTasks();
                         return true;
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 8bf32c2..ef6d73a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -143,6 +143,7 @@
     protected static final int MSG_SHOW_NEXT_AFFILIATED_TASK = 1024;
     protected static final int MSG_SHOW_PREV_AFFILIATED_TASK = 1025;
     protected static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU = 1026;
+    protected static final int MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU = 1027;
 
     protected static final boolean ENABLE_HEADS_UP = true;
     protected static final String SETTING_HEADS_UP_TICKER = "ticker_gets_heads_up";
@@ -1247,6 +1248,13 @@
     }
 
     @Override
+    public void dismissKeyboardShortcutsMenu() {
+        int msg = MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU;
+        mHandler.removeMessages(msg);
+        mHandler.sendEmptyMessage(msg);
+    }
+
+    @Override
     public void toggleKeyboardShortcutsMenu(int deviceId) {
         int msg = MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU;
         mHandler.removeMessages(msg);
@@ -1343,6 +1351,10 @@
         KeyboardShortcuts.toggle(mContext, deviceId);
     }
 
+    protected void dismissKeyboardShortcuts() {
+        KeyboardShortcuts.dismiss();
+    }
+
     protected void cancelPreloadingRecents() {
         if (mRecents != null) {
             mRecents.cancelPreloadingRecents();
@@ -1517,6 +1529,9 @@
              case MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU:
                   toggleKeyboardShortcuts(m.arg1);
                   break;
+             case MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU:
+                  dismissKeyboardShortcuts();
+                  break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index f7d13ee..1bc2ebc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -74,6 +74,7 @@
     private static final int MSG_CLICK_QS_TILE                 = 29 << MSG_SHIFT;
     private static final int MSG_TOGGLE_APP_SPLIT_SCREEN       = 30 << MSG_SHIFT;
     private static final int MSG_APP_TRANSITION_FINISHED       = 31 << MSG_SHIFT;
+    private static final int MSG_DISMISS_KEYBOARD_SHORTCUTS    = 32 << MSG_SHIFT;
 
     public static final int FLAG_EXCLUDE_NONE = 0;
     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -108,6 +109,7 @@
         void toggleRecentApps();
         void toggleSplitScreen();
         void preloadRecentApps();
+        void dismissKeyboardShortcutsMenu();
         void toggleKeyboardShortcutsMenu(int deviceId);
         void cancelPreloadRecentApps();
         void setWindowState(int window, int state);
@@ -256,6 +258,14 @@
     }
 
     @Override
+    public void dismissKeyboardShortcutsMenu() {
+        synchronized (mLock) {
+            mHandler.removeMessages(MSG_DISMISS_KEYBOARD_SHORTCUTS);
+            mHandler.obtainMessage(MSG_DISMISS_KEYBOARD_SHORTCUTS).sendToTarget();
+        }
+    }
+
+    @Override
     public void toggleKeyboardShortcutsMenu(int deviceId) {
         synchronized (mLock) {
             mHandler.removeMessages(MSG_TOGGLE_KEYBOARD_SHORTCUTS);
@@ -435,6 +445,9 @@
                 case MSG_CANCEL_PRELOAD_RECENT_APPS:
                     mCallbacks.cancelPreloadRecentApps();
                     break;
+                case MSG_DISMISS_KEYBOARD_SHORTCUTS:
+                    mCallbacks.dismissKeyboardShortcutsMenu();
+                    break;
                 case MSG_TOGGLE_KEYBOARD_SHORTCUTS:
                     mCallbacks.toggleKeyboardShortcutsMenu(msg.arg1);
                     break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 6e9de23..2806729 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -1346,7 +1346,7 @@
             expandButton.setVisibility(VISIBLE);
             mNotificationHeader.setOnClickListener(mExpandClickListener);
             mNotificationHeaderWrapper = NotificationViewWrapper.wrap(getContext(),
-                    mNotificationHeader);
+                    mNotificationHeader, this);
             addView(mNotificationHeader, indexOfChild(mChildrenContainer) + 1);
             mTranslateableViews.add(mNotificationHeader);
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutsReceiver.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutsReceiver.java
index 5f4ebd8..8a5bece 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutsReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutsReceiver.java
@@ -27,6 +27,8 @@
     public void onReceive(Context context, Intent intent) {
         if (Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(intent.getAction())) {
             KeyboardShortcuts.show(context, -1 /* deviceId unknown */);
+        } else if (Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(intent.getAction())) {
+            KeyboardShortcuts.dismiss();
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 491ffde..7be50c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -177,6 +177,13 @@
             if (updateContractedHeaderWidth()) {
                 mContractedChild.measure(widthMeasureSpec, heightSpec);
             }
+            if (mExpandedChild != null
+                    && mContractedChild.getMeasuredHeight() > mExpandedChild.getMeasuredHeight()) {
+                // the Expanded child is smaller then the collapsed. Let's remeasure it.
+                heightSpec = MeasureSpec.makeMeasureSpec(mContractedChild.getMeasuredHeight(),
+                        MeasureSpec.EXACTLY);
+                mExpandedChild.measure(widthMeasureSpec, heightSpec);
+            }
         }
         if (mHeadsUpChild != null) {
             int size = Math.min(maxSize, mHeadsUpHeight);
@@ -307,7 +314,8 @@
         addView(child);
         mContractedChild = child;
         mContractedChild.addOnLayoutChangeListener(mLayoutUpdater);
-        mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child);
+        mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child,
+                mContainingNotification);
         selectLayout(false /* animate */, true /* force */);
         mContractedWrapper.setDark(mDark, false /* animate */, 0 /* delay */);
     }
@@ -321,7 +329,8 @@
         addView(child);
         mExpandedChild = child;
         mExpandedChild.addOnLayoutChangeListener(mLayoutUpdater);
-        mExpandedWrapper = NotificationViewWrapper.wrap(getContext(), child);
+        mExpandedWrapper = NotificationViewWrapper.wrap(getContext(), child,
+                mContainingNotification);
         selectLayout(false /* animate */, true /* force */);
     }
 
@@ -334,7 +343,8 @@
         addView(child);
         mHeadsUpChild = child;
         mHeadsUpChild.addOnLayoutChangeListener(mLayoutUpdater);
-        mHeadsUpWrapper = NotificationViewWrapper.wrap(getContext(), child);
+        mHeadsUpWrapper = NotificationViewWrapper.wrap(getContext(), child,
+                mContainingNotification);
         selectLayout(false /* animate */, true /* force */);
     }
 
@@ -834,10 +844,14 @@
     public void updateExpandButtons(boolean expandable) {
         mExpandable = expandable;
         // if the expanded child has the same height as the collapsed one we hide it.
-        if (mExpandedChild != null && mExpandedChild.getHeight() != 0 &&
-                ((mIsHeadsUp && mExpandedChild.getHeight() == mHeadsUpChild.getHeight()) ||
-                (!mIsHeadsUp && mExpandedChild.getHeight() == mContractedChild.getHeight()))) {
-            expandable = false;
+        if (mExpandedChild != null && mExpandedChild.getHeight() != 0) {
+            if ((!mIsHeadsUp || mHeadsUpChild == null)) {
+                if (mExpandedChild.getHeight() == mContractedChild.getHeight()) {
+                    expandable = false;
+                }
+            } else if (mExpandedChild.getHeight() == mHeadsUpChild.getHeight()) {
+                expandable = false;
+            }
         }
         if (mExpandedChild != null) {
             mExpandedWrapper.updateExpandability(expandable, mExpandClickListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
index 06d79a7..3363993 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
@@ -65,12 +65,7 @@
             ImageView expand = (ImageView) view.findViewById(
                     com.android.internal.R.id.expand_button);
             applyToChild(icon, apply, header.getOriginalIconColor());
-            int color = header.getOriginalNotificationColor();
-            if (color == Notification.COLOR_DEFAULT) {
-                color = view.getContext().getColor(
-                        com.android.internal.R.color.notification_icon_default_color);
-            }
-            applyToChild(expand, apply, color);
+            applyToChild(expand, apply, header.getOriginalNotificationColor());
         }
 
         private void applyToChild(View view, boolean shouldApply, int originalColor) {
@@ -116,7 +111,7 @@
                     @Override
                     public boolean compare(View parent, View child, Object parentData,
                             Object childData) {
-                        return parent.getVisibility() == View.VISIBLE;
+                        return parent.getVisibility() != View.GONE;
                     }
 
                     @Override
@@ -161,11 +156,11 @@
                 mComparators.get(compI).apply(row);
             }
             // We need to sanitize the dividers since they might be off-balance now
-            sanitizeDividers(row);
+            sanitizeHeaderViews(row);
         }
     }
 
-    private void sanitizeDividers(ExpandableNotificationRow row) {
+    private void sanitizeHeaderViews(ExpandableNotificationRow row) {
         if (row.isSummaryWithChildren()) {
             sanitizeHeader(row.getNotificationHeader());
             return;
@@ -188,9 +183,26 @@
         if (rowHeader == null) {
             return;
         }
+        final int childCount = rowHeader.getChildCount();
+        View time = rowHeader.findViewById(com.android.internal.R.id.time);
+        boolean hasVisibleText = false;
+        for (int i = 1; i < childCount - 1 ; i++) {
+            View child = rowHeader.getChildAt(i);
+            if (child instanceof TextView
+                    && child.getVisibility() != View.GONE
+                    && !mDividers.contains(Integer.valueOf(child.getId()))
+                    && child != time) {
+                hasVisibleText = true;
+                break;
+            }
+        }
+        // in case no view is visible we make sure the time is visible
+        int timeVisibility = !hasVisibleText
+                || mRow.getStatusBarNotification().getNotification().showsTimeOrChronometer()
+                ? View.VISIBLE : View.GONE;
+        time.setVisibility(timeVisibility);
         View left = null;
         View right;
-        final int childCount = rowHeader.getChildCount();
         for (int i = 1; i < childCount - 1 ; i++) {
             View child = rowHeader.getChildAt(i);
             if (mDividers.contains(Integer.valueOf(child.getId()))) {
@@ -202,14 +214,14 @@
                         // A divider was found, this needs to be hidden
                         i--;
                         break;
-                    } else if (right.getVisibility() == View.VISIBLE) {
+                    } else if (right.getVisibility() != View.GONE && right instanceof TextView) {
                         visible = left != null;
                         left = right;
                         break;
                     }
                 }
                 child.setVisibility(visible ? View.VISIBLE : View.GONE);
-            } else if (child.getVisibility() == View.VISIBLE) {
+            } else if (child.getVisibility() != View.GONE && child instanceof TextView) {
                 left = child;
             }
         }
@@ -219,7 +231,7 @@
         for (int compI = 0; compI < mComparators.size(); compI++) {
             mComparators.get(compI).apply(row, true /* reset */);
         }
-        sanitizeDividers(row);
+        sanitizeHeaderViews(row);
     }
 
     private static class HeaderProcessor {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 988d537..2b59c68 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -295,6 +295,14 @@
             return;
         }
         // Clear out all old subIds.
+        for (PhoneState state : mPhoneStates) {
+            if (state.mMobile != null) {
+                state.maybeStopAnimatableDrawable(state.mMobile);
+            }
+            if (state.mMobileDark != null) {
+                state.maybeStopAnimatableDrawable(state.mMobileDark);
+            }
+        }
         mPhoneStates.clear();
         if (mMobileSignalGroup != null) {
             mMobileSignalGroup.removeAllViews();
@@ -391,6 +399,11 @@
                 state.mMobile.setImageDrawable(null);
                 state.mLastMobileStrengthId = -1;
             }
+            if (state.mMobileDark != null) {
+                state.maybeStopAnimatableDrawable(state.mMobileDark);
+                state.mMobileDark.setImageDrawable(null);
+                state.mLastMobileStrengthId = -1;
+            }
             if (state.mMobileType != null) {
                 state.mMobileType.setImageDrawable(null);
                 state.mLastMobileTypeId = -1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 811687c..d1fc780 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -178,7 +178,7 @@
         @Override
         public void onTaskStackChanged() {
             SystemServicesProxy ssp = Recents.getSystemServices();
-            ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getTopMostTask();
+            ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getRunningTask();
             mController.taskChanged(runningTaskInfo.baseActivity.getPackageName());
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
index c561601..6084770 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
@@ -23,13 +23,16 @@
 import android.service.notification.StatusBarNotification;
 import android.view.View;
 
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+
 /**
  * Wraps a notification containing a big picture template
  */
 public class NotificationBigPictureTemplateViewWrapper extends NotificationTemplateViewWrapper {
 
-    protected NotificationBigPictureTemplateViewWrapper(Context ctx, View view) {
-        super(ctx, view);
+    protected NotificationBigPictureTemplateViewWrapper(Context ctx, View view,
+            ExpandableNotificationRow row) {
+        super(ctx, view, row);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
index 487a7a0..3f49125 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
@@ -21,6 +21,7 @@
 import android.view.View;
 
 import com.android.internal.widget.ImageFloatingTextView;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.TransformableView;
 
 /**
@@ -30,8 +31,9 @@
 
     private ImageFloatingTextView mBigtext;
 
-    protected NotificationBigTextTemplateViewWrapper(Context ctx, View view) {
-        super(ctx, view);
+    protected NotificationBigTextTemplateViewWrapper(Context ctx, View view,
+            ExpandableNotificationRow row) {
+        super(ctx, view, row);
     }
 
     private void resolveViews(StatusBarNotification notification) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
index 49e4ba8..61df44a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
@@ -30,6 +30,7 @@
 
 import com.android.systemui.R;
 import com.android.systemui.ViewInvertHelper;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 /**
@@ -44,8 +45,8 @@
     private boolean mShouldInvertDark;
     private boolean mShowingLegacyBackground;
 
-    protected NotificationCustomViewWrapper(View view) {
-        super(view);
+    protected NotificationCustomViewWrapper(View view, ExpandableNotificationRow row) {
+        super(view, row);
         mInvertHelper = new ViewInvertHelper(view, NotificationPanelView.DOZE_ANIMATION_DURATION);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
index b201d8f..1bfbaa2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -36,6 +36,7 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.ViewInvertHelper;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.ViewTransformationHelper;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
@@ -61,8 +62,8 @@
     private ImageView mExpandButton;
     private NotificationHeaderView mNotificationHeader;
 
-    protected NotificationHeaderViewWrapper(Context ctx, View view) {
-        super(view);
+    protected NotificationHeaderViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
+        super(view, row);
         mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha);
         mInvertHelper = new ViewInvertHelper(ctx, NotificationPanelView.DOZE_ANIMATION_DURATION);
         mTransformationHelper = new ViewTransformationHelper();
@@ -156,7 +157,9 @@
         } else {
             mInvertHelper.update(dark);
         }
-        if (mIcon != null) {
+        if (mIcon != null && !mRow.isChildInGroup()) {
+            // We don't update the color for children views / their icon is invisible anyway.
+            // It also may lead to bugs where the icon isn't correctly greyed out.
             boolean hadColorFilter = mNotificationHeader.getOriginalIconColor()
                     != NotificationHeaderView.NO_COLOR;
             if (fade) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
index 30698e1..3c95a78 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
@@ -20,6 +20,7 @@
 import android.service.notification.StatusBarNotification;
 import android.view.View;
 
+import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.TransformableView;
 
 /**
@@ -27,8 +28,9 @@
  */
 public class NotificationMediaTemplateViewWrapper extends NotificationTemplateViewWrapper {
 
-    protected NotificationMediaTemplateViewWrapper(Context ctx, View view) {
-        super(ctx, view);
+    protected NotificationMediaTemplateViewWrapper(Context ctx, View view,
+            ExpandableNotificationRow row) {
+        super(ctx, view, row);
     }
 
     View mActions;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
index 78e23fc..889bd5c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -25,11 +25,10 @@
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
-import com.android.systemui.Interpolators;
 import com.android.systemui.statusbar.CrossFadeHelper;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.ViewTransformationHelper;
-import com.android.systemui.statusbar.stack.StackStateAnimator;
 
 /**
  * Wraps a notification view inflated from a template.
@@ -43,8 +42,8 @@
     private TextView mTitle;
     private TextView mText;
 
-    protected NotificationTemplateViewWrapper(Context ctx, View view) {
-        super(ctx, view);
+    protected NotificationTemplateViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
+        super(ctx, view, row);
         mTransformationHelper.setCustomTransformation(
                 new ViewTransformationHelper.CustomTransformation() {
                     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
index ebff69d..7a0df1f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -26,7 +26,7 @@
 
 import com.android.systemui.Interpolators;
 import com.android.systemui.statusbar.CrossFadeHelper;
-import com.android.systemui.statusbar.NotificationContentView;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
 
@@ -38,28 +38,30 @@
 
     protected final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix();
     protected final View mView;
+    protected final ExpandableNotificationRow mRow;
     protected boolean mDark;
     protected boolean mDarkInitialized = false;
 
-    public static NotificationViewWrapper wrap(Context ctx, View v) {
+    public static NotificationViewWrapper wrap(Context ctx, View v, ExpandableNotificationRow row) {
         if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) {
             if ("bigPicture".equals(v.getTag())) {
-                return new NotificationBigPictureTemplateViewWrapper(ctx, v);
+                return new NotificationBigPictureTemplateViewWrapper(ctx, v, row);
             } else if ("bigText".equals(v.getTag())) {
-                return new NotificationBigTextTemplateViewWrapper(ctx, v);
+                return new NotificationBigTextTemplateViewWrapper(ctx, v, row);
             } else if ("media".equals(v.getTag()) || "bigMediaNarrow".equals(v.getTag())) {
-                return new NotificationMediaTemplateViewWrapper(ctx, v);
+                return new NotificationMediaTemplateViewWrapper(ctx, v, row);
             }
-            return new NotificationTemplateViewWrapper(ctx, v);
+            return new NotificationTemplateViewWrapper(ctx, v, row);
         } else if (v instanceof NotificationHeaderView) {
-            return new NotificationHeaderViewWrapper(ctx, v);
+            return new NotificationHeaderViewWrapper(ctx, v, row);
         } else {
-            return new NotificationCustomViewWrapper(v);
+            return new NotificationCustomViewWrapper(v, row);
         }
     }
 
-    protected NotificationViewWrapper(View view) {
+    protected NotificationViewWrapper(View view, ExpandableNotificationRow row) {
         mView = view;
+        mRow = row;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index 0153a40..65b93c7 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -20,6 +20,7 @@
 import android.animation.LayoutTransition;
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
+import android.annotation.NonNull;
 import android.annotation.SuppressLint;
 import android.app.Dialog;
 import android.app.KeyguardManager;
@@ -109,6 +110,7 @@
     private final SparseBooleanArray mDynamic = new SparseBooleanArray();
     private final KeyguardManager mKeyguard;
     private final AudioManager mAudioManager;
+    private final AccessibilityManager mAccessibilityMgr;
     private int mExpandButtonAnimationDuration;
     private ZenFooter mZenFooter;
     private final LayoutTransition mLayoutTransition;
@@ -150,6 +152,7 @@
         mSpTexts = new SpTexts(mContext);
         mKeyguard = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        mAccessibilityMgr = (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
         mActiveSliderTint = loadColorStateList(R.color.system_accent_color);
         mInactiveSliderTint = loadColorStateList(R.color.volume_slider_inactive);
         mLayoutTransition = new LayoutTransition();
@@ -507,6 +510,15 @@
                 setExpandedH(false);
             }
         });
+        if (mAccessibilityMgr.isEnabled()) {
+            AccessibilityEvent event =
+                    AccessibilityEvent.obtain(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+            event.setPackageName(mContext.getPackageName());
+            event.setClassName(CustomDialog.class.getSuperclass().getName());
+            event.getText().add(mContext.getString(
+                    R.string.volume_dialog_accessibility_dismissed_message));
+            mAccessibilityMgr.sendAccessibilityEvent(event);
+        }
         Events.writeEvent(mContext, Events.EVENT_DISMISS_DIALOG, reason);
         mController.notifyVisible(false);
         synchronized (mSafetyWarningLock) {
@@ -1082,6 +1094,27 @@
             }
             return false;
         }
+
+        @Override
+        public boolean dispatchPopulateAccessibilityEvent(@NonNull AccessibilityEvent event) {
+            event.setClassName(getClass().getSuperclass().getName());
+            event.setPackageName(mContext.getPackageName());
+
+            ViewGroup.LayoutParams params = getWindow().getAttributes();
+            boolean isFullScreen = (params.width == ViewGroup.LayoutParams.MATCH_PARENT) &&
+                    (params.height == ViewGroup.LayoutParams.MATCH_PARENT);
+            event.setFullScreen(isFullScreen);
+
+            if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+                if (mShowing) {
+                    event.getText().add(mContext.getString(
+                            R.string.volume_dialog_accessibility_shown_message,
+                            getActiveRow().ss.name));
+                    return true;
+                }
+            }
+            return false;
+        }
     }
 
     private final class VolumeSeekBarChangeListener implements OnSeekBarChangeListener {
@@ -1138,16 +1171,13 @@
     }
 
     private final class Accessibility extends AccessibilityDelegate {
-        private AccessibilityManager mMgr;
         private boolean mFeedbackEnabled;
 
         public void init() {
-            mMgr = (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
             mDialogView.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
                 @Override
                 public void onViewDetachedFromWindow(View v) {
                     if (D.BUG) Log.d(TAG, "onViewDetachedFromWindow");
-                    // noop
                 }
 
                 @Override
@@ -1157,12 +1187,13 @@
                 }
             });
             mDialogView.setAccessibilityDelegate(this);
-            mMgr.addAccessibilityStateChangeListener(new AccessibilityStateChangeListener() {
-                @Override
-                public void onAccessibilityStateChanged(boolean enabled) {
-                    updateFeedbackEnabled();
-                }
-            });
+            mAccessibilityMgr.addAccessibilityStateChangeListener(
+                    new AccessibilityStateChangeListener() {
+                        @Override
+                        public void onAccessibilityStateChanged(boolean enabled) {
+                            updateFeedbackEnabled();
+                        }
+                    });
             updateFeedbackEnabled();
         }
 
@@ -1180,7 +1211,7 @@
         private boolean computeFeedbackEnabled() {
             // are there any enabled non-generic a11y services?
             final List<AccessibilityServiceInfo> services =
-                    mMgr.getEnabledAccessibilityServiceList(FEEDBACK_ALL_MASK);
+                    mAccessibilityMgr.getEnabledAccessibilityServiceList(FEEDBACK_ALL_MASK);
             for (AccessibilityServiceInfo asi : services) {
                 if (asi.feedbackType != 0 && asi.feedbackType != FEEDBACK_GENERIC) {
                     return true;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index b965f64..b069361 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -72,6 +72,7 @@
 import android.net.UidRange;
 import android.net.Uri;
 import android.net.metrics.DefaultNetworkEvent;
+import android.net.metrics.NetworkEvent;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -2109,6 +2110,7 @@
 
     private void linger(NetworkAgentInfo nai) {
         nai.lingering = true;
+        NetworkEvent.logEvent(nai.network.netId, NetworkEvent.NETWORK_LINGER);
         nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_LINGER);
         notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING);
     }
@@ -2122,6 +2124,7 @@
         nai.networkLingered.clear();
         if (!nai.lingering) return;
         nai.lingering = false;
+        NetworkEvent.logEvent(nai.network.netId, NetworkEvent.NETWORK_UNLINGER);
         if (VDBG) log("Canceling linger of " + nai.name());
         nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
     }
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 6c05173..bc9f69e 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -1048,7 +1048,13 @@
     private void changeUserKey(int userId, byte[] token, byte[] secret)
             throws RemoteException {
         final UserInfo userInfo = UserManager.get(mContext).getUserInfo(userId);
-        getMountService().changeUserKey(userId, userInfo.serialNumber, token, null, secret);
+        final IMountService mountService = getMountService();
+        final long callingId = Binder.clearCallingIdentity();
+        try {
+            mountService.changeUserKey(userId, userInfo.serialNumber, token, null, secret);
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java
index 6009984..f5f7732 100644
--- a/services/core/java/com/android/server/NativeDaemonConnector.java
+++ b/services/core/java/com/android/server/NativeDaemonConnector.java
@@ -41,6 +41,7 @@
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.LinkedList;
 
@@ -344,6 +345,30 @@
     }
 
     /**
+     * Method that waits until all asychronous notifications sent by the native daemon have
+     * been processed. This method must not be called on the notification thread or an
+     * exception will be thrown.
+     */
+    public void waitForCallbacks() {
+        if (Thread.currentThread() == mLooper.getThread()) {
+            throw new IllegalStateException("Must not call this method on callback thread");
+        }
+
+        final CountDownLatch latch = new CountDownLatch(1);
+        mCallbackHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                latch.countDown();
+            }
+        });
+        try {
+            latch.await();
+        } catch (InterruptedException e) {
+            Slog.wtf(TAG, "Interrupted while waiting for unsolicited response handling", e);
+        }
+    }
+
+    /**
      * Issue the given command to the native daemon and return a single expected
      * response.
      *
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index fffd850..7458898 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -1507,6 +1507,11 @@
         } catch (NativeDaemonConnectorException e) {
             throw e.rethrowAsParcelableException();
         }
+
+        // Ensure that before we return from this command, any asynchronous
+        // notifications generated before the command completed have been
+        // processed by all NetworkManagementEventObservers.
+        mConnector.waitForCallbacks();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 4791818..87dedc9 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -4696,26 +4696,20 @@
             ceHelper.getWritableDatabase();
             ceHelper.close();
             if (removeOldDb) {
-                // TODO STOPSHIP - backup file during testing. Remove file before the release
-                Log.i(TAG, "Migration complete - creating backup of old db " + preNDatabaseFile);
-                renameToBakFile(preNDatabaseFile);
+                Slog.i(TAG, "Migration complete - removing pre-N db " + preNDatabaseFile);
+                if (!SQLiteDatabase.deleteDatabase(preNDatabaseFile)) {
+                    Slog.e(TAG, "Cannot remove pre-N db " + preNDatabaseFile);
+                }
             }
             return ceHelper;
         }
 
-        private static void renameToBakFile(File file) {
-            File bakFile = new File(file.getPath() + ".bak");
-            if (!file.renameTo(bakFile)) {
-                Log.e(TAG, "Cannot move file to " + bakFile);
-            }
-        }
-
         private static boolean migratePreNDbToCe(File oldDbFile, File ceDbFile) {
-            Log.i(TAG, "Moving pre-N DB " + oldDbFile + " to CE " + ceDbFile);
+            Slog.i(TAG, "Moving pre-N DB " + oldDbFile + " to CE " + ceDbFile);
             try {
                 FileUtils.copyFileOrThrow(oldDbFile, ceDbFile);
             } catch (IOException e) {
-                Log.e(TAG, "Cannot copy file to " + ceDbFile + " from " + oldDbFile, e);
+                Slog.e(TAG, "Cannot copy file to " + ceDbFile + " from " + oldDbFile, e);
                 // Try to remove potentially damaged file if I/O error occurred
                 deleteDbFileWarnIfFailed(ceDbFile);
                 return false;
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 5b8d98c..b075279 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -711,6 +711,8 @@
                         updateServiceForegroundLocked(r.app, true);
                     }
                     getServiceMap(r.userId).ensureNotStartingBackground(r);
+                    mAm.notifyPackageUse(r.serviceInfo.packageName,
+                                         PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE);
                 } else {
                     if (r.isForeground) {
                         r.isForeground = false;
@@ -1756,7 +1758,8 @@
             synchronized (r.stats.getBatteryStats()) {
                 r.stats.startLaunchedLocked();
             }
-            mAm.notifyPackageUse(r.serviceInfo.packageName);
+            mAm.notifyPackageUse(r.serviceInfo.packageName,
+                                 PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
             app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
             app.thread.scheduleCreateService(r, r.serviceInfo,
                     mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3b024cf..162dddf 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -341,6 +341,7 @@
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
@@ -3350,10 +3351,10 @@
         return proc;
     }
 
-    void notifyPackageUse(String packageName) {
+    void notifyPackageUse(String packageName, int reason) {
         IPackageManager pm = AppGlobals.getPackageManager();
         try {
-            pm.notifyPackageUse(packageName);
+            pm.notifyPackageUse(packageName, reason);
         } catch (RemoteException e) {
         }
     }
@@ -6363,11 +6364,9 @@
                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
             }
 
-            notifyPackageUse(app.instrumentationInfo != null
-                    ? app.instrumentationInfo.packageName
-                    : app.info.packageName);
             if (app.instrumentationClass != null) {
-                notifyPackageUse(app.instrumentationClass.getPackageName());
+                notifyPackageUse(app.instrumentationClass.getPackageName(),
+                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
             }
             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
                     + processName + " with config " + mConfiguration);
@@ -6447,7 +6446,8 @@
         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
                     "New app is backup target, launching agent for " + app);
-            notifyPackageUse(mBackupTarget.appInfo.packageName);
+            notifyPackageUse(mBackupTarget.appInfo.packageName,
+                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
             try {
                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
@@ -9613,8 +9613,13 @@
                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
                             null /* initialBounds */);
                 }
-                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
-                        "moveTaskToStack", ANIMATE);
+                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
+                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
+                if (result && stackId == DOCKED_STACK_ID) {
+                    // If task moved to docked stack - show recents if needed.
+                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
+                            "moveTaskToDockedStack");
+                }
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -10094,7 +10099,8 @@
                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
                             mProcessStats);
                 }
-                notifyPackageUse(cpi.applicationInfo.packageName);
+                notifyPackageUse(cpi.applicationInfo.packageName,
+                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
             }
         }
         return providers;
@@ -17169,6 +17175,7 @@
         if (isCallerSystem) {
             if (isProtectedBroadcast
                     || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
+                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
                     || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
                     || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
                     || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index b043311..3df4a61 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -116,6 +116,7 @@
 import android.service.voice.IVoiceInteractionSession;
 import android.util.ArraySet;
 import android.util.EventLog;
+import android.util.Log;
 import android.util.Slog;
 import android.view.Display;
 
@@ -3431,8 +3432,10 @@
                 mWindowManager.prepareAppTransition(transit, false);
                 mWindowManager.setAppVisibility(r.appToken, false);
                 mWindowManager.executeAppTransition();
+                mStackSupervisor.mWaitingVisibleActivities.add(r);
             }
-            return finishCurrentActivityLocked(r, FINISH_AFTER_PAUSE, oomAdj) == null;
+            return finishCurrentActivityLocked(r, (r.visible || r.nowVisible) ?
+                    FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null;
         } else {
             if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
         }
@@ -5023,10 +5026,20 @@
     }
 
     void positionTask(final TaskRecord task, int position) {
+        final ActivityRecord topRunningActivity = task.topRunningActivityLocked();
+        final boolean wasResumed = topRunningActivity == task.stack.mResumedActivity;
         final ActivityStack prevStack = preAddTask(task, "positionTask");
         task.stack = this;
         insertTaskAtPosition(task, position);
         postAddTask(task, prevStack);
+        if (wasResumed) {
+            if (mResumedActivity != null) {
+                Log.wtf(TAG, "mResumedActivity was already set when moving mResumedActivity from"
+                        + " other stack to this stack mResumedActivity=" + mResumedActivity
+                        + " other mResumedActivity=" + topRunningActivity);
+            }
+            mResumedActivity = topRunningActivity;
+        }
     }
 
     private ActivityStack preAddTask(TaskRecord task, String reason) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 97ee744..f281683 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -30,8 +30,6 @@
 import android.app.IActivityContainerCallback;
 import android.app.IActivityManager;
 import android.app.IActivityManager.WaitResult;
-import android.app.KeyguardManager;
-import android.app.PendingIntent;
 import android.app.ProfilerInfo;
 import android.app.ResultInfo;
 import android.app.StatusBarManager;
@@ -40,7 +38,6 @@
 import android.content.Context;
 import android.content.IIntentSender;
 import android.content.Intent;
-import android.content.IntentSender;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
@@ -171,6 +168,7 @@
 import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
 import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
 import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
+import static com.android.server.am.ActivityStack.STACK_VISIBLE;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
@@ -1215,7 +1213,8 @@
                 // Home process is the root process of the task.
                 mService.mHomeProcess = task.mActivities.get(0).app;
             }
-            mService.notifyPackageUse(r.intent.getComponent().getPackageName());
+            mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
+                                      PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
             r.sleeping = false;
             r.forceNewConfig = false;
             mService.showAskCompatModeDialogLocked(r);
@@ -3399,6 +3398,7 @@
         info.displayId = Display.DEFAULT_DISPLAY;
         info.stackId = stack.mStackId;
         info.userId = stack.mCurrentUser;
+        info.visible = stack.getStackVisibilityLocked(null) == STACK_VISIBLE;
 
         ArrayList<TaskRecord> tasks = stack.getAllTasks();
         final int numTasks = tasks.size();
@@ -3421,6 +3421,9 @@
         info.taskNames = taskNames;
         info.taskBounds = taskBounds;
         info.taskUserIds = taskUserIds;
+
+        final ActivityRecord top = stack.topRunningActivityLocked();
+        info.topActivity = top != null ? top.intent.getComponent() : null;
         return info;
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 4da6976..6622b34 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -527,8 +527,13 @@
 
         doPendingActivityLaunchesLocked(false);
 
-        err = startActivityUnchecked(
-                r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask);
+        try {
+            mService.mWindowManager.deferSurfaceLayout();
+            err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
+                    true, options, inTask);
+        } finally {
+            mService.mWindowManager.continueSurfaceLayout();
+        }
         postStartActivityUncheckedProcessing(r, err, stack.mStackId);
         return err;
     }
@@ -1853,6 +1858,12 @@
 
     private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
             ActivityOptions aOptions) {
+
+        // We are reusing a task, keep the stack!
+        if (mReuseTask != null) {
+            return mReuseTask.stack;
+        }
+
         final int launchStackId =
                 (aOptions != null) ? aOptions.getLaunchStackId() : INVALID_STACK_ID;
 
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 68bd2fd..e9ed34b 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -293,19 +293,7 @@
             return;
         }
 
-        if (proc.thread != null) {
-            if (proc.pid == Process.myPid()) {
-                Log.w(TAG, "crashApplication: trying to crash self!");
-                return;
-            }
-            long ident = Binder.clearCallingIdentity();
-            try {
-                proc.thread.scheduleCrash(message);
-            } catch (RemoteException e) {
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
+        proc.scheduleCrash(message);
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 37c7765..1222f54 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -38,6 +38,7 @@
 import android.content.pm.ResolveInfo;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.DeadObjectException;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -273,7 +274,8 @@
             if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
                     "Delivering to component " + r.curComponent
                     + ": " + r);
-            mService.notifyPackageUse(r.intent.getComponent().getPackageName());
+            mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
+                                      PackageManager.NOTIFY_PACKAGE_USE_BROADCAST_RECEIVER);
             app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
                     mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
                     r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
@@ -446,7 +448,7 @@
         }
     }
 
-    private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
+    private void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
             Intent intent, int resultCode, String data, Bundle extras,
             boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
         // Send the intent to the receiver asynchronously using one-way binder calls.
@@ -454,8 +456,23 @@
             if (app.thread != null) {
                 // If we have an app thread, do the call through that so it is
                 // correctly ordered with other one-way calls.
-                app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
-                        data, extras, ordered, sticky, sendingUser, app.repProcState);
+                try {
+                    app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
+                            data, extras, ordered, sticky, sendingUser, app.repProcState);
+                // TODO: Uncomment this when (b/28322359) is fixed and we aren't getting
+                // DeadObjectException when the process isn't actually dead.
+                //} catch (DeadObjectException ex) {
+                // Failed to call into the process.  It's dying so just let it die and move on.
+                //    throw ex;
+                } catch (RemoteException ex) {
+                    // Failed to call into the process. It's either dying or wedged. Kill it gently.
+                    synchronized (mService) {
+                        Slog.w(TAG, "Can't deliver broadcast to " + app.processName
+                                + " (pid " + app.pid + "). Crashing it.");
+                        app.scheduleCrash("can't deliver broadcast");
+                    }
+                    throw ex;
+                }
             } else {
                 // Application has died. Receiver doesn't exist.
                 throw new RemoteException("app.thread must not be null");
@@ -853,6 +870,7 @@
                             Slog.w(TAG, "Failure ["
                                     + mQueueName + "] sending broadcast result of "
                                     + r.intent, e);
+
                         }
                     }
 
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 93d4060..059acbd 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -37,9 +37,11 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.res.CompatibilityInfo;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Process;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
@@ -552,6 +554,29 @@
         return adj;
     }
 
+    void scheduleCrash(String message) {
+        // Checking killedbyAm should keep it from showing the crash dialog if the process
+        // was already dead for a good / normal reason.
+        if (!killedByAm) {
+            if (thread != null) {
+                if (pid == Process.myPid()) {
+                    Slog.w(TAG, "scheduleCrash: trying to crash system process!");
+                    return;
+                }
+                long ident = Binder.clearCallingIdentity();
+                try {
+                    thread.scheduleCrash(message);
+                } catch (RemoteException e) {
+                    // If it's already dead our work is done. If it's wedged just kill it.
+                    // We won't get the crash dialog or the error reporting.
+                    kill("scheduleCrash for '" + message + "' failed", true);
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
+            }
+        }
+    }
+
     void kill(String reason, boolean noisy) {
         if (!killedByAm) {
             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill");
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index 381a110..f7784ac 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -34,9 +34,8 @@
 import android.net.ProxyInfo;
 import android.net.TrafficStats;
 import android.net.Uri;
-import android.net.metrics.CaptivePortalCheckResultEvent;
-import android.net.metrics.CaptivePortalStateChangeEvent;
-import android.net.metrics.NetworkMonitorEvent;
+import android.net.metrics.ValidationProbeEvent;
+import android.net.metrics.NetworkEvent;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.net.util.Stopwatch;
@@ -306,13 +305,11 @@
                     transitionTo(mLingeringState);
                     return HANDLED;
                 case CMD_NETWORK_CONNECTED:
-                    CaptivePortalStateChangeEvent.logEvent(mNetId,
-                            CaptivePortalStateChangeEvent.NETWORK_MONITOR_CONNECTED);
+                    NetworkEvent.logEvent(mNetId, NetworkEvent.NETWORK_CONNECTED);
                     transitionTo(mEvaluatingState);
                     return HANDLED;
                 case CMD_NETWORK_DISCONNECTED:
-                    CaptivePortalStateChangeEvent.logEvent(mNetId,
-                            CaptivePortalStateChangeEvent.NETWORK_MONITOR_DISCONNECTED);
+                    NetworkEvent.logEvent(mNetId, NetworkEvent.NETWORK_DISCONNECTED);
                     if (mLaunchCaptivePortalAppBroadcastReceiver != null) {
                         mContext.unregisterReceiver(mLaunchCaptivePortalAppBroadcastReceiver);
                         mLaunchCaptivePortalAppBroadcastReceiver = null;
@@ -363,11 +360,9 @@
         @Override
         public void enter() {
             if (mEvaluationTimer.isRunning()) {
-                NetworkMonitorEvent.logValidated(mNetId, mEvaluationTimer.stop());
+                NetworkEvent.logValidated(mNetId, mEvaluationTimer.stop());
                 mEvaluationTimer.reset();
             }
-            CaptivePortalStateChangeEvent.logEvent(mNetId,
-                   CaptivePortalStateChangeEvent.NETWORK_MONITOR_VALIDATED);
             mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED,
                     NETWORK_TEST_RESULT_VALID, mNetworkAgentInfo.network.netId, null));
         }
@@ -497,7 +492,6 @@
                     // will be unresponsive. isCaptivePortal() could be executed on another Thread
                     // if this is found to cause problems.
                     CaptivePortalProbeResult probeResult = isCaptivePortal();
-                    CaptivePortalCheckResultEvent.logEvent(mNetId, probeResult.mHttpResponseCode);
                     if (probeResult.mHttpResponseCode == 204) {
                         transitionTo(mValidatedState);
                     } else if (probeResult.mHttpResponseCode >= 200 &&
@@ -508,6 +502,7 @@
                     } else {
                         final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
                         sendMessageDelayed(msg, mReevaluateDelayMs);
+                        NetworkEvent.logEvent(mNetId, NetworkEvent.NETWORK_VALIDATION_FAILED);
                         mConnectivityServiceHandler.sendMessage(obtainMessage(
                                 EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, mNetId,
                                 probeResult.mRedirectUrl));
@@ -568,7 +563,7 @@
         @Override
         public void enter() {
             if (mEvaluationTimer.isRunning()) {
-                NetworkMonitorEvent.logCaptivePortalFound(mNetId, mEvaluationTimer.stop());
+                NetworkEvent.logCaptivePortalFound(mNetId, mEvaluationTimer.stop());
                 mEvaluationTimer.reset();
             }
             // Don't annoy user with sign-in notifications.
@@ -779,7 +774,8 @@
                 urlConnection.disconnect();
             }
         }
-        NetworkMonitorEvent.logPortalProbeEvent(mNetId, probeTimer.stop(), httpResponseCode);
+        final int probeType = ValidationProbeEvent.PROBE_HTTP;
+        ValidationProbeEvent.logEvent(mNetId, probeTimer.stop(), probeType, httpResponseCode);
         return new CaptivePortalProbeResult(httpResponseCode, redirectUrl);
     }
 
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 79b5978..c2022d5 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -273,9 +273,6 @@
                     // ignore usb0 down after enabling RNDIS
                     // we will handle disconnect in interfaceRemoved instead
                     if (VDBG) Log.d(TAG, "ignore interface down for " + iface);
-                } else if (isWifi(iface)) {
-                    // handle disconnect in interfaceRemoved
-                    if (VDBG) Log.d(TAG, "ignore interface down for " + iface);
                 } else if (sm != null) {
                     sm.sendMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN);
                     mIfaces.remove(iface);
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 5c80d04..c16dac2 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -147,6 +147,9 @@
     // A ring buffer containing all of the recent ambient light sensor readings.
     private AmbientLightRingBuffer mAmbientLightRingBuffer;
 
+    // A ring buffer containing the light sensor readings for the initial horizon period.
+    private AmbientLightRingBuffer mInitialHorizonAmbientLightRingBuffer;
+
     // The handler
     private AutomaticBrightnessHandler mHandler;
 
@@ -204,7 +207,10 @@
         mScreenAutoBrightnessAdjustmentMaxGamma = autoBrightnessAdjustmentMaxGamma;
 
         mHandler = new AutomaticBrightnessHandler(looper);
-        mAmbientLightRingBuffer = new AmbientLightRingBuffer(mLightSensorRate, mAmbientLightHorizon);
+        mAmbientLightRingBuffer =
+            new AmbientLightRingBuffer(mLightSensorRate, mAmbientLightHorizon);
+        mInitialHorizonAmbientLightRingBuffer =
+            new AmbientLightRingBuffer(mLightSensorRate, mAmbientLightHorizon);
 
         if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
             mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
@@ -273,6 +279,8 @@
         pw.println("  mLastObservedLuxTime=" + TimeUtils.formatUptime(mLastObservedLuxTime));
         pw.println("  mRecentLightSamples=" + mRecentLightSamples);
         pw.println("  mAmbientLightRingBuffer=" + mAmbientLightRingBuffer);
+        pw.println("  mInitialHorizonAmbientLightRingBuffer=" +
+                mInitialHorizonAmbientLightRingBuffer);
         pw.println("  mScreenAutoBrightness=" + mScreenAutoBrightness);
         pw.println("  mScreenAutoBrightnessAdjustment=" + mScreenAutoBrightnessAdjustment);
         pw.println("  mScreenAutoBrightnessAdjustmentMaxGamma=" + mScreenAutoBrightnessAdjustmentMaxGamma);
@@ -295,6 +303,7 @@
                 mAmbientLuxValid = !mResetAmbientLuxAfterWarmUpConfig;
                 mRecentLightSamples = 0;
                 mAmbientLightRingBuffer.clear();
+                mInitialHorizonAmbientLightRingBuffer.clear();
                 mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX);
                 mSensorManager.unregisterListener(mLightSensorListener);
             }
@@ -311,6 +320,11 @@
 
     private void applyLightSensorMeasurement(long time, float lux) {
         mRecentLightSamples++;
+        // Store all of the light measurements for the intial horizon period. This is to help
+        // diagnose dim wake ups and slow responses in b/27951906.
+        if (time <= mLightSensorEnableTime + mAmbientLightHorizon) {
+            mInitialHorizonAmbientLightRingBuffer.push(time, lux);
+        }
         mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
         mAmbientLightRingBuffer.push(time, lux);
 
@@ -617,7 +631,7 @@
         void updateBrightness();
     }
 
-    private static final class AmbientLightRingBuffer{
+    private static final class AmbientLightRingBuffer {
         // Proportional extra capacity of the buffer beyond the expected number of light samples
         // in the horizon
         private static final float BUFFER_SLACK = 1.5f;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 0633625..f285dec 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1152,16 +1152,24 @@
                     try {
                         f = file.startWrite();
                         BufferedOutputStream out = new BufferedOutputStream(f);
-                        FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
+                        FileUtils.setPermissions(file.getBaseFile().getPath(),
+                                0640, SYSTEM_UID, PACKAGE_INFO_GID);
                         StringBuilder sb = new StringBuilder();
+
+                        sb.append(USAGE_FILE_MAGIC_VERSION_1);
+                        sb.append('\n');
+                        out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
+
                         for (PackageParser.Package pkg : mPackages.values()) {
-                            if (pkg.mLastPackageUsageTimeInMills == 0) {
+                            if (pkg.getLatestPackageUseTimeInMills() == 0L) {
                                 continue;
                             }
                             sb.setLength(0);
                             sb.append(pkg.packageName);
-                            sb.append(' ');
-                            sb.append((long)pkg.mLastPackageUsageTimeInMills);
+                            for (long usageTimeInMillis : pkg.mLastPackageUsageTimeInMills) {
+                                sb.append(' ');
+                                sb.append(usageTimeInMillis);
+                            }
                             sb.append('\n');
                             out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
                         }
@@ -1185,28 +1193,12 @@
                 try {
                     in = new BufferedInputStream(file.openRead());
                     StringBuffer sb = new StringBuffer();
-                    while (true) {
-                        String packageName = readToken(in, sb, ' ');
-                        if (packageName == null) {
-                            break;
-                        }
-                        String timeInMillisString = readToken(in, sb, '\n');
-                        if (timeInMillisString == null) {
-                            throw new IOException("Failed to find last usage time for package "
-                                                  + packageName);
-                        }
-                        PackageParser.Package pkg = mPackages.get(packageName);
-                        if (pkg == null) {
-                            continue;
-                        }
-                        long timeInMillis;
-                        try {
-                            timeInMillis = Long.parseLong(timeInMillisString);
-                        } catch (NumberFormatException e) {
-                            throw new IOException("Failed to parse " + timeInMillisString
-                                                  + " as a long.", e);
-                        }
-                        pkg.mLastPackageUsageTimeInMills = timeInMillis;
+
+                    String firstLine = readLine(in, sb);
+                    if (firstLine.equals(USAGE_FILE_MAGIC_VERSION_1)) {
+                        readVersion1LP(in, sb);
+                    } else {
+                        readVersion0LP(in, sb, firstLine);
                     }
                 } catch (FileNotFoundException expected) {
                     mIsHistoricalPackageUsageAvailable = false;
@@ -1219,6 +1211,76 @@
             mLastWritten.set(SystemClock.elapsedRealtime());
         }
 
+        private void readVersion0LP(InputStream in, StringBuffer sb, String firstLine)
+                throws IOException {
+            // Initial version of the file had no version number and stored one
+            // package-timestamp pair per line.
+            // Note that the first line has already been read from the InputStream.
+            String line = firstLine;
+            while (true) {
+                if (line == null) {
+                    break;
+                }
+
+                String[] tokens = line.split(" ");
+                if (tokens.length != 2) {
+                    throw new IOException("Failed to parse " + line +
+                            " as package-timestamp pair.");
+                }
+
+                String packageName = tokens[0];
+                PackageParser.Package pkg = mPackages.get(packageName);
+                if (pkg == null) {
+                    continue;
+                }
+
+                long timestamp = parseAsLong(tokens[1]);
+                for (int reason = 0;
+                        reason < PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT;
+                        reason++) {
+                    pkg.mLastPackageUsageTimeInMills[reason] = timestamp;
+                }
+
+                line = readLine(in, sb);
+            }
+        }
+
+        private void readVersion1LP(InputStream in, StringBuffer sb) throws IOException {
+            // Version 1 of the file started with the corresponding version
+            // number and then stored a package name and eight timestamps per line.
+            String line;
+            while ((line = readLine(in, sb)) != null) {
+                String[] tokens = line.split(" ");
+                if (tokens.length != PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT + 1) {
+                    throw new IOException("Failed to parse " + line + " as a timestamp array.");
+                }
+
+                String packageName = tokens[0];
+                PackageParser.Package pkg = mPackages.get(packageName);
+                if (pkg == null) {
+                    continue;
+                }
+
+                for (int reason = 0;
+                        reason < PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT;
+                        reason++) {
+                    pkg.mLastPackageUsageTimeInMills[reason] = parseAsLong(tokens[reason + 1]);
+                }
+            }
+        }
+
+        private long parseAsLong(String token) throws IOException {
+            try {
+                return Long.parseLong(token);
+            } catch (NumberFormatException e) {
+                throw new IOException("Failed to parse " + token + " as a long.", e);
+            }
+        }
+
+        private String readLine(InputStream in, StringBuffer sb) throws IOException {
+            return readToken(in, sb, '\n');
+        }
+
         private String readToken(InputStream in, StringBuffer sb, char endOfToken)
                 throws IOException {
             sb.setLength(0);
@@ -1243,6 +1305,9 @@
             File fname = new File(systemDir, "package-usage.list");
             return new AtomicFile(fname);
         }
+
+        private static final String USAGE_FILE_MAGIC = "PACKAGE_USAGE__VERSION_";
+        private static final String USAGE_FILE_MAGIC_VERSION_1 = USAGE_FILE_MAGIC + "1";
     }
 
     class PackageHandler extends Handler {
@@ -7130,13 +7195,13 @@
     }
 
     @Override
-    public void notifyPackageUse(String packageName) {
+    public void notifyPackageUse(String packageName, int reason) {
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
             if (p == null) {
                 return;
             }
-            p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
+            p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index f79d6ee..3c065ae 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -69,7 +69,7 @@
         long now = System.currentTimeMillis();
         for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
             PackageParser.Package pkg = i.next();
-            long then = pkg.mLastPackageUsageTimeInMills;
+            long then = pkg.getLatestPackageUseTimeInMills();
             if (then + dexOptLRUThresholdInMills < now) {
                 if (DEBUG_DEXOPT) {
                     Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 93e4d31..7ea5919 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -632,15 +632,6 @@
         intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier());
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
         mContext.sendBroadcastAsUser(intent, parentHandle);
-
-        //TODO: remove once Launcher3 is updated.
-        Intent oldIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED);
-        oldIntent.putExtra(Intent.EXTRA_QUIET_MODE, inQuietMode);
-        oldIntent.putExtra(Intent.EXTRA_USER, profileHandle);
-        oldIntent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier());
-        oldIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-        mContext.sendBroadcastAsUser(oldIntent, parentHandle);
-
     }
 
     @Override
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 007190d..9f31f4f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3301,6 +3301,7 @@
                         shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                         try {
                             startActivityAsUser(shortcutIntent, UserHandle.CURRENT);
+                            dismissKeyboardShortcutsMenu();
                         } catch (ActivityNotFoundException ex) {
                             Slog.w(TAG, "Dropping shortcut key combination because "
                                     + "the activity to which it is registered was not found: "
@@ -3327,6 +3328,7 @@
                     shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                     try {
                         startActivityAsUser(shortcutIntent, UserHandle.CURRENT);
+                        dismissKeyboardShortcutsMenu();
                     } catch (ActivityNotFoundException ex) {
                         Slog.w(TAG, "Dropping shortcut key combination because "
                                 + "the activity to which it is registered was not found: "
@@ -3345,6 +3347,7 @@
                 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 try {
                     startActivityAsUser(intent, UserHandle.CURRENT);
+                    dismissKeyboardShortcutsMenu();
                 } catch (ActivityNotFoundException ex) {
                     Slog.w(TAG, "Dropping application launch key because "
                             + "the activity to which it is registered was not found: "
@@ -3635,6 +3638,13 @@
         }
     }
 
+    private void dismissKeyboardShortcutsMenu() {
+        StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
+        if (statusbar != null) {
+            statusbar.dismissKeyboardShortcutsMenu();
+        }
+    }
+
     private void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHome) {
         mPreloadedRecentApps = false; // preloading no longer needs to be canceled
         StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 38a3d01..52b2439 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -37,6 +37,7 @@
 
     void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
 
+    void dismissKeyboardShortcutsMenu();
     void toggleKeyboardShortcutsMenu(int deviceId);
 
     /**
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 9020677..c630d4a 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -277,6 +277,15 @@
         }
 
         @Override
+        public void dismissKeyboardShortcutsMenu() {
+            if (mBar != null) {
+                try {
+                    mBar.dismissKeyboardShortcutsMenu();
+                } catch (RemoteException ex) {}
+            }
+        }
+
+        @Override
         public void toggleKeyboardShortcutsMenu(int deviceId) {
             if (mBar != null) {
                 try {
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 11b01cc..9199d10 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -1914,6 +1914,14 @@
                 setAppTransition(transit);
             }
         }
+        if (transit != TRANSIT_DOCK_TASK_FROM_RECENTS
+                && mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS) {
+
+            // Somebody is trying to start another transition while we are waiting for the docking
+            // window to be drawn. Because TRANSIT_DOCK_TASK_FROM_RECENTS starts prolonged
+            // animations, we need to override it or our prolonged animations will never be ended.
+            setAppTransition(transit);
+        }
         boolean prepared = prepare();
         if (isTransitionSet()) {
             mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index aae52e8..abb1bb1 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -433,7 +433,7 @@
             WindowStateAnimator winAnimator = mAllAppWinAnimators.get(i);
             if (DEBUG_VISIBILITY) Slog.v(TAG, "performing show on: " + winAnimator);
             winAnimator.performShowLocked();
-            isAnimating |= winAnimator.isAnimating();
+            isAnimating |= winAnimator.isAnimationSet();
         }
         return isAnimating;
     }
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 545b9db..9f54b53 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -204,7 +204,7 @@
             if (DEBUG_VISIBILITY) {
                 Slog.v(TAG, "Win " + win + ": isDrawn="
                         + win.isDrawnLw()
-                        + ", isAnimating=" + win.mWinAnimator.isAnimating());
+                        + ", isAnimationSet=" + win.mWinAnimator.isAnimationSet());
                 if (!win.isDrawnLw()) {
                     Slog.v(TAG, "Not displayed: s=" +
                             win.mWinAnimator.mSurfaceController
@@ -220,11 +220,11 @@
             numInteresting++;
             if (win.isDrawnLw()) {
                 numDrawn++;
-                if (!win.mWinAnimator.isAnimating()) {
+                if (!win.mWinAnimator.isAnimationSet()) {
                     numVisible++;
                 }
                 nowGone = false;
-            } else if (win.mWinAnimator.isAnimating()) {
+            } else if (win.mWinAnimator.isAnimationSet()) {
                 nowGone = false;
             }
         }
@@ -297,7 +297,7 @@
             // Return true so that the alpha doesn't get cleared.
             if (!win.mAppFreezing
                     && (win.mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface
-                            || (win.mWinAnimator.isAnimating()
+                            || (win.mWinAnimator.isAnimationSet()
                                     && !service.mAppTransition.isTransitionSet()))
                     && !win.mDestroying
                     && win.isDrawnLw()) {
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 8a003de..30ba28a 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -353,7 +353,7 @@
             stack.getDimBounds(mTmpRect);
             if (mTmpRect.height() > 0 && mTmpRect.width() > 0) {
                 mDimLayer.setBounds(mTmpRect);
-                mDimLayer.show(mDisplayContent.mService.mLayersController.getResizeDimLayer(),
+                mDimLayer.show(mService.mLayersController.getResizeDimLayer(),
                         alpha, 0 /* duration */);
             } else {
                 visibleAndValid = false;
@@ -543,6 +543,9 @@
         } else if (mAnimatingForIme) {
             return animateForIme(now);
         } else {
+            if (mDimLayer != null) {
+                mDimLayer.setLayer(mService.mLayersController.getResizeDimLayer());
+            }
             return false;
         }
     }
diff --git a/services/core/java/com/android/server/wm/DropPermissionsHandler.java b/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
similarity index 91%
rename from services/core/java/com/android/server/wm/DropPermissionsHandler.java
rename to services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
index 5889fb8..1831ff9 100644
--- a/services/core/java/com/android/server/wm/DropPermissionsHandler.java
+++ b/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
@@ -23,11 +23,12 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 
-import com.android.internal.view.IDropPermissions;
+import com.android.internal.view.IDragAndDropPermissions;
 
 import java.util.ArrayList;
 
-class DropPermissionsHandler extends IDropPermissions.Stub implements IBinder.DeathRecipient {
+class DragAndDropPermissionsHandler extends IDragAndDropPermissions.Stub
+        implements IBinder.DeathRecipient {
 
     private final int mSourceUid;
     private final String mTargetPackage;
@@ -40,8 +41,8 @@
     private IBinder mActivityToken = null;
     private IBinder mPermissionOwnerToken = null;
 
-    DropPermissionsHandler(ClipData clipData, int sourceUid, String targetPackage, int mode,
-            int sourceUserId, int targetUserId) {
+    DragAndDropPermissionsHandler(ClipData clipData, int sourceUid, String targetPackage, int mode,
+                                  int sourceUserId, int targetUserId) {
         mSourceUid = sourceUid;
         mTargetPackage = targetPackage;
         mMode = mode;
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index ffe0336..0539b05 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -59,7 +59,7 @@
 import com.android.server.wm.WindowManagerService.DragInputEventReceiver;
 import com.android.server.wm.WindowManagerService.H;
 
-import com.android.internal.view.IDropPermissions;
+import com.android.internal.view.IDragAndDropPermissions;
 
 import java.util.ArrayList;
 
@@ -484,10 +484,10 @@
 
         final int targetUserId = UserHandle.getUserId(touchedWin.getOwningUid());
 
-        DropPermissionsHandler dropPermissions = null;
+        DragAndDropPermissionsHandler dragAndDropPermissions = null;
         if ((mFlags & View.DRAG_FLAG_GLOBAL) != 0 &&
                 (mFlags & DRAG_FLAGS_URI_ACCESS) != 0) {
-            dropPermissions = new DropPermissionsHandler(
+            dragAndDropPermissions = new DragAndDropPermissionsHandler(
                     mData,
                     mUid,
                     touchedWin.getOwningPackage(),
@@ -501,7 +501,7 @@
         final int myPid = Process.myPid();
         final IBinder token = touchedWin.mClient.asBinder();
         DragEvent evt = obtainDragEvent(touchedWin, DragEvent.ACTION_DROP, x, y,
-                null, null, mData, dropPermissions, false);
+                null, null, mData, dragAndDropPermissions, false);
         try {
             touchedWin.mClient.dispatchDragEvent(evt);
 
@@ -524,12 +524,12 @@
     private static DragEvent obtainDragEvent(WindowState win, int action,
             float x, float y, Object localState,
             ClipDescription description, ClipData data,
-            IDropPermissions dropPermissions,
+            IDragAndDropPermissions dragAndDropPermissions,
             boolean result) {
         final float winX = win.translateToWindowX(x);
         final float winY = win.translateToWindowY(y);
         return DragEvent.obtain(action, winX, winY, localState, description, data,
-                dropPermissions, result);
+                dragAndDropPermissions, result);
     }
 
     boolean stepAnimationLocked(long currentTimeMs) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 4f49eed..6925fa5 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -601,7 +601,7 @@
                     // Anyway we don't need to synchronize position and content updates for these
                     // windows since they aren't at the base layer and could be moved around anyway.
                     if (!win.computeDragResizing() && win.mAttrs.type == TYPE_BASE_APPLICATION &&
-                            !mStack.getBoundsAnimating()) {
+                            !mStack.getBoundsAnimating() && !win.isGoneForLayoutLw()) {
                         win.mResizedWhileNotDragResizing = true;
                     }
                 }
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 96847e8..037f316 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -41,7 +41,6 @@
 import android.util.SparseArray;
 import android.view.DisplayInfo;
 import android.view.Surface;
-import android.view.animation.PathInterpolator;
 import android.view.SurfaceControl;
 
 import com.android.internal.policy.DividerSnapAlgorithm;
@@ -119,7 +118,6 @@
     // Whether the stack and all its tasks is currently being drag-resized
     private boolean mDragResizing;
 
-    private final Rect mLastContentBounds = new Rect();
     private final Rect mTmpAdjustedBounds = new Rect();
     private boolean mAdjustedForIme;
     private boolean mImeGoingAway;
@@ -503,7 +501,7 @@
                 final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
                 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
                     final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
-                    if (winAnimator.isAnimating() || winAnimator.mWin.mAnimatingExit) {
+                    if (winAnimator.isAnimationSet() || winAnimator.mWin.mAnimatingExit) {
                         return true;
                     }
                 }
@@ -655,9 +653,12 @@
         Rect bounds = null;
         final TaskStack dockedStack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
         if (mStackId == DOCKED_STACK_ID
-                || (dockedStack != null && StackId.isResizeableByDockedStack(mStackId))) {
+                || (dockedStack != null && StackId.isResizeableByDockedStack(mStackId)
+                        && !dockedStack.isFullscreen())) {
             // The existence of a docked stack affects the size of other static stack created since
-            // the docked stack occupies a dedicated region on screen.
+            // the docked stack occupies a dedicated region on screen, but only if the dock stack is
+            // not fullscreen. If it's fullscreen, it means that we are in the transition of
+            // dismissing it, so we must not resize this stack.
             bounds = new Rect();
             displayContent.getLogicalDisplayRect(mTmpRect);
             mTmpRect2.setEmpty();
@@ -984,7 +985,6 @@
             contentBounds.bottom = imeTop;
         }
 
-        mLastContentBounds.set(contentBounds);
         final int yOffset = displayContentRect.bottom - contentBounds.bottom;
 
         final int dividerWidth =
@@ -1094,7 +1094,6 @@
         }
         if (!adjust) {
             mTmpAdjustedBounds.setEmpty();
-            mLastContentBounds.setEmpty();
         }
         setAdjustedBounds(mTmpAdjustedBounds);
 
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index e44b0f3..88028be 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -146,7 +146,7 @@
     }
 
     boolean isWallpaperTargetAnimating() {
-        return mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
+        return mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimationSet()
                 && !mWallpaperTarget.mWinAnimator.isDummyAnimation();
     }
 
@@ -516,7 +516,7 @@
             if (hasWallpaper && w.isOnScreen() && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
                 if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: #" + i + "=" + w);
                 result.setWallpaperTarget(w, i);
-                if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
+                if (w == mWallpaperTarget && w.mWinAnimator.isAnimationSet()) {
                     // The current wallpaper target is animating, so we'll look behind it for
                     // another possible target and figure out what is going on later.
                     if (DEBUG_WALLPAPER) Slog.v(TAG,
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 6bc633f..eae7838 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -670,6 +670,7 @@
         if (SHOW_TRANSACTIONS) Slog.i(
                 TAG, ">>> OPEN TRANSACTION animateLocked");
         SurfaceControl.openTransaction();
+        SurfaceControl.setAnimationTransaction();
         try {
             final int numDisplays = mDisplayContentsAnimators.size();
             for (int i = 0; i < numDisplays; i++) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index aee8fc9..ff63632 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -120,7 +120,6 @@
 import android.view.WindowManagerPolicy.PointerEventListener;
 import android.view.animation.Animation;
 import android.view.inputmethod.InputMethodManagerInternal;
-import android.widget.Toast;
 
 import com.android.internal.R;
 import com.android.internal.app.IAssistScreenshotReceiver;
@@ -174,6 +173,7 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.view.WindowManager.DOCKED_BOTTOM;
 import static android.view.WindowManager.DOCKED_INVALID;
+import static android.view.WindowManager.DOCKED_TOP;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
@@ -1525,7 +1525,7 @@
 
                 if (highestTarget != null) {
                     if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, mAppTransition + " " + highestTarget
-                            + " animating=" + highestTarget.mWinAnimator.isAnimating()
+                            + " animating=" + highestTarget.mWinAnimator.isAnimationSet()
                             + " layer=" + highestTarget.mWinAnimator.mAnimLayer
                             + " new layer=" + w.mWinAnimator.mAnimLayer);
 
@@ -1535,7 +1535,7 @@
                         mInputMethodTargetWaitingAnim = true;
                         mInputMethodTarget = highestTarget;
                         return highestPos + 1;
-                    } else if (highestTarget.mWinAnimator.isAnimating() &&
+                    } else if (highestTarget.mWinAnimator.isAnimationSet() &&
                             highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
                         // If the window we are currently targeting is involved
                         // with an animation, and it is on top of the next target
@@ -2275,7 +2275,7 @@
                 + " mRemoveOnExit=" + win.mRemoveOnExit
                 + " mHasSurface=" + win.mHasSurface
                 + " surfaceShowing=" + win.mWinAnimator.getShown()
-                + " isAnimating=" + win.mWinAnimator.isAnimating()
+                + " isAnimationSet=" + win.mWinAnimator.isAnimationSet()
                 + " app-animation="
                 + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
                 + " mWillReplaceWindow=" + win.mWillReplaceWindow
@@ -2339,7 +2339,7 @@
                 }
             }
             final boolean isAnimating =
-                    winAnimator.isAnimating() && !winAnimator.isDummyAnimation();
+                    winAnimator.isAnimationSet() && !winAnimator.isDummyAnimation();
             final boolean lastWindowIsStartingWindow = startingWindow && appToken != null
                     && appToken.allAppWindows.size() == 1;
             // We delay the removal of a window if it has a showing surface that can be used to run
@@ -2924,7 +2924,7 @@
             focusMayChange = isDefaultDisplay;
             win.mAnimatingExit = true;
             win.mWinAnimator.mAnimating = true;
-        } else if (win.mWinAnimator.isAnimating()) {
+        } else if (win.mWinAnimator.isAnimationSet()) {
             // Currently in a hide animation... turn this into
             // an exit.
             win.mAnimatingExit = true;
@@ -3281,7 +3281,7 @@
                         WindowState win = wtoken.windows.get(i);
                         displayContent = win.getDisplayContent();
 
-                        if (win.mWinAnimator.isAnimating()) {
+                        if (win.mWinAnimator.isAnimationSet()) {
                             delayed = true;
                         }
 
@@ -4297,7 +4297,7 @@
         }
 
         for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
-            if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimating()) {
+            if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimationSet()) {
                 delayed = true;
             }
         }
@@ -7467,6 +7467,10 @@
         final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw();
         final boolean dockVisible = isStackVisibleLocked(DOCKED_STACK_ID);
         final TaskStack imeTargetStack = getImeTargetStackLocked();
+        final int imeDockSide = (dockVisible && imeTargetStack != null) ?
+                imeTargetStack.getDockSide() : DOCKED_INVALID;
+        final boolean imeOnTop = (imeDockSide == DOCKED_TOP);
+        final boolean imeOnBottom = (imeDockSide == DOCKED_BOTTOM);
 
         // The divider could be adjusted for IME position, or be thinner than usual,
         // or both. There are three possible cases:
@@ -7474,20 +7478,19 @@
         // - If IME is visible, and focus is on bottom, divider is moved for IME and thinner.
         // - If IME is not visible, divider is not moved and is normal width.
 
-        if (imeVisible && dockVisible && imeTargetStack != null) {
-            final boolean isFocusOnBottom = imeTargetStack.getDockSide() == DOCKED_BOTTOM;
+        if (imeVisible && dockVisible && (imeOnTop || imeOnBottom)) {
             final ArrayList<TaskStack> stacks = displayContent.getStacks();
             for (int i = stacks.size() - 1; i >= 0; --i) {
                 final TaskStack stack = stacks.get(i);
                 final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
-                if (stack.isVisibleLocked() && (isFocusOnBottom || isDockedOnBottom)) {
+                if (stack.isVisibleLocked() && (imeOnBottom || isDockedOnBottom)) {
                     stack.setAdjustedForIme(imeWin);
                 } else {
                     stack.resetAdjustedForIme(false);
                 }
             }
             displayContent.mDividerControllerLocked.setAdjustedForIme(
-                    isFocusOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin);
+                    imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin);
         } else {
             final ArrayList<TaskStack> stacks = displayContent.getStacks();
             for (int i = stacks.size() - 1; i >= 0; --i) {
@@ -9101,7 +9104,7 @@
 
     void updateResizingWindows(final WindowState w) {
         final WindowStateAnimator winAnimator = w.mWinAnimator;
-        if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) {
+        if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq && !w.isGoneForLayoutLw()) {
             w.setInsetsChanged();
             boolean configChanged = w.isConfigChanged();
             if (DEBUG_CONFIGURATION && configChanged) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index f6330c1..1493bc7 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -292,21 +292,33 @@
         }
     }
 
-    /** Is the window or its container currently animating? */
-    boolean isAnimating() {
+    /**
+     * Is the window or its container currently set to animate or currently animating?
+     */
+    boolean isAnimationSet() {
         return mAnimation != null
                 || (mAttachedWinAnimator != null && mAttachedWinAnimator.mAnimation != null)
                 || (mAppAnimator != null && mAppAnimator.isAnimating());
     }
 
+    /**
+     * @return whether an animation is about to start, i.e. the animation is set already but we
+     *         haven't processed the first frame yet.
+     */
+    boolean isAnimationStarting() {
+        return isAnimationSet() && !mAnimating;
+    }
+
     /** Is the window animating the DummyAnimation? */
     boolean isDummyAnimation() {
         return mAppAnimator != null
                 && mAppAnimator.animation == sDummyAnimation;
     }
 
-    /** Is this window currently set to animate or currently animating? */
-    boolean isWindowAnimating() {
+    /**
+     * Is this window currently set to animate or currently animating?
+     */
+    boolean isWindowAnimationSet() {
         return mAnimation != null;
     }
 
@@ -341,7 +353,7 @@
     // there is more animation to run.
     boolean stepAnimationLocked(long currentTime) {
         // Save the animation state as it was before this step so WindowManagerService can tell if
-        // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
+        // we just started or just stopped animating by comparing mWasAnimating with isAnimationSet().
         mWasAnimating = mAnimating;
         final DisplayContent displayContent = mWin.getDisplayContent();
         if (displayContent != null && mService.okToDisplay()) {
@@ -403,7 +415,7 @@
                 // Little trick to get through the path below to act like
                 // we have finished an animation.
                 mAnimating = true;
-            } else if (isAnimating()) {
+            } else if (isAnimationSet()) {
                 mAnimating = true;
             }
         } else if (mAnimation != null) {
@@ -477,7 +489,7 @@
                 TAG, "finishExit in " + this
                 + ": exiting=" + mWin.mAnimatingExit
                 + " remove=" + mWin.mRemoveOnExit
-                + " windowAnimating=" + isWindowAnimating());
+                + " windowAnimating=" + isWindowAnimationSet());
 
         if (!mWin.mChildWindows.isEmpty()) {
             // Copying to a different list as multiple children can be removed.
@@ -500,7 +512,7 @@
             }
         }
 
-        if (!isWindowAnimating()) {
+        if (!isWindowAnimationSet()) {
             //TODO (multidisplay): Accessibility is supported only for the default display.
             if (mService.mAccessibilityController != null
                     && mWin.getDisplayId() == DEFAULT_DISPLAY) {
@@ -512,7 +524,7 @@
             return;
         }
 
-        if (isWindowAnimating()) {
+        if (isWindowAnimationSet()) {
             return;
         }
 
@@ -1311,7 +1323,7 @@
         final int stackClip = resolveStackClip();
 
         // It's animating and we don't want to clip it to stack bounds during animation - abort.
-        if (isAnimating() && stackClip == STACK_CLIP_NONE) {
+        if (isAnimationSet() && stackClip == STACK_CLIP_NONE) {
             return;
         }
 
@@ -1333,7 +1345,7 @@
 
         // If we are animating, we either apply the clip before applying all the animation
         // transformation or after all the transformation.
-        final boolean useFinalClipRect = isAnimating() && stackClip == STACK_CLIP_AFTER_ANIM;
+        final boolean useFinalClipRect = isAnimationSet() && stackClip == STACK_CLIP_AFTER_ANIM;
 
         // We need to do some acrobatics with surface position, because their clip region is
         // relative to the inside of the surface, but the stack bounds aren't.
@@ -1508,7 +1520,7 @@
                 w.mToken.hasVisible = true;
             }
         } else {
-            if (DEBUG_ANIM && isAnimating()) {
+            if (DEBUG_ANIM && isAnimationSet()) {
                 Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
             }
             displayed = true;
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 928fcc0..8937f09 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -10,7 +10,6 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
@@ -762,13 +761,15 @@
                             }
                         }
                     }
-                    if (!winAnimator.isAnimating()) {
+                    if (!winAnimator.isAnimationStarting()) {
                         // Updates the shown frame before we set up the surface. This is needed
                         // because the resizing could change the top-left position (in addition to
                         // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
-                        // position the surface. We only apply it to windows that aren't animating,
-                        // because we depend on the animation to calculate the correct shown frame
-                        // on the next animation step.
+                        // position the surface.
+                        //
+                        // If an animation is being started, we can't call this method because the
+                        // animation hasn't processed its initial transformation yet, but in general
+                        // we do want to update the position if the window is animating.
                         winAnimator.computeShownFrameLocked();
                     }
                     winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
@@ -792,7 +793,7 @@
                         if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
                             Slog.v(TAG, "Eval win " + w + ": isDrawn="
                                     + w.isDrawnLw()
-                                    + ", isAnimating=" + winAnimator.isAnimating());
+                                    + ", isAnimationSet=" + winAnimator.isAnimationSet());
                             if (!w.isDrawnLw()) {
                                 Slog.v(TAG, "Not displayed: s="
                                         + winAnimator.mSurfaceController
@@ -943,7 +944,8 @@
             // windows, since that means "perform layout as normal,
             // just don't display").
             if (!gone || !win.mHaveFrame || win.mLayoutNeeded
-                    || ((win.isConfigChanged() || win.setInsetsChanged()) &&
+                    || ((win.isConfigChanged() || win.setInsetsChanged())
+                            && !win.isGoneForLayoutLw() &&
                             ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
                             (win.mHasSurface && win.mAppToken != null &&
                             win.mAppToken.layoutConfigChanges)))) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 45a7311..56e2001 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4218,6 +4218,23 @@
         }
     }
 
+    private void removeCaApprovalsIfNeeded(int userId) {
+        for (UserInfo userInfo : mUserManager.getProfiles(userId)) {
+            boolean isSecure = mLockPatternUtils.isSecure(userInfo.id);
+            if (userInfo.isManagedProfile()){
+                isSecure |= mLockPatternUtils.isSecure(getProfileParentId(userInfo.id));
+            }
+            if (!isSecure) {
+                synchronized (this) {
+                    getUserData(userInfo.id).mAcceptedCaCertificates.clear();
+                    saveSettingsLocked(userInfo.id);
+                }
+
+                new MonitoringCertNotificationTask().execute(userInfo.id);
+            }
+        }
+    }
+
     @Override
     public boolean installCaCert(ComponentName admin, byte[] certBuffer) throws RemoteException {
         enforceCanManageCaCerts(admin);
@@ -4644,6 +4661,7 @@
                         DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
                         DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userHandle);
             }
+            removeCaApprovalsIfNeeded(userHandle);
         } finally {
             mInjector.binderRestoreCallingIdentity(ident);
         }
diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java
index 52701d5..6d0808f 100644
--- a/services/net/java/android/net/dhcp/DhcpClient.java
+++ b/services/net/java/android/net/dhcp/DhcpClient.java
@@ -264,8 +264,8 @@
             mInterfaceBroadcastAddr = new PacketSocketAddress(mIface.getIndex(),
                     DhcpPacket.ETHER_BROADCAST);
             return true;
-        } catch(SocketException e) {
-            Log.wtf(TAG, "Can't determine ifindex or MAC address for " + mIfaceName);
+        } catch(SocketException | NullPointerException e) {
+            Log.e(TAG, "Can't determine ifindex or MAC address for " + mIfaceName, e);
             return false;
         }
     }
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index 59ebf1b..5667e34 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -690,7 +690,7 @@
             final InterfaceConfiguration ifcg = new InterfaceConfiguration();
             ifcg.setLinkAddress(new LinkAddress("0.0.0.0/0"));
             mNwService.setInterfaceConfig(mInterfaceName, ifcg);
-        } catch (RemoteException e) {
+        } catch (IllegalStateException | RemoteException e) {
             Log.e(mTag, "ALERT: Failed to clear IPv4 address on interface " + mInterfaceName, e);
         }
     }
diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java
index 026942e..7182161 100644
--- a/services/print/java/com/android/server/print/UserState.java
+++ b/services/print/java/com/android/server/print/UserState.java
@@ -593,7 +593,11 @@
                     new ListenerRecord<IPrintServicesChangeListener>(listener) {
                         @Override
                         public void onBinderDied() {
-                            mPrintServicesChangeListenerRecords.remove(this);
+                            synchronized (mLock) {
+                                if (mPrintServicesChangeListenerRecords != null) {
+                                    mPrintServicesChangeListenerRecords.remove(this);
+                                }
+                            }
                         }
                     });
         }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 69fdadf..343b110 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -3605,14 +3605,21 @@
     }
 
     // ICC SIM Application Types
+    /** UICC application type is SIM */
     public static final int APPTYPE_SIM = PhoneConstants.APPTYPE_SIM;
+    /** UICC application type is USIM */
     public static final int APPTYPE_USIM = PhoneConstants.APPTYPE_USIM;
+    /** UICC application type is RUIM */
     public static final int APPTYPE_RUIM = PhoneConstants.APPTYPE_RUIM;
+    /** UICC application type is CSIM */
     public static final int APPTYPE_CSIM = PhoneConstants.APPTYPE_CSIM;
+    /** UICC application type is ISIM */
     public static final int APPTYPE_ISIM = PhoneConstants.APPTYPE_ISIM;
-    // authContext (parameter P2) when doing SIM challenge,
+    // authContext (parameter P2) when doing UICC challenge,
     // per 3GPP TS 31.102 (Section 7.1.2)
+    /** Authentication type for UICC challenge is EAP SIM. See RFC 4186 for details. */
     public static final int AUTHTYPE_EAP_SIM = PhoneConstants.AUTH_CONTEXT_EAP_SIM;
+    /** Authentication type for UICC challenge is EAP AKA. See RFC 4187 for details. */
     public static final int AUTHTYPE_EAP_AKA = PhoneConstants.AUTH_CONTEXT_EAP_AKA;
 
     /**