Merge "Moving all hierarchy chain to top when adjust focusable task." into rvc-dev am: 17efbc6266
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11680555 Change-Id: I3285f8b94d3ccdab2f25083dbefabe250f23a7df
This commit is contained in:
@@ -813,7 +813,7 @@ class ActivityStack extends Task {
|
||||
/** Resume next focusable stack after reparenting to another display. */
|
||||
void postReparent() {
|
||||
adjustFocusToNextFocusableTask("reparent", true /* allowFocusSelf */,
|
||||
true /* moveParentsToTop */);
|
||||
true /* moveDisplayToTop */);
|
||||
mRootWindowContainer.resumeFocusedStacksTopActivities();
|
||||
// Update visibility of activities before notifying WM. This way it won't try to resize
|
||||
// windows that are no longer visible.
|
||||
|
||||
@@ -2638,7 +2638,7 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
*/
|
||||
ActivityStack adjustFocusToNextFocusableTask(String reason) {
|
||||
return adjustFocusToNextFocusableTask(reason, false /* allowFocusSelf */,
|
||||
true /* moveParentsToTop */);
|
||||
true /* moveDisplayToTop */);
|
||||
}
|
||||
|
||||
/** Return the next focusable task by looking from the siblings and parent tasks */
|
||||
@@ -2661,11 +2661,11 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
* Find next proper focusable task and make it focused.
|
||||
* @param reason The reason of making the adjustment.
|
||||
* @param allowFocusSelf Is the focus allowed to remain on the same task.
|
||||
* @param moveParentsToTop Whether to move parents to top while making the task focused.
|
||||
* @param moveDisplayToTop Whether to move display to top while making the task focused.
|
||||
* @return The root task that now got the focus, {@code null} if none found.
|
||||
*/
|
||||
ActivityStack adjustFocusToNextFocusableTask(String reason, boolean allowFocusSelf,
|
||||
boolean moveParentsToTop) {
|
||||
boolean moveDisplayToTop) {
|
||||
ActivityStack focusableTask = (ActivityStack) getNextFocusableTask(allowFocusSelf);
|
||||
if (focusableTask == null) {
|
||||
focusableTask = mRootWindowContainer.getNextFocusableStack((ActivityStack) this,
|
||||
@@ -2676,10 +2676,17 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
}
|
||||
|
||||
final ActivityStack rootTask = (ActivityStack) focusableTask.getRootTask();
|
||||
if (!moveParentsToTop) {
|
||||
// Only move the next stack to top in its task container.
|
||||
if (!moveDisplayToTop) {
|
||||
// There may be multiple task layers above this task, so when relocating the task to the
|
||||
// top, we should move this task and each of its parent task that below display area to
|
||||
// the top of each layer.
|
||||
WindowContainer parent = focusableTask.getParent();
|
||||
parent.positionChildAt(POSITION_TOP, focusableTask, false /* includingParents */);
|
||||
WindowContainer next = focusableTask;
|
||||
do {
|
||||
parent.positionChildAt(POSITION_TOP, next, false /* includingParents */);
|
||||
next = parent;
|
||||
parent = next.getParent();
|
||||
} while (next.asTask() != null && parent != null);
|
||||
return rootTask;
|
||||
}
|
||||
|
||||
|
||||
@@ -299,8 +299,17 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
|
||||
|
||||
@Override
|
||||
void positionChildAt(int position, ActivityStack child, boolean includingParents) {
|
||||
final boolean moveToTop = (position == POSITION_TOP || position == getChildCount());
|
||||
final boolean moveToTop = position >= getChildCount() - 1;
|
||||
final boolean moveToBottom = (position == POSITION_BOTTOM || position == 0);
|
||||
|
||||
// Reset mPreferredTopFocusableStack before positioning to top or {@link
|
||||
// ActivityStackSupervisor#updateTopResumedActivityIfNeeded()} won't update the top
|
||||
// resumed activity.
|
||||
final boolean wasContained = mChildren.contains(child);
|
||||
if (moveToTop && wasContained && child.isFocusable()) {
|
||||
mPreferredTopFocusableStack = null;
|
||||
}
|
||||
|
||||
if (child.getWindowConfiguration().isAlwaysOnTop() && !moveToTop) {
|
||||
// This stack is always-on-top, override the default behavior.
|
||||
Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + this + " to bottom");
|
||||
@@ -330,6 +339,17 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
|
||||
child.updateTaskMovement(moveToTop);
|
||||
|
||||
mDisplayContent.setLayoutNeeded();
|
||||
|
||||
// The insert position may be adjusted to non-top when there is always-on-top stack. Since
|
||||
// the original position is preferred to be top, the stack should have higher priority when
|
||||
// we are looking for top focusable stack. The condition {@code wasContained} restricts the
|
||||
// preferred stack is set only when moving an existing stack to top instead of adding a new
|
||||
// stack that may be too early (e.g. in the middle of launching or reparenting).
|
||||
if (moveToTop && child.isFocusableAndVisible()) {
|
||||
mPreferredTopFocusableStack = child;
|
||||
} else if (mPreferredTopFocusableStack == child) {
|
||||
mPreferredTopFocusableStack = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -727,29 +747,10 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
|
||||
"positionStackAt: Can only have one task on display=" + this);
|
||||
}
|
||||
|
||||
final boolean movingToTop = wasContained && position >= getStackCount() - 1;
|
||||
// Reset mPreferredTopFocusableStack before positioning to top or {@link
|
||||
// ActivityStackSupervisor#updateTopResumedActivityIfNeeded()} won't update the top
|
||||
// resumed activity.
|
||||
if (movingToTop && stack.isFocusable()) {
|
||||
mPreferredTopFocusableStack = null;
|
||||
}
|
||||
|
||||
// Since positionChildAt() is called during the creation process of pinned stacks,
|
||||
// ActivityStack#getStack() can be null.
|
||||
positionStackAt(position, stack, includingParents);
|
||||
|
||||
// The insert position may be adjusted to non-top when there is always-on-top stack. Since
|
||||
// the original position is preferred to be top, the stack should have higher priority when
|
||||
// we are looking for top focusable stack. The condition {@code wasContained} restricts the
|
||||
// preferred stack is set only when moving an existing stack to top instead of adding a new
|
||||
// stack that may be too early (e.g. in the middle of launching or reparenting).
|
||||
if (movingToTop && stack.isFocusableAndVisible()) {
|
||||
mPreferredTopFocusableStack = stack;
|
||||
} else if (mPreferredTopFocusableStack == stack) {
|
||||
mPreferredTopFocusableStack = null;
|
||||
}
|
||||
|
||||
if (updateLastFocusedStackReason != null) {
|
||||
final ActivityStack currentFocusedStack = getFocusedStack();
|
||||
if (currentFocusedStack != prevFocusedStack) {
|
||||
|
||||
@@ -793,6 +793,39 @@ public class ActivityRecordTests extends ActivityTestsBase {
|
||||
assertEquals(mTask, mStack.getTopMostTask());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that when top focused activity is on secondary display, when finishing the top focused
|
||||
* activity on default display, the preferred top stack on default display should be changed by
|
||||
* adjusting focus.
|
||||
*/
|
||||
@Test
|
||||
public void testFinishActivityIfPossible_PreferredTopStackChanged() {
|
||||
final ActivityRecord topActivityOnNonTopDisplay =
|
||||
createActivityOnDisplay(true /* defaultDisplay */, null /* process */);
|
||||
ActivityStack topRootableTask = topActivityOnNonTopDisplay.getRootTask();
|
||||
topRootableTask.moveToFront("test");
|
||||
assertTrue(topRootableTask.isTopStackInDisplayArea());
|
||||
assertEquals(topRootableTask, topActivityOnNonTopDisplay.getDisplayArea()
|
||||
.mPreferredTopFocusableStack);
|
||||
|
||||
final ActivityRecord secondaryDisplayActivity =
|
||||
createActivityOnDisplay(false /* defaultDisplay */, null /* process */);
|
||||
topRootableTask = secondaryDisplayActivity.getRootTask();
|
||||
topRootableTask.moveToFront("test");
|
||||
assertTrue(topRootableTask.isTopStackInDisplayArea());
|
||||
assertEquals(topRootableTask,
|
||||
secondaryDisplayActivity.getDisplayArea().mPreferredTopFocusableStack);
|
||||
|
||||
// The global top focus activity is on secondary display now.
|
||||
// Finish top activity on default display and verify the next preferred top focusable stack
|
||||
// on default display has changed.
|
||||
topActivityOnNonTopDisplay.setState(RESUMED, "test");
|
||||
topActivityOnNonTopDisplay.finishIfPossible(0 /* resultCode */, null /* resultData */,
|
||||
null /* resultGrants */, "test", false /* oomAdj */);
|
||||
assertEquals(mTask, mStack.getTopMostTask());
|
||||
assertEquals(mStack, mActivity.getDisplayArea().mPreferredTopFocusableStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that resumed activity is paused due to finish request.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user