Per-display focused stacks in AM
This switches to tracking focused stacks for each display instead of
a single focused stack in the system.
Now ActivityDisplay#getFocusedStack() will return the corresponding
instance, if present on display. Previously it was tracked in
ActivityStackSupervisor with a field. Now the getter searches for a
focusable stack starting from top. Usually it will be the first one
- only PiP stack can be on on top and not focused.
ActivityStackSupervisor#getFocusedStack() will search across displays
for the topmost focusable stack based on the order provided by WM.
The assumption that there always exists a focused stack is still true
- ActivityStackSupervisor#getFocusedStack() should never return null.
There always exists a focusable home stack on the default display.
Bug: 111541062
Test: atest com.android.server.am
Change-Id: I92922e4298ebbe1c68791bf59406e8f387bcd564
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index 5f9f4eb..552ed16 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -339,6 +339,38 @@
this, stackId, mSupervisor, windowingMode, activityType, onTop);
}
+ ActivityStack getFocusedStack() {
+ for (int i = mStacks.size() - 1; i >= 0; --i) {
+ final ActivityStack stack = mStacks.get(i);
+ if (stack.isFocusable() && stack.shouldBeVisible(null /* starting */)) {
+ return stack;
+ }
+ }
+
+ return null;
+ }
+
+ ActivityRecord getResumedActivity() {
+ final ActivityStack focusedStack = getFocusedStack();
+ if (focusedStack == null) {
+ return null;
+ }
+ // TODO(b/111541062): Move this into ActivityStack#getResumedActivity()
+ // Check if the focused stack has the resumed activity
+ ActivityRecord resumedActivity = focusedStack.getResumedActivity();
+ if (resumedActivity == null || resumedActivity.app == null) {
+ // If there is no registered resumed activity in the stack or it is not running -
+ // try to use previously resumed one.
+ resumedActivity = focusedStack.mPausingActivity;
+ if (resumedActivity == null || resumedActivity.app == null) {
+ // If previously resumed activity doesn't work either - find the topmost running
+ // activity that can be focused.
+ resumedActivity = focusedStack.topRunningActivityLocked(true /* focusableOnly */);
+ }
+ }
+ return resumedActivity;
+ }
+
/**
* Removes stacks in the input windowing modes from the system if they are of activity type
* ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
@@ -585,7 +617,7 @@
/**
* Get the topmost stack on the display. It may be different from focused stack, because
- * focus may be on another display.
+ * some stacks are not focusable (e.g. PiP).
*/
ActivityStack getTopStack() {
return mStacks.isEmpty() ? null : mStacks.get(mStacks.size() - 1);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f02e8f6..bf9132f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -91,6 +91,7 @@
import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
+import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
import static com.android.internal.util.XmlUtils.readLongAttribute;
@@ -12825,8 +12826,8 @@
boolean needSep = printedAnything;
boolean printed = ActivityStackSupervisor.printThisActivity(pw,
- mStackSupervisor.getResumedActivityLocked(),
- dumpPackage, needSep, " ResumedActivity: ");
+ mStackSupervisor.getTopResumedActivity(), dumpPackage, needSep,
+ " ResumedActivity: ");
if (printed) {
printedAnything = true;
needSep = false;
@@ -20642,9 +20643,10 @@
}
}
- private final ActivityRecord resumedAppLocked() {
- final ActivityRecord act =
- mStackSupervisor != null ? mStackSupervisor.getResumedActivityLocked() : null;
+ // TODO(b/111541062): This method is only used for updating OOM adjustments. We need to update
+ // the logic there and in mBatteryStatsService to make them aware of multiple resumed activities
+ private ActivityRecord resumedAppLocked() {
+ final ActivityRecord act = mStackSupervisor.getTopResumedActivity();
String pkg;
int uid;
if (act != null) {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 70f638d..427a48e 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1792,7 +1792,7 @@
// considers the resumed activity, as normal means will bring the activity from STOPPED
// to RESUMED. Adding PAUSING in this scenario will lead to double lifecycles.
if (!isState(STOPPED, STOPPING) || getStack().mTranslucentActivityWaiting != null
- || mStackSupervisor.getResumedActivityLocked() == this) {
+ || isResumedActivityOnDisplay()) {
return false;
}
@@ -3003,6 +3003,15 @@
return mStackSupervisor.topRunningActivityLocked() == this;
}
+ /**
+ * @return {@code true} if this is the resumed activity on its current display, {@code false}
+ * otherwise.
+ */
+ boolean isResumedActivityOnDisplay() {
+ final ActivityDisplay display = getDisplay();
+ return display != null && this == display.getResumedActivity();
+ }
+
void registerRemoteAnimations(RemoteAnimationDefinition definition) {
mWindowContainerController.registerRemoteAnimations(definition);
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index bebaede..d9efb0f 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -847,7 +847,7 @@
}
}
- private ActivityRecord topRunningActivityLocked(boolean focusableOnly) {
+ ActivityRecord topRunningActivityLocked(boolean focusableOnly) {
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked();
if (r != null && (!focusableOnly || r.isFocusable())) {
@@ -1052,12 +1052,14 @@
if (!isActivityTypeHome() && returnsToHomeStack()) {
// Make sure the home stack is behind this stack since that is where we should return to
// when this stack is no longer visible.
+ // TODO(b/111541062): Move home stack on the current display
mStackSupervisor.moveHomeStackToFront(reason + " returnToHome");
}
display.positionChildAtTop(this);
mStackSupervisor.setFocusStackUnchecked(reason, this);
if (task != null) {
+ // This also moves the entire hierarchy branch to top, including parents
insertTaskAtTop(task, null);
return;
}
@@ -1083,6 +1085,8 @@
getDisplay().positionChildAtBottom(this);
mStackSupervisor.setFocusStackUnchecked(reason, getDisplay().getTopStack());
if (task != null) {
+ // TODO(b/111541062): We probably don't want to change display z-order to bottom just
+ // because one of its stacks moved to bottom.
insertTaskAtBottom(task);
return;
}
@@ -1734,7 +1738,17 @@
}
boolean isTopStackOnDisplay() {
- return getDisplay().isTopStack(this);
+ final ActivityDisplay display = getDisplay();
+ return display != null && display.isTopStack(this);
+ }
+
+ /**
+ * @return {@code true} if this is the focused stack on its current display, {@code false}
+ * otherwise.
+ */
+ boolean isFocusedStackOnDisplay() {
+ final ActivityDisplay display = getDisplay();
+ return display != null && this == display.getFocusedStack();
}
boolean isTopActivityVisible() {
@@ -1751,9 +1765,6 @@
if (!isAttached() || mForceHidden) {
return false;
}
- if (mStackSupervisor.isFocusedStack(this)) {
- return true;
- }
final ActivityRecord top = topRunningActivityLocked();
if (top == null && isInStackLocked(starting) == null && !isTopStackOnDisplay()) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index e3e1c48..fe594a8 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -336,9 +336,6 @@
* Display.DEFAULT_DISPLAY. */
ActivityStack mHomeStack;
- /** The stack currently receiving input or launching the next activity. */
- ActivityStack mFocusedStack;
-
/** If this is the same as mFocusedStack then the activity on the top of the focused stack has
* been resumed. If stacks are changing position this will hold the old stack until the new
* stack becomes resumed after which it will be set to mFocusedStack. */
@@ -682,12 +679,62 @@
calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
}
- mHomeStack = mFocusedStack = mLastFocusedStack = getDefaultDisplay().getOrCreateStack(
+ final ActivityDisplay defaultDisplay = getDefaultDisplay();
+ mHomeStack = mLastFocusedStack = defaultDisplay.getOrCreateStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
}
ActivityStack getFocusedStack() {
- return mFocusedStack;
+ mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds);
+
+ for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) {
+ final int displayId = mTmpOrderedDisplayIds.get(i);
+ final ActivityDisplay display = mActivityDisplays.get(displayId);
+
+ // If WindowManagerService has encountered the display before we have, ignore as there
+ // will be no stacks present and therefore no activities.
+ if (display == null) {
+ continue;
+ }
+ final ActivityStack focusedStack = display.getFocusedStack();
+ if (focusedStack != null) {
+ return focusedStack;
+ }
+ }
+ return null;
+ }
+
+ ActivityRecord getTopResumedActivity() {
+ if (mWindowManager == null) {
+ return null;
+ }
+
+ final ActivityStack focusedStack = getFocusedStack();
+ if (focusedStack == null) {
+ return null;
+ }
+ final ActivityRecord resumedActivity = focusedStack.getResumedActivity();
+ if (resumedActivity != null && resumedActivity.app != null) {
+ return resumedActivity;
+ }
+ // The top focused stack might not have a resumed activity yet - look on all displays in
+ // focus order.
+ mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds);
+ for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) {
+ final int displayId = mTmpOrderedDisplayIds.get(i);
+ final ActivityDisplay display = mActivityDisplays.get(displayId);
+
+ // If WindowManagerService has encountered the display before we have, ignore as there
+ // will be no stacks present and therefore no activities.
+ if (display == null) {
+ continue;
+ }
+ final ActivityRecord resumedActivityOnDisplay = display.getResumedActivity();
+ if (resumedActivityOnDisplay != null) {
+ return resumedActivityOnDisplay;
+ }
+ }
+ return null;
}
boolean isFocusable(ConfigurationContainer container, boolean alwaysFocusable) {
@@ -703,7 +750,7 @@
}
boolean isFocusedStack(ActivityStack stack) {
- return stack != null && stack == mFocusedStack;
+ return stack != null && stack == getFocusedStack();
}
/** NOTE: Should only be called from {@link ActivityStack#moveToFront} */
@@ -718,12 +765,12 @@
}
}
- if (focusCandidate != mFocusedStack) {
- mLastFocusedStack = mFocusedStack;
- mFocusedStack = focusCandidate;
-
+ final ActivityStack currentFocusedStack = getFocusedStack();
+ if (currentFocusedStack != focusCandidate) {
+ mLastFocusedStack = currentFocusedStack;
+ // TODO(b/111541062): Update event log to include focus movements on all displays
EventLogTags.writeAmFocusedStack(
- mCurrentUser, mFocusedStack == null ? -1 : mFocusedStack.getStackId(),
+ mCurrentUser, focusCandidate == null ? -1 : focusCandidate.getStackId(),
mLastFocusedStack == null ? -1 : mLastFocusedStack.getStackId(), reason);
}
@@ -961,21 +1008,6 @@
return candidateTaskId;
}
- ActivityRecord getResumedActivityLocked() {
- ActivityStack stack = mFocusedStack;
- if (stack == null) {
- return null;
- }
- ActivityRecord resumedActivity = stack.getResumedActivity();
- if (resumedActivity == null || resumedActivity.app == null) {
- resumedActivity = stack.mPausingActivity;
- if (resumedActivity == null || resumedActivity.app == null) {
- resumedActivity = stack.topRunningActivityLocked();
- }
- }
- return resumedActivity;
- }
-
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
@@ -1048,10 +1080,11 @@
}
}
// TODO: Not sure if this should check if all Paused are complete too.
+ final ActivityStack focusedStack = getFocusedStack();
if (DEBUG_STACK) Slog.d(TAG_STACK,
- "allResumedActivitiesComplete: mLastFocusedStack changing from=" +
- mLastFocusedStack + " to=" + mFocusedStack);
- mLastFocusedStack = mFocusedStack;
+ "allResumedActivitiesComplete: mLastFocusedStack changing from="
+ + mLastFocusedStack + " to=" + focusedStack);
+ mLastFocusedStack = focusedStack;
return true;
}
@@ -1235,7 +1268,7 @@
* @return The top running activity. {@code null} if none is available.
*/
ActivityRecord topRunningActivityLocked(boolean considerKeyguardState) {
- final ActivityStack focusedStack = mFocusedStack;
+ final ActivityStack focusedStack = getFocusedStack();
ActivityRecord r = focusedStack.topRunningActivityLocked();
if (r != null && isValidTopRunningActivity(r, considerKeyguardState)) {
return r;
@@ -1724,12 +1757,27 @@
boolean sendHint = forceSend;
if (!sendHint) {
- // If not forced, send power hint when the activity's process is different than the
- // current resumed activity.
- final ActivityRecord resumedActivity = getResumedActivityLocked();
- sendHint = resumedActivity == null
- || resumedActivity.app == null
- || !resumedActivity.app.equals(targetActivity.app);
+ // Send power hint if we don't know what we're launching yet
+ sendHint = targetActivity == null || targetActivity.app == null;
+ }
+
+ if (!sendHint) { // targetActivity != null
+ // Send power hint when the activity's process is different than the current resumed
+ // activity on all displays, or if there are no resumed activities in the system.
+ boolean noResumedActivities = true;
+ boolean allFocusedProcessesDiffer = true;
+ for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
+ final ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
+ final ActivityRecord resumedActivity = activityDisplay.getResumedActivity();
+ final WindowProcessController resumedActivityProcess =
+ resumedActivity == null ? null : resumedActivity.app;
+
+ noResumedActivities &= resumedActivityProcess == null;
+ if (resumedActivityProcess != null) {
+ allFocusedProcessesDiffer &= !resumedActivityProcess.equals(targetActivity.app);
+ }
+ }
+ sendHint = noResumedActivities || allFocusedProcessesDiffer;
}
if (sendHint && mService.mAm.mLocalPowerManager != null) {
@@ -2233,12 +2281,13 @@
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
- final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
+ final ActivityStack focusedStack = getFocusedStack();
+ final ActivityRecord r = focusedStack.topRunningActivityLocked();
if (r == null || !r.isState(RESUMED)) {
- mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
+ focusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.isState(RESUMED)) {
// Kick off any lingering app transitions form the MoveTaskToFront operation.
- mFocusedStack.executeAppTransition(targetOptions);
+ focusedStack.executeAppTransition(targetOptions);
}
return false;
@@ -3404,7 +3453,7 @@
return false;
}
- if (stack == mFocusedStack && stack.topRunningActivityLocked() == r) {
+ if (r == getTopResumedActivity()) {
if (DEBUG_FOCUS) Slog.d(TAG_FOCUS,
"moveActivityStackToFront: already on top, r=" + r);
return false;
@@ -3792,11 +3841,11 @@
}
boolean switchUserLocked(int userId, UserState uss) {
- final int focusStackId = mFocusedStack.getStackId();
+ final int focusStackId = getFocusedStack().getStackId();
// We dismiss the docked stack whenever we switch users.
final ActivityStack dockedStack = getDefaultDisplay().getSplitScreenPrimaryStack();
if (dockedStack != null) {
- moveTasksToFullscreenStackLocked(dockedStack, mFocusedStack == dockedStack);
+ moveTasksToFullscreenStackLocked(dockedStack, dockedStack.isFocusedStackOnDisplay());
}
// Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will
// also cause all tasks to be moved to the fullscreen stack at a position that is
@@ -3952,7 +4001,7 @@
}
public void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
+ pw.print(prefix); pw.print("mFocusedStack=" + getFocusedStack());
pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
pw.print(prefix);
pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser);
@@ -3978,13 +4027,15 @@
final long token = proto.start(fieldId);
super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
for (int displayNdx = 0; displayNdx < mActivityDisplays.size(); ++displayNdx) {
- ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
+ final ActivityDisplay activityDisplay = mActivityDisplays.valueAt(displayNdx);
activityDisplay.writeToProto(proto, DISPLAYS);
}
getKeyguardController().writeToProto(proto, KEYGUARD_CONTROLLER);
- if (mFocusedStack != null) {
- proto.write(FOCUSED_STACK_ID, mFocusedStack.mStackId);
- ActivityRecord focusedActivity = getResumedActivityLocked();
+ // TODO(b/111541062): Update tests to look for resumed activities on all displays
+ final ActivityStack focusedStack = getFocusedStack();
+ if (focusedStack != null) {
+ proto.write(FOCUSED_STACK_ID, focusedStack.mStackId);
+ final ActivityRecord focusedActivity = focusedStack.getDisplay().getResumedActivity();
if (focusedActivity != null) {
focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
}
@@ -4017,7 +4068,7 @@
ArrayList<ActivityRecord> getDumpActivitiesLocked(String name, boolean dumpVisibleStacksOnly,
boolean dumpFocusedStackOnly) {
if (dumpFocusedStackOnly) {
- return mFocusedStack.getDumpActivitiesLocked(name);
+ return getFocusedStack().getDumpActivitiesLocked(name);
} else {
ArrayList<ActivityRecord> activities = new ArrayList<>();
int numDisplays = mActivityDisplays.size();
@@ -4099,6 +4150,8 @@
}
needSep = printed;
}
+ printThisActivity(pw, activityDisplay.getResumedActivity(), dumpPackage, needSep,
+ " ResumedActivity:");
}
printed |= dumpHistoryList(fd, pw, mFinishingActivities, " ", "Fin", false, !dumpAll,
@@ -4584,9 +4637,12 @@
}
void setDockedStackMinimized(boolean minimized) {
+ // Get currently focused stack before setting mIsDockMinimized. We do this because if
+ // split-screen is active, primary stack will not be focusable (see #isFocusable) while
+ // still occluding other stacks. This will cause getFocusedStack() to return null.
+ final ActivityStack current = getFocusedStack();
mIsDockMinimized = minimized;
if (mIsDockMinimized) {
- final ActivityStack current = getFocusedStack();
if (current.inSplitScreenPrimaryWindowingMode()) {
// The primary split-screen stack can't be focused while it is minimize, so move
// focus to something else.
@@ -4850,6 +4906,7 @@
*/
List<IBinder> getTopVisibleActivities() {
final ArrayList<IBinder> topActivityTokens = new ArrayList<>();
+ final ActivityStack topFocusedStack = getFocusedStack();
// Traverse all displays.
for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
final ActivityDisplay display = mActivityDisplays.valueAt(i);
@@ -4860,7 +4917,7 @@
if (stack.shouldBeVisible(null /* starting */)) {
final ActivityRecord top = stack.getTopActivity();
if (top != null) {
- if (stack == mFocusedStack) {
+ if (stack == topFocusedStack) {
topActivityTokens.add(0, top.appToken);
} else {
topActivityTokens.add(top.appToken);
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index d59a651..a131e4a 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -802,10 +802,10 @@
null /*profilerInfo*/);
if (DEBUG_PERMISSIONS_REVIEW) {
+ final ActivityStack focusedStack = mSupervisor.getFocusedStack();
Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
true, false) + "} from uid " + callingUid + " on display "
- + (mSupervisor.mFocusedStack == null
- ? DEFAULT_DISPLAY : mSupervisor.mFocusedStack.mDisplayId));
+ + (focusedStack == null ? DEFAULT_DISPLAY : focusedStack.mDisplayId));
}
}
}
@@ -839,7 +839,7 @@
r.appTimeTracker = sourceRecord.appTimeTracker;
}
- final ActivityStack stack = mSupervisor.mFocusedStack;
+ final ActivityStack stack = mSupervisor.getFocusedStack();
// If we are starting an activity that is not from the same uid as the currently resumed
// one, check whether app switches are allowed.
@@ -1013,7 +1013,7 @@
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
synchronized (mService.mGlobalLock) {
- final ActivityStack stack = mSupervisor.mFocusedStack;
+ final ActivityStack stack = mSupervisor.getFocusedStack();
stack.mConfigWillChange = globalConfig != null
&& mService.getGlobalConfiguration().diff(globalConfig) != 0;
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
@@ -1354,7 +1354,7 @@
// If the activity being launched is the same as the one currently at the top, then
// we need to check if it should only be launched once.
- final ActivityStack topStack = mSupervisor.mFocusedStack;
+ final ActivityStack topStack = mSupervisor.getFocusedStack();
final ActivityRecord topFocused = topStack.getTopActivity();
final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
final boolean dontStart = top != null && mStartActivity.resultTo == null
@@ -1609,7 +1609,7 @@
if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
ActivityRecord checkedCaller = sourceRecord;
if (checkedCaller == null) {
- checkedCaller = mSupervisor.mFocusedStack.topRunningNonDelayedActivityLocked(
+ checkedCaller = mSupervisor.getFocusedStack().topRunningNonDelayedActivityLocked(
mNotTop);
}
if (!checkedCaller.realActivity.equals(r.realActivity)) {
@@ -2304,23 +2304,23 @@
}
final ActivityStack currentStack = task != null ? task.getStack() : null;
+ final ActivityStack focusedStack = mSupervisor.getFocusedStack();
if (currentStack != null) {
- if (mSupervisor.mFocusedStack != currentStack) {
+ if (focusedStack != currentStack) {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
"computeStackFocus: Setting " + "focused stack to r=" + r
+ " task=" + task);
} else {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
- "computeStackFocus: Focused stack already="
- + mSupervisor.mFocusedStack);
+ "computeStackFocus: Focused stack already=" + focusedStack);
}
return currentStack;
}
if (canLaunchIntoFocusedStack(r, newTask)) {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
- "computeStackFocus: Have a focused stack=" + mSupervisor.mFocusedStack);
- return mSupervisor.mFocusedStack;
+ "computeStackFocus: Have a focused stack=" + focusedStack);
+ return focusedStack;
}
if (mPreferredDisplayId != DEFAULT_DISPLAY) {
@@ -2356,7 +2356,7 @@
/** Check if provided activity record can launch in currently focused stack. */
// TODO: This method can probably be consolidated into getLaunchStack() below.
private boolean canLaunchIntoFocusedStack(ActivityRecord r, boolean newTask) {
- final ActivityStack focusedStack = mSupervisor.mFocusedStack;
+ final ActivityStack focusedStack = mSupervisor.getFocusedStack();
final boolean canUseFocusedStack;
if (focusedStack.isActivityTypeAssistant()) {
canUseFocusedStack = r.isActivityTypeAssistant();
@@ -2406,18 +2406,19 @@
}
// Otherwise handle adjacent launch.
+ final ActivityStack focusedStack = mSupervisor.getFocusedStack();
// The parent activity doesn't want to launch the activity on top of itself, but
// instead tries to put it onto other side in side-by-side mode.
- final ActivityStack parentStack = task != null ? task.getStack(): mSupervisor.mFocusedStack;
+ final ActivityStack parentStack = task != null ? task.getStack(): focusedStack;
- if (parentStack != mSupervisor.mFocusedStack) {
+ if (parentStack != focusedStack) {
// If task's parent stack is not focused - use it during adjacent launch.
return parentStack;
} else {
- if (mSupervisor.mFocusedStack != null && task == mSupervisor.mFocusedStack.topTask()) {
+ if (focusedStack != null && task == focusedStack.topTask()) {
// If task is already on top of focused stack - use it. We don't want to move the
// existing focused task to adjacent stack, just deliver new intent in this case.
- return mSupervisor.mFocusedStack;
+ return focusedStack;
}
if (parentStack != null && parentStack.inSplitScreenPrimaryWindowingMode()) {
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 3ed2875..461aaaf 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -1371,7 +1371,7 @@
r.immersive = immersive;
// update associated state if we're frontmost
- if (r == mStackSupervisor.getResumedActivityLocked()) {
+ if (r.isResumedActivityOnDisplay()) {
if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
applyUpdateLockStateLocked(r);
}
@@ -3703,7 +3703,7 @@
r.requestedVrComponent = (enabled) ? packageName : null;
// Update associated state if this activity is currently focused
- if (r == mStackSupervisor.getResumedActivityLocked()) {
+ if (r.isResumedActivityOnDisplay()) {
applyUpdateVrModeLocked(r);
}
return 0;
@@ -4720,8 +4720,9 @@
mH.post(mAmInternal::updateOomAdj);
}
+ // TODO(b/111541062): Update app time tracking to make it aware of multiple resumed activities
private void startTimeTrackingFocusedActivityLocked() {
- final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
+ final ActivityRecord resumedActivity = mStackSupervisor.getTopResumedActivity();
if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
mCurAppTimeTracker.start(resumedActivity.packageName);
}
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index efde70d..9bfb56f 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -381,7 +381,7 @@
return;
}
mStackSupervisor.moveTasksToFullscreenStackLocked(stack,
- mStackSupervisor.mFocusedStack == stack);
+ stack.isFocusedStackOnDisplay());
}
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index f2d3eb6..6fadb91 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -469,7 +469,7 @@
@Override
ActivityStack getNextFocusableStackLocked(ActivityStack currentFocus,
boolean ignoreCurrent) {
- return mFocusedStack;
+ return getFocusedStack();
}
}