Using the RecentsService connection to toggle recents

- Adding over scroll snap back when flinging stack

Change-Id: Ife9692ece95e0a40649d0b4b72ec4ea99ffabc16
diff --git a/packages/SystemUI/src/com/android/systemui/recent/Recents.java b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
index 07c0c78..3d8a800 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
@@ -107,8 +107,10 @@
     final static int MSG_UPDATE_TASK_THUMBNAIL = 1;
     final static int MSG_PRELOAD_TASKS = 2;
     final static int MSG_CANCEL_PRELOAD_TASKS = 3;
+    final static int MSG_CLOSE_RECENTS = 4;
+    final static int MSG_TOGGLE_RECENTS = 5;
 
-    final static String sToggleRecentsAction = "com.android.systemui.recents.TOGGLE_RECENTS";
+    final static String sToggleRecentsAction = "com.android.systemui.recents.SHOW_RECENTS";
     final static String sRecentsPackage = "com.android.systemui";
     final static String sRecentsActivity = "com.android.systemui.recents.RecentsActivity";
     final static String sRecentsService = "com.android.systemui.recents.RecentsService";
@@ -419,6 +421,33 @@
 
     /** Starts the recents activity */
     void startAlternateRecentsActivity() {
+        // If Recents is the front most activity, then we should just communicate with it directly
+        // to launch the first task or dismiss itself
+        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
+        if (!tasks.isEmpty()) {
+            ComponentName topActivity = tasks.get(0).topActivity;
+            Log.d(TAG, "[RecentsComponent|topActivity] " + topActivity);
+
+            // Check if the front most activity is recents
+            if (topActivity.getPackageName().equals(sRecentsPackage) &&
+                    topActivity.getClassName().equals(sRecentsActivity)) {
+                // Notify Recents to toggle itself
+                try {
+                    Bundle data = new Bundle();
+                    Message msg = Message.obtain(null, MSG_TOGGLE_RECENTS, 0, 0);
+                    msg.setData(data);
+                    mService.send(msg);
+                } catch (RemoteException re) {
+                    re.printStackTrace();
+                }
+                return;
+            }
+        }
+
+        // XXX: If window transitions are currently happening, then we should eat up the event here
+
+        // Otherwise, Recents is not the front-most activity and we should animate into it
         Rect taskRect = mFirstTaskRect;
         if (taskRect != null && taskRect.width() > 0 && taskRect.height() > 0 && hasFirstTask()) {
             // Loading from thumbnail
@@ -511,6 +540,17 @@
     public void closeRecents() {
         if (mUseAlternateRecents) {
             Log.d(TAG, "[RecentsComponent|closeRecents]");
+            if (mServiceIsBound) {
+                // Try and update the recents configuration
+                try {
+                    Bundle data = new Bundle();
+                    Message msg = Message.obtain(null, MSG_CLOSE_RECENTS, 0, 0);
+                    msg.setData(data);
+                    mService.send(msg);
+                } catch (RemoteException re) {
+                    re.printStackTrace();
+                }
+            }
         } else {
             Intent intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT);
             intent.setPackage("com.android.systemui");
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index 62da17e..ede4ea8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -28,6 +28,7 @@
         public static class App {
             public static final boolean EnableTaskFiltering = false;
             public static final boolean EnableTaskStackClipping = false;
+            public static final boolean EnableToggleNewRecentsActivity = false;
             // This disables the bitmap and icon caches to
             public static final boolean DisableBackgroundCache = false;
 
@@ -76,6 +77,8 @@
                 public static final int SnapScrollBackDuration = 650;
             }
 
+            public static final int TaskStackOverscrollRange = 150;
+
             // The padding will be applied to the smallest dimension, and then applied to all sides
             public static final float StackPaddingPct = 0.15f;
             // The overlap height relative to the task height
@@ -91,12 +94,13 @@
         public static class TaskView {
             public static class Animation {
                 public static final int TaskDataUpdatedFadeDuration = 250;
-                public static final int TaskIconCircularClipInDuration = 225;
-                public static final int TaskIconCircularClipOutDuration = 85;
+                public static final int TaskIconOnEnterDuration = 175;
+                public static final int TaskIconOnLeavingDuration = 75;
             }
 
             public static final boolean AnimateFrontTaskIconOnEnterRecents = true;
             public static final boolean AnimateFrontTaskIconOnLeavingRecents = true;
+            public static final boolean AnimateFrontTaskIconOnEnterUseClip = false;
             public static final boolean AnimateFrontTaskIconOnLeavingUseClip = false;
             public static final boolean DrawColoredTaskBars = false;
             public static final boolean UseRoundedCorners = true;
@@ -106,9 +110,4 @@
             public static final float TaskIconSizeDps = 60;
         }
     }
-
-    // UNMIGRATED CONSTANTS:
-
-    /** Determines whether to layout the stack vertically in landscape mode */
-    public static final boolean LANDSCAPE_LAYOUT_VERTICAL_STACK = true;
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index e3908ff..8408684 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -17,27 +17,48 @@
 package com.android.systemui.recents;
 
 import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.FrameLayout;
-import com.android.systemui.recent.RecentTasksLoader;
+import com.android.systemui.R;
 import com.android.systemui.recents.model.SpaceNode;
 import com.android.systemui.recents.model.TaskStack;
 import com.android.systemui.recents.views.RecentsView;
-import com.android.systemui.R;
 
 import java.util.ArrayList;
 
 
 /* Activity */
-public class RecentsActivity extends Activity {
+public class RecentsActivity extends Activity implements RecentsView.RecentsViewCallbacks {
     FrameLayout mContainerView;
     RecentsView mRecentsView;
     View mEmptyView;
+
     boolean mVisible;
+    boolean mTaskLaunched;
+
+    BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+                    "[RecentsActivity|serviceBroadcast]", action, Console.AnsiRed);
+            if (action.equals(RecentsService.ACTION_FINISH_RECENTS_ACTIVITY)) {
+                if (Constants.DebugFlags.App.EnableToggleNewRecentsActivity) {
+                    finish();
+                }
+            } else if (action.equals(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY)) {
+                // Dismiss recents and launch the first task if possible
+                dismissRecentsIfVisible();
+            }
+        }
+    };
 
     /** Updates the set of recent tasks */
     void updateRecentsTasks() {
@@ -63,14 +84,12 @@
     }
 
     /** Dismisses recents if we are already visible and the intent is to toggle the recents view */
-    boolean dismissRecentsIfVisible(Intent intent) {
-        if ("com.android.systemui.recents.TOGGLE_RECENTS".equals(intent.getAction())) {
-            if (mVisible) {
-                if (!mRecentsView.launchFirstTask()) {
-                    finish();
-                }
-                return true;
+    boolean dismissRecentsIfVisible() {
+        if (mVisible) {
+            if (!mRecentsView.launchFirstTask()) {
+                finish();
             }
+            return true;
         }
         return false;
     }
@@ -87,9 +106,6 @@
         RecentsTaskLoader.initialize(this);
         RecentsConfiguration.reinitialize(this);
 
-        // Dismiss recents if it is visible and we are toggling
-        if (dismissRecentsIfVisible(getIntent())) return;
-
         // Set the background dim
         WindowManager.LayoutParams wlp = getWindow().getAttributes();
         wlp.dimAmount = Constants.Values.Window.BackgroundDim;
@@ -98,6 +114,7 @@
 
         // Create the view hierarchy
         mRecentsView = new RecentsView(this);
+        mRecentsView.setCallbacks(this);
         mRecentsView.setLayoutParams(new FrameLayout.LayoutParams(
                 FrameLayout.LayoutParams.MATCH_PARENT,
                 FrameLayout.LayoutParams.MATCH_PARENT));
@@ -118,13 +135,14 @@
     @Override
     protected void onNewIntent(Intent intent) {
         super.onNewIntent(intent);
+
+        // Reset the task launched flag if we encounter an onNewIntent() before onStop()
+        mTaskLaunched = false;
+
         Console.logDivider(Constants.DebugFlags.App.SystemUIHandshake);
         Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onNewIntent]",
                 intent.getAction() + " visible: " + mVisible, Console.AnsiRed);
 
-        // Dismiss recents if it is visible and we are toggling
-        if (dismissRecentsIfVisible(intent)) return;
-
         // Initialize the loader and the configuration
         RecentsTaskLoader.initialize(this);
         RecentsConfiguration.reinitialize(this);
@@ -146,6 +164,12 @@
         Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onResume]", "",
                 Console.AnsiRed);
         super.onResume();
+
+        // Register the broadcast receiver to handle messages from our service
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY);
+        filter.addAction(RecentsService.ACTION_FINISH_RECENTS_ACTIVITY);
+        registerReceiver(mServiceBroadcastReceiver, filter);
     }
 
     @Override
