Speed up recents -> app #2

Creating the thumbnail of the header for the transition was on the
critical path for starting the activity. This moves it off this path
by doing it after onPause().

Change-Id: Ic54a104d5ad4c40e88638566a3a69cc265a0a0fe
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 534ef77..fa97a86 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -24,12 +24,17 @@
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.net.Uri;
+import android.os.Bundle;
+import android.os.IRemoteCallback;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowInsets;
+import android.view.WindowManagerGlobal;
 import android.widget.FrameLayout;
 
 import com.android.systemui.R;
@@ -52,6 +57,8 @@
 public class RecentsView extends FrameLayout implements TaskStackView.TaskStackViewCallbacks,
         RecentsPackageMonitor.PackageCallbacks {
 
+    private static final String TAG = "RecentsView";
+
     /** The RecentsView callbacks */
     public interface RecentsViewCallbacks {
         public void onTaskViewClicked();
@@ -59,8 +66,8 @@
         public void onAllTaskViewsDismissed();
         public void onExitToHomeAnimationTriggered();
         public void onScreenPinningRequest();
-
         public void onTaskResize(Task t);
+        public void runAfterPause(Runnable r);
     }
 
     RecentsConfiguration mConfig;
@@ -438,6 +445,62 @@
         }
     }
 
+    private void postDrawHeaderThumbnailTransitionRunnable(final TaskView tv, final int offsetX,
+            final int offsetY, final TaskViewTransform transform,
+            final ActivityOptions.OnAnimationStartedListener animStartedListener) {
+        Runnable r = new Runnable() {
+            @Override
+            public void run() {
+                // Disable any focused state before we draw the header
+                if (tv.isFocusedTask()) {
+                    tv.unsetFocusedTask();
+                }
+
+                float scale = tv.getScaleX();
+                int fromHeaderWidth = (int) (tv.mHeaderView.getMeasuredWidth() * scale);
+                int fromHeaderHeight = (int) (tv.mHeaderView.getMeasuredHeight() * scale);
+
+                Bitmap b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight,
+                        Bitmap.Config.ARGB_8888);
+                if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) {
+                    b.eraseColor(0xFFff0000);
+                } else {
+                    Canvas c = new Canvas(b);
+                    c.scale(tv.getScaleX(), tv.getScaleY());
+                    tv.mHeaderView.draw(c);
+                    c.setBitmap(null);
+                }
+                b = b.createAshmemBitmap();
+                int[] pts = new int[2];
+                tv.getLocationOnScreen(pts);
+                try {
+                    WindowManagerGlobal.getWindowManagerService()
+                            .overridePendingAppTransitionAspectScaledThumb(b,
+                                    pts[0] + offsetX,
+                                    pts[1] + offsetY,
+                                    transform.rect.width(),
+                                    transform.rect.height(),
+                                    new IRemoteCallback.Stub() {
+                                        @Override
+                                        public void sendResult(Bundle data)
+                                                throws RemoteException {
+                                            post(new Runnable() {
+                                                @Override
+                                                public void run() {
+                                                    if (animStartedListener != null) {
+                                                        animStartedListener.onAnimationStarted();
+                                                    }
+                                                }
+                                            });
+                                        }
+                                    }, true);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Error overriding app transition", e);
+                }
+            }
+        };
+        mCb.runAfterPause(r);
+    }
     /**** TaskStackView.TaskStackCallbacks Implementation ****/
 
     @Override
@@ -474,32 +537,6 @@
         ActivityOptions opts = null;
         if (task.thumbnail != null && task.thumbnail.getWidth() > 0 &&
                 task.thumbnail.getHeight() > 0) {
-            Bitmap b;
-            if (tv != null) {
-                // Disable any focused state before we draw the header
-                if (tv.isFocusedTask()) {
-                    tv.unsetFocusedTask();
-                }
-
-                float scale = tv.getScaleX();
-                int fromHeaderWidth = (int) (tv.mHeaderView.getMeasuredWidth() * scale);
-                int fromHeaderHeight = (int) (tv.mHeaderView.getMeasuredHeight() * scale);
-
-                b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight,
-                        Bitmap.Config.ARGB_8888);
-                if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) {
-                    b.eraseColor(0xFFff0000);
-                } else {
-                    Canvas c = new Canvas(b);
-                    c.scale(tv.getScaleX(), tv.getScaleY());
-                    tv.mHeaderView.draw(c);
-                    c.setBitmap(null);
-                }
-            } else {
-                // Notify the system to skip the thumbnail layer by using an ALPHA_8 bitmap
-                b = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
-            }
-            Bitmap bImmut = b.createAshmemBitmap();
             ActivityOptions.OnAnimationStartedListener animStartedListener = null;
             if (lockToTask) {
                 animStartedListener = new ActivityOptions.OnAnimationStartedListener() {
@@ -518,6 +555,10 @@
                     }
                 };
             }
+            if (tv != null) {
+                postDrawHeaderThumbnailTransitionRunnable(tv, offsetX, offsetY, transform,
+                        animStartedListener);
+            }
             if (mConfig.multiStackEnabled) {
                 opts = ActivityOptions.makeCustomAnimation(sourceView.getContext(),
                         R.anim.recents_from_unknown_enter,
@@ -525,7 +566,8 @@
                         sourceView.getHandler(), animStartedListener);
             } else {
                 opts = ActivityOptions.makeThumbnailAspectScaleUpAnimation(sourceView,
-                        bImmut, offsetX, offsetY, transform.rect.width(), transform.rect.height(),
+                        Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8).createAshmemBitmap(),
+                        offsetX, offsetY, transform.rect.width(), transform.rect.height(),
                         sourceView.getHandler(), animStartedListener);
             }
         }