Merge "Adjusting focus starting from sibling rootable app tasks" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d4fdca6e39
@@ -2543,23 +2543,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
|
||||
pauseKeyDispatchingLocked();
|
||||
|
||||
// We are finishing the top focused activity and its stack has nothing to be focused so
|
||||
// the next focusable stack should be focused.
|
||||
if (mayAdjustTop
|
||||
&& (stack.topRunningActivity() == null || !stack.isTopActivityFocusable())) {
|
||||
if (shouldAdjustGlobalFocus) {
|
||||
// Move the entire hierarchy to top with updating global top resumed activity
|
||||
// and focused application if needed.
|
||||
stack.adjustFocusToNextFocusableStack("finish-top");
|
||||
} else {
|
||||
// Only move the next stack to top in its task container.
|
||||
final TaskDisplayArea taskDisplayArea = stack.getDisplayArea();
|
||||
next = taskDisplayArea.topRunningActivity();
|
||||
if (next != null) {
|
||||
taskDisplayArea.positionStackAtTop(next.getRootTask(),
|
||||
false /* includingParents */, "finish-display-top");
|
||||
}
|
||||
}
|
||||
// We are finishing the top focused activity and its task has nothing to be focused so
|
||||
// the next focusable task should be focused.
|
||||
if (mayAdjustTop && ((ActivityStack) task).topRunningActivity(true /* focusableOnly */)
|
||||
== null) {
|
||||
task.adjustFocusToNextFocusableTask("finish-top", false /* allowFocusSelf */,
|
||||
shouldAdjustGlobalFocus);
|
||||
}
|
||||
|
||||
finishActivityResults(resultCode, resultData);
|
||||
|
||||
@@ -847,7 +847,8 @@ class ActivityStack extends Task {
|
||||
|
||||
/** Resume next focusable stack after reparenting to another display. */
|
||||
void postReparent() {
|
||||
adjustFocusToNextFocusableStack("reparent", true /* allowFocusSelf */);
|
||||
adjustFocusToNextFocusableTask("reparent", true /* allowFocusSelf */,
|
||||
true /* moveParentsToTop */);
|
||||
mRootWindowContainer.resumeFocusedStacksTopActivities();
|
||||
// Update visibility of activities before notifying WM. This way it won't try to resize
|
||||
// windows that are no longer visible.
|
||||
@@ -2069,7 +2070,7 @@ class ActivityStack extends Task {
|
||||
final String reason = "noMoreActivities";
|
||||
|
||||
if (!isActivityTypeHome()) {
|
||||
final ActivityStack nextFocusedStack = adjustFocusToNextFocusableStack(reason);
|
||||
final ActivityStack nextFocusedStack = adjustFocusToNextFocusableTask(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
|
||||
@@ -2277,48 +2278,6 @@ class ActivityStack extends Task {
|
||||
return taskTop;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 ActivityStack adjustFocusToNextFocusableStack(String reason, boolean allowFocusSelf) {
|
||||
final ActivityStack stack =
|
||||
mRootWindowContainer.getNextFocusableStack(this, !allowFocusSelf);
|
||||
final String myReason = reason + " adjustFocusToNextFocusableStack";
|
||||
if (stack == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final ActivityRecord top = stack.topRunningActivity();
|
||||
|
||||
if (stack.isActivityTypeHome() && (top == null || !top.mVisibleRequested)) {
|
||||
// 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.
|
||||
stack.getDisplayArea().moveHomeActivityToTop(reason);
|
||||
return stack;
|
||||
}
|
||||
|
||||
stack.moveToFront(myReason);
|
||||
// Top display focused stack is changed, update top resumed activity if needed.
|
||||
if (stack.mResumedActivity != null) {
|
||||
mStackSupervisor.updateTopResumedActivityIfNeeded();
|
||||
// Set focused app directly because if the next focused activity is already resumed
|
||||
// (e.g. the next top activity is on a different display), there won't have activity
|
||||
// state change to update it.
|
||||
mAtmService.setResumedActivityUncheckLocked(stack.mResumedActivity, reason);
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish the topmost activity that belongs to the crashed app. We may also finish the activity
|
||||
* that requested launch of the crashed one to prevent launch-crash loop.
|
||||
|
||||
@@ -2579,6 +2579,80 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
return currentCount[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Find next proper focusable stack and make it focused.
|
||||
* @return The stack that now got the focus, {@code null} if none found.
|
||||
*/
|
||||
ActivityStack adjustFocusToNextFocusableTask(String reason) {
|
||||
return adjustFocusToNextFocusableTask(reason, false /* allowFocusSelf */,
|
||||
true /* moveParentsToTop */);
|
||||
}
|
||||
|
||||
/** Return the next focusable task by looking from the siblings and parent tasks */
|
||||
private Task getNextFocusableTask(boolean allowFocusSelf) {
|
||||
final WindowContainer parent = getParent();
|
||||
if (parent == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Task focusableTask = parent.getTask((task) -> (allowFocusSelf || task != this)
|
||||
&& ((ActivityStack) task).isFocusableAndVisible());
|
||||
if (focusableTask == null && parent.asTask() != null) {
|
||||
return parent.asTask().getNextFocusableTask(allowFocusSelf);
|
||||
} else {
|
||||
return focusableTask;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @return The root task that now got the focus, {@code null} if none found.
|
||||
*/
|
||||
ActivityStack adjustFocusToNextFocusableTask(String reason, boolean allowFocusSelf,
|
||||
boolean moveParentsToTop) {
|
||||
ActivityStack focusableTask = (ActivityStack) getNextFocusableTask(allowFocusSelf);
|
||||
if (focusableTask == null) {
|
||||
focusableTask = mRootWindowContainer.getNextFocusableStack((ActivityStack) this,
|
||||
!allowFocusSelf);
|
||||
}
|
||||
if (focusableTask == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String myReason = reason + " adjustFocusToNextFocusableStack";
|
||||
final ActivityRecord top = focusableTask.topRunningActivity();
|
||||
final ActivityStack rootTask = (ActivityStack) focusableTask.getRootTask();
|
||||
if (focusableTask.isActivityTypeHome() && (top == null || !top.mVisibleRequested)) {
|
||||
// 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.
|
||||
focusableTask.getDisplayArea().moveHomeActivityToTop(myReason);
|
||||
return rootTask;
|
||||
}
|
||||
|
||||
if (!moveParentsToTop) {
|
||||
// Only move the next stack to top in its task container.
|
||||
WindowContainer parent = focusableTask.getParent();
|
||||
parent.positionChildAt(POSITION_TOP, focusableTask, false /* includingParents */);
|
||||
return rootTask;
|
||||
}
|
||||
|
||||
// Move the entire hierarchy to top with updating global top resumed activity
|
||||
// and focused application if needed.
|
||||
focusableTask.moveToFront(myReason);
|
||||
// Top display focused stack is changed, update top resumed activity if needed.
|
||||
if (rootTask.mResumedActivity != null) {
|
||||
mStackSupervisor.updateTopResumedActivityIfNeeded();
|
||||
// Set focused app directly because if the next focused activity is already resumed
|
||||
// (e.g. the next top activity is on a different display), there won't have activity
|
||||
// state change to update it.
|
||||
mAtmService.setResumedActivityUncheckLocked(rootTask.mResumedActivity, reason);
|
||||
}
|
||||
return rootTask;
|
||||
}
|
||||
|
||||
/** Calculate the minimum possible position for a task that can be shown to the user.
|
||||
* The minimum position will be above all other tasks that can't be shown.
|
||||
* @param minPosition The minimum position the caller is suggesting.
|
||||
|
||||
@@ -751,6 +751,31 @@ public class ActivityRecordTests extends ActivityTestsBase {
|
||||
assertTrue(stack1.isTopStackInDisplayArea());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that when finishing the top focused activity while root task was created by organizer,
|
||||
* the stack order will be changed by adjusting focus.
|
||||
*/
|
||||
@Test
|
||||
public void testFinishActivityIfPossible_adjustStackOrderOrganizedRoot() {
|
||||
// Make mStack be a the root task that created by task organizer
|
||||
mStack.mCreatedByOrganizer = true;
|
||||
|
||||
// Have two tasks (topRootableTask and mTask) as the children of mStack.
|
||||
ActivityRecord topActivity = new ActivityBuilder(mActivity.mAtmService)
|
||||
.setCreateTask(true)
|
||||
.setStack(mStack)
|
||||
.build();
|
||||
ActivityStack topRootableTask = (ActivityStack) topActivity.getTask();
|
||||
topRootableTask.moveToFront("test");
|
||||
assertTrue(mStack.isTopStackInDisplayArea());
|
||||
|
||||
// Finish top activity and verify the next focusable rootable task has adjusted to top.
|
||||
topActivity.setState(RESUMED, "test");
|
||||
topActivity.finishIfPossible(0 /* resultCode */, null /* resultData */, "test",
|
||||
false /* oomAdj */);
|
||||
assertEquals(mTask, mStack.getTopMostTask());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that resumed activity is paused due to finish request.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user