Don't put non-resizeable activities on secondary displays
There is a contract that a non-resizeable activity cannot get
a configuration different from the global config (or fullscreen
config on primary display). This CL ensures that for launching on
secondary displays and checks if target display's config matches
the global config.
If a forced-resizeable activity is launched to a secondary display
or there was an attempt to launch a non-resizeable activity that
failed, corresponding toast message will be displayed.
Bug: 36777179
Test: android.server.cts.ActivityManagerDisplayTests
Test: #testLaunchNonResizeableActivityOnSecondaryDisplay
Test: #testLaunchNonResizeableActivityWithSplitScreen
Test: #testMoveNonResizeableActivityToSecondaryDisplay
Change-Id: I5346afe740e78e4e5ba9a9694e97ac60b92663e9
diff --git a/services/core/java/com/android/server/am/TaskChangeNotificationController.java b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
index 94cf092..7d2bc5b 100644
--- a/services/core/java/com/android/server/am/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
@@ -48,6 +48,7 @@
static final int NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG = 15;
static final int NOTIFY_PINNED_STACK_ANIMATION_STARTED_LISTENERS_MSG = 16;
static final int NOTIFY_ACTIVITY_UNPINNED_LISTENERS_MSG = 17;
+ static final int NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG = 18;
// Delay in notifying task stack change listeners (in millis)
static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
@@ -115,13 +116,17 @@
};
private final TaskStackConsumer mNotifyActivityForcedResizable = (l, m) -> {
- l.onActivityForcedResizable((String) m.obj, m.arg1);
+ l.onActivityForcedResizable((String) m.obj, m.arg1, m.arg2);
};
private final TaskStackConsumer mNotifyActivityDismissingDockedStack = (l, m) -> {
l.onActivityDismissingDockedStack();
};
+ private final TaskStackConsumer mNotifyActivityLaunchOnSecondaryDisplayFailed = (l, m) -> {
+ l.onActivityLaunchOnSecondaryDisplayFailed();
+ };
+
private final TaskStackConsumer mNotifyTaskProfileLocked = (l, m) -> {
l.onTaskProfileLocked(m.arg1, m.arg2);
};
@@ -191,6 +196,9 @@
case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG:
forAllRemoteListeners(mNotifyActivityDismissingDockedStack, msg);
break;
+ case NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG:
+ forAllRemoteListeners(mNotifyActivityLaunchOnSecondaryDisplayFailed, msg);
+ break;
case NOTIFY_TASK_PROFILE_LOCKED_LISTENERS_MSG:
forAllRemoteListeners(mNotifyTaskProfileLocked, msg);
break;
@@ -324,14 +332,22 @@
forAllLocalListeners(mNotifyActivityDismissingDockedStack, message);
}
- void notifyActivityForcedResizable(int taskId, String packageName) {
+ void notifyActivityForcedResizable(int taskId, int reason, String packageName) {
mHandler.removeMessages(NOTIFY_FORCED_RESIZABLE_MSG);
- final Message msg = mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, taskId,
- 0 /* unused */, packageName);
+ final Message msg = mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, taskId, reason,
+ packageName);
forAllLocalListeners(mNotifyActivityForcedResizable, msg);
msg.sendToTarget();
}
+ void notifyActivityLaunchOnSecondaryDisplayFailed() {
+ mHandler.removeMessages(NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG);
+ final Message msg = mHandler.obtainMessage(
+ NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG);
+ forAllLocalListeners(mNotifyActivityLaunchOnSecondaryDisplayFailed, msg);
+ msg.sendToTarget();
+ }
+
void notifyTaskCreated(int taskId, ComponentName componentName) {
final Message msg = mHandler.obtainMessage(NOTIFY_TASK_ADDED_LISTENERS_MSG,
taskId, 0 /* unused */, componentName);