OSDN Git Service

Launch state/config change audit. (Part 1)
authorWinson <winsonc@google.com>
Fri, 25 Mar 2016 19:23:12 +0000 (12:23 -0700)
committerWinson <winsonc@google.com>
Sat, 26 Mar 2016 01:16:46 +0000 (18:16 -0700)
- Fixing issue with onResume logic being run even when the window focus
  is changing.  This only needs to be run when we are launching into
  Recents again.
- Removed a bunch of launch state flags that are no longer necessary
  because of changes to configuration handling.  This reduces the work
  that we have to do on resize, etc.
- Decoupled the resume with the stack-update, which fixes a couple
  issues where we were updating the layout unexpectedly.
- Fixed an issue where we were not updating the nav bar scrims on
  configuration change
- Fixing margin start/end regression in header bar
- Fixing small issue with paddings being scaled beyond their base size
- Fixing issue where the clip state was not properly getting reset
  causing lots of overdraw.

Change-Id: I9aeb191a99ff23807b3f5d905f6480b10157a060

19 files changed:
packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java
packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java

index 9cba93b..8536882 100644 (file)
@@ -73,6 +73,7 @@ import com.android.systemui.recents.model.RecentsTaskLoadPlan;
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.recents.views.AnimationProps;
 import com.android.systemui.recents.views.RecentsView;
 import com.android.systemui.recents.views.SystemBarScrimViews;
 import com.android.systemui.statusbar.BaseStatusBar;
@@ -285,6 +286,9 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
         registerReceiver(mSystemBroadcastReceiver, filter);
 
         getWindow().addPrivateFlags(LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION);
+
+        // Reload the stack view
+        reloadStackView();
     }
 
     @Override
@@ -297,15 +301,17 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
     }
 
     @Override
-    public void onEnterAnimationComplete() {
-        super.onEnterAnimationComplete();
-        EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
-    }
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
 
-    @Override
-    protected void onResume() {
-        super.onResume();
+        // Reload the stack view
+        reloadStackView();
+    }
 
