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

Commit b35eb1af authored by Maryam Dehaini's avatar Maryam Dehaini Committed by Android (Google) Code Review
Browse files

Merge "[9/N] WindowDecor refactor: Use WindowDecoration2 when refactor is enabled" into main

parents 52f20f1d 0a69e1a8
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1197,6 +1197,7 @@ public abstract class WMShellModule {
            @ShellMainThread Handler mainHandler,
            @ShellMainThread Choreographer mainChoreographer,
            @ShellMainThread MainCoroutineDispatcher mainDispatcher,
            @ShellMainThread CoroutineScope mainScope,
            @ShellBackgroundThread CoroutineScope bgScope,
            @ShellBackgroundThread ShellExecutor bgExecutor,
            ShellInit shellInit,
@@ -1241,7 +1242,7 @@ public abstract class WMShellModule {
            return Optional.empty();
        }
        return Optional.of(new DesktopModeWindowDecorViewModel(context, shellExecutor, mainHandler,
                mainChoreographer, mainDispatcher, bgScope, bgExecutor,
                mainChoreographer, mainDispatcher, mainScope, bgScope, bgExecutor,
                shellInit, shellCommandHandler, windowManager,
                taskOrganizer, desktopUserRepositories, displayController, shellController,
                displayInsetsController, syncQueue, transitions, desktopTasksController,
+27 −20
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
     */
    private boolean mShouldPilferCaptionEvents;

    private final SparseArray<CaptionWindowDecoration> mWindowDecorByTaskId = new SparseArray<>();
    private final SparseArray<WindowDecorationWrapper> mWindowDecorByTaskId = new SparseArray<>();

    private final ISystemGestureExclusionListener mGestureExclusionListener =
            new ISystemGestureExclusionListener.Stub() {
@@ -123,6 +123,9 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
                }
            };

    private final WindowDecorationWrapper.Factory mWindowDecorationWrapperFactory =
            new WindowDecorationWrapper.Factory();

    public CaptionWindowDecorViewModel(
            Context context,
            Handler mainHandler,
@@ -173,9 +176,9 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
    @Override
    public void onFocusedTaskChanged(RunningTaskInfo taskInfo, boolean isFocusedOnDisplay,
            boolean isFocusedGlobally) {
        final WindowDecoration decor = mWindowDecorByTaskId.get(taskInfo.taskId);
        final WindowDecorationWrapper decor = mWindowDecorByTaskId.get(taskInfo.taskId);
        if (decor != null) {
            decor.relayout(decor.mTaskInfo, isFocusedGlobally, decor.mExclusionRegion);
            decor.relayout(decor.getTaskInfo(), isFocusedGlobally, decor.getExclusionRegion());
        }
    }

@@ -200,7 +203,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT

    @Override
    public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
        final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
        final WindowDecorationWrapper decoration = mWindowDecorByTaskId.get(taskInfo.taskId);

        if (decoration == null) return;

@@ -211,9 +214,10 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT

        if (ENABLE_DISPLAY_FOCUS_IN_SHELL_TRANSITIONS.isTrue()) {
            // Pass the current global focus status to avoid updates outside of a ShellTransition.
            decoration.relayout(taskInfo, decoration.mHasGlobalFocus, decoration.mExclusionRegion);
            decoration.relayout(
                    taskInfo, decoration.getHasGlobalFocus(), decoration.getExclusionRegion());
        } else {
            decoration.relayout(taskInfo, taskInfo.isFocused, decoration.mExclusionRegion);
            decoration.relayout(taskInfo, taskInfo.isFocused, decoration.getExclusionRegion());
        }
    }

@@ -238,7 +242,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
            SurfaceControl taskSurface,
            SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT) {
        final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
        final WindowDecorationWrapper decoration = mWindowDecorByTaskId.get(taskInfo.taskId);

        if (!shouldShowWindowDecor(taskInfo)) {
            if (decoration != null) {
@@ -262,7 +266,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
            RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT) {
        final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
        final WindowDecorationWrapper decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
        if (decoration == null) return;

        decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */,
@@ -273,7 +277,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT

    @Override
    public void destroyWindowDecoration(RunningTaskInfo taskInfo) {
        final CaptionWindowDecoration decoration =
        final WindowDecorationWrapper decoration =
                mWindowDecorByTaskId.removeReturnOld(taskInfo.taskId);
        if (decoration == null) return;

@@ -283,8 +287,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
    private void onExclusionRegionChanged(int displayId, @NonNull Region exclusionRegion) {
        final int decorCount = mWindowDecorByTaskId.size();
        for (int i = 0; i < decorCount; i++) {
            final CaptionWindowDecoration decoration = mWindowDecorByTaskId.valueAt(i);
            if (decoration.mTaskInfo.displayId != displayId) continue;
            final WindowDecorationWrapper decoration = mWindowDecorByTaskId.valueAt(i);
            if (decoration.getTaskInfo().displayId != displayId) continue;
            decoration.onExclusionRegionChanged(exclusionRegion);
        }
    }
@@ -331,15 +335,16 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
            SurfaceControl taskSurface,
            SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT) {
        final CaptionWindowDecoration oldDecoration = mWindowDecorByTaskId.get(taskInfo.taskId);
        final WindowDecorationWrapper oldDecoration = mWindowDecorByTaskId.get(taskInfo.taskId);
        if (oldDecoration != null) {
            // close the old decoration if it exists to avoid two window decorations being added
            oldDecoration.close();
        }
        final CaptionWindowDecoration windowDecoration =
                new CaptionWindowDecoration(
        final WindowDecorationWrapper windowDecoration = mWindowDecorationWrapperFactory
                .fromCaptionDecoration(new CaptionWindowDecoration(
                        mContext,
                        mContext.createContextAsUser(UserHandle.of(taskInfo.userId), 0 /* flags */),
                        mContext.createContextAsUser(UserHandle.of(taskInfo.userId),
                                0 /* flags */),
                        mDisplayController,
                        mTaskOrganizer,
                        taskInfo,
@@ -351,7 +356,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
                        mMainChoreographer,
                        mSyncQueue,
                        mWindowDecorViewHostSupplier,
                        mDesktopConfig);
                        mDesktopConfig)
                );
        mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);

        final FluidResizeTaskPositioner taskPositioner =
@@ -359,7 +365,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
                        mDisplayController, mDesktopState);
        final CaptionTouchEventListener touchEventListener =
                new CaptionTouchEventListener(taskInfo, taskPositioner);
        windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
        windowDecoration.setCaptionListeners(touchEventListener, touchEventListener,
                /* onLongClickListener= */ null, /* onGenericMotionListener= */ null);
        windowDecoration.setDragPositioningCallback(taskPositioner);
        windowDecoration.setTaskDragResizer(taskPositioner);
        windowDecoration.relayout(taskInfo, startT, finishT,
@@ -424,7 +431,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
                    mSyncQueue.queue(wct);
                }
            }
            final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
            final WindowDecorationWrapper decoration = mWindowDecorByTaskId.get(mTaskId);

            final int actionMasked = e.getActionMasked();
            final boolean isDown = actionMasked == MotionEvent.ACTION_DOWN;
@@ -436,7 +443,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
                final boolean downInExclusionRegion = mExclusionRegion.contains(
                        (int) e.getRawX(), (int) e.getRawY());
                final boolean isTransparentCaption =
                        TaskInfoKt.isTransparentCaptionBarAppearance(decoration.mTaskInfo);
                        TaskInfoKt.isTransparentCaptionBarAppearance(decoration.getTaskInfo());
                // MotionEvent's coordinates are relative to view, we want location in window
                // to offset position relative to caption as a whole.
                int[] viewLocation = new int[2];
@@ -492,7 +499,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
                    if (e.findPointerIndex(mDragPointerId) == -1) {
                        mDragPointerId = e.getPointerId(0);
                    }
                    final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
                    final WindowDecorationWrapper decoration = mWindowDecorByTaskId.get(mTaskId);
                    // If a decor's resize drag zone is active, don't also try to reposition it.
                    if (decoration.isHandlingDragResize()) break;
                    final int dragPointerIdx = e.findPointerIndex(mDragPointerId);
+73 −35
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.graphics.Rect
import android.graphics.Region
import android.os.Handler
import android.os.Trace
import android.os.UserHandle
import android.util.Size
import android.view.Choreographer
import android.view.InsetsSource.FLAG_FORCE_CONSUMING
@@ -77,6 +78,7 @@ import com.android.wm.shell.windowdecor.caption.AppHandleController
import com.android.wm.shell.windowdecor.caption.AppHeaderController
import com.android.wm.shell.windowdecor.caption.CaptionController
import com.android.wm.shell.windowdecor.common.DecorThemeUtil
import com.android.wm.shell.windowdecor.common.ExclusionRegionListener
import com.android.wm.shell.windowdecor.common.Theme
import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader
import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost
@@ -87,17 +89,16 @@ import com.android.wm.shell.windowdecor.extension.isTransparentCaptionBarAppeara
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainCoroutineDispatcher


/**
 * Default window decoration implementation that controls both the app handle and the app header
 * captions. This class also adds various decorations to the window including the [ResizeVeil].
 */
class DefaultWindowDecoration(
class DefaultWindowDecoration @JvmOverloads constructor(
    taskInfo: RunningTaskInfo,
    taskSurface: SurfaceControl,
    genericLinksParser: AppToWebGenericLinksParser,
    assistContentRequester: AssistContentRequester,
    private val context: Context,
    val context: Context,
    private val userContext: Context,
    private val displayController: DisplayController,
    private val taskResourceLoader: WindowDecorTaskResourceLoader,
@@ -107,6 +108,7 @@ class DefaultWindowDecoration(
    @ShellMainThread private val handler: Handler,
    @ShellMainThread private val mainExecutor: ShellExecutor,
    @ShellMainThread private val mainDispatcher: MainCoroutineDispatcher,
    @ShellMainThread private val mainScope: CoroutineScope,
    @ShellBackgroundThread private val bgScope: CoroutineScope,
    @ShellBackgroundThread private val bgExecutor: ShellExecutor,
    private val transitions: Transitions,
@@ -169,15 +171,25 @@ class DefaultWindowDecoration(
        get() = taskBounds.width()
    private val taskHeight
        get() = taskBounds.height()
    /** Returns the current user. */
    val user: UserHandle
        get() = userContext.user
    private val captionType
        get() = captionController?.captionType ?: CaptionController.CaptionType.NO_CAPTION
    val maximizeMenuController: MaximizeMenuController?
        get() = captionController?.maximizeMenuController
    val handleMenuController: HandleMenuController?
        get() = captionController?.handleMenuController
    val manageWindowsMenuController: ManageWindowsMenuController?
        get() = captionController?.manageWindowsMenuController


    init {
        taskResourceLoader.onWindowDecorCreated(taskInfo)
    }

    /** Declares whether the window decoration is being dragged. */
    private var isDragging = false
    var isDragging = false

    /**
     * Declares whether a Recents transition is currently active.
@@ -186,24 +198,24 @@ class DefaultWindowDecoration(
     * corner radius of its task surfaces, so each window decoration should stop updating the corner
     * radius of its task surface during that time.
     */
    private var isRecentsTransitionRunning = false
    var isRecentsTransitionRunning = false
        set(running) {
            field = running
            captionController?.isRecentsTransitionRunning = running
        }

    /** Adds the [dragResizeListener] which gets notified on the task being drag resized. */
    private fun addDragResizeListener(dragResizeListener: DragEventListener?) {
    fun addDragResizeListener(dragResizeListener: DragEventListener?) {
        taskDragResizer?.addDragEventListener(dragResizeListener)
    }

    /** Removes the [dragResizeListener] if previously added. */
    private fun removeDragResizeListener(dragResizeListener: DragEventListener?) {
    fun removeDragResizeListener(dragResizeListener: DragEventListener?) {
        taskDragResizer?.removeDragEventListener(dragResizeListener)
    }

    /** Set the listeners for the decorations. */
    private fun setListeners(
    fun setListeners(
        onClickListener: OnClickListener,
        onTouchListener: OnTouchListener,
        onLongClickListener: OnLongClickListener,
@@ -219,12 +231,12 @@ class DefaultWindowDecoration(
     * Sets the [exclusionRegionListener] which is notified when the exclusion region is changed or
     * dismissed.
     */
    private fun setExclusionRegionListener(exclusionRegionListener: ExclusionRegionListener) {
    fun setExclusionRegionListener(exclusionRegionListener: ExclusionRegionListener) {
        this.exclusionRegionListener = exclusionRegionListener
    }

    /** Sets the [dragPositioningCallback] which is called when a task is repositioned via drag. */
    private fun setDragPositioningCallback(dragPositioningCallback: DragPositioningCallback) {
    fun setDragPositioningCallback(dragPositioningCallback: DragPositioningCallback) {
        this.dragPositioningCallback = dragPositioningCallback
    }

@@ -245,7 +257,7 @@ class DefaultWindowDecoration(
     * Disables resizing for the [disabledResizingEdge]. Executes immediately or delays if
     * [shouldDelayUpdate].
     */
    private fun updateDisabledResizingEdge(
    fun updateDisabledResizingEdge(
        disabledResizingEdge: DisabledEdge,
        shouldDelayUpdate: Boolean
    ) {
@@ -254,7 +266,7 @@ class DefaultWindowDecoration(
        decorationContainerSurface?.let { updateDragResizeListenerIfNeeded(it) }
    }


    /** Updates all window decorations, including any existing caption. */
    override fun relayout(
        taskInfo: RunningTaskInfo,
        hasGlobalFocus: Boolean,
@@ -294,7 +306,8 @@ class DefaultWindowDecoration(
        }
    }

    private fun relayout(
    /** Updates all window decorations, including any existing caption. */
    fun relayout(
        taskInfo: RunningTaskInfo,
        startT: SurfaceControl.Transaction,
        finishT: SurfaceControl.Transaction,
@@ -446,7 +459,7 @@ class DefaultWindowDecoration(
        // the original reference so that the configuration isn't mutated on config changes and
        // diff checks can be made in WindowDecoration#relayout using the pre/post-relayout
        // configuration. See b/301119301.
        // TODO(b/301119301): consider moving the config data needed for diffs to relayout params
        // TODO: b/301119301 - consider moving the config data needed for diffs to relayout params
        // instead of using a whole Configuration as a parameter.
        val windowDecorConfig =
            if (DesktopModeFlags.ENABLE_APP_HEADER_WITH_TASK_DENSITY.isTrue && isAppHeader) {
@@ -609,7 +622,7 @@ class DefaultWindowDecoration(
            // Caption should always be visible in freeform mode. When not in freeform,
            // align with the status bar except when showing over keyguard (where it should not
            // shown).
            //  TODO(b/356405803): Investigate how it's possible for the status bar visibility to
            //  TODO: b/356405803 - Investigate how it's possible for the status bar visibility to
            //   be false while a freeform window is open if the status bar is always
            //   forcibly-shown. It may be that the InsetsState (from which |mIsStatusBarVisible|
            //   is set) still contains an invisible insets source in immersive cases even if the
@@ -722,11 +735,13 @@ class DefaultWindowDecoration(
        return exclusionRegion
    }

    private fun shouldResizeListenerHandleEvent(e: MotionEvent, offset: Point): Boolean {
    /** Returns [true] if [dragResizeListener] should handle the motion event. */
    fun shouldResizeListenerHandleEvent(e: MotionEvent, offset: Point): Boolean {
        return dragResizeListener?.shouldHandleEvent(e, offset) ?: false
    }

    private fun isHandlingDragResize(): Boolean {
    /** Returns [true] if [dragResizeListener] is handling the motion event. */
    fun isHandlingDragResize(): Boolean {
        return dragResizeListener?.isHandlingDragResize ?: false
    }

@@ -735,7 +750,8 @@ class DefaultWindowDecoration(
        dragResizeListener = null
    }

    private fun setAnimatingTaskResizeOrReposition(animatingTaskResizeOrReposition: Boolean) {
    /** Returns true if task resize or reposition is currently being animated. */
    fun setAnimatingTaskResizeOrReposition(animatingTaskResizeOrReposition: Boolean) {
        captionController?.onAnimatingTaskRepositioningOrResize(animatingTaskResizeOrReposition)
    }

@@ -761,14 +777,14 @@ class DefaultWindowDecoration(
    /**
     * Show the resize veil.
     */
    private fun showResizeVeil(taskBounds: Rect) {
    fun showResizeVeil(taskBounds: Rect) {
        getOrCreateResizeVeil().showVeil(taskSurface, taskBounds, taskInfo)
    }

    /**
     * Show the resize veil.
     */
    private fun showResizeVeil(tx: SurfaceControl.Transaction, taskBounds: Rect) {
    fun showResizeVeil(tx: SurfaceControl.Transaction, taskBounds: Rect) {
        getOrCreateResizeVeil().showVeil(
            t = tx,
            parent = taskSurface,
@@ -781,21 +797,21 @@ class DefaultWindowDecoration(
    /**
     * Set new bounds for the resize veil
     */
    private fun updateResizeVeil(newBounds: Rect) {
    fun updateResizeVeil(newBounds: Rect) {
        resizeVeil?.updateResizeVeil(newBounds)
    }

    /**
     * Set new bounds for the resize veil
     */
    private fun updateResizeVeil(tx: SurfaceControl.Transaction, newBounds: Rect) {
    fun updateResizeVeil(tx: SurfaceControl.Transaction, newBounds: Rect) {
        resizeVeil?.updateResizeVeil(tx, newBounds)
    }

    /**
     * Fade the resize veil out.
     */
    private fun hideResizeVeil() {
    fun hideResizeVeil() {
        resizeVeil?.hideVeil()
    }

@@ -804,6 +820,38 @@ class DefaultWindowDecoration(
        resizeVeil = null
    }

    /** Handles a interruption to a drag event. */
    fun handleDragInterrupted() {
        (captionController as? AppHandleController)?.handleDragInterrupted()
    }

    /**
     * Check if touch event occurred in caption when caption is unable to receive touch events
     * (i.e. when caption is behind the status bar).
     */
    fun checkTouchEventInCaption(e: MotionEvent): Boolean =
        (captionController as? AppHandleController)?.checkTouchEventInCaption(e) ?: false


    /** Checks if touch event occurred in caption's customizable region. */
    fun checkTouchEventInCustomizableRegion(e: MotionEvent): Boolean =
        (captionController as? AppHandleController)?.checkTouchEventInCustomizableRegion(e) ?: false


    /** Adds inset for caption if one exists. */
    fun addCaptionInset(wct: WindowContainerTransaction) {
        captionController?.addCaptionInset(wct)
    }

    /**
     * Announces that the app window is now being focused for accessibility. This is used after a
     * window is minimized/closed, and a new app window gains focus.
     */
    fun a11yAnnounceNewFocusedWindow() {
        (captionController as? AppHeaderController)?.a11yAnnounceFocused()
    }

    /** Closes the window decoration. */
    override fun close() {
        taskResourceLoader.onWindowDecorClosed(taskInfo)
        closeDragResizeListener()
@@ -832,6 +880,7 @@ class DefaultWindowDecoration(
                handler,
                mainExecutor,
                mainDispatcher,
                mainScope,
                bgScope,
                bgExecutor,
                syncQueue,
@@ -867,6 +916,7 @@ class DefaultWindowDecoration(
                { "Expected non-null decoration container surface" },
                handler,
                mainDispatcher,
                mainScope,
                bgScope,
                windowManagerWrapper,
                multiInstanceHelper,
@@ -883,16 +933,4 @@ class DefaultWindowDecoration(

        CaptionController.CaptionType.NO_CAPTION -> null
    }

    /** Listener for changes and dismissal of the exclusion region. */
    interface ExclusionRegionListener {
        /** Inform the implementing class of this task's change in region resize handles. */
        fun onExclusionRegionChanged(taskId: Int, region: Region)

        /**
         * Inform the implementing class that this task no longer needs an exclusion region,
         * likely due to it closing.
         */
        fun onExclusionRegionDismissed(taskId: Int)
    }
}
+240 −186

File changed.

Preview size limit exceeded, changes collapsed.

+23 −92
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ import com.android.wm.shell.shared.multiinstance.ManageWindowsViewContainer;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.windowdecor.common.DecorThemeUtil;
import com.android.wm.shell.windowdecor.common.ExclusionRegionListener;
import com.android.wm.shell.windowdecor.common.Theme;
import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader;
import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost;
@@ -126,7 +127,7 @@ import kotlin.jvm.functions.Function1;
import kotlinx.coroutines.CoroutineScope;
import kotlinx.coroutines.MainCoroutineDispatcher;

import java.util.List;
import java.util.ArrayList;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
@@ -138,7 +139,8 @@ import java.util.function.Supplier;
 *
 * The shadow's thickness is 20dp when the window is in focus and 5dp when the window isn't.
 */
public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLinearLayout> {
public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLinearLayout>
        implements HandleMenuController, ManageWindowsMenuController, MaximizeMenuController {
    private static final String TAG = "DesktopModeWindowDecoration";

    @VisibleForTesting
@@ -1260,7 +1262,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        return new Point(menuLeft, menuTop);
    }

    boolean isHandleMenuActive() {
    @Override
    public boolean isHandleMenuActive() {
        return mHandleMenu != null;
    }

@@ -1428,7 +1431,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    /**
     * Create and display maximize menu window
     */
    void createMaximizeMenu() {
    @Override
    public void createMaximizeMenu() {
        if (isMaximizeMenuActive()) return;
        mDesktopModeUiEventLogger.log(mTaskInfo,
                DesktopUiEventEnum.DESKTOP_WINDOW_MAXIMIZE_BUTTON_REVEAL_MENU);
@@ -1457,7 +1461,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    }

    /** Set whether the app header's maximize button is hovered. */
    void setAppHeaderMaximizeButtonHovered(boolean hovered) {
    @Override
    public void setAppHeaderMaximizeButtonHovered(boolean hovered) {
        mIsAppHeaderMaximizeButtonHovered = hovered;
        onMaximizeHoverStateChanged();
    }
@@ -1466,7 +1471,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
     * Called when either one of the maximize button in the app header or the maximize menu has
     * changed its hover state.
     */
    void onMaximizeHoverStateChanged() {
    @Override
    public void onMaximizeHoverStateChanged() {
        if (!mIsMaximizeMenuHovered && !mIsAppHeaderMaximizeButtonHovered) {
            // Neither is hovered, close the menu.
            if (isMaximizeMenuActive()) {
@@ -1496,14 +1502,16 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        mMaximizeMenu = null;
    }

    boolean isMaximizeMenuActive() {
    @Override
    public boolean isMaximizeMenuActive() {
        return mMaximizeMenu != null;
    }

    /**
     * Updates app info and creates and displays handle menu window.
     */
    void createHandleMenu(boolean minimumInstancesFound) {
    @Override
    public void createHandleMenu(boolean minimumInstancesFound) {
        if (isHandleMenuActive()) return;
        mMinimumInstancesFound = minimumInstancesFound;
        if (AppToWebUtils.canShowAppLinks(mDisplay, mDesktopState)) {
@@ -1595,7 +1603,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        mMinimumInstancesFound = false;
    }

    void createManageWindowsMenu(@NonNull List<Pair<Integer, TaskSnapshot>> snapshotList) {
    @Override
    public void createManageWindowsMenu(
            @NonNull ArrayList<Pair<Integer, TaskSnapshot>> snapshotList) {
        final Function1<Integer, Unit> onOpenInstanceListener = (requestedTaskId) -> {
            closeManageWindowsMenu();
            if (mTaskInfo.taskId != requestedTaskId) {
@@ -1986,14 +1996,16 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    /**
     * Called when there is a {@link MotionEvent#ACTION_HOVER_EXIT} on the maximize window button.
     */
    void onMaximizeButtonHoverExit() {
    @Override
    public void onMaximizeButtonHoverExit() {
        asAppHeader(mWindowDecorViewHolder).onMaximizeWindowHoverExit();
    }

    /**
     * Called when there is a {@link MotionEvent#ACTION_HOVER_ENTER} on the maximize window button.
     */
    void onMaximizeButtonHoverEnter() {
    @Override
    public void onMaximizeButtonHoverEnter() {
        asAppHeader(mWindowDecorViewHolder).onMaximizeWindowHoverEnter();
    }

@@ -2018,76 +2030,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                + "}";
    }

    static class Factory {

        DesktopModeWindowDecoration create(
                Context context,
                @NonNull Context userContext,
                DisplayController displayController,
                @NonNull WindowDecorTaskResourceLoader appResourceProvider,
                SplitScreenController splitScreenController,
                DesktopUserRepositories desktopUserRepositories,
                ShellTaskOrganizer taskOrganizer,
                ActivityManager.RunningTaskInfo taskInfo,
                SurfaceControl taskSurface,
                @ShellMainThread Handler handler,
                @ShellMainThread ShellExecutor mainExecutor,
                @ShellMainThread MainCoroutineDispatcher mainDispatcher,
                @ShellBackgroundThread CoroutineScope bgScope,
                @ShellBackgroundThread ShellExecutor bgExecutor,
                Transitions transitions,
                Choreographer choreographer,
                SyncTransactionQueue syncQueue,
                AppHeaderViewHolder.Factory appHeaderViewHolderFactory,
                AppHandleViewHolder.Factory appHandleViewHolderFactory,
                RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
                AppToWebGenericLinksParser genericLinksParser,
                AssistContentRequester assistContentRequester,
                @NonNull WindowDecorViewHostSupplier<WindowDecorViewHost>
                        windowDecorViewHostSupplier,
                MultiInstanceHelper multiInstanceHelper,
                WindowDecorCaptionRepository windowDecorCaptionRepository,
                DesktopModeEventLogger desktopModeEventLogger,
                DesktopModeUiEventLogger desktopModeUiEventLogger,
                DesktopModeCompatPolicy desktopModeCompatPolicy,
                DesktopState desktopState,
                DesktopConfig desktopConfig,
                WindowDecorationActions windowDecorationActions) {
            return new DesktopModeWindowDecoration(
                    context,
                    userContext,
                    displayController,
                    appResourceProvider,
                    splitScreenController,
                    desktopUserRepositories,
                    taskOrganizer,
                    taskInfo,
                    taskSurface,
                    handler,
                    mainExecutor,
                    mainDispatcher,
                    bgScope,
                    bgExecutor,
                    transitions,
                    choreographer,
                    syncQueue,
                    appHeaderViewHolderFactory,
                    appHandleViewHolderFactory,
                    rootTaskDisplayAreaOrganizer,
                    genericLinksParser,
                    assistContentRequester,
                    windowDecorViewHostSupplier,
                    multiInstanceHelper,
                    windowDecorCaptionRepository,
                    desktopModeEventLogger,
                    desktopModeUiEventLogger,
                    desktopModeCompatPolicy,
                    desktopState,
                    desktopConfig,
                    windowDecorationActions);
        }
    }

    @VisibleForTesting
    static class CapturedLink {
        private final long mTimeStamp;
@@ -2103,15 +2045,4 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            mUsed = true;
        }
    }

    interface ExclusionRegionListener {
        /** Inform the implementing class of this task's change in region resize handles */
        void onExclusionRegionChanged(int taskId, Region region);

        /**
         * Inform the implementing class that this task no longer needs an exclusion region,
         * likely due to it closing.
         */
        void onExclusionRegionDismissed(int taskId);
    }
}
Loading