OSDN Git Service

Fix issue with wrong user task being resolved
authorWinson Chung <winsonc@google.com>
Fri, 17 May 2019 00:36:05 +0000 (17:36 -0700)
committerWinson Chung <winsonc@google.com>
Sat, 18 May 2019 14:25:10 +0000 (14:25 +0000)
- 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

services/core/java/com/android/server/wm/RecentsAnimation.java
services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java

index f82fdba..c5b2566 100644 (file)
@@ -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;
     }
 }
index 8b2912c..8f41a42 100644 (file)
 
 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 */);
     }