Some live tile and state fixes

> Removing LayoutListener which was causing relayouts in the middle of
  the transitions
> Fixing some logging in MultiStateCallback
> Using an overlay to draw the hole for the live tile

Bug: 124451190
Change-Id: I91351f76ec7cc2793a835f40002bfd912939d40d
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/OverviewState.java
index de6f7a7..4eda454 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/OverviewState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/OverviewState.java
@@ -15,7 +15,6 @@
  */
 package com.android.launcher3.uioverrides;
 
-import static com.android.launcher3.AbstractFloatingView.TYPE_QUICKSTEP_PREVIEW;
 import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
 import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
 import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
@@ -76,11 +75,7 @@
     public void onStateEnabled(Launcher launcher) {
         RecentsView rv = launcher.getOverviewPanel();
         rv.setOverviewStateEnabled(true);
-        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
-            AbstractFloatingView.closeAllOpenViews(launcher);
-        } else {
-            AbstractFloatingView.closeAllOpenViewsExcept(launcher, TYPE_QUICKSTEP_PREVIEW);
-        }
+        AbstractFloatingView.closeAllOpenViews(launcher);
     }
 
     @Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index 930cdc5..94237f0 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -36,6 +36,7 @@
 import android.graphics.Region;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewOverlay;
 import android.view.animation.Interpolator;
 
 import com.android.launcher3.DeviceProfile;
@@ -43,6 +44,7 @@
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherInitListener;
 import com.android.launcher3.LauncherState;
+import com.android.launcher3.R;
 import com.android.launcher3.TestProtocol;
 import com.android.launcher3.allapps.DiscoveryBounce;
 import com.android.launcher3.anim.AnimatorPlaybackController;
@@ -55,7 +57,6 @@
 import com.android.launcher3.views.FloatingIconView;
 import com.android.quickstep.util.ClipAnimationHelper;
 import com.android.quickstep.util.LayoutUtils;
-import com.android.quickstep.views.LauncherLayoutListener;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -73,16 +74,6 @@
 public final class LauncherActivityControllerHelper implements ActivityControlHelper<Launcher> {
 
     @Override
-    public LayoutListener createLayoutListener(Launcher activity) {
-        return LauncherLayoutListener.resetAndGet(activity);
-    }
-
-    @Override
-    public void executeOnWindowAvailable(Launcher activity, Runnable action) {
-        activity.getWorkspace().runOnOverlayHidden(action);
-    }
-
-    @Override
     public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect) {
         LayoutUtils.calculateLauncherTaskSize(context, dp, outRect);
         if (dp.isVerticalBarLayout()) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
index 25e0af2..1eaa8bc 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
@@ -15,10 +15,8 @@
  */
 package com.android.launcher3.uioverrides;
 
-import static com.android.launcher3.AbstractFloatingView.TYPE_QUICKSTEP_PREVIEW;
 import static com.android.launcher3.LauncherAnimUtils.ALL_APPS_TRANSITION_MS;
 import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.Launcher;
@@ -46,11 +44,7 @@
 
     @Override
     public void onStateEnabled(Launcher launcher) {
-        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
-            AbstractFloatingView.closeAllOpenViews(launcher);
-        } else {
-            AbstractFloatingView.closeAllOpenViewsExcept(launcher, TYPE_QUICKSTEP_PREVIEW);
-        }
+        AbstractFloatingView.closeAllOpenViews(launcher);
         dispatchWindowStateChanged(launcher);
     }
 
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index bb64c2b..4c2c279 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -49,10 +49,6 @@
 @TargetApi(Build.VERSION_CODES.P)
 public interface ActivityControlHelper<T extends BaseDraggingActivity> {
 
-    LayoutListener createLayoutListener(T activity);
-
-    void executeOnWindowAvailable(T activity, Runnable action);
-
     void onTransitionCancelled(T activity, boolean activityVisible);
 
     int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect);
@@ -105,18 +101,6 @@
 
     boolean isInLiveTileMode();
 
-    interface LayoutListener {
-
-        void open();
-
-        void setHandler(WindowTransformSwipeHandler handler);
-
-        void finish();
-
-        void update(boolean shouldFinish, boolean isLongSwipe, RectF currentRect,
-                float cornerRadius);
-    }
-
     interface ActivityInitListener {
 
         void register();
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java b/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
index b655d1d..719795b 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityControllerHelper.java
@@ -57,11 +57,6 @@
     }
 
     @Override
