Merge "Always start launcher when empty home stack is being resumed" into qt-dev

am: 331eb26c1c

Change-Id: I3acc0d2fb30e22bc5dff64298f70f16f86fc54a1
This commit is contained in:
Andrii Kulian
2019-06-05 09:53:44 -07:00
committed by android-build-merger
2 changed files with 78 additions and 12 deletions

View File

@@ -2640,7 +2640,7 @@ class ActivityStack extends ConfigurationContainer {
if (!hasRunningActivity) {
// There are no activities left in the stack, let's look somewhere else.
return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
}
next.delayedResume = false;
@@ -3041,21 +3041,33 @@ class ActivityStack extends ConfigurationContainer {
return true;
}
private boolean resumeTopActivityInNextFocusableStack(ActivityRecord prev,
ActivityOptions options, String reason) {
final ActivityStack nextFocusedStack = adjustFocusToNextFocusableStack(reason);
if (nextFocusedStack != null) {
// Try to move focus to the next visible stack with a running activity if this
// stack is not covering the entire screen or is on a secondary display (with no home
// stack).
return mRootActivityContainer.resumeFocusedStacksTopActivities(nextFocusedStack, prev,
null /* targetOptions */);
/**
* Resume the next eligible activity in a focusable stack when this one does not have any
* running activities left. The focus will be adjusted to the next focusable stack and
* top running activities will be resumed in all focusable stacks. However, if the current stack
* is a home stack - we have to keep it focused, start and resume a home activity on the current
* display instead to make sure that the display is not empty.
*/
private boolean resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev,
ActivityOptions options) {
final String reason = "noMoreActivities";
if (!isActivityTypeHome()) {
final ActivityStack nextFocusedStack = adjustFocusToNextFocusableStack(reason);
if (nextFocusedStack != null) {
// Try to move focus to the next visible stack with a running activity if this
// stack is not covering the entire screen or is on a secondary display with no home
// stack.
return mRootActivityContainer.resumeFocusedStacksTopActivities(nextFocusedStack,
prev, null /* targetOptions */);
}
}
// Let's just start up the Launcher...
// If the current stack is a home stack, or if focus didn't switch to a different stack -
// just start up the Launcher...
ActivityOptions.abort(options);
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityInNextFocusableStack: " + reason + ", go home");
"resumeNextFocusableActivityWhenStackIsEmpty: " + reason + ", go home");
return mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);
}

View File

@@ -16,6 +16,7 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
@@ -35,6 +36,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.ActivityDisplay.POSITION_TOP;
import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
import static com.android.server.wm.RootActivityContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
import static org.junit.Assert.assertEquals;
@@ -396,6 +398,58 @@ public class RootActivityContainerTests extends ActivityTestsBase {
eq(activity), eq(null /* targetOptions */));
}
/**
* Verify that home activity will be started on a display even if another display has a
* focusable activity.
*/
@Test
public void testResumeFocusedStacksStartsHomeActivity_NoActivities() {
mFullscreenStack.remove();
mService.mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY).getHomeStack().remove();
mService.mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY)
.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
doReturn(true).when(mRootActivityContainer).resumeHomeActivity(any(), any(), anyInt());
mService.setBooted(true);
// Trigger resume on all displays
mRootActivityContainer.resumeFocusedStacksTopActivities();
// Verify that home activity was started on the default display
verify(mRootActivityContainer).resumeHomeActivity(any(), any(), eq(DEFAULT_DISPLAY));
}
/**
* Verify that home activity will be started on a display even if another display has a
* focusable activity.
*/
@Test
public void testResumeFocusedStacksStartsHomeActivity_ActivityOnSecondaryScreen() {
mFullscreenStack.remove();
mService.mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY).getHomeStack().remove();
mService.mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY)
.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
// Create an activity on secondary display.
final TestActivityDisplay secondDisplay = addNewActivityDisplayAt(
ActivityDisplay.POSITION_TOP);
final ActivityStack stack = secondDisplay.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
final TaskRecord task = new TaskBuilder(mSupervisor).setStack(stack).build();
new ActivityBuilder(mService).setTask(task).build();
doReturn(true).when(mRootActivityContainer).resumeHomeActivity(any(), any(), anyInt());
mService.setBooted(true);
// Trigger resume on all displays
mRootActivityContainer.resumeFocusedStacksTopActivities();
// Verify that home activity was started on the default display
verify(mRootActivityContainer).resumeHomeActivity(any(), any(), eq(DEFAULT_DISPLAY));
}
/**
* Verify that a lingering transition is being executed in case the activity to be resumed is
* already resumed