Merge "Simplify the association of shared starting window" into tm-qpr-dev am: bf4367fd84

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20270816

Change-Id: I92a65ea5688963c86456f08d38bedbe9a8537f87
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Riddle Hsu
2022-11-03 01:28:25 +00:00
committed by Automerger Merge Worker
10 changed files with 55 additions and 62 deletions

View File

@@ -812,7 +812,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
StartingData mStartingData;
WindowState mStartingWindow;
StartingSurfaceController.StartingSurface mStartingSurface;
boolean startingDisplayed;
boolean startingMoved;
/** The last set {@link DropInputMode} for this activity surface. */
@@ -821,13 +820,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
/** Whether the input to this activity will be dropped during the current playing animation. */
private boolean mIsInputDroppedForAnimation;
/**
* If it is non-null, it requires all activities who have the same starting data to be drawn
* to remove the starting window.
* TODO(b/189385912): Remove starting window related fields after migrating them to task.
*/
private StartingData mSharedStartingData;
boolean mHandleExitSplashScreen;
@TransferSplashScreenState
int mTransferringSplashScreenState = TRANSFER_SPLASH_SCREEN_IDLE;
@@ -1200,14 +1192,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn);
pw.print(" mIsExiting="); pw.println(mIsExiting);
}
if (mSharedStartingData != null) {
pw.println(prefix + "mSharedStartingData=" + mSharedStartingData);
}
if (mStartingWindow != null || mStartingSurface != null
|| startingDisplayed || startingMoved || mVisibleSetFromTransferredStartingWindow) {
if (mStartingWindow != null || mStartingData != null || mStartingSurface != null
|| startingMoved || mVisibleSetFromTransferredStartingWindow) {
pw.print(prefix); pw.print("startingWindow="); pw.print(mStartingWindow);
pw.print(" startingSurface="); pw.print(mStartingSurface);
pw.print(" startingDisplayed="); pw.print(startingDisplayed);
pw.print(" startingDisplayed="); pw.print(isStartingWindowDisplayed());
pw.print(" startingMoved="); pw.print(startingMoved);
pw.println(" mVisibleSetFromTransferredStartingWindow="
+ mVisibleSetFromTransferredStartingWindow);
@@ -2690,13 +2679,23 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
}
boolean isStartingWindowDisplayed() {
final StartingData data = mStartingData != null ? mStartingData : task != null
? task.mSharedStartingData : null;
return data != null && data.mIsDisplayed;
}
/** Called when the starting window is added to this activity. */
void attachStartingWindow(@NonNull WindowState startingWindow) {
startingWindow.mStartingData = mStartingData;
mStartingWindow = startingWindow;
// The snapshot type may have called associateStartingDataWithTask().
if (mStartingData != null && mStartingData.mAssociatedTask != null) {
attachStartingSurfaceToAssociatedTask();
if (mStartingData != null) {
if (mStartingData.mAssociatedTask != null) {
// The snapshot type may have called associateStartingDataWithTask().
attachStartingSurfaceToAssociatedTask();
} else if (isEmbedded()) {
associateStartingWindowWithTaskIfNeeded();
}
}
}
@@ -2711,11 +2710,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
/** Called when the starting window is not added yet but its data is known to fill the task. */
private void associateStartingDataWithTask() {
mStartingData.mAssociatedTask = task;
task.forAllActivities(r -> {
if (r.mVisibleRequested && !r.firstWindowDrawn) {
r.mSharedStartingData = mStartingData;
}
});
task.mSharedStartingData = mStartingData;
}
/** Associates and attaches an added starting window to the current task. */
@@ -2746,10 +2741,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
void removeStartingWindowAnimation(boolean prepareAnimation) {
mTransferringSplashScreenState = TRANSFER_SPLASH_SCREEN_IDLE;
if (mSharedStartingData != null) {
mSharedStartingData.mAssociatedTask.forAllActivities(r -> {
r.mSharedStartingData = null;
});
if (task != null) {
task.mSharedStartingData = null;
}
if (mStartingWindow == null) {
if (mStartingData != null) {
@@ -2772,7 +2765,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mStartingData = null;
mStartingSurface = null;
mStartingWindow = null;
startingDisplayed = false;
if (surface == null) {
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "startingWindow was set but "
+ "startingSurface==null, couldn't remove");
@@ -4257,7 +4249,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
* @return {@code true} if starting window is in app's hierarchy.
*/
boolean hasStartingWindow() {
if (startingDisplayed || mStartingData != null) {
if (mStartingData != null) {
return true;
}
for (int i = mChildren.size() - 1; i >= 0; i--) {
@@ -4355,10 +4347,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Transfer the starting window over to the new token.
mStartingData = fromActivity.mStartingData;
mSharedStartingData = fromActivity.mSharedStartingData;
mStartingSurface = fromActivity.mStartingSurface;
startingDisplayed = fromActivity.startingDisplayed;
fromActivity.startingDisplayed = false;
mStartingWindow = tStartingWindow;
reportedVisible = fromActivity.reportedVisible;
fromActivity.mStartingData = null;
@@ -4424,7 +4413,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
"Moving pending starting from %s to %s", fromActivity, this);
mStartingData = fromActivity.mStartingData;
mSharedStartingData = fromActivity.mSharedStartingData;
fromActivity.mStartingData = null;
fromActivity.startingMoved = true;
scheduleAddStartingWindow();
@@ -6534,14 +6522,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Remove starting window directly if is in a pure task. Otherwise if it is associated with
// a task (e.g. nested task fragment), then remove only if all visible windows in the task
// are drawn.
final Task associatedTask =
mSharedStartingData != null ? mSharedStartingData.mAssociatedTask : null;
final Task associatedTask = task.mSharedStartingData != null ? task : null;
if (associatedTask == null) {
removeStartingWindow();
} else if (associatedTask.getActivity(r -> r.mVisibleRequested && !r.firstWindowDrawn
// Don't block starting window removal if an Activity can't be a starting window
// target.
&& r.mSharedStartingData != null) == null) {
} else if (associatedTask.getActivity(
r -> r.mVisibleRequested && !r.firstWindowDrawn) == null) {
// The last drawn activity may not be the one that owns the starting window.
final ActivityRecord r = associatedTask.topActivityContainsStartingWindow();
if (r != null) {
@@ -6756,7 +6741,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (mLastTransactionSequence != mWmService.mTransactionSequence) {
mLastTransactionSequence = mWmService.mTransactionSequence;
mNumDrawnWindows = 0;
startingDisplayed = false;
// There is the main base application window, even if it is exiting, wait for it
mNumInterestingWindows = findMainWindow(false /* includeStartingApp */) != null ? 1 : 0;
@@ -6800,9 +6784,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
isInterestingAndDrawn = true;
}
}
} else if (w.isDrawn()) {
} else if (mStartingData != null && w.isDrawn()) {
// The starting window for this container is drawn.
startingDisplayed = true;
mStartingData.mIsDisplayed = true;
}
}
@@ -7550,7 +7534,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
ProtoLog.v(WM_DEBUG_ANIM, "Animation done in %s"
+ ": reportedVisible=%b okToDisplay=%b okToAnimate=%b startingDisplayed=%b",
this, reportedVisible, okToDisplay(), okToAnimate(), startingDisplayed);
this, reportedVisible, okToDisplay(), okToAnimate(),
isStartingWindowDisplayed());
// clean up thumbnail window
if (mThumbnail != null) {
@@ -9649,7 +9634,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (mStartingWindow != null) {
mStartingWindow.writeIdentifierToProto(proto, STARTING_WINDOW);
}
proto.write(STARTING_DISPLAYED, startingDisplayed);
proto.write(STARTING_DISPLAYED, isStartingWindowDisplayed());
proto.write(STARTING_MOVED, startingMoved);
proto.write(VISIBLE_SET_FROM_TRANSFERRED_STARTING_WINDOW,
mVisibleSetFromTransferredStartingWindow);

View File

@@ -1229,11 +1229,11 @@ public class AppTransitionController {
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
"Check opening app=%s: allDrawn=%b startingDisplayed=%b "
+ "startingMoved=%b isRelaunching()=%b startingWindow=%s",
activity, activity.allDrawn, activity.startingDisplayed,
activity, activity.allDrawn, activity.isStartingWindowDisplayed(),
activity.startingMoved, activity.isRelaunching(),
activity.mStartingWindow);
final boolean allDrawn = activity.allDrawn && !activity.isRelaunching();
if (!allDrawn && !activity.startingDisplayed && !activity.startingMoved) {
if (!allDrawn && !activity.isStartingWindowDisplayed() && !activity.startingMoved) {
return false;
}
if (allDrawn) {

View File

@@ -38,6 +38,9 @@ public abstract class StartingData {
*/
Task mAssociatedTask;
/** Whether the starting window is drawn. */
boolean mIsDisplayed;
protected StartingData(WindowManagerService service, int typeParams) {
mService = service;
mTypeParams = typeParams;

View File

@@ -358,6 +358,13 @@ class Task extends TaskFragment {
int mLockTaskUid = -1; // The uid of the application that called startLockTask().
/**
* If non-null, the starting window should cover the associated task. It is assigned when the
* parent activity of starting window is put in a partial area of the task. This field will be
* cleared when all visible activities in this task are drawn.
*/
StartingData mSharedStartingData;
/** The process that had previously hosted the root activity of this task.
* Used to know that we should try harder to keep this process around, in case the
* user wants to return to it. */
@@ -3689,6 +3696,9 @@ class Task extends TaskFragment {
if (mRootProcess != null) {
pw.print(prefix); pw.print("mRootProcess="); pw.println(mRootProcess);
}
if (mSharedStartingData != null) {
pw.println(prefix + "mSharedStartingData=" + mSharedStartingData);
}
pw.print(prefix); pw.print("taskId=" + mTaskId);
pw.println(" rootTaskId=" + getRootTaskId());
pw.print(prefix); pw.println("hasChildPipActivity=" + (mChildPipActivity != null));

View File

@@ -1890,10 +1890,10 @@ class TaskFragment extends WindowContainer<WindowContainer> {
RemoteAnimationTarget createRemoteAnimationTarget(
RemoteAnimationController.RemoteAnimationRecord record) {
final ActivityRecord activity = record.getMode() == RemoteAnimationTarget.MODE_OPENING
// There may be a trampoline activity without window on top of the existing task
// which is moving to front. Exclude the finishing activity so the window of next
// activity can be chosen to create the animation target.
? getTopNonFinishingActivity()
// There may be a launching (e.g. trampoline or embedded) activity without a window
// on top of the existing task which is moving to front. Exclude finishing activity
// so the window of next activity can be chosen to create the animation target.
? getActivity(r -> !r.finishing && r.hasChild())
: getTopMostActivity();
return activity != null ? activity.createRemoteAnimationTarget(record) : null;
}

View File

@@ -1842,8 +1842,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
* @return {@code true} if one or more windows have been displayed, else false.
*/
boolean hasAppShownWindows() {
return mActivityRecord != null
&& (mActivityRecord.firstWindowDrawn || mActivityRecord.startingDisplayed);
return mActivityRecord != null && (mActivityRecord.firstWindowDrawn
|| mActivityRecord.isStartingWindowDisplayed());
}
@Override

View File

@@ -374,13 +374,6 @@ class WindowStateAnimator {
}
void destroySurfaceLocked(SurfaceControl.Transaction t) {
final ActivityRecord activity = mWin.mActivityRecord;
if (activity != null) {
if (mWin == activity.mStartingWindow) {
activity.startingDisplayed = false;
}
}
if (mSurfaceController == null) {
return;
}

View File

@@ -2886,6 +2886,7 @@ public class ActivityRecordTests extends WindowTestsBase {
fragmentSetup.accept(taskFragment1, new Rect(0, 0, width / 2, height));
task.addChild(taskFragment1, POSITION_TOP);
assertEquals(task, activity1.mStartingData.mAssociatedTask);
assertEquals(activity1.mStartingData, task.mSharedStartingData);
final TaskFragment taskFragment2 = new TaskFragment(
mAtm, null /* fragmentToken */, false /* createdByOrganizer */);
@@ -2905,7 +2906,6 @@ public class ActivityRecordTests extends WindowTestsBase {
verify(activity1.getSyncTransaction()).reparent(eq(startingWindow.mSurfaceControl),
eq(task.mSurfaceControl));
assertEquals(activity1.mStartingData, startingWindow.mStartingData);
assertEquals(task.mSurfaceControl, startingWindow.getAnimationLeashParent());
assertEquals(taskFragment1.getBounds(), activity1.getBounds());
// The activity was resized by task fragment, but starting window must still cover the task.
@@ -2916,6 +2916,7 @@ public class ActivityRecordTests extends WindowTestsBase {
activity1.onFirstWindowDrawn(activityWindow);
activity2.onFirstWindowDrawn(activityWindow);
assertNull(activity1.mStartingWindow);
assertNull(task.mSharedStartingData);
}
@Test
@@ -2991,10 +2992,10 @@ public class ActivityRecordTests extends WindowTestsBase {
final WindowManager.LayoutParams attrs =
new WindowManager.LayoutParams(TYPE_APPLICATION_STARTING);
final TestWindowState startingWindow = createWindowState(attrs, activity);
activity.startingDisplayed = true;
activity.mStartingData = mock(StartingData.class);
activity.addWindow(startingWindow);
assertTrue("Starting window should be present", activity.hasStartingWindow());
activity.startingDisplayed = false;
activity.mStartingData = null;
assertTrue("Starting window should be present", activity.hasStartingWindow());
activity.removeChild(startingWindow);

View File

@@ -1300,6 +1300,8 @@ public class AppTransitionControllerTest extends WindowTestsBase {
activity.allDrawn = true;
// Skip manipulate the SurfaceControl.
doNothing().when(activity).setDropInputMode(anyInt());
// Assume the activity contains a window.
doReturn(true).when(activity).hasChild();
// Make sure activity can create remote animation target.
doReturn(mock(RemoteAnimationTarget.class)).when(activity).createRemoteAnimationTarget(
any());

View File

@@ -321,7 +321,6 @@ public class AppTransitionTests extends WindowTestsBase {
final ActivityRecord activity2 = createActivityRecord(dc2);
activity1.allDrawn = true;
activity1.startingDisplayed = true;
activity1.startingMoved = true;
// Simulate activity resume / finish flows to prepare app transition & set visibility,