Merge "Animation for docking task gesture" into nyc-dev

This commit is contained in:
Jorim Jaggi
2016-03-09 13:00:15 +00:00
committed by Android (Google) Code Review
14 changed files with 119 additions and 77 deletions

View File

@@ -307,6 +307,9 @@
<!-- The padding between freeform workspace tasks --> <!-- The padding between freeform workspace tasks -->
<dimen name="recents_freeform_workspace_task_padding">8dp</dimen> <dimen name="recents_freeform_workspace_task_padding">8dp</dimen>
<!-- The offsets the tasks animate from when recents is launched while docking -->
<dimen name="recents_task_view_launched_while_docking_offset">144dp</dimen>
<!-- Space reserved for the cards behind the top card in the bottom stack --> <!-- Space reserved for the cards behind the top card in the bottom stack -->
<dimen name="bottom_stack_peek_amount">12dp</dimen> <dimen name="bottom_stack_peek_amount">12dp</dimen>

View File

@@ -16,6 +16,8 @@
package com.android.systemui.recents; package com.android.systemui.recents;
import android.graphics.Rect;
/** /**
* Due to the fact that RecentsActivity is per-user, we need to establish an * Due to the fact that RecentsActivity is per-user, we need to establish an
* interface (this) for the non-system user to register itself for callbacks and to * interface (this) for the non-system user to register itself for callbacks and to
@@ -27,6 +29,6 @@ oneway interface IRecentsSystemUserCallbacks {
void updateRecentsVisibility(boolean visible); void updateRecentsVisibility(boolean visible);
void startScreenPinning(); void startScreenPinning();
void sendRecentsDrawnEvent(); void sendRecentsDrawnEvent();
void sendDockingTopTaskEvent(int dragMode); void sendDockingTopTaskEvent(int dragMode, in Rect initialRect);
void sendLaunchRecentsEvent(); void sendLaunchRecentsEvent();
} }

View File

@@ -43,7 +43,7 @@ import com.android.systemui.R;
import com.android.systemui.RecentsComponent; import com.android.systemui.RecentsComponent;
import com.android.systemui.SystemUI; import com.android.systemui.SystemUI;
import com.android.systemui.recents.events.EventBus; import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.DockingTopTaskEvent; import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent; import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent; import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.events.component.ScreenPinningRequestEvent; import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
@@ -577,14 +577,15 @@ public class Recents extends SystemUI
} }
} }
public final void onBusEvent(final DockingTopTaskEvent event) { public final void onBusEvent(final DockedTopTaskEvent event) {
int processUser = sSystemServicesProxy.getProcessUser(); int processUser = sSystemServicesProxy.getProcessUser();
if (!sSystemServicesProxy.isSystemUser(processUser)) { if (!sSystemServicesProxy.isSystemUser(processUser)) {
postToSystemUser(new Runnable() { postToSystemUser(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
mUserToSystemCallbacks.sendDockingTopTaskEvent(event.dragMode); mUserToSystemCallbacks.sendDockingTopTaskEvent(event.dragMode,
event.initialRect);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Callback failed", e); Log.e(TAG, "Callback failed", e);
} }

View File

@@ -47,7 +47,7 @@ import com.android.systemui.Prefs;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.SystemUIApplication; import com.android.systemui.SystemUIApplication;
import com.android.systemui.recents.events.EventBus; import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.DockingTopTaskEvent; import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent; import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
import com.android.systemui.recents.events.activity.HideRecentsEvent; import com.android.systemui.recents.events.activity.HideRecentsEvent;
import com.android.systemui.recents.events.activity.IterateRecentsEvent; import com.android.systemui.recents.events.activity.IterateRecentsEvent;
@@ -66,7 +66,6 @@ import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.Task; import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskGrouping; import com.android.systemui.recents.model.TaskGrouping;
import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.tv.views.TaskStackHorizontalGridView;
import com.android.systemui.recents.views.TaskStackLayoutAlgorithm; import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
import com.android.systemui.recents.views.TaskStackView; import com.android.systemui.recents.views.TaskStackView;
import com.android.systemui.recents.views.TaskStackViewScroller; import com.android.systemui.recents.views.TaskStackViewScroller;
@@ -569,7 +568,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
// Make sure we inform DividerView before we actually start the activity so we can change // Make sure we inform DividerView before we actually start the activity so we can change
// the resize mode already. // the resize mode already.
if (ssp.moveTaskToDockedStack(topTaskId, stackCreateMode, initialBounds)) { if (ssp.moveTaskToDockedStack(topTaskId, stackCreateMode, initialBounds)) {
EventBus.getDefault().send(new DockingTopTaskEvent(dragMode)); EventBus.getDefault().send(new DockedTopTaskEvent(dragMode, initialBounds));
showRecents( showRecents(
false /* triggeredFromAltTab */, false /* triggeredFromAltTab */,
dragMode == NavigationBarGestureHelper.DRAG_MODE_RECENTS, dragMode == NavigationBarGestureHelper.DRAG_MODE_RECENTS,

