Lockscreen launch animations

- Get rid of ActivityManager.dismissKeyguardOnNextActivity, which was
  used for two different things: Dismiss keyguard from somewhere else
  (not really necessary anymore), wait to actually dismiss keyguard
  after the window behind is drawn. Instead, introduce
  keyguardWaitingForActivityDrawn(), and change the semantics where
  necessary.
- Make wallpaper_close_enter consistent with task_open_enter and the
  Keyguard launch animation.
- Close the panel even on lockscreen when launching a notification.
- Block notification shade updates during the collapsing motion so
  notification don't play the disappear animation immediately after
  having launched a notification.

Bug: 15991916

Change-Id: I133c177b84e926c87c1a404ba93d633593fec3ab
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index c23a4cd..12fd0cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -42,6 +42,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
@@ -89,6 +90,7 @@
 import com.android.systemui.SystemUI;
 import com.android.systemui.statusbar.NotificationData.Entry;
 import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
@@ -130,9 +132,6 @@
     public static final int EXPANDED_LEAVE_ALONE = -10000;
     public static final int EXPANDED_FULL_OPEN = -10001;
 
-    /** If true, delays dismissing the Keyguard until the ActivityManager calls back. */
-    protected static final boolean DELAY_DISMISS_TO_ACTIVITY_LAUNCH = false;
-
     protected CommandQueue mCommandQueue;
     protected IStatusBarService mBarService;
     protected H mHandler = createHandler();
@@ -163,6 +162,7 @@
     protected DevicePolicyManager mDevicePolicyManager;
     protected IDreamManager mDreamManager;
     PowerManager mPowerManager;
+    protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     protected int mRowMinHeight;
     protected int mRowMaxHeight;
 
@@ -252,27 +252,33 @@
             }
             final boolean isActivity = pendingIntent.isActivity();
             if (isActivity) {
+                final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
                 dismissKeyguardThenExecute(new OnDismissAction() {
                     @Override
                     public boolean onDismiss() {
-                        try {
-                            // The intent we are sending is for the application, which
-                            // won't have permission to immediately start an activity after
-                            // the user switches to home.  We know it is safe to do at this
-                            // point, so make sure new activity switches are now allowed.
-                            ActivityManagerNative.getDefault().resumeAppSwitches();
-                        } catch (RemoteException e) {
+                        if (keyguardShowing) {
+                            try {
+                                ActivityManagerNative.getDefault()
+                                        .keyguardWaitingForActivityDrawn();
+                                // The intent we are sending is for the application, which
+                                // won't have permission to immediately start an activity after
+                                // the user switches to home.  We know it is safe to do at this
+                                // point, so make sure new activity switches are now allowed.
+                                ActivityManagerNative.getDefault().resumeAppSwitches();
+                            } catch (RemoteException e) {
+                            }
                         }
 
                         boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent);
+                        overrideActivityPendingAppTransition(keyguardShowing);
 
                         // close the shade if it was open
                         if (handled) {
-                            animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
+                            animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
                             visibilityChanged(false);
                         }
                         // Wait for activity start.
-                        return handled && DELAY_DISMISS_TO_ACTIVITY_LAUNCH;
+                        return handled;
                     }
                 });
                 return true;
@@ -1064,7 +1070,7 @@
                             startAppNotificationSettingsActivity(pkg, appUidF);
                             animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
                             visibilityChanged(false);
-                            return DELAY_DISMISS_TO_ACTIVITY_LAUNCH;
+                            return true;
                         }
                     });
                 }
