Merge "Consider lock state when determining next activity to become visible." into pi-dev
am: 00f4a4bc74
Change-Id: Ied73f5090e5c790c884d817ac57399d70952ff6f
This commit is contained in:
@@ -3802,7 +3802,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
// and the resumed activity is not yet visible, then hold off on
|
||||
// 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)
|
||||
&& next != null && !next.nowVisible) {
|
||||
|
||||
@@ -1210,6 +1210,18 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
|
||||
}
|
||||
|
||||
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;
|
||||
ActivityRecord r = focusedStack.topRunningActivityLocked();
|
||||
if (r != null) {
|
||||
@@ -1228,16 +1240,33 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
|
||||
if (display == null) {
|
||||
continue;
|
||||
}
|
||||
for (int j = display.getChildCount() - 1; j >= 0; --j) {
|
||||
final ActivityStack stack = display.getChildAt(j);
|
||||
if (stack != focusedStack && stack.isTopStackOnDisplay() && stack.isFocusable()) {
|
||||
r = stack.topRunningActivityLocked();
|
||||
if (r != null) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: We probably want to consider the top fullscreen stack as we could have a pinned
|
||||
// stack on top.
|
||||
final ActivityStack topStack = display.getTopStack();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.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 org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
@@ -329,4 +330,52 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
|
||||
REMOVE_TASK_MODE_DESTROYING);
|
||||
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 */));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +132,7 @@ public class ActivityTestsBase {
|
||||
private int mUid;
|
||||
private boolean mCreateTask;
|
||||
private ActivityStack mStack;
|
||||
private int mActivityFlags;
|
||||
|
||||
ActivityBuilder(ActivityManagerService service) {
|
||||
mService = service;
|
||||
@@ -152,6 +153,11 @@ public class ActivityTestsBase {
|
||||
return this;
|
||||
}
|
||||
|
||||
ActivityBuilder setActivityFlags(int flags) {
|
||||
mActivityFlags = flags;
|
||||
return this;
|
||||
}
|
||||
|
||||
ActivityBuilder setStack(ActivityStack stack) {
|
||||
mStack = stack;
|
||||
return this;
|
||||
@@ -186,6 +192,8 @@ public class ActivityTestsBase {
|
||||
aInfo.applicationInfo = new ApplicationInfo();
|
||||
aInfo.applicationInfo.packageName = mComponent.getPackageName();
|
||||
aInfo.applicationInfo.uid = mUid;
|
||||
aInfo.flags |= mActivityFlags;
|
||||
|
||||
final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
|
||||
0 /* launchedFromPid */, 0, null, intent, null,
|
||||
aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */,
|
||||
|
||||
Reference in New Issue
Block a user