Merge changes from topic "hiddenapi-new-black"
* changes:
Start using new list of non-SDK APIs
Greylist com.google.vr.platform hidden methods
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index ebf751c..52c76cc 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -62,6 +62,8 @@
optional .com.android.server.wm.ConfigurationContainerProto configuration_container = 1;
repeated ActivityDisplayProto displays = 2;
optional KeyguardControllerProto keyguard_controller = 3;
+ // TODO(b/111541062): Focused stack and resumed activity are now per-display. Topmost instances
+ // can be obtained from top display and these fields can be removed.
optional int32 focused_stack_id = 4;
optional .com.android.server.wm.IdentifierProto resumed_activity = 5;
// Whether or not the home activity is the recents activity. This is needed for the CTS tests to
@@ -77,6 +79,8 @@
optional .com.android.server.wm.ConfigurationContainerProto configuration_container = 1;
optional int32 id = 2;
repeated ActivityStackProto stacks = 3;
+ optional int32 focused_stack_id = 4;
+ optional .com.android.server.wm.IdentifierProto resumed_activity = 5;
}
message ActivityStackProto {
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index acdc738..f98650b 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -16,6 +16,7 @@
package com.android.server.am;
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -31,13 +32,18 @@
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;
+import static com.android.server.am.ActivityDisplayProto.RESUMED_ACTIVITY;
import static com.android.server.am.ActivityDisplayProto.STACKS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
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;
@@ -350,6 +356,45 @@
return null;
}
+ ActivityStack getNextFocusableStack() {
+ return getNextFocusableStack(null /* currentFocus */, false /* ignoreCurrent */);
+ }
+
+ ActivityStack getNextFocusableStack(ActivityStack currentFocus, boolean ignoreCurrent) {
+ final int currentWindowingMode = currentFocus != null
+ ? currentFocus.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
+
+ ActivityStack candidate = null;
+ for (int i = mStacks.size() - 1; i >= 0; --i) {
+ final ActivityStack stack = mStacks.get(i);
+ if (ignoreCurrent && stack == currentFocus) {
+ continue;
+ }
+ if (!stack.isFocusable() || !stack.shouldBeVisible(null)) {
+ continue;
+ }
+
+ if (currentWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
+ && candidate == null && stack.inSplitScreenPrimaryWindowingMode()) {
+ // If the currently focused stack is in split-screen secondary we save off the
+ // top primary split-screen stack as a candidate for focus because we might
+ // prefer focus to move to an other stack to avoid primary split-screen stack
+ // overlapping with a fullscreen stack when a fullscreen stack is higher in z
+ // than the next split-screen stack. Assistant stack, I am looking at you...
+ // We only move the focus to the primary-split screen stack if there isn't a
+ // better alternative.
+ candidate = stack;
+ continue;
+ }
+ if (candidate != null && stack.inSplitScreenSecondaryWindowingMode()) {
+ // Use the candidate stack since we are now at the secondary split-screen.
+ return candidate;
+ }
+ return stack;
+ }
+ return candidate;
+ }
+
ActivityRecord getResumedActivity() {
final ActivityStack focusedStack = getFocusedStack();
if (focusedStack == null) {
@@ -372,6 +417,30 @@
}
/**
+ * Pause all activities in either all of the stacks or just the back stacks.
+ * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
+ * @param resuming The resuming activity.
+ * @param dontWait The resuming activity isn't going to wait for all activities to be paused
+ * before resuming.
+ * @return true if any activity was paused as a result of this call.
+ */
+ boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {
+ boolean someActivityPaused = false;
+ for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ // TODO(b/111541062): Check if resumed activity on this display instead
+ if (!mSupervisor.isTopDisplayFocusedStack(stack)
+ && stack.getResumedActivity() != null) {
+ if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
+ " mResumedActivity=" + stack.getResumedActivity());
+ someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
+ dontWait);
+ }
+ }
+ return someActivityPaused;
+ }
+
+ /**
* Removes stacks in the input windowing modes from the system if they are of activity type
* ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
*/
@@ -898,6 +967,16 @@
final long token = proto.start(fieldId);
super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
proto.write(ID, mDisplayId);
+ 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);
+ }
+ } else {
+ proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID);
+ }
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = mStacks.get(stackNdx);
stack.writeToProto(proto, STACKS);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index aa0315a..9f2fd4a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4380,7 +4380,7 @@
mWindowManager.deferSurfaceLayout();
try {
if (!restarting && hasVisibleActivities
- && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
+ && !mStackSupervisor.resumeFocusedStacksTopActivitiesLocked()) {
// If there was nothing to resume, and we are not already restarting this process, but
// there is a visible activity that is hosted by the process... then make sure all
// visible activities are running, taking care of restarting this process.
@@ -5468,7 +5468,7 @@
// Clean-up disabled activities.
if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
packageName, disabledClasses, true, false, userId) && mBooted) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
mStackSupervisor.scheduleIdleLocked();
}
@@ -5642,7 +5642,7 @@
}
}
if (mBooted) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
mStackSupervisor.scheduleIdleLocked();
}
}
@@ -10198,7 +10198,7 @@
} finally {
Binder.restoreCallingIdentity(ident);
}
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
BinderInternal.nSetBinderProxyCountWatermarks(6000,5500);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index bd621ed..67abedc 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1941,7 +1941,7 @@
} else {
if (deferRelaunchUntilPaused) {
stack.destroyActivityLocked(this, true /* removeFromApp */, "stop-config");
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
} else {
mStackSupervisor.updatePreviousProcessLocked(this);
}
@@ -2362,7 +2362,7 @@
frozenBeforeDestroy = true;
if (!service.updateDisplayOverrideConfigurationLocked(config, this,
false /* deferResume */, displayId)) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
service.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index cbce3f4..faa499b 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -497,7 +497,10 @@
if (DEBUG_STACK) Slog.v(TAG_STACK, "set resumed activity to:" + record + " reason:"
+ reason);
setResumedActivity(record, reason + " - onActivityStateChanged");
- mService.setResumedActivityUncheckLocked(record, reason);
+ if (record == mStackSupervisor.getTopResumedActivity()) {
+ // TODO(b/111541062): Support tracking multiple resumed activities
+ mService.setResumedActivityUncheckLocked(record, reason);
+ }
mStackSupervisor.mRecentTasks.add(record.getTask());
}
}
@@ -663,7 +666,7 @@
if (!deferEnsuringVisibility) {
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
@@ -696,7 +699,7 @@
mWindowContainerController.reparent(activityDisplay.mDisplayId, mTmpRect2, onTop);
postAddToDisplay(activityDisplay, mTmpRect2.isEmpty() ? null : mTmpRect2, onTop);
adjustFocusToNextFocusableStack("reparent", true /* allowFocusSelf */);
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
// Update visibility of activities before notifying WM. This way it won't try to resize
// windows that are no longer visible.
mStackSupervisor.ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
@@ -1445,7 +1448,7 @@
if (prev == null) {
if (resuming == null) {
Slog.wtf(TAG, "Trying to pause when nothing is resumed");
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
return false;
}
@@ -1525,7 +1528,7 @@
// pause, so just treat it as being paused now.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
if (resuming == null) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
return false;
}
@@ -1619,7 +1622,7 @@
if (resumeNext) {
final ActivityStack topStack = mStackSupervisor.getTopDisplayFocusedStack();
if (!topStack.shouldSleepOrShutDownActivities()) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked(topStack, prev, null);
} else {
checkReadyForSleep();
ActivityRecord top = topStack.topRunningActivityLocked();
@@ -1628,7 +1631,7 @@
// something. Also if the top activity on the stack is not the just paused
// activity, we need to go ahead and resume it to ensure we complete an
// in-flight app switch.
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
}
@@ -2307,7 +2310,7 @@
*
* NOTE: It is not safe to call this method directly as it can cause an activity in a
* non-focused stack to be resumed.
- * Use {@link ActivityStackSupervisor#resumeFocusedStackTopActivityLocked} to resume the
+ * Use {@link ActivityStackSupervisor#resumeFocusedStacksTopActivitiesLocked} to resume the
* right activity for the current system state.
*/
@GuardedBy("mService")
@@ -2470,7 +2473,7 @@
final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0
&& !lastResumedCanPip;
- boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
+ boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
@@ -2659,7 +2662,7 @@
// the screen based on the new activity order.
boolean notUpdated = true;
- if (mStackSupervisor.isTopDisplayFocusedStack(this)) {
+ if (isFocusedStackOnDisplay()) {
// We have special rotation behavior when here is some active activity that
// requests specific orientation or Keyguard is locked. Make sure all activity
// visibilities are set correctly as well as the transition is updated if needed
@@ -2791,12 +2794,13 @@
private boolean resumeTopActivityInNextFocusableStack(ActivityRecord prev,
ActivityOptions options, String reason) {
- if (adjustFocusToNextFocusableStack(reason)) {
+ final ActivityStack nextFocusedStack = adjustFocusToNextFocusableStack(reason);
+ if (nextFocusedStack != null) {
// Try to move focus to the next visible stack with a running activity if this
// stack is not covering the entire screen or is on a secondary display (with no home
// stack).
- return mStackSupervisor.resumeFocusedStackTopActivityLocked(
- mStackSupervisor.getTopDisplayFocusedStack(), prev, null);
+ return mStackSupervisor.resumeFocusedStacksTopActivitiesLocked(nextFocusedStack, prev,
+ null /* targetOptions */);
}
// Let's just start up the Launcher...
@@ -2809,20 +2813,6 @@
mStackSupervisor.resumeHomeStackTask(prev, reason);
}
- private TaskRecord getNextTask(TaskRecord targetTask) {
- final int index = mTaskHistory.indexOf(targetTask);
- if (index >= 0) {
- final int numTasks = mTaskHistory.size();
- for (int i = index + 1; i < numTasks; ++i) {
- TaskRecord task = mTaskHistory.get(i);
- if (task.userId == targetTask.userId) {
- return task;
- }
- }
- }
- return null;
- }
-
/** Returns the position the input task should be placed in this stack. */
int getAdjustedPositionForTask(TaskRecord task, int suggestedPosition,
ActivityRecord starting) {
@@ -3437,7 +3427,7 @@
}
// Move focus to next focusable stack if possible.
- if (adjustFocusToNextFocusableStack(myReason)) {
+ if (adjustFocusToNextFocusableStack(myReason) != null) {
return;
}
@@ -3445,21 +3435,25 @@
mStackSupervisor.moveHomeStackTaskToTop(myReason);
}
- /** Find next proper focusable stack and make it focused. */
- boolean adjustFocusToNextFocusableStack(String reason) {
+ /**
+ * Find next proper focusable stack and make it focused.
+ * @return The stack that now got the focus, {@code null} if none found.
+ */
+ ActivityStack adjustFocusToNextFocusableStack(String reason) {
return adjustFocusToNextFocusableStack(reason, false /* allowFocusSelf */);
}
/**
* Find next proper focusable stack and make it focused.
* @param allowFocusSelf Is the focus allowed to remain on the same stack.
+ * @return The stack that now got the focus, {@code null} if none found.
*/
- private boolean adjustFocusToNextFocusableStack(String reason, boolean allowFocusSelf) {
+ private ActivityStack adjustFocusToNextFocusableStack(String reason, boolean allowFocusSelf) {
final ActivityStack stack =
mStackSupervisor.getNextFocusableStackLocked(this, !allowFocusSelf);
final String myReason = reason + " adjustFocusToNextFocusableStack";
if (stack == null) {
- return false;
+ return null;
}
final ActivityRecord top = stack.topRunningActivityLocked();
@@ -3467,11 +3461,12 @@
if (stack.isActivityTypeHome() && (top == null || !top.visible)) {
// If we will be focusing on the home stack next and its current top activity isn't
// visible, then use the move the home stack task to top to make the activity visible.
- return mStackSupervisor.moveHomeStackTaskToTop(reason);
+ mStackSupervisor.moveHomeStackTaskToTop(reason);
+ return stack;
}
stack.moveToFront(myReason);
- return true;
+ return stack;
}
final void stopActivityLocked(ActivityRecord r) {
@@ -3877,7 +3872,7 @@
false /* markFrozenIfConfigChanged */, true /* deferResume */);
}
if (activityRemoved) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
"destroyActivityLocked: finishCurrentActivityLocked r=" + r +
@@ -3890,7 +3885,7 @@
if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r);
mStackSupervisor.mFinishingActivities.add(r);
r.resumeKeyDispatchingLocked();
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
return r;
}
@@ -4236,7 +4231,7 @@
}
}
if (activityRemoved) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
@@ -4431,7 +4426,7 @@
}
}
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list,
@@ -4664,7 +4659,7 @@
topActivity.supportsEnterPipOnTaskSwitch = true;
}
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
mService.getTaskChangeNotificationController().notifyTaskMovedToFront(tr.taskId);
@@ -4735,7 +4730,7 @@
return true;
}
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
return true;
}
@@ -4782,7 +4777,7 @@
if (updatedConfig) {
// Ensure the resumed state of the focus activity if we updated the configuration of
// any activity.
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
@@ -5182,7 +5177,7 @@
if (isOnHomeDisplay() && mode != REMOVE_TASK_MODE_MOVING_TO_TOP
&& mStackSupervisor.isTopDisplayFocusedStack(this)) {
String myReason = reason + " leftTaskHistoryEmpty";
- if (!inMultiWindowMode() || !adjustFocusToNextFocusableStack(myReason)) {
+ if (!inMultiWindowMode() || adjustFocusToNextFocusableStack(myReason) == null) {
mStackSupervisor.moveHomeStackToFront(myReason);
}
}
@@ -5287,7 +5282,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);
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
private ActivityStack preAddTask(TaskRecord task, String reason, boolean toTop) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 002f718..65ed8b7 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -17,10 +17,8 @@
package com.android.server.am;
import static android.Manifest.permission.ACTIVITY_EMBEDDING;
-import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.START_ANY_ACTIVITY;
-import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
@@ -76,7 +74,6 @@
import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
import static com.android.server.am.ActivityRecord.RELAUNCH_REASON_NONE;
import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
-import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
@@ -201,8 +198,8 @@
private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
private static final String TAG_STACK = TAG + POSTFIX_STACK;
- private static final String TAG_STATES = TAG + POSTFIX_STATES;
private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
+ static final String TAG_STATES = TAG + POSTFIX_STATES;
static final String TAG_TASKS = TAG + POSTFIX_TASKS;
/** How long we wait until giving up on the last activity telling us it is idle. */
@@ -821,7 +818,7 @@
// Only resume home activity if isn't finishing.
if (r != null && !r.finishing) {
moveFocusableActivityStackToFrontLocked(r, myReason);
- return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
+ return resumeFocusedStacksTopActivitiesLocked(mHomeStack, prev, null);
}
return mService.mAm.startHomeActivityLocked(mCurrentUser, myReason);
}
@@ -1119,16 +1116,8 @@
boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {
boolean someActivityPaused = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
- final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
- if (!isTopDisplayFocusedStack(stack) && stack.getResumedActivity() != null) {
- if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
- " mResumedActivity=" + stack.getResumedActivity());
- someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
- dontWait);
- }
- }
+ someActivityPaused |= mActivityDisplays.valueAt(displayNdx)
+ .pauseBackStacks(userLeaving, resuming, dontWait);
}
return someActivityPaused;
}
@@ -2175,7 +2164,7 @@
//mWindowManager.dump();
if (activityRemoved) {
- resumeFocusedStackTopActivityLocked();
+ resumeFocusedStacksTopActivitiesLocked();
}
return r;
@@ -2271,28 +2260,35 @@
}
}
- boolean resumeFocusedStackTopActivityLocked() {
- return resumeFocusedStackTopActivityLocked(null, null, null);
+ boolean resumeFocusedStacksTopActivitiesLocked() {
+ return resumeFocusedStacksTopActivitiesLocked(null, null, null);
}
- boolean resumeFocusedStackTopActivityLocked(
+ boolean resumeFocusedStacksTopActivitiesLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (!readyToResume()) {
return false;
}
- if (targetStack != null && isTopDisplayFocusedStack(targetStack)) {
+ if (targetStack != null && targetStack.isTopStackOnDisplay()) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
- final ActivityStack focusedStack = getTopDisplayFocusedStack();
- final ActivityRecord r = focusedStack.topRunningActivityLocked();
- if (r == null || !r.isState(RESUMED)) {
- focusedStack.resumeTopActivityUncheckedLocked(null, null);
- } else if (r.isState(RESUMED)) {
- // Kick off any lingering app transitions form the MoveTaskToFront operation.
- focusedStack.executeAppTransition(targetOptions);
+ // Resume all top activities in focused stacks on all displays.
+ for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
+ final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+ final ActivityStack focusedStack = display.getFocusedStack();
+ if (focusedStack == null) {
+ continue;
+ }
+ final ActivityRecord r = focusedStack.topRunningActivityLocked();
+ if (r == null || !r.isState(RESUMED)) {
+ focusedStack.resumeTopActivityUncheckedLocked(null, null);
+ } else if (r.isState(RESUMED)) {
+ // Kick off any lingering app transitions form the MoveTaskToFront operation.
+ focusedStack.executeAppTransition(targetOptions);
+ }
}
return false;
@@ -2628,58 +2624,48 @@
}
/**
- * Get next focusable stack in the system. This will search across displays and stacks
- * in last-focused order for a focusable and visible stack, different from the target stack.
+ * Get next focusable stack in the system. This will search through the stack on the same
+ * display as the current focused stack, looking for a focusable and visible stack, different
+ * from the target stack. If no valid candidates will be found, it will then go through all
+ * displays and stacks in last-focused order.
*
* @param currentFocus The stack that previously had focus.
* @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next
* candidate.
- * @return Next focusable {@link ActivityStack}, null if not found.
+ * @return Next focusable {@link ActivityStack}, {@code null} if not found.
*/
- ActivityStack getNextFocusableStackLocked(ActivityStack currentFocus, boolean ignoreCurrent) {
- mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds);
+ ActivityStack getNextFocusableStackLocked(@NonNull ActivityStack currentFocus,
+ boolean ignoreCurrent) {
+ // First look for next focusable stack on the same display
+ final ActivityDisplay preferredDisplay = currentFocus.getDisplay();
+ final ActivityStack preferredFocusableStack = preferredDisplay.getNextFocusableStack(
+ currentFocus, ignoreCurrent);
+ if (preferredFocusableStack != null) {
+ return preferredFocusableStack;
+ }
- final int currentWindowingMode = currentFocus != null
- ? currentFocus.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
- ActivityStack candidate = null;
+ // Now look through all displays
+ mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds);
for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) {
final int displayId = mTmpOrderedDisplayIds.get(i);
+ if (displayId == preferredDisplay.mDisplayId) {
+ // We've already checked this one
+ continue;
+ }
// If a display is registered in WM, it must also be available in AM.
final ActivityDisplay display = getActivityDisplayOrCreateLocked(displayId);
if (display == null) {
// Looks like the display no longer exists in the system...
continue;
}
- for (int j = display.getChildCount() - 1; j >= 0; --j) {
- final ActivityStack stack = display.getChildAt(j);
- if (ignoreCurrent && stack == currentFocus) {
- continue;
- }
- if (!stack.isFocusable() || !stack.shouldBeVisible(null)) {
- continue;
- }
-
- if (currentWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
- && candidate == null && stack.inSplitScreenPrimaryWindowingMode()) {
- // If the currently focused stack is in split-screen secondary we save off the
- // top primary split-screen stack as a candidate for focus because we might
- // prefer focus to move to an other stack to avoid primary split-screen stack
- // overlapping with a fullscreen stack when a fullscreen stack is higher in z
- // than the next split-screen stack. Assistant stack, I am looking at you...
- // We only move the focus to the primary-split screen stack if there isn't a
- // better alternative.
- candidate = stack;
- continue;
- }
- if (candidate != null && stack.inSplitScreenSecondaryWindowingMode()) {
- // Use the candidate stack since we are now at the secondary split-screen.
- return candidate;
- }
- return stack;
+ final ActivityStack nextFocusableStack = display.getNextFocusableStack(currentFocus,
+ ignoreCurrent);
+ if (nextFocusableStack != null) {
+ return nextFocusableStack;
}
}
- return candidate;
+ return null;
}
/**
@@ -2878,7 +2864,7 @@
}
ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
- resumeFocusedStackTopActivityLocked();
+ resumeFocusedStacksTopActivitiesLocked();
} finally {
mAllowDockedStackResize = true;
mWindowManager.continueSurfaceLayout();
@@ -3435,7 +3421,7 @@
// drawn signal is scheduled after the bounds animation start call on the bounds animator
// thread.
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
- resumeFocusedStackTopActivityLocked();
+ resumeFocusedStacksTopActivitiesLocked();
mService.getTaskChangeNotificationController().notifyActivityPinned(r);
}
@@ -3466,6 +3452,11 @@
"moveActivityStackToFront: r=" + r);
stack.moveToFront(reason, task);
+ // Report top activity change to tracking services and WM
+ if (r == getTopResumedActivity()) {
+ // TODO(b/111541062): Support tracking multiple resumed activities
+ mService.setResumedActivityUncheckLocked(r, reason);
+ }
return true;
}
@@ -3622,7 +3613,7 @@
// It is possible that the display will not be awake at the time we
// process the keyguard going away, which can happen before the sleep token
// is released. As a result, it is important we resume the activity here.
- resumeFocusedStackTopActivityLocked();
+ resumeFocusedStacksTopActivitiesLocked();
}
}
}
@@ -4728,7 +4719,7 @@
} break;
case RESUME_TOP_ACTIVITY_MSG: {
synchronized (mService.mGlobalLock) {
- resumeFocusedStackTopActivityLocked();
+ resumeFocusedStacksTopActivitiesLocked();
}
} break;
case SLEEP_TIMEOUT_MSG: {
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 0a1b26c..05fae83 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1367,7 +1367,7 @@
// For paranoia, make sure we have correctly resumed the top activity.
topStack.mLastPausedActivity = null;
if (mDoResume) {
- mSupervisor.resumeFocusedStackTopActivityLocked();
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
ActivityOptions.abort(mOptions);
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
@@ -1451,7 +1451,7 @@
&& !mSupervisor.isTopDisplayFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
- mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked(mTargetStack, mStartActivity,
mOptions);
}
} else if (mStartActivity != null) {
@@ -2023,7 +2023,7 @@
private void resumeTargetStackIfNeeded() {
if (mDoResume) {
- mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions);
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked(mTargetStack, null, mOptions);
} else {
ActivityOptions.abort(mOptions);
}
@@ -2139,7 +2139,7 @@
// For paranoia, make sure we have correctly resumed the top activity.
mTargetStack.mLastPausedActivity = null;
if (mDoResume) {
- mSupervisor.resumeFocusedStackTopActivityLocked();
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
ActivityOptions.abort(mOptions);
return START_DELIVERED_TO_TOP;
@@ -2157,7 +2157,7 @@
deliverNewIntent(top);
mTargetStack.mLastPausedActivity = null;
if (mDoResume) {
- mSupervisor.resumeFocusedStackTopActivityLocked();
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
return START_DELIVERED_TO_TOP;
}
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 91f2b5f..3b3263c 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -1624,7 +1624,7 @@
final ActivityRecord r = stack.topRunningActivityLocked();
if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
r, "setFocusedStack")) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
} finally {
@@ -1645,7 +1645,7 @@
}
final ActivityRecord r = task.topRunningActivityLocked();
if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
} finally {
@@ -4735,6 +4735,7 @@
updateResumedAppTrace(r);
mLastResumedActivity = r;
+ // TODO(b/111541062): Support multiple focused apps in WM
mWindowManager.setFocusedApp(r.appToken, true);
applyUpdateLockStateLocked(r);
@@ -5149,7 +5150,7 @@
}
if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
r, "setFocusedActivity")) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 2c58094..3b98f37 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -503,7 +503,7 @@
mService.mStackSupervisor.handleAppCrashLocked(r.getWindowProcessController());
if (!r.isPersistent()) {
mService.removeProcessLocked(r, false, false, "crash");
- mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
} finally {
Binder.restoreCallingIdentity(orig);
@@ -743,12 +743,12 @@
// annoy the user repeatedly. Unless it is persistent, since those
// processes run critical code.
mService.removeProcessLocked(app, false, tryAgain, "crash");
- mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
if (!showBackground) {
return false;
}
}
- mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
} else {
final TaskRecord affectedTask =
mService.mStackSupervisor.finishTopCrashedActivitiesLocked(app.getWindowProcessController(), reason);
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index e345b4d..ee4e36f 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -163,7 +163,7 @@
updateKeyguardSleepToken();
// Some stack visibility might change (e.g. docked stack)
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
mStackSupervisor.addStartingWindowsForVisibleActivities(true /* taskSwitch */);
mWindowManager.executeAppTransition();
diff --git a/services/core/java/com/android/server/am/LockTaskController.java b/services/core/java/com/android/server/am/LockTaskController.java
index 4fd01cd..643c922 100644
--- a/services/core/java/com/android/server/am/LockTaskController.java
+++ b/services/core/java/com/android/server/am/LockTaskController.java
@@ -446,7 +446,7 @@
return;
}
task.performClearTaskLocked();
- mSupervisor.resumeFocusedStackTopActivityLocked();
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
/**
@@ -578,7 +578,7 @@
if (andResume) {
mSupervisor.findTaskToMoveToFront(task, 0, null, reason,
lockTaskModeState != LOCK_TASK_MODE_NONE);
- mSupervisor.resumeFocusedStackTopActivityLocked();
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked();
mWindowManager.executeAppTransition();
} else if (lockTaskModeState != LOCK_TASK_MODE_NONE) {
mSupervisor.handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED,
@@ -653,7 +653,7 @@
}
if (taskChanged) {
- mSupervisor.resumeFocusedStackTopActivityLocked();
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
diff --git a/services/core/java/com/android/server/am/RecentsAnimation.java b/services/core/java/com/android/server/am/RecentsAnimation.java
index 1c7ad3f..c5586bb 100644
--- a/services/core/java/com/android/server/am/RecentsAnimation.java
+++ b/services/core/java/com/android/server/am/RecentsAnimation.java
@@ -287,7 +287,7 @@
mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, false);
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
// No reason to wait for the pausing activity in this case, as the hiding of
// surfaces needs to be done immediately.
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 2d0c2a8..ed5cc2e 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -16,9 +16,9 @@
package com.android.server.am;
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED;
import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM;
-import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -63,6 +63,7 @@
import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.am.TaskRecordProto.ACTIVITIES;
+import static com.android.server.am.TaskRecordProto.ACTIVITY_TYPE;
import static com.android.server.am.TaskRecordProto.BOUNDS;
import static com.android.server.am.TaskRecordProto.CONFIGURATION_CONTAINER;
import static com.android.server.am.TaskRecordProto.FULLSCREEN;
@@ -74,7 +75,6 @@
import static com.android.server.am.TaskRecordProto.REAL_ACTIVITY;
import static com.android.server.am.TaskRecordProto.RESIZE_MODE;
import static com.android.server.am.TaskRecordProto.STACK_ID;
-import static com.android.server.am.TaskRecordProto.ACTIVITY_TYPE;
import static java.lang.Integer.MAX_VALUE;
@@ -87,7 +87,6 @@
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.AppGlobals;
-import android.app.IActivityManager;
import android.app.TaskInfo;
import android.content.ComponentName;
import android.content.Intent;
@@ -478,7 +477,7 @@
mResizeMode = resizeMode;
mWindowContainerController.setResizeable(resizeMode);
mService.mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
- mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
void setTaskDockedResizing(boolean resizing) {
@@ -552,7 +551,7 @@
mService.mStackSupervisor.ensureActivitiesVisibleLocked(r, 0,
preserveWindow);
if (!kept) {
- mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
}
@@ -752,7 +751,7 @@
// The task might have already been running and its visibility needs to be synchronized
// with the visibility of the stack / windows.
supervisor.ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow);
- supervisor.resumeFocusedStackTopActivityLocked();
+ supervisor.resumeFocusedStacksTopActivitiesLocked();
}
// TODO: Handle incorrect request to move before the actual move, not after.
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index ba604e0..f854df6 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -104,11 +104,9 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -2243,7 +2241,7 @@
protected void stackSupervisorResumeFocusedStackTopActivity() {
synchronized (mService) {
- mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
diff --git a/services/core/java/com/android/server/pm/InstantAppRegistry.java b/services/core/java/com/android/server/pm/InstantAppRegistry.java
index 38b9024..06f67cd 100644
--- a/services/core/java/com/android/server/pm/InstantAppRegistry.java
+++ b/services/core/java/com/android/server/pm/InstantAppRegistry.java
@@ -1176,15 +1176,13 @@
private final class CookiePersistence extends Handler {
private static final long PERSIST_COOKIE_DELAY_MILLIS = 1000L; /* one second */
- // In case you wonder why we stash the cookies aside, we use
- // the user id for the message id and the package for the payload.
- // Handler allows removing messages by id and tag where the
- // tag is compared using ==. So to allow cancelling the
- // pending persistence for an app under a given user we use
- // the fact that package are cached by the system so the ==
- // comparison would match and we end up with a way to cancel
- // persisting the cookie for a user and package.
- private final SparseArray<ArrayMap<PackageParser.Package, SomeArgs>> mPendingPersistCookies
+ // The cookies are cached per package name per user-id in this sparse
+ // array. The caching is so that pending persistence can be canceled within
+ // a short interval. To ensure we still return pending persist cookies
+ // for a package that uninstalled and reinstalled while the persistence
+ // was still pending, we use the package name as a key for
+ // mPendingPersistCookies, since that stays stable across reinstalls.
+ private final SparseArray<ArrayMap<String, SomeArgs>> mPendingPersistCookies
= new SparseArray<>();
public CookiePersistence(Looper looper) {
@@ -1214,10 +1212,10 @@
public @Nullable byte[] getPendingPersistCookieLPr(@NonNull PackageParser.Package pkg,
@UserIdInt int userId) {
- ArrayMap<PackageParser.Package, SomeArgs> pendingWorkForUser =
+ ArrayMap<String, SomeArgs> pendingWorkForUser =
mPendingPersistCookies.get(userId);
if (pendingWorkForUser != null) {
- SomeArgs state = pendingWorkForUser.get(pkg);
+ SomeArgs state = pendingWorkForUser.get(pkg.packageName);
if (state != null) {
return (byte[]) state.arg1;
}
@@ -1237,7 +1235,7 @@
private void addPendingPersistCookieLPw(@UserIdInt int userId,
@NonNull PackageParser.Package pkg, @NonNull byte[] cookie,
@NonNull File cookieFile) {
- ArrayMap<PackageParser.Package, SomeArgs> pendingWorkForUser =
+ ArrayMap<String, SomeArgs> pendingWorkForUser =
mPendingPersistCookies.get(userId);
if (pendingWorkForUser == null) {
pendingWorkForUser = new ArrayMap<>();
@@ -1246,16 +1244,16 @@
SomeArgs args = SomeArgs.obtain();
args.arg1 = cookie;
args.arg2 = cookieFile;
- pendingWorkForUser.put(pkg, args);
+ pendingWorkForUser.put(pkg.packageName, args);
}
private SomeArgs removePendingPersistCookieLPr(@NonNull PackageParser.Package pkg,
@UserIdInt int userId) {
- ArrayMap<PackageParser.Package, SomeArgs> pendingWorkForUser =
+ ArrayMap<String, SomeArgs> pendingWorkForUser =
mPendingPersistCookies.get(userId);
SomeArgs state = null;
if (pendingWorkForUser != null) {
- state = pendingWorkForUser.remove(pkg);
+ state = pendingWorkForUser.remove(pkg.packageName);
if (pendingWorkForUser.isEmpty()) {
mPendingPersistCookies.remove(userId);
}