Move ensure activity visibility processing to helper class (72/n)
Reduces the amount of cruft in ActivityStack class and makes it
helper to refactor later.
Bug: 80414790
Test: Existing tests pass
Change-Id: I937b7083348fbd860d70d2c80714a5491dc1e213
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java
index ebfc65e..5258357 100644
--- a/services/core/java/com/android/server/wm/ActivityDisplay.java
+++ b/services/core/java/com/android/server/wm/ActivityDisplay.java
@@ -1408,7 +1408,7 @@
boolean preserveWindows, boolean notifyClients) {
for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = getChildAt(stackNdx);
- stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
+ stack.ensureActivitiesVisible(starting, configChanges, preserveWindows,
notifyClients);
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 210a3c7..ba8212b 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -4569,7 +4569,7 @@
// If the activity is stopped, stopping, cycle to an active state. We avoid doing
// this when there is an activity waiting to become translucent as the extra binder
// calls will lead to noticeable jank. A later call to
- // ActivityStack#ensureActivitiesVisibleLocked will bring the activity to a proper
+ // ActivityStack#ensureActivitiesVisible will bring the activity to a proper
// active state.
if (!isState(STARTED, RESUMED, PAUSED, STOPPED, STOPPING)
|| getActivityStack().mTranslucentActivityWaiting != null) {
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index d5350eb..f1c47eb 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -213,7 +213,7 @@
static final String TAG_TASKS = TAG + POSTFIX_TASKS;
private static final String TAG_TRANSITION = TAG + POSTFIX_TRANSITION;
private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
- private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
+ static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
// Ticks during which we check progress while waiting for an app to launch.
private static final int LAUNCH_TICK = 500;
@@ -515,6 +515,8 @@
}
private static final ResetTargetTaskHelper sResetTargetTaskHelper = new ResetTargetTaskHelper();
+ private final EnsureActivitiesVisibleHelper mEnsureActivitiesVisibleHelper =
+ new EnsureActivitiesVisibleHelper(this);
int numActivities() {
int count = 0;
@@ -1492,8 +1494,7 @@
void goToSleep() {
// Ensure visibility without updating configuration, as activities are about to sleep.
- ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
- !PRESERVE_WINDOWS);
+ ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, !PRESERVE_WINDOWS);
// Make sure any paused or stopped but visible activities are now sleeping.
// This ensures that the activity's onStop() is called.
@@ -1979,127 +1980,25 @@
* Make sure that all activities that need to be visible in the stack (that is, they
* currently can be seen by the user) actually are and update their configuration.
*/
- final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
+ void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
boolean preserveWindows) {
- ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
- true /* notifyClients */);
+ ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
}
/**
* Ensure visibility with an option to also update the configuration of visible activities.
- * @see #ensureActivitiesVisibleLocked(ActivityRecord, int, boolean)
+ * @see #ensureActivitiesVisible(ActivityRecord, int, boolean)
* @see RootActivityContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
*/
// TODO: Should be re-worked based on the fact that each task as a stack in most cases.
- final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
+ void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
mTopActivityOccludesKeyguard = false;
mTopDismissingKeyguardActivity = null;
mStackSupervisor.getKeyguardController().beginActivityVisibilityUpdate();
try {
- ActivityRecord top = topRunningActivityLocked();
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top
- + " configChanges=0x" + Integer.toHexString(configChanges));
- if (top != null) {
- checkTranslucentActivityWaiting(top);
- }
-
- // If the top activity is not fullscreen, then we need to
- // make sure any activities under it are now visible.
- boolean aboveTop = top != null;
- final boolean stackShouldBeVisible = shouldBeVisible(starting);
- boolean behindFullscreenActivity = !stackShouldBeVisible;
- // We should not resume activities that being launched behind because these
- // activities are actually behind other fullscreen activities, but still required
- // to be visible (such as performing Recents animation).
- final boolean resumeTopActivity = isFocusable() && isInStackLocked(starting) == null
- && top != null && !top.mLaunchTaskBehind;
- for (int taskNdx = getChildCount() - 1; taskNdx >= 0; --taskNdx) {
- final Task task = getChildAt(taskNdx);
- for (int activityNdx = task.getChildCount() - 1; activityNdx >= 0; --activityNdx) {
- final ActivityRecord r = task.getChildAt(activityNdx);
- final boolean isTop = r == top;
- if (aboveTop && !isTop) {
- continue;
- }
- aboveTop = false;
-
- final boolean reallyVisible = r.shouldBeVisible(behindFullscreenActivity,
- false /* ignoringKeyguard */);
- // Check whether activity should be visible without Keyguard influence
- if (r.visibleIgnoringKeyguard) {
- if (r.occludesParent()) {
- // At this point, nothing else needs to be shown in this task.
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
- + " stackVisible=" + stackShouldBeVisible
- + " behindFullscreen=" + behindFullscreenActivity);
- behindFullscreenActivity = true;
- } else {
- behindFullscreenActivity = false;
- }
- }
-
- if (reallyVisible) {
- if (r.finishing) {
- continue;
- }
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
- + " finishing=" + r.finishing + " state=" + r.getState());
- // First: if this is not the current activity being started, make
- // sure it matches the current configuration.
- if (r != starting && notifyClients) {
- r.ensureActivityConfiguration(0 /* globalChanges */, preserveWindows,
- true /* ignoreVisibility */);
- }
-
- if (!r.attachedToProcess()) {
- makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
- resumeTopActivity && isTop, r);
- } else if (r.mVisibleRequested) {
- // If this activity is already visible, then there is nothing to do here.
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
- "Skipping: already visible at " + r);
-
- if (r.mClientVisibilityDeferred && notifyClients) {
- r.makeClientVisible();
- }
-
- r.handleAlreadyVisible();
- if (notifyClients) {
- r.makeActiveIfNeeded(starting);
- }
- } else {
- r.makeVisibleIfNeeded(starting, notifyClients);
- }
- // Aggregate current change flags.
- configChanges |= r.configChangeFlags;
- } else {
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
- + " finishing=" + r.finishing + " state=" + r.getState()
- + " stackShouldBeVisible=" + stackShouldBeVisible
- + " behindFullscreenActivity=" + behindFullscreenActivity
- + " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
- r.makeInvisible();
- }
- }
- final int windowingMode = getWindowingMode();
- if (windowingMode == WINDOWING_MODE_FREEFORM) {
- // The visibility of tasks and the activities they contain in freeform stack are
- // determined individually unlike other stacks where the visibility or fullscreen
- // status of an activity in a previous task affects other.
- behindFullscreenActivity = !stackShouldBeVisible;
- } else if (isActivityTypeHome()) {
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
- + " stackShouldBeVisible=" + stackShouldBeVisible
- + " behindFullscreenActivity=" + behindFullscreenActivity);
- // No other task in the home stack should be visible behind the home activity.
- // Home activities is usually a translucent activity with the wallpaper behind
- // them. However, when they don't have the wallpaper behind them, we want to
- // show activities in the next application stack behind them vs. another
- // task in the home stack like recents.
- behindFullscreenActivity = true;
- }
- }
+ mEnsureActivitiesVisibleHelper.process(
+ starting, configChanges, preserveWindows, notifyClients);
if (mTranslucentActivityWaiting != null &&
mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
@@ -2214,7 +2113,7 @@
return (flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0;
}
- private void checkTranslucentActivityWaiting(ActivityRecord top) {
+ void checkTranslucentActivityWaiting(ActivityRecord top) {
if (mTranslucentActivityWaiting != top) {
mUndrawnActivitiesBelowTopTranslucent.clear();
if (mTranslucentActivityWaiting != null) {
@@ -2226,31 +2125,6 @@
}
}
- private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
- boolean isTop, boolean andResume, ActivityRecord r) {
- // We need to make sure the app is running if it's the top, or it is just made visible from
- // invisible. If the app is already visible, it must have died while it was visible. In this
- // case, we'll show the dead window but will not restart the app. Otherwise we could end up
- // thrashing.
- if (isTop || !r.mVisibleRequested) {
- // This activity needs to be visible, but isn't even running...
- // get it started and resume if no other stack in this stack is resumed.
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
- if (r != starting) {
- r.startFreezingScreenLocked(configChanges);
- }
- if (!r.mVisibleRequested || r.mLaunchTaskBehind) {
- if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
- r.setVisibility(true);
- }
- if (r != starting) {
- mStackSupervisor.startSpecificActivityLocked(r, andResume, true /* checkConfig */);
- return true;
- }
- }
- return false;
- }
-
void convertActivityToTranslucent(ActivityRecord r) {
mTranslucentActivityWaiting = r;
mUndrawnActivitiesBelowTopTranslucent.clear();
@@ -2490,7 +2364,7 @@
&& next.containsDismissKeyguardWindow();
if (canShowWhenLocked || mayDismissKeyguard) {
- ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
+ ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
!PRESERVE_WINDOWS);
nothingToResume = shouldSleepActivities();
}
@@ -2819,7 +2693,7 @@
next.showStartingWindow(null /* prev */, false /* newTask */,
false /* taskSwitch */);
}
- mStackSupervisor.startSpecificActivityLocked(next, true, false);
+ mStackSupervisor.startSpecificActivity(next, true, false);
return true;
}
@@ -2846,7 +2720,7 @@
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
}
if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
- mStackSupervisor.startSpecificActivityLocked(next, true, true);
+ mStackSupervisor.startSpecificActivity(next, true, true);
}
return true;
@@ -2991,7 +2865,7 @@
// Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
// tell WindowManager that r is visible even though it is at the back of the stack.
r.setVisibility(true);
- ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
// Go ahead to execute app transition for this activity since the app transition
// will not be triggered through the resume channel.
getDisplay().mDisplayContent.executeAppTransition();
@@ -4381,7 +4255,7 @@
// The task might have already been running and its visibility needs to be synchronized with
// the visibility of the stack / windows.
- ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 6ea80d2..304f230 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -975,7 +975,7 @@
}
}
- void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
+ void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
@@ -1742,12 +1742,12 @@
* to the fullscreen stack. This is to guarantee that when we are removing a stack,
* that the client receives onStop() before it is reparented. We do this by detaching
* the stack from the display so that it will be considered invisible when
- * ensureActivitiesVisibleLocked() is called, and all of its activitys will be marked
+ * ensureActivitiesVisible() is called, and all of its activitys will be marked
* invisible as well and added to the stopping list. After which we process the
* stopping list by handling the idle.
*/
stack.mForceHidden = true;
- stack.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
+ stack.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
stack.mForceHidden = false;
activityIdleInternalLocked(null, false /* fromTimeout */,
true /* processPausingActivites */, null /* configuration */);
@@ -2072,7 +2072,7 @@
mRecentTasks.add(task);
mService.getTaskChangeNotificationController().notifyTaskStackChanged();
- stack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ stack.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
// When launching tasks behind, update the last active time of the top task after the new
// task has been shown briefly
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 21d5861..8455c6d 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1574,7 +1574,7 @@
// Also, we don't want to resume activities in a task that currently has an overlay
// as the starting activity just needs to be in the visible paused state until the
// over is removed.
- mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
+ mTargetStack.ensureActivitiesVisible(mStartActivity, 0, !PRESERVE_WINDOWS);
// Go ahead and tell window manager to execute app transition for this activity
// since the app transition will not be triggered through the resume channel.
mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
diff --git a/services/core/java/com/android/server/wm/CompatModePackages.java b/services/core/java/com/android/server/wm/CompatModePackages.java
index 104805f..320ca65 100644
--- a/services/core/java/com/android/server/wm/CompatModePackages.java
+++ b/services/core/java/com/android/server/wm/CompatModePackages.java
@@ -346,7 +346,7 @@
false /* preserveWindow */);
// And we need to make sure at this point that all other activities
// are made visible with the correct configuration.
- stack.ensureActivitiesVisibleLocked(starting, 0, !PRESERVE_WINDOWS);
+ stack.ensureActivitiesVisible(starting, 0, !PRESERVE_WINDOWS);
}
}
}
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
new file mode 100644
index 0000000..3aae1b1
--- /dev/null
+++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+
+import static com.android.server.wm.ActivityStack.TAG_VISIBILITY;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
+
+import android.util.Slog;
+
+import com.android.internal.util.function.pooled.PooledConsumer;
+import com.android.internal.util.function.pooled.PooledLambda;
+
+/** Helper class to ensure activities are in the right visible state for a container. */
+class EnsureActivitiesVisibleHelper {
+ private final ActivityStack mContiner;
+ private ActivityRecord mTop;
+ private ActivityRecord mStarting;
+ private boolean mAboveTop;
+ private boolean mContainerShouldBeVisible;
+ private boolean mBehindFullscreenActivity;
+ private int mConfigChanges;
+ private boolean mPreserveWindows;
+ private boolean mNotifyClients;
+
+ EnsureActivitiesVisibleHelper(ActivityStack container) {
+ mContiner = container;
+ }
+
+ void reset(ActivityRecord starting, int configChanges, boolean preserveWindows,
+ boolean notifyClients) {
+ mStarting = starting;
+ mTop = mContiner.topRunningActivityLocked();
+ // If the top activity is not fullscreen, then we need to make sure any activities under it
+ // are now visible.
+ mAboveTop = mTop != null;
+ mContainerShouldBeVisible = mContiner.shouldBeVisible(mStarting);
+ mBehindFullscreenActivity = !mContainerShouldBeVisible;
+ mConfigChanges = configChanges;
+ mPreserveWindows = preserveWindows;
+ mNotifyClients = notifyClients;
+ }
+
+ /**
+ * Ensure visibility with an option to also update the configuration of visible activities.
+ * @see ActivityStack#ensureActivitiesVisible(ActivityRecord, int, boolean)
+ * @see RootActivityContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
+ */
+ void process(ActivityRecord starting, int configChanges, boolean preserveWindows,
+ boolean notifyClients) {
+ reset(starting, configChanges, preserveWindows, notifyClients);
+
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + mTop
+ + " configChanges=0x" + Integer.toHexString(configChanges));
+ if (mTop != null) {
+ mContiner.checkTranslucentActivityWaiting(mTop);
+ }
+
+ // We should not resume activities that being launched behind because these
+ // activities are actually behind other fullscreen activities, but still required
+ // to be visible (such as performing Recents animation).
+ final boolean resumeTopActivity = mTop != null && !mTop.mLaunchTaskBehind
+ && mContiner.isFocusable() && mContiner.isInStackLocked(starting) == null;
+
+ final PooledConsumer f = PooledLambda.obtainConsumer(
+ EnsureActivitiesVisibleHelper::setActivityVisibilityState, this,
+ PooledLambda.__(ActivityRecord.class), resumeTopActivity);
+ mContiner.forAllActivities(f);
+ f.recycle();
+ }
+
+ private void setActivityVisibilityState(ActivityRecord r, final boolean resumeTopActivity) {
+ final boolean isTop = r == mTop;
+ if (mAboveTop && !isTop) {
+ return;
+ }
+ mAboveTop = false;
+
+ final boolean reallyVisible = r.shouldBeVisible(
+ mBehindFullscreenActivity, false /* ignoringKeyguard */);
+
+ // Check whether activity should be visible without Keyguard influence
+ if (r.visibleIgnoringKeyguard) {
+ if (r.occludesParent()) {
+ // At this point, nothing else needs to be shown in this task.
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
+ + " stackVisible=" + mContainerShouldBeVisible
+ + " behindFullscreen=" + mBehindFullscreenActivity);
+ mBehindFullscreenActivity = true;
+ } else {
+ mBehindFullscreenActivity = false;
+ }
+ }
+
+ if (reallyVisible) {
+ if (r.finishing) {
+ return;
+ }
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
+ + " finishing=" + r.finishing + " state=" + r.getState());
+ // First: if this is not the current activity being started, make
+ // sure it matches the current configuration.
+ if (r != mStarting && mNotifyClients) {
+ r.ensureActivityConfiguration(0 /* globalChanges */, mPreserveWindows,
+ true /* ignoreVisibility */);
+ }
+
+ if (!r.attachedToProcess()) {
+ makeVisibleAndRestartIfNeeded(mStarting, mConfigChanges, isTop,
+ resumeTopActivity && isTop, r);
+ } else if (r.mVisibleRequested) {
+ // If this activity is already visible, then there is nothing to do here.
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
+ "Skipping: already visible at " + r);
+
+ if (r.mClientVisibilityDeferred && mNotifyClients) {
+ r.makeClientVisible();
+ }
+
+ r.handleAlreadyVisible();
+ if (mNotifyClients) {
+ r.makeActiveIfNeeded(mStarting);
+ }
+ } else {
+ r.makeVisibleIfNeeded(mStarting, mNotifyClients);
+ }
+ // Aggregate current change flags.
+ mConfigChanges |= r.configChangeFlags;
+ } else {
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
+ + " finishing=" + r.finishing + " state=" + r.getState()
+ + " stackShouldBeVisible=" + mContainerShouldBeVisible
+ + " behindFullscreenActivity=" + mBehindFullscreenActivity
+ + " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
+ r.makeInvisible();
+ }
+
+ final int windowingMode = mContiner.getWindowingMode();
+ if (windowingMode == WINDOWING_MODE_FREEFORM) {
+ // The visibility of tasks and the activities they contain in freeform stack are
+ // determined individually unlike other stacks where the visibility or fullscreen
+ // status of an activity in a previous task affects other.
+ mBehindFullscreenActivity = !mContainerShouldBeVisible;
+ } else if (mContiner.isActivityTypeHome()) {
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + mContiner
+ + " stackShouldBeVisible=" + mContainerShouldBeVisible
+ + " behindFullscreenActivity=" + mBehindFullscreenActivity);
+ // No other task in the home stack should be visible behind the home activity.
+ // Home activities is usually a translucent activity with the wallpaper behind
+ // them. However, when they don't have the wallpaper behind them, we want to
+ // show activities in the next application stack behind them vs. another
+ // task in the home stack like recents.
+ mBehindFullscreenActivity = true;
+ }
+ }
+
+ private void makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
+ boolean isTop, boolean andResume, ActivityRecord r) {
+ // We need to make sure the app is running if it's the top, or it is just made visible from
+ // invisible. If the app is already visible, it must have died while it was visible. In this
+ // case, we'll show the dead window but will not restart the app. Otherwise we could end up
+ // thrashing.
+ if (!isTop && r.mVisibleRequested) {
+ return;
+ }
+
+ // This activity needs to be visible, but isn't even running...
+ // get it started and resume if no other stack in this stack is resumed.
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
+ if (r != starting) {
+ r.startFreezingScreenLocked(configChanges);
+ }
+ if (!r.mVisibleRequested || r.mLaunchTaskBehind) {
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
+ r.setVisibility(true);
+ }
+ if (r != starting) {
+ mContiner.mStackSupervisor.startSpecificActivity(r, andResume, true /* checkConfig */);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index a17bd24..824a3c8 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -134,7 +134,7 @@
if (!targetActivity.attachedToProcess()) {
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Real start recents");
- mStackSupervisor.startSpecificActivityLocked(targetActivity, false /* andResume */,
+ mStackSupervisor.startSpecificActivity(targetActivity, false /* andResume */,
false /* checkConfig */);
// Make sure the activity won't be involved in transition.
if (targetActivity.getDisplayContent() != null) {
@@ -368,7 +368,7 @@
// transition (the target activity will be one of closing apps).
if (!controller.shouldDeferCancelWithScreenshot()
&& !targetStack.isFocusedStackOnDisplay()) {
- targetStack.ensureActivitiesVisibleLocked(null /* starting */,
+ targetStack.ensureActivitiesVisible(null /* starting */,
0 /* starting */, false /* preserveWindows */);
}
// Keep target stack in place, nothing changes, so ignore the transition
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index b71659e..ba54859 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -1118,7 +1118,7 @@
r.setState(ActivityStack.ActivityState.INITIALIZING, "test");
// Ensure precondition that the activity is opaque.
assertTrue(r.occludesParent());
- mSupervisor.startSpecificActivityLocked(r, false /* andResume */,
+ mSupervisor.startSpecificActivity(r, false /* andResume */,
false /* checkConfig */);
}
mSupervisor.endDeferResume();
@@ -1145,12 +1145,12 @@
new ActivityBuilder(mService).setTask(mTask).build();
doReturn(false).when(nonTopVisibleActivity).attachedToProcess();
doReturn(true).when(nonTopVisibleActivity).shouldBeVisible(anyBoolean(), anyBoolean());
- doNothing().when(mSupervisor).startSpecificActivityLocked(any(), anyBoolean(),
+ doNothing().when(mSupervisor).startSpecificActivity(any(), anyBoolean(),
anyBoolean());
- mStack.ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
+ mStack.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
false /* preserveWindows */);
- verify(mSupervisor).startSpecificActivityLocked(any(), eq(false) /* andResume */,
+ verify(mSupervisor).startSpecificActivity(any(), eq(false) /* andResume */,
anyBoolean());
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index d48b9d7..e67380c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -200,7 +200,7 @@
startRecentsActivity();
// Recents activity must be restarted, but not be resumed while running recents animation.
- verify(mRootActivityContainer.mStackSupervisor).startSpecificActivityLocked(
+ verify(mRootActivityContainer.mStackSupervisor).startSpecificActivity(
eq(recentActivity), eq(false), anyBoolean());
assertThat(recentActivity.getState()).isEqualTo(PAUSED);
}