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

Commit aba16a14 authored by Bryce Lee's avatar Bryce Lee Committed by android-build-merger
Browse files

Merge "Consider lock state when determining next activity to become visible."...

Merge "Consider lock state when determining next activity to become visible." into pi-dev am: 00f4a4bc
am: dcae0222

Change-Id: Ida7eae9c7d5b63e94ca2c3e0b48b5eef2f96bdb1
parents c1970b1d dcae0222
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -3802,7 +3802,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        // and the resumed activity is not yet visible, then hold off on
        // and the resumed activity is not yet visible, then hold off on
        // finishing until the resumed one becomes visible.
        // finishing until the resumed one becomes visible.


        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
        // The activity that we are finishing may be over the lock screen. In this case, we do not
        // want to consider activities that cannot be shown on the lock screen as running and should
        // proceed with finishing the activity if there is no valid next top running activity.
        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked(
                true /* considerKeyguardState */);


        if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
        if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
                && next != null && !next.nowVisible) {
                && next != null && !next.nowVisible) {
+37 −8
Original line number Original line Diff line number Diff line
@@ -1210,6 +1210,18 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
    }
    }


    ActivityRecord topRunningActivityLocked() {
    ActivityRecord topRunningActivityLocked() {
        return topRunningActivityLocked(false /* considerKeyguardState */);
    }

    /**
     * Returns the top running activity in the focused stack. In the case the focused stack has no
     * such activity, the next focusable stack on top of a display is returned.
     * @param considerKeyguardState Indicates whether the locked state should be considered. if
     *                            {@code true} and the keyguard is locked, only activities that
     *                            can be shown on top of the keyguard will be considered.
     * @return The top running activity. {@code null} if none is available.
     */
    ActivityRecord topRunningActivityLocked(boolean considerKeyguardState) {
        final ActivityStack focusedStack = mFocusedStack;
        final ActivityStack focusedStack = mFocusedStack;
        ActivityRecord r = focusedStack.topRunningActivityLocked();
        ActivityRecord r = focusedStack.topRunningActivityLocked();
        if (r != null) {
        if (r != null) {
@@ -1228,16 +1240,33 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            if (display == null) {
            if (display == null) {
                continue;
                continue;
            }
            }
            for (int j = display.getChildCount() - 1; j >= 0; --j) {

                final ActivityStack stack = display.getChildAt(j);
            // TODO: We probably want to consider the top fullscreen stack as we could have a pinned
                if (stack != focusedStack && stack.isTopStackOnDisplay() && stack.isFocusable()) {
            // stack on top.
                    r = stack.topRunningActivityLocked();
            final ActivityStack topStack = display.getTopStack();
                    if (r != null) {

                        return r;
            // Only consider focusable top stacks other than the current focused one.
            if (topStack == null || !topStack.isFocusable() || topStack == focusedStack) {
                continue;
            }
            }

            final ActivityRecord topActivity = topStack.topRunningActivityLocked();

            // Skip if no top activity.
            if (topActivity == null) {
                continue;
            }
            }

            final boolean keyguardLocked = getKeyguardController().isKeyguardLocked();

            // This activity can be considered the top running activity if we are not
            // considering the locked state, the keyguard isn't locked, or we can show when
            // locked.
            if (!considerKeyguardState || !keyguardLocked || topActivity.canShowWhenLocked()) {
                return topActivity;
            }
            }
        }
        }

        return null;
        return null;
    }
    }


+49 −0
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;


import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNull;
@@ -329,4 +330,52 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
                REMOVE_TASK_MODE_DESTROYING);
                REMOVE_TASK_MODE_DESTROYING);
        assertFalse(pinnedStack.isFocusable());
        assertFalse(pinnedStack.isFocusable());
    }
    }

    /**
     * Verifies the correct activity is returned when querying the top running activity with an
     * empty focused stack.
     */
    @Test
    public void testNonFocusedTopRunningActivity() throws Exception {
        // Create stack to hold focus
        final ActivityStack focusedStack = mService.mStackSupervisor.getDefaultDisplay()
                .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);

        final KeyguardController keyguard = mSupervisor.getKeyguardController();
        final ActivityStack stack = mService.mStackSupervisor.getDefaultDisplay().createStack(
                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
        final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
                .setStack(stack).build();

        mSupervisor.mFocusedStack = focusedStack;

        doAnswer((InvocationOnMock invocationOnMock) -> {
            final SparseIntArray displayIds = invocationOnMock.<SparseIntArray>getArgument(0);
            displayIds.put(0, mSupervisor.getDefaultDisplay().mDisplayId);
            return null;
        }).when(mSupervisor.mWindowManager).getDisplaysInFocusOrder(any());

        // Make sure the top running activity is not affected when keyguard is not locked
        assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
        assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked(
                true /* considerKeyguardState */));

        // Check to make sure activity not reported when it cannot show on lock and lock is on.
        doReturn(true).when(keyguard).isKeyguardLocked();
        assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
        assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked(
                true /* considerKeyguardState */));

        // Add activity that should be shown on the keyguard.
        final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mService)
                .setCreateTask(true)
                .setStack(stack)
                .setActivityFlags(FLAG_SHOW_WHEN_LOCKED)
                .build();

        // Ensure the show when locked activity is returned.
        assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked());
        assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked(
                true /* considerKeyguardState */));
    }
}
}
+8 −0
Original line number Original line Diff line number Diff line
@@ -132,6 +132,7 @@ public class ActivityTestsBase {
        private int mUid;
        private int mUid;
        private boolean mCreateTask;
        private boolean mCreateTask;
        private ActivityStack mStack;
        private ActivityStack mStack;
        private int mActivityFlags;


        ActivityBuilder(ActivityManagerService service) {
        ActivityBuilder(ActivityManagerService service) {
            mService = service;
            mService = service;
@@ -152,6 +153,11 @@ public class ActivityTestsBase {
            return this;
            return this;
        }
        }


        ActivityBuilder setActivityFlags(int flags) {
            mActivityFlags = flags;
            return this;
        }

        ActivityBuilder setStack(ActivityStack stack) {
        ActivityBuilder setStack(ActivityStack stack) {
            mStack = stack;
            mStack = stack;
            return this;
            return this;
@@ -186,6 +192,8 @@ public class ActivityTestsBase {
            aInfo.applicationInfo = new ApplicationInfo();
            aInfo.applicationInfo = new ApplicationInfo();
            aInfo.applicationInfo.packageName = mComponent.getPackageName();
            aInfo.applicationInfo.packageName = mComponent.getPackageName();
            aInfo.applicationInfo.uid = mUid;
            aInfo.applicationInfo.uid = mUid;
            aInfo.flags |= mActivityFlags;

            final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
            final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
                    0 /* launchedFromPid */, 0, null, intent, null,
                    0 /* launchedFromPid */, 0, null, intent, null,
                    aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */,
                    aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */,