Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1cebea61 authored by Winson Chung's avatar Winson Chung
Browse files

Fixing some issues with the assistant stack



- Only boost window layers for the docked stack above the windows for
  stacks that are split with the docked stack. In addition, only adjust
  the assistant windows if the docked stack windows are boosted.
- In addition, mark activities in the fullscreen stack as invisible when
  they are under another task that returns to another stack. This prevents
  all the fullscreen tasks from being visible when a translucent activity
  is started from the assistant stack.
- Also fix an issue where returning from the assistant after launching a
  fullscreen task would incorrectly being the fullscreen stack forward
  (since the assistant stack is finishing and considered translucent).
  In such cases, use the return-type of the assistant stack task to bring
  the home stack forward instead.

Bug: 37527727
Test: android.server.cts.ActivityManagerAssistantStackTests
Test: go/wm-smoke

Change-Id: Ie81fbebe016f4854c7edebf382c0c3255f1b6471
Signed-off-by: default avatarWinson Chung <winsonc@google.com>
parent b544b81b
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -745,6 +745,13 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        return null;
    }

    final TaskRecord bottomTask() {
        if (mTaskHistory.isEmpty()) {
            return null;
        }
        return mTaskHistory.get(0);
    }

    TaskRecord taskForIdLocked(int id) {
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            final TaskRecord task = mTaskHistory.get(taskNdx);
@@ -1896,7 +1903,14 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                        // the recents activity from an app.
                        behindFullscreenActivity = true;
                    }

                } else if (mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Skipping after task=" + task
                            + " returning to non-application type=" + task.getTaskToReturnTo());
                    // Once we reach a fullscreen task that should return to another task, then no
                    // other activities behind that one should be visible.
                    if (task.getTaskToReturnTo() != APPLICATION_ACTIVITY_TYPE) {
                        behindFullscreenActivity = true;
                    }
                }
            }

