diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index e539bf8035424..eb7e9c8f6d424 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 649d5770f6a9b..d7136bf6017a7 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 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 e9a13585d8fb5..52b0edc8de2d3 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 9663a1b58686a..08b8af289bd82 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()); + } }