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
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user