diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 4ce157fde648b5cd8473e880cf4d6ba847753d8a..767deb98379ab3d75f3b830d7fa1134c06d2784c 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -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() { diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 1e9edd9a1b4490a1299fb723c4b8f5983c8e19c3..6d4ac8f99651c6b22dfe80decafe2deae49254a7 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -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() { diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 731a44d35cf2cd3d0616042f5edfa0235d65bd3f..cbf30bdd0cbb4c146d4e6f9b88a299674c15a69c 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -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; } diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java index 9663a1b58686aa07687f58be1b632af7f5621062..08b8af289bd823e4ac3837ed4c365192c0824582 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java @@ -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()); + } }