Merge "leanback: Fix link to changed API setTitle()" into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index 91340a9..c960ad9 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -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 {
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 39f87ad..e5a88cc1 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -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 {
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 84ce5a5..abe91bc 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -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 {
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/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/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/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
index d20b924..39eba7d 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,21 @@
         update();
     }
 
+    @android.view.RemotableViewMethod
+    public void setShowRelativeTime(boolean showRelativeTime) {
+        mShowRelativeTime = showRelativeTime;
+        updateNowText();
+        update();
+    }
+
     void update() {
         if (mTime == null) {
             return;
         }
-
-        long start = System.nanoTime();
+        if (mShowRelativeTime) {
+            updateRelativeTime();
+            return;
+        }
 
         int display;
         Date time = mTime;
@@ -181,12 +213,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/res/res/layout/notification_template_part_time.xml b/core/res/res/layout/notification_template_part_time.xml
index 442ff8c..e53f378 100644
--- a/core/res/res/layout/notification_template_part_time.xml
+++ b/core/res/res/layout/notification_template_part_time.xml
@@ -21,5 +21,6 @@
     android:layout_gravity="center"
     android:layout_marginEnd="4dp"
     android:layout_weight="0"
+    android:showRelative="true"
     android:singleLine="true"
     />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 5bfa2d4..b85ed9c 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -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 2040d7de..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/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/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/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index b043311..06d6430 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 ? 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/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 37c7765f..bbb8bdf 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;
@@ -446,7 +447,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 +455,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 +869,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/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/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 a289855..00de7e4 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;
                     }
                 }
@@ -975,7 +973,6 @@
             contentBounds.bottom = imeTop;
         }
 
-        mLastContentBounds.set(contentBounds);
         final int yOffset = displayContentRect.bottom - contentBounds.bottom;
 
         final int dividerWidth =
@@ -1085,7 +1082,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 59b0a00..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;
@@ -1526,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);
 
@@ -1536,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
@@ -2276,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
@@ -2340,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
@@ -2925,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;
@@ -3282,7 +3281,7 @@
                         WindowState win = wtoken.windows.get(i);
                         displayContent = win.getDisplayContent();
 
-                        if (win.mWinAnimator.isAnimating()) {
+                        if (win.mWinAnimator.isAnimationSet()) {
                             delayed = true;
                         }
 
@@ -4298,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;
             }
         }
@@ -9105,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 8c29c9b..f603995 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -291,21 +291,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;
     }
 
@@ -340,7 +352,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()) {
@@ -402,7 +414,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) {
@@ -476,7 +488,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.
@@ -499,7 +511,7 @@
             }
         }
 
-        if (!isWindowAnimating()) {
+        if (!isWindowAnimationSet()) {
             //TODO (multidisplay): Accessibility is supported only for the default display.
             if (mService.mAccessibilityController != null
                     && mWin.getDisplayId() == DEFAULT_DISPLAY) {
@@ -511,7 +523,7 @@
             return;
         }
 
-        if (isWindowAnimating()) {
+        if (isWindowAnimationSet()) {
             return;
         }
 
@@ -1310,7 +1322,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;
         }
 
@@ -1332,7 +1344,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.
@@ -1507,7 +1519,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)))) {