Merge "Moving all hierarchy chain to top when adjust focusable task." into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
17efbc6266
@@ -813,7 +813,7 @@ class ActivityStack extends Task {
|
|||||||
/** Resume next focusable stack after reparenting to another display. */
|
/** Resume next focusable stack after reparenting to another display. */
|
||||||
void postReparent() {
|
void postReparent() {
|
||||||
adjustFocusToNextFocusableTask("reparent", true /* allowFocusSelf */,
|
adjustFocusToNextFocusableTask("reparent", true /* allowFocusSelf */,
|
||||||
true /* moveParentsToTop */);
|
true /* moveDisplayToTop */);
|
||||||
mRootWindowContainer.resumeFocusedStacksTopActivities();
|
mRootWindowContainer.resumeFocusedStacksTopActivities();
|
||||||
// Update visibility of activities before notifying WM. This way it won't try to resize
|
// Update visibility of activities before notifying WM. This way it won't try to resize
|
||||||
// windows that are no longer visible.
|
// windows that are no longer visible.
|
||||||
|
|||||||
@@ -2638,7 +2638,7 @@ class Task extends WindowContainer<WindowContainer> {
|
|||||||
*/
|
*/
|
||||||
ActivityStack adjustFocusToNextFocusableTask(String reason) {
|
ActivityStack adjustFocusToNextFocusableTask(String reason) {
|
||||||
return adjustFocusToNextFocusableTask(reason, false /* allowFocusSelf */,
|
return adjustFocusToNextFocusableTask(reason, false /* allowFocusSelf */,
|
||||||
true /* moveParentsToTop */);
|
true /* moveDisplayToTop */);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the next focusable task by looking from the siblings and parent tasks */
|
/** 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.
|
* Find next proper focusable task and make it focused.
|
||||||
* @param reason The reason of making the adjustment.
|
* @param reason The reason of making the adjustment.
|
||||||
* @param allowFocusSelf Is the focus allowed to remain on the same task.
|
* @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.
|
* @return The root task that now got the focus, {@code null} if none found.
|
||||||
*/
|
*/
|
||||||
ActivityStack adjustFocusToNextFocusableTask(String reason, boolean allowFocusSelf,
|
ActivityStack adjustFocusToNextFocusableTask(String reason, boolean allowFocusSelf,
|
||||||
boolean moveParentsToTop) {
|
boolean moveDisplayToTop) {
|
||||||
ActivityStack focusableTask = (ActivityStack) getNextFocusableTask(allowFocusSelf);
|
ActivityStack focusableTask = (ActivityStack) getNextFocusableTask(allowFocusSelf);
|
||||||
if (focusableTask == null) {
|
if (focusableTask == null) {
|
||||||
focusableTask = mRootWindowContainer.getNextFocusableStack((ActivityStack) this,
|
focusableTask = mRootWindowContainer.getNextFocusableStack((ActivityStack) this,
|
||||||
@@ -2676,10 +2676,17 @@ class Task extends WindowContainer<WindowContainer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final ActivityStack rootTask = (ActivityStack) focusableTask.getRootTask();
|
final ActivityStack rootTask = (ActivityStack) focusableTask.getRootTask();
|
||||||
if (!moveParentsToTop) {
|
if (!moveDisplayToTop) {
|
||||||
// Only move the next stack to top in its task container.
|
// 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();
|
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;
|
return rootTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -299,8 +299,17 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
void positionChildAt(int position, ActivityStack child, boolean includingParents) {
|
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);
|
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) {
|
if (child.getWindowConfiguration().isAlwaysOnTop() && !moveToTop) {
|
||||||
// This stack is always-on-top, override the default behavior.
|
// This stack is always-on-top, override the default behavior.
|
||||||
Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + this + " to bottom");
|
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);
|
child.updateTaskMovement(moveToTop);
|
||||||
|
|
||||||
mDisplayContent.setLayoutNeeded();
|
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);
|
"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,
|
// Since positionChildAt() is called during the creation process of pinned stacks,
|
||||||
// ActivityStack#getStack() can be null.
|
// ActivityStack#getStack() can be null.
|
||||||
positionStackAt(position, stack, includingParents);
|
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) {
|
if (updateLastFocusedStackReason != null) {
|
||||||
final ActivityStack currentFocusedStack = getFocusedStack();
|
final ActivityStack currentFocusedStack = getFocusedStack();
|
||||||
if (currentFocusedStack != prevFocusedStack) {
|
if (currentFocusedStack != prevFocusedStack) {
|
||||||
|
|||||||
@@ -793,6 +793,39 @@ public class ActivityRecordTests extends ActivityTestsBase {
|
|||||||
assertEquals(mTask, mStack.getTopMostTask());
|
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.
|
* Verify that resumed activity is paused due to finish request.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user