Merge "Use the top stack on display instead of focused"

This commit is contained in:
Andrii Kulian
2017-02-17 18:36:05 +00:00
committed by Android (Google) Code Review
2 changed files with 59 additions and 46 deletions

View File

@@ -1559,12 +1559,13 @@ final class ActivityStack extends ConfigurationContainer implements StackWindowL
return STACK_INVISIBLE;
}
final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
final int focusedStackId = focusedStack.mStackId;
// Check position and visibility of this stack relative to the front stack on its display.
final ActivityStack topStack = getTopStackOnDisplay();
final int topStackId = topStack.mStackId;
if (StackId.isBackdropToTranslucentActivity(mStackId)
&& hasVisibleBehindActivity() && StackId.isHomeOrRecentsStack(focusedStackId)
&& !focusedStack.topActivity().fullscreen) {
&& hasVisibleBehindActivity() && StackId.isHomeOrRecentsStack(topStackId)
&& !topStack.topActivity().fullscreen) {
// The fullscreen or assistant stack should be visible if it has a visible behind
// activity behind the home or recents stack that is translucent.
return STACK_VISIBLE_ACTIVITY_BEHIND;
@@ -1574,39 +1575,39 @@ final class ActivityStack extends ConfigurationContainer implements StackWindowL
// Docked stack is always visible, except in the case where the top running activity
// task in the focus stack doesn't support any form of resizing but we show it for the
// home task even though it's not resizable.
final ActivityRecord r = focusedStack.topRunningActivityLocked();
final ActivityRecord r = topStack.topRunningActivityLocked();
final TaskRecord task = r != null ? r.task : null;
return task == null || task.supportsSplitScreen() || task.isHomeTask() ? STACK_VISIBLE
: STACK_INVISIBLE;
}
// Find the first stack behind focused stack that actually got something visible.
int stackBehindFocusedIndex = mStacks.indexOf(focusedStack) - 1;
while (stackBehindFocusedIndex >= 0 &&
mStacks.get(stackBehindFocusedIndex).topRunningActivityLocked() == null) {
stackBehindFocusedIndex--;
// Find the first stack behind front stack that actually got something visible.
int stackBehindTopIndex = mStacks.indexOf(topStack) - 1;
while (stackBehindTopIndex >= 0 &&
mStacks.get(stackBehindTopIndex).topRunningActivityLocked() == null) {
stackBehindTopIndex--;
}
if ((focusedStackId == DOCKED_STACK_ID || focusedStackId == PINNED_STACK_ID)
&& stackIndex == stackBehindFocusedIndex) {
if ((topStackId == DOCKED_STACK_ID || topStackId == PINNED_STACK_ID)
&& stackIndex == stackBehindTopIndex) {
// Stacks directly behind the docked or pinned stack are always visible.
return STACK_VISIBLE;
}
final int stackBehindFocusedId = (stackBehindFocusedIndex >= 0)
? mStacks.get(stackBehindFocusedIndex).mStackId : INVALID_STACK_ID;
final int stackBehindTopId = (stackBehindTopIndex >= 0)
? mStacks.get(stackBehindTopIndex).mStackId : INVALID_STACK_ID;
if (StackId.isBackdropToTranslucentActivity(focusedStackId)
&& focusedStack.isStackTranslucent(starting, stackBehindFocusedId)) {
if (StackId.isBackdropToTranslucentActivity(topStackId)
&& topStack.isStackTranslucent(starting, stackBehindTopId)) {
// Stacks behind the fullscreen or assistant stack with a translucent activity are
// always visible so they can act as a backdrop to the translucent activity.
// For example, dialog activities
if (stackIndex == stackBehindFocusedIndex) {
if (stackIndex == stackBehindTopIndex) {
return STACK_VISIBLE;
}
if (stackBehindFocusedIndex >= 0) {
if ((stackBehindFocusedId == DOCKED_STACK_ID
|| stackBehindFocusedId == PINNED_STACK_ID)
&& stackIndex == (stackBehindFocusedIndex - 1)) {
if (stackBehindTopIndex >= 0) {
if ((stackBehindTopId == DOCKED_STACK_ID
|| stackBehindTopId == PINNED_STACK_ID)
&& stackIndex == (stackBehindTopIndex - 1)) {
// The stack behind the docked or pinned stack is also visible so we can have a
// complete backdrop to the translucent activity when the docked stack is up.
return STACK_VISIBLE;
@@ -4271,8 +4272,8 @@ final class ActivityStack extends ConfigurationContainer implements StackWindowL
AppTimeTracker timeTracker, String reason) {
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);
final ActivityRecord focusedTopActivity = mStackSupervisor.getFocusedStack() != null
? mStackSupervisor.getFocusedStack().topActivity() : null;
final ActivityStack topStack = getTopStackOnDisplay();
final ActivityRecord topActivity = topStack != null ? topStack.topActivity() : null;
final int numTasks = mTaskHistory.size();
final int index = mTaskHistory.indexOf(tr);
if (numTasks == 0 || index < 0) {
@@ -4297,7 +4298,7 @@ final class ActivityStack extends ConfigurationContainer implements StackWindowL
insertTaskAtTop(tr, null);
// Don't refocus if invisible to current user
ActivityRecord top = tr.getTopActivity();
final ActivityRecord top = tr.getTopActivity();
if (top == null || !top.okToShowLocked()) {
addRecentActivityLocked(top);
ActivityOptions.abort(options);
@@ -4305,7 +4306,7 @@ final class ActivityStack extends ConfigurationContainer implements StackWindowL
}
// Set focus to the top running activity of this stack.
ActivityRecord r = topRunningActivityLocked();
final ActivityRecord r = topRunningActivityLocked();
mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, reason);
if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
@@ -4320,8 +4321,8 @@ final class ActivityStack extends ConfigurationContainer implements StackWindowL
}
// If a new task is moved to the front, then mark the existing top activity as supporting
// picture-in-picture while paused
if (focusedTopActivity != null) {
focusedTopActivity.supportsPictureInPictureWhilePausing = true;
if (topActivity != null) {
topActivity.supportsPictureInPictureWhilePausing = true;
}
mStackSupervisor.resumeFocusedStackTopActivityLocked();
@@ -4447,6 +4448,15 @@ final class ActivityStack extends ConfigurationContainer implements StackWindowL
return true;
}
/**
* Get the topmost stack on the current display. It may be different from focused stack, because
* focus may be on another display.
*/
private ActivityStack getTopStackOnDisplay() {
final ArrayList<ActivityStack> stacks = mActivityContainer.mActivityDisplay.mStacks;
return stacks.isEmpty() ? null : stacks.get(stacks.size() - 1);
}
static void logStartActivity(int tag, ActivityRecord r, TaskRecord task) {
final Uri data = r.intent.getData();
final String strData = data != null ? data.toSafeString() : null;

View File

@@ -181,6 +181,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener {
@@ -2772,7 +2773,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
stack.prepareFreezingTaskBounds();
// Make sure the task has the appropriate bounds/size for the stack it is in.
if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) {
if (stackId == FULLSCREEN_WORKSPACE_STACK_ID
&& !Objects.equals(task.mBounds, stack.mBounds)) {
kept = task.resize(stack.mBounds, RESIZE_MODE_SYSTEM, !mightReplaceWindow,
deferResume);
} else if (stackId == FREEFORM_WORKSPACE_STACK_ID) {
@@ -2895,6 +2897,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
mService.mTaskChangeNotificationController.notifyActivityPinned();
}
/** Move activity with its stack to front and make the stack focused. */
boolean moveFocusableActivityStackToFrontLocked(ActivityRecord r, String reason) {
if (r == null || !r.isFocusable()) {
if (DEBUG_FOCUS) Slog.d(TAG_FOCUS,
@@ -4905,24 +4908,24 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
* @return a list of activities which are the top ones in each visible stack. The first
* entry will be the focused activity.
*/
public List<IBinder> getTopVisibleActivities() {
// TODO(multi-display): Get rid of DEFAULT_DISPLAY here. Used in
// VoiceInteractionManagerServiceImpl#showSessionLocked.
final ActivityDisplay display = mActivityDisplays.get(DEFAULT_DISPLAY);
if (display == null) {
return Collections.EMPTY_LIST;
}
ArrayList<IBinder> topActivityTokens = new ArrayList<>();
final ArrayList<ActivityStack> stacks = display.mStacks;
for (int i = stacks.size() - 1; i >= 0; i--) {
ActivityStack stack = stacks.get(i);
if (stack.getStackVisibilityLocked(null) == ActivityStack.STACK_VISIBLE) {
ActivityRecord top = stack.topActivity();
if (top != null) {
if (stack == mFocusedStack) {
topActivityTokens.add(0, top.appToken);
} else {
topActivityTokens.add(top.appToken);
List<IBinder> getTopVisibleActivities() {
final ArrayList<IBinder> topActivityTokens = new ArrayList<>();
// Traverse all displays.
for (int i = mActivityDisplays.size(); i >= 0; i--) {
final ActivityDisplay display = mActivityDisplays.valueAt(i);
// Traverse all stacks on a display.
for (int j = display.mStacks.size() - 1; j >= 0; j--) {
final ActivityStack stack = display.mStacks.get(j);
// Get top activity from a visible stack and add it to the list.
if (stack.getStackVisibilityLocked(null /* starting */)
== ActivityStack.STACK_VISIBLE) {
final ActivityRecord top = stack.topActivity();
if (top != null) {
if (stack == mFocusedStack) {
topActivityTokens.add(0, top.appToken);
} else {
topActivityTokens.add(top.appToken);
}
}
}
}