Merge changes Ia8a90434,I35f484c7,I2e87e764 into nyc-dev

* changes:
  Tweaks to make overview animations to match spec.
  Closing system windows when dismissing recents to app or home.
  Caching the display rect to reduce binder calls.
This commit is contained in:
Winson Chung
2016-04-22 22:15:45 +00:00
committed by Android (Google) Code Review
13 changed files with 211 additions and 190 deletions

View File

@@ -26,5 +26,6 @@
android:layout_gravity="center" android:layout_gravity="center"
android:drawableTop="@drawable/recents_info_light" android:drawableTop="@drawable/recents_info_light"
android:drawablePadding="8dp" android:drawablePadding="8dp"
android:text="@string/recents_incompatible_app_message" /> android:text="@string/recents_incompatible_app_message"
android:textColor="@android:color/white" />
</FrameLayout> </FrameLayout>

View File

@@ -144,12 +144,6 @@
<!-- The min animation duration for animating the nav bar scrim in. --> <!-- The min animation duration for animating the nav bar scrim in. -->
<integer name="recents_nav_bar_scrim_enter_duration">400</integer> <integer name="recents_nav_bar_scrim_enter_duration">400</integer>
<!-- The animation duration for animating the removal of a task view. -->
<integer name="recents_animate_task_view_remove_duration">175</integer>
<!-- The base animation duration for animating the removal of all task views. -->
<integer name="recents_animate_task_views_remove_all_duration">300</integer>
<!-- The animation duration for scrolling the stack to a particular item. --> <!-- The animation duration for scrolling the stack to a particular item. -->
<integer name="recents_animate_task_stack_scroll_duration">200</integer> <integer name="recents_animate_task_stack_scroll_duration">200</integer>

View File

@@ -26,6 +26,7 @@ import android.content.IntentFilter;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
@@ -97,6 +98,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
public final static int INCOMPATIBLE_APP_ALPHA_DURATION = 150; public final static int INCOMPATIBLE_APP_ALPHA_DURATION = 150;
private RecentsPackageMonitor mPackageMonitor; private RecentsPackageMonitor mPackageMonitor;
private Handler mHandler = new Handler();
private long mLastTabKeyEventTime; private long mLastTabKeyEventTime;
private int mLastDeviceOrientation = Configuration.ORIENTATION_UNDEFINED; private int mLastDeviceOrientation = Configuration.ORIENTATION_UNDEFINED;
private int mLastDisplayDensity; private int mLastDisplayDensity;
@@ -138,12 +140,14 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
@Override @Override
public void run() { public void run() {
try { try {
mHandler.post(() -> {
ActivityOptions opts = mOpts; ActivityOptions opts = mOpts;
if (opts == null) { if (opts == null) {
opts = ActivityOptions.makeCustomAnimation(RecentsActivity.this, opts = ActivityOptions.makeCustomAnimation(RecentsActivity.this,
R.anim.recents_to_launcher_enter, R.anim.recents_to_launcher_exit); R.anim.recents_to_launcher_enter, R.anim.recents_to_launcher_exit);
} }
startActivityAsUser(mLaunchIntent, opts.toBundle(), UserHandle.CURRENT); startActivityAsUser(mLaunchIntent, opts.toBundle(), UserHandle.CURRENT);
});
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, getString(R.string.recents_launch_error_message, "Home"), e); Log.e(TAG, getString(R.string.recents_launch_error_message, "Home"), e);
} }
@@ -223,13 +227,8 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
new DismissRecentsToHomeAnimationStarted(animateTaskViews); new DismissRecentsToHomeAnimationStarted(animateTaskViews);
dismissEvent.addPostAnimationCallback(new LaunchHomeRunnable(mHomeIntent, dismissEvent.addPostAnimationCallback(new LaunchHomeRunnable(mHomeIntent,
overrideAnimation)); overrideAnimation));
dismissEvent.addPostAnimationCallback(new Runnable() {
@Override
public void run() {
Recents.getSystemServices().sendCloseSystemWindows( Recents.getSystemServices().sendCloseSystemWindows(
BaseStatusBar.SYSTEM_DIALOG_REASON_HOME_KEY); BaseStatusBar.SYSTEM_DIALOG_REASON_HOME_KEY);
}
});
EventBus.getDefault().send(dismissEvent); EventBus.getDefault().send(dismissEvent);
} }

View File

@@ -588,6 +588,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
*/ */
private void updateHeaderBarLayout(TaskStack stack, Rect windowRectOverride) { private void updateHeaderBarLayout(TaskStack stack, Rect windowRectOverride) {
SystemServicesProxy ssp = Recents.getSystemServices(); SystemServicesProxy ssp = Recents.getSystemServices();
Rect displayRect = ssp.getDisplayRect();
Rect systemInsets = new Rect(); Rect systemInsets = new Rect();
ssp.getStableInsets(systemInsets); ssp.getStableInsets(systemInsets);
Rect windowRect = windowRectOverride != null Rect windowRect = windowRectOverride != null
@@ -608,10 +609,10 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
// Rebind the header bar and draw it for the transition // Rebind the header bar and draw it for the transition
stackLayout.setSystemInsets(systemInsets); stackLayout.setSystemInsets(systemInsets);
if (stack != null) { if (stack != null) {
stackLayout.getTaskStackBounds(windowRect, systemInsets.top, systemInsets.right, stackLayout.getTaskStackBounds(displayRect, windowRect, systemInsets.top,
mTaskStackBounds); systemInsets.right, mTaskStackBounds);
stackLayout.reset(); stackLayout.reset();
stackLayout.initialize(windowRect, mTaskStackBounds, stackLayout.initialize(displayRect, windowRect, mTaskStackBounds,
TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack)); TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack));
mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */); mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);

View File

