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

Commit a61bb061 authored by Jorge Gil's avatar Jorge Gil Committed by Android (Google) Code Review
Browse files

Merge "Add WindowDecorViewHost and WindowDecorViewHostSupplier" into main

parents 544ef065 4c008874
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.wm.shell.dagger;

import static com.android.wm.shell.shared.desktopmode.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_TASK_LIMIT;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.KeyguardManager;
import android.content.Context;
@@ -114,6 +115,8 @@ import com.android.wm.shell.unfold.qualifier.UnfoldTransition;
import com.android.wm.shell.windowdecor.CaptionWindowDecorViewModel;
import com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel;
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
import com.android.wm.shell.windowdecor.viewhost.DefaultWindowDecorViewHostSupplier;
import com.android.wm.shell.windowdecor.viewhost.WindowDecorViewHostSupplier;

import dagger.Binds;
import dagger.Lazy;
@@ -244,7 +247,8 @@ public abstract class WMShellModule {
            AssistContentRequester assistContentRequester,
            MultiInstanceHelper multiInstanceHelper,
            Optional<DesktopTasksLimiter> desktopTasksLimiter,
            Optional<DesktopActivityOrientationChangeHandler> desktopActivityOrientationHandler) {
            Optional<DesktopActivityOrientationChangeHandler> desktopActivityOrientationHandler,
            WindowDecorViewHostSupplier windowDecorViewHostSupplier) {
        if (DesktopModeStatus.canEnterDesktopMode(context)) {
            return new DesktopModeWindowDecorViewModel(
                    context,
@@ -268,7 +272,8 @@ public abstract class WMShellModule {
                    assistContentRequester,
                    multiInstanceHelper,
                    desktopTasksLimiter,
                    desktopActivityOrientationHandler);
                    desktopActivityOrientationHandler,
                    windowDecorViewHostSupplier);
        }
        return new CaptionWindowDecorViewModel(
                context,
@@ -282,7 +287,8 @@ public abstract class WMShellModule {
                displayController,
                rootTaskDisplayAreaOrganizer,
                syncQueue,
                transitions);
                transitions,
                windowDecorViewHostSupplier);
    }

    @WMSingleton
@@ -371,6 +377,13 @@ public abstract class WMShellModule {
                context, shellInit, transitions, windowDecorViewModel);
    }

    @WMSingleton
    @Provides
    static WindowDecorViewHostSupplier provideWindowDecorViewHostSupplier(
            @ShellMainThread @NonNull CoroutineScope mainScope) {
        return new DefaultWindowDecorViewHostSupplier(mainScope);
    }

    //
    // One handed mode
    //
+7 −2
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
import com.android.wm.shell.windowdecor.viewhost.WindowDecorViewHostSupplier;