+    /**
+     * Reloads the stack views upon launching Recents.
+     */
+    private void reloadStackView() {
         // If the Recents component has preloaded a load plan, then use that to prevent
         // reconstructing the task stack
         RecentsTaskLoader loader = Recents.getTaskLoader();
@@ -328,38 +334,21 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
         loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
         loader.loadTasks(this, loadPlan, loadOpts);
         TaskStack stack = loadPlan.getTaskStack();
-        mRecentsView.onResume(mIsVisible, false /* multiWindowChange */, stack);
+        mRecentsView.onReload(mIsVisible, stack.getTaskCount() == 0);
+        mRecentsView.updateStack(stack);
 
-        // Animate the SystemUI scrims into view
-        Task launchTarget = stack.getLaunchTarget();
-        int taskCount = stack.getTaskCount();
-        int launchTaskIndexInStack = launchTarget != null
-                ? stack.indexOfStackTask(launchTarget)
-                : 0;
-        boolean hasNavBarScrim = (taskCount > 0) && !config.hasTransposedNavBar;
+        // Update the nav bar scrim, but defer the animation until the enter-window event
         boolean animateNavBarScrim = !launchState.launchedWhileDocking;
-        mScrimViews.prepareEnterRecentsAnimation(hasNavBarScrim, animateNavBarScrim);
+        updateNavBarScrim(animateNavBarScrim, null);
 
-        // If this is a new instance from a configuration change, then we have to manually trigger
-        // the enter animation state, or if recents was relaunched by AM, without going through
-        // the normal mechanisms
+        // If this is a new instance relaunched by AM, without going through the normal mechanisms,
+        // then we have to manually trigger the enter animation state
         boolean wasLaunchedByAm = !launchState.launchedFromHome &&
                 !launchState.launchedFromApp;
-        if (launchState.launchedHasConfigurationChanged || wasLaunchedByAm) {
+        if (wasLaunchedByAm) {
             EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
         }
 
-        mRecentsView.getViewTreeObserver().addOnPreDrawListener(
-                new ViewTreeObserver.OnPreDrawListener() {
-
-                    @Override
-                    public boolean onPreDraw() {
-                        mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
-                        EventBus.getDefault().post(new RecentsDrawnEvent());
-                        return true;
-                    }
-                });
-
         // Keep track of whether we launched from the nav bar button or via alt-tab
         if (launchState.launchedWithAltTab) {
             MetricsLogger.count(this, "overview_trigger_alttab", 1);
@@ -369,6 +358,10 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
 
         // Keep track of whether we launched from an app or from home
         if (launchState.launchedFromApp) {
+            Task launchTarget = stack.getLaunchTarget();
+            int launchTaskIndexInStack = launchTarget != null
+                    ? stack.indexOfStackTask(launchTarget)
+                    : 0;
             MetricsLogger.count(this, "overview_source_app", 1);
             // If from an app, track the stack index of the app in the stack (for affiliated tasks)
             MetricsLogger.histogram(this, "overview_source_app_index", launchTaskIndexInStack);
@@ -377,6 +370,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
         }
 
         // Keep track of the total stack task count
+        int taskCount = mRecentsView.getStack().getTaskCount();
         MetricsLogger.histogram(this, "overview_task_count", taskCount);
 
         // After we have resumed, set the visible state until the next onStop() call
@@ -384,6 +378,29 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
     }
 
     @Override
+    public void onEnterAnimationComplete() {
+        super.onEnterAnimationComplete();
+        EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // Notify of the next draw
+        mRecentsView.getViewTreeObserver().addOnPreDrawListener(
+                new ViewTreeObserver.OnPreDrawListener() {
+
+                    @Override
+                    public boolean onPreDraw() {
+                        mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this);
+                        EventBus.getDefault().post(new RecentsDrawnEvent());
+                        return true;
+                    }
+                });
+    }
+
+    @Override
     protected void onPause() {
         super.onPause();
 
@@ -395,10 +412,37 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
     public void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
 
+        // Update the nav bar for the current orientation
+        updateNavBarScrim(false /* animateNavBarScrim */, AnimationProps.IMMEDIATE);
+
         EventBus.getDefault().send(new ConfigurationChangedEvent());
     }
 
     @Override
+    public void onMultiWindowChanged(boolean inMultiWindow) {
+        super.onMultiWindowChanged(inMultiWindow);
+        EventBus.getDefault().send(new ConfigurationChangedEvent());
+
+        if (mRecentsView != null) {
+            // Reload the task stack completely
+            RecentsConfiguration config = Recents.getConfiguration();
+            RecentsActivityLaunchState launchState = config.getLaunchState();
+            RecentsTaskLoader loader = Recents.getTaskLoader();
+            RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
+            loader.preloadTasks(loadPlan, -1 /* topTaskId */, false /* isTopTaskHome */);
+
+            RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
+            loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
+            loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
+            loader.loadTasks(this, loadPlan, loadOpts);
+
+            mRecentsView.updateStack(loadPlan.getTaskStack());
+        }
+
+        EventBus.getDefault().send(new MultiWindowStateChangedEvent(inMultiWindow));
+    }
+
+    @Override
     protected void onStop() {
         super.onStop();
 
@@ -454,28 +498,6 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
     }
 
     @Override
-    public void onMultiWindowChanged(boolean inMultiWindow) {
-        super.onMultiWindowChanged(inMultiWindow);
-        EventBus.getDefault().send(new ConfigurationChangedEvent());
-
-        // Reload the task stack completely
-        RecentsConfiguration config = Recents.getConfiguration();
-        RecentsActivityLaunchState launchState = config.getLaunchState();
-        RecentsTaskLoader loader = Recents.getTaskLoader();
-        RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
-        loader.preloadTasks(loadPlan, -1 /* topTaskId */, false /* isTopTaskHome */);
-
-        RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
-        loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
-        loadOpts.numVisibleTaskThumbnails = launchState.launchedNumVisibleThumbnails;
-        loader.loadTasks(this, loadPlan, loadOpts);
-
-        mRecentsView.onResume(mIsVisible, true /* multiWindowChange */, loadPlan.getTaskStack());
-
-        EventBus.getDefault().send(new MultiWindowStateChangedEvent(inMultiWindow));
-    }
-
-    @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         switch (keyCode) {
             case KeyEvent.KEYCODE_TAB: {
@@ -697,4 +719,18 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
         });
         return true;
     }