@@ -49,6 +49,7 @@ import android.util.SparseArray;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import com.android.internal.policy.DockedDividerUtils; import com.android.internal.policy.DockedDividerUtils;
import com.android.systemui.Interpolators;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.recents.Recents; import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsDebugFlags; import com.android.systemui.recents.RecentsDebugFlags;
@@ -253,7 +254,7 @@ public class TaskStack {
private static final int HORIZONTAL = 0; private static final int HORIZONTAL = 0;
private static final int VERTICAL = 1; private static final int VERTICAL = 1;
private static final int DOCK_AREA_ALPHA = 192; private static final int DOCK_AREA_ALPHA = 80;
public static final DockState NONE = new DockState(DOCKED_INVALID, -1, 80, 255, HORIZONTAL, public static final DockState NONE = new DockState(DOCKED_INVALID, -1, 80, 255, HORIZONTAL,
null, null, null); null, null, null);
public static final DockState LEFT = new DockState(DOCKED_LEFT, public static final DockState LEFT = new DockState(DOCKED_LEFT,
@@ -368,19 +369,28 @@ public class TaskStack {
mDockAreaOverlayAnimator.cancel(); mDockAreaOverlayAnimator.cancel();
} }
ObjectAnimator anim;
ArrayList<Animator> animators = new ArrayList<>(); ArrayList<Animator> animators = new ArrayList<>();
if (dockAreaOverlay.getAlpha() != areaAlpha) { if (dockAreaOverlay.getAlpha() != areaAlpha) {
if (animateAlpha) { if (animateAlpha) {
animators.add(ObjectAnimator.ofInt(dockAreaOverlay, anim = ObjectAnimator.ofInt(dockAreaOverlay,
Utilities.DRAWABLE_ALPHA, dockAreaOverlay.getAlpha(), areaAlpha)); Utilities.DRAWABLE_ALPHA, dockAreaOverlay.getAlpha(), areaAlpha);
anim.setDuration(duration);
anim.setInterpolator(interpolator);
animators.add(anim);
} else { } else {
dockAreaOverlay.setAlpha(areaAlpha); dockAreaOverlay.setAlpha(areaAlpha);
} }
} }
if (mHintTextAlpha != hintAlpha) { if (mHintTextAlpha != hintAlpha) {
if (animateAlpha) { if (animateAlpha) {
animators.add(ObjectAnimator.ofInt(this, HINT_ALPHA, mHintTextAlpha, anim = ObjectAnimator.ofInt(this, HINT_ALPHA, mHintTextAlpha,
hintAlpha)); hintAlpha);
anim.setDuration(150);
anim.setInterpolator(hintAlpha > mHintTextAlpha
? Interpolators.ALPHA_IN
: Interpolators.ALPHA_OUT);
animators.add(anim);
} else { } else {
mHintTextAlpha = hintAlpha; mHintTextAlpha = hintAlpha;
dockAreaOverlay.invalidateSelf(); dockAreaOverlay.invalidateSelf();
@@ -390,8 +400,11 @@ public class TaskStack {
if (animateBounds) { if (animateBounds) {
PropertyValuesHolder prop = PropertyValuesHolder.ofObject( PropertyValuesHolder prop = PropertyValuesHolder.ofObject(
Utilities.DRAWABLE_RECT, Utilities.RECT_EVALUATOR, Utilities.DRAWABLE_RECT, Utilities.RECT_EVALUATOR,
dockAreaOverlay.getBounds(), bounds); new Rect(dockAreaOverlay.getBounds()), bounds);
animators.add(ObjectAnimator.ofPropertyValuesHolder(dockAreaOverlay, prop)); anim = ObjectAnimator.ofPropertyValuesHolder(dockAreaOverlay, prop);
anim.setDuration(duration);
anim.setInterpolator(interpolator);
animators.add(anim);
} else { } else {
dockAreaOverlay.setBounds(bounds); dockAreaOverlay.setBounds(bounds);
} }
@@ -399,8 +412,6 @@ public class TaskStack {
if (!animators.isEmpty()) { if (!animators.isEmpty()) {
mDockAreaOverlayAnimator = new AnimatorSet(); mDockAreaOverlayAnimator = new AnimatorSet();
mDockAreaOverlayAnimator.playTogether(animators); mDockAreaOverlayAnimator.playTogether(animators);
mDockAreaOverlayAnimator.setDuration(duration);
mDockAreaOverlayAnimator.setInterpolator(interpolator);
mDockAreaOverlayAnimator.start(); mDockAreaOverlayAnimator.start();
} }
} }
@@ -481,8 +492,9 @@ public class TaskStack {
* Returns the task stack bounds with the given {@param width} and * Returns the task stack bounds with the given {@param width} and
* {@param height}. * {@param height}.
*/ */
public Rect getDockedTaskStackBounds(int width, int height, int dividerSize, Rect insets, public Rect getDockedTaskStackBounds(Rect displayRect, int width, int height,
TaskStackLayoutAlgorithm layoutAlgorithm, Resources res, Rect windowRectOut) { int dividerSize, Rect insets, TaskStackLayoutAlgorithm layoutAlgorithm,
Resources res, Rect windowRectOut) {
// Calculate the inverse docked task bounds // Calculate the inverse docked task bounds
boolean isHorizontalDivision = boolean isHorizontalDivision =
res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
@@ -499,7 +511,8 @@ public class TaskStack {
int top = dockArea.bottom < 1f int top = dockArea.bottom < 1f
? 0 ? 0
: insets.top; : insets.top;
layoutAlgorithm.getTaskStackBounds(windowRectOut, top, insets.right, taskStackBounds); layoutAlgorithm.getTaskStackBounds(displayRect, windowRectOut, top, insets.right,
taskStackBounds);
return taskStackBounds; return taskStackBounds;
} }
} }

View File

@@ -18,6 +18,7 @@ package com.android.systemui.recents.views;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorSet; import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.IntDef; import android.annotation.IntDef;
import android.util.SparseArray; import android.util.SparseArray;
import android.util.SparseLongArray; import android.util.SparseLongArray;
@@ -53,6 +54,7 @@ public class AnimationProps {
public static final int FOCUS_STATE = 8; public static final int FOCUS_STATE = 8;
private SparseLongArray mPropStartDelay; private SparseLongArray mPropStartDelay;
private SparseLongArray mPropInitialPlayTime;
private SparseLongArray mPropDuration; private SparseLongArray mPropDuration;
private SparseArray<Interpolator> mPropInterpolators; private SparseArray<Interpolator> mPropInterpolators;
private Animator.AnimatorListener mListener; private Animator.AnimatorListener mListener;
@@ -116,10 +118,14 @@ public class AnimationProps {
* Applies the specific start delay, duration and interpolator to the given {@param animator} * Applies the specific start delay, duration and interpolator to the given {@param animator}
* for the specified {@param propertyType}. * for the specified {@param propertyType}.
*/ */
public <T extends Animator> T apply(@PropType int propertyType, T animator) { public <T extends ValueAnimator> T apply(@PropType int propertyType, T animator) {
animator.setStartDelay(getStartDelay(propertyType)); animator.setStartDelay(getStartDelay(propertyType));
animator.setDuration(getDuration(propertyType)); animator.setDuration(getDuration(propertyType));
animator.setInterpolator(getInterpolator(propertyType)); animator.setInterpolator(getInterpolator(propertyType));
long initialPlayTime = getInitialPlayTime(propertyType);
if (initialPlayTime != 0) {
animator.setCurrentPlayTime(initialPlayTime);
}
return animator; return animator;
} }
@@ -134,6 +140,17 @@ public class AnimationProps {
return this; return this;
} }
/**
* Sets a initial play time for a specific property.
*/
public AnimationProps setInitialPlayTime(@PropType int propertyType, int initialPlayTime) {
if (mPropInitialPlayTime == null) {
mPropInitialPlayTime = new SparseLongArray();
}
mPropInitialPlayTime.append(propertyType, initialPlayTime);
return this;
}
/** /**
* Returns the start delay for a specific property. * Returns the start delay for a specific property.
*/ */
@@ -199,6 +216,20 @@ public class AnimationProps {
return Interpolators.LINEAR; return Interpolators.LINEAR;
} }
/**
* Returns the initial play time for a specific property, falling back to the general initial
* play time if there is no specific property interpolator.
*/
public long getInitialPlayTime(@PropType int propertyType) {
if (mPropInitialPlayTime != null) {
if (mPropInitialPlayTime.indexOfKey(propertyType) != -1) {
return mPropInitialPlayTime.get(propertyType);
}
return mPropInitialPlayTime.get(ALL, 0);
}
return 0;
}
/** /**
* Sets an animator listener for this animation. * Sets an animator listener for this animation.
*/ */

View File

@@ -51,6 +51,7 @@ import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.Task; import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.statusbar.BaseStatusBar;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -167,6 +168,8 @@ public class RecentsTransitionHelper {
animStartedListener); animStartedListener);
} }
} }
Recents.getSystemServices().sendCloseSystemWindows(
BaseStatusBar.SYSTEM_DIALOG_REASON_HOME_KEY);
} }
public IRemoteCallback wrapStartedListener(final OnAnimationStartedListener listener) { public IRemoteCallback wrapStartedListener(final OnAnimationStartedListener listener) {
@@ -284,7 +287,6 @@ public class RecentsTransitionHelper {
} }
// Calculate the offscreen task rect (for tasks that are not backed by views) // Calculate the offscreen task rect (for tasks that are not backed by views)
float stackScroll = stackView.getScroller().getStackScroll();
TaskView taskView = stackView.getChildViewForTask(task); TaskView taskView = stackView.getChildViewForTask(task);
TaskStackLayoutAlgorithm stackLayout = stackView.getStackAlgorithm(); TaskStackLayoutAlgorithm stackLayout = stackView.getStackAlgorithm();
Rect offscreenTaskRect = new Rect(); Rect offscreenTaskRect = new Rect();
@@ -404,7 +406,7 @@ public class RecentsTransitionHelper {
transform.rect.round(taskRect); transform.rect.round(taskRect);
if (stackView.getStack().getStackFrontMostTask(false /* includeFreeformTasks */) != if (stackView.getStack().getStackFrontMostTask(false /* includeFreeformTasks */) !=
taskView.getTask()) { taskView.getTask()) {
taskRect.bottom = 2 * Recents.getSystemServices().getDisplayRect().height(); taskRect.bottom = taskRect.top + stackView.getMeasuredHeight();
} }
return new AppTransitionAnimationSpec(taskView.getTask().key.id, b, taskRect); return new AppTransitionAnimationSpec(taskView.getTask().key.id, b, taskRect);
} }

