am b8c4a0f9: am 87024f73: am 16158852: Merge "Ensure that loading and unloading of tasks happen symmetrically with lifecycle events. (Bug 18574950)" into lmp-mr1-dev

* commit 'b8c4a0f99864378dc256c66db22970a53a82fc4c':
  Ensure that loading and unloading of tasks happen symmetrically with lifecycle events. (Bug 18574950)
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index 4f0700e..f1bf66d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -61,15 +61,8 @@
 /** A proxy implementation for the recents component */
 public class AlternateRecentsComponent implements ActivityOptions.OnAnimationStartedListener {
 
-    final public static String EXTRA_FROM_HOME = "recents.triggeredOverHome";
-    final public static String EXTRA_FROM_SEARCH_HOME = "recents.triggeredOverSearchHome";
-    final public static String EXTRA_FROM_APP_THUMBNAIL = "recents.animatingWithThumbnail";
-    final public static String EXTRA_FROM_TASK_ID = "recents.activeTaskId";
     final public static String EXTRA_TRIGGERED_FROM_ALT_TAB = "recents.triggeredFromAltTab";
     final public static String EXTRA_TRIGGERED_FROM_HOME_KEY = "recents.triggeredFromHomeKey";
-    final public static String EXTRA_REUSE_TASK_STACK_VIEWS = "recents.reuseTaskStackViews";
-    final public static String EXTRA_NUM_VISIBLE_TASKS = "recents.numVisibleTasks";
-    final public static String EXTRA_NUM_VISIBLE_THUMBNAILS = "recents.numVisibleThumbnails";
 
     final public static String ACTION_START_ENTER_ANIMATION = "action_start_enter_animation";
     final public static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity";
@@ -550,7 +543,8 @@
             ActivityOptions opts = getThumbnailTransitionActivityOptions(topTask, stack,
                     mDummyStackView);
             if (opts != null) {
-                startAlternateRecentsActivity(topTask, opts, EXTRA_FROM_APP_THUMBNAIL, stackVr);
+                startAlternateRecentsActivity(topTask, opts, false /* fromHome */,
+                        false /* fromSearchHome */, true /* fromThumbnail */, stackVr);
             } else {
                 // Fall through below to the non-thumbnail transition
                 useThumbnailTransition = false;
@@ -583,12 +577,13 @@
                 }
 
                 ActivityOptions opts = getHomeTransitionActivityOptions(fromSearchHome);
-                startAlternateRecentsActivity(topTask, opts,
-                        fromSearchHome ? EXTRA_FROM_SEARCH_HOME : EXTRA_FROM_HOME, stackVr);
+                startAlternateRecentsActivity(topTask, opts, true /* fromHome */, fromSearchHome,
+                        false /* fromThumbnail */, stackVr);
             } else {
                 // Otherwise we do the normal fade from an unknown source
                 ActivityOptions opts = getUnknownTransitionActivityOptions();
-                startAlternateRecentsActivity(topTask, opts, EXTRA_FROM_HOME, stackVr);
+                startAlternateRecentsActivity(topTask, opts, true /* fromHome */,
+                        false /* fromSearchHome */, false /* fromThumbnail */, stackVr);
             }
         }
         mLastToggleTime = SystemClock.elapsedRealtime();
