diff options
author | Louis Chang <louischang@google.com> | 2018-08-30 03:48:16 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-08-30 03:48:16 +0000 |
commit | 589ce41dd33b6ce385158d97196a59475cd77c95 (patch) | |
tree | 83a5ed602767dceb050429388c54476c9927b600 | |
parent | d7f361e924c6fb984e0dd5eb8814dc5c6067db69 (diff) | |
parent | 7d0037cdffb9b4d1684cb9990f0d0101ce5246a1 (diff) |
Merge "Finish non-standard activity type when display removed"
4 files changed, 80 insertions, 60 deletions
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java index 73ffd5cc4ff4..3568a473b2ec 100644 --- a/services/core/java/com/android/server/am/ActivityDisplay.java +++ b/services/core/java/com/android/server/am/ActivityDisplay.java @@ -31,6 +31,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.FLAG_PRIVATE; import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT; + import static com.android.server.am.ActivityDisplayProto.CONFIGURATION_CONTAINER; import static com.android.server.am.ActivityDisplayProto.FOCUSED_STACK_ID; import static com.android.server.am.ActivityDisplayProto.ID; @@ -43,7 +44,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.am.ActivityStackSupervisor.TAG_STATES; -import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityOptions; import android.app.WindowConfiguration; @@ -103,6 +103,12 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> private boolean mSleeping; + /** + * The display is removed from the system and we are just waiting for all activities on it to be + * finished before removing this object. + */ + private boolean mRemoved; + // Cached reference to some special stacks we tend to get a lot so we don't need to loop // through the list to find them. private ActivityStack mHomeStack = null; @@ -155,6 +161,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> + " from displayId=" + mDisplayId); mStacks.remove(stack); removeStackReferenceIfNeeded(stack); + releaseSelfIfNeeded(); mSupervisor.mService.updateSleepIfNeededLocked(); onStackOrderChanged(); } @@ -484,16 +491,11 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> final int windowingMode = stack.getWindowingMode(); if (activityType == ACTIVITY_TYPE_HOME) { - // TODO(b/111363427) Rollback to throws exceptions once we figure out how to properly - // deal with home type stack when external display removed if (mHomeStack != null && mHomeStack != stack) { - // throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack=" - // + mHomeStack + " already exist on display=" + this + " stack=" + stack); - Slog.e(TAG, "addStackReferenceIfNeeded: home stack=" + throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack=" + mHomeStack + " already exist on display=" + this + " stack=" + stack); - } else { - mHomeStack = stack; } + mHomeStack = stack; } else if (activityType == ACTIVITY_TYPE_RECENTS) { if (mRecentsStack != null && mRecentsStack != stack) { throw new IllegalArgumentException("addStackReferenceIfNeeded: recents stack=" @@ -796,28 +798,47 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> return false; } + /** + * @see #mRemoved + */ + boolean isRemoved() { + return mRemoved; + } + void remove() { final boolean destroyContentOnRemoval = shouldDestroyContentOnRemove(); - while (getChildCount() > 0) { - final ActivityStack stack = getChildAt(0); - if (destroyContentOnRemoval) { - // Override the stack configuration to make it equal to the current applied one, so - // that we don't accidentally report configuration change to activities that are - // going to be finished. - stack.onOverrideConfigurationChanged(stack.getConfiguration()); - mSupervisor.moveStackToDisplayLocked(stack.mStackId, DEFAULT_DISPLAY, - false /* onTop */); + + // Stacks could be reparented from the removed display to other display. While + // reparenting the last stack of the removed display, the remove display is ready to be + // released (no more ActivityStack). But, we cannot release it at that moment or the + // related WindowContainer and WindowContainerController will also be removed. So, we + // set display as removed after reparenting stack finished. + for (int i = mStacks.size() - 1; i >= 0; --i) { + final ActivityStack stack = mStacks.get(i); + // Always finish non-standard type stacks. + if (destroyContentOnRemoval || !stack.isActivityTypeStandardOrUndefined()) { stack.finishAllActivitiesLocked(true /* immediately */); } else { - // Moving all tasks to fullscreen stack, because it's guaranteed to be - // a valid launch stack for all activities. This way the task history from - // external display will be preserved on primary after move. - mSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */); + // If default display is in split-window mode, set windowing mode of the stack to + // split-screen secondary. Otherwise, set the windowing mode to undefined by + // default to let stack inherited the windowing mode from the new display. + int windowingMode = mSupervisor.getDefaultDisplay().hasSplitScreenPrimaryStack() + ? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY : WINDOWING_MODE_UNDEFINED; + mSupervisor.moveStackToDisplayLocked(stack.mStackId, DEFAULT_DISPLAY, true); + stack.setWindowingMode(windowingMode); } } + mRemoved = true; - mWindowContainerController.removeContainer(); - mWindowContainerController = null; + releaseSelfIfNeeded(); + } + + private void releaseSelfIfNeeded() { + if (mStacks.isEmpty() && mRemoved) { + mWindowContainerController.removeContainer(); + mWindowContainerController = null; + mSupervisor.releaseActivityDisplayLocked(mDisplayId); + } } /** Update and get all UIDs that are present on the display and have access to it. */ diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index fbf285596ed9..78fef65687fd 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -36,6 +36,15 @@ import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD; import static android.view.Display.INVALID_DISPLAY; +import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE; +import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN; +import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE; +import static android.view.WindowManager.TRANSIT_NONE; +import static android.view.WindowManager.TRANSIT_TASK_CLOSE; +import static android.view.WindowManager.TRANSIT_TASK_OPEN; +import static android.view.WindowManager.TRANSIT_TASK_OPEN_BEHIND; +import static android.view.WindowManager.TRANSIT_TASK_TO_BACK; +import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; import static com.android.server.am.ActivityDisplay.POSITION_BOTTOM; import static com.android.server.am.ActivityDisplay.POSITION_TOP; @@ -82,10 +91,6 @@ import static com.android.server.am.ActivityStack.ActivityState.PAUSING; import static com.android.server.am.ActivityStack.ActivityState.RESUMED; import static com.android.server.am.ActivityStack.ActivityState.STOPPED; import static com.android.server.am.ActivityStack.ActivityState.STOPPING; -import static com.android.server.am.ActivityStackSupervisor.FindTaskResult; -import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY; -import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; -import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.am.ActivityStackProto.BOUNDS; import static com.android.server.am.ActivityStackProto.CONFIGURATION_CONTAINER; import static com.android.server.am.ActivityStackProto.DISPLAY_ID; @@ -93,15 +98,10 @@ import static com.android.server.am.ActivityStackProto.FULLSCREEN; import static com.android.server.am.ActivityStackProto.ID; import static com.android.server.am.ActivityStackProto.RESUMED_ACTIVITY; import static com.android.server.am.ActivityStackProto.TASKS; -import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE; -import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN; -import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE; -import static android.view.WindowManager.TRANSIT_NONE; -import static android.view.WindowManager.TRANSIT_TASK_CLOSE; -import static android.view.WindowManager.TRANSIT_TASK_OPEN; -import static android.view.WindowManager.TRANSIT_TASK_OPEN_BEHIND; -import static android.view.WindowManager.TRANSIT_TASK_TO_BACK; -import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; +import static com.android.server.am.ActivityStackSupervisor.FindTaskResult; +import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY; +import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; +import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import static java.lang.Integer.MAX_VALUE; @@ -115,12 +115,12 @@ import android.app.WindowConfiguration.ActivityType; import android.app.WindowConfiguration.WindowingMode; import android.app.servertransaction.ActivityResultItem; import android.app.servertransaction.ClientTransaction; -import android.app.servertransaction.NewIntentItem; -import android.app.servertransaction.WindowVisibilityItem; import android.app.servertransaction.DestroyActivityItem; +import android.app.servertransaction.NewIntentItem; import android.app.servertransaction.PauseActivityItem; import android.app.servertransaction.ResumeActivityItem; import android.app.servertransaction.StopActivityItem; +import android.app.servertransaction.WindowVisibilityItem; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -5191,7 +5191,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (isAttached()) { getDisplay().positionChildAtBottom(this); } - if (!isActivityTypeHome()) { + if (!isActivityTypeHome() || getDisplay().isRemoved()) { remove(); } } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 9809bfa38252..4cfcbee08a57 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -48,6 +48,7 @@ import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.Display.TYPE_VIRTUAL; +import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS; @@ -81,13 +82,6 @@ import static com.android.server.am.ActivityStack.ActivityState.RESUMED; import static com.android.server.am.ActivityStack.ActivityState.STOPPED; import static com.android.server.am.ActivityStack.ActivityState.STOPPING; import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING; -import static com.android.server.am.TaskRecord.INVALID_TASK_ID; -import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE; -import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; -import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED; -import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT; -import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE; -import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT; import static com.android.server.am.ActivityStackSupervisorProto.CONFIGURATION_CONTAINER; import static com.android.server.am.ActivityStackSupervisorProto.DISPLAYS; import static com.android.server.am.ActivityStackSupervisorProto.FOCUSED_STACK_ID; @@ -95,7 +89,13 @@ import static com.android.server.am.ActivityStackSupervisorProto.IS_HOME_RECENTS import static com.android.server.am.ActivityStackSupervisorProto.KEYGUARD_CONTROLLER; import static com.android.server.am.ActivityStackSupervisorProto.PENDING_ACTIVITIES; import static com.android.server.am.ActivityStackSupervisorProto.RESUMED_ACTIVITY; -import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS; +import static com.android.server.am.TaskRecord.INVALID_TASK_ID; +import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE; +import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; +import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED; +import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT; +import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE; +import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT; import static java.lang.Integer.MAX_VALUE; @@ -109,8 +109,6 @@ import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.StackInfo; import android.app.ActivityManagerInternal; -import com.android.internal.util.function.pooled.PooledLambda; -import com.android.server.wm.ActivityTaskManagerInternal.SleepToken; import android.app.ActivityOptions; import android.app.AppOpsManager; import android.app.ProfilerInfo; @@ -170,11 +168,13 @@ import android.view.Display; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.ReferrerIntent; -import com.android.internal.os.logging.MetricsLoggerWrapper; import com.android.internal.os.TransferPipe; +import com.android.internal.os.logging.MetricsLoggerWrapper; import com.android.internal.util.ArrayUtils; +import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; import com.android.server.am.ActivityStack.ActivityState; +import com.android.server.wm.ActivityTaskManagerInternal.SleepToken; import com.android.server.wm.ConfigurationContainer; import com.android.server.wm.PinnedStackWindowController; import com.android.server.wm.WindowManagerService; @@ -1862,7 +1862,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(launchDisplayId); - if (activityDisplay == null) { + if (activityDisplay == null || activityDisplay.isRemoved()) { Slog.w(TAG, "Launch on display check: display not found"); return false; } @@ -4359,11 +4359,14 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D activityDisplay.remove(); releaseSleepTokens(activityDisplay); - - mActivityDisplays.remove(displayId); } } + void releaseActivityDisplayLocked(int displayId) { + mActivityDisplays.remove(displayId); + } + + private void handleDisplayChanged(int displayId) { synchronized (mService.mGlobalLock) { ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index a2dd67929fef..ba467373398d 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -3514,16 +3514,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private void addStackReferenceIfNeeded(TaskStack stack) { if (stack.isActivityTypeHome()) { - // TODO(b/111363427) Rollback to throws exceptions once we figure out how to - // properly deal with home type stack when external display removed if (mHomeStack != null) { - // throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack=" - // + mHomeStack + " already exist on display=" + this + " stack=" + stack); - Slog.e(TAG, "addStackReferenceIfNeeded: home stack=" + throw new IllegalArgumentException("addStackReferenceIfNeeded: home stack=" + mHomeStack + " already exist on display=" + this + " stack=" + stack); - } else { - mHomeStack = stack; + } + mHomeStack = stack; } final int windowingMode = stack.getWindowingMode(); if (windowingMode == WINDOWING_MODE_PINNED) { |