Add APIs to notify and restart activity in size compatibility mode
- Notify listeners about whether the resumed activity is using the
native screen configuration.
- Able to restart foreground activity with saved state.
Bug: 112288258
Test: atest ActivityRecordTests#testRestartProcessIfVisible
Test: atest ActivityDisplayTests#testHandleActivitySizeCompatMode
Change-Id: I0b916b25f187e9406154afced0214a41c02c761a
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index d747198..6664b76 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1666,13 +1666,32 @@
final long origId = Binder.clearCallingIdentity();
+ String restartingName = null;
+ int restartingUid = 0;
+ final ActivityRecord r;
synchronized (mGlobalLock) {
- final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ r = ActivityRecord.isInStackLocked(token);
if (r != null) {
+ if (r.attachedToProcess()
+ && r.isState(ActivityStack.ActivityState.RESTARTING_PROCESS)) {
+ // The activity was requested to restart from
+ // {@link #restartActivityProcessIfVisible}.
+ restartingName = r.app.mName;
+ restartingUid = r.app.mUid;
+ }
r.activityStoppedLocked(icicle, persistentState, description);
}
}
+ if (restartingName != null) {
+ // In order to let the foreground activity can be restarted with its saved state from
+ // {@link android.app.Activity#onSaveInstanceState}, the kill operation is postponed
+ // until the activity reports stopped with the state. And the activity record will be
+ // kept because the record state is restarting, then the activity will be restarted
+ // immediately if it is still the top one.
+ mStackSupervisor.removeRestartTimeouts(r);
+ mAmInternal.killProcess(restartingName, restartingUid, "restartActivityProcess");
+ }
mAmInternal.trimApplications();
Binder.restoreCallingIdentity(origId);
@@ -2014,6 +2033,23 @@
}
@Override
+ public void restartActivityProcessIfVisible(IBinder activityToken) {
+ mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "restartActivityProcess()");
+ final long callingId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
+ if (r == null) {
+ return;
+ }
+ r.restartProcessIfVisible();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
+ @Override
public boolean removeTask(int taskId) {
enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
synchronized (mGlobalLock) {