@@ -1254,54 +1260,74 @@
         }
 
         public void onClick(final View v) {
+            final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
             dismissKeyguardThenExecute(new OnDismissAction() {
                 public boolean onDismiss() {
-                    try {
-                        // The intent we are sending is for the application, which
-                        // won't have permission to immediately start an activity after
-                        // the user switches to home.  We know it is safe to do at this
-                        // point, so make sure new activity switches are now allowed.
-                        ActivityManagerNative.getDefault().resumeAppSwitches();
-                    } catch (RemoteException e) {
+                    if (mIsHeadsUp) {
+                        mHeadsUpNotificationView.clear();
                     }
+                    AsyncTask.execute(new Runnable() {
+                        @Override
+                        public void run() {
+                            if (keyguardShowing) {
+                                try {
+                                    ActivityManagerNative.getDefault()
+                                            .keyguardWaitingForActivityDrawn();
+                                    // The intent we are sending is for the application, which
+                                    // won't have permission to immediately start an activity after
+                                    // the user switches to home.  We know it is safe to do at this
+                                    // point, so make sure new activity switches are now allowed.
+                                    ActivityManagerNative.getDefault().resumeAppSwitches();
+                                } catch (RemoteException e) {
+                                }
+                            }
 
-                    boolean sent = false;
-                    if (mIntent != null) {
-                        int[] pos = new int[2];
-                        v.getLocationOnScreen(pos);
-                        Intent overlay = new Intent();
-                        overlay.setSourceBounds(new Rect(pos[0], pos[1],
-                                pos[0] + v.getWidth(), pos[1] + v.getHeight()));
-                        try {
-                            mIntent.send(mContext, 0, overlay);
-                            sent = true;
-                        } catch (PendingIntent.CanceledException e) {
-                            // the stack trace isn't very helpful here.
-                            // Just log the exception message.
-                            Log.w(TAG, "Sending contentIntent failed: " + e);
-                        }
-                    }
+                            if (mIntent != null) {
+                                try {
+                                    mIntent.send();
+                                } catch (PendingIntent.CanceledException e) {
+                                    // the stack trace isn't very helpful here.
+                                    // Just log the exception message.
+                                    Log.w(TAG, "Sending contentIntent failed: " + e);
 
-                    try {
-                        if (mIsHeadsUp) {
-                            mHeadsUpNotificationView.clear();
+                                    // TODO: Dismiss Keyguard.
+                                }
+                                if (mIntent.isActivity()) {
+                                    overrideActivityPendingAppTransition(keyguardShowing);
+                                }
+                            }
+
+                            try {
+                                mBarService.onNotificationClick(mNotificationKey);
+                            } catch (RemoteException ex) {
+                                // system process is dead if we're here.
+                            }
                         }
-                        mBarService.onNotificationClick(mNotificationKey);
-                    } catch (RemoteException ex) {
-                        // system process is dead if we're here.
-                    }
+                    });
 
                     // close the shade if it was open
-                    animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
+                    animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
                     visibilityChanged(false);
 
-                    boolean waitForActivityLaunch = sent && mIntent.isActivity();
-                    return waitForActivityLaunch && DELAY_DISMISS_TO_ACTIVITY_LAUNCH;
+                    return mIntent != null && mIntent.isActivity();
                 }
             });
         }
     }
 
+    public void animateCollapsePanels(int flags, boolean force) {
+    }
+
+    public void overrideActivityPendingAppTransition(boolean keyguardShowing) {
+        if (keyguardShowing) {
+            try {
+                mWindowManagerService.overridePendingAppTransition(null, 0, 0, null);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Error overriding app transition: " + e);
+            }
+        }
+    }
+
     /**
      * The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
      * This was added last-minute and is inconsistent with the way the rest of the notifications
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java
index 5bc7e5a..23810f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java
@@ -24,5 +24,5 @@
  * Keyguard.
  */
 public interface ActivityStarter {
-    public void startActivity(Intent intent);
+    public void startActivity(Intent intent, boolean dismissShade);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index e11f20f..6a800fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -221,12 +221,12 @@
                 !mPreviewInflater.wouldLaunchResolverActivity(intent)) {
             mContext.startActivityAsUser(intent, UserHandle.CURRENT);
         } else {
-            mActivityStarter.startActivity(intent);
+            mActivityStarter.startActivity(intent, false /* dismissShade */);
         }
     }
 
     public void launchPhone() {
-        mActivityStarter.startActivity(PHONE_INTENT);
+        mActivityStarter.startActivity(PHONE_INTENT, false /* dismissShade */);
     }
 
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index db42b9d..fc737be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -98,7 +98,7 @@
     public void startPreHideAnimation(Runnable runnable) {
         if (mKeyguardView != null) {
             mKeyguardView.startDisappearAnimation(runnable);
-        } else {
+        } else if (runnable != null) {
             runnable.run();
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index acdc6bc..bac46be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -414,12 +414,12 @@
     }
 
     @Override
-    public void fling(float vel, boolean always) {
+    public void fling(float vel, boolean expand) {
         GestureRecorder gr = ((PhoneStatusBarView) mBar).mBar.getGestureRecorder();
         if (gr != null) {
             gr.tag("fling " + ((vel > 0) ? "open" : "closed"), "notifications,v=" + vel);
         }
-        super.fling(vel, always);
+        super.fling(vel, expand);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index 59f94f2..f74d2f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -140,7 +140,7 @@
         mPanelHolder.setSelectedPanel(mTouchingPanel);
         for (PanelView pv : mPanels) {
             if (pv != panel) {
-                pv.collapse();
+                pv.collapse(false /* delayed */);
             }
         }
     }
@@ -191,7 +191,7 @@
         boolean waiting = false;
         for (PanelView pv : mPanels) {
             if (animate && !pv.isFullyCollapsed()) {
-                pv.collapse();
+                pv.collapse(true /* delayed */);
                 waiting = true;
             } else {
                 pv.resetViews();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 469a831..c8e943e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -99,6 +99,7 @@
     };
 
     protected void onExpandingFinished() {
+        mClosing = false;
         mBar.onExpandingFinished();
     }
 
@@ -150,7 +151,7 @@
                     postOnAnimation(new Runnable() {
                         @Override
                         public void run() {
-                            collapse();
+                            collapse(false /* delayed */);
                         }
                     });
                 }
@@ -651,7 +652,7 @@
         mBar = panelBar;
     }
 
-    public void collapse() {
+    public void collapse(boolean delayed) {
         if (DEBUG) logf("collapse: " + this);
         if (mPeekPending || mPeekAnimator != null) {
             mCollapseAfterPeek = true;
@@ -668,7 +669,16 @@
             }
             mClosing = true;
             notifyExpandingStarted();
-            fling(0, false /* expand */);
+            if (delayed) {
+                postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        fling(0, false /* expand */);
+                    }
+                }, 120);
+            } else {
+                fling(0, false /* expand */);
+            }
         }
     }
 
