diff --git a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java index eaafafac3f879..94b2fdbf5ff82 100644 --- a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java +++ b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java @@ -21,9 +21,9 @@ import android.view.Display; import android.view.View; public interface RecentsComponent { - void showRecents(boolean triggeredFromAltTab, boolean fromHome, View statusBarView); + void showRecents(boolean triggeredFromAltTab, boolean fromHome); void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey); - void toggleRecents(Display display, int layoutDirection, View statusBarView); + void toggleRecents(Display display); void preloadRecents(); void cancelPreloadingRecents(); void showNextAffiliatedTask(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl b/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl index 7ce9384258fe9..940366444e637 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl +++ b/packages/SystemUI/src/com/android/systemui/recents/IRecentsNonSystemUserCallbacks.aidl @@ -27,9 +27,9 @@ oneway interface IRecentsNonSystemUserCallbacks { void preloadRecents(); void cancelPreloadingRecents(); void showRecents(boolean triggeredFromAltTab, boolean draggingInRecents, boolean animate, - boolean reloadTasks, boolean fromHome); + boolean reloadTasks, boolean fromHome, int recentsGrowTarget); void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey); - void toggleRecents(); + void toggleRecents(int recentsGrowTarget); void onConfigurationChanged(); void dockTopTask(int topTaskId, int dragMode, int stackCreateMode, in Rect initialBounds); diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index bb709c5ca9c0a..630cb6655a191 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -37,9 +37,7 @@ import android.os.UserHandle; import android.provider.Settings; import android.util.EventLog; import android.util.Log; -import android.util.MutableBoolean; import android.view.Display; -import android.view.View; import android.widget.Toast; import com.android.internal.logging.MetricsLogger; @@ -59,6 +57,7 @@ import com.android.systemui.recents.events.ui.RecentsDrawnEvent; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.model.RecentsTaskLoader; import com.android.systemui.recents.tv.RecentsTvImpl; +import com.android.systemui.stackdivider.Divider; import java.util.ArrayList; @@ -75,6 +74,7 @@ public class Recents extends SystemUI public final static int EVENT_BUS_PRIORITY = 1; public final static int BIND_TO_SYSTEM_USER_RETRY_DELAY = 5000; + public final static int RECENTS_GROW_TARGET_INVALID = -1; // Purely for experimentation private final static String RECENTS_OVERRIDE_SYSPROP_KEY = "persist.recents_override_pkg"; @@ -238,7 +238,7 @@ public class Recents extends SystemUI * Shows the Recents. */ @Override - public void showRecents(boolean triggeredFromAltTab, boolean fromHome, View statusBarView) { + public void showRecents(boolean triggeredFromAltTab, boolean fromHome) { // Ensure the device has been provisioned before allowing the user to interact with // recents if (!isUserSetup()) { @@ -249,10 +249,12 @@ public class Recents extends SystemUI return; } + int recentsGrowTarget = getComponent(Divider.class).getView().growsRecents(); + int currentUser = sSystemServicesProxy.getCurrentUser(); if (sSystemServicesProxy.isSystemUser(currentUser)) { mImpl.showRecents(triggeredFromAltTab, false /* draggingInRecents */, - true /* animate */, false /* reloadTasks */, fromHome); + true /* animate */, false /* reloadTasks */, fromHome, recentsGrowTarget); } else { if (mSystemToUserCallbacks != null) { IRecentsNonSystemUserCallbacks callbacks = @@ -260,7 +262,8 @@ public class Recents extends SystemUI if (callbacks != null) { try { callbacks.showRecents(triggeredFromAltTab, false /* draggingInRecents */, - true /* animate */, false /* reloadTasks */, fromHome); + true /* animate */, false /* reloadTasks */, fromHome, + recentsGrowTarget); } catch (RemoteException e) { Log.e(TAG, "Callback failed", e); } @@ -310,7 +313,7 @@ public class Recents extends SystemUI * Toggles the Recents activity. */ @Override - public void toggleRecents(Display display, int layoutDirection, View statusBarView) { + public void toggleRecents(Display display) { // Ensure the device has been provisioned before allowing the user to interact with // recents if (!isUserSetup()) { @@ -321,16 +324,18 @@ public class Recents extends SystemUI return; } + int growTarget = getComponent(Divider.class).getView().growsRecents(); + int currentUser = sSystemServicesProxy.getCurrentUser(); if (sSystemServicesProxy.isSystemUser(currentUser)) { - mImpl.toggleRecents(); + mImpl.toggleRecents(growTarget); } else { if (mSystemToUserCallbacks != null) { IRecentsNonSystemUserCallbacks callbacks = mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser); if (callbacks != null) { try { - callbacks.toggleRecents(); + callbacks.toggleRecents(growTarget); } catch (RemoteException e) { Log.e(TAG, "Callback failed", e); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java index 3ecada961a24b..f961390043ebf 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java @@ -38,8 +38,10 @@ import android.util.MutableBoolean; import android.view.AppTransitionAnimationSpec; import android.view.LayoutInflater; import android.view.ViewConfiguration; +import android.view.WindowManager; import com.android.internal.logging.MetricsLogger; +import com.android.internal.policy.DockedDividerUtils; import com.android.systemui.R; import com.android.systemui.SystemUIApplication; import com.android.systemui.recents.events.EventBus; @@ -68,6 +70,7 @@ import com.android.systemui.recents.views.TaskStackView; import com.android.systemui.recents.views.TaskStackViewScroller; import com.android.systemui.recents.views.TaskViewHeader; import com.android.systemui.recents.views.TaskViewTransform; +import com.android.systemui.stackdivider.DividerView; import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.phone.NavigationBarGestureHelper; import com.android.systemui.statusbar.phone.PhoneStatusBar; @@ -156,7 +159,8 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener // When this fires, then the user has not released alt-tab for at least // FAST_ALT_TAB_DELAY_MS milliseconds showRecents(mTriggeredFromAltTab, false /* draggingInRecents */, true /* animate */, - false /* reloadTasks */, false /* fromHome */); + false /* reloadTasks */, false /* fromHome */, + DividerView.INVALID_RECENTS_GROW_TARGET); } }); @@ -230,7 +234,8 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener } public void showRecents(boolean triggeredFromAltTab, boolean draggingInRecents, - boolean animate, boolean launchedWhileDockingTask, boolean fromHome) { + boolean animate, boolean launchedWhileDockingTask, boolean fromHome, + int growTarget) { mTriggeredFromAltTab = triggeredFromAltTab; mDraggingInRecents = draggingInRecents; mLaunchedWhileDocking = launchedWhileDockingTask; @@ -260,7 +265,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener ActivityManager.RunningTaskInfo topTask = ssp.getTopMostTask(); MutableBoolean isTopTaskHome = new MutableBoolean(true); if (topTask == null || !ssp.isRecentsTopMost(topTask, isTopTaskHome)) { - startRecentsActivity(topTask, isTopTaskHome.value || fromHome, animate); + startRecentsActivity(topTask, isTopTaskHome.value || fromHome, animate, growTarget); } } catch (ActivityNotFoundException e) { Log.e(TAG, "Failed to launch RecentsActivity", e); @@ -284,7 +289,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener triggeredFromHomeKey)); } - public void toggleRecents() { + public void toggleRecents(int growTarget) { // Skip this toggle if we are already waiting to trigger recents via alt-tab if (mFastAltTabTrigger.isDozing()) { return; @@ -338,7 +343,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener } // Otherwise, start the recents activity - startRecentsActivity(topTask, isTopTaskHome.value, true /* animate */); + startRecentsActivity(topTask, isTopTaskHome.value, true /* animate */, growTarget); // Only close the other system windows if we are actually showing recents ssp.sendCloseSystemWindows(BaseStatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS); @@ -369,7 +374,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener // At this point, we don't know anything about the stack state. So only calculate // the dimensions of the thumbnail that we need for the transition into Recents, but // do not draw it until we construct the activity options when we start Recents - updateHeaderBarLayout(stack); + updateHeaderBarLayout(stack, null /* window rect override*/); } } } @@ -535,7 +540,8 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener dragMode == NavigationBarGestureHelper.DRAG_MODE_RECENTS, false /* animate */, true /* launchedWhileDockingTask*/, - false /* fromHome */); + false /* fromHome */, + DividerView.INVALID_RECENTS_GROW_TARGET); } } @@ -574,12 +580,17 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener * since the last call, it will attempt to re-measure and layout the header bar to the new size. * * @param stack the stack to initialize the stack layout with + * @param windowRectOverride the rectangle to use when calculating the stack state which can + * be different from the current window rect if recents is resizing + * while being launched */ - private void updateHeaderBarLayout(TaskStack stack) { + private void updateHeaderBarLayout(TaskStack stack, Rect windowRectOverride) { SystemServicesProxy ssp = Recents.getSystemServices(); Rect systemInsets = new Rect(); ssp.getStableInsets(systemInsets); - Rect windowRect = ssp.getWindowRect(); + Rect windowRect = windowRectOverride != null + ? new Rect(windowRectOverride) + : ssp.getWindowRect(); // When docked, the nav bar insets are consumed and the activity is measured without insets. // However, the window bounds include the insets, so we need to subtract them here to make // them identical. @@ -682,7 +693,8 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener * Creates the activity options for an app->recents transition. */ private ActivityOptions getThumbnailTransitionActivityOptions( - ActivityManager.RunningTaskInfo topTask, TaskStackView stackView) { + ActivityManager.RunningTaskInfo topTask, TaskStackView stackView, + Rect windowOverrideRect) { if (topTask.stackId == FREEFORM_WORKSPACE_STACK_ID) { ArrayList specs = new ArrayList<>(); ArrayList tasks = stackView.getStack().getStackTasks(); @@ -696,7 +708,8 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener Task task = tasks.get(i); if (task.isFreeformTask()) { mTmpTransform = stackLayout.getStackTransformScreenCoordinates(task, - stackScroller.getStackScroll(), mTmpTransform, null); + stackScroller.getStackScroll(), mTmpTransform, null, + windowOverrideRect); Bitmap thumbnail = drawThumbnailTransitionBitmap(task, mTmpTransform, mThumbTransitionBitmapCache); Rect toTaskRect = new Rect(); @@ -711,7 +724,8 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener } else { // Update the destination rect Task toTask = new Task(); - TaskViewTransform toTransform = getThumbnailTransitionTransform(stackView, toTask); + TaskViewTransform toTransform = getThumbnailTransitionTransform(stackView, toTask, + windowOverrideRect); Bitmap thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform, mThumbTransitionBitmapCache); if (thumbnail != null) { @@ -729,7 +743,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener * Returns the transition rect for the given task id. */ private TaskViewTransform getThumbnailTransitionTransform(TaskStackView stackView, - Task runningTaskOut) { + Task runningTaskOut, Rect windowOverrideRect) { // Find the running task in the TaskStack TaskStack stack = stackView.getStack(); Task launchTask = stack.getLaunchTarget(); @@ -745,7 +759,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener stackView.updateLayoutAlgorithm(true /* boundScroll */); stackView.updateToInitialState(); stackView.getStackAlgorithm().getStackTransformScreenCoordinates(launchTask, - stackView.getScroller().getStackScroll(), mTmpTransform, null); + stackView.getScroller().getStackScroll(), mTmpTransform, null, windowOverrideRect); return mTmpTransform; } @@ -788,7 +802,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener * Shows the recents activity */ protected void startRecentsActivity(ActivityManager.RunningTaskInfo topTask, - boolean isTopTaskHome, boolean animate) { + boolean isTopTaskHome, boolean animate, int growTarget) { RecentsTaskLoader loader = Recents.getTaskLoader(); RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState(); @@ -820,7 +834,8 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener preloadIcon(topTask); // Update the header bar if necessary - updateHeaderBarLayout(stack); + Rect windowOverrideRect = getWindowRectOverride(growTarget); + updateHeaderBarLayout(stack, windowOverrideRect); // Prepare the dummy stack for the transition TaskStackLayoutAlgorithm.VisibilityReport stackVr = @@ -838,7 +853,8 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener ActivityOptions opts; if (useThumbnailTransition) { // Try starting with a thumbnail transition - opts = getThumbnailTransitionActivityOptions(topTask, mDummyStackView); + opts = getThumbnailTransitionActivityOptions(topTask, mDummyStackView, + windowOverrideRect); } else { // If there is no thumbnail transition, but is launching from home into recents, then // use a quick home transition @@ -850,6 +866,18 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener mLastToggleTime = SystemClock.elapsedRealtime(); } + private Rect getWindowRectOverride(int growTarget) { + if (growTarget == DividerView.INVALID_RECENTS_GROW_TARGET) { + return null; + } + Rect result = new Rect(); + Rect displayRect = Recents.getSystemServices().getDisplayRect(); + DockedDividerUtils.calculateBoundsForPosition(growTarget, WindowManager.DOCKED_BOTTOM, + result, displayRect.width(), displayRect.height(), + Recents.getSystemServices().getDockedDividerSize(mContext)); + return result; + } + /** * Starts the recents activity. */ diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java index 257bda2e147a9..defc6ed042bcb 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplProxy.java @@ -57,13 +57,15 @@ public class RecentsImplProxy extends IRecentsNonSystemUserCallbacks.Stub { @Override public void showRecents(boolean triggeredFromAltTab, boolean draggingInRecents, boolean animate, - boolean reloadTasks, boolean fromHome) throws RemoteException { + boolean reloadTasks, boolean fromHome, int growTarget) + throws RemoteException { SomeArgs args = SomeArgs.obtain(); args.argi1 = triggeredFromAltTab ? 1 : 0; args.argi2 = draggingInRecents ? 1 : 0; args.argi3 = animate ? 1 : 0; args.argi4 = reloadTasks ? 1 : 0; args.argi5 = fromHome ? 1 : 0; + args.argi6 = growTarget; mHandler.sendMessage(mHandler.obtainMessage(MSG_SHOW_RECENTS, args)); } @@ -75,8 +77,8 @@ public class RecentsImplProxy extends IRecentsNonSystemUserCallbacks.Stub { } @Override - public void toggleRecents() throws RemoteException { - mHandler.sendEmptyMessage(MSG_TOGGLE_RECENTS); + public void toggleRecents(int growTarget) throws RemoteException { + mHandler.sendMessage(mHandler.obtainMessage(MSG_TOGGLE_RECENTS, growTarget)); } @Override @@ -119,13 +121,13 @@ public class RecentsImplProxy extends IRecentsNonSystemUserCallbacks.Stub { case MSG_SHOW_RECENTS: SomeArgs args = (SomeArgs) msg.obj; mImpl.showRecents(args.argi1 != 0, args.argi2 != 0, args.argi3 != 0, - args.argi4 != 0, args.argi5 != 0); + args.argi4 != 0, args.argi5 != 0, args.argi6); break; case MSG_HIDE_RECENTS: mImpl.hideRecents(msg.arg1 != 0, msg.arg2 != 0); break; case MSG_TOGGLE_RECENTS: - mImpl.toggleRecents(); + mImpl.toggleRecents(msg.arg1); break; case MSG_ON_CONFIGURATION_CHANGED: mImpl.onConfigurationChanged(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsGrowingEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsGrowingEvent.java new file mode 100644 index 0000000000000..d9b00271b31ec --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/RecentsGrowingEvent.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.recents.events.ui; + +import com.android.systemui.recents.events.EventBus; + +/** + * Sent when recents is about to grow in multi-window mode when entering recents. + */ +public class RecentsGrowingEvent extends EventBus.Event { + +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java index dc0d1f1fe465d..18b9263564bba 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java @@ -49,7 +49,7 @@ public class RecentsTvImpl extends RecentsImpl{ @Override protected void startRecentsActivity(ActivityManager.RunningTaskInfo topTask, - boolean isTopTaskHome, boolean animate) { + boolean isTopTaskHome, boolean animate, int growTarget) { RecentsTaskLoader loader = Recents.getTaskLoader(); // In the case where alt-tab is triggered, we never get a preloadRecents() call, so we diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java index 04f10ef8e8930..1238c637e006b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java @@ -302,7 +302,8 @@ public class RecentsTransitionHelper { specs.add(composeOffscreenAnimationSpec(task, offscreenTaskRect)); } else { mTmpTransform.fillIn(taskView); - stackLayout.transformToScreenCoordinates(mTmpTransform); + stackLayout.transformToScreenCoordinates(mTmpTransform, + null /* windowOverrideRect */); specs.add(composeAnimationSpec(stackView, taskView, mTmpTransform, true /* addHeaderBitmap */)); } @@ -324,7 +325,8 @@ public class RecentsTransitionHelper { specs.add(composeOffscreenAnimationSpec(t, offscreenTaskRect)); } else { mTmpTransform.fillIn(taskView); - stackLayout.transformToScreenCoordinates(mTmpTransform); + stackLayout.transformToScreenCoordinates(mTmpTransform, + null /* windowOverrideRect */); specs.add(composeAnimationSpec(stackView, tv, mTmpTransform, true /* addHeaderBitmap */)); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java index 774e4e9cd0869..0022d66103b10 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java @@ -830,18 +830,23 @@ public class TaskStackLayoutAlgorithm { * Like {@link #getStackTransform}, but in screen coordinates */ public TaskViewTransform getStackTransformScreenCoordinates(Task task, float stackScroll, - TaskViewTransform transformOut, TaskViewTransform frontTransform) { + TaskViewTransform transformOut, TaskViewTransform frontTransform, + Rect windowOverrideRect) { TaskViewTransform transform = getStackTransform(task, stackScroll, mFocusState, transformOut, frontTransform, true /* forceUpdate */, false /* ignoreTaskOverrides */); - return transformToScreenCoordinates(transform); + return transformToScreenCoordinates(transform, windowOverrideRect); } /** - * Transforms the given {@param transformOut} to the screen coordinates. + * Transforms the given {@param transformOut} to the screen coordinates, overriding the current + * window rectangle with {@param windowOverrideRect} if non-null. */ - public TaskViewTransform transformToScreenCoordinates(TaskViewTransform transformOut) { - Rect windowRect = Recents.getSystemServices().getWindowRect(); + public TaskViewTransform transformToScreenCoordinates(TaskViewTransform transformOut, + Rect windowOverrideRect) { + Rect windowRect = windowOverrideRect != null + ? windowOverrideRect + : Recents.getSystemServices().getWindowRect(); transformOut.rect.offset(windowRect.left, windowRect.top); return transformOut; } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index 6176d99a7c174..f0a83332e597b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -72,6 +72,7 @@ import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent; import com.android.systemui.recents.events.ui.DeleteTaskDataEvent; import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent; import com.android.systemui.recents.events.ui.DismissTaskViewEvent; +import com.android.systemui.recents.events.ui.RecentsGrowingEvent; import com.android.systemui.recents.events.ui.TaskViewDismissedEvent; import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEvent; import com.android.systemui.recents.events.ui.UserInteractionEvent; @@ -189,6 +190,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal private TaskViewTransform mTmpTransform = new TaskViewTransform(); private ArrayList mTmpTaskTransforms = new ArrayList<>(); private int[] mTmpIntPair = new int[2]; + private boolean mResetToInitialStateWhenResized; + private int mLastWidth; + private int mLastHeight; // A convenience update listener to request updating clipping of tasks private ValueAnimator.AnimatorUpdateListener mRequestUpdateClippingListener = @@ -1164,9 +1168,13 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // If this is the first layout, then scroll to the front of the stack, then update the // TaskViews with the stack so that we can lay them out - if (mAwaitingFirstLayout || mInitialState != INITIAL_STATE_UPDATE_NONE) { - if (mInitialState != INITIAL_STATE_UPDATE_LAYOUT_ONLY) { + boolean resetToInitialState = (width != mLastWidth || height != mLastHeight) + && mResetToInitialStateWhenResized; + if (mAwaitingFirstLayout || mInitialState != INITIAL_STATE_UPDATE_NONE + || resetToInitialState) { + if (mInitialState != INITIAL_STATE_UPDATE_LAYOUT_ONLY || resetToInitialState) { updateToInitialState(); + mResetToInitialStateWhenResized = false; } if (!mAwaitingFirstLayout) { mInitialState = INITIAL_STATE_UPDATE_NONE; @@ -1186,6 +1194,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } setMeasuredDimension(width, height); + mLastWidth = width; + mLastHeight = height; mInMeasureLayout = false; } @@ -1972,6 +1982,10 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } } + public final void onBusEvent(RecentsGrowingEvent event) { + mResetToInitialStateWhenResized = true; + } + public void reloadOnConfigurationChange() { mStableLayoutAlgorithm.reloadOnConfigurationChange(getContext()); mLayoutAlgorithm.reloadOnConfigurationChange(getContext()); diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java index 67c4008b4dc6c..8cd674c09c398 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java @@ -32,6 +32,7 @@ import android.graphics.Region.Op; import android.hardware.display.DisplayManager; import android.os.Bundle; import android.util.AttributeSet; +import android.util.MutableInt; import android.view.Display; import android.view.DisplayInfo; import android.view.GestureDetector; @@ -66,6 +67,7 @@ import com.android.systemui.recents.events.activity.DockedTopTaskEvent; import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent; import com.android.systemui.recents.events.activity.UndockingTaskEvent; import com.android.systemui.recents.events.ui.RecentsDrawnEvent; +import com.android.systemui.recents.events.ui.RecentsGrowingEvent; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.stackdivider.events.StartedDragingEvent; import com.android.systemui.stackdivider.events.StoppedDragingEvent; @@ -81,6 +83,8 @@ public class DividerView extends FrameLayout implements OnTouchListener, static final long TOUCH_ANIMATION_DURATION = 150; static final long TOUCH_RELEASE_ANIMATION_DURATION = 200; + public static final int INVALID_RECENTS_GROW_TARGET = -1; + private static final int LOG_VALUE_RESIZE_50_50 = 0; private static final int LOG_VALUE_RESIZE_DOCKED_SMALLER = 1; private static final int LOG_VALUE_RESIZE_DOCKED_LARGER = 2; @@ -88,7 +92,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, private static final int LOG_VALUE_UNDOCK_MAX_DOCKED = 0; private static final int LOG_VALUE_UNDOCK_MAX_OTHER = 1; - private static final int TASK_POSITION_SAME = Integer.MAX_VALUE; private static final boolean SWAPPING_ENABLED = false; @@ -997,6 +1000,24 @@ public class DividerView extends FrameLayout implements OnTouchListener, mBackground.getRight(), mBackground.getBottom(), Op.UNION); } + /** + * Checks whether recents will grow when invoked. This happens in multi-window when recents is + * very small. When invoking recents, we shrink the docked stack so recents has more space. + * + * @return the position of the divider when recents grows, or + * {@link #INVALID_RECENTS_GROW_TARGET} if recents won't grow + */ + public int growsRecents() { + boolean result = mGrowRecents + && mWindowManagerProxy.getDockSide() == WindowManager.DOCKED_TOP + && getCurrentPosition() == getSnapAlgorithm().getLastSplitTarget().position; + if (result) { + return getSnapAlgorithm().getMiddleTarget().position; + } else { + return INVALID_RECENTS_GROW_TARGET; + } + } + public final void onBusEvent(RecentsActivityStartingEvent recentsActivityStartingEvent) { if (mGrowRecents && getWindowManagerProxy().getDockSide() == WindowManager.DOCKED_TOP && getCurrentPosition() == getSnapAlgorithm().getLastSplitTarget().position) { @@ -1036,7 +1057,8 @@ public class DividerView extends FrameLayout implements OnTouchListener, if (mGrowAfterRecentsDrawn) { mGrowAfterRecentsDrawn = false; updateDockSide(); - stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 250, + EventBus.getDefault().send(new RecentsGrowingEvent()); + stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 336, Interpolators.FAST_OUT_SLOW_IN); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 7c6c641cb7c9c..f6f818ba3cc31 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -1318,7 +1318,7 @@ public abstract class BaseStatusBar extends SystemUI implements protected void showRecents(boolean triggeredFromAltTab, boolean fromHome) { if (mRecents != null) { sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS); - mRecents.showRecents(triggeredFromAltTab, fromHome, getStatusBarView()); + mRecents.showRecents(triggeredFromAltTab, fromHome); } } @@ -1330,7 +1330,7 @@ public abstract class BaseStatusBar extends SystemUI implements protected void toggleRecents() { if (mRecents != null) { - mRecents.toggleRecents(mDisplay, mLayoutDirection, getStatusBarView()); + mRecents.toggleRecents(mDisplay); } } diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 1f76f318b251a..369179ea456a6 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1352,7 +1352,7 @@ class WindowStateAnimator { final Task task = w.getTask(); // We got resized, so block all updates until we got the new surface. - if (w.mResizedWhileNotDragResizing) { + if (w.mResizedWhileNotDragResizing && !w.isGoneForLayoutLw()) { return; }