@@ -154,9 +178,8 @@
                 Console.AnsiRed);
         super.onPause();
 
-        // Stop the loader immediately when we leave Recents
-        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
-        loader.stopLoader();
+        // Unregister any broadcast receivers we have registered
+        unregisterReceiver(mServiceBroadcastReceiver);
     }
 
     @Override
@@ -164,7 +187,21 @@
         Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onStop]", "",
                 Console.AnsiRed);
         super.onStop();
+
+        // Finish the current recents activity after we have launched a task
+        if (mTaskLaunched && Constants.DebugFlags.App.EnableToggleNewRecentsActivity) {
+            finish();
+        }
+
         mVisible = false;
+        mTaskLaunched = false;
+    }
+
+    @Override
+    protected void onDestroy() {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onDestroy]", "",
+                Console.AnsiRed);
+        super.onDestroy();
     }
 
     @Override
@@ -181,4 +218,9 @@
             super.onBackPressed();
         }
     }
+
+    @Override
+    public void onTaskLaunching() {
+        mTaskLaunched = true;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
index 46ff841..25dd269 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
@@ -33,57 +33,71 @@
 import java.lang.ref.WeakReference;
 
 
-/* Service */
-public class RecentsService extends Service {
-    // XXX: This should be getting the message from recents definition
-    final static int MSG_UPDATE_RECENTS_FOR_CONFIGURATION = 0;
+/** The message handler to process Recents SysUI messages */
+class SystemUIMessageHandler extends Handler {
+    WeakReference<Context> mContext;
 
-    /** This Handler should be static to prevent holding onto a reference to the service. */
-    static class MessageHandler extends Handler {
-        WeakReference<Context> mContext;
-
-        MessageHandler(Context context) {
-            // Keep a weak ref to the context instead of a strong ref
-            mContext = new WeakReference<Context>(context);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            Console.log(Constants.DebugFlags.App.SystemUIHandshake,
-                    "[RecentsService|handleMessage]", msg);
-            if (msg.what == MSG_UPDATE_RECENTS_FOR_CONFIGURATION) {
-                Context context = mContext.get();
-                if (context == null) return;
-
-                RecentsTaskLoader.initialize(context);
-                RecentsConfiguration.reinitialize(context);
-
-                try {
-                    Bundle data = msg.getData();
-                    Rect windowRect = (Rect) data.getParcelable("windowRect");
-                    Rect systemInsets = (Rect) data.getParcelable("systemInsets");
-                    RecentsConfiguration.getInstance().updateSystemInsets(systemInsets);
-
-                    // Create a dummy task stack & compute the rect for the thumbnail to animate to
-                    TaskStack stack = new TaskStack(context);
-                    TaskStackView tsv = new TaskStackView(context, stack);
-                    tsv.computeRects(windowRect.width(), windowRect.height() - systemInsets.top);
-                    tsv.boundScroll();
-                    TaskViewTransform transform = tsv.getStackTransform(0);
-                    Rect taskRect = new Rect(transform.rect);
-
-                    data.putParcelable("taskRect", taskRect);
-                    Message reply = Message.obtain(null, MSG_UPDATE_RECENTS_FOR_CONFIGURATION, 0, 0);
-                    reply.setData(data);
-                    msg.replyTo.send(reply);
-                } catch (RemoteException re) {
-                    re.printStackTrace();
-                }
-            }
-        }
+    SystemUIMessageHandler(Context context) {
+        // Keep a weak ref to the context instead of a strong ref
+        mContext = new WeakReference<Context>(context);
     }
 
-    Messenger mMessenger = new Messenger(new MessageHandler(this));
+    @Override
+    public void handleMessage(Message msg) {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+                "[RecentsService|handleMessage]", msg);
+
+        Context context = mContext.get();
+        if (context == null) return;
+
+        if (msg.what == RecentsService.MSG_UPDATE_RECENTS_FOR_CONFIGURATION) {
+            RecentsTaskLoader.initialize(context);
+            RecentsConfiguration.reinitialize(context);
+
+            try {
+                Bundle data = msg.getData();
+                Rect windowRect = (Rect) data.getParcelable("windowRect");
+                Rect systemInsets = (Rect) data.getParcelable("systemInsets");
+                RecentsConfiguration.getInstance().updateSystemInsets(systemInsets);
+
+                // Create a dummy task stack & compute the rect for the thumbnail to animate to
+                TaskStack stack = new TaskStack(context);
+                TaskStackView tsv = new TaskStackView(context, stack);
+                tsv.computeRects(windowRect.width(), windowRect.height() - systemInsets.top);
+                tsv.boundScroll();
+                TaskViewTransform transform = tsv.getStackTransform(0);
+                Rect taskRect = new Rect(transform.rect);
+
+                data.putParcelable("taskRect", taskRect);
+                Message reply = Message.obtain(null,
+                        RecentsService.MSG_UPDATE_RECENTS_FOR_CONFIGURATION, 0, 0);
+                reply.setData(data);
+                msg.replyTo.send(reply);
+            } catch (RemoteException re) {
+                re.printStackTrace();
+            }
+        } else if (msg.what == RecentsService.MSG_CLOSE_RECENTS) {
+            // Do nothing
+        } else if (msg.what == RecentsService.MSG_TOGGLE_RECENTS) {
+            // Send a broadcast to toggle recents
+            Intent intent = new Intent(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY);
+            intent.setPackage(context.getPackageName());
+            context.sendBroadcast(intent);
+        }
+    }
+}
+
+/* Service */
+public class RecentsService extends Service {
+    final static String ACTION_FINISH_RECENTS_ACTIVITY = "action_finish_recents_activity";
+    final static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity";
+
+    // XXX: This should be getting the message from recents definition
+    final static int MSG_UPDATE_RECENTS_FOR_CONFIGURATION = 0;
+    final static int MSG_CLOSE_RECENTS = 4;
+    final static int MSG_TOGGLE_RECENTS = 5;
+
+    Messenger mSystemUIMessenger = new Messenger(new SystemUIMessageHandler(this));
 
     @Override
     public void onCreate() {
@@ -94,7 +108,7 @@
     @Override
     public IBinder onBind(Intent intent) {
         Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsService|onBind]");
-        return mMessenger.getBinder();
+        return mSystemUIMessenger.getBinder();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
index 253b8e3..5f9162d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
@@ -511,7 +511,8 @@
 
         switch (level) {
             case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
-                // Do nothing
+                // Stop the loader immediately when the UI is no longer visible
+                stopLoader();
                 break;
             case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
             case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
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 c85c14b..9133f7d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -40,14 +40,27 @@
  * to their SpaceNode bounds.
  */
 public class RecentsView extends FrameLayout implements TaskStackView.TaskStackViewCallbacks {
+
+    /** The RecentsView callbacks */
+    public interface RecentsViewCallbacks {
+        public void onTaskLaunching();
+    }
+
     // The space partitioning root of this container
     SpaceNode mBSP;
+    // Recents view callbacks
+    RecentsViewCallbacks mCb;
 
     public RecentsView(Context context) {
         super(context);
         setWillNotDraw(false);
     }
 
+    /** Sets the callbacks */
+    public void setCallbacks(RecentsViewCallbacks cb) {
+        mCb = cb;
+    }
+
     /** Set/get the bsp root node */
     public void setBSP(SpaceNode n) {
         mBSP = n;
@@ -64,14 +77,19 @@
 
     /** Launches the first task from the first stack if possible */
     public boolean launchFirstTask() {
+        // Get the first stack view
         int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             TaskStackView stackView = (TaskStackView) getChildAt(i);
             TaskStack stack = stackView.mStack;
             ArrayList<Task> tasks = stack.getTasks();
+
+            // Get the first task in the stack
             if (!tasks.isEmpty()) {
                 Task task = tasks.get(tasks.size() - 1);
                 TaskView tv = null;
+
+                // Try and use the first child task view as the source of the launch animation
                 if (stackView.getChildCount() > 0) {
                     TaskView stv = (TaskView) stackView.getChildAt(stackView.getChildCount() - 1);
                     if (stv.getTask() == task) {
@@ -133,13 +151,15 @@
 
     @Override
     protected void dispatchDraw(Canvas canvas) {
-        Console.log(Constants.DebugFlags.UI.Draw, "[RecentsView|dispatchDraw]", "", Console.AnsiPurple);
+        Console.log(Constants.DebugFlags.UI.Draw, "[RecentsView|dispatchDraw]", "",
+                Console.AnsiPurple);
         super.dispatchDraw(canvas);
     }
 
     @Override
     protected boolean fitSystemWindows(Rect insets) {
-        Console.log(Constants.DebugFlags.UI.MeasureAndLayout, "[RecentsView|fitSystemWindows]", "insets: " + insets, Console.AnsiGreen);
+        Console.log(Constants.DebugFlags.UI.MeasureAndLayout,
+                "[RecentsView|fitSystemWindows]", "insets: " + insets, Console.AnsiGreen);
 
         // Update the configuration with the latest system insets and trigger a relayout
         RecentsConfiguration config = RecentsConfiguration.getInstance();
@@ -166,11 +186,16 @@
         return false;
     }
 
-    /**** View.OnClickListener Implementation ****/
+    /**** TaskStackView.TaskStackCallbacks Implementation ****/
 
     @Override
     public void onTaskLaunched(final TaskStackView stackView, final TaskView tv,
                                final TaskStack stack, final Task task) {
+        // Notify any callbacks of the launching of a new task
+        if (mCb != null) {
+            mCb.onTaskLaunching();
+        }
+
         final Runnable launchRunnable = new Runnable() {
             @Override
             public void run() {
@@ -221,7 +246,7 @@
 
         // Launch the app right away if there is no task view, otherwise, animate the icon out first
         if (tv == null || !Constants.Values.TaskView.AnimateFrontTaskIconOnLeavingRecents) {
-            launchRunnable.run();
+            post(launchRunnable);
         } else {
             tv.animateOnLeavingRecents(launchRunnable);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 17660d8..4ec055e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -920,18 +920,25 @@
                 int velocity = (int) velocityTracker.getYVelocity(mActivePointerId);
 
                 if (mIsScrolling && (Math.abs(velocity) > mMinimumVelocity)) {
-                    Console.log(Constants.DebugFlags.UI.TouchEvents,
-                        "[TaskStackViewTouchHandler|fling]",
-                        "scroll: " + mSv.getStackScroll() + " velocity: " + velocity,
-                            Console.AnsiGreen);
                     // Enable HW layers on the stack
                     mSv.addHwLayersRefCount("flingScroll");
+                    int overscrollRange = (int) (Math.min(1f,
+                            Math.abs((float) velocity / mMaximumVelocity)) *
+                            Constants.Values.TaskStackView.TaskStackOverscrollRange);
+
+                    Console.log(Constants.DebugFlags.UI.TouchEvents,
+                            "[TaskStackViewTouchHandler|fling]",
+                            "scroll: " + mSv.getStackScroll() + " velocity: " + velocity +
+                                    " maxVelocity: " + mMaximumVelocity +
+                                    " overscrollRange: " + overscrollRange,
+                            Console.AnsiGreen);
+
                     // Fling scroll
                     mSv.mScroller.fling(0, mSv.getStackScroll(),
                             0, -velocity,
                             0, 0,
                             mSv.mMinScroll, mSv.mMaxScroll,
-                            0, 0);
+                            0, overscrollRange);
                     // Invalidate to kick off computeScroll
                     mSv.invalidate();
                 } else if (mSv.isScrollOutOfBounds()) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index ace2428..9d4f92d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -290,17 +290,36 @@
 
     /** Animates this task view as it enters recents */
     public void animateOnEnterRecents() {
-        mIconView.setCircularClipRadius(0f);
-        mIconView.animateCircularClip(true, 1f,
-            Constants.Values.TaskView.Animation.TaskIconCircularClipInDuration,
-            300, new AccelerateInterpolator(), null);
+        if (Constants.Values.TaskView.AnimateFrontTaskIconOnEnterUseClip) {
+            mIconView.setCircularClipRadius(0f);
+            mIconView.animateCircularClip(true, 1f,
+                Constants.Values.TaskView.Animation.TaskIconOnEnterDuration,
+                300, new AccelerateInterpolator(), null);
+        } else {
+            RecentsConfiguration config = RecentsConfiguration.getInstance();
+            int translate = config.pxFromDp(10);
+            mIconView.setScaleX(1.25f);
+            mIconView.setScaleY(1.25f);
+            mIconView.setAlpha(0f);
+            mIconView.setTranslationX(translate / 2);
+            mIconView.setTranslationY(-translate);
+            mIconView.animate()
+                    .alpha(1f)
+                    .scaleX(1f)
+                    .scaleY(1f)
+                    .translationX(0)
+                    .translationY(0)
+                    .setStartDelay(235)
+                    .setDuration(Constants.Values.TaskView.Animation.TaskIconOnEnterDuration)
+                    .start();
+        }
     }
 
     /** Animates this task view as it exits recents */
     public void animateOnLeavingRecents(final Runnable r) {
         if (Constants.Values.TaskView.AnimateFrontTaskIconOnLeavingUseClip) {
             mIconView.animateCircularClip(false, 0f,
-                Constants.Values.TaskView.Animation.TaskIconCircularClipOutDuration, 0,
+                Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration, 0,
                 new DecelerateInterpolator(),
                 new AnimatorListenerAdapter() {
                     @Override
@@ -311,7 +330,7 @@
         } else {
             mIconView.animate()
                 .alpha(0f)
-                .setDuration(Constants.Values.TaskView.Animation.TaskIconCircularClipOutDuration)
+                .setDuration(Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration)
                 .setInterpolator(new DecelerateInterpolator())
                 .setListener(
                     new AnimatorListenerAdapter() {