+
+    /**
+     * Updates the nav bar scrim.
+     */
+    private void updateNavBarScrim(boolean animateNavBarScrim, AnimationProps animation) {
+        // Animate the SystemUI scrims into view
+        SystemServicesProxy ssp = Recents.getSystemServices();
+        int taskCount = mRecentsView.getStack().getTaskCount();
+        boolean hasNavBarScrim = (taskCount > 0) && !ssp.hasTransposedNavBar();
+        mScrimViews.prepareEnterRecentsAnimation(hasNavBarScrim, animateNavBarScrim);
+        if (animateNavBarScrim && animation != null) {
+            mScrimViews.animateNavBarScrimVisibility(true, animation);
+        }
+    }
 }
index ab3b79e..77f7739 100644 (file)
@@ -31,8 +31,6 @@ public class RecentsActivityLaunchState {
     public boolean launchedFromApp;
     public boolean launchedFromAppDocked;
     public boolean launchedFromHome;
-    public boolean launchedReuseTaskStackViews;
-    public boolean launchedHasConfigurationChanged;
     public boolean launchedViaDragGesture;
     public boolean launchedWhileDocking;
     public int launchedToTaskId;
@@ -45,7 +43,6 @@ public class RecentsActivityLaunchState {
         launchedFromAppDocked = false;
         launchedToTaskId = -1;
         launchedWithAltTab = false;
-        launchedHasConfigurationChanged = false;
         launchedViaDragGesture = false;
         launchedWhileDocking = false;
     }
@@ -53,10 +50,6 @@ public class RecentsActivityLaunchState {
     /** Called when the configuration has changed, and we want to reset any configuration specific
      * members. */
     public void updateOnConfigurationChange() {
-        // Reset this flag on configuration change to ensure that we recreate new task views
-        launchedReuseTaskStackViews = false;
-        // Set this flag to indicate that the configuration has changed since Recents last launched
-        launchedHasConfigurationChanged = true;
         launchedViaDragGesture = false;
         launchedWhileDocking = false;
     }
index 2afb09a..40613f0 100644 (file)
@@ -47,11 +47,6 @@ public class RecentsConfiguration {
     // Launch states
     public RecentsActivityLaunchState mLaunchState = new RecentsActivityLaunchState();
 
-    // TODO: Values determined by the current context, needs to be refactored into something that is
-    //       agnostic of the activity context, but still calculable from the Recents component for
-    //       the transition into recents
-    public boolean hasTransposedNavBar;
-
     // Since the positions in Recents has to be calculated globally (before the RecentsActivity
     // starts), we need to calculate some resource values ourselves, instead of relying on framework
     // resources.
@@ -79,13 +74,6 @@ public class RecentsConfiguration {
     }
 
     /**
-     * Updates the configuration based on the current state of the system
-     */
-    void update(Rect systemInsets) {
-        hasTransposedNavBar = systemInsets.right > 0;
-    }
-
-    /**
      * Returns the activity launch state.
      * TODO: This will be refactored out of RecentsConfiguration.
      */
index fce120a..e682882 100644 (file)
@@ -140,7 +140,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
     protected Context mContext;
     protected Handler mHandler;
     TaskStackListenerImpl mTaskStackListener;
-    protected boolean mCanReuseTaskStackViews = true;
     boolean mDraggingInRecents;
     boolean mLaunchedWhileDocking;
 
@@ -209,8 +208,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
     public void onConfigurationChanged() {
         reloadHeaderBarLayout();
         updateHeaderBarLayout(null /* stack */);
-        // Don't reuse task stack views if the configuration changes
-        mCanReuseTaskStackViews = false;
         Recents.getConfiguration().updateOnConfigurationChange();
     }
 
@@ -592,9 +589,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
         calculateWindowStableInsets(systemInsets, windowRect);
         windowRect.offsetTo(0, 0);
 
-        // Update the configuration for the current state
-        Recents.getConfiguration().update(systemInsets);
-
         TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
         stackLayout.getTaskStackBounds(windowRect, systemInsets.top, systemInsets.right,
                 mTaskStackBounds);
@@ -605,8 +599,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
         if (stack != null) {
             stackLayout.initialize(windowRect, taskStackBounds,
                     TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack));
-            mDummyStackView.setTasks(stack, false /* notifyStackChanges */,
-                    false /* relayoutTaskStack */, false /* multiWindowChange */);
+            mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);
         }
         Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
         if (!taskViewBounds.equals(mLastTaskViewBounds)) {
@@ -862,10 +855,8 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
         launchState.launchedToTaskId = (topTask != null) ? topTask.id : -1;
         launchState.launchedFromAppDocked = mLaunchedWhileDocking;
         launchState.launchedWithAltTab = mTriggeredFromAltTab;
-        launchState.launchedReuseTaskStackViews = mCanReuseTaskStackViews;
         launchState.launchedNumVisibleTasks = stackVr.numVisibleTasks;
         launchState.launchedNumVisibleThumbnails = stackVr.numVisibleThumbnails;
-        launchState.launchedHasConfigurationChanged = false;
         launchState.launchedViaDragGesture = mDraggingInRecents;
         launchState.launchedWhileDocking = mLaunchedWhileDocking;
 
@@ -915,7 +906,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
         } else {
             mContext.startActivityAsUser(intent, UserHandle.CURRENT);
         }
-        mCanReuseTaskStackViews = true;
         EventBus.getDefault().send(new RecentsActivityStartingEvent());
     }
 
