Fixes the animation and state when docking a task by drag
There was 3 issues in this bug. First the wrong stack id was used to defer and continue updating bounds that broke a lot of the animation. This was fixed by using the recents stack id instead of home. Secondly, the wrong transit was passed into AppTransition.java getting the wrong animation for recents to be docked, defering surface layouts ensures that the correct transition is gained in that transaction. Lastly, remove the starting window for the docked-by-drag-from-recents transition because it was causing the window container to freeze its bounds causing clipping issues and 2 flickers (where it appears over the thumbnail) during the animation. Added a TODO to fix it later. Test: go/wm-smoke Bug: 34099271 Change-Id: Iaf0dffe5c2f5108c9946c9ea23c6e3fd6a49c34d
This commit is contained in:
@@ -2364,7 +2364,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
|
||||
}
|
||||
|
||||
void notifyAppTransitionDone() {
|
||||
continueUpdateBounds(HOME_STACK_ID);
|
||||
continueUpdateBounds(RECENTS_STACK_ID);
|
||||
for (int i = mResizingTasksDuringAnimation.size() - 1; i >= 0; i--) {
|
||||
final int taskId = mResizingTasksDuringAnimation.valueAt(i);
|
||||
final TaskRecord task =
|
||||
@@ -5090,73 +5090,79 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
|
||||
+ taskId + " can't be launch in the home/recents stack.");
|
||||
}
|
||||
|
||||
if (launchStackId == DOCKED_STACK_ID) {
|
||||
mWindowManager.setDockedStackCreateState(
|
||||
activityOptions.getDockCreateMode(), null /* initialBounds */);
|
||||
mWindowManager.deferSurfaceLayout();
|
||||
try {
|
||||
if (launchStackId == DOCKED_STACK_ID) {
|
||||
mWindowManager.setDockedStackCreateState(
|
||||
activityOptions.getDockCreateMode(), null /* initialBounds */);
|
||||
|
||||
// Defer updating the stack in which recents is until the app transition is done, to
|
||||
// not run into issues where we still need to draw the task in recents but the
|
||||
// docked stack is already created.
|
||||
deferUpdateBounds(HOME_STACK_ID);
|
||||
mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
|
||||
}
|
||||
|
||||
task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE,
|
||||
launchStackId);
|
||||
if (task == null) {
|
||||
continueUpdateBounds(HOME_STACK_ID);
|
||||
mWindowManager.executeAppTransition();
|
||||
throw new IllegalArgumentException(
|
||||
"startActivityFromRecentsInner: Task " + taskId + " not found.");
|
||||
}
|
||||
|
||||
// Since we don't have an actual source record here, we assume that the currently focused
|
||||
// activity was the source.
|
||||
final ActivityStack focusedStack = getFocusedStack();
|
||||
final ActivityRecord sourceRecord =
|
||||
focusedStack != null ? focusedStack.topActivity() : null;
|
||||
|
||||
if (launchStackId != INVALID_STACK_ID) {
|
||||
if (task.getStackId() != launchStackId) {
|
||||
task.reparent(launchStackId, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, ANIMATE,
|
||||
DEFER_RESUME, "startActivityFromRecents");
|
||||
// Defer updating the stack in which recents is until the app transition is done, to
|
||||
// not run into issues where we still need to draw the task in recents but the
|
||||
// docked stack is already created.
|
||||
deferUpdateBounds(RECENTS_STACK_ID);
|
||||
mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
|
||||
}
|
||||
}
|
||||
|
||||
// If the user must confirm credentials (e.g. when first launching a work app and the
|
||||
// Work Challenge is present) let startActivityInPackage handle the intercepting.
|
||||
if (!mService.mUserController.shouldConfirmCredentials(task.userId)
|
||||
&& task.getRootActivity() != null) {
|
||||
mService.mActivityStarter.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */);
|
||||
mActivityMetricsLogger.notifyActivityLaunching();
|
||||
mService.moveTaskToFrontLocked(task.taskId, 0, bOptions);
|
||||
mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT,
|
||||
task.getTopActivity());
|
||||
task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE,
|
||||
launchStackId);
|
||||
if (task == null) {
|
||||
continueUpdateBounds(RECENTS_STACK_ID);
|
||||
mWindowManager.executeAppTransition();
|
||||
throw new IllegalArgumentException(
|
||||
"startActivityFromRecentsInner: Task " + taskId + " not found.");
|
||||
}
|
||||
|
||||
// If we are launching the task in the docked stack, put it into resizing mode so
|
||||
// the window renders full-screen with the background filling the void. Also only
|
||||
// call this at the end to make sure that tasks exists on the window manager side.
|
||||
// Since we don't have an actual source record here, we assume that the currently
|
||||
// focused activity was the source.
|
||||
final ActivityStack focusedStack = getFocusedStack();
|
||||
final ActivityRecord sourceRecord =
|
||||
focusedStack != null ? focusedStack.topActivity() : null;
|
||||
|
||||
if (launchStackId != INVALID_STACK_ID) {
|
||||
if (task.getStackId() != launchStackId) {
|
||||
task.reparent(launchStackId, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, ANIMATE,
|
||||
DEFER_RESUME, "startActivityFromRecents");
|
||||
}
|
||||
}
|
||||
|
||||
// If the user must confirm credentials (e.g. when first launching a work app and the
|
||||
// Work Challenge is present) let startActivityInPackage handle the intercepting.
|
||||
if (!mService.mUserController.shouldConfirmCredentials(task.userId)
|
||||
&& task.getRootActivity() != null) {
|
||||
mService.mActivityStarter.sendPowerHintForLaunchStartIfNeeded(true /* forceSend */);
|
||||
mActivityMetricsLogger.notifyActivityLaunching();
|
||||
mService.moveTaskToFrontLocked(task.taskId, 0, bOptions);
|
||||
mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT,
|
||||
task.getTopActivity());
|
||||
|
||||
// If we are launching the task in the docked stack, put it into resizing mode so
|
||||
// the window renders full-screen with the background filling the void. Also only
|
||||
// call this at the end to make sure that tasks exists on the window manager side.
|
||||
if (launchStackId == DOCKED_STACK_ID) {
|
||||
setResizingDuringAnimation(task);
|
||||
}
|
||||
|
||||
mService.mActivityStarter.postStartActivityProcessing(task.getTopActivity(),
|
||||
ActivityManager.START_TASK_TO_FRONT,
|
||||
sourceRecord != null
|
||||
? sourceRecord.getTask().getStackId() : INVALID_STACK_ID,
|
||||
sourceRecord, task.getStack());
|
||||
return ActivityManager.START_TASK_TO_FRONT;
|
||||
}
|
||||
callingUid = task.mCallingUid;
|
||||
callingPackage = task.mCallingPackage;
|
||||
intent = task.intent;
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
|
||||
userId = task.userId;
|
||||
int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null,
|
||||
null, null, 0, 0, bOptions, userId, null, task);
|
||||
if (launchStackId == DOCKED_STACK_ID) {
|
||||
setResizingDuringAnimation(task);
|
||||
}
|
||||
|
||||
mService.mActivityStarter.postStartActivityProcessing(task.getTopActivity(),
|
||||
ActivityManager.START_TASK_TO_FRONT,
|
||||
sourceRecord != null ? sourceRecord.getTask().getStackId() : INVALID_STACK_ID,
|
||||
sourceRecord, task.getStack());
|
||||
return ActivityManager.START_TASK_TO_FRONT;
|
||||
return result;
|
||||
} finally {
|
||||
mWindowManager.continueSurfaceLayout();
|
||||
}
|
||||
callingUid = task.mCallingUid;
|
||||
callingPackage = task.mCallingPackage;
|
||||
intent = task.intent;
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
|
||||
userId = task.userId;
|
||||
int result = mService.startActivityInPackage(callingUid, callingPackage, intent, null,
|
||||
null, null, 0, 0, bOptions, userId, null, task);
|
||||
if (launchStackId == DOCKED_STACK_ID) {
|
||||
setResizingDuringAnimation(task);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.android.server.wm;
|
||||
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
|
||||
|
||||
import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS;
|
||||
import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
|
||||
@@ -581,8 +583,12 @@ public class AppWindowContainerController
|
||||
|
||||
private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning,
|
||||
boolean allowTaskSnapshot, boolean activityCreated) {
|
||||
if (newTask || !processRunning
|
||||
|| (taskSwitch && !activityCreated)) {
|
||||
if (mService.mAppTransition.getAppTransition() == TRANSIT_DOCK_TASK_FROM_RECENTS) {
|
||||
// TODO(b/34099271): Remove this statement to add back the starting window and figure
|
||||
// out why it causes flickering, the starting window appears over the thumbnail while
|
||||
// the docked from recents transition occurs
|
||||
return STARTING_WINDOW_TYPE_NONE;
|
||||
} else if (newTask || !processRunning || (taskSwitch && !activityCreated)) {
|
||||
return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
|
||||
} else if (taskSwitch && allowTaskSnapshot) {
|
||||
return STARTING_WINDOW_TYPE_SNAPSHOT;
|
||||
|
||||
Reference in New Issue
Block a user