-    public void executeOnWindowAvailable(RecentsActivity activity, Runnable action) {
-        action.run();
-    }
-
-    @Override
     public void onTransitionCancelled(RecentsActivity activity, boolean activityVisible) {
         // TODO:
     }
@@ -152,26 +147,6 @@
     }
 
     @Override
-    public LayoutListener createLayoutListener(RecentsActivity activity) {
-        // We do not change anything as part of layout changes in fallback activity. Return a
-        // default layout listener.
-        return new LayoutListener() {
-            @Override
-            public void open() { }
-
-            @Override
-            public void setHandler(WindowTransformSwipeHandler handler) { }
-
-            @Override
-            public void finish() { }
-
-            @Override
-            public void update(boolean shouldFinish, boolean isLongSwipe, RectF currentRect,
-                    float cornerRadius) { }
-        };
-    }
-
-    @Override
     public ActivityInitListener createActivityInitListener(
             BiPredicate<RecentsActivity, Boolean> onInitListener) {
         return new RecentsActivityTracker(onInitListener);
diff --git a/quickstep/src/com/android/quickstep/MultiStateCallback.java b/quickstep/src/com/android/quickstep/MultiStateCallback.java
index ba66293..9fceab4 100644
--- a/quickstep/src/com/android/quickstep/MultiStateCallback.java
+++ b/quickstep/src/com/android/quickstep/MultiStateCallback.java
@@ -44,6 +44,11 @@
      * Adds the provided state flags to the global state and executes any callbacks as a result.
      */
     public void setState(int stateFlag) {
+        if (DEBUG_STATES) {
+            Log.d(TAG, "[" + System.identityHashCode(this) + "] Adding "
+                    + convertToFlagNames(stateFlag) + " to " + convertToFlagNames(mState));
+        }
+
         int oldState = mState;
         mState = mState | stateFlag;
 
@@ -68,6 +73,11 @@
      * as a result.
      */
     public void clearState(int stateFlag) {
+        if (DEBUG_STATES) {
+            Log.d(TAG, "[" + System.identityHashCode(this) + "] Removing "
+                    + convertToFlagNames(stateFlag) + " from " + convertToFlagNames(mState));
+        }
+
         int oldState = mState;
         mState = mState & ~stateFlag;
         notifyStateChangeHandlers(oldState);
@@ -109,24 +119,14 @@
         return (mState & stateMask) == stateMask;
     }
 
-    private void debugNewState(int stateFlag) {
-        if (!DEBUG_STATES) {
-            return;
-        }
-
-        int state = getState();
-        StringJoiner currentStateStr = new StringJoiner(", ", "[", "]");
-        String stateFlagStr = "Unknown-" + stateFlag;
+    private String convertToFlagNames(int flags) {
+        StringJoiner joiner = new StringJoiner(", ", "[", " (" + flags + ")]");
         for (int i = 0; i < mStateNames.length; i++) {
-            if ((state & (i << i)) != 0) {
-                currentStateStr.add(mStateNames[i]);
-            }
-            if (stateFlag == (1 << i)) {
-                stateFlagStr = mStateNames[i] + " (" + stateFlag + ")";
+            if ((flags & (1 << i)) != 0) {
+                joiner.add(mStateNames[i]);
             }
         }
-        Log.d(TAG, "[" + System.identityHashCode(this) + "] Adding " + stateFlagStr + " to "
-                + currentStateStr);
+        return joiner.toString();
     }
 
 }
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index aeb648d..f3f5daf 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -60,7 +60,9 @@
 import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.View.OnApplyWindowInsetsListener;
 import android.view.ViewTreeObserver.OnDrawListener;
+import android.view.WindowInsets;
 import android.view.WindowManager;
 import android.view.animation.Interpolator;
 
@@ -87,11 +89,11 @@
 import com.android.quickstep.ActivityControlHelper.AnimationFactory;
 import com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState;
 import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory;
-import com.android.quickstep.ActivityControlHelper.LayoutListener;
 import com.android.quickstep.util.ClipAnimationHelper;
 import com.android.quickstep.util.RemoteAnimationTargetSet;
 import com.android.quickstep.util.SwipeAnimationTargetSet;
 import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
+import com.android.quickstep.views.LiveTileOverlay;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -111,10 +113,10 @@
 
 @TargetApi(Build.VERSION_CODES.O)
 public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
-        implements SwipeAnimationListener {
+        implements SwipeAnimationListener, OnApplyWindowInsetsListener {
     private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName();
 
-    private static final String[] STATE_NAMES = DEBUG_STATES ? new String[19] : null;
+    private static final String[] STATE_NAMES = DEBUG_STATES ? new String[20] : null;
 
     private static int getFlagForIndex(int index, String name) {
         if (DEBUG_STATES) {
@@ -167,6 +169,9 @@
     private static final int STATE_ASSIST_DATA_RECEIVED =
             getFlagForIndex(18, "STATE_ASSIST_DATA_RECEIVED");
 
+    private static final int STATE_LONG_SWIPE_ACTIVE =
+            getFlagForIndex(19, "LONG_SWIPE_ACTIVE");
+
     private static final int LAUNCHER_UI_STATES =
             STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_ACTIVITY_MULTIPLIER_COMPLETE
             | STATE_LAUNCHER_STARTED;
@@ -252,10 +257,10 @@
     private AnimatorPlaybackController mLauncherTransitionController;
 
     private T mActivity;
-    private LayoutListener mLayoutListener;
     private RecentsView mRecentsView;
     private SyncRtSurfaceTransactionApplierCompat mSyncTransactionApplier;
     private AnimationFactory mAnimationFactory = (t) -> { };
+    private LiveTileOverlay mLiveTileOverlay = new LiveTileOverlay();
 
     private boolean mWasLauncherAlreadyVisible;
 
@@ -360,6 +365,7 @@
 
         mStateCallback.addCallback(LONG_SWIPE_ENTER_STATE, this::checkLongSwipeCanEnter);
         mStateCallback.addCallback(LONG_SWIPE_START_STATE, this::checkLongSwipeCanStart);
+        mStateCallback.addChangeHandler(STATE_LONG_SWIPE_ACTIVE, this::onLongSwipeActiveChanged);
 
         if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) {
             mStateCallback.addChangeHandler(STATE_APP_CONTROLLER_RECEIVED | STATE_LAUNCHER_PRESENT
@@ -410,7 +416,6 @@
             int oldState = mStateCallback.getState() & ~LAUNCHER_UI_STATES;
             initStateCallbacks();
             mStateCallback.setState(oldState);
-            mLayoutListener.setHandler(null);
         }
         mWasLauncherAlreadyVisible = alreadyOnHome;
         mActivity = activity;
@@ -423,10 +428,10 @@
         }
 
         mRecentsView = activity.getOverviewPanel();
-        SyncRtSurfaceTransactionApplierCompat.create(mRecentsView, (applier) -> {
-            mSyncTransactionApplier = applier;
-        });
+        SyncRtSurfaceTransactionApplierCompat.create(mRecentsView,
+                applier ->  mSyncTransactionApplier = applier );
         mRecentsView.setEnableFreeScroll(false);
+
         mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
             if (!mLongSwipeMode && mGestureEndTarget != HOME) {
                 updateFinalShift();
@@ -434,7 +439,7 @@
         });
         mRecentsView.setRecentsAnimationWrapper(mRecentsAnimationWrapper);
         mRecentsView.setClipAnimationHelper(mClipAnimationHelper);
-        mLayoutListener = mActivityControlHelper.createLayoutListener(mActivity);
+        mActivity.getRootView().getOverlay().add(mLiveTileOverlay);
 
         mStateCallback.setState(STATE_LAUNCHER_PRESENT);
         if (alreadyOnHome) {
@@ -480,7 +485,7 @@
         }
 
         setupRecentsViewUi();
-        mLayoutListener.open();
+        activity.getRootView().setOnApplyWindowInsetsListener(this);
         mStateCallback.setState(STATE_LAUNCHER_STARTED);
     }
 
@@ -522,7 +527,6 @@
     }
 
     private void initializeLauncherAnimationController() {
-        mLayoutListener.setHandler(this);
         buildAnimationController();
 
         if (LatencyTrackerCompat.isEnabled(mContext)) {
@@ -570,13 +574,13 @@
             mCurrentShift.updateValue(1);
 
             if (!mLongSwipeMode && !FeatureFlags.SWIPE_HOME.get()) {
-                onLongSwipeEnabled();
+                setStateOnUiThread(STATE_LONG_SWIPE_ACTIVE);
             }
             mLongSwipeDisplacement = displacement - mTransitionDragLength;
             onLongSwipeDisplacementUpdated();
         } else {
             if (mLongSwipeMode) {
-                onLongSwipeDisabled();
+                mStateCallback.clearState(STATE_LONG_SWIPE_ACTIVE);
             }
             float translation = Math.max(displacement, 0);
             float shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength;
@@ -598,14 +602,18 @@
         }
     }
 
-    /**
-     * Called by {@link #mLayoutListener} when launcher layout changes
-     */
-    public void buildAnimationController() {
+    private void buildAnimationController() {
         initTransitionEndpoints(mActivity.getDeviceProfile());
         mAnimationFactory.createActivityController(mTransitionDragLength);
     }
 
+    @Override
+    public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
+        WindowInsets result = view.onApplyWindowInsets(windowInsets);
+        buildAnimationController();
+        return result;
+    }
+
     private void onAnimatorPlaybackControllerCreated(AnimatorPlaybackController anim) {
         mLauncherTransitionController = anim;
         mLauncherTransitionController.dispatchOnStart();
@@ -640,10 +648,8 @@
         }
 
         if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
-            if (mRecentsAnimationWrapper.getController() != null && mLayoutListener != null) {
-                mLayoutListener.open();
-                mLayoutListener.update(mCurrentShift.value > 1, mLongSwipeMode,
-                        mClipAnimationHelper.getCurrentRectWithInsets(),
+            if (mRecentsAnimationWrapper.getController() != null) {
+                mLiveTileOverlay.update(mClipAnimationHelper.getCurrentRectWithInsets(),
                         mClipAnimationHelper.getCurrentCornerRadius());
             }
         }
@@ -1106,12 +1112,16 @@
 
     private void invalidateHandlerWithLauncher() {
         mLauncherTransitionController = null;
-        mLayoutListener.finish();
         mActivityControlHelper.getAlphaProperty(mActivity).setValue(1);
 
         mRecentsView.setEnableFreeScroll(true);
         mRecentsView.setRunningTaskIconScaledDown(false);
         mRecentsView.setOnScrollChangeListener(null);
+        mRecentsView.setRunningTaskHidden(false);
+        mRecentsView.setEnableDrawingLiveTile(true);
+
+        mActivity.getRootView().setOnApplyWindowInsetsListener(null);
+        mActivity.getRootView().getOverlay().remove(mLiveTileOverlay);
     }
 
     private void notifyTransitionCancelled() {
@@ -1224,22 +1234,27 @@
     }
 
     // Handling long swipe
-    private void onLongSwipeEnabled() {
-        mLongSwipeMode = true;
-        checkLongSwipeCanEnter();
-        checkLongSwipeCanStart();
-    }
+    private void onLongSwipeActiveChanged(boolean isActive) {
+        mLongSwipeMode = isActive;
 
-    private void onLongSwipeDisabled() {
-        mLongSwipeMode = false;
-        mStateCallback.clearState(STATE_SCREENSHOT_VIEW_SHOWN);
+        if (mLongSwipeMode) {
+            checkLongSwipeCanEnter();
+            checkLongSwipeCanStart();
+        } else {
+            mStateCallback.clearState(STATE_SCREENSHOT_VIEW_SHOWN);
 
-        if (mLongSwipeController != null) {
-            mLongSwipeController.destroy();
-            setTargetAlphaProvider((t, a1) -> a1);
+            if (mLongSwipeController != null) {
+                mLongSwipeController.destroy();
+                setTargetAlphaProvider((t, a1) -> a1);
 
-            // Rebuild animations
-            buildAnimationController();
+                // Rebuild animations
+                buildAnimationController();
+            }
+        }
+        mLiveTileOverlay.setDrawEnabled(!mLongSwipeMode);
+        if (mRecentsView != null) {
+            mRecentsView.setRunningTaskHidden(!isActive);
+            mRecentsView.setEnableDrawingLiveTile(isActive);
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/LauncherLayoutListener.java b/quickstep/src/com/android/quickstep/views/LauncherLayoutListener.java
deleted file mode 100644
index a8205cd..0000000
--- a/quickstep/src/com/android/quickstep/views/LauncherLayoutListener.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep.views;
-
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.states.RotationHelper.REQUEST_NONE;
-
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.view.MotionEvent;
-import android.widget.FrameLayout;
-
-import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.Insettable;
-import com.android.launcher3.Launcher;
-import com.android.quickstep.ActivityControlHelper.LayoutListener;
-import com.android.quickstep.WindowTransformSwipeHandler;
-
-/**
- * Floating view which shows the task snapshot allowing it to be dragged and placed.
- */
-public class LauncherLayoutListener extends AbstractFloatingView
-        implements Insettable, LayoutListener {
-
-    public static LauncherLayoutListener resetAndGet(Launcher launcher) {
-        LauncherRecentsView lrv = launcher.getOverviewPanel();
-        LauncherLayoutListener listener = lrv.mLauncherLayoutListener;
-        if (listener.isOpen()) {
-            listener.close(false);
-        }
-        listener.setHandler(null);
-        return listener;
-    }
-
-    private final Launcher mLauncher;
-    private final Paint mPaint = new Paint();
-    private WindowTransformSwipeHandler mHandler;
-    private RectF mCurrentRect;
-    private float mCornerRadius;
-
-    private boolean mWillNotDraw;
-
-    /**
-     * package private
-     */
-    LauncherLayoutListener(Launcher launcher) {
-        super(launcher, null);
-        mLauncher = launcher;
-        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
-        setLayoutParams(new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
-
-        mWillNotDraw = willNotDraw();
-        super.setWillNotDraw(false);
-    }
-
-    @Override
-    public void update(boolean shouldFinish, boolean isLongSwipe, RectF currentRect,
-                  float cornerRadius) {
-        if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) {
-            if (shouldFinish) {
-                finish();
-            }
-            return;
-        }
-
-        mCurrentRect = currentRect;
-        mCornerRadius = cornerRadius;
-
-        setWillNotDraw(mCurrentRect == null || isLongSwipe);
-        invalidate();
-    }
-
-    @Override
-    public void setWillNotDraw(boolean willNotDraw) {
-        // Prevent super call as that causes additional relayout.
-        mWillNotDraw = willNotDraw;
-    }
-
-    @Override
-    public void setHandler(WindowTransformSwipeHandler handler) {
-        mHandler = handler;
-    }
-
-    @Override
-    public void setInsets(Rect insets) {
-        if (mHandler != null) {
-            mHandler.buildAnimationController();
-        }
-    }
-
-    @Override
-    public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
-        return false;
-    }
-
-    @Override
-    protected void handleClose(boolean animate) {
-        if (mIsOpen) {
-            mIsOpen = false;
-            // We don't support animate.
-            mLauncher.getDragLayer().removeView(this);
-
-            if (mHandler != null) {
-                mHandler.layoutListenerClosed();
-            }
-        }
-    }
-
-    @Override
-    public void open() {
-        if (!mIsOpen) {
-            mLauncher.getDragLayer().addView(this);
-            mIsOpen = true;
-        }
-    }
-
-    @Override
-    public void logActionCommand(int command) {
-        // We should probably log the weather
-    }
-
-    @Override
-    protected boolean isOfType(int type) {
-        return (type & TYPE_QUICKSTEP_PREVIEW) != 0;
-    }
-
-    @Override
-    public void finish() {
-        close(false);
-        setHandler(null);
-        mLauncher.getRotationHelper().setStateHandlerRequest(REQUEST_NONE);
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        if (!mWillNotDraw) {
-            canvas.drawRoundRect(mCurrentRect, mCornerRadius, mCornerRadius, mPaint);
-        }
-    }
-}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 1ee5110..d2adef7 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -15,7 +15,6 @@
  */
 package com.android.quickstep.views;
 
-import static com.android.launcher3.AbstractFloatingView.TYPE_QUICKSTEP_PREVIEW;
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA;
 import static com.android.launcher3.LauncherState.NORMAL;
@@ -36,8 +35,6 @@
 import android.view.View;
 import android.view.ViewDebug;
 
-import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BaseActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
@@ -77,7 +74,6 @@
     private float mTranslationYFactor;
 
     private final TransformParams mTransformParams = new TransformParams();
-    final LauncherLayoutListener mLauncherLayoutListener;
 
     public LauncherRecentsView(Context context) {
         this(context, null);
@@ -90,7 +86,6 @@
     public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         setContentAlpha(0);
-        mLauncherLayoutListener = new LauncherLayoutListener(BaseActivity.fromContext(context));
     }
 
     @Override
@@ -205,12 +200,8 @@
 
     @Override
     public void redrawLiveTile(boolean mightNeedToRefill) {
-        AbstractFloatingView layoutListener = AbstractFloatingView.getTopOpenViewWithType(
-                mActivity, TYPE_QUICKSTEP_PREVIEW);
-        if (layoutListener != null && layoutListener.isOpen()) {
-            return;
-        }
-        if (mRecentsAnimationWrapper == null || mClipAnimationHelper == null) {
+        if (!mEnableDrawingLiveTile || mRecentsAnimationWrapper == null
+                || mClipAnimationHelper == null) {
             return;
         }
         TaskView taskView = getRunningTaskView();
diff --git a/quickstep/src/com/android/quickstep/views/LiveTileOverlay.java b/quickstep/src/com/android/quickstep/views/LiveTileOverlay.java
new file mode 100644
index 0000000..ab2b90f
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/LiveTileOverlay.java
@@ -0,0 +1,62 @@
+package com.android.quickstep.views;
+
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+
+public class LiveTileOverlay extends Drawable {
+
+    private final Paint mPaint = new Paint();
+
+    private Rect mBoundsRect = new Rect();
+    private RectF mCurrentRect;
+    private float mCornerRadius;
+
+    private boolean mDrawEnabled = true;
+
+    public LiveTileOverlay() {
+        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
+    }
+
+    public void update(RectF currentRect, float cornerRadius) {
+        invalidateSelf();
+
+        mCurrentRect = currentRect;
+        mCornerRadius = cornerRadius;
+
+        mCurrentRect.roundOut(mBoundsRect);
+        setBounds(mBoundsRect);
+        invalidateSelf();
+    }
+
+    public void setDrawEnabled(boolean drawEnabled) {
+        if (mDrawEnabled != drawEnabled) {
+            mDrawEnabled = drawEnabled;
+            invalidateSelf();
+        }
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        if (mCurrentRect != null && mDrawEnabled) {
+            canvas.drawRoundRect(mCurrentRect, mCornerRadius, mCornerRadius, mPaint);
+        }
+    }
+
+    @Override
+    public void setAlpha(int i) { }
+
+    @Override
+    public void setColorFilter(ColorFilter colorFilter) { }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.TRANSLUCENT;
+    }
+}
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index e75527e..599a353 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -55,7 +55,6 @@
             TYPE_DISCOVERY_BOUNCE,
             TYPE_SNACKBAR,
 
-            TYPE_QUICKSTEP_PREVIEW,
             TYPE_TASK_MENU,
             TYPE_OPTIONS_POPUP
     })
@@ -71,25 +70,23 @@
     public static final int TYPE_SNACKBAR = 1 << 7;
 
     // Popups related to quickstep UI
-    public static final int TYPE_QUICKSTEP_PREVIEW = 1 << 8;
-    public static final int TYPE_TASK_MENU = 1 << 9;
-    public static final int TYPE_OPTIONS_POPUP = 1 << 10;
+    public static final int TYPE_TASK_MENU = 1 << 8;
+    public static final int TYPE_OPTIONS_POPUP = 1 << 9;
 
     public static final int TYPE_ALL = TYPE_FOLDER | TYPE_ACTION_POPUP
             | TYPE_WIDGETS_BOTTOM_SHEET | TYPE_WIDGET_RESIZE_FRAME | TYPE_WIDGETS_FULL_SHEET
-            | TYPE_QUICKSTEP_PREVIEW | TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE | TYPE_TASK_MENU
+            | TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE | TYPE_TASK_MENU
             | TYPE_OPTIONS_POPUP | TYPE_SNACKBAR;
 
     // Type of popups which should be kept open during launcher rebind
     public static final int TYPE_REBIND_SAFE = TYPE_WIDGETS_FULL_SHEET
-            | TYPE_QUICKSTEP_PREVIEW | TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE;
+            | TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE;
 
     // Usually we show the back button when a floating view is open. Instead, hide for these types.
     public static final int TYPE_HIDE_BACK_BUTTON = TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE
             | TYPE_SNACKBAR;
 
-    public static final int TYPE_ACCESSIBLE = TYPE_ALL
-            & ~TYPE_DISCOVERY_BOUNCE & ~TYPE_QUICKSTEP_PREVIEW;
+    public static final int TYPE_ACCESSIBLE = TYPE_ALL & ~TYPE_DISCOVERY_BOUNCE;
 
     // These view all have particular operation associated with swipe down interaction.
     public static final int TYPE_STATUS_BAR_SWIPE_DOWN_DISALLOW = TYPE_WIDGETS_BOTTOM_SHEET |