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

Commit c3917ba5 authored by Gustav Sennton's avatar Gustav Sennton Committed by Android (Google) Code Review
Browse files

Merge "Refactor WindowDecoration#relayout() into smaller methods." into main

parents f8368520 833a9a0b
Loading
Loading
Loading
Loading
+51 −38
Original line number Diff line number Diff line
@@ -233,32 +233,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        }

        if (oldRootView != mResult.mRootView) {
            if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_app_handle) {
                mWindowDecorViewHolder = new AppHandleViewHolder(
                        mResult.mRootView,
                        mOnCaptionTouchListener,
                        mOnCaptionButtonClickListener
                );
            } else if (mRelayoutParams.mLayoutResId
                    == R.layout.desktop_mode_app_header) {
                loadAppInfoIfNeeded();
                mWindowDecorViewHolder = new AppHeaderViewHolder(
                        mResult.mRootView,
                        mOnCaptionTouchListener,
                        mOnCaptionButtonClickListener,
                        mOnCaptionLongClickListener,
                        mOnCaptionGenericMotionListener,
                        mAppName,
                        mAppIconBitmap,
                        () -> {
                            if (!isMaximizeMenuActive()) {
                                createMaximizeMenu();
                            }
                            return Unit.INSTANCE;
                        });
            } else {
                throw new IllegalArgumentException("Unexpected layout resource id");
            }
            mWindowDecorViewHolder = createViewHolder();
        }
        Trace.beginSection("DesktopModeWindowDecoration#relayout-binding");
        mWindowDecorViewHolder.bindData(mTaskInfo);
@@ -269,16 +244,18 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            closeMaximizeMenu();
        }

        final boolean isFreeform =
                taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM;
        final boolean isDragResizeable = isFreeform && taskInfo.isResizeable;
        if (!isDragResizeable) {
        updateDragResizeListener(oldDecorationSurface);
        updateMaximizeMenu(startT);
        Trace.endSection(); // DesktopModeWindowDecoration#relayout
    }

    private void updateDragResizeListener(SurfaceControl oldDecorationSurface) {
        if (!isDragResizable(mTaskInfo)) {
            if (!mTaskInfo.positionInParent.equals(mPositionInParent)) {
                // We still want to track caption bar's exclusion region on a non-resizeable task.
                updateExclusionRegion();
            }
            closeDragResizeListener();
            Trace.endSection(); // DesktopModeWindowDecoration#relayout
            return;
        }

@@ -312,15 +289,51 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                || !mTaskInfo.positionInParent.equals(mPositionInParent)) {
            updateExclusionRegion();
        }
    }

        if (isMaximizeMenuActive()) {
    private static boolean isDragResizable(ActivityManager.RunningTaskInfo taskInfo) {
        final boolean isFreeform =
                taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM;
        return isFreeform && taskInfo.isResizeable;
    }

    private void updateMaximizeMenu(SurfaceControl.Transaction startT) {
        if (!isDragResizable(mTaskInfo) || !isMaximizeMenuActive()) {
            return;
        }
        if (!mTaskInfo.isVisible()) {
            closeMaximizeMenu();
        } else {
            mMaximizeMenu.positionMenu(calculateMaximizeMenuPosition(), startT);
        }
    }
        Trace.endSection(); // DesktopModeWindowDecoration#relayout

    private WindowDecorationViewHolder createViewHolder() {
        if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_app_handle) {
            return new AppHandleViewHolder(
                    mResult.mRootView,
                    mOnCaptionTouchListener,
                    mOnCaptionButtonClickListener
            );
        } else if (mRelayoutParams.mLayoutResId
                == R.layout.desktop_mode_app_header) {
            loadAppInfoIfNeeded();
            return new AppHeaderViewHolder(
                    mResult.mRootView,
                    mOnCaptionTouchListener,
                    mOnCaptionButtonClickListener,
                    mOnCaptionLongClickListener,
                    mOnCaptionGenericMotionListener,
                    mAppName,
                    mAppIconBitmap,
                    () -> {
                        if (!isMaximizeMenuActive()) {
                            createMaximizeMenu();
                        }
                        return Unit.INSTANCE;
                    });
        }
        throw new IllegalArgumentException("Unexpected layout resource id");
    }

    @VisibleForTesting