View File

@@ -17,6 +17,7 @@
package com.android.systemui.recents; package com.android.systemui.recents;
import android.content.Context; import android.content.Context;
import android.graphics.Rect;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.EventLog; import android.util.EventLog;
@@ -26,7 +27,7 @@ import android.util.SparseArray;
import com.android.systemui.EventLogConstants; import com.android.systemui.EventLogConstants;
import com.android.systemui.EventLogTags; import com.android.systemui.EventLogTags;
import com.android.systemui.recents.events.EventBus; import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.DockingTopTaskEvent; import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent; import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
import com.android.systemui.recents.events.ui.RecentsDrawnEvent; import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
@@ -91,8 +92,8 @@ public class RecentsSystemUser extends IRecentsSystemUserCallbacks.Stub {
} }
@Override @Override
public void sendDockingTopTaskEvent(int dragMode) throws RemoteException { public void sendDockingTopTaskEvent(int dragMode, Rect initialRect) throws RemoteException {
EventBus.getDefault().post(new DockingTopTaskEvent(dragMode)); EventBus.getDefault().post(new DockedTopTaskEvent(dragMode, initialRect));
} }
@Override @Override

View File

@@ -16,16 +16,21 @@
package com.android.systemui.recents.events.activity; package com.android.systemui.recents.events.activity;
import android.graphics.Rect;
import com.android.systemui.recents.events.EventBus; import com.android.systemui.recents.events.EventBus;
/** /**
* Fires when the user invoked the gesture to dock the top/left task. * Fires when the user invoked the gesture to dock the top/left task after we called into window
* manager and before we start recents.
*/ */
public class DockingTopTaskEvent extends EventBus.Event { public class DockedTopTaskEvent extends EventBus.Event {
public int dragMode; public int dragMode;
public Rect initialRect;
public DockingTopTaskEvent(int dragMode) { public DockedTopTaskEvent(int dragMode, Rect initialRect) {
this.dragMode = dragMode; this.dragMode = dragMode;
this.initialRect = initialRect;
} }
} }

View File

