Merge changes from topic "fw_quickstep_update" into pi-dev
* changes: Reparent recents animation task leash to app animation layer Allow recents animation to override divider minimized state Prevent unnecessary reordering of the home stack
This commit is contained in:
committed by
Android (Google) Code Review
commit
5fa07c0986
@@ -20,7 +20,7 @@ Landroid/app/AppOpsManager$PackageOps;->getOps()Ljava/util/List;
|
||||
Landroid/app/AppOpsManager$PackageOps;->getPackageName()Ljava/lang/String;
|
||||
Landroid/app/AppOpsManager$PackageOps;->getUid()I
|
||||
Landroid/app/IActivityController$Stub;-><init>()V
|
||||
Landroid/app/IActivityManager;->cancelRecentsAnimation()V
|
||||
Landroid/app/IActivityManager;->cancelRecentsAnimation(Z)V
|
||||
Landroid/app/IActivityManager;->cancelTaskWindowTransition(I)V
|
||||
Landroid/app/IActivityManager;->closeSystemDialogs(Ljava/lang/String;)V
|
||||
Landroid/app/IActivityManager;->getCurrentUser()Landroid/content/pm/UserInfo;
|
||||
|
||||
@@ -450,7 +450,7 @@ interface IActivityManager {
|
||||
in Intent intent, in String resolvedType, in Bundle options, int userId);
|
||||
void startRecentsActivity(in Intent intent, in IAssistDataReceiver assistDataReceiver,
|
||||
in IRecentsAnimationRunner recentsAnimationRunner);
|
||||
void cancelRecentsAnimation();
|
||||
void cancelRecentsAnimation(boolean restoreHomeStackPosition);
|
||||
int startActivityFromRecents(int taskId, in Bundle options);
|
||||
Bundle getActivityOptions(in IBinder token);
|
||||
List<IBinder> getAppTasks(in String callingPackage);
|
||||
|
||||
@@ -59,4 +59,9 @@ interface IRecentsAnimationController {
|
||||
* taken.
|
||||
*/
|
||||
void setAnimationTargetsBehindSystemBars(boolean behindSystemBars);
|
||||
|
||||
/**
|
||||
* Informs the system that the primary split-screen stack should be minimized.
|
||||
*/
|
||||
void setSplitScreenMinimized(boolean minimized);
|
||||
}
|
||||
|
||||
@@ -258,9 +258,9 @@ public class ActivityManagerWrapper {
|
||||
/**
|
||||
* Cancels the remote recents animation started from {@link #startRecentsActivity}.
|
||||
*/
|
||||
public void cancelRecentsAnimation() {
|
||||
public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
|
||||
try {
|
||||
ActivityManager.getService().cancelRecentsAnimation();
|
||||
ActivityManager.getService().cancelRecentsAnimation(restoreHomeStackPosition);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to cancel recents animation", e);
|
||||
}
|
||||
|
||||
@@ -61,6 +61,14 @@ public class RecentsAnimationControllerCompat {
|
||||
}
|
||||
}
|
||||
|
||||
public void setSplitScreenMinimized(boolean minimized) {
|
||||
try {
|
||||
mAnimationController.setSplitScreenMinimized(minimized);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to set minimize dock", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void finish(boolean toHome) {
|
||||
try {
|
||||
mAnimationController.finish(toHome);
|
||||
|
||||
@@ -52,6 +52,7 @@ import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider.ButtonI
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.statusbar.VibratorHelper;
|
||||
|
||||
import static android.view.KeyEvent.KEYCODE_HOME;
|
||||
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
|
||||
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
|
||||
|
||||
@@ -270,8 +271,12 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
|
||||
if (mCode != 0) {
|
||||
if (doIt) {
|
||||
// If there was a pending remote recents animation, then we need to
|
||||
// cancel the animation now before we handle the button itself
|
||||
ActivityManagerWrapper.getInstance().cancelRecentsAnimation();
|
||||
// cancel the animation now before we handle the button itself. In the case
|
||||
// where we are going home and the recents animation has already started,
|
||||
// just cancel the recents animation, leaving the home stack in place
|
||||
boolean isHomeKey = mCode == KEYCODE_HOME;
|
||||
ActivityManagerWrapper.getInstance().cancelRecentsAnimation(!isHomeKey);
|
||||
|
||||
sendEvent(KeyEvent.ACTION_UP, 0);
|
||||
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
|
||||
} else {
|
||||
|
||||
@@ -204,6 +204,8 @@ import static android.view.WindowManager.TRANSIT_NONE;
|
||||
import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
|
||||
import static android.view.WindowManager.TRANSIT_TASK_OPEN;
|
||||
import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_ORIGINAL_POSITION;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_HOME_IN_PLACE;
|
||||
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
|
||||
import static org.xmlpull.v1.XmlPullParser.START_TAG;
|
||||
|
||||
@@ -257,7 +259,6 @@ import android.app.WaitResult;
|
||||
import android.app.WindowConfiguration.ActivityType;
|
||||
import android.app.WindowConfiguration.WindowingMode;
|
||||
import android.app.admin.DevicePolicyCache;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.assist.AssistContent;
|
||||
import android.app.assist.AssistStructure;
|
||||
import android.app.backup.IBackupManager;
|
||||
@@ -5238,12 +5239,14 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelRecentsAnimation() {
|
||||
public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
|
||||
enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (this) {
|
||||
mWindowManager.cancelRecentsAnimation();
|
||||
mWindowManager.cancelRecentsAnimation(restoreHomeStackPosition
|
||||
? REORDER_MOVE_HOME_TO_ORIGINAL_POSITION
|
||||
: REORDER_KEEP_HOME_IN_PLACE);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
|
||||
@@ -23,6 +23,8 @@ import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
|
||||
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
|
||||
import static android.view.WindowManager.TRANSIT_NONE;
|
||||
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_ORIGINAL_POSITION;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_TOP;
|
||||
|
||||
import android.app.ActivityOptions;
|
||||
import android.content.ComponentName;
|
||||
@@ -32,6 +34,7 @@ import android.os.RemoteException;
|
||||
import android.os.Trace;
|
||||
import android.util.Slog;
|
||||
import android.view.IRecentsAnimationRunner;
|
||||
import com.android.server.wm.RecentsAnimationController;
|
||||
import com.android.server.wm.RecentsAnimationController.RecentsAnimationCallbacks;
|
||||
import com.android.server.wm.WindowManagerService;
|
||||
|
||||
@@ -123,7 +126,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
|
||||
|
||||
// Fetch all the surface controls and pass them to the client to get the animation
|
||||
// started
|
||||
mWindowManager.cancelRecentsAnimation();
|
||||
mWindowManager.cancelRecentsAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
mWindowManager.initializeRecentsAnimation(recentsAnimationRunner, this,
|
||||
display.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds());
|
||||
|
||||
@@ -140,7 +143,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationFinished(boolean moveHomeToTop) {
|
||||
public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode) {
|
||||
synchronized (mService) {
|
||||
if (mWindowManager.getRecentsAnimationController() == null) return;
|
||||
|
||||
@@ -151,9 +154,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
|
||||
"RecentsAnimation#onAnimationFinished_inSurfaceTransaction");
|
||||
mWindowManager.deferSurfaceLayout();
|
||||
try {
|
||||
mWindowManager.cleanupRecentsAnimation(moveHomeToTop);
|
||||
mWindowManager.cleanupRecentsAnimation(reorderMode);
|
||||
|
||||
// Move the home stack to the front
|
||||
final ActivityRecord homeActivity = mStackSupervisor.getHomeActivity();
|
||||
if (homeActivity == null) {
|
||||
return;
|
||||
@@ -162,15 +164,19 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
|
||||
// Restore the launched-behind state
|
||||
homeActivity.mLaunchTaskBehind = false;
|
||||
|
||||
if (moveHomeToTop) {
|
||||
if (reorderMode == REORDER_MOVE_HOME_TO_TOP) {
|
||||
// Bring the home stack to the front
|
||||
final ActivityStack homeStack = homeActivity.getStack();
|
||||
mStackSupervisor.mNoAnimActivities.add(homeActivity);
|
||||
homeStack.moveToFront("RecentsAnimation.onAnimationFinished()");
|
||||
} else {
|
||||
} else if (reorderMode == REORDER_MOVE_HOME_TO_ORIGINAL_POSITION){
|
||||
// Restore the home stack to its previous position
|
||||
final ActivityDisplay display = homeActivity.getDisplay();
|
||||
display.moveHomeStackBehindStack(mRestoreHomeBehindStack);
|
||||
} else {
|
||||
// Keep home stack in place, nothing changes, so ignore the transition logic
|
||||
// below
|
||||
return;
|
||||
}
|
||||
|
||||
mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
|
||||
@@ -180,6 +186,11 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
|
||||
// No reason to wait for the pausing activity in this case, as the hiding of
|
||||
// surfaces needs to be done immediately.
|
||||
mWindowManager.executeAppTransition();
|
||||
|
||||
// After reordering the stacks, reset the minimized state. At this point, either
|
||||
// home is now top-most and we will stay minimized (if in split-screen), or we
|
||||
// will have returned to the app, and the minimized state should be reset
|
||||
mWindowManager.checkSplitScreenMinimizedChanged(true /* animate */);
|
||||
} finally {
|
||||
mWindowManager.continueSurfaceLayout();
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
|
||||
@@ -161,7 +161,10 @@ public class BoundsAnimationController {
|
||||
|
||||
// Timeout callback to ensure we continue the animation if waiting for resuming or app
|
||||
// windows drawn fails
|
||||
private final Runnable mResumeRunnable = () -> resume();
|
||||
private final Runnable mResumeRunnable = () -> {
|
||||
if (DEBUG) Slog.d(TAG, "pause: timed out waiting for windows drawn");
|
||||
resume();
|
||||
};
|
||||
|
||||
BoundsAnimator(BoundsAnimationTarget target, Rect from, Rect to,
|
||||
@SchedulePipModeChangedState int schedulePipModeChangedState,
|
||||
@@ -213,7 +216,7 @@ public class BoundsAnimationController {
|
||||
|
||||
// When starting an animation from fullscreen, pause here and wait for the
|
||||
// windows-drawn signal before we start the rest of the transition down into PiP.
|
||||
if (mMoveFromFullscreen) {
|
||||
if (mMoveFromFullscreen && mTarget.shouldDeferStartOnMoveToFullscreen()) {
|
||||
pause();
|
||||
}
|
||||
} else if (mPrevSchedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_END &&
|
||||
|
||||
@@ -33,6 +33,12 @@ interface BoundsAnimationTarget {
|
||||
*/
|
||||
void onAnimationStart(boolean schedulePipModeChangedCallback, boolean forceUpdate);
|
||||
|
||||
/**
|
||||
* @return Whether the animation should be paused waiting for the windows to draw before
|
||||
* entering PiP.
|
||||
*/
|
||||
boolean shouldDeferStartOnMoveToFullscreen();
|
||||
|
||||
/**
|
||||
* Sets the size of the target (without any intermediate steps, like scheduling animation)
|
||||
* but freezes the bounds of any tasks in the target at taskBounds, to allow for more
|
||||
|
||||
@@ -3568,7 +3568,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
if (s.inSplitScreenWindowingMode() && mSplitScreenDividerAnchor != null) {
|
||||
t.setLayer(mSplitScreenDividerAnchor, layer++);
|
||||
}
|
||||
if (s.isAppAnimating() && state != ALWAYS_ON_TOP_STATE) {
|
||||
if ((s.isTaskAnimating() || s.isAppAnimating())
|
||||
&& state != ALWAYS_ON_TOP_STATE) {
|
||||
// Ensure the animation layer ends up above the
|
||||
// highest animating stack and no higher.
|
||||
layerForAnimationLayer = layer++;
|
||||
|
||||
@@ -666,13 +666,16 @@ public class DockedStackDividerController {
|
||||
}
|
||||
final TaskStack topSecondaryStack = mDisplayContent.getTopStackInWindowingMode(
|
||||
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
|
||||
final RecentsAnimationController recentsAnim = mService.getRecentsAnimationController();
|
||||
final boolean minimizedForRecentsAnimation = recentsAnim != null &&
|
||||
recentsAnim.isSplitScreenMinimized();
|
||||
boolean homeVisible = homeTask.getTopVisibleAppToken() != null;
|
||||
if (homeVisible && topSecondaryStack != null) {
|
||||
// Home should only be considered visible if it is greater or equal to the top secondary
|
||||
// stack in terms of z-order.
|
||||
homeVisible = homeStack.compareTo(topSecondaryStack) >= 0;
|
||||
}
|
||||
setMinimizedDockedStack(homeVisible, animate);
|
||||
setMinimizedDockedStack(homeVisible || minimizedForRecentsAnimation, animate);
|
||||
}
|
||||
|
||||
private boolean isWithinDisplay(Task task) {
|
||||
|
||||
@@ -29,6 +29,7 @@ import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION
|
||||
import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
|
||||
import static com.android.server.wm.AnimationAdapterProto.REMOTE;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.app.ActivityManager.TaskSnapshot;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.graphics.Point;
|
||||
@@ -67,12 +68,25 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
private static final boolean DEBUG = false;
|
||||
private static final long FAILSAFE_DELAY = 1000;
|
||||
|
||||
public static final int REORDER_KEEP_HOME_IN_PLACE = 0;
|
||||
public static final int REORDER_MOVE_HOME_TO_TOP = 1;
|
||||
public static final int REORDER_MOVE_HOME_TO_ORIGINAL_POSITION = 2;
|
||||
|
||||
@IntDef(prefix = { "REORDER_MODE_" }, value = {
|
||||
REORDER_KEEP_HOME_IN_PLACE,
|
||||
REORDER_MOVE_HOME_TO_TOP,
|
||||
REORDER_MOVE_HOME_TO_ORIGINAL_POSITION
|
||||
})
|
||||
public @interface ReorderMode {}
|
||||
|
||||
private final WindowManagerService mService;
|
||||
private final IRecentsAnimationRunner mRunner;
|
||||
private final RecentsAnimationCallbacks mCallbacks;
|
||||
private final ArrayList<TaskAnimationAdapter> mPendingAnimations = new ArrayList<>();
|
||||
private final int mDisplayId;
|
||||
private final Runnable mFailsafeRunnable = this::cancelAnimation;
|
||||
private final Runnable mFailsafeRunnable = () -> {
|
||||
cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
};
|
||||
|
||||
// The recents component app token that is shown behind the visibile tasks
|
||||
private AppWindowToken mHomeAppToken;
|
||||
@@ -84,16 +98,20 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
private boolean mPendingStart = true;
|
||||
|
||||
// Set when the animation has been canceled
|
||||
private boolean mCanceled = false;
|
||||
private boolean mCanceled;
|
||||
|
||||
// Whether or not the input consumer is enabled. The input consumer must be both registered and
|
||||
// enabled for it to start intercepting touch events.
|
||||
private boolean mInputConsumerEnabled;
|
||||
|
||||
// Whether or not the recents animation should cause the primary split-screen stack to be
|
||||
// minimized
|
||||
private boolean mSplitScreenMinimized;
|
||||
|
||||
private Rect mTmpRect = new Rect();
|
||||
|
||||
public interface RecentsAnimationCallbacks {
|
||||
void onAnimationFinished(boolean moveHomeToTop);
|
||||
void onAnimationFinished(@ReorderMode int reorderMode);
|
||||
}
|
||||
|
||||
private final IRecentsAnimationController mController =
|
||||
@@ -102,7 +120,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
@Override
|
||||
public TaskSnapshot screenshotTask(int taskId) {
|
||||
if (DEBUG) Log.d(TAG, "screenshotTask(" + taskId + "): mCanceled=" + mCanceled);
|
||||
long token = Binder.clearCallingIdentity();
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mService.getWindowManagerLock()) {
|
||||
if (mCanceled) {
|
||||
@@ -131,7 +149,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
@Override
|
||||
public void finish(boolean moveHomeToTop) {
|
||||
if (DEBUG) Log.d(TAG, "finish(" + moveHomeToTop + "): mCanceled=" + mCanceled);
|
||||
long token = Binder.clearCallingIdentity();
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mService.getWindowManagerLock()) {
|
||||
if (mCanceled) {
|
||||
@@ -141,7 +159,9 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
|
||||
// Note, the callback will handle its own synchronization, do not lock on WM lock
|
||||
// prior to calling the callback
|
||||
mCallbacks.onAnimationFinished(moveHomeToTop);
|
||||
mCallbacks.onAnimationFinished(moveHomeToTop
|
||||
? REORDER_MOVE_HOME_TO_TOP
|
||||
: REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
@@ -150,7 +170,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
@Override
|
||||
public void setAnimationTargetsBehindSystemBars(boolean behindSystemBars)
|
||||
throws RemoteException {
|
||||
long token = Binder.clearCallingIdentity();
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mService.getWindowManagerLock()) {
|
||||
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
|
||||
@@ -167,7 +187,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
public void setInputConsumerEnabled(boolean enabled) {
|
||||
if (DEBUG) Log.d(TAG, "setInputConsumerEnabled(" + enabled + "): mCanceled="
|
||||
+ mCanceled);
|
||||
long token = Binder.clearCallingIdentity();
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mService.getWindowManagerLock()) {
|
||||
if (mCanceled) {
|
||||
@@ -182,6 +202,23 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSplitScreenMinimized(boolean minimized) {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mService.getWindowManagerLock()) {
|
||||
if (mCanceled) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSplitScreenMinimized = minimized;
|
||||
mService.checkSplitScreenMinimizedChanged(true /* animate */);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -222,14 +259,14 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
|
||||
// Skip the animation if there is nothing to animate
|
||||
if (mPendingAnimations.isEmpty()) {
|
||||
cancelAnimation();
|
||||
cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mRunner.asBinder().linkToDeath(this, 0);
|
||||
} catch (RemoteException e) {
|
||||
cancelAnimation();
|
||||
cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -299,7 +336,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
reasons).sendToTarget();
|
||||
}
|
||||
|
||||
void cancelAnimation() {
|
||||
void cancelAnimation(@ReorderMode int reorderMode) {
|
||||
if (DEBUG) Log.d(TAG, "cancelAnimation()");
|
||||
synchronized (mService.getWindowManagerLock()) {
|
||||
if (mCanceled) {
|
||||
@@ -314,18 +351,20 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
Slog.e(TAG, "Failed to cancel recents animation", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up and return to the previous app
|
||||
// Don't hold the WM lock here as it calls back to AM/RecentsAnimation
|
||||
mCallbacks.onAnimationFinished(false /* moveHomeToTop */);
|
||||
mCallbacks.onAnimationFinished(reorderMode);
|
||||
}
|
||||
|
||||
void cleanupAnimation(boolean moveHomeToTop) {
|
||||
void cleanupAnimation(@ReorderMode int reorderMode) {
|
||||
if (DEBUG) Log.d(TAG, "cleanupAnimation(): mPendingAnimations="
|
||||
+ mPendingAnimations.size());
|
||||
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
|
||||
final TaskAnimationAdapter adapter = mPendingAnimations.get(i);
|
||||
adapter.mTask.setCanAffectSystemUiFlags(true);
|
||||
if (moveHomeToTop) {
|
||||
if (reorderMode == REORDER_MOVE_HOME_TO_TOP
|
||||
|| reorderMode == REORDER_KEEP_HOME_IN_PLACE) {
|
||||
adapter.mTask.dontAnimateDimExit();
|
||||
}
|
||||
adapter.mCapturedFinishCallback.onAnimationFinished(adapter);
|
||||
@@ -333,7 +372,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
mPendingAnimations.clear();
|
||||
|
||||
mRunner.asBinder().unlinkToDeath(this, 0);
|
||||
|
||||
// Clear associated input consumers
|
||||
mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
|
||||
mService.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
|
||||
}
|
||||
@@ -344,7 +383,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
|
||||
@Override
|
||||
public void binderDied() {
|
||||
cancelAnimation();
|
||||
cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
}
|
||||
|
||||
void checkAnimationReady(WallpaperController wallpaperController) {
|
||||
@@ -358,6 +397,10 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
}
|
||||
}
|
||||
|
||||
boolean isSplitScreenMinimized() {
|
||||
return mSplitScreenMinimized;
|
||||
}
|
||||
|
||||
boolean isWallpaperVisible(WindowState w) {
|
||||
return w != null && w.mAppToken != null && mHomeAppToken == w.mAppToken
|
||||
&& isHomeAppOverWallpaper();
|
||||
@@ -389,6 +432,15 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
return mHomeAppToken.windowsCanBeWallpaperTarget();
|
||||
}
|
||||
|
||||
boolean isAnimatingTask(Task task) {
|
||||
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
|
||||
if (task == mPendingAnimations.get(i).mTask) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isAnimatingApp(AppWindowToken appToken) {
|
||||
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
|
||||
final Task task = mPendingAnimations.get(i).mTask;
|
||||
@@ -409,18 +461,18 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
private OnAnimationFinishedCallback mCapturedFinishCallback;
|
||||
private final boolean mIsRecentTaskInvisible;
|
||||
private RemoteAnimationTarget mTarget;
|
||||
private final Point mPosition = new Point();
|
||||
private final Rect mBounds = new Rect();
|
||||
|
||||
TaskAnimationAdapter(Task task, boolean isRecentTaskInvisible) {
|
||||
mTask = task;
|
||||
mIsRecentTaskInvisible = isRecentTaskInvisible;
|
||||
final WindowContainer container = mTask.getParent();
|
||||
container.getRelativePosition(mPosition);
|
||||
container.getBounds(mBounds);
|
||||
}
|
||||
|
||||
RemoteAnimationTarget createRemoteAnimationApp() {
|
||||
final Point position = new Point();
|
||||
final Rect bounds = new Rect();
|
||||
final WindowContainer container = mTask.getParent();
|
||||
container.getRelativePosition(position);
|
||||
container.getBounds(bounds);
|
||||
final WindowState mainWindow = mTask.getTopVisibleAppMainWindow();
|
||||
if (mainWindow == null) {
|
||||
return null;
|
||||
@@ -429,7 +481,7 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
InsetUtils.addInsets(insets, mainWindow.mAppToken.getLetterboxInsets());
|
||||
mTarget = new RemoteAnimationTarget(mTask.mTaskId, MODE_CLOSING, mCapturedLeash,
|
||||
!mTask.fillsParent(), mainWindow.mWinAnimator.mLastClipRect,
|
||||
insets, mTask.getPrefixOrderIndex(), position, bounds,
|
||||
insets, mTask.getPrefixOrderIndex(), mPosition, mBounds,
|
||||
mTask.getWindowConfiguration(), mIsRecentTaskInvisible);
|
||||
return mTarget;
|
||||
}
|
||||
@@ -452,13 +504,14 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
@Override
|
||||
public void startAnimation(SurfaceControl animationLeash, Transaction t,
|
||||
OnAnimationFinishedCallback finishCallback) {
|
||||
t.setPosition(animationLeash, mPosition.x, mPosition.y);
|
||||
mCapturedLeash = animationLeash;
|
||||
mCapturedFinishCallback = finishCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancelled(SurfaceControl animationLeash) {
|
||||
cancelAnimation();
|
||||
cancelAnimation(REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -44,6 +44,7 @@ import android.util.Slog;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.Surface;
|
||||
|
||||
import android.view.SurfaceControl;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -559,6 +560,23 @@ class Task extends WindowContainer<AppWindowToken> {
|
||||
&& !mStack.isAnimatingBoundsToFullscreen() && !mPreserveNonFloatingState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceControl getAnimationLeashParent() {
|
||||
// Reparent to the animation layer so that we aren't clipped by the non-minimized
|
||||
// stack bounds, currently we only animate the task for the recents animation
|
||||
return getAppAnimationLayer(false /* boosted */);
|
||||
}
|
||||
|
||||
boolean isTaskAnimating() {
|
||||
final RecentsAnimationController recentsAnim = mService.getRecentsAnimationController();
|
||||
if (recentsAnim != null) {
|
||||
if (recentsAnim.isAnimatingTask(this)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
WindowState getTopVisibleAppMainWindow() {
|
||||
final AppWindowToken token = getTopVisibleAppToken();
|
||||
return token != null ? token.findMainWindow() : null;
|
||||
|
||||
@@ -33,8 +33,6 @@ import static android.view.WindowManager.DOCKED_LEFT;
|
||||
import static android.view.WindowManager.DOCKED_RIGHT;
|
||||
import static android.view.WindowManager.DOCKED_TOP;
|
||||
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
|
||||
import static com.android.server.wm.StackProto.ADJUSTED_BOUNDS;
|
||||
import static com.android.server.wm.StackProto.ADJUSTED_FOR_IME;
|
||||
import static com.android.server.wm.StackProto.ADJUST_DIVIDER_AMOUNT;
|
||||
@@ -47,6 +45,8 @@ import static com.android.server.wm.StackProto.ID;
|
||||
import static com.android.server.wm.StackProto.MINIMIZE_AMOUNT;
|
||||
import static com.android.server.wm.StackProto.TASKS;
|
||||
import static com.android.server.wm.StackProto.WINDOW_CONTAINER;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
|
||||
|
||||
import android.annotation.CallSuper;
|
||||
import android.content.res.Configuration;
|
||||
@@ -62,12 +62,10 @@ import android.util.proto.ProtoOutputStream;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
import com.android.internal.policy.DividerSnapAlgorithm;
|
||||
import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
|
||||
import com.android.internal.policy.DockedDividerUtils;
|
||||
import com.android.server.EventLogTags;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class TaskStack extends WindowContainer<Task> implements
|
||||
@@ -1333,6 +1331,20 @@ public class TaskStack extends WindowContainer<Task> implements
|
||||
return mMinimizeAmount != 0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if we have a {@link Task} that is animating (currently only used for the
|
||||
* recents animation); {@code false} otherwise.
|
||||
*/
|
||||
boolean isTaskAnimating() {
|
||||
for (int j = mChildren.size() - 1; j >= 0; j--) {
|
||||
final Task task = mChildren.get(j);
|
||||
if (task.isTaskAnimating()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
@Override
|
||||
public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
|
||||
@@ -1687,6 +1699,25 @@ public class TaskStack extends WindowContainer<Task> implements
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDeferStartOnMoveToFullscreen() {
|
||||
// Workaround for the recents animation -- normally we need to wait for the new activity to
|
||||
// show before starting the PiP animation, but because we start and show the home activity
|
||||
// early for the recents animation prior to the PiP animation starting, there is no
|
||||
// subsequent all-drawn signal. In this case, we can skip the pause when the home stack is
|
||||
// already visible and drawn.
|
||||
final TaskStack homeStack = mDisplayContent.getHomeStack();
|
||||
if (homeStack == null) {
|
||||
return true;
|
||||
}
|
||||
final Task homeTask = homeStack.getTopChild();
|
||||
final AppWindowToken homeApp = homeTask.getTopVisibleAppToken();
|
||||
if (!homeTask.isVisible() || homeApp == null) {
|
||||
return true;
|
||||
}
|
||||
return !homeApp.allDrawn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if we are currently animating the pinned stack from fullscreen to non-fullscreen
|
||||
* bounds and we have a deferred PiP mode changed callback set with the animation.
|
||||
|
||||
@@ -26,6 +26,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
|
||||
|
||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
||||
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
|
||||
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_HOME_TO_ORIGINAL_POSITION;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
|
||||
@@ -618,7 +619,8 @@ class WallpaperController {
|
||||
|
||||
// If there was a recents animation in progress, cancel that animation
|
||||
if (mService.getRecentsAnimationController() != null) {
|
||||
mService.getRecentsAnimationController().cancelAnimation();
|
||||
mService.getRecentsAnimationController().cancelAnimation(
|
||||
REORDER_MOVE_HOME_TO_ORIGINAL_POSITION);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2687,20 +2687,20 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelRecentsAnimation() {
|
||||
public void cancelRecentsAnimation(@RecentsAnimationController.ReorderMode int reorderMode) {
|
||||
// Note: Do not hold the WM lock, this will lock appropriately in the call which also
|
||||
// calls through to AM/RecentsAnimation.onAnimationFinished()
|
||||
if (mRecentsAnimationController != null) {
|
||||
// This call will call through to cleanupAnimation() below after the animation is
|
||||
// canceled
|
||||
mRecentsAnimationController.cancelAnimation();
|
||||
mRecentsAnimationController.cancelAnimation(reorderMode);
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanupRecentsAnimation(boolean moveHomeToTop) {
|
||||
public void cleanupRecentsAnimation(@RecentsAnimationController.ReorderMode int reorderMode) {
|
||||
synchronized (mWindowMap) {
|
||||
if (mRecentsAnimationController != null) {
|
||||
mRecentsAnimationController.cleanupAnimation(moveHomeToTop);
|
||||
mRecentsAnimationController.cleanupAnimation(reorderMode);
|
||||
mRecentsAnimationController = null;
|
||||
mAppTransition.updateBooster();
|
||||
}
|
||||
|
||||
@@ -649,7 +649,7 @@ public class RecentTasksTest extends ActivityTestsBase {
|
||||
assertSecurityException(expectCallable, () -> mService.cancelTaskWindowTransition(0));
|
||||
assertSecurityException(expectCallable, () -> mService.startRecentsActivity(null, null,
|
||||
null));
|
||||
assertSecurityException(expectCallable, () -> mService.cancelRecentsAnimation());
|
||||
assertSecurityException(expectCallable, () -> mService.cancelRecentsAnimation(true));
|
||||
}
|
||||
|
||||
private void testGetTasksApis(boolean expectCallable) {
|
||||
|
||||
@@ -158,6 +158,11 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
||||
mForcePipModeChangedCallback = forceUpdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDeferStartOnMoveToFullscreen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setPinnedStackSize(Rect stackBounds, Rect taskBounds) {
|
||||
// TODO: Once we break the runs apart, we should fail() here if this is called outside
|
||||
|
||||
Reference in New Issue
Block a user