+102 −83
Original line number Diff line number Diff line
@@ -213,13 +213,39 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
            return;
        }

        inflateIfNeeded(params, wct, rootView, oldLayoutResId, outResult);
        if (outResult.mRootView == null) {
            // Didn't manage to create a root view, early out.
            return;
        }
        rootView = null; // Clear it just in case we use it accidentally

        updateCaptionVisibility(outResult.mRootView, mTaskInfo.displayId);

        final Rect taskBounds = mTaskInfo.getConfiguration().windowConfiguration.getBounds();
        outResult.mWidth = taskBounds.width();
        outResult.mHeight = taskBounds.height();
        outResult.mRootView.setTaskFocusState(mTaskInfo.isFocused);
        final Resources resources = mDecorWindowContext.getResources();
        outResult.mCaptionHeight = loadDimensionPixelSize(resources, params.mCaptionHeightId);
        outResult.mCaptionWidth = params.mCaptionWidthId != Resources.ID_NULL
                ? loadDimensionPixelSize(resources, params.mCaptionWidthId) : taskBounds.width();
        outResult.mCaptionX = (outResult.mWidth - outResult.mCaptionWidth) / 2;

        updateDecorationContainerSurface(startT, outResult);
        updateCaptionContainerSurface(startT, outResult);
        updateCaptionInsets(params, wct, outResult, taskBounds);
        updateTaskSurface(params, startT, finishT, outResult);
        updateViewHost(params, startT, outResult);
    }

    private void inflateIfNeeded(RelayoutParams params, WindowContainerTransaction wct,
            T rootView, int oldLayoutResId, RelayoutResult<T> outResult) {
        if (rootView == null && params.mLayoutResId == 0) {
            throw new IllegalArgumentException("layoutResId and rootView can't both be invalid.");
        }

        outResult.mRootView = rootView;
        rootView = null; // Clear it just in case we use it accidentally

        final int oldDensityDpi = mWindowDecorConfig != null
                ? mWindowDecorConfig.densityDpi : DENSITY_DPI_UNDEFINED;
        final int oldNightMode =  mWindowDecorConfig != null
@@ -253,25 +279,17 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
            outResult.mRootView = (T) LayoutInflater.from(mDecorWindowContext)
                    .inflate(params.mLayoutResId, null);
        }
    }

        updateCaptionVisibility(outResult.mRootView, mTaskInfo.displayId);

        final Resources resources = mDecorWindowContext.getResources();
        final Configuration taskConfig = mTaskInfo.getConfiguration();
        final Rect taskBounds = taskConfig.windowConfiguration.getBounds();
        final boolean isFullscreen = taskConfig.windowConfiguration.getWindowingMode()
                == WINDOWING_MODE_FULLSCREEN;
        outResult.mWidth = taskBounds.width();
        outResult.mHeight = taskBounds.height();

        // DecorationContainerSurface
    private void updateDecorationContainerSurface(
            SurfaceControl.Transaction startT, RelayoutResult<T> outResult) {
        if (mDecorationContainerSurface == null) {
            final SurfaceControl.Builder builder = mSurfaceControlBuilderSupplier.get();
            mDecorationContainerSurface = builder
                    .setName("Decor container of Task=" + mTaskInfo.taskId)
                    .setContainerLayer()
                    .setParent(mTaskSurface)
                    .setCallsite("WindowDecoration.relayout_1")
                    .setCallsite("WindowDecoration.updateDecorationContainerSurface")
                    .build();

            startT.setTrustedOverlay(mDecorationContainerSurface, true)
@@ -281,33 +299,36 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>

        startT.setWindowCrop(mDecorationContainerSurface, outResult.mWidth, outResult.mHeight)
                .show(mDecorationContainerSurface);
    }

        // CaptionContainerSurface, CaptionWindowManager
    private void updateCaptionContainerSurface(
            SurfaceControl.Transaction startT, RelayoutResult<T> outResult) {
        if (mCaptionContainerSurface == null) {
            final SurfaceControl.Builder builder = mSurfaceControlBuilderSupplier.get();
            mCaptionContainerSurface = builder
                    .setName("Caption container of Task=" + mTaskInfo.taskId)
                    .setContainerLayer()
                    .setParent(mDecorationContainerSurface)
                    .setCallsite("WindowDecoration.relayout_2")
                    .setCallsite("WindowDecoration.updateCaptionContainerSurface")
                    .build();
        }

        outResult.mCaptionHeight = loadDimensionPixelSize(resources, params.mCaptionHeightId);
        outResult.mCaptionWidth = params.mCaptionWidthId != Resources.ID_NULL
                ? loadDimensionPixelSize(resources, params.mCaptionWidthId) : taskBounds.width();
        outResult.mCaptionX = (outResult.mWidth - outResult.mCaptionWidth) / 2;

        startT.setWindowCrop(mCaptionContainerSurface, outResult.mCaptionWidth,
                        outResult.mCaptionHeight)
                .setPosition(mCaptionContainerSurface, outResult.mCaptionX, 0 /* y */)
                .setLayer(mCaptionContainerSurface, CAPTION_LAYER_Z_ORDER)
                .show(mCaptionContainerSurface);
    }

        outResult.mRootView.setTaskFocusState(mTaskInfo.isFocused);

        // Caption insets
        if (mIsCaptionVisible) {
    private void updateCaptionInsets(RelayoutParams params, WindowContainerTransaction wct,
            RelayoutResult<T> outResult, Rect taskBounds) {
        if (!mIsCaptionVisible) {
            if (mWindowDecorationInsets != null) {
                mWindowDecorationInsets.remove(wct);
                mWindowDecorationInsets = null;
            }
            return;
        }
        // Caption inset is the full width of the task with the |captionHeight| and
        // positioned at the top of the task bounds, also in absolute coordinates.
        // So just reuse the task bounds and adjust the bottom coordinate.
@@ -326,6 +347,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
            if (params.hasInputFeatureSpy()) {
                outResult.mCustomizableCaptionRegion.set(captionInsetsRect);
            }
            final Resources resources = mDecorWindowContext.getResources();
            boundingRects = new Rect[numOfElements];
            for (int i = 0; i < numOfElements; i++) {
                final OccludingCaptionElement element =
@@ -350,32 +372,28 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
            mWindowDecorationInsets = newInsets;
            mWindowDecorationInsets.addOrUpdate(wct);
        }
        } else {
            if (mWindowDecorationInsets != null) {
                mWindowDecorationInsets.remove(wct);
                mWindowDecorationInsets = null;
            }
        }

        // Task surface itself
        float shadowRadius;
        final Point taskPosition = mTaskInfo.positionInParent;
        if (isFullscreen) {
            // Shadow is not needed for fullscreen tasks
            shadowRadius = 0;
        } else {
            shadowRadius = loadDimension(resources, params.mShadowRadiusId);
    }

    private void updateTaskSurface(RelayoutParams params, SurfaceControl.Transaction startT,
            SurfaceControl.Transaction finishT, RelayoutResult<T> outResult) {
        if (params.mSetTaskPositionAndCrop) {
            final Point taskPosition = mTaskInfo.positionInParent;
            startT.setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight);
            finishT.setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight)
                    .setPosition(mTaskSurface, taskPosition.x, taskPosition.y);
        }

        startT.setShadowRadius(mTaskSurface, shadowRadius)
                .show(mTaskSurface);
        float shadowRadius;
        if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
            // Shadow is not needed for fullscreen tasks
            shadowRadius = 0;
        } else {
            shadowRadius =
                    loadDimension(mDecorWindowContext.getResources(), params.mShadowRadiusId);
        }
        startT.setShadowRadius(mTaskSurface, shadowRadius).show(mTaskSurface);
        finishT.setShadowRadius(mTaskSurface, shadowRadius);

        if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
            if (!DesktopModeStatus.isVeiledResizeEnabled()) {
                // When fluid resize is enabled, add a background to freeform tasks
@@ -390,7 +408,10 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
        } else if (!DesktopModeStatus.isVeiledResizeEnabled()) {
            startT.unsetColor(mTaskSurface);
        }
    }

    private void updateViewHost(RelayoutParams params, SurfaceControl.Transaction onDrawTransaction,
            RelayoutResult<T> outResult) {
        Trace.beginSection("CaptionViewHostLayout");
        if (mCaptionWindowManager == null) {
            // Put caption under a container surface because ViewRootImpl sets the destination frame
@@ -399,9 +420,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
                    mTaskInfo.getConfiguration(), mCaptionContainerSurface,
                    null /* hostInputToken */);
        }

        // Caption view
        mCaptionWindowManager.setConfiguration(taskConfig);
        mCaptionWindowManager.setConfiguration(mTaskInfo.getConfiguration());
        final WindowManager.LayoutParams lp =
                new WindowManager.LayoutParams(outResult.mCaptionWidth, outResult.mCaptionHeight,
                        TYPE_APPLICATION,
@@ -414,14 +433,14 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
            mViewHost = mSurfaceControlViewHostFactory.create(mDecorWindowContext, mDisplay,
                    mCaptionWindowManager);
            if (params.mApplyStartTransactionOnDraw) {
                mViewHost.getRootSurfaceControl().applyTransactionOnDraw(startT);
                mViewHost.getRootSurfaceControl().applyTransactionOnDraw(onDrawTransaction);
            }
            mViewHost.setView(outResult.mRootView, lp);
            Trace.endSection();
        } else {
            Trace.beginSection("CaptionViewHostLayout-relayout");
            if (params.mApplyStartTransactionOnDraw) {
                mViewHost.getRootSurfaceControl().applyTransactionOnDraw(startT);
                mViewHost.getRootSurfaceControl().applyTransactionOnDraw(onDrawTransaction);
            }
            mViewHost.relayout(lp);
            Trace.endSection();