View File

@@ -88,7 +88,6 @@ public class RecentsView extends FrameLayout {
private static final String TAG = "RecentsView"; private static final String TAG = "RecentsView";
private static final int DOCK_AREA_OVERLAY_TRANSITION_DURATION = 135;
private static final int DEFAULT_UPDATE_SCRIM_DURATION = 200; private static final int DEFAULT_UPDATE_SCRIM_DURATION = 200;
private static final float DEFAULT_SCRIM_ALPHA = 0.33f; private static final float DEFAULT_SCRIM_ALPHA = 0.33f;
@@ -733,8 +732,8 @@ public class RecentsView extends FrameLayout {
TaskStack.DockState.ViewState viewState = dockState.viewState; TaskStack.DockState.ViewState viewState = dockState.viewState;
if (newDockStates == null || !newDockStatesSet.contains(dockState)) { if (newDockStates == null || !newDockStatesSet.contains(dockState)) {
// This is no longer visible, so hide it // This is no longer visible, so hide it
viewState.startAnimation(null, 0, 0, DOCK_AREA_OVERLAY_TRANSITION_DURATION, viewState.startAnimation(null, 0, 0, TaskStackView.SLOW_SYNC_STACK_DURATION,
Interpolators.ALPHA_OUT, animateAlpha, animateBounds); Interpolators.FAST_OUT_SLOW_IN, animateAlpha, animateBounds);
} else { } else {
// This state is now visible, update the bounds and show it // This state is now visible, update the bounds and show it
int areaAlpha = overrideAreaAlpha != -1 int areaAlpha = overrideAreaAlpha != -1
@@ -752,7 +751,7 @@ public class RecentsView extends FrameLayout {
viewState.dockAreaOverlay.setBounds(bounds); viewState.dockAreaOverlay.setBounds(bounds);
} }
viewState.startAnimation(bounds, areaAlpha, hintAlpha, viewState.startAnimation(bounds, areaAlpha, hintAlpha,
DOCK_AREA_OVERLAY_TRANSITION_DURATION, Interpolators.ALPHA_IN, TaskStackView.SLOW_SYNC_STACK_DURATION, Interpolators.FAST_OUT_SLOW_IN,
animateAlpha, animateBounds); animateAlpha, animateBounds);
} }
} }

View File