/**
 * View model for the window decoration with a caption and shadows. Works with
@@ -83,6 +84,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
    private final Transitions mTransitions;
    private final Region mExclusionRegion = Region.obtain();
    private final InputManager mInputManager;
    private final WindowDecorViewHostSupplier mWindowDecorViewHostSupplier;
    private TaskOperations mTaskOperations;

    /**
@@ -120,7 +122,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
            DisplayController displayController,
            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
            SyncTransactionQueue syncQueue,
            Transitions transitions) {
            Transitions transitions,
            WindowDecorViewHostSupplier windowDecorViewHostSupplier) {
        mContext = context;
        mMainExecutor = shellExecutor;
        mMainHandler = mainHandler;
@@ -132,6 +135,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
        mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
        mSyncQueue = syncQueue;
        mTransitions = transitions;
        mWindowDecorViewHostSupplier = windowDecorViewHostSupplier;
        if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
            mTaskOperations = new TaskOperations(null, mContext, mSyncQueue);
        }
@@ -295,7 +299,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel {
                        mMainHandler,
                        mBgExecutor,
                        mMainChoreographer,
                        mSyncQueue);
                        mSyncQueue,
                        mWindowDecorViewHostSupplier);
        mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);

        final FluidResizeTaskPositioner taskPositioner =
+5 −2
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
import com.android.wm.shell.windowdecor.viewhost.WindowDecorViewHostSupplier;

/**
 * Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with
@@ -88,8 +89,10 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
            Handler handler,
            @ShellBackgroundThread ShellExecutor bgExecutor,
            Choreographer choreographer,
            SyncTransactionQueue syncQueue) {
        super(context, userContext, displayController, taskOrganizer, taskInfo, taskSurface);
            SyncTransactionQueue syncQueue,
            WindowDecorViewHostSupplier windowDecorViewHostSupplier) {
        super(context, userContext, displayController, taskOrganizer, taskInfo, taskSurface,
                windowDecorViewHostSupplier);
        mHandler = handler;
        mBgExecutor = bgExecutor;
        mChoreographer = choreographer;
+9 −3
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.ExclusionReg
import com.android.wm.shell.windowdecor.extension.InsetsStateKt;
import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
import com.android.wm.shell.windowdecor.viewhost.WindowDecorViewHostSupplier;

import kotlin.Unit;

@@ -155,6 +156,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
    private final InteractionJankMonitor mInteractionJankMonitor;
    private final MultiInstanceHelper mMultiInstanceHelper;
    private final Optional<DesktopTasksLimiter> mDesktopTasksLimiter;
    private final WindowDecorViewHostSupplier mWindowDecorViewHostSupplier;
    private boolean mTransitionDragActive;

    private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();
@@ -223,8 +225,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            AssistContentRequester assistContentRequester,
            MultiInstanceHelper multiInstanceHelper,
            Optional<DesktopTasksLimiter> desktopTasksLimiter,
            Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler
    ) {
            Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
            WindowDecorViewHostSupplier windowDecorViewHostSupplier) {
        this(
                context,
                shellExecutor,
@@ -244,6 +246,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                genericLinksParser,
                assistContentRequester,
                multiInstanceHelper,
                windowDecorViewHostSupplier,
                new DesktopModeWindowDecoration.Factory(),
                new InputMonitorFactory(),
                SurfaceControl.Transaction::new,
@@ -275,6 +278,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
            AppToWebGenericLinksParser genericLinksParser,
            AssistContentRequester assistContentRequester,
            MultiInstanceHelper multiInstanceHelper,
            WindowDecorViewHostSupplier windowDecorViewHostSupplier,
            DesktopModeWindowDecoration.Factory desktopModeWindowDecorFactory,
            InputMonitorFactory inputMonitorFactory,
            Supplier<SurfaceControl.Transaction> transactionFactory,
@@ -300,6 +304,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
        mMultiInstanceHelper = multiInstanceHelper;
        mShellCommandHandler = shellCommandHandler;
        mWindowManager = windowManager;
        mWindowDecorViewHostSupplier = windowDecorViewHostSupplier;
        mDesktopModeWindowDecorFactory = desktopModeWindowDecorFactory;
        mInputMonitorFactory = inputMonitorFactory;
        mTransactionFactory = transactionFactory;
@@ -1284,7 +1289,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
                        mRootTaskDisplayAreaOrganizer,
                        mGenericLinksParser,
                        mAssistContentRequester,
                        mMultiInstanceHelper);
                        mMultiInstanceHelper,
                        mWindowDecorViewHostSupplier);
        mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);

        final TaskPositioner taskPositioner = mTaskPositionerFactory.create(
+20 −82
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getResiz

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.WindowConfiguration.WindowingMode;
import android.app.assist.AssistContent;
@@ -92,6 +91,7 @@ import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
import com.android.wm.shell.windowdecor.viewholder.AppHandleViewHolder;
import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
import com.android.wm.shell.windowdecor.viewholder.WindowDecorationViewHolder;
import com.android.wm.shell.windowdecor.viewhost.WindowDecorViewHostSupplier;

import kotlin.Unit;
import kotlin.jvm.functions.Function0;
@@ -134,12 +134,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    private DragPositioningCallback mDragPositioningCallback;
    private DragResizeInputListener mDragResizeListener;
    private DragDetector mDragDetector;
    private Runnable mCurrentViewHostRunnable = null;
    private RelayoutParams mRelayoutParams = new RelayoutParams();
    private final WindowDecoration.RelayoutResult<WindowDecorLinearLayout> mResult =
            new WindowDecoration.RelayoutResult<>();
    private final Runnable mViewHostRunnable =
            () -> updateViewHost(mRelayoutParams, null /* onDrawTransaction */, mResult);

    private final Point mPositionInParent = new Point();
    private HandleMenu mHandleMenu;
