diff options
Diffstat (limited to 'libs')
2 files changed, 153 insertions, 121 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java index a4ade1b676ec..01a479f0bc6c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java @@ -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()) { - if (!mTaskInfo.isVisible()) { - closeMaximizeMenu(); - } else { - mMaximizeMenu.positionMenu(calculateMaximizeMenuPosition(), startT); - } + 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; } - Trace.endSection(); // DesktopModeWindowDecoration#relayout + if (!mTaskInfo.isVisible()) { + closeMaximizeMenu(); + } else { + mMaximizeMenu.positionMenu(calculateMaximizeMenuPosition(), startT); + } + } + + 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 diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java index a08f97cde06f..b9532dd9e681 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java @@ -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,101 +299,101 @@ 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) { - // 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. - final Rect captionInsetsRect = new Rect(taskBounds); - captionInsetsRect.bottom = captionInsetsRect.top + outResult.mCaptionHeight; - - // Caption bounding rectangles: these are optional, and are used to present finer - // insets than traditional |Insets| to apps about where their content is occluded. - // These are also in absolute coordinates. - final Rect[] boundingRects; - final int numOfElements = params.mOccludingCaptionElements.size(); - if (numOfElements == 0) { - boundingRects = null; - } else { - // The customizable region can at most be equal to the caption bar. - if (params.hasInputFeatureSpy()) { - outResult.mCustomizableCaptionRegion.set(captionInsetsRect); - } - boundingRects = new Rect[numOfElements]; - for (int i = 0; i < numOfElements; i++) { - final OccludingCaptionElement element = - params.mOccludingCaptionElements.get(i); - final int elementWidthPx = - resources.getDimensionPixelSize(element.mWidthResId); - boundingRects[i] = - calculateBoundingRect(element, elementWidthPx, captionInsetsRect); - // Subtract the regions used by the caption elements, the rest is - // customizable. - if (params.hasInputFeatureSpy()) { - outResult.mCustomizableCaptionRegion.op(boundingRects[i], - Region.Op.DIFFERENCE); - } - } - } - - final WindowDecorationInsets newInsets = new WindowDecorationInsets( - mTaskInfo.token, mOwner, captionInsetsRect, boundingRects); - if (!newInsets.equals(mWindowDecorationInsets)) { - // Add or update this caption as an insets source. - mWindowDecorationInsets = newInsets; - mWindowDecorationInsets.addOrUpdate(wct); - } - } else { + private void updateCaptionInsets(RelayoutParams params, WindowContainerTransaction wct, + RelayoutResult<T> outResult, Rect taskBounds) { + if (!mIsCaptionVisible) { if (mWindowDecorationInsets != null) { mWindowDecorationInsets.remove(wct); mWindowDecorationInsets = null; } + return; } - - // Task surface itself - float shadowRadius; - final Point taskPosition = mTaskInfo.positionInParent; - if (isFullscreen) { - // Shadow is not needed for fullscreen tasks - shadowRadius = 0; + // 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. + final Rect captionInsetsRect = new Rect(taskBounds); + captionInsetsRect.bottom = captionInsetsRect.top + outResult.mCaptionHeight; + + // Caption bounding rectangles: these are optional, and are used to present finer + // insets than traditional |Insets| to apps about where their content is occluded. + // These are also in absolute coordinates. + final Rect[] boundingRects; + final int numOfElements = params.mOccludingCaptionElements.size(); + if (numOfElements == 0) { + boundingRects = null; } else { - shadowRadius = loadDimension(resources, params.mShadowRadiusId); + // The customizable region can at most be equal to the caption bar. + 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 = + params.mOccludingCaptionElements.get(i); + final int elementWidthPx = + resources.getDimensionPixelSize(element.mWidthResId); + boundingRects[i] = + calculateBoundingRect(element, elementWidthPx, captionInsetsRect); + // Subtract the regions used by the caption elements, the rest is + // customizable. + if (params.hasInputFeatureSpy()) { + outResult.mCustomizableCaptionRegion.op(boundingRects[i], + Region.Op.DIFFERENCE); + } + } } + final WindowDecorationInsets newInsets = new WindowDecorationInsets( + mTaskInfo.token, mOwner, captionInsetsRect, boundingRects); + if (!newInsets.equals(mWindowDecorationInsets)) { + // Add or update this caption as an insets source. + mWindowDecorationInsets = newInsets; + mWindowDecorationInsets.addOrUpdate(wct); + } + } + + 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(); |