@@ -596,21 +591,24 @@
 
     /** Starts the recents activity */
     void startAlternateRecentsActivity(ActivityManager.RunningTaskInfo topTask,
-            ActivityOptions opts, String extraFlag,
+            ActivityOptions opts, boolean fromHome, boolean fromSearchHome, boolean fromThumbnail,
             TaskStackViewLayoutAlgorithm.VisibilityReport vr) {
+        // Update the configuration based on the launch options
+        mConfig.launchedFromHome = fromSearchHome || fromHome;
+        mConfig.launchedFromSearchHome = fromSearchHome;
+        mConfig.launchedFromAppWithThumbnail = fromThumbnail;
+        mConfig.launchedToTaskId = (topTask != null) ? topTask.id : -1;
+        mConfig.launchedWithAltTab = mTriggeredFromAltTab;
+        mConfig.launchedReuseTaskStackViews = mCanReuseTaskStackViews;
+        mConfig.launchedNumVisibleTasks = vr.numVisibleTasks;
+        mConfig.launchedNumVisibleThumbnails = vr.numVisibleThumbnails;
+        mConfig.launchedHasConfigurationChanged = false;
+
         Intent intent = new Intent(sToggleRecentsAction);
         intent.setClassName(sRecentsPackage, sRecentsActivity);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
                 | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
-        if (extraFlag != null) {
-            intent.putExtra(extraFlag, true);
-        }
-        intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, mTriggeredFromAltTab);
-        intent.putExtra(EXTRA_FROM_TASK_ID, (topTask != null) ? topTask.id : -1);
-        intent.putExtra(EXTRA_REUSE_TASK_STACK_VIEWS, mCanReuseTaskStackViews);
-        intent.putExtra(EXTRA_NUM_VISIBLE_TASKS, vr.numVisibleTasks);
-        intent.putExtra(EXTRA_NUM_VISIBLE_THUMBNAILS, vr.numVisibleThumbnails);
         if (opts != null) {
             mContext.startActivityAsUser(intent, opts.toBundle(), UserHandle.CURRENT);
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index a37bc54..6baff96 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -108,8 +108,6 @@
 
         @Override
         public void run() {
-            // Mark Recents as no longer visible
-            onRecentsActivityVisibilityChanged(false);
             // Finish Recents
             if (mLaunchIntent != null) {
                 if (mLaunchOpts != null) {
@@ -133,8 +131,6 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
             if (action.equals(AlternateRecentsComponent.ACTION_HIDE_RECENTS_ACTIVITY)) {
-                // Mark Recents as no longer visible
-                AlternateRecentsComponent.notifyVisibilityChanged(false);
                 if (intent.getBooleanExtra(AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false)) {
                     // If we are hiding from releasing Alt-Tab, dismiss Recents to the focused app
                     dismissRecentsToFocusedTaskOrHome(false);
@@ -186,24 +182,6 @@
 
     /** Updates the set of recent tasks */
     void updateRecentsTasks(Intent launchIntent) {
-        // Update the configuration based on the launch intent
-        boolean fromSearchHome = launchIntent.getBooleanExtra(
-                AlternateRecentsComponent.EXTRA_FROM_SEARCH_HOME, false);
-        int numVisibleTasks = launchIntent.getIntExtra(
-                AlternateRecentsComponent.EXTRA_NUM_VISIBLE_TASKS, 0);
-        int numVisibleThumbnails = launchIntent.getIntExtra(
-                AlternateRecentsComponent.EXTRA_NUM_VISIBLE_THUMBNAILS, 0);
-        mConfig.launchedFromHome = fromSearchHome || launchIntent.getBooleanExtra(
-                AlternateRecentsComponent.EXTRA_FROM_HOME, false);
-        mConfig.launchedFromAppWithThumbnail = launchIntent.getBooleanExtra(
-                AlternateRecentsComponent.EXTRA_FROM_APP_THUMBNAIL, false);
-        mConfig.launchedToTaskId = launchIntent.getIntExtra(
-                AlternateRecentsComponent.EXTRA_FROM_TASK_ID, -1);
-        mConfig.launchedWithAltTab = launchIntent.getBooleanExtra(
-                AlternateRecentsComponent.EXTRA_TRIGGERED_FROM_ALT_TAB, false);
-        mConfig.launchedReuseTaskStackViews = launchIntent.getBooleanExtra(
-                AlternateRecentsComponent.EXTRA_REUSE_TASK_STACK_VIEWS, false);
-
         // If AlternateRecentsComponent has preloaded a load plan, then use that to prevent
         // reconstructing the task stack
         RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
@@ -218,8 +196,8 @@
         }
         RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
         loadOpts.runningTaskId = mConfig.launchedToTaskId;
-        loadOpts.numVisibleTasks = numVisibleTasks;
-        loadOpts.numVisibleTaskThumbnails = numVisibleThumbnails;
+        loadOpts.numVisibleTasks = mConfig.launchedNumVisibleTasks;
+        loadOpts.numVisibleTaskThumbnails = mConfig.launchedNumVisibleThumbnails;
         loader.loadTasks(this, plan, loadOpts);
 
         SpaceNode root = plan.getSpaceNode();
@@ -237,9 +215,9 @@
                 Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
         mFinishLaunchHomeRunnable = new FinishRecentsRunnable(homeIntent,
             ActivityOptions.makeCustomAnimation(this,
-                fromSearchHome ? R.anim.recents_to_search_launcher_enter :
+                mConfig.launchedFromSearchHome ? R.anim.recents_to_search_launcher_enter :
                         R.anim.recents_to_launcher_enter,
-                fromSearchHome ? R.anim.recents_to_search_launcher_exit :
+                    mConfig.launchedFromSearchHome ? R.anim.recents_to_search_launcher_exit :
                         R.anim.recents_to_launcher_exit));
 
         // Mark the task that is the launch target
@@ -403,12 +381,12 @@
         mEmptyViewStub = (ViewStub) findViewById(R.id.empty_view_stub);
         mDebugOverlayStub = (ViewStub) findViewById(R.id.debug_overlay_stub);
         mScrimViews = new SystemBarScrimViews(this, mConfig);
+        mStatusBar = ((SystemUIApplication) getApplication())
+                .getComponent(PhoneStatusBar.class);
         inflateDebugOverlay();
 
         // Bind the search app widget when we first start up
         bindSearchBarAppWidget();
-        // Update the recent tasks
-        updateRecentsTasks(getIntent());
 
         // Register the broadcast receiver to handle messages when the screen is turned off
         IntentFilter filter = new IntentFilter();
@@ -424,17 +402,6 @@
         } catch (InvocationTargetException e) {
             e.printStackTrace();
         }
-
-        // Update if we are getting a configuration change
-        if (savedInstanceState != null) {
-            // Update RecentsConfiguration
-            mConfig.updateOnConfigurationChange();
-            // Trigger the enter animation
-            onEnterAnimationTriggered();
-        }
-
-        mStatusBar = ((SystemUIApplication) getApplication())
-                .getComponent(PhoneStatusBar.class);
     }
 
     /** Inflates the debug overlay if debug mode is enabled. */
@@ -449,14 +416,6 @@
         }
     }
 
-    /** Handles changes to the activity visibility. */
-    void onRecentsActivityVisibilityChanged(boolean visible) {
-        if (!visible) {
-            AlternateRecentsComponent.notifyVisibilityChanged(visible);
-        }
-        mVisible = visible;
-    }
-
     @Override
     protected void onNewIntent(Intent intent) {
         super.onNewIntent(intent);
@@ -469,14 +428,13 @@
         if (mDebugOverlay != null) {
             mDebugOverlay.clear();
         }
-
-        // Update the recent tasks
-        updateRecentsTasks(intent);
     }
 
     @Override
     protected void onStart() {
         super.onStart();
+        mVisible = true;
+        AlternateRecentsComponent.notifyVisibilityChanged(true);
 
         // Register the broadcast receiver to handle messages from our service
         IntentFilter filter = new IntentFilter();
@@ -487,19 +445,16 @@
 
         // Register any broadcast receivers for the task loader
         RecentsTaskLoader.getInstance().registerReceivers(this, mRecentsView);
-    }
 
-    @Override
-    protected void onResume() {
-        super.onResume();
-
-        // Mark Recents as visible
-        onRecentsActivityVisibilityChanged(true);
+        // Update the recent tasks
+        updateRecentsTasks(getIntent());
     }
 
     @Override
     protected void onStop() {
         super.onStop();
+        mVisible = false;
+        AlternateRecentsComponent.notifyVisibilityChanged(false);
 
         // Notify the views that we are no longer visible
         mRecentsView.onRecentsHidden();
@@ -641,8 +596,6 @@
 
     @Override
     public void onTaskViewClicked() {
-        // Mark recents as no longer visible
-        onRecentsActivityVisibilityChanged(false);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 2b33d14..52e7e7f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -124,8 +124,12 @@
     public boolean launchedWithNoRecentTasks;
     public boolean launchedFromAppWithThumbnail;
     public boolean launchedFromHome;
+    public boolean launchedFromSearchHome;
     public boolean launchedReuseTaskStackViews;
+    public boolean launchedHasConfigurationChanged;
     public int launchedToTaskId;
+    public int launchedNumVisibleTasks;
+    public int launchedNumVisibleThumbnails;
 
     /** Misc **/
     public boolean useHardwareLayers;
@@ -308,12 +312,10 @@
     /** Called when the configuration has changed, and we want to reset any configuration specific
      * members. */
     public void updateOnConfigurationChange() {
-        launchedWithAltTab = false;
-        launchedWithNoRecentTasks = false;
-        launchedFromAppWithThumbnail = false;
-        launchedFromHome = false;
+        // Reset this flag on configuration change to ensure that we recreate new task views
         launchedReuseTaskStackViews = false;
-        launchedToTaskId = -1;
+        // Set this flag to indicate that the configuration has changed since Recents last launched
+        launchedHasConfigurationChanged = true;
     }
 
     /** Returns whether the search bar app widget exists. */
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 33a36f6..169683f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -715,14 +715,20 @@
             mStartEnterAnimationContext = null;
         }
 
-        // When Alt-Tabbing, we scroll to and focus the previous task
+        // When Alt-Tabbing, focus the previous task (but leave the animation until we finish the
+        // enter animation).
         if (mConfig.launchedWithAltTab) {
-            if (mConfig.launchedFromHome) {
-                focusTask(Math.max(0, mStack.getTaskCount() - 1), false, true);
+            if (mConfig.launchedFromAppWithThumbnail) {
+                focusTask(Math.max(0, mStack.getTaskCount() - 2), false,
+                        mConfig.launchedHasConfigurationChanged);
             } else {
-                focusTask(Math.max(0, mStack.getTaskCount() - 2), false, true);
+                focusTask(Math.max(0, mStack.getTaskCount() - 1), false,
+                        mConfig.launchedHasConfigurationChanged);
             }
         }
+
+        // Start dozing
+        mUIDozeTrigger.startDozing();
     }
 
     /** Requests this task stacks to start it's enter-recents animation */
@@ -767,16 +773,27 @@
                 @Override
                 public void run() {
                     mStartEnterAnimationCompleted = true;
-                    // Start dozing
-                    mUIDozeTrigger.startDozing();
-                    // Focus the first view if accessibility is enabled
+                    // Poke the dozer to restart the trigger after the animation completes
+                    mUIDozeTrigger.poke();
+
                     RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
                     SystemServicesProxy ssp = loader.getSystemServicesProxy();
                     int childCount = getChildCount();
-                    if (childCount > 0 && ssp.isTouchExplorationEnabled()) {
-                        TaskView tv = ((TaskView) getChildAt(childCount - 1));
-                        tv.requestAccessibilityFocus();
-                        mPrevAccessibilityFocusedIndex = mStack.indexOfTask(tv.getTask());
+                    if (childCount > 0) {
+                        // Focus the first view if accessibility is enabled
+                        if (ssp.isTouchExplorationEnabled()) {
+                            TaskView tv = ((TaskView) getChildAt(childCount - 1));
+                            tv.requestAccessibilityFocus();
+                            mPrevAccessibilityFocusedIndex = mStack.indexOfTask(tv.getTask());
+                        }
+                    }
+
+                    // Start the focus animation when alt-tabbing
+                    if (mConfig.launchedWithAltTab && !mConfig.launchedHasConfigurationChanged) {
+                        View tv = getChildAt(mFocusedTaskIndex);
+                        if (tv != null) {
+                            ((TaskView) tv).setFocusedTask(true);
+                        }
                     }
                 }
             });
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
index 26fbbf4..49b9129 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
@@ -135,7 +135,6 @@
         // Update the task offsets
         float pAtBackMostCardTop = 0.5f;
         float pAtFrontMostCardTop = pAtBackMostCardTop;
-        float pAtSecondFrontMostCardTop = pAtBackMostCardTop;
         int taskCount = tasks.size();
         for (int i = 0; i < taskCount; i++) {
             Task task = tasks.get(i);
@@ -145,25 +144,19 @@
                 // Increment the peek height
                 float pPeek = task.group.isFrontMostTask(task) ?
                         pBetweenAffiliateOffset : pWithinAffiliateOffset;
-                pAtSecondFrontMostCardTop = pAtFrontMostCardTop;
                 pAtFrontMostCardTop += pPeek;
             }
         }
 
         mMaxScrollP = pAtFrontMostCardTop - ((1f - pTaskHeightOffset - pNavBarOffset));
         mMinScrollP = tasks.size() == 1 ? Math.max(mMaxScrollP, 0f) : 0f;
-        if (launchedWithAltTab) {
-            if (launchedFromHome) {
-                // Center the top most task, since that will be focused first
-                mInitialScrollP = pAtSecondFrontMostCardTop - 0.5f;
-            } else {
-                // Center the second top most task, since that will be focused first
-                mInitialScrollP = pAtSecondFrontMostCardTop - 0.5f;
-            }
+        if (launchedWithAltTab && launchedFromHome) {
+            // Center the top most task, since that will be focused first
+            mInitialScrollP = mMaxScrollP;
         } else {
             mInitialScrollP = pAtFrontMostCardTop - 0.825f;
         }
-        mInitialScrollP = Math.max(0, mInitialScrollP);
+        mInitialScrollP = Math.min(mMaxScrollP, Math.max(0, mInitialScrollP));
     }
 
     /**
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 de5974f..faa728d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -235,7 +235,9 @@
     void prepareEnterRecentsAnimation(boolean isTaskViewLaunchTargetTask,
                                              boolean occludesLaunchTarget, int offscreenY) {
         int initialDim = getDim();
-        if (mConfig.launchedFromAppWithThumbnail) {
+        if (mConfig.launchedHasConfigurationChanged) {
+            // Just load the views as-is
+        } else if (mConfig.launchedFromAppWithThumbnail) {
             if (isTaskViewLaunchTargetTask) {
                 // Set the dim to 0 so we can animate it in
                 initialDim = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index 464d007..05f6f40 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -237,15 +237,17 @@
 
     /** Animates this task bar if the user does not interact with the stack after a certain time. */
     void startNoUserInteractionAnimation() {
-        mDismissButton.setVisibility(View.VISIBLE);
-        mDismissButton.setAlpha(0f);
-        mDismissButton.animate()
-                .alpha(1f)
-                .setStartDelay(0)
-                .setInterpolator(mConfig.fastOutLinearInInterpolator)
-                .setDuration(mConfig.taskViewEnterFromAppDuration)
-                .withLayer()
-                .start();
+        if (mDismissButton.getVisibility() != View.VISIBLE) {
+            mDismissButton.setVisibility(View.VISIBLE);
+            mDismissButton.setAlpha(0f);
+            mDismissButton.animate()
+                    .alpha(1f)
+                    .setStartDelay(0)
+                    .setInterpolator(mConfig.fastOutLinearInInterpolator)
+                    .setDuration(mConfig.taskViewEnterFromAppDuration)
+                    .withLayer()
+                    .start();
+        }
     }
 
     /** Mark this task view that the user does has not interacted with the stack after a certain time. */