@@ -190,14 +187,16 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
            AppToWebGenericLinksParser genericLinksParser,
            AssistContentRequester assistContentRequester,
            MultiInstanceHelper multiInstanceHelper) {
            MultiInstanceHelper multiInstanceHelper,
            WindowDecorViewHostSupplier windowDecorViewHostSupplier) {
        this (context, userContext, displayController, splitScreenController, taskOrganizer,
                taskInfo, taskSurface, handler, bgExecutor, choreographer, syncQueue,
                rootTaskDisplayAreaOrganizer, genericLinksParser, assistContentRequester,
                SurfaceControl.Builder::new, SurfaceControl.Transaction::new,
                WindowContainerTransaction::new, SurfaceControl::new, new WindowManagerWrapper(
                        context.getSystemService(WindowManager.class)),
                new SurfaceControlViewHostFactory() {}, DefaultMaximizeMenuFactory.INSTANCE,
                new SurfaceControlViewHostFactory() {}, windowDecorViewHostSupplier,
                DefaultMaximizeMenuFactory.INSTANCE,
                DefaultHandleMenuFactory.INSTANCE, multiInstanceHelper);
    }

@@ -222,13 +221,14 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            Supplier<SurfaceControl> surfaceControlSupplier,
            WindowManagerWrapper windowManagerWrapper,
            SurfaceControlViewHostFactory surfaceControlViewHostFactory,
            WindowDecorViewHostSupplier windowDecorViewHostSupplier,
            MaximizeMenuFactory maximizeMenuFactory,
            HandleMenuFactory handleMenuFactory,
            MultiInstanceHelper multiInstanceHelper) {
        super(context, userContext, displayController, taskOrganizer, taskInfo, taskSurface,
                surfaceControlBuilderSupplier, surfaceControlTransactionSupplier,
                windowContainerTransactionSupplier, surfaceControlSupplier,
                surfaceControlViewHostFactory);
                surfaceControlViewHostFactory, windowDecorViewHostSupplier);
        mSplitScreenController = splitScreenController;
        mHandler = handler;
        mBgExecutor = bgExecutor;