@@ -71,6 +71,8 @@ public class TaskStackAnimationHelper {
public static final int ENTER_FROM_HOME_ALPHA_DURATION = 100; public static final int ENTER_FROM_HOME_ALPHA_DURATION = 100;
public static final int ENTER_FROM_HOME_TRANSLATION_DURATION = 333; public static final int ENTER_FROM_HOME_TRANSLATION_DURATION = 333;
public static final int ENTER_WHILE_DOCKING_DURATION = 150;
private static final PathInterpolator ENTER_FROM_HOME_TRANSLATION_INTERPOLATOR = private static final PathInterpolator ENTER_FROM_HOME_TRANSLATION_INTERPOLATOR =
new PathInterpolator(0, 0, 0, 1f); new PathInterpolator(0, 0, 0, 1f);
private static final PathInterpolator ENTER_FROM_HOME_ALPHA_INTERPOLATOR = private static final PathInterpolator ENTER_FROM_HOME_ALPHA_INTERPOLATOR =
@@ -90,6 +92,9 @@ public class TaskStackAnimationHelper {
private static final PathInterpolator FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR = private static final PathInterpolator FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR =
new PathInterpolator(0.4f, 0, 0.2f, 1f); new PathInterpolator(0.4f, 0, 0.2f, 1f);
private static final PathInterpolator ENTER_WHILE_DOCKING_INTERPOLATOR =
new PathInterpolator(0, 0, 0.2f, 1f);
private TaskStackView mStackView; private TaskStackView mStackView;
private TaskViewTransform mTmpTransform = new TaskViewTransform(); private TaskViewTransform mTmpTransform = new TaskViewTransform();
@@ -122,6 +127,8 @@ public class TaskStackAnimationHelper {
int offscreenYOffset = stackLayout.mStackRect.height(); int offscreenYOffset = stackLayout.mStackRect.height();
int taskViewAffiliateGroupEnterOffset = res.getDimensionPixelSize( int taskViewAffiliateGroupEnterOffset = res.getDimensionPixelSize(
R.dimen.recents_task_view_affiliate_group_enter_offset); R.dimen.recents_task_view_affiliate_group_enter_offset);
int launchedWhileDockingOffset = res.getDimensionPixelSize(
R.dimen.recents_task_view_launched_while_docking_offset);
// Prepare each of the task views for their enter animation from front to back // Prepare each of the task views for their enter animation from front to back
List<TaskView> taskViews = mStackView.getTaskViews(); List<TaskView> taskViews = mStackView.getTaskViews();
@@ -141,7 +148,7 @@ public class TaskStackAnimationHelper {
tv.setVisibility(View.INVISIBLE); tv.setVisibility(View.INVISIBLE);
} else if (launchState.launchedHasConfigurationChanged) { } else if (launchState.launchedHasConfigurationChanged) {
// Just load the views as-is // Just load the views as-is
} else if (launchState.launchedFromApp) { } else if (launchState.launchedFromApp && !launchState.launchedWhileDocking) {
if (task.isLaunchTarget) { if (task.isLaunchTarget) {
tv.onPrepareLaunchTargetForEnterAnimation(); tv.onPrepareLaunchTargetForEnterAnimation();
} else if (currentTaskOccludesLaunchTarget) { } else if (currentTaskOccludesLaunchTarget) {
@@ -159,6 +166,11 @@ public class TaskStackAnimationHelper {
bounds.offset(0, offscreenYOffset); bounds.offset(0, offscreenYOffset);
tv.setLeftTopRightBottom((int) bounds.left, (int) bounds.top, (int) bounds.right, tv.setLeftTopRightBottom((int) bounds.left, (int) bounds.top, (int) bounds.right,
(int) bounds.bottom); (int) bounds.bottom);
} else if (launchState.launchedWhileDocking) {
RectF bounds = new RectF(mTmpTransform.rect);
bounds.offset(0, launchedWhileDockingOffset);
tv.setLeftTopRightBottom((int) bounds.left, (int) bounds.top, (int) bounds.right,
(int) bounds.bottom);
} }
} }
} }
@@ -192,6 +204,7 @@ public class TaskStackAnimationHelper {
int taskViewCount = taskViews.size(); int taskViewCount = taskViews.size();
for (int i = taskViewCount - 1; i >= 0; i--) { for (int i = taskViewCount - 1; i >= 0; i--) {
int taskIndexFromFront = taskViewCount - i - 1; int taskIndexFromFront = taskViewCount - i - 1;
int taskIndexFromBack = i;
final TaskView tv = taskViews.get(i); final TaskView tv = taskViews.get(i);
Task task = tv.getTask(); Task task = tv.getTask();
boolean currentTaskOccludesLaunchTarget = false; boolean currentTaskOccludesLaunchTarget = false;
@@ -205,7 +218,7 @@ public class TaskStackAnimationHelper {
stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform, stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
null); null);
if (launchState.launchedFromApp) { if (launchState.launchedFromApp && !launchState.launchedWhileDocking) {
if (task.isLaunchTarget) { if (task.isLaunchTarget) {
tv.onStartLaunchTargetEnterAnimation(mTmpTransform, tv.onStartLaunchTargetEnterAnimation(mTmpTransform,
taskViewEnterFromAppDuration, mStackView.mScreenPinningEnabled, taskViewEnterFromAppDuration, mStackView.mScreenPinningEnabled,
@@ -241,6 +254,16 @@ public class TaskStackAnimationHelper {
.setListener(postAnimationTrigger.decrementOnAnimationEnd()); .setListener(postAnimationTrigger.decrementOnAnimationEnd());
postAnimationTrigger.increment(); postAnimationTrigger.increment();
mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation); mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
} else if (launchState.launchedWhileDocking) {
// Animate the tasks up
AnimationProps taskAnimation = new AnimationProps()
.setDuration(AnimationProps.BOUNDS, (int) (ENTER_WHILE_DOCKING_DURATION +
(taskIndexFromBack * 2f * FRAME_OFFSET_MS)))
.setInterpolator(AnimationProps.BOUNDS,
ENTER_WHILE_DOCKING_INTERPOLATOR)
.setListener(postAnimationTrigger.decrementOnAnimationEnd());
postAnimationTrigger.increment();
mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
} }
} }
} }

View File

@@ -641,9 +641,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
// If we had a deferred animation, cancel that // If we had a deferred animation, cancel that
mDeferredTaskViewLayoutAnimation = null; mDeferredTaskViewLayoutAnimation = null;
// Cancel all task view animations
cancelAllTaskViewAnimations();
// Synchronize the current set of TaskViews // Synchronize the current set of TaskViews
bindVisibleTaskViews(mStackScroller.getStackScroll(), ignoreTasksSet, bindVisibleTaskViews(mStackScroller.getStackScroll(), ignoreTasksSet,
false /* ignoreTaskOverrides */); false /* ignoreTaskOverrides */);
@@ -678,6 +675,10 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
*/ */
public void updateTaskViewToTransform(TaskView taskView, TaskViewTransform transform, public void updateTaskViewToTransform(TaskView taskView, TaskViewTransform transform,
AnimationProps animation) { AnimationProps animation) {
if (taskView.isAnimatingTo(transform)) {
return;
}
taskView.cancelTransformAnimation();
taskView.updateViewPropertiesToTaskTransform(transform, animation, taskView.updateViewPropertiesToTaskTransform(transform, animation,
mRequestUpdateClippingListener); mRequestUpdateClippingListener);
} }

View File

@@ -147,6 +147,7 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
AnimateableViewBounds mViewBounds; AnimateableViewBounds mViewBounds;
private AnimatorSet mTransformAnimation; private AnimatorSet mTransformAnimation;
private final TaskViewTransform mTargetAnimationTransform = new TaskViewTransform();
private ArrayList<Animator> mTmpAnimators = new ArrayList<>(); private ArrayList<Animator> mTmpAnimators = new ArrayList<>();
View mContent; View mContent;
@@ -319,6 +320,7 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
// Create the animator // Create the animator
mTransformAnimation = toAnimation.createAnimator(mTmpAnimators); mTransformAnimation = toAnimation.createAnimator(mTmpAnimators);
mTransformAnimation.start(); mTransformAnimation.start();
mTargetAnimationTransform.copyFrom(toTransform);
} }
} }
@@ -337,6 +339,14 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
mActionButtonView.setTranslationZ(mActionButtonTranslationZ); mActionButtonView.setTranslationZ(mActionButtonTranslationZ);
} }
/**
* @return whether we are animating towards {@param transform}
*/
boolean isAnimatingTo(TaskViewTransform transform) {
return mTransformAnimation != null && mTransformAnimation.isStarted()
&& mTargetAnimationTransform.isSame(transform);
}
/** /**
* Cancels any current transform animations. * Cancels any current transform animations.
*/ */

