From 2bc60c047734d3ec61ff847922ceb0c3bfdee235 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Thu, 16 May 2019 17:36:05 -0700 Subject: [PATCH] Fix issue with wrong user task being resolved - Setup wizard used to finish itself and start home automatically, but now we have the Tips app show afterwards which requires the user to swipe up to go home as a part of learning the gesture. Previously that would have created the home task for the secondary user and subsequent swipes would work, but in the new flow, the creation of the secondary user home task would never happen because the recents animation logic tries to find the primary user's home task. This is only an issue on the first launch for the secondary user, subsequent launches after completing SUW will start home as a part of switching users. This change ensures that we account for the user when trying to resolve an existing target activity. Bug: 132410734 Test: atest RecentsAnimationTest Change-Id: If14ad535948c5aadd83af528592b320dba62c40e --- .../com/android/server/wm/RecentsAnimation.java | 20 +++++++------ .../android/server/wm/RecentsAnimationTest.java | 35 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java index f82fdba97766..c5b25664f762 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimation.java +++ b/services/core/java/com/android/server/wm/RecentsAnimation.java @@ -100,13 +100,15 @@ class RecentsAnimation implements RecentsAnimationCallbacks, } // If the activity is associated with the recents stack, then try and get that first + final int userId = mService.getCurrentUserId(); mTargetActivityType = intent.getComponent() != null && recentsComponent.equals(intent.getComponent()) ? ACTIVITY_TYPE_RECENTS : ACTIVITY_TYPE_HOME; ActivityStack targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED, mTargetActivityType); - ActivityRecord targetActivity = getTargetActivity(targetStack, intent.getComponent()); + ActivityRecord targetActivity = getTargetActivity(targetStack, intent.getComponent(), + userId); final boolean hasExistingActivity = targetActivity != null; if (hasExistingActivity) { final ActivityDisplay display = targetActivity.getDisplay(); @@ -156,13 +158,13 @@ class RecentsAnimation implements RecentsAnimationCallbacks, .setCallingUid(recentsUid) .setCallingPackage(recentsComponent.getPackageName()) .setActivityOptions(SafeActivityOptions.fromBundle(options.toBundle())) - .setMayWait(mService.getCurrentUserId()) + .setMayWait(userId) .execute(); // Move the recents activity into place for the animation - targetActivity = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED, - mTargetActivityType).getTopActivity(); - targetStack = targetActivity.getActivityStack(); + targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED, + mTargetActivityType); + targetActivity = getTargetActivity(targetStack, intent.getComponent(), userId); mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack); if (DEBUG) { Slog.d(TAG, "Moved stack=" + targetStack + " behind stack=" @@ -172,7 +174,6 @@ class RecentsAnimation implements RecentsAnimationCallbacks, mWindowManager.prepareAppTransition(TRANSIT_NONE, false); mWindowManager.executeAppTransition(); - // TODO: Maybe wait for app to draw in this particular case? if (DEBUG) Slog.d(TAG, "Started intent=" + intent); @@ -406,17 +407,18 @@ class RecentsAnimation implements RecentsAnimationCallbacks, * @return the top activity in the {@param targetStack} matching the {@param component}, or just * the top activity of the top task if no task matches the component. */ - private ActivityRecord getTargetActivity(ActivityStack targetStack, ComponentName component) { + private ActivityRecord getTargetActivity(ActivityStack targetStack, ComponentName component, + int userId) { if (targetStack == null) { return null; } for (int i = targetStack.getChildCount() - 1; i >= 0; i--) { final TaskRecord task = targetStack.getChildAt(i); - if (task.getBaseIntent().getComponent().equals(component)) { + if (task.userId == userId && task.getBaseIntent().getComponent().equals(component)) { return task.getTopActivity(); } } - return targetStack.getTopActivity(); + return null; } } diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java index 8b2912cc1931..8f41a42bde38 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java @@ -16,9 +16,11 @@ package com.android.server.wm; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod; @@ -56,6 +58,8 @@ import org.junit.Test; @Presubmit public class RecentsAnimationTest extends ActivityTestsBase { + private static final int TEST_USER_ID = 100; + private final ComponentName mRecentsComponent = new ComponentName(mContext.getPackageName(), "RecentsActivity"); private RecentsAnimationController mRecentsAnimationController; @@ -223,6 +227,37 @@ public class RecentsAnimationTest extends ActivityTestsBase { verify(mRecentsAnimationController, times(0)).cancelOnNextTransitionStart(); } + @Test + public void testMultipleUserHomeActivity_findUserHomeTask() { + ActivityDisplay display = mService.mRootActivityContainer.getDefaultDisplay(); + ActivityStack homeStack = display.getStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME); + ActivityRecord otherUserHomeActivity = new ActivityBuilder(mService) + .setStack(homeStack) + .setCreateTask(true) + .setComponent(new ComponentName(mContext.getPackageName(), "Home2")) + .build(); + otherUserHomeActivity.getTaskRecord().userId = TEST_USER_ID; + + ActivityStack fullscreenStack = display.createStack(WINDOWING_MODE_FULLSCREEN, + ACTIVITY_TYPE_STANDARD, true /* onTop */); + new ActivityBuilder(mService) + .setComponent(new ComponentName(mContext.getPackageName(), "App1")) + .setCreateTask(true) + .setStack(fullscreenStack) + .build(); + + doReturn(TEST_USER_ID).when(mService).getCurrentUserId(); + doCallRealMethod().when(mRootActivityContainer).ensureActivitiesVisible( + any() /* starting */, anyInt() /* configChanges */, + anyBoolean() /* preserveWindows */); + + startRecentsActivity(otherUserHomeActivity.getTaskRecord().getBaseIntent().getComponent(), + true); + + // Ensure we find the task for the right user and it is made visible + assertTrue(otherUserHomeActivity.visible); + } + private void startRecentsActivity() { startRecentsActivity(mRecentsComponent, false /* getRecentsAnimation */); } -- 2.11.0