@@ -337,73 +337,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop) {
        Trace.beginSection("DesktopModeWindowDecoration#relayout");
        if (taskInfo.isFreeform()) {
            // The Task is in Freeform mode -> show its header in sync since it's an integral part
            // of the window itself - a delayed header might cause bad UX.
            relayoutInSync(taskInfo, startT, finishT, applyStartTransactionOnDraw,
                    shouldSetTaskPositionAndCrop);
        } else {
            // The Task is outside Freeform mode -> allow the handle view to be delayed since the
            // handle is just a small addition to the window.
            relayoutWithDelayedViewHost(taskInfo, startT, finishT, applyStartTransactionOnDraw,
                    shouldSetTaskPositionAndCrop);
        }
        Trace.endSection();
    }

    /** Run the whole relayout phase immediately without delay. */
    private void relayoutInSync(ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop) {
        // Clear the current ViewHost runnable as we will update the ViewHost here
        clearCurrentViewHostRunnable();
        updateRelayoutParamsAndSurfaces(taskInfo, startT, finishT, applyStartTransactionOnDraw,
                shouldSetTaskPositionAndCrop);
        if (mResult.mRootView != null) {
            updateViewHost(mRelayoutParams, startT, mResult);
        }
    }

    /**
     * Clear the current ViewHost runnable - to ensure it doesn't run once relayout params have been
     * updated.
     */
    private void clearCurrentViewHostRunnable() {
        if (mCurrentViewHostRunnable != null) {
            mHandler.removeCallbacks(mCurrentViewHostRunnable);
            mCurrentViewHostRunnable = null;
        }
    }

    /**
     * Relayout the window decoration but repost some of the work, to unblock the current callstack.
     */
    private void relayoutWithDelayedViewHost(ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop) {
        if (applyStartTransactionOnDraw) {
            throw new IllegalArgumentException(
                    "We cannot both sync viewhost ondraw and delay viewhost creation.");
        }
        // Clear the current ViewHost runnable as we will update the ViewHost here
        clearCurrentViewHostRunnable();
        updateRelayoutParamsAndSurfaces(taskInfo, startT, finishT,
                false /* applyStartTransactionOnDraw */, shouldSetTaskPositionAndCrop);
        if (mResult.mRootView == null) {
            // This means something blocks the window decor from showing, e.g. the task is hidden.
            // Nothing is set up in this case including the decoration surface.
            return;
        }
        // Store the current runnable so it can be removed if we start a new relayout.
        mCurrentViewHostRunnable = mViewHostRunnable;
        mHandler.post(mCurrentViewHostRunnable);
    }

    @SuppressLint("MissingPermission")
    private void updateRelayoutParamsAndSurfaces(ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop) {
        Trace.beginSection("DesktopModeWindowDecoration#updateRelayoutParamsAndSurfaces");

        if (Flags.enableDesktopWindowingAppToWeb()) {
            setCapturedLink(taskInfo.capturedLink, taskInfo.capturedLinkTimestamp);
@@ -420,8 +353,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
        final WindowContainerTransaction wct = new WindowContainerTransaction();

        Trace.beginSection("DesktopModeWindowDecoration#relayout-updateViewsAndSurfaces");
        updateViewsAndSurfaces(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
        Trace.beginSection("DesktopModeWindowDecoration#relayout-inner");
        relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
        Trace.endSection();
        // After this line, mTaskInfo is up-to-date and should be used instead of taskInfo

@@ -433,7 +366,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            // This means something blocks the window decor from showing, e.g. the task is hidden.
            // Nothing is set up in this case including the decoration surface.
            disposeStatusBarInputLayer();
            Trace.endSection(); // DesktopModeWindowDecoration#updateRelayoutParamsAndSurfaces
            Trace.endSection(); // DesktopModeWindowDecoration#relayout
            return;
        }

@@ -441,12 +374,12 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            disposeStatusBarInputLayer();
            mWindowDecorViewHolder = createViewHolder();
        }
        Trace.beginSection("DesktopModeWindowDecoration#relayout-binding");

        final Point position = new Point();
        if (isAppHandle(mWindowDecorViewHolder)) {
            position.set(determineHandlePosition());
        }
        Trace.beginSection("DesktopModeWindowDecoration#relayout-bindData");
        mWindowDecorViewHolder.bindData(mTaskInfo,
                position,
                mResult.mCaptionWidth,
@@ -460,7 +393,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        }
        updateDragResizeListener(oldDecorationSurface);
        updateMaximizeMenu(startT);
        Trace.endSection(); // DesktopModeWindowDecoration#updateRelayoutParamsAndSurfaces
        Trace.endSection(); // DesktopModeWindowDecoration#relayout
    }

    private boolean isCaptionVisible() {
@@ -638,6 +571,10 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        relayoutParams.mLayoutResId = captionLayoutId;
        relayoutParams.mCaptionHeightId = getCaptionHeightIdStatic(taskInfo.getWindowingMode());
        relayoutParams.mCaptionWidthId = getCaptionWidthId(relayoutParams.mLayoutResId);
        // Allow the handle view to be delayed since the handle is just a small addition to the
        // window, whereas the header cannot be delayed because it is expected to be visible from
        // the first frame.
        relayoutParams.mAsyncViewHost = isAppHandle;

        if (isAppHeader) {
            if (TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo)) {
@@ -1253,7 +1190,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        mExclusionRegionListener.onExclusionRegionDismissed(mTaskInfo.taskId);
        disposeResizeVeil();
        disposeStatusBarInputLayer();
        clearCurrentViewHostRunnable();
        super.close();
    }

@@ -1364,7 +1300,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
                AppToWebGenericLinksParser genericLinksParser,
                AssistContentRequester assistContentRequester,
                MultiInstanceHelper multiInstanceHelper) {
                MultiInstanceHelper multiInstanceHelper,
                WindowDecorViewHostSupplier windowDecorViewHostSupplier) {
            return new DesktopModeWindowDecoration(
                    context,
                    userContext,
@@ -1380,7 +1317,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                    rootTaskDisplayAreaOrganizer,
                    genericLinksParser,
                    assistContentRequester,
                    multiInstanceHelper);
                    multiInstanceHelper,
                    windowDecorViewHostSupplier);
        }
    }

Loading