@@ -3366,6 +3380,16 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
     * @param allowFocusSelf Is the focus allowed to remain on the same stack.
     */
    private boolean adjustFocusToNextFocusableStackLocked(String reason, boolean allowFocusSelf) {
        if (isAssistantStack() && bottomTask() != null &&
                bottomTask().getTaskToReturnTo() == HOME_ACTIVITY_TYPE) {
            // If the current stack is the assistant stack, then use the return-to type to determine
            // whether to return to the home screen. This is needed to workaround an issue where
            // launching a fullscreen task (and subequently returning from that task) will cause
            // the fullscreen stack to be found as the next focusable stack below, even if the
            // assistant was launched over home.
            return mStackSupervisor.moveHomeStackTaskToTop(reason);
        }

        final ActivityStack stack = mStackSupervisor.getNextFocusableStackLocked(
                allowFocusSelf ? null : this);
        final String myReason = reason + " adjustFocusToNextFocusableStack";
+37 −27
Original line number Diff line number Diff line
@@ -17,13 +17,14 @@
package com.android.server.wm;

import android.util.Slog;
import android.view.Display;

import java.util.ArrayDeque;
import java.util.function.Consumer;

import static android.app.ActivityManager.StackId;
import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
@@ -56,7 +57,6 @@ class WindowLayersController {
        mService = service;
    }

    private int mHighestApplicationLayer = 0;
    private ArrayDeque<WindowState> mPinnedWindows = new ArrayDeque<>();
    private ArrayDeque<WindowState> mDockedWindows = new ArrayDeque<>();
    private ArrayDeque<WindowState> mAssistantWindows = new ArrayDeque<>();
@@ -66,6 +66,8 @@ class WindowLayersController {
    private int mCurBaseLayer;
    private int mCurLayer;
    private boolean mAnyLayerChanged;
    private int mHighestApplicationLayer;
    private int mHighestDockedAffectedLayer;
    private int mHighestLayerInImeTargetBaseLayer;
    private WindowState mImeTarget;
    private boolean mAboveImeTarget;
@@ -98,6 +100,10 @@ class WindowLayersController {
            mHighestLayerInImeTargetBaseLayer = Math.max(mHighestLayerInImeTargetBaseLayer,
                    w.mWinAnimator.mAnimLayer);
        }
        if (w.getAppToken() != null && StackId.isResizeableByDockedStack(w.getStackId())) {
            mHighestDockedAffectedLayer = Math.max(mHighestDockedAffectedLayer,
                    w.mWinAnimator.mAnimLayer);
        }

        collectSpecialWindows(w);

@@ -135,7 +141,6 @@ class WindowLayersController {
    }

    private void reset() {
        mHighestApplicationLayer = 0;
        mPinnedWindows.clear();
        mInputMethodWindows.clear();
        mDockedWindows.clear();
@@ -147,8 +152,10 @@ class WindowLayersController {
        mCurLayer = 0;
        mAnyLayerChanged = false;

        mImeTarget = mService.mInputMethodTarget;
        mHighestApplicationLayer = 0;
        mHighestDockedAffectedLayer = 0;
        mHighestLayerInImeTargetBaseLayer = (mImeTarget != null) ? mImeTarget.mBaseLayer : 0;
        mImeTarget = mService.mInputMethodTarget;
        mAboveImeTarget = false;
        mAboveImeTargetAppWindows.clear();
    }
@@ -179,33 +186,42 @@ class WindowLayersController {
            }
        }

        final Task task = w.getTask();
        if (task == null) {
            return;
        }
        final TaskStack stack = task.mStack;
        if (stack == null) {
            return;
        }
        if (stack.mStackId == PINNED_STACK_ID) {
        final int stackId = w.getAppToken() != null ? w.getStackId() : INVALID_STACK_ID;
        if (stackId == PINNED_STACK_ID) {
            mPinnedWindows.add(w);
        } else if (stack.mStackId == DOCKED_STACK_ID) {
        } else if (stackId == DOCKED_STACK_ID) {
            mDockedWindows.add(w);
        } else if (stack.mStackId == ASSISTANT_STACK_ID) {
        } else if (stackId == ASSISTANT_STACK_ID) {
            mAssistantWindows.add(w);
        }
    }

    private void adjustSpecialWindows() {
        int layer = mHighestApplicationLayer + WINDOW_LAYER_MULTIPLIER;
        // For pinned and docked stack window, we want to make them above other windows also when
        // these windows are animating.
        // The following adjustments are beyond the highest docked-affected layer
        int layer = mHighestDockedAffectedLayer +  WINDOW_LAYER_MULTIPLIER;

        // Adjust the docked stack windows and dock divider above only the windows that are affected
        // by the docked stack. When this happens, also boost the assistant window layers, otherwise
        // the docked stack windows & divider would be promoted above the assistant.
        if (!mDockedWindows.isEmpty() && mHighestDockedAffectedLayer > 0) {
            while (!mDockedWindows.isEmpty()) {
            layer = assignAndIncreaseLayerIfNeeded(mDockedWindows.remove(), layer);
                final WindowState window = mDockedWindows.remove();
                layer = assignAndIncreaseLayerIfNeeded(window, layer);
            }

            layer = assignAndIncreaseLayerIfNeeded(mDockDivider, layer);

            while (!mAssistantWindows.isEmpty()) {
                final WindowState window = mAssistantWindows.remove();
                if (window.mLayer > mHighestDockedAffectedLayer) {
                    layer = assignAndIncreaseLayerIfNeeded(window, layer);
                }
            }
        }

        // The following adjustments are beyond the highest app layer or boosted layer
        layer = Math.max(layer, mHighestApplicationLayer + WINDOW_LAYER_MULTIPLIER);

        // We know that we will be animating a relaunching window in the near future, which will
        // receive a z-order increase. We want the replaced window to immediately receive the same
        // treatment, e.g. to be above the dock divider.
@@ -213,12 +229,6 @@ class WindowLayersController {
            layer = assignAndIncreaseLayerIfNeeded(mReplacingWindows.remove(), layer);
        }

        // Adjust the assistant stack windows to be above the docked and fullscreen stack windows,
        // but under the pinned stack windows
        while (!mAssistantWindows.isEmpty()) {
            layer = assignAndIncreaseLayerIfNeeded(mAssistantWindows.remove(), layer);
        }

        while (!mPinnedWindows.isEmpty()) {
            layer = assignAndIncreaseLayerIfNeeded(mPinnedWindows.remove(), layer);
        }