index 1e624fd..3b759c0 100644 (file)
@@ -1064,6 +1064,16 @@ public class SystemServicesProxy {
         }
     }
 
+    /**
+     * Returns whether the device has a transposed nav bar (on the right of the screen) in the
+     * current display orientation.
+     */
+    public boolean hasTransposedNavBar() {
+        Rect insets = new Rect();
+        getStableInsets(insets);
+        return insets.right > 0;
+    }
+
     private final class H extends Handler {
         private static final int ON_TASK_STACK_CHANGED = 1;
         private static final int ON_ACTIVITY_PINNED = 2;
index dbb692c..82c81ae 100644 (file)
@@ -274,7 +274,9 @@ public class RecentsTaskLoader {
             new TaskKeyLruCache.EvictionCallback() {
         @Override
         public void onEntryEvicted(Task.TaskKey key) {
-            mActivityInfoCache.remove(key.getComponent());
+            if (key != null) {
+                mActivityInfoCache.remove(key.getComponent());
+            }
         }
     };
 
index a930791..5a2507d 100644 (file)
@@ -220,6 +220,11 @@ public class TaskStack {
          */
         void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
             Task newFrontMostTask, AnimationProps animation, boolean fromDockGesture);
+
+        /**
+         * Notifies when tasks in the stack have been updated.
+         */
+        void onStackTasksUpdated(TaskStack stack);
     }
 
     /**
@@ -560,14 +565,19 @@ public class TaskStack {
         mStackTaskList.set(allTasks);
         mRawTaskList = allTasks;
 
+        // Update the affiliated groupings
+        createAffiliatedGroupings(context);
+
         // Only callback for the newly added tasks after this stack has been updated
         int addedTaskCount = addedTasks.size();
         for (int i = 0; i < addedTaskCount; i++) {
             mCb.onStackTaskAdded(this, addedTasks.get(i));
         }
 
-        // Update the affiliated groupings
-        createAffiliatedGroupings(context);
+        // Notify that the task stack has been updated
+        if (notifyStackChanges) {
+            mCb.onStackTasksUpdated(this);
+        }
     }
 
     /**
index 58d2da7..134b90c 100644 (file)
@@ -313,7 +313,7 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
         RecentsActivityLaunchState launchState = config.getLaunchState();
         boolean wasLaunchedByAm = !launchState.launchedFromHome &&
                 !launchState.launchedFromApp;
-        if (launchState.launchedHasConfigurationChanged || wasLaunchedByAm) {
+        if (wasLaunchedByAm) {
             EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
         }
 
index aa27325..c1b47dc 100644 (file)
@@ -24,10 +24,13 @@ import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.os.SystemClock;
 import android.os.UserHandle;
-import com.android.systemui.recents.*;
+
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.RecentsActivityLaunchState;
+import com.android.systemui.recents.RecentsConfiguration;
+import com.android.systemui.recents.RecentsImpl;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
-import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.TaskStack;
 import com.android.systemui.recents.tv.views.TaskCardView;
@@ -101,8 +104,6 @@ public class RecentsTvImpl extends RecentsImpl{
         launchState.launchedFromApp = fromThumbnail;
         launchState.launchedToTaskId = (topTask != null) ? topTask.id : -1;
         launchState.launchedWithAltTab = mTriggeredFromAltTab;
-        launchState.launchedReuseTaskStackViews = mCanReuseTaskStackViews;
-        launchState.launchedHasConfigurationChanged = false;
 
         Intent intent = new Intent();
         intent.setClassName(RECENTS_PACKAGE, RECENTS_TV_ACTIVITY);
@@ -115,7 +116,6 @@ public class RecentsTvImpl extends RecentsImpl{
         } else {
             mContext.startActivityAsUser(intent, UserHandle.CURRENT);
         }
-        mCanReuseTaskStackViews = true;
         EventBus.getDefault().send(new RecentsActivityStartingEvent());
     }
 
index 22ade9f..3d0e75a 100644 (file)
@@ -156,4 +156,9 @@ public class TaskStackHorizontalGridView extends HorizontalGridView implements T
             }
         }
     }
+
+    @Override
+    public void onStackTasksUpdated(TaskStack stack) {
+        // Do nothing
+    }
 }
index 7c5b441..98616f4 100644 (file)
@@ -82,9 +82,9 @@ public class RecentsTransitionHelper {
         }
     };
 
-    public RecentsTransitionHelper(Context context, Handler handler) {
+    public RecentsTransitionHelper(Context context) {
         mContext = context;
-        mHandler = handler;
+        mHandler = new Handler();
     }
 
     /**
index 28880df..a1ba493 100644 (file)
@@ -19,7 +19,6 @@ package com.android.systemui.recents.views;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 
 import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.app.ActivityOptions.OnAnimationStartedListener;
 import android.content.Context;
@@ -29,10 +28,6 @@ import android.graphics.Outline;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IRemoteCallback;
-import android.os.RemoteException;
 import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.view.AppTransitionAnimationSpec;
@@ -44,11 +39,9 @@ import android.view.ViewDebug;
 import android.view.ViewOutlineProvider;
 import android.view.ViewPropertyAnimator;
 import android.view.WindowInsets;
-import android.view.WindowManagerGlobal;
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.Interpolators;
@@ -94,8 +87,6 @@ public class RecentsView extends FrameLayout {
     private static final int DEFAULT_UPDATE_SCRIM_DURATION = 200;
     private static final float DEFAULT_SCRIM_ALPHA = 0.33f;
 
-    private final Handler mHandler;
-
     private TaskStack mStack;
     private TaskStackView mTaskStackView;
     private TextView mStackActionButton;
@@ -133,18 +124,17 @@ public class RecentsView extends FrameLayout {
         setWillNotDraw(false);
 
         SystemServicesProxy ssp = Recents.getSystemServices();
-        mHandler = new Handler();
-        mTransitionHelper = new RecentsTransitionHelper(getContext(), mHandler);
+        mTransitionHelper = new RecentsTransitionHelper(getContext());
         mDividerSize = ssp.getDockedDividerSize(context);
         mTouchHandler = new RecentsViewTouchHandler(this);
         mFlingAnimationUtils = new FlingAnimationUtils(context, 0.3f);
 
-        final float cornerRadius = context.getResources().getDimensionPixelSize(
-                R.dimen.recents_task_view_rounded_corners_radius);
         LayoutInflater inflater = LayoutInflater.from(context);
         if (RecentsDebugFlags.Static.EnableStackActionButton) {
-            mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button, this,
-                    false);
+            float cornerRadius = context.getResources().getDimensionPixelSize(
+                    R.dimen.recents_task_view_rounded_corners_radius);
+            mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button,
+                    this, false);
             mStackActionButton.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View v) {
@@ -166,19 +156,17 @@ public class RecentsView extends FrameLayout {
         setBackground(mBackgroundScrim);
     }
 
-    /** Set/get the bsp root node */
-    public void onResume(boolean isResumingFromVisible, boolean multiWindowChange,
-            TaskStack stack) {
+    /**
+     * Called from RecentsActivity when it is relaunched.
+     */
+    public void onReload(boolean isResumingFromVisible, boolean isTaskStackEmpty) {
         RecentsConfiguration config = Recents.getConfiguration();
         RecentsActivityLaunchState launchState = config.getLaunchState();
 
-        if (!multiWindowChange &&
-                (mTaskStackView == null || !launchState.launchedReuseTaskStackViews)) {
+        if (mTaskStackView == null) {
             isResumingFromVisible = false;
-            removeView(mTaskStackView);
             mTaskStackView = new TaskStackView(getContext());
             mTaskStackView.setSystemInsets(mSystemInsets);
-            mStack = mTaskStackView.getStack();
             addView(mTaskStackView);
         }
 
@@ -187,9 +175,7 @@ public class RecentsView extends FrameLayout {
         mLastTaskLaunchedWasFreeform = false;
 
         // Update the stack
-        mTaskStackView.onResume(isResumingFromVisible);
-        mTaskStackView.setTasks(stack, isResumingFromVisible /* notifyStackChanges */,
-                true /* relayoutTaskStack */, multiWindowChange);
+        mTaskStackView.onReload(isResumingFromVisible);
 
         if (isResumingFromVisible) {
             // If we are already visible, then restore the background scrim
@@ -199,12 +185,20 @@ public class RecentsView extends FrameLayout {
             // Otherwise, defer until the enter animation completes to animate the scrim alpha with
             // the tasks for the home animation.
             if (launchState.launchedWhileDocking || launchState.launchedFromApp
-                    || mStack.getTaskCount() == 0) {
+                    || isTaskStackEmpty) {
                 mBackgroundScrim.setAlpha((int) (DEFAULT_SCRIM_ALPHA * 255));
             } else {
                 mBackgroundScrim.setAlpha(0);
             }
         }
+    }
+
+    /**
+     * Called from RecentsActivity when the task stack is updated.
+     */
+    public void updateStack(TaskStack stack) {
+        mStack = stack;
+        mTaskStackView.setTasks(stack, true /* allowNotifyStackChanges */);
 
         // Update the top level view's visibilities
         if (stack.getTaskCount() > 0) {
@@ -215,6 +209,13 @@ public class RecentsView extends FrameLayout {
     }
 
     /**
+     * Returns the current TaskStack.
+     */
+    public TaskStack getStack() {
+        return mStack;
+    }
+
+    /**
      * Returns whether the last task launched was in the freeform stack or not.
      */
     public boolean isLastTaskLaunchedFreeform() {
index 6bdaaf9..9c8189a 100644 (file)
@@ -46,7 +46,7 @@ public class SystemBarScrimViews {
 
     /**
      * Prepares the scrim views for animating when entering Recents. This will be called before
-     * the first draw.
+     * the first draw, unless we are updating the scrim on configuration change.
      */
     public void prepareEnterRecentsAnimation(boolean hasNavBarScrim, boolean animateNavBarScrim) {
         mHasNavBarScrim = hasNavBarScrim;
index 4155dd2..1c7d609 100644 (file)
@@ -152,8 +152,6 @@ public class TaskStackAnimationHelper {
 
             if (hideTask) {
                 tv.setVisibility(View.INVISIBLE);
-            } else if (launchState.launchedHasConfigurationChanged) {
-                // Just load the views as-is
             } else if (launchState.launchedFromApp && !launchState.launchedWhileDocking) {
                 if (task.isLaunchTarget) {
                     tv.onPrepareLaunchTargetForEnterAnimation();
@@ -354,6 +352,12 @@ public class TaskStackAnimationHelper {
 
             if (tv == launchingTaskView) {
                 tv.setClipViewInStack(false);
+                postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
+                    @Override
+                    public void run() {
+                        tv.setClipViewInStack(true);
+                    }
+                });
                 tv.onStartLaunchTargetLaunchAnimation(taskViewExitToAppDuration,
                         screenPinningRequested, postAnimationTrigger);
             } else if (currentTaskOccludesLaunchTarget) {
@@ -386,7 +390,8 @@ public class TaskStackAnimationHelper {
         int taskViewRemoveAnimTranslationXPx = res.getDimensionPixelSize(
                 R.dimen.recents_task_view_remove_anim_translation_x);
 
-        // Disabling clipping with the stack while the view is animating away
+        // Disabling clipping with the stack while the view is animating away, this will get
+        // restored when the task is next picked up from the view pool
         deleteTaskView.setClipViewInStack(false);
 
         // Compose the new animation and transform and star the animation
@@ -395,9 +400,6 @@ public class TaskStackAnimationHelper {
             @Override
             public void onAnimationEnd(Animator animation) {
                 postAnimationTrigger.decrement();
-
-                // Re-enable clipping with the stack (we will reuse this view)
-                deleteTaskView.setClipViewInStack(true);
             }
         });
         postAnimationTrigger.increment();
index 83f8b7e..36cdb1c 100644 (file)
@@ -953,14 +953,8 @@ public class TaskStackLayoutAlgorithm {
      */
     public void getTaskStackBounds(Rect windowRect, int topInset, int rightInset,
             Rect taskStackBounds) {
-        RecentsConfiguration config = Recents.getConfiguration();
-        if (config.hasTransposedNavBar) {
-            taskStackBounds.set(windowRect.left, windowRect.top + topInset,
-                    windowRect.right - rightInset, windowRect.bottom);
-        } else {
-            taskStackBounds.set(windowRect.left, windowRect.top + topInset,
-                    windowRect.right - rightInset, windowRect.bottom);
-        }
+        taskStackBounds.set(windowRect.left, windowRect.top + topInset,
+                windowRect.right - rightInset, windowRect.bottom);
 
         // Ensure that the new width is at most the smaller display edge size
         SystemServicesProxy ssp = Recents.getSystemServices();
@@ -1105,9 +1099,11 @@ public class TaskStackLayoutAlgorithm {
     private int getScaleForExtent(Rect instance, Rect other, int value, int minValue,
                                   @Extent int extent) {
         if (extent == WIDTH) {
-            return Math.max(minValue, (int) (((float) instance.width() / other.width()) * value));
+            float scale = Utilities.clamp01((float) instance.width() / other.width());
+            return Math.max(minValue, (int) (scale * value));
         } else if (extent == HEIGHT) {
-            return Math.max(minValue, (int) (((float) instance.height() / other.height()) * value));
+            float scale = Utilities.clamp01((float) instance.height() / other.height());
+            return Math.max(minValue, (int) (scale * value));
         }
         return value;
     }
index bea47f1..a1a43ec 100644 (file)
@@ -255,10 +255,23 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
         }
     }
 
+    @Override
+    protected void onAttachedToWindow() {
+        EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
+        super.onAttachedToWindow();
+        readSystemFlags();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        EventBus.getDefault().unregister(this);
+    }
+
     /**
-     * Called only if we are resuming Recents.
+     * Called from RecentsActivity when it is relaunched.
      */
-    void onResume(boolean isResumingFromVisible) {
+    void onReload(boolean isResumingFromVisible) {
         if (!isResumingFromVisible) {
             // Reset the focused task
             resetFocusedTask(getFocusedTask());
@@ -269,7 +282,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
         taskViews.addAll(getTaskViews());
         taskViews.addAll(mViewPool.getViews());
         for (int i = taskViews.size() - 1; i >= 0; i--) {
-            taskViews.get(i).onResume(isResumingFromVisible);
+            taskViews.get(i).onReload(isResumingFromVisible);
         }
 
         // Reset the stack state
@@ -285,53 +298,23 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
         } else {
             mStackScroller.reset();
             mLayoutAlgorithm.reset();
-            mAwaitingFirstLayout = true;
-            requestLayout();
         }
-    }
 
-    @Override
-    protected void onAttachedToWindow() {
-        EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1);
-        super.onAttachedToWindow();
-        readSystemFlags();
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        EventBus.getDefault().unregister(this);
+        // Since we always animate to the same place in (the initial state), always reset the stack
+        // to the initial state when resuming
+        mAwaitingFirstLayout = true;
+        requestLayout();
     }
 
     /**
      * Sets the stack tasks of this TaskStackView from the given TaskStack.
      */
-    public void setTasks(TaskStack stack, boolean notifyStackChanges, boolean relayoutTaskStack,
-            boolean multiWindowChange) {
+    public void setTasks(TaskStack stack, boolean allowNotifyStackChanges) {
         boolean isInitialized = mLayoutAlgorithm.isInitialized();
+        // Only notify if we are already initialized, otherwise, everything will pick up all the
+        // new and old tasks when we next layout
         mStack.setTasks(getContext(), stack.computeAllTasksList(),
-                notifyStackChanges && isInitialized);
-        if (isInitialized) {
-            // Only update the layout if we are notifying, otherwise, we will update it in the next
-            // measure/layout pass
-            updateLayoutAlgorithm(false /* boundScroll */, EMPTY_TASK_SET);
-            if (!multiWindowChange) {
-                updateToInitialState();
-            }
-
-            if (relayoutTaskStack) {
-                relayoutTaskViews(AnimationProps.IMMEDIATE);
-
-                // Rebind all the task views.  This will not trigger new resources to be loaded
-                // unless they have actually changed
-                List<TaskView> taskViews = getTaskViews();
-                int taskViewCount = taskViews.size();
-                for (int i = 0; i < taskViewCount; i++) {
-                    TaskView tv = taskViews.get(i);
-                    bindTaskView(tv, tv.getTask());
-                }
-            }
-        }
+                allowNotifyStackChanges && isInitialized);
     }
 
     /** Returns the task stack. */
@@ -771,8 +754,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
      * Updates the clip for each of the task views from back to front.
      */
     private void clipTaskViews() {
-        RecentsConfiguration config = Recents.getConfiguration();
-
         // Update the clip on each task child
         List<TaskView> taskViews = getTaskViews();
         TaskView tmpTv = null;
@@ -1439,6 +1420,22 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
         }
     }
 
+    @Override
+    public void onStackTasksUpdated(TaskStack stack) {
+        // Update the layout and immediately layout
+        updateLayoutAlgorithm(false /* boundScroll */);
+        relayoutTaskViews(AnimationProps.IMMEDIATE);
+
+        // Rebind all the task views.  This will not trigger new resources to be loaded
+        // unless they have actually changed
+        List<TaskView> taskViews = getTaskViews();
+        int taskViewCount = taskViews.size();
+        for (int i = 0; i < taskViewCount; i++) {
+            TaskView tv = taskViews.get(i);
+            bindTaskView(tv, tv.getTask());
+        }
+    }
+
     /**** ViewPoolConsumer Implementation ****/
 
     @Override
index 0c47b13..d3052bc 100644 (file)
@@ -191,15 +191,15 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
         mCb = cb;
     }
 
-    /** Resets this TaskView for reuse. */
-    void onResume(boolean isResumingFromVisible) {
+    /**
+     * Called from RecentsActivity when it is relaunched.
+     */
+    void onReload(boolean isResumingFromVisible) {
         resetNoUserInteractionState();
         readSystemFlags();
         if (!isResumingFromVisible) {
             resetViewProperties();
-            setClipViewInStack(false);
         }
-        setCallbacks(null);
     }
 
     /** Gets the task */
index 62995a6..7f05fd1 100644 (file)
@@ -284,14 +284,14 @@ public class TaskViewHeader extends FrameLayout
         icon.setLayoutParams(lp);
         lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                 ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL);
-        lp.leftMargin = mHeaderBarHeight;
+        lp.setMarginStart(mHeaderBarHeight);
         lp.rightMargin = mMoveTaskButton != null
                 ? 2 * mHeaderBarHeight
                 : mHeaderBarHeight;
         title.setLayoutParams(lp);
         if (secondaryButton != null) {
             lp = new FrameLayout.LayoutParams(mHeaderBarHeight, mHeaderBarHeight, Gravity.END);
-            lp.rightMargin = mHeaderBarHeight;
+            lp.setMarginEnd(mHeaderBarHeight);
             secondaryButton.setLayoutParams(lp);
             secondaryButton.setPadding(mHeaderButtonPadding, mHeaderButtonPadding,
                     mHeaderButtonPadding, mHeaderButtonPadding);
index e9c09ac..3eeabc7 100644 (file)
@@ -243,11 +243,6 @@ public class TaskViewThumbnail extends View {
     public void updateThumbnailScale() {
         mThumbnailScale = 1f;
         if (mBitmapShader != null) {
-
-            if (mThumbnailInfo != null) {
-                System.out.println(mTask.title + " bounds: " + mThumbnailInfo.taskWidth + "x" + mThumbnailInfo.taskHeight + ", " + mThumbnailInfo.screenOrientation);
-            }
-
             // We consider this a stack task if it is not freeform (ie. has no bounds) or has been
             // dragged into the stack from the freeform workspace
             boolean isStackTask = !mTask.isFreeformTask() || mTask.bounds == null;