Only show the toast of dismissing docked stack if it actually happens
When launching a non-resizable activity on secondary display, an overlay
activity will show "App may not work on a secondary display" on it.
Because the overlay activity is resizable, it is nothing to handle on
secondary display. But it falls to the condition of split-screen, and
even there is no docked stack, the toast of dismissing docked stack is
still shown.
Bug: 128674132
Test: atest ActivityStackSupervisorTests# \
testHandleNonResizableTaskOnSecondaryDisplay
Change-Id: I1b8fe892ec4cace4f87112f132e0eefdae19024d
This commit is contained in:
@@ -2453,46 +2453,43 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
|
||||
mService.getTaskChangeNotificationController()
|
||||
.notifyActivityLaunchOnSecondaryDisplayFailed(task.getTaskInfo(),
|
||||
preferredDisplayId);
|
||||
return;
|
||||
} else if (!forceNonResizable && handleForcedResizableTask(task,
|
||||
FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY)) {
|
||||
return;
|
||||
} else if (!forceNonResizable) {
|
||||
handleForcedResizableTaskIfNeeded(task, FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY);
|
||||
}
|
||||
// The information about not support secondary display should already be notified, we
|
||||
// don't want to show another message on default display about split-screen. And it may
|
||||
// be the case that a resizable activity is launched on a non-resizable task.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!task.supportsSplitScreenWindowingMode() || forceNonResizable) {
|
||||
// Display a warning toast that we tried to put an app that doesn't support split-screen
|
||||
// in split-screen.
|
||||
mService.getTaskChangeNotificationController().notifyActivityDismissingDockedStack();
|
||||
|
||||
// Dismiss docked stack. If task appeared to be in docked stack but is not resizable -
|
||||
// we need to move it to top of fullscreen stack, otherwise it will be covered.
|
||||
|
||||
final ActivityStack dockedStack =
|
||||
task.getStack().getDisplay().getSplitScreenPrimaryStack();
|
||||
if (dockedStack != null) {
|
||||
// Display a warning toast that we tried to put an app that doesn't support
|
||||
// split-screen in split-screen.
|
||||
mService.getTaskChangeNotificationController()
|
||||
.notifyActivityDismissingDockedStack();
|
||||
moveTasksToFullscreenStackLocked(dockedStack, actualStack == dockedStack);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
handleForcedResizableTask(task, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN);
|
||||
handleForcedResizableTaskIfNeeded(task, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the top activity of the task is forced to be resizable and the user
|
||||
* was notified about activity being forced resized.
|
||||
*/
|
||||
private boolean handleForcedResizableTask(TaskRecord task, int reason) {
|
||||
/** Notifies that the top activity of the task is forced to be resizeable. */
|
||||
private void handleForcedResizableTaskIfNeeded(TaskRecord task, int reason) {
|
||||
final ActivityRecord topActivity = task.getTopActivity();
|
||||
if (topActivity != null && topActivity.isNonResizableOrForcedResizable()
|
||||
&& !topActivity.noDisplay) {
|
||||
final String packageName = topActivity.appInfo.packageName;
|
||||
mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
|
||||
task.taskId, reason, packageName);
|
||||
return true;
|
||||
if (topActivity == null || topActivity.noDisplay
|
||||
|| !topActivity.isNonResizableOrForcedResizable()) {
|
||||
return;
|
||||
}
|
||||
return false;
|
||||
mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
|
||||
task.taskId, reason, topActivity.appInfo.packageName);
|
||||
}
|
||||
|
||||
void activityRelaunchedLocked(IBinder token) {
|
||||
|
||||
@@ -18,32 +18,26 @@ package com.android.server.wm;
|
||||
|
||||
import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
|
||||
import static android.app.ActivityManager.START_TASK_TO_FRONT;
|
||||
import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.contains;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
|
||||
import android.app.WaitResult;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
|
||||
import androidx.test.filters.MediumTest;
|
||||
@@ -112,4 +106,44 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
|
||||
assertEquals(deliverToTopWait.who, firstActivity.mActivityComponent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that {@link TaskChangeNotificationController} notifies only when an activity is
|
||||
* forced to resize on secondary display.
|
||||
*/
|
||||
@Test
|
||||
public void testHandleNonResizableTaskOnSecondaryDisplay() {
|
||||
// Create an unresizable task on secondary display.
|
||||
final ActivityDisplay newDisplay = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
|
||||
final ActivityStack stack = new StackBuilder(mRootActivityContainer)
|
||||
.setDisplay(newDisplay).build();
|
||||
final ActivityRecord unresizableActivity = stack.getTopActivity();
|
||||
final TaskRecord task = unresizableActivity.getTaskRecord();
|
||||
unresizableActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
|
||||
task.setResizeMode(unresizableActivity.info.resizeMode);
|
||||
|
||||
final TaskChangeNotificationController taskChangeNotifier =
|
||||
mService.getTaskChangeNotificationController();
|
||||
spyOn(taskChangeNotifier);
|
||||
|
||||
mSupervisor.handleNonResizableTaskIfNeeded(task, newDisplay.getWindowingMode(),
|
||||
newDisplay.mDisplayId, stack);
|
||||
// The top activity is unresizable, so it should notify the activity is forced resizing.
|
||||
verify(taskChangeNotifier).notifyActivityForcedResizable(eq(task.taskId),
|
||||
eq(FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY),
|
||||
eq(unresizableActivity.packageName));
|
||||
reset(taskChangeNotifier);
|
||||
|
||||
// Put a resizable activity on top of the unresizable task.
|
||||
final ActivityRecord resizableActivity = new ActivityBuilder(mService)
|
||||
.setTask(task).build();
|
||||
resizableActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
|
||||
|
||||
mSupervisor.handleNonResizableTaskIfNeeded(task, newDisplay.getWindowingMode(),
|
||||
newDisplay.mDisplayId, stack);
|
||||
// For the resizable activity, it is no need to force resizing or dismiss the docked stack.
|
||||
verify(taskChangeNotifier, never()).notifyActivityForcedResizable(anyInt() /* taskId */,
|
||||
anyInt() /* reason */, anyString() /* packageName */);
|
||||
verify(taskChangeNotifier, never()).notifyActivityDismissingDockedStack();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user