Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2bc60c04 authored by Winson Chung's avatar Winson Chung
Browse files

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
parent d76c0d75
Loading
Loading
Loading
Loading
+11 −9
Original line number Diff line number Diff line
@@ -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;
    }
}
+35 −0
Original line number Diff line number Diff line
@@ -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 */);
    }