@@ -18,6 +18,7 @@ package com.android.systemui.recents.views;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
@@ -32,7 +33,6 @@ import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsActivityLaunchState; import com.android.systemui.recents.RecentsActivityLaunchState;
import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.ReferenceCountedTrigger; import com.android.systemui.recents.misc.ReferenceCountedTrigger;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.Task; import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.model.TaskStack;
@@ -74,32 +74,35 @@ public class TaskStackAnimationHelper {
void onStartFrontTaskEnterAnimation(boolean screenPinningEnabled); void onStartFrontTaskEnterAnimation(boolean screenPinningEnabled);
} }
private static final int DOUBLE_FRAME_OFFSET_MS = 33;
private static final int FRAME_OFFSET_MS = 16; private static final int FRAME_OFFSET_MS = 16;
public static final int ENTER_FROM_HOME_ALPHA_DURATION = 100; private static final int ENTER_EXIT_NUM_ANIMATING_TASKS = 5;
public static final int ENTER_FROM_HOME_TRANSLATION_DURATION = 333;
private static final PathInterpolator ENTER_FROM_HOME_TRANSLATION_INTERPOLATOR = private static final int ENTER_FROM_HOME_ALPHA_DURATION = 100;
new PathInterpolator(0, 0, 0, 1f); public static final int ENTER_FROM_HOME_TRANSLATION_DURATION = 300;
private static final PathInterpolator ENTER_FROM_HOME_ALPHA_INTERPOLATOR = private static final Interpolator ENTER_FROM_HOME_TRANSLATION_INTERPOLATOR =
new PathInterpolator(0, 0, 0.2f, 1f); Interpolators.LINEAR_OUT_SLOW_IN;
private static final Interpolator ENTER_FROM_HOME_ALPHA_INTERPOLATOR = Interpolators.LINEAR;
public static final int EXIT_TO_HOME_ALPHA_DURATION = 100; public static final int EXIT_TO_HOME_TRANSLATION_DURATION = 200;
public static final int EXIT_TO_HOME_TRANSLATION_DURATION = 150; private static final Interpolator EXIT_TO_HOME_TRANSLATION_INTERPOLATOR =
private static final PathInterpolator EXIT_TO_HOME_TRANSLATION_INTERPOLATOR = new PathInterpolator(0.4f, 0, 0.6f, 1f);
new PathInterpolator(0.8f, 0, 0.6f, 1f);
private static final PathInterpolator EXIT_TO_HOME_ALPHA_INTERPOLATOR = private static final int DISMISS_TASK_DURATION = 175;
private static final int DISMISS_ALL_TASKS_DURATION = 200;
private static final Interpolator DISMISS_ALL_TRANSLATION_INTERPOLATOR =
new PathInterpolator(0.4f, 0, 1f, 1f); new PathInterpolator(0.4f, 0, 1f, 1f);
private static final PathInterpolator FOCUS_NEXT_TASK_INTERPOLATOR = private static final Interpolator FOCUS_NEXT_TASK_INTERPOLATOR =
new PathInterpolator(0.4f, 0, 0, 1f); new PathInterpolator(0.4f, 0, 0, 1f);
private static final PathInterpolator FOCUS_IN_FRONT_NEXT_TASK_INTERPOLATOR = private static final Interpolator FOCUS_IN_FRONT_NEXT_TASK_INTERPOLATOR =
new PathInterpolator(0, 0, 0, 1f); new PathInterpolator(0, 0, 0, 1f);
private static final PathInterpolator FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR = private static final Interpolator FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR =
new PathInterpolator(0.4f, 0, 0.2f, 1f); Interpolators.LINEAR_OUT_SLOW_IN;
private static final PathInterpolator ENTER_WHILE_DOCKING_INTERPOLATOR = private static final Interpolator ENTER_WHILE_DOCKING_INTERPOLATOR =
new PathInterpolator(0, 0, 0.2f, 1f); Interpolators.LINEAR_OUT_SLOW_IN;
private TaskStackView mStackView; private TaskStackView mStackView;
@@ -251,16 +254,20 @@ public class TaskStackAnimationHelper {
} }
} else if (launchState.launchedFromHome) { } else if (launchState.launchedFromHome) {
// Animate the tasks up // Animate the tasks up, but offset the animations to be relative to the front-most
// task animation
AnimationProps taskAnimation = new AnimationProps() AnimationProps taskAnimation = new AnimationProps()
.setStartDelay(AnimationProps.ALPHA, taskIndexFromFront * FRAME_OFFSET_MS) .setInitialPlayTime(AnimationProps.BOUNDS,
Math.min(ENTER_EXIT_NUM_ANIMATING_TASKS, taskIndexFromFront) *
DOUBLE_FRAME_OFFSET_MS)
.setStartDelay(AnimationProps.ALPHA,
Math.min(ENTER_EXIT_NUM_ANIMATING_TASKS, taskIndexFromFront) *
FRAME_OFFSET_MS)
.setDuration(AnimationProps.BOUNDS, ENTER_FROM_HOME_TRANSLATION_DURATION)
.setDuration(AnimationProps.ALPHA, ENTER_FROM_HOME_ALPHA_DURATION) .setDuration(AnimationProps.ALPHA, ENTER_FROM_HOME_ALPHA_DURATION)
.setDuration(AnimationProps.BOUNDS, ENTER_FROM_HOME_TRANSLATION_DURATION -
(taskIndexFromFront * FRAME_OFFSET_MS))
.setInterpolator(AnimationProps.BOUNDS, .setInterpolator(AnimationProps.BOUNDS,
ENTER_FROM_HOME_TRANSLATION_INTERPOLATOR) ENTER_FROM_HOME_TRANSLATION_INTERPOLATOR)
.setInterpolator(AnimationProps.ALPHA, .setInterpolator(AnimationProps.ALPHA, ENTER_FROM_HOME_ALPHA_INTERPOLATOR)
ENTER_FROM_HOME_ALPHA_INTERPOLATOR)
.setListener(postAnimationTrigger.decrementOnAnimationEnd()); .setListener(postAnimationTrigger.decrementOnAnimationEnd());
postAnimationTrigger.increment(); postAnimationTrigger.increment();
mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation); mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
@@ -270,8 +277,8 @@ public class TaskStackAnimationHelper {
} else if (launchState.launchedViaDockGesture) { } else if (launchState.launchedViaDockGesture) {
// Animate the tasks up // Animate the tasks up
AnimationProps taskAnimation = new AnimationProps() AnimationProps taskAnimation = new AnimationProps()
.setDuration(AnimationProps.BOUNDS, (int) (dockGestureAnimDuration + .setDuration(AnimationProps.BOUNDS, dockGestureAnimDuration +
(taskIndexFromBack * 2f * FRAME_OFFSET_MS))) (taskIndexFromBack * DOUBLE_FRAME_OFFSET_MS))
.setInterpolator(AnimationProps.BOUNDS, .setInterpolator(AnimationProps.BOUNDS,
ENTER_WHILE_DOCKING_INTERPOLATOR) ENTER_WHILE_DOCKING_INTERPOLATOR)
.setListener(postAnimationTrigger.decrementOnAnimationEnd()); .setListener(postAnimationTrigger.decrementOnAnimationEnd());
@@ -302,20 +309,17 @@ public class TaskStackAnimationHelper {
for (int i = 0; i < taskViewCount; i++) { for (int i = 0; i < taskViewCount; i++) {
int taskIndexFromFront = taskViewCount - i - 1; int taskIndexFromFront = taskViewCount - i - 1;
TaskView tv = taskViews.get(i); TaskView tv = taskViews.get(i);
Task task = tv.getTask();
// Animate the tasks down // Animate the tasks down
AnimationProps taskAnimation; AnimationProps taskAnimation;
if (animated) { if (animated) {
int delay = Math.min(ENTER_EXIT_NUM_ANIMATING_TASKS , taskIndexFromFront) *
DOUBLE_FRAME_OFFSET_MS;
taskAnimation = new AnimationProps() taskAnimation = new AnimationProps()
.setStartDelay(AnimationProps.ALPHA, i * FRAME_OFFSET_MS) .setStartDelay(AnimationProps.BOUNDS, delay)
.setDuration(AnimationProps.ALPHA, EXIT_TO_HOME_ALPHA_DURATION) .setDuration(AnimationProps.BOUNDS, EXIT_TO_HOME_TRANSLATION_DURATION)
.setDuration(AnimationProps.BOUNDS, EXIT_TO_HOME_TRANSLATION_DURATION +
(taskIndexFromFront * FRAME_OFFSET_MS))
.setInterpolator(AnimationProps.BOUNDS, .setInterpolator(AnimationProps.BOUNDS,
EXIT_TO_HOME_TRANSLATION_INTERPOLATOR) EXIT_TO_HOME_TRANSLATION_INTERPOLATOR)
.setInterpolator(AnimationProps.ALPHA,
EXIT_TO_HOME_ALPHA_INTERPOLATOR)
.setListener(postAnimationTrigger.decrementOnAnimationEnd()); .setListener(postAnimationTrigger.decrementOnAnimationEnd());
postAnimationTrigger.increment(); postAnimationTrigger.increment();
} else { } else {
@@ -323,7 +327,6 @@ public class TaskStackAnimationHelper {
} }
mTmpTransform.fillIn(tv); mTmpTransform.fillIn(tv);
mTmpTransform.alpha = 0f;
mTmpTransform.rect.offset(0, offscreenYOffset); mTmpTransform.rect.offset(0, offscreenYOffset);
mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation); mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
} }
@@ -384,8 +387,6 @@ public class TaskStackAnimationHelper {
Resources res = mStackView.getResources(); Resources res = mStackView.getResources();
TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm(); TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
int taskViewRemoveAnimDuration = res.getInteger(
R.integer.recents_animate_task_view_remove_duration);
int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.mTaskRect.left; int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.mTaskRect.left;
// Disabling clipping with the stack while the view is animating away, this will get // Disabling clipping with the stack while the view is animating away, this will get
@@ -393,7 +394,7 @@ public class TaskStackAnimationHelper {
deleteTaskView.setClipViewInStack(false); deleteTaskView.setClipViewInStack(false);
// Compose the new animation and transform and star the animation // Compose the new animation and transform and star the animation
AnimationProps taskAnimation = new AnimationProps(taskViewRemoveAnimDuration, AnimationProps taskAnimation = new AnimationProps(DISMISS_TASK_DURATION,
Interpolators.ALPHA_OUT, new AnimatorListenerAdapter() { Interpolators.ALPHA_OUT, new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
@@ -413,29 +414,23 @@ public class TaskStackAnimationHelper {
*/ */
public void startDeleteAllTasksAnimation(final List<TaskView> taskViews, public void startDeleteAllTasksAnimation(final List<TaskView> taskViews,
final ReferenceCountedTrigger postAnimationTrigger) { final ReferenceCountedTrigger postAnimationTrigger) {
Resources res = mStackView.getResources();
TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm(); TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
int taskViewRemoveAnimDuration = res.getInteger(
R.integer.recents_animate_task_views_remove_all_duration);
int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.mTaskRect.left; int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.mTaskRect.left;
int taskViewCount = taskViews.size(); int taskViewCount = taskViews.size();
int startDelayMax = 125;
for (int i = taskViewCount - 1; i >= 0; i--) { for (int i = taskViewCount - 1; i >= 0; i--) {
TaskView tv = taskViews.get(i); TaskView tv = taskViews.get(i);
int indexFromFront = taskViewCount - i - 1; int taskIndexFromFront = taskViewCount - i - 1;
float x = Interpolators.ACCELERATE.getInterpolation((float) indexFromFront / int startDelay = taskIndexFromFront * DOUBLE_FRAME_OFFSET_MS;
taskViewCount);
int startDelay = (int) Utilities.mapRange(x, 0, startDelayMax);
// Disabling clipping with the stack while the view is animating away // Disabling clipping with the stack while the view is animating away
tv.setClipViewInStack(false); tv.setClipViewInStack(false);
// Compose the new animation and transform and star the animation // Compose the new animation and transform and star the animation
AnimationProps taskAnimation = new AnimationProps(startDelay, AnimationProps taskAnimation = new AnimationProps(startDelay,
taskViewRemoveAnimDuration, Interpolators.FAST_OUT_LINEAR_IN, DISMISS_ALL_TASKS_DURATION, DISMISS_ALL_TRANSLATION_INTERPOLATOR,
new AnimatorListenerAdapter() { new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
@@ -605,7 +600,7 @@ public class TaskStackAnimationHelper {
// Now, animate in the front-most task // Now, animate in the front-most task
if (frontMostTaskView != null) { if (frontMostTaskView != null) {
mStackView.updateTaskViewToTransform(frontMostTaskView, frontMostTransform, mStackView.updateTaskViewToTransform(frontMostTaskView, frontMostTransform,
new AnimationProps(75, 200, FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR)); new AnimationProps(75, 250, FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR));
} }
} }
}); });

View File

@@ -432,10 +432,9 @@ public class TaskStackLayoutAlgorithm {
* Computes the stack and task rects. The given task stack bounds already has the top/right * Computes the stack and task rects. The given task stack bounds already has the top/right
* insets and left/right padding already applied. * insets and left/right padding already applied.
*/ */
public void initialize(Rect windowRect, Rect taskStackBounds, StackState state) { public void initialize(Rect displayRect, Rect windowRect, Rect taskStackBounds,
SystemServicesProxy ssp = Recents.getSystemServices(); StackState state) {
Rect lastStackRect = new Rect(mStackRect); Rect lastStackRect = new Rect(mStackRect);
Rect displayRect = ssp.getDisplayRect();
int topMargin = getScaleForExtent(windowRect, displayRect, mBaseTopMargin, mMinMargin, HEIGHT); int topMargin = getScaleForExtent(windowRect, displayRect, mBaseTopMargin, mMinMargin, HEIGHT);
int bottomMargin = getScaleForExtent(windowRect, displayRect, mBaseBottomMargin, mMinMargin, int bottomMargin = getScaleForExtent(windowRect, displayRect, mBaseBottomMargin, mMinMargin,
@@ -999,14 +998,12 @@ public class TaskStackLayoutAlgorithm {
* top and right system insets (but not the bottom inset) and left/right paddings, but _not_ * top and right system insets (but not the bottom inset) and left/right paddings, but _not_
* the top/bottom padding or insets. * the top/bottom padding or insets.
*/ */
public void getTaskStackBounds(Rect windowRect, int topInset, int rightInset, public void getTaskStackBounds(Rect displayRect, Rect windowRect, int topInset, int rightInset,
Rect taskStackBounds) { Rect taskStackBounds) {
taskStackBounds.set(windowRect.left, windowRect.top + topInset, taskStackBounds.set(windowRect.left, windowRect.top + topInset,
windowRect.right - rightInset, windowRect.bottom); windowRect.right - rightInset, windowRect.bottom);
// Ensure that the new width is at most the smaller display edge size // Ensure that the new width is at most the smaller display edge size
SystemServicesProxy ssp = Recents.getSystemServices();
Rect displayRect = ssp.getDisplayRect();
int sideMargin = getScaleForExtent(windowRect, displayRect, mBaseSideMargin, mMinMargin, int sideMargin = getScaleForExtent(windowRect, displayRect, mBaseSideMargin, mMinMargin,
WIDTH); WIDTH);
int targetStackWidth = taskStackBounds.width() - 2 * sideMargin; int targetStackWidth = taskStackBounds.width() - 2 * sideMargin;

View File

@@ -25,6 +25,7 @@ import android.animation.ValueAnimator;
import android.annotation.IntDef; import android.annotation.IntDef;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Rect; import android.graphics.Rect;
@@ -109,6 +110,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
private static final float HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD = 0.3f; private static final float HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD = 0.3f;
public static final int DEFAULT_SYNC_STACK_DURATION = 200; public static final int DEFAULT_SYNC_STACK_DURATION = 200;
public static final int SLOW_SYNC_STACK_DURATION = 250;
private static final int DRAG_SCALE_DURATION = 175; private static final int DRAG_SCALE_DURATION = 175;
static final float DRAG_SCALE_FACTOR = 1.05f; static final float DRAG_SCALE_FACTOR = 1.05f;
@@ -126,48 +128,48 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
/** Update only the layout to the initial state. */ /** Update only the layout to the initial state. */
private static final int INITIAL_STATE_UPDATE_LAYOUT_ONLY = 2; private static final int INITIAL_STATE_UPDATE_LAYOUT_ONLY = 2;
LayoutInflater mInflater; private LayoutInflater mInflater;
TaskStack mStack = new TaskStack(); private TaskStack mStack = new TaskStack();
@ViewDebug.ExportedProperty(deepExport=true, prefix="layout_") @ViewDebug.ExportedProperty(deepExport=true, prefix="layout_")
TaskStackLayoutAlgorithm mLayoutAlgorithm; TaskStackLayoutAlgorithm mLayoutAlgorithm;
// The stable layout algorithm is only used to calculate the task rect with the stable bounds // The stable layout algorithm is only used to calculate the task rect with the stable bounds
TaskStackLayoutAlgorithm mStableLayoutAlgorithm; private TaskStackLayoutAlgorithm mStableLayoutAlgorithm;
@ViewDebug.ExportedProperty(deepExport=true, prefix="scroller_") @ViewDebug.ExportedProperty(deepExport=true, prefix="scroller_")
TaskStackViewScroller mStackScroller; private TaskStackViewScroller mStackScroller;
@ViewDebug.ExportedProperty(deepExport=true, prefix="touch_") @ViewDebug.ExportedProperty(deepExport=true, prefix="touch_")
TaskStackViewTouchHandler mTouchHandler; private TaskStackViewTouchHandler mTouchHandler;
TaskStackAnimationHelper mAnimationHelper; private TaskStackAnimationHelper mAnimationHelper;
GradientDrawable mFreeformWorkspaceBackground; private GradientDrawable mFreeformWorkspaceBackground;
ObjectAnimator mFreeformWorkspaceBackgroundAnimator; private ObjectAnimator mFreeformWorkspaceBackgroundAnimator;
ViewPool<TaskView, Task> mViewPool; private ViewPool<TaskView, Task> mViewPool;
ArrayList<TaskView> mTaskViews = new ArrayList<>(); private ArrayList<TaskView> mTaskViews = new ArrayList<>();
ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<>(); private ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<>();
ArraySet<Task.TaskKey> mIgnoreTasks = new ArraySet<>(); private ArraySet<Task.TaskKey> mIgnoreTasks = new ArraySet<>();
AnimationProps mDeferredTaskViewLayoutAnimation = null; private AnimationProps mDeferredTaskViewLayoutAnimation = null;
@ViewDebug.ExportedProperty(deepExport=true, prefix="doze_") @ViewDebug.ExportedProperty(deepExport=true, prefix="doze_")
DozeTrigger mUIDozeTrigger; private DozeTrigger mUIDozeTrigger;
@ViewDebug.ExportedProperty(deepExport=true, prefix="focused_task_") @ViewDebug.ExportedProperty(deepExport=true, prefix="focused_task_")
Task mFocusedTask; private Task mFocusedTask;
int mTaskCornerRadiusPx; private int mTaskCornerRadiusPx;
private int mDividerSize; private int mDividerSize;
private int mStartTimerIndicatorDuration; private int mStartTimerIndicatorDuration;
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
boolean mTaskViewsClipDirty = true; private boolean mTaskViewsClipDirty = true;
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
boolean mAwaitingFirstLayout = true; private boolean mAwaitingFirstLayout = true;
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
@InitialStateAction @InitialStateAction
int mInitialState = INITIAL_STATE_UPDATE_ALL; private int mInitialState = INITIAL_STATE_UPDATE_ALL;
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
boolean mInMeasureLayout = false; private boolean mInMeasureLayout = false;
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
boolean mEnterAnimationComplete = false; private boolean mEnterAnimationComplete = false;
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
boolean mTouchExplorationEnabled; private boolean mTouchExplorationEnabled;
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
boolean mScreenPinningEnabled; boolean mScreenPinningEnabled;
@@ -183,12 +185,17 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
// The current window bounds are dynamic and may change as the user drags and drops // The current window bounds are dynamic and may change as the user drags and drops
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
private Rect mWindowRect = new Rect(); private Rect mWindowRect = new Rect();
// The current display bounds
@ViewDebug.ExportedProperty(category="recents")
private Rect mDisplayRect = new Rect();
// The current display orientation
@ViewDebug.ExportedProperty(category="recents")
private int mDisplayOrientation = Configuration.ORIENTATION_UNDEFINED;
private Rect mTmpRect = new Rect(); private Rect mTmpRect = new Rect();
private ArrayMap<Task.TaskKey, TaskView> mTmpTaskViewMap = new ArrayMap<>(); private ArrayMap<Task.TaskKey, TaskView> mTmpTaskViewMap = new ArrayMap<>();
private List<TaskView> mTmpTaskViews = new ArrayList<>(); private List<TaskView> mTmpTaskViews = new ArrayList<>();
private TaskViewTransform mTmpTransform = new TaskViewTransform(); private TaskViewTransform mTmpTransform = new TaskViewTransform();
private ArrayList<TaskViewTransform> mTmpTaskTransforms = new ArrayList<>();
private int[] mTmpIntPair = new int[2]; private int[] mTmpIntPair = new int[2];
private boolean mResetToInitialStateWhenResized; private boolean mResetToInitialStateWhenResized;
private int mLastWidth; private int mLastWidth;
@@ -248,6 +255,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
mTaskCornerRadiusPx = res.getDimensionPixelSize( mTaskCornerRadiusPx = res.getDimensionPixelSize(
R.dimen.recents_task_view_rounded_corners_radius); R.dimen.recents_task_view_rounded_corners_radius);
mDividerSize = ssp.getDockedDividerSize(context); mDividerSize = ssp.getDockedDividerSize(context);
mDisplayOrientation = Utilities.getAppConfiguration(mContext).orientation;
mDisplayRect = ssp.getDisplayRect();
int taskBarDismissDozeDelaySeconds = getResources().getInteger( int taskBarDismissDozeDelaySeconds = getResources().getInteger(
R.integer.recents_task_bar_dismiss_delay_seconds); R.integer.recents_task_bar_dismiss_delay_seconds);
@@ -1150,7 +1159,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
// Update the stable stack bounds, but only update the current stack bounds if the stable // Update the stable stack bounds, but only update the current stack bounds if the stable
// bounds have changed. This is because we may get spurious measures while dragging where // bounds have changed. This is because we may get spurious measures while dragging where
// our current stack bounds reflect the target drop region. // our current stack bounds reflect the target drop region.
mLayoutAlgorithm.getTaskStackBounds(new Rect(0, 0, width, height), mLayoutAlgorithm.getTaskStackBounds(mDisplayRect, new Rect(0, 0, width, height),
mLayoutAlgorithm.mSystemInsets.top, mLayoutAlgorithm.mSystemInsets.right, mTmpRect); mLayoutAlgorithm.mSystemInsets.top, mLayoutAlgorithm.mSystemInsets.right, mTmpRect);
if (!mTmpRect.equals(mStableStackBounds)) { if (!mTmpRect.equals(mStableStackBounds)) {
mStableStackBounds.set(mTmpRect); mStableStackBounds.set(mTmpRect);
@@ -1160,9 +1169,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
} }
// Compute the rects in the stack algorithm // Compute the rects in the stack algorithm
mStableLayoutAlgorithm.initialize(mStableWindowRect, mStableStackBounds, mStableLayoutAlgorithm.initialize(mDisplayRect, mStableWindowRect, mStableStackBounds,
TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack)); TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
mLayoutAlgorithm.initialize(mWindowRect, mStackBounds, mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds,
TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack)); TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
updateLayoutAlgorithm(false /* boundScroll */); updateLayoutAlgorithm(false /* boundScroll */);
@@ -1538,7 +1547,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
private void bindTaskView(TaskView tv, Task task) { private void bindTaskView(TaskView tv, Task task) {
// Rebind the task and request that this task's data be filled into the TaskView // Rebind the task and request that this task's data be filled into the TaskView
tv.onTaskBound(task); tv.onTaskBound(task, mTouchExplorationEnabled, mDisplayOrientation, mDisplayRect);
// Load the task data // Load the task data
Recents.getTaskLoader().loadTaskData(task); Recents.getTaskLoader().loadTaskData(task);
@@ -1789,7 +1798,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
} }
public final void onBusEvent(DragDropTargetChangedEvent event) { public final void onBusEvent(DragDropTargetChangedEvent event) {
AnimationProps animation = new AnimationProps(250, Interpolators.FAST_OUT_SLOW_IN); AnimationProps animation = new AnimationProps(SLOW_SYNC_STACK_DURATION,
Interpolators.FAST_OUT_SLOW_IN);
boolean ignoreTaskOverrides = false; boolean ignoreTaskOverrides = false;
if (event.dropTarget instanceof TaskStack.DockState) { if (event.dropTarget instanceof TaskStack.DockState) {
// Calculate the new task stack bounds that matches the window size that Recents will // Calculate the new task stack bounds that matches the window size that Recents will
@@ -1802,11 +1812,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
int height = getMeasuredHeight(); int height = getMeasuredHeight();
height -= systemInsets.bottom; height -= systemInsets.bottom;
systemInsets.bottom = 0; systemInsets.bottom = 0;
mStackBounds.set(dockState.getDockedTaskStackBounds(getMeasuredWidth(), mStackBounds.set(dockState.getDockedTaskStackBounds(mDisplayRect, getMeasuredWidth(),
height, mDividerSize, systemInsets, height, mDividerSize, systemInsets,
mLayoutAlgorithm, getResources(), mWindowRect)); mLayoutAlgorithm, getResources(), mWindowRect));
mLayoutAlgorithm.setSystemInsets(systemInsets); mLayoutAlgorithm.setSystemInsets(systemInsets);
mLayoutAlgorithm.initialize(mWindowRect, mStackBounds, mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds,
TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack)); TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
updateLayoutAlgorithm(true /* boundScroll */); updateLayoutAlgorithm(true /* boundScroll */);
ignoreTaskOverrides = true; ignoreTaskOverrides = true;
@@ -1817,7 +1827,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
mStackBounds.set(mStableStackBounds); mStackBounds.set(mStableStackBounds);
removeIgnoreTask(event.task); removeIgnoreTask(event.task);
mLayoutAlgorithm.setSystemInsets(mStableLayoutAlgorithm.mSystemInsets); mLayoutAlgorithm.setSystemInsets(mStableLayoutAlgorithm.mSystemInsets);
mLayoutAlgorithm.initialize(mWindowRect, mStackBounds, mLayoutAlgorithm.initialize(mDisplayRect, mWindowRect, mStackBounds,
TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack)); TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
updateLayoutAlgorithm(true /* boundScroll */); updateLayoutAlgorithm(true /* boundScroll */);
addIgnoreTask(event.task); addIgnoreTask(event.task);
@@ -1960,6 +1970,10 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
} }
public final void onBusEvent(ConfigurationChangedEvent event) { public final void onBusEvent(ConfigurationChangedEvent event) {
if (event.fromDeviceOrientationChange) {
mDisplayOrientation = Utilities.getAppConfiguration(mContext).orientation;
mDisplayRect = Recents.getSystemServices().getDisplayRect();
}
reloadOnConfigurationChange(); reloadOnConfigurationChange();
// Notify the task views of the configuration change so they can reload their resources // Notify the task views of the configuration change so they can reload their resources
@@ -2072,6 +2086,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
writer.print(" stackBounds="); writer.print(Utilities.dumpRect(mStackBounds)); writer.print(" stackBounds="); writer.print(Utilities.dumpRect(mStackBounds));
writer.print(" stableWindow="); writer.print(Utilities.dumpRect(mStableWindowRect)); writer.print(" stableWindow="); writer.print(Utilities.dumpRect(mStableWindowRect));
writer.print(" window="); writer.print(Utilities.dumpRect(mWindowRect)); writer.print(" window="); writer.print(Utilities.dumpRect(mWindowRect));
writer.print(" display="); writer.print(Utilities.dumpRect(mDisplayRect));
writer.print(" orientation="); writer.print(mDisplayOrientation);
writer.print(" [0x"); writer.print(id); writer.print("]"); writer.print(" [0x"); writer.print(id); writer.print("]");
writer.println(); writer.println();

View File

@@ -126,21 +126,21 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
}; };
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
float mDimAlpha; private float mDimAlpha;
float mActionButtonTranslationZ; private float mActionButtonTranslationZ;
@ViewDebug.ExportedProperty(deepExport=true, prefix="task_") @ViewDebug.ExportedProperty(deepExport=true, prefix="task_")
Task mTask; private Task mTask;
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
boolean mTaskDataLoaded; private boolean mTaskDataLoaded;
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
boolean mClipViewInStack = true; private boolean mClipViewInStack = true;
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
boolean mTouchExplorationEnabled; private boolean mTouchExplorationEnabled;
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
boolean mIsDisabledInSafeMode; private boolean mIsDisabledInSafeMode;
@ViewDebug.ExportedProperty(deepExport=true, prefix="view_bounds_") @ViewDebug.ExportedProperty(deepExport=true, prefix="view_bounds_")
AnimateableViewBounds mViewBounds; private AnimateableViewBounds mViewBounds;
private AnimatorSet mTransformAnimation; private AnimatorSet mTransformAnimation;
private ObjectAnimator mDimAnimator; private ObjectAnimator mDimAnimator;
@@ -152,12 +152,12 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
TaskViewThumbnail mThumbnailView; TaskViewThumbnail mThumbnailView;
@ViewDebug.ExportedProperty(deepExport=true, prefix="header_") @ViewDebug.ExportedProperty(deepExport=true, prefix="header_")
TaskViewHeader mHeaderView; TaskViewHeader mHeaderView;
View mActionButtonView; private View mActionButtonView;
View mIncompatibleAppToastView; private View mIncompatibleAppToastView;
TaskViewCallbacks mCb; private TaskViewCallbacks mCb;
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
Point mDownTouchPos = new Point(); private Point mDownTouchPos = new Point();
private Toast mDisabledAppToast; private Toast mDisabledAppToast;
@@ -196,7 +196,6 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
*/ */
void onReload(boolean isResumingFromVisible) { void onReload(boolean isResumingFromVisible) {
resetNoUserInteractionState(); resetNoUserInteractionState();
readSystemFlags();
if (!isResumingFromVisible) { if (!isResumingFromVisible) {
resetViewProperties(); resetViewProperties();
} }
@@ -212,12 +211,6 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
return mViewBounds; return mViewBounds;
} }
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
readSystemFlags();
}
@Override @Override
protected void onFinishInflate() { protected void onFinishInflate() {
// Bind the views // Bind the views
@@ -598,12 +591,14 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
/**** TaskCallbacks Implementation ****/ /**** TaskCallbacks Implementation ****/
public void onTaskBound(Task t) { public void onTaskBound(Task t, boolean touchExplorationEnabled, int displayOrientation,
Rect displayRect) {
SystemServicesProxy ssp = Recents.getSystemServices(); SystemServicesProxy ssp = Recents.getSystemServices();
mTouchExplorationEnabled = touchExplorationEnabled;
mTask = t; mTask = t;
mTask.addCallback(this); mTask.addCallback(this);
mIsDisabledInSafeMode = !mTask.isSystemApp && ssp.isInSafeMode(); mIsDisabledInSafeMode = !mTask.isSystemApp && ssp.isInSafeMode();
mThumbnailView.bindToTask(mTask, mIsDisabledInSafeMode); mThumbnailView.bindToTask(mTask, mIsDisabledInSafeMode, displayOrientation, displayRect);
mHeaderView.bindToTask(mTask, mTouchExplorationEnabled, mIsDisabledInSafeMode); mHeaderView.bindToTask(mTask, mTouchExplorationEnabled, mIsDisabledInSafeMode);
if (!t.isDockable && ssp.hasDockedTask()) { if (!t.isDockable && ssp.hasDockedTask()) {
@@ -709,12 +704,4 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
} }
EventBus.getDefault().unregister(this); EventBus.getDefault().unregister(this);
} }
/**
* Reads current system flags related to accessibility and screen pinning.
*/
private void readSystemFlags() {
SystemServicesProxy ssp = Recents.getSystemServices();
mTouchExplorationEnabled = ssp.isTouchExplorationEnabled();
}
} }

View File

@@ -29,16 +29,12 @@ import android.graphics.LightingColorFilter;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Shader; import android.graphics.Shader;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View; import android.view.View;
import android.view.ViewDebug; import android.view.ViewDebug;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.Task; import com.android.systemui.recents.model.Task;
@@ -53,41 +49,38 @@ public class TaskViewThumbnail extends View {
private Task mTask; private Task mTask;
private int mDisplayOrientation = Configuration.ORIENTATION_UNDEFINED;
private Rect mDisplayRect = new Rect(); private Rect mDisplayRect = new Rect();
private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
// Drawing // Drawing
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
Rect mTaskViewRect = new Rect(); private Rect mTaskViewRect = new Rect();
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
Rect mThumbnailRect = new Rect(); private Rect mThumbnailRect = new Rect();
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
float mThumbnailScale; private float mThumbnailScale;
float mFullscreenThumbnailScale; private float mFullscreenThumbnailScale;
ActivityManager.TaskThumbnailInfo mThumbnailInfo; private ActivityManager.TaskThumbnailInfo mThumbnailInfo;
int mCornerRadius; private int mCornerRadius;
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
float mDimAlpha; private float mDimAlpha;
Matrix mScaleMatrix = new Matrix(); private Matrix mScaleMatrix = new Matrix();
Paint mDrawPaint = new Paint(); private Paint mDrawPaint = new Paint();
Paint mBgFillPaint = new Paint(); private Paint mBgFillPaint = new Paint();
BitmapShader mBitmapShader; private BitmapShader mBitmapShader;
LightingColorFilter mLightingColorFilter = new LightingColorFilter(0xffffffff, 0); private LightingColorFilter mLightingColorFilter = new LightingColorFilter(0xffffffff, 0);
// Task bar clipping, the top of this thumbnail can be clipped against the opaque header // Clip the top of the thumbnail against the opaque header bar that overlaps this view
// bar that overlaps this thumbnail private View mTaskBar;
View mTaskBar;
@ViewDebug.ExportedProperty(category="recents")
Rect mClipRect = new Rect();
// Visibility optimization, if the thumbnail height is less than the height of the header // Visibility optimization, if the thumbnail height is less than the height of the header
// bar for the task view, then just mark this thumbnail view as invisible // bar for the task view, then just mark this thumbnail view as invisible
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
boolean mInvisible; private boolean mInvisible;
@ViewDebug.ExportedProperty(category="recents") @ViewDebug.ExportedProperty(category="recents")
boolean mDisabledInSafeMode; private boolean mDisabledInSafeMode;
public TaskViewThumbnail(Context context) { public TaskViewThumbnail(Context context) {
this(context, null); this(context, null);
@@ -128,15 +121,6 @@ public class TaskViewThumbnail extends View {
updateThumbnailScale(); updateThumbnailScale();
} }
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
SystemServicesProxy ssp = Recents.getSystemServices();
mOrientation = Utilities.getAppConfiguration(mContext).orientation;
mDisplayRect = ssp.getDisplayRect();
}
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
if (mInvisible) { if (mInvisible) {
@@ -247,7 +231,7 @@ public class TaskViewThumbnail extends View {
mThumbnailScale = 0f; mThumbnailScale = 0f;
} else if (isStackTask) { } else if (isStackTask) {
float invThumbnailScale = 1f / mFullscreenThumbnailScale; float invThumbnailScale = 1f / mFullscreenThumbnailScale;
if (mOrientation == Configuration.ORIENTATION_PORTRAIT) { if (mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT) {
if (mThumbnailInfo.screenOrientation == Configuration.ORIENTATION_PORTRAIT) { if (mThumbnailInfo.screenOrientation == Configuration.ORIENTATION_PORTRAIT) {
// If we are in the same orientation as the screenshot, just scale it to the // If we are in the same orientation as the screenshot, just scale it to the
// width of the task view // width of the task view
@@ -306,9 +290,11 @@ public class TaskViewThumbnail extends View {
/** /**
* Binds the thumbnail view to the task. * Binds the thumbnail view to the task.
*/ */
void bindToTask(Task t, boolean disabledInSafeMode) { void bindToTask(Task t, boolean disabledInSafeMode, int displayOrientation, Rect displayRect) {
mTask = t; mTask = t;
mDisabledInSafeMode = disabledInSafeMode; mDisabledInSafeMode = disabledInSafeMode;
mDisplayOrientation = displayOrientation;
mDisplayRect.set(displayRect);
if (t.colorBackground != 0) { if (t.colorBackground != 0) {
mBgFillPaint.setColor(t.colorBackground); mBgFillPaint.setColor(t.colorBackground);
} }