Workaround for empty recents, defer the enter animation.

- When docking the first time after starting up, the enter-animation 
  callback is not dispatched in the same way, and we end up with the
  callback before the first layout.  In such cases, defer sending the
  event which triggers the animation until the next frame when the
  layout is stable.

Bug: 28705801
Change-Id: If62eb03d6f297bff06982325ada9cd7f388438c3
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index a5f3e77..8dd9ca6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -107,6 +107,7 @@
     private boolean mFinishedOnStartup;
     private boolean mIgnoreAltTabRelease;
     private boolean mIsVisible;
+    private boolean mReceivedNewIntent;
 
     // Top level views
     private RecentsView mRecentsView;
@@ -120,6 +121,9 @@
     private int mFocusTimerDuration;
     private DozeTrigger mIterateTrigger;
     private final UserInteractionEvent mUserInteractionEvent = new UserInteractionEvent();
+    private final Runnable mSendEnterWindowAnimationCompleteRunnable = () -> {
+        EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
+    };
 
     /**
      * A common Runnable to finish Recents by launching Home with an animation depending on the
@@ -342,6 +346,7 @@
     @Override
     protected void onNewIntent(Intent intent) {
         super.onNewIntent(intent);
+        mReceivedNewIntent = true;
 
         // Reload the stack view
         reloadStackView();
@@ -419,7 +424,16 @@
     @Override
     public void onEnterAnimationComplete() {
         super.onEnterAnimationComplete();
-        EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
+
+        // Workaround for b/28705801, on first docking, we may receive the enter animation callback
+        // before the first layout, so in such cases, send the event on the next frame after all
+        // the views are laid out and attached (and registered to the EventBus).
+        mHandler.removeCallbacks(mSendEnterWindowAnimationCompleteRunnable);
+        if (!mReceivedNewIntent) {
+            mHandler.post(mSendEnterWindowAnimationCompleteRunnable);
+        } else {
+            mSendEnterWindowAnimationCompleteRunnable.run();
+        }
     }
 
     @Override
@@ -477,6 +491,7 @@
 
         // Notify that recents is now hidden
         mIsVisible = false;
+        mReceivedNewIntent = false;
         EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, false));
         MetricsLogger.hidden(this, MetricsEvent.OVERVIEW_ACTIVITY);