View File

@@ -120,6 +120,18 @@ public class TaskViewTransform {
rect.set(other.rect); rect.set(other.rect);
} }
/**
* @return whether {@param other} is the same transform as this
*/
public boolean isSame(TaskViewTransform other) {
return translationZ == other.translationZ
&& scale == other.scale
&& other.alpha == alpha
&& dimAlpha == other.dimAlpha
&& visible == other.visible
&& rect.equals(other.rect);
}
/** /**
* Resets the current transform. * Resets the current transform.
*/ */

View File

@@ -53,7 +53,7 @@ import com.android.internal.policy.DockedDividerUtils;
import com.android.systemui.Interpolators; import com.android.systemui.Interpolators;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.recents.events.EventBus; import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.DockingTopTaskEvent; import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent; import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
import com.android.systemui.recents.events.activity.UndockingTaskEvent; import com.android.systemui.recents.events.activity.UndockingTaskEvent;
import com.android.systemui.recents.events.ui.RecentsDrawnEvent; import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
@@ -123,6 +123,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
private final Rect mDockedInsetRect = new Rect(); private final Rect mDockedInsetRect = new Rect();
private final Rect mOtherInsetRect = new Rect(); private final Rect mOtherInsetRect = new Rect();
private final Rect mLastResizeRect = new Rect(); private final Rect mLastResizeRect = new Rect();
private final Rect mDisplayRect = new Rect();
private final WindowManagerProxy mWindowManagerProxy = WindowManagerProxy.getInstance(); private final WindowManagerProxy mWindowManagerProxy = WindowManagerProxy.getInstance();
private DividerWindowManager mWindowManager; private DividerWindowManager mWindowManager;
private VelocityTracker mVelocityTracker; private VelocityTracker mVelocityTracker;
@@ -133,7 +134,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
private boolean mAnimateAfterRecentsDrawn; private boolean mAnimateAfterRecentsDrawn;
private boolean mGrowAfterRecentsDrawn; private boolean mGrowAfterRecentsDrawn;
private boolean mGrowRecents; private boolean mGrowRecents;
private Animator mCurrentAnimator; private ValueAnimator mCurrentAnimator;
private boolean mEntranceAnimationRunning;
private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() { private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() {
@Override @Override
@@ -411,6 +413,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
mWindowManagerProxy.setResizing(false); mWindowManagerProxy.setResizing(false);
mDockSide = WindowManager.DOCKED_INVALID; mDockSide = WindowManager.DOCKED_INVALID;
mCurrentAnimator = null; mCurrentAnimator = null;
mEntranceAnimationRunning = false;
} }
}); });
mCurrentAnimator = anim; mCurrentAnimator = anim;
@@ -594,7 +597,18 @@ public class DividerView extends FrameLayout implements OnTouchListener,
} }
mLastResizeRect.set(mDockedRect); mLastResizeRect.set(mDockedRect);
if (taskPosition != TASK_POSITION_SAME) { if (mEntranceAnimationRunning && taskPosition != TASK_POSITION_SAME) {
if (mCurrentAnimator != null) {
calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect);
} else {
calculateBoundsForPosition(isHorizontalDivision() ? mDisplayHeight : mDisplayWidth,
mDockSide, mDockedTaskRect);
}
calculateBoundsForPosition(taskPosition, DockedDividerUtils.invertDockSide(mDockSide),
mOtherTaskRect);
mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, null,
mOtherTaskRect, null);
} else if (taskPosition != TASK_POSITION_SAME) {
calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide), calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide),
mOtherRect); mOtherRect);
int dockSideInverted = DockedDividerUtils.invertDockSide(mDockSide); int dockSideInverted = DockedDividerUtils.invertDockSide(mDockSide);
@@ -610,16 +624,17 @@ public class DividerView extends FrameLayout implements OnTouchListener,
calculateBoundsForPosition(taskPositionDocked, mDockSide, mDockedTaskRect); calculateBoundsForPosition(taskPositionDocked, mDockSide, mDockedTaskRect);
calculateBoundsForPosition(taskPositionOther, dockSideInverted, mOtherTaskRect); calculateBoundsForPosition(taskPositionOther, dockSideInverted, mOtherTaskRect);
mDisplayRect.set(0, 0, mDisplayWidth, mDisplayHeight);
alignTopLeft(mDockedRect, mDockedTaskRect); alignTopLeft(mDockedRect, mDockedTaskRect);
alignTopLeft(mOtherRect, mOtherTaskRect); alignTopLeft(mOtherRect, mOtherTaskRect);
mDockedInsetRect.set(mDockedTaskRect); mDockedInsetRect.set(mDockedTaskRect);
mOtherInsetRect.set(mOtherTaskRect); mOtherInsetRect.set(mOtherTaskRect);
if (dockSideTopLeft(mDockSide)) { if (dockSideTopLeft(mDockSide)) {
alignTopLeft(mDockedRect, mDockedInsetRect); alignTopLeft(mDisplayRect, mDockedInsetRect);
alignBottomRight(mOtherRect, mOtherInsetRect); alignBottomRight(mDisplayRect, mOtherInsetRect);
} else { } else {
alignBottomRight(mDockedRect, mDockedInsetRect); alignBottomRight(mDisplayRect, mDockedInsetRect);
alignTopLeft(mOtherRect, mOtherInsetRect); alignTopLeft(mDisplayRect, mOtherInsetRect);
} }
applyDismissingParallax(mDockedTaskRect, mDockSide, taskSnapTarget, position, applyDismissingParallax(mDockedTaskRect, mDockSide, taskSnapTarget, position,
taskPositionDocked); taskPositionDocked);
@@ -638,6 +653,9 @@ public class DividerView extends FrameLayout implements OnTouchListener,
} }
private float getDimFraction(int position, SnapTarget dismissTarget) { private float getDimFraction(int position, SnapTarget dismissTarget) {
if (mEntranceAnimationRunning) {
return 0f;
}
float fraction = mSnapAlgorithm.calculateDismissingFraction(position); float fraction = mSnapAlgorithm.calculateDismissingFraction(position);
fraction = Math.max(0, Math.min(fraction, 1f)); fraction = Math.max(0, Math.min(fraction, 1f));
fraction = DIM_INTERPOLATOR.getInterpolation(fraction); fraction = DIM_INTERPOLATOR.getInterpolation(fraction);
@@ -839,12 +857,18 @@ public class DividerView extends FrameLayout implements OnTouchListener,
} }
} }
public final void onBusEvent(DockingTopTaskEvent dockingEvent) { public final void onBusEvent(DockedTopTaskEvent event) {
if (dockingEvent.dragMode == NavigationBarGestureHelper.DRAG_MODE_NONE) { if (event.dragMode == NavigationBarGestureHelper.DRAG_MODE_NONE) {
mGrowAfterRecentsDrawn = false; mGrowAfterRecentsDrawn = false;
mAnimateAfterRecentsDrawn = true; mAnimateAfterRecentsDrawn = true;
startDragging(false /* animate */, false /* touching */); startDragging(false /* animate */, false /* touching */);
} }
updateDockSide();
int position = DockedDividerUtils.calculatePositionForBounds(event.initialRect,
mDockSide, mDividerSize);
mEntranceAnimationRunning = true;
resizeStack(position, mSnapAlgorithm.getMiddleTarget().position,
mSnapAlgorithm.getMiddleTarget());
} }
public final void onBusEvent(RecentsDrawnEvent drawnEvent) { public final void onBusEvent(RecentsDrawnEvent drawnEvent) {

View File

@@ -414,6 +414,12 @@ final class ActivityStack {
mTaskPositioner.reset(); mTaskPositioner.reset();
} }
mWindowManager.detachStack(mStackId); mWindowManager.detachStack(mStackId);
if (mStackId == DOCKED_STACK_ID) {
// If we removed a docked stack we want to resize it so it resizes all other stacks
// in the system to fullscreen.
mStackSupervisor.resizeDockedStackLocked(
null, null, null, null, null, PRESERVE_WINDOWS);
}
} }
public void getDisplaySize(Point out) { public void getDisplaySize(Point out) {

View File

@@ -148,9 +148,7 @@ public class TaskStack implements DimLayer.DimLayerUser,
boolean setBounds( boolean setBounds(
Rect stackBounds, SparseArray<Configuration> configs, SparseArray<Rect> taskBounds, Rect stackBounds, SparseArray<Configuration> configs, SparseArray<Rect> taskBounds,
SparseArray<Rect> taskTempInsetBounds) { SparseArray<Rect> taskTempInsetBounds) {
if (!setBounds(stackBounds)) { setBounds(stackBounds);
return false;
}
// Update bounds of containing tasks. // Update bounds of containing tasks.
for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) { for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
@@ -608,13 +606,6 @@ public class TaskStack implements DimLayer.DimLayerUser,
} }
updateDisplayInfo(bounds); updateDisplayInfo(bounds);
if (mStackId == DOCKED_STACK_ID) {
// Attaching a docked stack to the display affects the size of all other static
// stacks since the docked stack occupies a dedicated region on screen.
// Resize existing static stacks so they are pushed to the side of the docked stack.
resizeNonDockedStacks(!FULLSCREEN, mBounds);
}
} }
void getStackDockedModeBoundsLocked(Rect outBounds, boolean ignoreVisibility) { void getStackDockedModeBoundsLocked(Rect outBounds, boolean ignoreVisibility) {
@@ -723,36 +714,6 @@ public class TaskStack implements DimLayer.DimLayerUser,
DockedDividerUtils.sanitizeStackBounds(outBounds, !dockOnTopOrLeft); DockedDividerUtils.sanitizeStackBounds(outBounds, !dockOnTopOrLeft);
} }
/** Resizes all non-docked stacks in the system to either fullscreen or the appropriate size
* based on the presence of a docked stack.
* @param fullscreen If true the stacks will be resized to fullscreen, else they will be
* resized to the appropriate size based on the presence of a docked stack.
* @param dockedBounds Bounds of the docked stack.
*/
private void resizeNonDockedStacks(boolean fullscreen, Rect dockedBounds) {
// Not using mTmpRect because we are posting the object in a message.
final Rect bounds = new Rect();
mDisplayContent.getLogicalDisplayRect(bounds);
if (!fullscreen) {
final boolean dockedOnTopOrLeft = mService.mDockedStackCreateMode
== DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
getStackDockedModeBounds(bounds, bounds, FULLSCREEN_WORKSPACE_STACK_ID, dockedBounds,
mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
}
final int count = mService.mStackIdToStack.size();
for (int i = 0; i < count; i++) {
final TaskStack otherStack = mService.mStackIdToStack.valueAt(i);
final int otherStackId = otherStack.mStackId;
if (StackId.isResizeableByDockedStack(otherStackId)
&& !otherStack.mBounds.equals(bounds)) {
mService.mH.sendMessage(
mService.mH.obtainMessage(RESIZE_STACK, otherStackId,
1 /*allowResizeInDockedMode*/, fullscreen ? null : bounds));
}
}
}
void resetDockedStackToMiddle() { void resetDockedStackToMiddle() {
if (mStackId != DOCKED_STACK_ID) { if (mStackId != DOCKED_STACK_ID) {
throw new IllegalStateException("Not a docked stack=" + this); throw new IllegalStateException("Not a docked stack=" + this);
@@ -786,12 +747,6 @@ public class TaskStack implements DimLayer.DimLayerUser,
mService.mWindowPlacerLocked.requestTraversal(); mService.mWindowPlacerLocked.requestTraversal();
} }
if (mStackId == DOCKED_STACK_ID) {
// Docked stack was detached from the display, so we no longer need to restrict the
// region of the screen other static stacks occupy. Go ahead and make them fullscreen.
resizeNonDockedStacks(FULLSCREEN, null);
}
close(); close();
} }

View File

@@ -780,9 +780,9 @@ final class WindowState implements WindowManagerPolicy.WindowState {
Math.min(mStableFrame.bottom, frame.bottom)); Math.min(mStableFrame.bottom, frame.bottom));
} }
if (!windowsAreFloating) { if (fullscreenTask && !windowsAreFloating) {
// Windows from floating tasks (e.g. freeform, pinned) may be positioned outside // Windows that are not fullscreen can be positioned outside of the display frame,
// of the display frame, but that is not a reason to provide them with overscan insets. // but that is not a reason to provide them with overscan insets.
mOverscanInsets.set(Math.max(mOverscanFrame.left - frame.left, 0), mOverscanInsets.set(Math.max(mOverscanFrame.left - frame.left, 0),
Math.max(mOverscanFrame.top - frame.top, 0), Math.max(mOverscanFrame.top - frame.top, 0),
Math.max(frame.right - mOverscanFrame.right, 0), Math.max(frame.right - mOverscanFrame.right, 0),
@@ -2257,7 +2257,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
// background. // background.
return (mDisplayContent.mDividerControllerLocked.isResizing() return (mDisplayContent.mDividerControllerLocked.isResizing()
|| mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) && || mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) &&
!task.inFreeformWorkspace() && isVisibleLw(); !task.inFreeformWorkspace() && !isGoneForLayoutLw();
} }