@@ -856,7 +866,7 @@
     private final Runnable mPostCollapseRunnable = new Runnable() {
         @Override
         public void run() {
-            collapse();
+            collapse(false /* delayed */);
         }
     };
     private boolean onMiddleClicked() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index caecf1d..6a81424 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -323,7 +323,7 @@
     VelocityTracker mVelocityTracker;
 
     int[] mAbsPos = new int[2];
-    Runnable mPostCollapseCleanup = null;
+    ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
 
     // for disabling the status bar
     int mDisabled = 0;
@@ -395,7 +395,6 @@
     private int mNavigationBarMode;
     private Boolean mScreenOn;
 
-    private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private ViewMediatorCallback mKeyguardViewMediatorCallback;
     private ScrimController mScrimController;
 
@@ -575,6 +574,7 @@
 
         mDozeServiceHost = new DozeServiceHost();
         putComponent(DozeService.Host.class, mDozeServiceHost);
+        putComponent(PhoneStatusBar.class, this);
 
         setControllerUsers();
     }
@@ -887,14 +887,14 @@
             return;
         }
 
-        mPostCollapseCleanup = new Runnable() {
+        addPostCollapseAction(new Runnable() {
             @Override
             public void run() {
                 try {
                     mBarService.onClearAllNotifications(mCurrentUserId);
                 } catch (Exception ex) { }
             }
-        };
+        });
 
         performDismissAllAnimations(viewsToHide);
 
@@ -1366,6 +1366,17 @@
     private void updateNotificationShade() {
         if (mStackScroller == null) return;
 
+        // Do not modify the notifications during collapse.
+        if (isCollapsing()) {
+            addPostCollapseAction(new Runnable() {
+                @Override
+                public void run() {
+                    updateNotificationShade();
+                }
+            });
+            return;
+        }
+
         ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
         ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size());
         final int N = activeNotifications.size();
@@ -2004,8 +2015,8 @@
     }
 
     @Override
-    public void startActivity(Intent intent) {
-        startActivityDismissingKeyguard(intent, false);
+    public void startActivity(Intent intent, boolean dismissShade) {
+        startActivityDismissingKeyguard(intent, false, dismissShade);
     }
 
     public ScrimController getScrimController() {
@@ -2126,10 +2137,7 @@
     public void animateCollapsePanels(int flags, boolean force) {
         if (!force &&
                 (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
-            if (mPostCollapseCleanup != null) {
-                mPostCollapseCleanup.run();
-                mPostCollapseCleanup = null;
-            }
+            runPostCollapseRunnables();
             return;
         }
         if (SPEW) {
@@ -2159,6 +2167,14 @@
         }
     }
 
+    private void runPostCollapseRunnables() {
+        int size = mPostCollapseRunnables.size();
+        for (int i = 0; i < size; i++) {
+            mPostCollapseRunnables.get(i).run();
+        }
+        mPostCollapseRunnables.clear();
+    }
+
     public ViewPropertyAnimator setVisibilityWhenDone(
             final ViewPropertyAnimator a, final View v, final int vis) {
         a.setListener(new AnimatorListenerAdapter() {
@@ -2270,11 +2286,7 @@
         // Close any "App info" popups that might have snuck on-screen
         dismissPopups();
 
-        if (mPostCollapseCleanup != null) {
-            mPostCollapseCleanup.run();
-            mPostCollapseCleanup = null;
-        }
-
+        runPostCollapseRunnables();
         setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
         showBouncer();
         disable(mDisabledUnmodified, true /* animate */);
@@ -2874,7 +2886,8 @@
         }
     }
 
-    public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned) {
+    public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
+            final boolean dismissShade) {
         if (onlyProvisioned && !isDeviceProvisioned()) return;
 
         final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
@@ -2884,32 +2897,27 @@
                 AsyncTask.execute(new Runnable() {
                     public void run() {
                         try {
+                            if (keyguardShowing) {
+                                ActivityManagerNative.getDefault()
+                                        .keyguardWaitingForActivityDrawn();
+                            }
                             intent.setFlags(
                                     Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                             mContext.startActivityAsUser(
                                     intent, new UserHandle(UserHandle.USER_CURRENT));
-                            if (keyguardShowing) {
-                                mWindowManagerService.overridePendingAppTransition(
-                                        null, 0, 0, null);
-                            }
+                            overrideActivityPendingAppTransition(keyguardShowing);
                         } catch (RemoteException e) {
                         }
                     }
                 });
-                animateCollapsePanels();
-
-                return DELAY_DISMISS_TO_ACTIVITY_LAUNCH;
+                if (dismissShade) {
+                    animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
+                }
+                return true;
             }
         });
     }
 
-    private View.OnClickListener mClockClickListener = new View.OnClickListener() {
-        public void onClick(View v) {
-            startActivityDismissingKeyguard(
-                    new Intent(Intent.ACTION_QUICK_CLOCK), true); // have fun, everyone
-        }
-    };
-
     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         public void onReceive(Context context, Intent intent) {
             if (DEBUG) Log.v(TAG, "onReceive: " + intent);
@@ -3208,19 +3216,7 @@
     }
 
     private void handleStartSettingsActivity(Intent intent, boolean onlyProvisioned) {
-        if (onlyProvisioned && !isDeviceProvisioned()) return;
-        try {
-            // Dismiss the lock screen when Settings starts.
-            ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
-        } catch (RemoteException e) {
-        }
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
-        animateCollapsePanels();
-    }
-
-    public void startSettingsActivity(String action) {
-        postStartSettingsActivity(new Intent(action), 0);
+        startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
     }
 
     private static class FastColorDrawable extends Drawable {
@@ -3363,6 +3359,14 @@
         }
     }
 
+    public boolean isCollapsing() {
+        return mNotificationPanel.isCollapsing();
+    }
+
+    public void addPostCollapseAction(Runnable r) {
+        mPostCollapseRunnables.add(r);
+    }
+
     public boolean isInLaunchTransition() {
         return mNotificationPanel.isLaunchTransitionRunning()
                 || mNotificationPanel.isLaunchTransitionFinished();
@@ -3603,10 +3607,7 @@
     }
 
     public void onTrackingStarted() {
-        if (mPostCollapseCleanup != null) {
-            mPostCollapseCleanup.run();
-            mPostCollapseCleanup = null;
-        }
+        runPostCollapseRunnables();
     }
 
     public void onUnlockHintStarted() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index 0c62fd3..85aa00d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -483,17 +483,19 @@
         } else if (v == mAlarmStatus && mNextAlarm != null) {
             PendingIntent showIntent = mNextAlarm.getShowIntent();
             if (showIntent != null && showIntent.isActivity()) {
-                mActivityStarter.startActivity(showIntent.getIntent());
+                mActivityStarter.startActivity(showIntent.getIntent(), true /* dismissShade */);
             }
         }
     }
 
     private void startSettingsActivity() {
-        mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));
+        mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS),
+                true /* dismissShade */);
     }
 
     private void startBatteryActivity() {
-        mActivityStarter.startActivity(new Intent(Intent.ACTION_POWER_USAGE_SUMMARY));
+        mActivityStarter.startActivity(new Intent(Intent.ACTION_POWER_USAGE_SUMMARY),
+                true /* dismissShade */);
     }
 
     public void setQSPanel(QSPanel qsp) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 68dd4f9..b03e6c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -206,12 +206,13 @@
      * Starts the animation before we dismiss Keyguard, i.e. an disappearing animation on the
      * security view of the bouncer.
      *
-     * @param finishRunnable the runnable to be run after the animation finished
+     * @param finishRunnable the runnable to be run after the animation finished, or {@code null} if
+     *                       no action should be run
      */
     public void startPreHideAnimation(Runnable finishRunnable) {
         if (mBouncer.isShowing()) {
             mBouncer.startPreHideAnimation(finishRunnable);
-        } else {
+        } else if (finishRunnable != null) {
             finishRunnable.run();
         }
     }
@@ -362,4 +363,17 @@
     public boolean interceptMediaKey(KeyEvent event) {
         return mBouncer.interceptMediaKey(event);
     }
+
+    public void onActivityDrawn() {
+        if (mPhoneStatusBar.isCollapsing()) {
+            mPhoneStatusBar.addPostCollapseAction(new Runnable() {
+                @Override
+                public void run() {
+                    mViewMediatorCallback.readyForKeyguardDone();
+                }
+            });
+        } else {
+            mViewMediatorCallback.readyForKeyguardDone();
+        }
+    }
 }