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

Commit 7b851cc7 authored by Bryce Lee's avatar Bryce Lee
Browse files

Move container focusability logic to ActivityStackSupervisor.

A number of factors are considered across the container hierarchy
when determining whether the container can be focused. Previously,
windowing mode consideration was added to the activity record, but
not stack. This led to inconsistent behavior when queried.

This changelist combines the logic and moves it to
ActivityStackSupervisor, where it can be invoked by any container.

Change-Id: I0d16faa069fd05500d39cd1619de9f8c488daa25
Fixes: 77708107
Test: atest FrameworksServicesTests:com.android.server.am.ActivityStackSupervisorTests#testFocusability
Test: atest CtsActivityManagerDeviceTestCases:android.server.am.lifecycle.ActivityLifecycleTests#testPausedWhenRestartedFromInNonFocusedStack
parent cfa439f0
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -1198,10 +1198,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
    }

    boolean isFocusable() {
        if (inSplitScreenPrimaryWindowingMode() && mStackSupervisor.mIsDockMinimized) {
            return false;
        }
        return getWindowConfiguration().canReceiveKeys() || isAlwaysFocusable();
        return mStackSupervisor.isFocusable(this, isAlwaysFocusable());
    }

    boolean isResizeable() {
+1 −6
Original line number Diff line number Diff line
@@ -1077,13 +1077,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
    }

    boolean isFocusable() {
        if (getWindowConfiguration().canReceiveKeys()) {
            return true;
        }
        // The stack isn't focusable. See if its top activity is focusable to force focus on the
        // stack.
        final ActivityRecord r = topRunningActivityLocked();
        return r != null && r.isFocusable();
        return mStackSupervisor.isFocusable(this, r != null && r.isFocusable());
    }

    final boolean isAttached() {
+8 −0
Original line number Diff line number Diff line
@@ -667,6 +667,14 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        return mFocusedStack;
    }

    boolean isFocusable(ConfigurationContainer container, boolean alwaysFocusable) {
        if (container.inSplitScreenPrimaryWindowingMode() && mIsDockMinimized) {
            return false;
        }

        return container.getWindowConfiguration().canReceiveKeys() || alwaysFocusable;
    }

    ActivityStack getLastStack() {
        return mLastFocusedStack;
    }
+42 −0
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;

import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -287,4 +290,43 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
        // Verify that the stack was removed.
        assertEquals(originalStackCount, defaultDisplay.getChildCount());
    }

    @Test
    public void testFocusability() throws Exception {
        final ActivityStack stack = mService.mStackSupervisor.getDefaultDisplay().createStack(
                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */);
        final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
                .setStack(stack).build();

        // Under split screen primary we should be focusable when not minimized
        mService.mStackSupervisor.setDockedStackMinimized(false);
        assertTrue(stack.isFocusable());
        assertTrue(activity.isFocusable());

        // Under split screen primary we should not be focusable when minimized
        mService.mStackSupervisor.setDockedStackMinimized(true);
        assertFalse(stack.isFocusable());
        assertFalse(activity.isFocusable());

        final ActivityStack pinnedStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
        final ActivityRecord pinnedActivity = new ActivityBuilder(mService).setCreateTask(true)
                .setStack(pinnedStack).build();

        // We should not be focusable when in pinned mode
        assertFalse(pinnedStack.isFocusable());
        assertFalse(pinnedActivity.isFocusable());

        // Add flag forcing focusability.
        pinnedActivity.info.flags |= FLAG_ALWAYS_FOCUSABLE;

        // We should not be focusable when in pinned mode
        assertTrue(pinnedStack.isFocusable());
        assertTrue(pinnedActivity.isFocusable());

        // Without the overridding activity, stack should not be focusable.
        pinnedStack.removeTask(pinnedActivity.getTask(), "testFocusability",
                REMOVE_TASK_MODE_DESTROYING);
        assertFalse(pinnedStack.isFocusable());
    }
}