From 9f9e91c29f4eb6c2c8eb8befd7f419bb1f62054b Mon Sep 17 00:00:00 2001 From: Felix Stern Date: Thu, 15 Aug 2024 14:25:32 +0000 Subject: Fix showing the IME from EmbeddedWindow - With the refactor in [1], the IME does not show, when requested from EmbeddedWindow. - This CL introduces a new parent interface (InsetsTarget) for InsetsControlTarget and InputType. However, an EmbeddedWindow may not be a controlTarget, as it should not be able to control other insets types, except of the IME. - Previously the initiallyVisible of an IME control was always false [2]. This will now take into account, whether there was an ongoing transition (e.g., in case of app -> Launcher, in this case it is not initiallyVisible), or otherwise whether it is is client- and serverVisible (otherwise it cannot be currently be shown). - The leash was hidden in InsetsSourceProvider.ControlAdapter#startAnimation, which is due to this change also not needed anymore (otherwise the leash could have a different visibility than given in initiallyVisible). - DisplayImeController was not using initiallyVisible, but uses it now to update its own imeVisible state and start an animation, if necessary. [1]: I8e3a74ee579f085cb582040fdba725e7a63d6b85 [2]: I459debedb243b4345b9981b88adf6e4a0ea9b44a Test: atest CtsSurfaceControlTests:android.view.surfacecontrol.cts.SurfaceControlViewHostTests#testImeVisible Flag: android.view.inputmethod.refactor_insets_controller Fix: 355047142 Change-Id: I5aeb3ccfbfe7d4cd0b7b5f0e0400769e65bb70a4 --- .../wm/shell/common/DisplayImeController.java | 24 ++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'libs') diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java index 5b01a0d87b5e..ddb5494a52b0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java @@ -309,21 +309,29 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged lastSurfacePosition); } else { if (!haveSameLeash(mImeSourceControl, imeSourceControl)) { - applyVisibilityToLeash(imeSourceControl); - if (android.view.inputmethod.Flags.refactorInsetsController()) { pendingImeStartAnimation = true; + // The starting point for the IME should be it's previous state + // (whether it is initiallyVisible or not) + updateImeVisibility(imeSourceControl.isInitiallyVisible()); } + applyVisibilityToLeash(imeSourceControl); } if (!mImeShowing) { removeImeSurface(mDisplayId); } } - } else if (!android.view.inputmethod.Flags.refactorInsetsController() - && mAnimation != null) { - // we don"t want to cancel the hide animation, when the control is lost, but - // continue the bar to slide to the end (even without visible IME) - mAnimation.cancel(); + } else { + if (!android.view.inputmethod.Flags.refactorInsetsController() + && mAnimation != null) { + // we don't want to cancel the hide animation, when the control is lost, but + // continue the bar to slide to the end (even without visible IME) + mAnimation.cancel(); + } else if (android.view.inputmethod.Flags.refactorInsetsController() && mImeShowing + && mAnimation == null) { + // There is no leash, so the IME cannot be in a showing state + updateImeVisibility(false); + } } if (positionChanged) { if (android.view.inputmethod.Flags.refactorInsetsController()) { @@ -345,7 +353,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged if (android.view.inputmethod.Flags.refactorInsetsController()) { if (pendingImeStartAnimation) { - startAnimation(true, true /* forceRestart */); + startAnimation(mImeRequestedVisible, true /* forceRestart */); } } } -- cgit v1.2.3-59-g8ed1b From cdc00f517fd70176945d9e579cc05571b469f85f Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Fri, 13 Sep 2024 15:20:05 +0800 Subject: Extra common logic of default transition animation Make it more flexible to run other animation implementation. Bug: 326331384 Flag: EXEMPT simple refactor Test: Default activity/task switch Change-Id: I7aaebda531ed8a21138c3f42ddbbb7bb1c7d3765 --- .../shell/transition/DefaultTransitionHandler.java | 125 +++++++++++++++------ 1 file changed, 89 insertions(+), 36 deletions(-) (limited to 'libs') diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index 4fc6c4489f2b..609ddbeb1818 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -828,24 +828,26 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { @NonNull Runnable finishCallback, @NonNull TransactionPool pool, @NonNull ShellExecutor mainExecutor, @Nullable Point position, float cornerRadius, @Nullable Rect clipRect, boolean isActivity) { + final DefaultAnimationAdapter adapter = new DefaultAnimationAdapter(anim, leash, + position, clipRect, cornerRadius, isActivity); + buildSurfaceAnimation(animations, anim, finishCallback, pool, mainExecutor, adapter); + } + + /** Builds an animator for the surface and adds it to the `animations` list. */ + static void buildSurfaceAnimation(@NonNull ArrayList animations, + @NonNull Animation anim, @NonNull Runnable finishCallback, + @NonNull TransactionPool pool, @NonNull ShellExecutor mainExecutor, + @NonNull AnimationAdapter updateListener) { final SurfaceControl.Transaction transaction = pool.acquire(); + updateListener.setTransaction(transaction); final ValueAnimator va = ValueAnimator.ofFloat(0f, 1f); - final Transformation transformation = new Transformation(); - final float[] matrix = new float[9]; // Animation length is already expected to be scaled. va.overrideDurationScale(1.0f); va.setDuration(anim.computeDurationHint()); - final ValueAnimator.AnimatorUpdateListener updateListener = animation -> { - final long currentPlayTime = Math.min(va.getDuration(), va.getCurrentPlayTime()); - - applyTransformation(currentPlayTime, transaction, leash, anim, transformation, matrix, - position, cornerRadius, clipRect, isActivity); - }; va.addUpdateListener(updateListener); final Runnable finisher = () -> { - applyTransformation(va.getDuration(), transaction, leash, anim, transformation, matrix, - position, cornerRadius, clipRect, isActivity); + updateListener.onAnimationUpdate(va); pool.release(transaction); mainExecutor.execute(() -> { @@ -1009,37 +1011,88 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { || animType == ANIM_FROM_STYLE; } - private static void applyTransformation(long time, SurfaceControl.Transaction t, - SurfaceControl leash, Animation anim, Transformation tmpTransformation, float[] matrix, - Point position, float cornerRadius, @Nullable Rect immutableClipRect, - boolean isActivity) { - tmpTransformation.clear(); - anim.getTransformation(time, tmpTransformation); - if (com.android.graphics.libgui.flags.Flags.edgeExtensionShader() - && anim.getExtensionEdges() != 0x0 && isActivity) { - t.setEdgeExtensionEffect(leash, anim.getExtensionEdges()); + /** The animation adapter for buildSurfaceAnimation. */ + abstract static class AnimationAdapter implements ValueAnimator.AnimatorUpdateListener { + @NonNull final SurfaceControl mLeash; + @NonNull SurfaceControl.Transaction mTransaction; + private Choreographer mChoreographer; + + AnimationAdapter(@NonNull SurfaceControl leash) { + mLeash = leash; } - if (position != null) { - tmpTransformation.getMatrix().postTranslate(position.x, position.y); + + void setTransaction(@NonNull SurfaceControl.Transaction transaction) { + mTransaction = transaction; } - t.setMatrix(leash, tmpTransformation.getMatrix(), matrix); - t.setAlpha(leash, tmpTransformation.getAlpha()); - - final Rect clipRect = immutableClipRect == null ? null : new Rect(immutableClipRect); - Insets extensionInsets = Insets.min(tmpTransformation.getInsets(), Insets.NONE); - if (!extensionInsets.equals(Insets.NONE) && clipRect != null && !clipRect.isEmpty()) { - // Clip out any overflowing edge extension - clipRect.inset(extensionInsets); - t.setCrop(leash, clipRect); + + @Override + public void onAnimationUpdate(@NonNull ValueAnimator animator) { + applyTransformation(animator); + if (mChoreographer == null) { + mChoreographer = Choreographer.getInstance(); + } + mTransaction.setFrameTimelineVsync(mChoreographer.getVsyncId()); + mTransaction.apply(); } - if (anim.hasRoundedCorners() && cornerRadius > 0 && clipRect != null) { - // We can only apply rounded corner if a crop is set - t.setCrop(leash, clipRect); - t.setCornerRadius(leash, cornerRadius); + abstract void applyTransformation(@NonNull ValueAnimator animator); + } + + private static class DefaultAnimationAdapter extends AnimationAdapter { + final Transformation mTransformation = new Transformation(); + final float[] mMatrix = new float[9]; + @NonNull final Animation mAnim; + @Nullable final Point mPosition; + @Nullable final Rect mClipRect; + final float mCornerRadius; + final boolean mIsActivity; + + DefaultAnimationAdapter(@NonNull Animation anim, @NonNull SurfaceControl leash, + @Nullable Point position, @Nullable Rect clipRect, float cornerRadius, + boolean isActivity) { + super(leash); + mAnim = anim; + mPosition = (position != null && (position.x != 0 || position.y != 0)) + ? position : null; + mClipRect = (clipRect != null && !clipRect.isEmpty()) ? clipRect : null; + mCornerRadius = cornerRadius; + mIsActivity = isActivity; } - t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId()); - t.apply(); + @Override + void applyTransformation(@NonNull ValueAnimator animator) { + final long currentPlayTime = Math.min(animator.getDuration(), + animator.getCurrentPlayTime()); + final Transformation transformation = mTransformation; + final SurfaceControl.Transaction t = mTransaction; + final SurfaceControl leash = mLeash; + transformation.clear(); + mAnim.getTransformation(currentPlayTime, transformation); + if (com.android.graphics.libgui.flags.Flags.edgeExtensionShader() + && mIsActivity && mAnim.getExtensionEdges() != 0) { + t.setEdgeExtensionEffect(leash, mAnim.getExtensionEdges()); + } + if (mPosition != null) { + transformation.getMatrix().postTranslate(mPosition.x, mPosition.y); + } + t.setMatrix(leash, transformation.getMatrix(), mMatrix); + t.setAlpha(leash, transformation.getAlpha()); + + if (mClipRect != null) { + Rect clipRect = mClipRect; + final Insets extensionInsets = Insets.min(transformation.getInsets(), Insets.NONE); + if (!extensionInsets.equals(Insets.NONE)) { + // Clip out any overflowing edge extension. + clipRect = new Rect(mClipRect); + clipRect.inset(extensionInsets); + t.setCrop(leash, clipRect); + } + if (mCornerRadius > 0 && mAnim.hasRoundedCorners()) { + // Rounded corner can only be applied if a crop is set. + t.setCrop(leash, clipRect); + t.setCornerRadius(leash, mCornerRadius); + } + } + } } } -- cgit v1.2.3-59-g8ed1b From 502d5d08314d4f0b22a62304411c809eebda2a2a Mon Sep 17 00:00:00 2001 From: Eghosa Ewansiha-Vlachavas Date: Tue, 10 Sep 2024 08:35:32 +0000 Subject: Add tests for the `FixedAspectRatioTaskPositionerDecorator` Flag: NONE(tests) Test: atest WMShellUnitTests:FixedAspectRatioDragPositioningDecoratorTests Fix: 365741940 Change-Id: I3e5bc9292319c6d3c7799632f41dfe5efdb9da2a --- .../FixedAspectRatioTaskPositionerDecorator.kt | 10 +- ...FixedAspectRatioTaskPositionerDecoratorTests.kt | 636 +++++++++++++++++++++ 2 files changed, 644 insertions(+), 2 deletions(-) create mode 100644 libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FixedAspectRatioTaskPositionerDecoratorTests.kt (limited to 'libs') diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FixedAspectRatioTaskPositionerDecorator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FixedAspectRatioTaskPositionerDecorator.kt index e8131a00ba40..3885761d0742 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FixedAspectRatioTaskPositionerDecorator.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FixedAspectRatioTaskPositionerDecorator.kt @@ -16,8 +16,10 @@ package com.android.wm.shell.windowdecor +import android.app.ActivityManager.RunningTaskInfo import android.graphics.PointF import android.graphics.Rect +import com.android.internal.annotations.VisibleForTesting import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_LEFT import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT @@ -51,8 +53,7 @@ class FixedAspectRatioTaskPositionerDecorator ( return super.onDragPositioningStart(originalCtrlType, x, y) } - lastRepositionedBounds.set( - windowDecoration.mTaskInfo.configuration.windowConfiguration.bounds) + lastRepositionedBounds.set(getBounds(windowDecoration.mTaskInfo)) startingPoint.set(x, y) lastValidPoint.set(x, y) val startingBoundWidth = lastRepositionedBounds.width() @@ -255,4 +256,9 @@ class FixedAspectRatioTaskPositionerDecorator ( private fun requiresFixedAspectRatio(): Boolean { return originalCtrlType.isResizing() && !windowDecoration.mTaskInfo.isResizeable } + + @VisibleForTesting + fun getBounds(taskInfo: RunningTaskInfo): Rect { + return taskInfo.configuration.windowConfiguration.bounds + } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FixedAspectRatioTaskPositionerDecoratorTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FixedAspectRatioTaskPositionerDecoratorTests.kt new file mode 100644 index 000000000000..ce17c1df50bc --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FixedAspectRatioTaskPositionerDecoratorTests.kt @@ -0,0 +1,636 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.windowdecor + +import android.app.ActivityManager +import android.graphics.PointF +import android.graphics.Rect +import android.util.MathUtils.abs +import android.util.MathUtils.max +import androidx.test.filters.SmallTest +import com.android.wm.shell.ShellTestCase +import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM +import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_LEFT +import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT +import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP +import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_UNDEFINED +import com.android.wm.shell.windowdecor.DragPositioningCallback.CtrlType +import com.google.common.truth.Truth.assertThat +import com.google.testing.junit.testparameterinjector.TestParameter +import com.google.testing.junit.testparameterinjector.TestParameterInjector +import kotlin.math.min +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.spy +import org.mockito.Mockito.verify +import org.mockito.kotlin.any +import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.never + +/** + * Tests for the [FixedAspectRatioTaskPositionerDecorator], written in parameterized form to check + * decorators behaviour for different variations of drag actions. + * + * Build/Install/Run: + * atest WMShellUnitTests:FixedAspectRatioTaskPositionerDecoratorTests + */ +@SmallTest +@RunWith(TestParameterInjector::class) +class FixedAspectRatioTaskPositionerDecoratorTests : ShellTestCase(){ + @Mock + private lateinit var mockDesktopWindowDecoration: DesktopModeWindowDecoration + @Mock + private lateinit var mockTaskPositioner: VeiledResizeTaskPositioner + + private lateinit var decoratedTaskPositioner: FixedAspectRatioTaskPositionerDecorator + + @Before + fun setUp() { + mockDesktopWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply { + isResizeable = false + configuration.windowConfiguration.setBounds(PORTRAIT_BOUNDS) + } + doReturn(PORTRAIT_BOUNDS).`when`(mockTaskPositioner).onDragPositioningStart( + any(), any(), any()) + doReturn(Rect()).`when`(mockTaskPositioner).onDragPositioningMove(any(), any()) + doReturn(Rect()).`when`(mockTaskPositioner).onDragPositioningEnd(any(), any()) + decoratedTaskPositioner = spy( + FixedAspectRatioTaskPositionerDecorator( + mockDesktopWindowDecoration, mockTaskPositioner) + ) + } + + @Test + fun testOnDragPositioningStart_noAdjustment( + @TestParameter testCase: ResizeableOrNotResizingTestCases + ) { + val originalX = 0f + val originalY = 0f + mockDesktopWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply { + isResizeable = testCase.isResizeable + } + + decoratedTaskPositioner.onDragPositioningStart(testCase.ctrlType, originalX, originalY) + + val capturedValues = getLatestOnStartArguments() + assertThat(capturedValues.ctrlType).isEqualTo(testCase.ctrlType) + assertThat(capturedValues.x).isEqualTo(originalX) + assertThat(capturedValues.y).isEqualTo(originalY) + } + + @Test + fun testOnDragPositioningStart_cornerResize_noAdjustment( + @TestParameter testCase: CornerResizeStartTestCases + ) { + val originalX = 0f + val originalY = 0f + + decoratedTaskPositioner.onDragPositioningStart(testCase.ctrlType, originalX, originalY) + + val capturedValues = getLatestOnStartArguments() + assertThat(capturedValues.ctrlType).isEqualTo(testCase.ctrlType) + assertThat(capturedValues.x).isEqualTo(originalX) + assertThat(capturedValues.y).isEqualTo(originalY) + } + + @Test + fun testOnDragPositioningStart_edgeResize_ctrlTypeAdjusted( + @TestParameter testCase: EdgeResizeStartTestCases, @TestParameter orientation: Orientation + ) { + val startingBounds = getAndMockBounds(orientation) + val startingPoint = getEdgeStartingPoint( + testCase.ctrlType, testCase.additionalEdgeCtrlType, startingBounds) + + decoratedTaskPositioner.onDragPositioningStart( + testCase.ctrlType, startingPoint.x, startingPoint.y) + + val adjustedCtrlType = testCase.ctrlType + testCase.additionalEdgeCtrlType + val capturedValues = getLatestOnStartArguments() + assertThat(capturedValues.ctrlType).isEqualTo(adjustedCtrlType) + assertThat(capturedValues.x).isEqualTo(startingPoint.x) + assertThat(capturedValues.y).isEqualTo(startingPoint.y) + } + + @Test + fun testOnDragPositioningMove_noAdjustment( + @TestParameter testCase: ResizeableOrNotResizingTestCases + ) { + val originalX = 0f + val originalY = 0f + decoratedTaskPositioner.onDragPositioningStart(testCase.ctrlType, originalX, originalX) + mockDesktopWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply { + isResizeable = testCase.isResizeable + } + + decoratedTaskPositioner.onDragPositioningMove( + originalX + SMALL_DELTA, originalY + SMALL_DELTA) + + val capturedValues = getLatestOnMoveArguments() + assertThat(capturedValues.x).isEqualTo(originalX + SMALL_DELTA) + assertThat(capturedValues.y).isEqualTo(originalY + SMALL_DELTA) + } + + @Test + fun testOnDragPositioningMove_cornerResize_invalidRegion_noResize( + @TestParameter testCase: InvalidCornerResizeTestCases, + @TestParameter orientation: Orientation + ) { + val startingBounds = getAndMockBounds(orientation) + val startingPoint = getCornerStartingPoint(testCase.ctrlType, startingBounds) + + decoratedTaskPositioner.onDragPositioningStart( + testCase.ctrlType, startingPoint.x, startingPoint.y) + + val updatedBounds = decoratedTaskPositioner.onDragPositioningMove( + startingPoint.x + testCase.dragDelta.x, + startingPoint.y + testCase.dragDelta.y) + + verify(mockTaskPositioner, never()).onDragPositioningMove(any(), any()) + assertThat(updatedBounds).isEqualTo(startingBounds) + } + + + @Test + fun testOnDragPositioningMove_cornerResize_validRegion_resizeToAdjustedCoordinates( + @TestParameter testCase: ValidCornerResizeTestCases, + @TestParameter orientation: Orientation + ) { + val startingBounds = getAndMockBounds(orientation) + val startingPoint = getCornerStartingPoint(testCase.ctrlType, startingBounds) + + decoratedTaskPositioner.onDragPositioningStart( + testCase.ctrlType, startingPoint.x, startingPoint.y) + + decoratedTaskPositioner.onDragPositioningMove( + startingPoint.x + testCase.dragDelta.x, startingPoint.y + testCase.dragDelta.y) + + val adjustedDragDelta = calculateAdjustedDelta( + testCase.ctrlType, testCase.dragDelta, orientation) + val capturedValues = getLatestOnMoveArguments() + val absChangeX = abs(capturedValues.x - startingPoint.x) + val absChangeY = abs(capturedValues.y - startingPoint.y) + val resultAspectRatio = max(absChangeX, absChangeY) / min(absChangeX, absChangeY) + assertThat(capturedValues.x).isEqualTo(startingPoint.x + adjustedDragDelta.x) + assertThat(capturedValues.y).isEqualTo(startingPoint.y + adjustedDragDelta.y) + assertThat(resultAspectRatio).isEqualTo(STARTING_ASPECT_RATIO) + } + + @Test + fun testOnDragPositioningMove_edgeResize_resizeToAdjustedCoordinates( + @TestParameter testCase: EdgeResizeTestCases, + @TestParameter orientation: Orientation + ) { + val startingBounds = getAndMockBounds(orientation) + val startingPoint = getEdgeStartingPoint( + testCase.ctrlType, testCase.additionalEdgeCtrlType, startingBounds) + + decoratedTaskPositioner.onDragPositioningStart( + testCase.ctrlType, startingPoint.x, startingPoint.y) + + decoratedTaskPositioner.onDragPositioningMove( + startingPoint.x + testCase.dragDelta.x, + startingPoint.y + testCase.dragDelta.y) + + val adjustedDragDelta = calculateAdjustedDelta( + testCase.ctrlType + testCase.additionalEdgeCtrlType, + testCase.dragDelta, + orientation) + val capturedValues = getLatestOnMoveArguments() + val absChangeX = abs(capturedValues.x - startingPoint.x) + val absChangeY = abs(capturedValues.y - startingPoint.y) + val resultAspectRatio = max(absChangeX, absChangeY) / min(absChangeX, absChangeY) + assertThat(capturedValues.x).isEqualTo(startingPoint.x + adjustedDragDelta.x) + assertThat(capturedValues.y).isEqualTo(startingPoint.y + adjustedDragDelta.y) + assertThat(resultAspectRatio).isEqualTo(STARTING_ASPECT_RATIO) + } + + @Test + fun testOnDragPositioningEnd_noAdjustment( + @TestParameter testCase: ResizeableOrNotResizingTestCases + ) { + val originalX = 0f + val originalY = 0f + decoratedTaskPositioner.onDragPositioningStart(testCase.ctrlType, originalX, originalX) + mockDesktopWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply { + isResizeable = testCase.isResizeable + } + + decoratedTaskPositioner.onDragPositioningEnd( + originalX + SMALL_DELTA, originalY + SMALL_DELTA) + + val capturedValues = getLatestOnEndArguments() + assertThat(capturedValues.x).isEqualTo(originalX + SMALL_DELTA) + assertThat(capturedValues.y).isEqualTo(originalY + SMALL_DELTA) + } + + @Test + fun testOnDragPositioningEnd_cornerResize_invalidRegion_endsAtPreviousValidPoint( + @TestParameter testCase: InvalidCornerResizeTestCases, + @TestParameter orientation: Orientation + ) { + val startingBounds = getAndMockBounds(orientation) + val startingPoint = getCornerStartingPoint(testCase.ctrlType, startingBounds) + + decoratedTaskPositioner.onDragPositioningStart( + testCase.ctrlType, startingPoint.x, startingPoint.y) + + decoratedTaskPositioner.onDragPositioningEnd( + startingPoint.x + testCase.dragDelta.x, + startingPoint.y + testCase.dragDelta.y) + + val capturedValues = getLatestOnEndArguments() + assertThat(capturedValues.x).isEqualTo(startingPoint.x) + assertThat(capturedValues.y).isEqualTo(startingPoint.y) + } + + @Test + fun testOnDragPositioningEnd_cornerResize_validRegion_endAtAdjustedCoordinates( + @TestParameter testCase: ValidCornerResizeTestCases, + @TestParameter orientation: Orientation + ) { + val startingBounds = getAndMockBounds(orientation) + val startingPoint = getCornerStartingPoint(testCase.ctrlType, startingBounds) + + decoratedTaskPositioner.onDragPositioningStart( + testCase.ctrlType, startingPoint.x, startingPoint.y) + + decoratedTaskPositioner.onDragPositioningEnd( + startingPoint.x + testCase.dragDelta.x, startingPoint.y + testCase.dragDelta.y) + + val adjustedDragDelta = calculateAdjustedDelta( + testCase.ctrlType, testCase.dragDelta, orientation) + val capturedValues = getLatestOnEndArguments() + val absChangeX = abs(capturedValues.x - startingPoint.x) + val absChangeY = abs(capturedValues.y - startingPoint.y) + val resultAspectRatio = max(absChangeX, absChangeY) / min(absChangeX, absChangeY) + assertThat(capturedValues.x).isEqualTo(startingPoint.x + adjustedDragDelta.x) + assertThat(capturedValues.y).isEqualTo(startingPoint.y + adjustedDragDelta.y) + assertThat(resultAspectRatio).isEqualTo(STARTING_ASPECT_RATIO) + } + + @Test + fun testOnDragPositioningEnd_edgeResize_endAtAdjustedCoordinates( + @TestParameter testCase: EdgeResizeTestCases, + @TestParameter orientation: Orientation + ) { + val startingBounds = getAndMockBounds(orientation) + val startingPoint = getEdgeStartingPoint( + testCase.ctrlType, testCase.additionalEdgeCtrlType, startingBounds) + + decoratedTaskPositioner.onDragPositioningStart( + testCase.ctrlType, startingPoint.x, startingPoint.y) + + decoratedTaskPositioner.onDragPositioningEnd( + startingPoint.x + testCase.dragDelta.x, + startingPoint.y + testCase.dragDelta.y) + + val adjustedDragDelta = calculateAdjustedDelta( + testCase.ctrlType + testCase.additionalEdgeCtrlType, + testCase.dragDelta, + orientation) + val capturedValues = getLatestOnEndArguments() + val absChangeX = abs(capturedValues.x - startingPoint.x) + val absChangeY = abs(capturedValues.y - startingPoint.y) + val resultAspectRatio = max(absChangeX, absChangeY) / min(absChangeX, absChangeY) + assertThat(capturedValues.x).isEqualTo(startingPoint.x + adjustedDragDelta.x) + assertThat(capturedValues.y).isEqualTo(startingPoint.y + adjustedDragDelta.y) + assertThat(resultAspectRatio).isEqualTo(STARTING_ASPECT_RATIO) + } + + /** + * Returns the most recent arguments passed to the `.onPositioningStart()` of the + * [mockTaskPositioner]. + */ + private fun getLatestOnStartArguments(): CtrlCoordinateCapture { + val captorCtrlType = argumentCaptor() + val captorCoordinates = argumentCaptor() + verify(mockTaskPositioner).onDragPositioningStart( + captorCtrlType.capture(), captorCoordinates.capture(), captorCoordinates.capture()) + + return CtrlCoordinateCapture(captorCtrlType.firstValue, captorCoordinates.firstValue, + captorCoordinates.secondValue) + } + + /** + * Returns the most recent arguments passed to the `.onPositioningMove()` of the + * [mockTaskPositioner]. + */ + private fun getLatestOnMoveArguments(): PointF { + val captorCoordinates = argumentCaptor() + verify(mockTaskPositioner).onDragPositioningMove( + captorCoordinates.capture(), captorCoordinates.capture()) + + return PointF(captorCoordinates.firstValue, captorCoordinates.secondValue) + } + + /** + * Returns the most recent arguments passed to the `.onPositioningEnd()` of the + * [mockTaskPositioner]. + */ + private fun getLatestOnEndArguments(): PointF { + val captorCoordinates = argumentCaptor() + verify(mockTaskPositioner).onDragPositioningEnd( + captorCoordinates.capture(), captorCoordinates.capture()) + + return PointF(captorCoordinates.firstValue, captorCoordinates.secondValue) + } + + /** + * Mocks the app bounds to correspond with a given orientation and returns the mocked bounds. + */ + private fun getAndMockBounds(orientation: Orientation): Rect { + val mockBounds = if (orientation.isPortrait) PORTRAIT_BOUNDS else LANDSCAPE_BOUNDS + doReturn(mockBounds).`when`(mockTaskPositioner).onDragPositioningStart( + any(), any(), any()) + doReturn(mockBounds).`when`(decoratedTaskPositioner).getBounds(any()) + return mockBounds + } + + /** + * Calculates the corner point a given drag action should start from, based on the [ctrlType], + * given the [startingBounds]. + */ + private fun getCornerStartingPoint(@CtrlType ctrlType: Int, startingBounds: Rect): PointF { + return when (ctrlType) { + CTRL_TYPE_BOTTOM + CTRL_TYPE_RIGHT -> + PointF(startingBounds.right.toFloat(), startingBounds.bottom.toFloat()) + + CTRL_TYPE_BOTTOM + CTRL_TYPE_LEFT -> + PointF(startingBounds.left.toFloat(), startingBounds.bottom.toFloat()) + + CTRL_TYPE_TOP + CTRL_TYPE_RIGHT -> + PointF(startingBounds.right.toFloat(), startingBounds.top.toFloat()) + // CTRL_TYPE_TOP + CTRL_TYPE_LEFT + else -> + PointF(startingBounds.left.toFloat(), startingBounds.top.toFloat()) + } + } + + /** + * Calculates the point along an edge the edge resize should start from, based on the starting + * edge ([edgeCtrlType]) and the additional edge we expect to resize ([additionalEdgeCtrlType]), + * given the [startingBounds]. + */ + private fun getEdgeStartingPoint( + @CtrlType edgeCtrlType: Int, @CtrlType additionalEdgeCtrlType: Int, startingBounds: Rect + ): PointF { + val simulatedCorner = getCornerStartingPoint( + edgeCtrlType + additionalEdgeCtrlType, startingBounds) + when (additionalEdgeCtrlType) { + CTRL_TYPE_TOP -> { + simulatedCorner.offset(0f, -SMALL_DELTA) + return simulatedCorner + } + CTRL_TYPE_BOTTOM -> { + simulatedCorner.offset(0f, SMALL_DELTA) + return simulatedCorner + } + CTRL_TYPE_LEFT -> { + simulatedCorner.offset(SMALL_DELTA, 0f) + return simulatedCorner + } + // CTRL_TYPE_RIGHT + else -> { + simulatedCorner.offset(-SMALL_DELTA, 0f) + return simulatedCorner + } + } + } + + /** + * Calculates the adjustments to the drag delta we expect for a given action and orientation. + */ + private fun calculateAdjustedDelta( + @CtrlType ctrlType: Int, delta: PointF, orientation: Orientation + ): PointF { + if ((abs(delta.x) < abs(delta.y) && delta.x != 0f) || delta.y == 0f) { + // Only respect x delta if it's less than y delta but non-zero (i.e there is a change + // in x to be applied), or if the y delta is zero (i.e there is no change in y to be + // applied). + val adjustedY = if (orientation.isPortrait) + delta.x * STARTING_ASPECT_RATIO else + delta.x / STARTING_ASPECT_RATIO + if (ctrlType.isBottomRightOrTopLeftCorner()) { + return PointF(delta.x, adjustedY) + } + return PointF(delta.x, -adjustedY) + } + // Respect y delta. + val adjustedX = if (orientation.isPortrait) + delta.y / STARTING_ASPECT_RATIO else + delta.y * STARTING_ASPECT_RATIO + if (ctrlType.isBottomRightOrTopLeftCorner()) { + return PointF(adjustedX, delta.y) + } + return PointF(-adjustedX, delta.y) + } + + private fun @receiver:CtrlType Int.isBottomRightOrTopLeftCorner(): Boolean { + return this == CTRL_TYPE_BOTTOM + CTRL_TYPE_RIGHT || this == CTRL_TYPE_TOP + CTRL_TYPE_LEFT + } + + private inner class CtrlCoordinateCapture(ctrl: Int, xValue: Float, yValue: Float) { + var ctrlType = ctrl + var x = xValue + var y = yValue + } + + companion object { + private val PORTRAIT_BOUNDS = Rect(100, 100, 200, 400) + private val LANDSCAPE_BOUNDS = Rect(100, 100, 400, 200) + private val STARTING_ASPECT_RATIO = PORTRAIT_BOUNDS.height() / PORTRAIT_BOUNDS.width() + private const val LARGE_DELTA = 50f + private const val SMALL_DELTA = 30f + + enum class Orientation( + val isPortrait: Boolean + ) { + PORTRAIT (true), + LANDSCAPE (false) + } + + enum class ResizeableOrNotResizingTestCases( + val ctrlType: Int, + val isResizeable: Boolean + ) { + NotResizing (CTRL_TYPE_UNDEFINED, false), + Resizeable (CTRL_TYPE_RIGHT, true) + } + + /** + * Tests cases for the start of a corner resize. + * @param ctrlType the control type of the corner the resize is initiated on. + */ + enum class CornerResizeStartTestCases( + val ctrlType: Int + ) { + BottomRightCorner (CTRL_TYPE_BOTTOM + CTRL_TYPE_RIGHT), + BottomLeftCorner (CTRL_TYPE_BOTTOM + CTRL_TYPE_LEFT), + TopRightCorner (CTRL_TYPE_TOP + CTRL_TYPE_RIGHT), + TopLeftCorner (CTRL_TYPE_TOP + CTRL_TYPE_LEFT) + } + + /** + * Tests cases for the moving and ending of a invalid corner resize. Where the compass point + * (e.g `SouthEast`) represents the direction of the drag. + * @param ctrlType the control type of the corner the resize is initiated on. + * @param dragDelta the delta of the attempted drag action, from the [ctrlType]'s + * corresponding corner point. Represented as a combination a different signed small and + * large deltas which correspond to the direction/angle of drag. + */ + enum class InvalidCornerResizeTestCases( + val ctrlType: Int, + val dragDelta: PointF + ) { + BottomRightCornerNorthEastDrag ( + CTRL_TYPE_BOTTOM + CTRL_TYPE_RIGHT, + PointF(LARGE_DELTA, -LARGE_DELTA)), + BottomRightCornerSouthWestDrag ( + CTRL_TYPE_BOTTOM + CTRL_TYPE_RIGHT, + PointF(-LARGE_DELTA, LARGE_DELTA)), + TopLeftCornerNorthEastDrag ( + CTRL_TYPE_TOP + CTRL_TYPE_LEFT, + PointF(LARGE_DELTA, -LARGE_DELTA)), + TopLeftCornerSouthWestDrag ( + CTRL_TYPE_TOP + CTRL_TYPE_LEFT, + PointF(-LARGE_DELTA, LARGE_DELTA)), + BottomLeftCornerSouthEastDrag ( + CTRL_TYPE_BOTTOM + CTRL_TYPE_LEFT, + PointF(LARGE_DELTA, LARGE_DELTA)), + BottomLeftCornerNorthWestDrag ( + CTRL_TYPE_BOTTOM + CTRL_TYPE_LEFT, + PointF(-LARGE_DELTA, -LARGE_DELTA)), + TopRightCornerSouthEastDrag ( + CTRL_TYPE_TOP + CTRL_TYPE_RIGHT, + PointF(LARGE_DELTA, LARGE_DELTA)), + TopRightCornerNorthWestDrag ( + CTRL_TYPE_TOP + CTRL_TYPE_RIGHT, + PointF(-LARGE_DELTA, -LARGE_DELTA)), + } + + /** + * Tests cases for the moving and ending of a valid corner resize. Where the compass point + * (e.g `SouthEast`) represents the direction of the drag, followed by the expected + * behaviour in that direction (i.e `RespectY` means the y delta will be respected whereas + * `RespectX` means the x delta will be respected). + * @param ctrlType the control type of the corner the resize is initiated on. + * @param dragDelta the delta of the attempted drag action, from the [ctrlType]'s + * corresponding corner point. Represented as a combination a different signed small and + * large deltas which correspond to the direction/angle of drag. + */ + enum class ValidCornerResizeTestCases( + val ctrlType: Int, + val dragDelta: PointF, + ) { + BottomRightCornerSouthEastDragRespectY ( + CTRL_TYPE_BOTTOM + CTRL_TYPE_RIGHT, + PointF(+LARGE_DELTA, SMALL_DELTA)), + BottomRightCornerSouthEastDragRespectX ( + CTRL_TYPE_BOTTOM + CTRL_TYPE_RIGHT, + PointF(SMALL_DELTA, LARGE_DELTA)), + BottomRightCornerNorthWestDragRespectY ( + CTRL_TYPE_BOTTOM + CTRL_TYPE_RIGHT, + PointF(-LARGE_DELTA, -SMALL_DELTA)), + BottomRightCornerNorthWestDragRespectX ( + CTRL_TYPE_BOTTOM + CTRL_TYPE_RIGHT, + PointF(-SMALL_DELTA, -LARGE_DELTA)), + TopLeftCornerSouthEastDragRespectY ( + CTRL_TYPE_TOP + CTRL_TYPE_LEFT, + PointF(LARGE_DELTA, SMALL_DELTA)), + TopLeftCornerSouthEastDragRespectX ( + CTRL_TYPE_TOP + CTRL_TYPE_LEFT, + PointF(SMALL_DELTA, LARGE_DELTA)), + TopLeftCornerNorthWestDragRespectY ( + CTRL_TYPE_TOP + CTRL_TYPE_LEFT, + PointF(-LARGE_DELTA, -SMALL_DELTA)), + TopLeftCornerNorthWestDragRespectX ( + CTRL_TYPE_TOP + CTRL_TYPE_LEFT, + PointF(-SMALL_DELTA, -LARGE_DELTA)), + BottomLeftCornerSouthWestDragRespectY ( + CTRL_TYPE_BOTTOM + CTRL_TYPE_LEFT, + PointF(-LARGE_DELTA, SMALL_DELTA)), + BottomLeftCornerSouthWestDragRespectX ( + CTRL_TYPE_BOTTOM + CTRL_TYPE_LEFT, + PointF(-SMALL_DELTA, LARGE_DELTA)), + BottomLeftCornerNorthEastDragRespectY ( + CTRL_TYPE_BOTTOM + CTRL_TYPE_LEFT, + PointF(LARGE_DELTA, -SMALL_DELTA)), + BottomLeftCornerNorthEastDragRespectX ( + CTRL_TYPE_BOTTOM + CTRL_TYPE_LEFT, + PointF(SMALL_DELTA, -LARGE_DELTA)), + TopRightCornerSouthWestDragRespectY ( + CTRL_TYPE_TOP + CTRL_TYPE_RIGHT, + PointF(-LARGE_DELTA, SMALL_DELTA)), + TopRightCornerSouthWestDragRespectX ( + CTRL_TYPE_TOP + CTRL_TYPE_RIGHT, + PointF(-SMALL_DELTA, LARGE_DELTA)), + TopRightCornerNorthEastDragRespectY ( + CTRL_TYPE_TOP + CTRL_TYPE_RIGHT, + PointF(LARGE_DELTA, -SMALL_DELTA)), + TopRightCornerNorthEastDragRespectX ( + CTRL_TYPE_TOP + CTRL_TYPE_RIGHT, + PointF(+SMALL_DELTA, -LARGE_DELTA)) + } + + /** + * Tests cases for the start of an edge resize. + * @param ctrlType the control type of the edge the resize is initiated on. + * @param additionalEdgeCtrlType the expected additional edge to be included in the ctrl + * type. + */ + enum class EdgeResizeStartTestCases( + val ctrlType: Int, + val additionalEdgeCtrlType: Int + ) { + BottomOfLeftEdgeResize (CTRL_TYPE_LEFT, CTRL_TYPE_BOTTOM), + TopOfLeftEdgeResize (CTRL_TYPE_LEFT, CTRL_TYPE_TOP), + BottomOfRightEdgeResize (CTRL_TYPE_RIGHT, CTRL_TYPE_BOTTOM), + TopOfRightEdgeResize (CTRL_TYPE_RIGHT, CTRL_TYPE_TOP), + RightOfTopEdgeResize (CTRL_TYPE_TOP, CTRL_TYPE_RIGHT), + LeftOfTopEdgeResize (CTRL_TYPE_TOP, CTRL_TYPE_LEFT), + RightOfBottomEdgeResize (CTRL_TYPE_BOTTOM, CTRL_TYPE_RIGHT), + LeftOfBottomEdgeResize (CTRL_TYPE_BOTTOM, CTRL_TYPE_LEFT) + } + + /** + * Tests cases for the moving and ending of an edge resize. + * @param ctrlType the control type of the edge the resize is initiated on. + * @param additionalEdgeCtrlType the expected additional edge to be included in the ctrl + * type. + * @param dragDelta the delta of the attempted drag action, from the [ctrlType]'s + * corresponding edge point. Represented as a combination a different signed small and + * large deltas which correspond to the direction/angle of drag. + */ + enum class EdgeResizeTestCases( + val ctrlType: Int, + val additionalEdgeCtrlType: Int, + val dragDelta: PointF + ) { + BottomOfLeftEdgeResize (CTRL_TYPE_LEFT, CTRL_TYPE_BOTTOM, PointF(-SMALL_DELTA, 0f)), + TopOfLeftEdgeResize (CTRL_TYPE_LEFT, CTRL_TYPE_TOP, PointF(-SMALL_DELTA, 0f)), + BottomOfRightEdgeResize (CTRL_TYPE_RIGHT, CTRL_TYPE_BOTTOM, PointF(SMALL_DELTA, 0f)), + TopOfRightEdgeResize (CTRL_TYPE_RIGHT, CTRL_TYPE_TOP, PointF(SMALL_DELTA, 0f)), + RightOfTopEdgeResize (CTRL_TYPE_TOP, CTRL_TYPE_RIGHT, PointF(0f, -SMALL_DELTA)), + LeftOfTopEdgeResize (CTRL_TYPE_TOP, CTRL_TYPE_LEFT, PointF(0f, -SMALL_DELTA)), + RightOfBottomEdgeResize (CTRL_TYPE_BOTTOM, CTRL_TYPE_RIGHT, PointF(0f, SMALL_DELTA)), + LeftOfBottomEdgeResize (CTRL_TYPE_BOTTOM, CTRL_TYPE_LEFT, PointF(0f, SMALL_DELTA)) + } + } +} -- cgit v1.2.3-59-g8ed1b From b8cc0a3c11727d002488a9c15a9b4dfd2f4316bc Mon Sep 17 00:00:00 2001 From: Eghosa Ewansiha-Vlachavas Date: Fri, 13 Sep 2024 14:10:51 +0000 Subject: Maintain aspect ratio in DragPositioningCallbackUtility.changeBounds() Adjusting one side of an unresizeable app without also adjusted a adjacent edge in proportion will cause the aspect ratio of the bounds to change. To prevent the aspect ratio of unresizeable apps being modified, opt to reset all coordinates to their previous valid state if at least one of the coordinates needs adjusting due to constraints. Flag: com.android.window.flags.enable_windowing_scaled_resizing Fix: 366424454 Test: atest WMShellUnitTests:DragPositioningCallbackUtilityTest Test: atest WMShellUnitTests:VeiledResizeTaskPositionerTest Test: atest WMShellUnitTests:FluidResizeTaskPositionerTest Change-Id: I4959f3a9a725e619bb620f00cc383e939a173e79 --- .../DragPositioningCallbackUtility.java | 38 ++++++++++ .../DragPositioningCallbackUtilityTest.kt | 84 ++++++++++++++++++++++ .../windowdecor/FluidResizeTaskPositionerTest.kt | 1 + .../windowdecor/VeiledResizeTaskPositionerTest.kt | 1 + 4 files changed, 124 insertions(+) (limited to 'libs') diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java index cb9781e86c87..cad34621c82a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java @@ -84,22 +84,47 @@ public class DragPositioningCallbackUtility { repositionTaskBounds.set(taskBoundsAtDragStart); + boolean isAspectRatioMaintained = true; // Make sure the new resizing destination in any direction falls within the stable bounds. if ((ctrlType & CTRL_TYPE_LEFT) != 0) { repositionTaskBounds.left = Math.max(repositionTaskBounds.left + (int) delta.x, stableBounds.left); + if (repositionTaskBounds.left == stableBounds.left + && repositionTaskBounds.left + (int) delta.x != stableBounds.left) { + // If the task edge have been set to the stable bounds and not due to the users + // drag, the aspect ratio of the task will not be maintained. + isAspectRatioMaintained = false; + } } if ((ctrlType & CTRL_TYPE_RIGHT) != 0) { repositionTaskBounds.right = Math.min(repositionTaskBounds.right + (int) delta.x, stableBounds.right); + if (repositionTaskBounds.right == stableBounds.right + && repositionTaskBounds.right + (int) delta.x != stableBounds.right) { + // If the task edge have been set to the stable bounds and not due to the users + // drag, the aspect ratio of the task will not be maintained. + isAspectRatioMaintained = false; + } } if ((ctrlType & CTRL_TYPE_TOP) != 0) { repositionTaskBounds.top = Math.max(repositionTaskBounds.top + (int) delta.y, stableBounds.top); + if (repositionTaskBounds.top == stableBounds.top + && repositionTaskBounds.top + (int) delta.y != stableBounds.top) { + // If the task edge have been set to the stable bounds and not due to the users + // drag, the aspect ratio of the task will not be maintained. + isAspectRatioMaintained = false; + } } if ((ctrlType & CTRL_TYPE_BOTTOM) != 0) { repositionTaskBounds.bottom = Math.min(repositionTaskBounds.bottom + (int) delta.y, stableBounds.bottom); + if (repositionTaskBounds.bottom == stableBounds.bottom + && repositionTaskBounds.bottom + (int) delta.y != stableBounds.bottom) { + // If the task edge have been set to the stable bounds and not due to the users + // drag, the aspect ratio of the task will not be maintained. + isAspectRatioMaintained = false; + } } // If width or height are negative or exceeding the width or height constraints, revert the @@ -108,11 +133,24 @@ public class DragPositioningCallbackUtility { windowDecoration)) { repositionTaskBounds.right = oldRight; repositionTaskBounds.left = oldLeft; + isAspectRatioMaintained = false; } if (isExceedingHeightConstraint(repositionTaskBounds, stableBounds, displayController, windowDecoration)) { repositionTaskBounds.top = oldTop; repositionTaskBounds.bottom = oldBottom; + isAspectRatioMaintained = false; + } + + // If the application is unresizeable and any bounds have been set back to their old + // location or to a stable bound edge, reset all the bounds to maintain the applications + // aspect ratio. + if (DesktopModeFlags.SCALED_RESIZING.isEnabled(windowDecoration.mDecorWindowContext) + && !isAspectRatioMaintained && !windowDecoration.mTaskInfo.isResizeable) { + repositionTaskBounds.top = oldTop; + repositionTaskBounds.bottom = oldBottom; + repositionTaskBounds.right = oldRight; + repositionTaskBounds.left = oldLeft; } // If there are no changes to the bounds after checking new bounds against minimum and diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt index 1f33ae69b724..24f6becc3536 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt @@ -39,6 +39,7 @@ import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP import com.google.common.truth.Truth.assertThat +import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import org.junit.After import org.junit.Before @@ -105,6 +106,7 @@ class DragPositioningCallbackUtilityTest { initializeTaskInfo() mockWindowDecoration.mDisplay = mockDisplay mockWindowDecoration.mDecorWindowContext = mockContext + mockWindowDecoration.mTaskInfo.isResizeable = true whenever(mockContext.getResources()).thenReturn(mockResources) whenever(mockWindowDecoration.mDecorWindowContext.resources).thenReturn(mockResources) whenever(mockResources.getDimensionPixelSize(R.dimen.desktop_mode_minimum_window_width)) @@ -163,6 +165,60 @@ class DragPositioningCallbackUtilityTest { assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom) } + @Test + @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_SCALED_RESIZING) + fun testChangeBounds_unresizeableApp_heightLessThanMin_resetToStartingBounds() { + mockWindowDecoration.mTaskInfo.isResizeable = false + val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat()) + val repositionTaskBounds = Rect(STARTING_BOUNDS) + + // Resize to width of 95px and height of 5px with min width of 10px + val newX = STARTING_BOUNDS.right.toFloat() - 5 + val newY = STARTING_BOUNDS.top.toFloat() + 95 + val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) + + assertFalse( + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, + repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, + mockWindowDecoration + ) + ) + + assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) + assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) + assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right) + assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom) + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_SCALED_RESIZING) + fun testChangeBounds_unresizeableApp_widthLessThanMin_resetToStartingBounds() { + mockWindowDecoration.mTaskInfo.isResizeable = false + val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat()) + val repositionTaskBounds = Rect(STARTING_BOUNDS) + + // Resize to height of 95px and width of 5px with min width of 10px + val newX = STARTING_BOUNDS.right.toFloat() - 95 + val newY = STARTING_BOUNDS.top.toFloat() + 5 + val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) + + assertFalse( + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, + repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, + mockWindowDecoration + ) + ) + + + assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) + assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) + assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right) + assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom) + } + + @Test fun testChangeBoundsDoesNotChangeHeightWhenNegative() { val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat()) @@ -316,6 +372,34 @@ class DragPositioningCallbackUtilityTest { assertThat(repositionTaskBounds.bottom).isEqualTo(STABLE_BOUNDS.bottom) } + @Test + @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_SCALED_RESIZING) + fun testChangeBounds_unresizeableApp_beyondStableBounds_resetToStartingBounds() { + mockWindowDecoration.mTaskInfo.isResizeable = false + val startingPoint = PointF( + STARTING_BOUNDS.right.toFloat(), + STARTING_BOUNDS.bottom.toFloat() + ) + val repositionTaskBounds = Rect(STARTING_BOUNDS) + + // Resize to beyond stable bounds. + val newX = STARTING_BOUNDS.right.toFloat() + STABLE_BOUNDS.width() + val newY = STARTING_BOUNDS.bottom.toFloat() + STABLE_BOUNDS.height() + + val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint) + assertFalse( + DragPositioningCallbackUtility.changeBounds( + CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM, + repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController, + mockWindowDecoration + ) + ) + assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left) + assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top) + assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right) + assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom) + } + @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS) fun taskMinWidthHeightUndefined_changeBoundsInDesktopModeLessThanMin_shouldNotChangeBounds() { diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt index 3a3e965b625e..7543fed4b085 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt @@ -121,6 +121,7 @@ class FluidResizeTaskPositionerTest : ShellTestCase() { displayId = DISPLAY_ID configuration.windowConfiguration.setBounds(STARTING_BOUNDS) configuration.windowConfiguration.displayRotation = ROTATION_90 + isResizeable = true } `when`(mockWindowDecoration.calculateValidDragArea()).thenReturn(VALID_DRAG_AREA) mockWindowDecoration.mDisplay = mockDisplay diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt index 6ae16edaf3df..7784af6b1111 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt @@ -141,6 +141,7 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() { displayId = DISPLAY_ID configuration.windowConfiguration.setBounds(STARTING_BOUNDS) configuration.windowConfiguration.displayRotation = ROTATION_90 + isResizeable = true } `when`(mockDesktopWindowDecoration.calculateValidDragArea()).thenReturn(VALID_DRAG_AREA) mockDesktopWindowDecoration.mDisplay = mockDisplay -- cgit v1.2.3-59-g8ed1b From e5629678bcac93e2cf15b85bde0c4f249169fb66 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 13 Sep 2024 14:18:34 -0700 Subject: Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ife69afa23782bc4cf0026953a6d9db10f8ef76c3 --- libs/WindowManager/Shell/res/values-es-rUS/strings.xml | 3 +-- libs/WindowManager/Shell/res/values-es/strings.xml | 3 +-- libs/WindowManager/Shell/res/values-fr/strings.xml | 3 +-- libs/WindowManager/Shell/res/values-it/strings.xml | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) (limited to 'libs') diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml index 8644780dba03..0dd0a99dd9ae 100644 --- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml +++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml @@ -73,8 +73,7 @@ "contraer %1$s" "Configuración de %1$s" "Descartar burbuja" - - + "Mover a pantalla completa" "No mostrar la conversación en burbuja" "Chat con burbujas" "Las conversaciones nuevas aparecen como elementos flotantes o burbujas. Presiona para abrir la burbuja. Arrástrala para moverla." diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index 9718bf19fcc3..6df154d9233d 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -73,8 +73,7 @@ "contraer %1$s" "Ajustes de %1$s" "Cerrar burbuja" - - + "Cambiar a pantalla completa" "No mostrar conversación en burbuja" "Chatea con burbujas" "Las conversaciones nuevas aparecen como iconos flotantes llamados \"burbujas\". Toca una burbuja para abrirla. Arrástrala para moverla." diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index 63b5994cd707..92f579db10b5 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -73,8 +73,7 @@ "Réduire %1$s" "Paramètres %1$s" "Fermer la bulle" - - + "Passer en plein écran" "Ne pas afficher la conversation dans une bulle" "Chatter en utilisant des bulles" "Les nouvelles conversations s\'affichent sous forme d\'icônes flottantes ou de bulles. Appuyez sur la bulle pour l\'ouvrir. Faites-la glisser pour la déplacer." diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml index 3ba6873617f6..5f9c492bf055 100644 --- a/libs/WindowManager/Shell/res/values-it/strings.xml +++ b/libs/WindowManager/Shell/res/values-it/strings.xml @@ -73,8 +73,7 @@ "comprimi %1$s" "Impostazioni %1$s" "Ignora bolla" - - + "Passa a schermo intero" "Non mettere la conversazione nella bolla" "Chatta utilizzando le bolle" "Le nuove conversazioni vengono mostrate come icone mobili o bolle. Tocca per aprire la bolla. Trascinala per spostarla." -- cgit v1.2.3-59-g8ed1b From cd2ee6d88da6bf2e7c47333f8fce5aba8711422c Mon Sep 17 00:00:00 2001 From: mattsziklay Date: Fri, 13 Sep 2024 15:29:26 -0700 Subject: [Desktop Windowing] Rename Additional Windows Above Status Bar flag. Renames the flag to "Enable Handle Input Fix" to better describe the use of the flag, that being to fix input issues in the handle area. Also labels it as a bugfix flag. Bug: 316186265 Test: m Flag: NONE, renaming a flag Change-Id: I7abafcdeca5d4c668d893b069c291d277e5b0359 --- .../android/window/flags/lse_desktop_experience.aconfig | 7 +++++-- .../shell/windowdecor/DesktopModeWindowDecorViewModel.java | 12 ++++++------ .../wm/shell/windowdecor/DesktopModeWindowDecoration.java | 14 +++++++------- .../src/com/android/wm/shell/windowdecor/HandleMenu.kt | 6 +++--- .../android/wm/shell/windowdecor/HandleMenuImageButton.kt | 2 +- .../wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt | 2 +- .../windowdecor/DesktopModeWindowDecorViewModelTests.kt | 4 ++-- .../windowdecor/DesktopModeWindowDecorationTests.java | 4 ++-- .../src/com/android/wm/shell/windowdecor/HandleMenuTest.kt | 8 ++++---- 9 files changed, 31 insertions(+), 28 deletions(-) (limited to 'libs') diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig index 6e89c497cbac..ca96460afb29 100644 --- a/core/java/android/window/flags/lse_desktop_experience.aconfig +++ b/core/java/android/window/flags/lse_desktop_experience.aconfig @@ -86,10 +86,13 @@ flag { } flag { - name: "enable_additional_windows_above_status_bar" + name: "enable_handle_input_fix" namespace: "lse_desktop_experience" - description: "Allows for additional windows tied to WindowDecoration to be layered between status bar and notification shade." + description: "Enables using AdditionalSystemViewContainer to resolve handle input issues." bug: "316186265" + metadata { + purpose: PURPOSE_BUGFIX + } } flag { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java index a0047da46d60..3812ddc93ce9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java @@ -405,7 +405,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { final RunningTaskInfo oldTaskInfo = decoration.mTaskInfo; if (taskInfo.displayId != oldTaskInfo.displayId - && !Flags.enableAdditionalWindowsAboveStatusBar()) { + && !Flags.enableHandleInputFix()) { removeTaskFromEventReceiver(oldTaskInfo.displayId); incrementEventReceiverTasks(taskInfo.displayId); } @@ -472,7 +472,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { decoration.close(); final int displayId = taskInfo.displayId; if (mEventReceiversByDisplay.contains(displayId) - && !Flags.enableAdditionalWindowsAboveStatusBar()) { + && !Flags.enableHandleInputFix()) { removeTaskFromEventReceiver(displayId); } // Remove the decoration from the cache last because WindowDecoration#close could still @@ -1032,7 +1032,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { relevantDecor.updateHoverAndPressStatus(ev); final int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { - if (!mTransitionDragActive && !Flags.enableAdditionalWindowsAboveStatusBar()) { + if (!mTransitionDragActive && !Flags.enableHandleInputFix()) { relevantDecor.closeHandleMenuIfNeeded(ev); } } @@ -1075,7 +1075,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { } final boolean shouldStartTransitionDrag = relevantDecor.checkTouchEventInFocusedCaptionHandle(ev) - || Flags.enableAdditionalWindowsAboveStatusBar(); + || Flags.enableHandleInputFix(); if (dragFromStatusBarAllowed && shouldStartTransitionDrag) { mTransitionDragActive = true; } @@ -1342,7 +1342,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { windowDecoration.setDragDetector(touchEventListener.mDragDetector); windowDecoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */, false /* shouldSetTaskPositionAndCrop */); - if (!Flags.enableAdditionalWindowsAboveStatusBar()) { + if (!Flags.enableHandleInputFix()) { incrementEventReceiverTasks(taskInfo.displayId); } } @@ -1475,7 +1475,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { && Flags.enableDesktopWindowingImmersiveHandleHiding()) { decor.onInsetsStateChanged(insetsState); } - if (!Flags.enableAdditionalWindowsAboveStatusBar()) { + if (!Flags.enableHandleInputFix()) { // If status bar inset is visible, top task is not in immersive mode. // This value is only needed when the App Handle input is being handled // through the global input monitor (hence the flag check) to ignore gestures 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 1409d3011395..6fcbc65ff64c 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 @@ -516,7 +516,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration Date: Thu, 12 Sep 2024 19:13:07 +0000 Subject: Batch migration of frameworks/base TEST_MAPPING to test_module_config modules As part of go/test-module-config we are moving test options from TEST_MAPPING -> Android.bp files. In previous Cls, we created the new `test_module_config` rules in Android.bp This is updating the TEST_MAPPING file to use those rules. It is also removing "FlakyTest and IgnoreTest" exclude annoations as they are now added in gcl files per run rather than ad-hoc per module. I have a script that looks at the generated tradefed config file for the new options added in Android.bp files, then it looks at TEST_MAPPING files and find the places to update where the options match for the test. I am also doing abtd runs of each TEST_MAPPING file before and after my change and ensuring the number of tests run is the same (or at least as many). There are cases where tradefed would comping include-filters across TEST_MAPPING entries for the same module, but now they will be purposefully split up, causing some tests to be run under two different modules. Flag: TEST_ONLY Test: Ran adbt on each TEST_MAPPING and compared before and after results. Verified we were still running all the tests we were before. i.e. after the adbt run, I would download the test artfiact for the tradefed detailed evenvt and compare test counts. You can see CtsAppTestCases became CtsAppTestCases_cts_requesttileserviceaddtest, etc. I'm not including results for all 100 TEST_MAPPING files, but I did verify with scripts and eyes. Minor differences (like 2011 vs 2009) on a test that didn't change are ignored, but in general there were more tests run, not fewer. % diff <(grep started frameworks_base_services_core_java_com_android_server_statusbar_TEST_MAPPING/BASE.details) <(grep started frameworks_base_services_core_java_com_android_server_statusbar_TEST_MAPPING/NEW.details) | grep run < [run x86_64 CtsAppTestCases (testCount: 6,attempt: 0) started] > [run x86_64 CtsAppTestCases_cts_requesttileserviceaddtest (testCount: 6,attempt: 0) started] < [run x86_64 CtsLocationFineTestCases (testCount: 96,attempt: 0) started] > [run x86_64 CtsLocationFineTestCases_android_server_location (testCount: 96,attempt: 0) started] < [run x86_64 FrameworksNetTests (testCount: 2009,attempt: 0) started] > [run x86_64 FrameworksNetTests (testCount: 2011,attempt: 0) started] Test-Mapping-Slo-Bypass-Bug: b/335015078 Change-Id: If6e3cd0624ac1c16f1cd088566d967769f47199c --- TEST_MAPPING | 174 ++-------------- .../service/java/com/android/server/TEST_MAPPING | 5 +- .../com/android/server/deviceidle/TEST_MAPPING | 5 +- .../java/com/android/server/job/TEST_MAPPING | 22 +- .../java/com/android/server/usage/TEST_MAPPING | 8 +- cmds/locksettings/TEST_MAPPING | 10 +- core/java/android/app/TEST_MAPPING | 221 ++------------------- core/java/android/app/time/TEST_MAPPING | 24 +-- core/java/android/app/timedetector/TEST_MAPPING | 21 +- .../java/android/app/timezonedetector/TEST_MAPPING | 21 +- core/java/android/app/trust/TEST_MAPPING | 20 +- core/java/android/content/TEST_MAPPING | 19 +- core/java/android/content/om/TEST_MAPPING | 7 +- .../android/content/pm/verify/domain/TEST_MAPPING | 7 +- core/java/android/net/TEST_MAPPING | 16 +- core/java/android/os/TEST_MAPPING | 38 +--- core/java/android/permission/TEST_MAPPING | 20 +- core/java/android/print/TEST_MAPPING | 7 +- core/java/android/provider/TEST_MAPPING | 7 +- core/java/android/security/TEST_MAPPING | 7 +- .../java/android/service/notification/TEST_MAPPING | 26 +-- .../android/service/quicksettings/TEST_MAPPING | 10 +- core/java/android/service/timezone/TEST_MAPPING | 7 +- core/java/android/speech/TEST_MAPPING | 10 +- core/java/android/text/TEST_MAPPING | 10 +- core/java/android/view/TEST_MAPPING | 32 +-- core/java/android/view/inputmethod/TEST_MAPPING | 16 +- core/java/android/view/textclassifier/TEST_MAPPING | 14 +- core/java/android/webkit/TEST_MAPPING | 21 +- core/java/android/widget/TEST_MAPPING | 43 +--- core/java/android/widget/inline/TEST_MAPPING | 13 +- core/java/com/android/internal/infra/TEST_MAPPING | 7 +- core/java/com/android/internal/os/TEST_MAPPING | 7 +- .../coretests/src/android/content/pm/TEST_MAPPING | 16 +- core/tests/vibrator/TEST_MAPPING | 7 +- graphics/TEST_MAPPING | 17 +- graphics/java/android/graphics/TEST_MAPPING | 10 +- .../java/android/graphics/drawable/TEST_MAPPING | 10 +- graphics/java/android/graphics/fonts/TEST_MAPPING | 10 +- graphics/java/android/graphics/pdf/TEST_MAPPING | 7 +- graphics/java/android/graphics/text/TEST_MAPPING | 10 +- libs/WindowManager/Jetpack/src/TEST_MAPPING | 26 +-- .../src/com/android/wm/shell/back/TEST_MAPPING | 26 +-- media/TEST_MAPPING | 14 +- media/java/android/media/projection/TEST_MAPPING | 10 +- native/android/TEST_MAPPING | 7 +- native/webview/TEST_MAPPING | 21 +- packages/PrintSpooler/TEST_MAPPING | 7 +- .../src/com/android/settingslib/users/TEST_MAPPING | 7 +- packages/SettingsProvider/TEST_MAPPING | 7 +- packages/Shell/TEST_MAPPING | 17 +- packages/SystemUI/TEST_MAPPING | 20 +- .../accessibility/accessibilitymenu/TEST_MAPPING | 7 +- packages/SystemUI/compose/core/TEST_MAPPING | 20 +- packages/SystemUI/compose/scene/TEST_MAPPING | 30 +-- .../src/com/android/systemui/qs/TEST_MAPPING | 20 +- .../com/android/systemui/statusbar/TEST_MAPPING | 13 +- ravenwood/TEST_MAPPING | 20 +- .../java/com/android/server/autofill/TEST_MAPPING | 10 +- services/backup/TEST_MAPPING | 7 +- .../android/server/companion/virtual/TEST_MAPPING | 70 +------ services/core/java/com/android/server/TEST_MAPPING | 22 +- .../core/java/com/android/server/am/TEST_MAPPING | 47 +---- .../core/java/com/android/server/app/TEST_MAPPING | 33 +-- .../java/com/android/server/appop/TEST_MAPPING | 14 +- .../java/com/android/server/attention/TEST_MAPPING | 19 +- .../java/com/android/server/display/TEST_MAPPING | 13 +- .../core/java/com/android/server/hdmi/TEST_MAPPING | 13 +- .../java/com/android/server/lights/TEST_MAPPING | 7 +- .../java/com/android/server/location/TEST_MAPPING | 8 +- .../com/android/server/locksettings/TEST_MAPPING | 10 +- .../android/server/media/projection/TEST_MAPPING | 10 +- .../core/java/com/android/server/net/TEST_MAPPING | 32 +-- .../com/android/server/notification/TEST_MAPPING | 26 +-- .../core/java/com/android/server/os/TEST_MAPPING | 24 +-- .../android/server/pm/verify/domain/TEST_MAPPING | 7 +- .../java/com/android/server/policy/TEST_MAPPING | 47 +---- .../java/com/android/server/power/TEST_MAPPING | 31 +-- .../java/com/android/server/security/TEST_MAPPING | 7 +- .../java/com/android/server/statusbar/TEST_MAPPING | 23 +-- .../com/android/server/timedetector/TEST_MAPPING | 7 +- .../android/server/timezonedetector/TEST_MAPPING | 7 +- .../java/com/android/server/trust/TEST_MAPPING | 30 +-- .../core/java/com/android/server/uri/TEST_MAPPING | 26 +-- .../java/com/android/server/wm/utils/TEST_MAPPING | 13 +- .../foldables/devicestateprovider/TEST_MAPPING | 7 +- services/incremental/TEST_MAPPING | 7 +- .../java/com/android/server/people/TEST_MAPPING | 7 +- services/permission/TEST_MAPPING | 20 +- .../java/com/android/server/print/TEST_MAPPING | 7 +- .../InputMethodSystemServerTests/TEST_MAPPING | 14 +- .../tests/PackageManagerServiceTests/TEST_MAPPING | 32 +-- services/tests/dreamservicetests/TEST_MAPPING | 13 +- .../src/com/android/server/rollback/TEST_MAPPING | 7 +- services/tests/powerstatstests/TEST_MAPPING | 13 +- .../server/location/contexthub/TEST_MAPPING | 18 +- .../src/com/android/server/om/TEST_MAPPING | 7 +- services/tests/vibrator/TEST_MAPPING | 7 +- services/tests/voiceinteractiontests/TEST_MAPPING | 7 +- .../com/android/server/translation/TEST_MAPPING | 7 +- .../java/com/android/server/usage/TEST_MAPPING | 24 +-- services/voiceinteraction/TEST_MAPPING | 35 +--- telecomm/TEST_MAPPING | 56 +----- telephony/TEST_MAPPING | 49 +---- tests/TrustTests/TEST_MAPPING | 20 +- tests/utils/testutils/TEST_MAPPING | 13 +- 106 files changed, 237 insertions(+), 1930 deletions(-) (limited to 'libs') diff --git a/TEST_MAPPING b/TEST_MAPPING index 49384cde5803..bdae506115e8 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -1,44 +1,17 @@ { "presubmit-large": [ { - "name": "FrameworksServicesTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksServicesTests_Presubmit" } ], "presubmit-pm": [ { - "name": "PackageManagerServiceServerTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "PackageManagerServiceServerTests_Presubmit" } ], "presubmit": [ { - "name": "ManagedProvisioningTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ManagedProvisioningTests" }, { "file_patterns": [ @@ -46,86 +19,28 @@ "SystemServer\\.java", "services/tests/apexsystemservices/.*" ], - "name": "ApexSystemServicesTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "ApexSystemServicesTestCases" }, { - "name": "FrameworksUiServicesTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "FrameworksUiServicesTests" }, { - "name": "FrameworksInputMethodSystemServerTests", - "options": [ - {"include-filter": "com.android.server.inputmethod"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "FrameworksInputMethodSystemServerTests_server_inputmethod" }, { - "name": "ExtServicesUnitTests-tplus", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ExtServicesUnitTests-tplus" }, { - "name": "ExtServicesUnitTests-sminus", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ExtServicesUnitTests-sminus" }, { - "name": "FrameworksCoreTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksCoreTests_Presubmit" }, { - "name": "FrameworkPermissionTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworkPermissionTests_Presubmit" }, { - "name": "FrameworksInProcessTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksInProcessTests" }, { "name": "vts_treble_vintf_framework_test" @@ -159,78 +74,25 @@ // infra during the hardening phase. // TODO: this tag to be removed once the above is no longer an issue. { - "name": "FrameworksUiServicesTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "FrameworksUiServicesTests" }, { - "name": "ExtServicesUnitTests-tplus", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ExtServicesUnitTests-tplus" }, { - "name": "ExtServicesUnitTests-sminus", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ExtServicesUnitTests-sminus" }, { - "name": "TestablesTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TestablesTests" }, { - "name": "FrameworksCoreTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksCoreTests_Presubmit" }, { - "name": "FrameworksServicesTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksServicesTests_presubmit" }, { - "name": "PackageManagerServiceServerTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "PackageManagerServiceServerTests_Presubmit" } ] } diff --git a/apex/jobscheduler/service/java/com/android/server/TEST_MAPPING b/apex/jobscheduler/service/java/com/android/server/TEST_MAPPING index b58cb881fade..e3e72f43ef65 100644 --- a/apex/jobscheduler/service/java/com/android/server/TEST_MAPPING +++ b/apex/jobscheduler/service/java/com/android/server/TEST_MAPPING @@ -11,10 +11,7 @@ ], "postsubmit": [ { - "name": "FrameworksMockingServicesTests", - "options": [ - {"include-filter": "com.android.server"} - ] + "name": "FrameworksMockingServicesTests_android_server" } ] } diff --git a/apex/jobscheduler/service/java/com/android/server/deviceidle/TEST_MAPPING b/apex/jobscheduler/service/java/com/android/server/deviceidle/TEST_MAPPING index afa509c6ea93..ed8851c93042 100644 --- a/apex/jobscheduler/service/java/com/android/server/deviceidle/TEST_MAPPING +++ b/apex/jobscheduler/service/java/com/android/server/deviceidle/TEST_MAPPING @@ -6,10 +6,7 @@ ], "postsubmit": [ { - "name": "FrameworksMockingServicesTests", - "options": [ - {"include-filter": "com.android.server"} - ] + "name": "FrameworksMockingServicesTests_android_server" } ] } diff --git a/apex/jobscheduler/service/java/com/android/server/job/TEST_MAPPING b/apex/jobscheduler/service/java/com/android/server/job/TEST_MAPPING index a0bf78f28127..d198bfdd03ee 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/TEST_MAPPING +++ b/apex/jobscheduler/service/java/com/android/server/job/TEST_MAPPING @@ -1,11 +1,7 @@ { "presubmit": [ { - "name": "CtsJobSchedulerTestCases", - "options": [ - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "androidx.test.filters.LargeTest"} - ] + "name": "CtsJobSchedulerTestCases_com_android_server_job" }, { "name": "FrameworksMockingServicesTests_com_android_server_job_Presubmit" @@ -19,26 +15,16 @@ "name": "CtsJobSchedulerTestCases" }, { - "name": "FrameworksMockingServicesTests", - "options": [ - {"include-filter": "com.android.server.job"} - ] + "name": "FrameworksMockingServicesTests_com_android_server_job" }, { "name": "FrameworksServicesTests_com_android_server_job" }, { - "name": "CtsHostsideNetworkPolicyTests", - "options": [ - {"include-filter": "com.android.cts.netpolicy.HostsideRestrictBackgroundNetworkTests#testMeteredNetworkAccess_expeditedJob"}, - {"include-filter": "com.android.cts.netpolicy.HostsideRestrictBackgroundNetworkTests#testNonMeteredNetworkAccess_expeditedJob"} - ] + "name": "CtsHostsideNetworkPolicyTests_com_android_server_job" }, { - "name": "CtsStatsdAtomHostTestCases", - "options": [ - {"include-filter": "android.cts.statsdatom.jobscheduler"} - ] + "name": "CtsStatsdAtomHostTestCases_statsdatom_jobscheduler" } ] } diff --git a/apex/jobscheduler/service/java/com/android/server/usage/TEST_MAPPING b/apex/jobscheduler/service/java/com/android/server/usage/TEST_MAPPING index f56c14da8f23..1a2013daf2cd 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/TEST_MAPPING +++ b/apex/jobscheduler/service/java/com/android/server/usage/TEST_MAPPING @@ -1,13 +1,7 @@ { "presubmit": [ { - "name": "CtsUsageStatsTestCases", - "options": [ - {"include-filter": "android.app.usage.cts.UsageStatsTest"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "androidx.test.filters.MediumTest"}, - {"exclude-annotation": "androidx.test.filters.LargeTest"} - ] + "name": "CtsUsageStatsTestCases_cts_usagestatstest" }, { "name": "CtsBRSTestCases" diff --git a/cmds/locksettings/TEST_MAPPING b/cmds/locksettings/TEST_MAPPING index af54a2decd89..0f502c9904e5 100644 --- a/cmds/locksettings/TEST_MAPPING +++ b/cmds/locksettings/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit-large": [ { - "name": "CtsDevicePolicyManagerTestCases", - "options": [ - { - "include-annotation": "com.android.cts.devicepolicy.annotations.LockSettingsTest" - }, - { - "exclude-annotation": "android.platform.test.annotations.FlakyTest" - } - ] + "name": "CtsDevicePolicyManagerTestCases_LockSettingsTest" } ], "postsubmit": [ diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING index 2358d67c55e8..5ed1f4e35533 100644 --- a/core/java/android/app/TEST_MAPPING +++ b/core/java/android/app/TEST_MAPPING @@ -16,12 +16,7 @@ }, { "file_patterns": ["(/|^)AppOpsManager.java"], - "name": "CtsAppOpsTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsAppOpsTestCases" }, { "file_patterns": ["(/|^)AppOpsManager.java"], @@ -54,12 +49,7 @@ "file_patterns": ["INotificationManager\\.aidl"] }, { - "name": "CtsWindowManagerDeviceWindow", - "options": [ - { - "include-filter": "android.server.wm.window.ToastWindowTest" - } - ], + "name": "CtsWindowManagerDeviceWindow_window_toastwindowtest", "file_patterns": ["INotificationManager\\.aidl"] }, { @@ -67,42 +57,15 @@ "file_patterns": ["(/|^)InstantAppResolve[^/]*"] }, { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-filter": "android.autofillservice.cts.saveui.AutofillSaveDialogTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ], + "name": "CtsAutoFillServiceTestCases_saveui_autofillsavedialogtest", "file_patterns": ["(/|^)Activity.java"] }, { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-filter": "android.autofillservice.cts.saveui.PreSimpleSaveActivityTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ], + "name": "CtsAutoFillServiceTestCases_saveui_presimplesaveactivitytest", "file_patterns": ["(/|^)Activity.java"] }, { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-filter": "android.autofillservice.cts.saveui.SimpleSaveActivityTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "android.platform.test.annotations.AppModeFull" - } - ], + "name": "CtsAutoFillServiceTestCases_saveui_simplesaveactivitytest", "file_patterns": ["(/|^)Activity.java"] }, { @@ -119,32 +82,10 @@ }, { "name": "CtsLocalVoiceInteraction", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ], "file_patterns": ["(/|^)VoiceInteract[^/]*"] }, { - "name": "CtsOsTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.os.cts.StrictModeTest" - } - ], + "name": "CtsOsTestCases_cts_strictmodetest_Presubmit", "file_patterns": ["(/|^)ContextImpl.java"] }, { @@ -153,12 +94,7 @@ }, { "file_patterns": ["(/|^)LocaleManager.java"], - "name": "CtsLocaleManagerTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsLocaleManagerTestCases" }, { "name": "FrameworksCoreTests_keyguard_manager", @@ -173,172 +109,51 @@ ] }, { - "name": "FrameworksCoreGameManagerTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.app" - } - ], + "name": "FrameworksCoreGameManagerTests_android_app", "file_patterns": [ "(/|^)GameManager[^/]*", "(/|^)GameMode[^/]*" ] }, { - "name": "HdmiCecTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.hardware.hdmi" - } - ], + "name": "HdmiCecTests_hardware_hdmi", "file_patterns": [ "(/|^)DeviceFeature[^/]*", "(/|^)Hdmi[^/]*" ] }, { - "name": "CtsWindowManagerDeviceActivity", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceActivity_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceAm", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceAm_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceBackNavigation", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceBackNavigation_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceDisplay", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceDisplay_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceKeyguard", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceKeyguard_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceInsets", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceInsets_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceTaskFragment", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceTaskFragment_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceWindow", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceWindow_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceOther", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceOther_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { diff --git a/core/java/android/app/time/TEST_MAPPING b/core/java/android/app/time/TEST_MAPPING index 7673acacbfbe..9e416385bbfb 100644 --- a/core/java/android/app/time/TEST_MAPPING +++ b/core/java/android/app/time/TEST_MAPPING @@ -1,31 +1,13 @@ { "presubmit": [ { - "name": "FrameworksTimeCoreTests", - "options": [ - { - "include-filter": "android.app." - } - ] + "name": "FrameworksTimeCoreTests_android_app" }, { - "name": "CtsTimeTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTimeTestCases" }, { - "name": "FrameworksTimeServicesTests", - "options": [ - { - "include-filter": "com.android.server.timezonedetector." - }, - { - "include-filter": "com.android.server.timedetector." - } - ] + "name": "FrameworksTimeServicesTests_time" } ] } diff --git a/core/java/android/app/timedetector/TEST_MAPPING b/core/java/android/app/timedetector/TEST_MAPPING index c7ca6a230d43..d876308f4a9b 100644 --- a/core/java/android/app/timedetector/TEST_MAPPING +++ b/core/java/android/app/timedetector/TEST_MAPPING @@ -1,28 +1,13 @@ { "presubmit": [ { - "name": "FrameworksTimeCoreTests", - "options": [ - { - "include-filter": "android.app." - } - ] + "name": "FrameworksTimeCoreTests_android_app" }, { - "name": "CtsTimeTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTimeTestCases" }, { - "name": "FrameworksTimeServicesTests", - "options": [ - { - "include-filter": "com.android.server.timedetector." - } - ] + "name": "FrameworksTimeServicesTests_server_timedetector" } ] } diff --git a/core/java/android/app/timezonedetector/TEST_MAPPING b/core/java/android/app/timezonedetector/TEST_MAPPING index c8d0bb2306cd..dca7bbf17ab9 100644 --- a/core/java/android/app/timezonedetector/TEST_MAPPING +++ b/core/java/android/app/timezonedetector/TEST_MAPPING @@ -1,28 +1,13 @@ { "presubmit": [ { - "name": "FrameworksTimeCoreTests", - "options": [ - { - "include-filter": "android.app." - } - ] + "name": "FrameworksTimeCoreTests_android_app" }, { - "name": "CtsTimeTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTimeTestCases" }, { - "name": "FrameworksTimeServicesTests", - "options": [ - { - "include-filter": "com.android.server.timezonedetector." - } - ] + "name": "FrameworksTimeServicesTests_server_timezonedetector" } ] } diff --git a/core/java/android/app/trust/TEST_MAPPING b/core/java/android/app/trust/TEST_MAPPING index 23923eeb83ee..b0dd55100c8a 100644 --- a/core/java/android/app/trust/TEST_MAPPING +++ b/core/java/android/app/trust/TEST_MAPPING @@ -1,28 +1,12 @@ { "presubmit": [ { - "name": "TrustTests", - "options": [ - { - "include-filter": "android.trust.test" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TrustTests_trust_test" } ], "trust-tablet": [ { - "name": "TrustTests", - "options": [ - { - "include-filter": "android.trust.test" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TrustTests_trust_test" } ] } \ No newline at end of file diff --git a/core/java/android/content/TEST_MAPPING b/core/java/android/content/TEST_MAPPING index e353a0107bab..8d90b021fbfc 100644 --- a/core/java/android/content/TEST_MAPPING +++ b/core/java/android/content/TEST_MAPPING @@ -1,24 +1,7 @@ { "presubmit": [ { - "name": "CtsOsTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.os.cts.StrictModeTest" - } - ], + "name": "CtsOsTestCases_cts_strictmodetest_Presubmit", "file_patterns": ["(/|^)Context.java", "(/|^)ContextWrapper.java"] }, { diff --git a/core/java/android/content/om/TEST_MAPPING b/core/java/android/content/om/TEST_MAPPING index 82c47a03863b..b36c8958ea71 100644 --- a/core/java/android/content/om/TEST_MAPPING +++ b/core/java/android/content/om/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.om" - } - ] + "name": "FrameworksServicesTests_server_om" }, { "name": "OverlayDeviceTests" diff --git a/core/java/android/content/pm/verify/domain/TEST_MAPPING b/core/java/android/content/pm/verify/domain/TEST_MAPPING index 8a1982a339ea..db98c402eeeb 100644 --- a/core/java/android/content/pm/verify/domain/TEST_MAPPING +++ b/core/java/android/content/pm/verify/domain/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "PackageManagerServiceUnitTests", - "options": [ - { - "include-filter": "com.android.server.pm.test.verify.domain" - } - ] + "name": "PackageManagerServiceUnitTests_verify_domain" }, { "name": "CtsDomainVerificationDeviceStandaloneTestCases" diff --git a/core/java/android/net/TEST_MAPPING b/core/java/android/net/TEST_MAPPING index 3df56162bd2c..ea509bb24f0a 100644 --- a/core/java/android/net/TEST_MAPPING +++ b/core/java/android/net/TEST_MAPPING @@ -19,21 +19,7 @@ ], "presubmit": [ { - "name": "FrameworksCoreTests", - "options": [ - { - "include-filter": "android.net" - }, - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksCoreTests_android_net" } ] } diff --git a/core/java/android/os/TEST_MAPPING b/core/java/android/os/TEST_MAPPING index ce8a58081782..7c36cb91db93 100644 --- a/core/java/android/os/TEST_MAPPING +++ b/core/java/android/os/TEST_MAPPING @@ -38,33 +38,15 @@ }, { "file_patterns": ["Bugreport[^/]*\\.java"], - "name": "BugreportManagerTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "BugreportManagerTestCases_android_server_os" }, { "file_patterns": ["Bugreport[^/]*\\.java"], - "name": "CtsBugreportTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsBugreportTestCases_android_server_os" }, { "file_patterns": ["Bugreport[^/]*\\.java"], - "name": "ShellTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ShellTests_android_server_os" }, { "file_patterns": [ @@ -99,12 +81,7 @@ "Parcel\\.java", "[^/]*Bundle[^/]*\\.java" ], - "name": "FrameworksMockingCoreTests", - "options": [ - { "include-filter": "android.os.BundleRecyclingTest"}, - { "exclude-annotation": "androidx.test.filters.FlakyTest" }, - { "exclude-annotation": "org.junit.Ignore" } - ] + "name": "FrameworksMockingCoreTests_os_bundlerecyclingtest" }, { "file_patterns": [ @@ -116,12 +93,7 @@ }, { "file_patterns": ["SharedMemory[^/]*\\.java"], - "name": "CtsOsTestCases", - "options": [ - { - "include-filter": "android.os.cts.SharedMemoryTest" - } - ] + "name": "CtsOsTestCases_cts_sharedmemorytest" }, { "file_patterns": ["Environment[^/]*\\.java"], diff --git a/core/java/android/permission/TEST_MAPPING b/core/java/android/permission/TEST_MAPPING index b317b80d5677..3e5a131fbdc1 100644 --- a/core/java/android/permission/TEST_MAPPING +++ b/core/java/android/permission/TEST_MAPPING @@ -6,26 +6,10 @@ ], "postsubmit": [ { - "name": "CtsVirtualDevicesAudioTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "include-filter": "android.virtualdevice.cts.audio.VirtualAudioPermissionTest" - } - ] + "name": "CtsVirtualDevicesAudioTestCases_audio_virtualaudiopermissiontest" }, { - "name": "CtsVirtualDevicesAppLaunchTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "include-filter": "android.virtualdevice.cts.applaunch.VirtualDevicePermissionTest" - } - ] + "name": "CtsVirtualDevicesAppLaunchTestCases_applaunch_virtualdevicepermissiontest" } ] } diff --git a/core/java/android/print/TEST_MAPPING b/core/java/android/print/TEST_MAPPING index 4fa882265e53..1033b1a86edb 100644 --- a/core/java/android/print/TEST_MAPPING +++ b/core/java/android/print/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsPrintTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - } - ] + "name": "CtsPrintTestCases_Presubmit" } ] } diff --git a/core/java/android/provider/TEST_MAPPING b/core/java/android/provider/TEST_MAPPING index 2eb285dda0a2..a6fe3016e8ba 100644 --- a/core/java/android/provider/TEST_MAPPING +++ b/core/java/android/provider/TEST_MAPPING @@ -24,12 +24,7 @@ "name": "SettingsProviderTest" }, { - "name": "CtsPackageManagerHostTestCases", - "options": [ - { - "include-filter": "android.appsecurity.cts.ReadableSettingsFieldsTest" - } - ] + "name": "CtsPackageManagerHostTestCases_cts_readablesettingsfieldstest" } ], "postsubmit": [ diff --git a/core/java/android/security/TEST_MAPPING b/core/java/android/security/TEST_MAPPING index 5a679b1a2bf7..e1c7f3c2f3d3 100644 --- a/core/java/android/security/TEST_MAPPING +++ b/core/java/android/security/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsSecurityTestCases", - "options": [ - { - "include-filter": "android.security.cts.FileIntegrityManagerTest" - } - ], + "name": "CtsSecurityTestCases_cts_fileintegritymanagertest", "file_patterns": [ "FileIntegrityManager\\.java", "IFileIntegrityService\\.aidl" diff --git a/core/java/android/service/notification/TEST_MAPPING b/core/java/android/service/notification/TEST_MAPPING index 468c4518602e..dc7129cde5e5 100644 --- a/core/java/android/service/notification/TEST_MAPPING +++ b/core/java/android/service/notification/TEST_MAPPING @@ -1,32 +1,10 @@ { "presubmit": [ { - "name": "CtsNotificationTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsNotificationTestCases_notification" }, { - "name": "FrameworksUiServicesTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "FrameworksUiServicesTests_notification" } ], "postsubmit": [ diff --git a/core/java/android/service/quicksettings/TEST_MAPPING b/core/java/android/service/quicksettings/TEST_MAPPING index 2d45c5b252cc..986dc5fd2ba9 100644 --- a/core/java/android/service/quicksettings/TEST_MAPPING +++ b/core/java/android/service/quicksettings/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "CtsTileServiceTestCases", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTileServiceTestCases" } ] } \ No newline at end of file diff --git a/core/java/android/service/timezone/TEST_MAPPING b/core/java/android/service/timezone/TEST_MAPPING index bf46ff2ffe06..2071717e5f60 100644 --- a/core/java/android/service/timezone/TEST_MAPPING +++ b/core/java/android/service/timezone/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "FrameworksTimeCoreTests", - "options": [ - { - "include-filter": "android.service." - } - ] + "name": "FrameworksTimeCoreTests_android_service" }, { "name": "CtsLocationTimeZoneManagerHostTest" diff --git a/core/java/android/speech/TEST_MAPPING b/core/java/android/speech/TEST_MAPPING index 7b125c2b0851..cb490f5b62d4 100644 --- a/core/java/android/speech/TEST_MAPPING +++ b/core/java/android/speech/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "CtsVoiceRecognitionTestCases", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVoiceRecognitionTestCases" } ] } diff --git a/core/java/android/text/TEST_MAPPING b/core/java/android/text/TEST_MAPPING index c9bd2cacb138..9f8a72cb5975 100644 --- a/core/java/android/text/TEST_MAPPING +++ b/core/java/android/text/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "CtsTextTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsTextTestCases_text" } ] } diff --git a/core/java/android/view/TEST_MAPPING b/core/java/android/view/TEST_MAPPING index db3590814e08..ac6cd02b58aa 100644 --- a/core/java/android/view/TEST_MAPPING +++ b/core/java/android/view/TEST_MAPPING @@ -4,39 +4,11 @@ "name": "CtsAccelerationTestCases" }, { - "name": "CtsOsTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.os.cts.StrictModeTest" - } - ], + "name": "CtsOsTestCases_cts_strictmodetest_Presubmit", "file_patterns": ["(/|^)ViewConfiguration.java", "(/|^)GestureDetector.java"] }, { - "name": "CtsViewReceiveContentTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ], + "name": "CtsViewReceiveContentTestCases_Presubmit", "file_patterns": ["ContentInfo\\.java", "OnReceiveContentListener\\.java", "View\\.java"] } ], diff --git a/core/java/android/view/inputmethod/TEST_MAPPING b/core/java/android/view/inputmethod/TEST_MAPPING index ad59463ea1f1..989b686d6281 100644 --- a/core/java/android/view/inputmethod/TEST_MAPPING +++ b/core/java/android/view/inputmethod/TEST_MAPPING @@ -1,21 +1,7 @@ { "presubmit": [ { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-filter": "android.autofillservice.cts.inline" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "android.platform.test.annotations.AppModeFull" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsAutoFillServiceTestCases_cts_inline_ExcludeAppModeFull" } ] } diff --git a/core/java/android/view/textclassifier/TEST_MAPPING b/core/java/android/view/textclassifier/TEST_MAPPING index 050c65191cad..bc7f3b0e2dc1 100644 --- a/core/java/android/view/textclassifier/TEST_MAPPING +++ b/core/java/android/view/textclassifier/TEST_MAPPING @@ -4,20 +4,10 @@ "name": "FrameworksCoreTests_textclassifier" }, { - "name": "CtsTextClassifierTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTextClassifierTestCases" }, { - "name": "TextClassifierServiceTest", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TextClassifierServiceTest" } ] } diff --git a/core/java/android/webkit/TEST_MAPPING b/core/java/android/webkit/TEST_MAPPING index 07f438329e43..38580595dc2d 100644 --- a/core/java/android/webkit/TEST_MAPPING +++ b/core/java/android/webkit/TEST_MAPPING @@ -1,28 +1,13 @@ { "presubmit": [ { - "name": "CtsWebkitTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsWebkitTestCases" }, { - "name": "CtsSdkSandboxWebkitTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsSdkSandboxWebkitTestCases" }, { - "name": "CtsHostsideWebViewTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsHostsideWebViewTests" }, { "name": "GtsWebViewTestCases", diff --git a/core/java/android/widget/TEST_MAPPING b/core/java/android/widget/TEST_MAPPING index bc71bee33d06..624fa864aea6 100644 --- a/core/java/android/widget/TEST_MAPPING +++ b/core/java/android/widget/TEST_MAPPING @@ -10,52 +10,17 @@ "file_patterns": ["Toast\\.java"] }, { - "name": "CtsWindowManagerDeviceWindow", - "options": [ - { - "include-filter": "android.server.wm.window.ToastWindowTest" - } - ], + "name": "CtsWindowManagerDeviceWindow_window_toastwindowtest", "file_patterns": ["Toast\\.java"] }, { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-filter": "android.autofillservice.cts.dropdown.LoginActivityTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "android.platform.test.annotations.AppModeFull" - } - ] + "name": "CtsAutoFillServiceTestCases_dropdown_loginactivitytest" }, { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-filter": "android.autofillservice.cts.dropdown.CheckoutActivityTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "android.platform.test.annotations.AppModeFull" - } - ] + "name": "CtsAutoFillServiceTestCases_dropdown_checkoutactivitytest" }, { - "name": "CtsTextTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsTextTestCases_text" } ] } diff --git a/core/java/android/widget/inline/TEST_MAPPING b/core/java/android/widget/inline/TEST_MAPPING index 82c6f61c3486..eb412f110def 100644 --- a/core/java/android/widget/inline/TEST_MAPPING +++ b/core/java/android/widget/inline/TEST_MAPPING @@ -1,18 +1,7 @@ { "presubmit-large": [ { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-filter": "android.autofillservice.cts.inline" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsAutoFillServiceTestCases_cts_inline" } ] } diff --git a/core/java/com/android/internal/infra/TEST_MAPPING b/core/java/com/android/internal/infra/TEST_MAPPING index 35f0553d41d7..092aa20ba730 100644 --- a/core/java/com/android/internal/infra/TEST_MAPPING +++ b/core/java/com/android/internal/infra/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsRoleTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsRoleTestCases" }, { "name": "CtsPermissionTestCases_Platform" diff --git a/core/java/com/android/internal/os/TEST_MAPPING b/core/java/com/android/internal/os/TEST_MAPPING index 467cd77f15b4..83773e251a9e 100644 --- a/core/java/com/android/internal/os/TEST_MAPPING +++ b/core/java/com/android/internal/os/TEST_MAPPING @@ -49,12 +49,7 @@ ], "postsubmit": [ { - "name": "PowerStatsTests", - "options": [ - { - "include-filter": "com.android.server.power.stats.BstatsCpuTimesValidationTest" - } - ], + "name": "PowerStatsTests_stats_bstatscputimesvalidationtest", "file_patterns": [ "Kernel[^/]*\\.java" ] diff --git a/core/tests/coretests/src/android/content/pm/TEST_MAPPING b/core/tests/coretests/src/android/content/pm/TEST_MAPPING index 9ab438ef9fd2..b350d7d50251 100644 --- a/core/tests/coretests/src/android/content/pm/TEST_MAPPING +++ b/core/tests/coretests/src/android/content/pm/TEST_MAPPING @@ -6,21 +6,7 @@ ], "postsubmit": [ { - "name": "FrameworksCoreTests", - "options": [ - { - "include-filter": "android.content.pm." - }, - { - "include-annotation": "android.platform.test.annotations.Postsubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksCoreTests_android_content_pm_PostSubmit" } ] } diff --git a/core/tests/vibrator/TEST_MAPPING b/core/tests/vibrator/TEST_MAPPING index 54a5ff1d675d..d91b883b873e 100644 --- a/core/tests/vibrator/TEST_MAPPING +++ b/core/tests/vibrator/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "FrameworksVibratorCoreTests", - "options": [ - {"exclude-annotation": "androidx.test.filters.LargeTest"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "FrameworksVibratorCoreTests" } ], "postsubmit": [ diff --git a/graphics/TEST_MAPPING b/graphics/TEST_MAPPING index 8afc30d54a53..75cb87c0e737 100644 --- a/graphics/TEST_MAPPING +++ b/graphics/TEST_MAPPING @@ -1,23 +1,10 @@ { "presubmit": [ { - "name": "CtsGraphicsTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsGraphicsTestCases" }, { - "name": "CtsTextTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ], + "name": "CtsTextTestCases_text", "file_patterns": ["(/|^)Typeface\\.java", "(/|^)Paint\\.java"] } ] diff --git a/graphics/java/android/graphics/TEST_MAPPING b/graphics/java/android/graphics/TEST_MAPPING index df912222909a..5cc31ba840f7 100644 --- a/graphics/java/android/graphics/TEST_MAPPING +++ b/graphics/java/android/graphics/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "CtsTextTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ], + "name": "CtsTextTestCases_text", "file_patterns": [ "Typeface\\.java", "Paint\\.java", diff --git a/graphics/java/android/graphics/drawable/TEST_MAPPING b/graphics/java/android/graphics/drawable/TEST_MAPPING index 4f064522b037..da0a721c89ef 100644 --- a/graphics/java/android/graphics/drawable/TEST_MAPPING +++ b/graphics/java/android/graphics/drawable/TEST_MAPPING @@ -1,14 +1,8 @@ { "presubmit": [ { - - "name": "CtsGraphicsTestCases", - "file_patterns": ["(/|^)Icon\\.java"], - "options" : [ - { - "include-filter": "android.graphics.drawable.cts.IconTest" - } - ] + "name": "CtsGraphicsTestCases_cts_icontest", + "file_patterns": ["(/|^)Icon\\.java"] }, { diff --git a/graphics/java/android/graphics/fonts/TEST_MAPPING b/graphics/java/android/graphics/fonts/TEST_MAPPING index 99cbfe720c05..9f8a72cb5975 100644 --- a/graphics/java/android/graphics/fonts/TEST_MAPPING +++ b/graphics/java/android/graphics/fonts/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "CtsTextTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsTextTestCases_text" } ] } diff --git a/graphics/java/android/graphics/pdf/TEST_MAPPING b/graphics/java/android/graphics/pdf/TEST_MAPPING index afec35c76371..8720b9571474 100644 --- a/graphics/java/android/graphics/pdf/TEST_MAPPING +++ b/graphics/java/android/graphics/pdf/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsPdfTestCases", - "options": [ - { - "include-filter": "android.graphics.pdf.cts.PdfDocumentTest" - } - ] + "name": "CtsPdfTestCases_cts_pdfdocumenttest" } ] } diff --git a/graphics/java/android/graphics/text/TEST_MAPPING b/graphics/java/android/graphics/text/TEST_MAPPING index 99cbfe720c05..9f8a72cb5975 100644 --- a/graphics/java/android/graphics/text/TEST_MAPPING +++ b/graphics/java/android/graphics/text/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "CtsTextTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsTextTestCases_text" } ] } diff --git a/libs/WindowManager/Jetpack/src/TEST_MAPPING b/libs/WindowManager/Jetpack/src/TEST_MAPPING index f8f64001dd24..600c79bb88a4 100644 --- a/libs/WindowManager/Jetpack/src/TEST_MAPPING +++ b/libs/WindowManager/Jetpack/src/TEST_MAPPING @@ -1,32 +1,10 @@ { "presubmit": [ { - "name": "WMJetpackUnitTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "WMJetpackUnitTests_Presubmit" }, { - "name": "CtsWindowManagerJetpackTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "CtsWindowManagerJetpackTestCases_Presubmit" } ], "imports": [ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/TEST_MAPPING b/libs/WindowManager/Shell/src/com/android/wm/shell/back/TEST_MAPPING index f02559f36169..df3a369febbc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/TEST_MAPPING +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/TEST_MAPPING @@ -1,32 +1,10 @@ { "presubmit": [ { - "name": "WMShellUnitTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "include-filter": "com.android.wm.shell.back" - } - ] + "name": "WMShellUnitTests_shell_back" }, { - "name": "CtsWindowManagerDeviceBackNavigation", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "include-filter": "android.server.wm.backnavigation.BackGestureInvokedTest" - }, - { - "include-filter": "android.server.wm.backnavigation.BackNavigationTests" - }, - { - "include-filter": "android.server.wm.backnavigation.OnBackInvokedCallbackGestureTest" - } - ] + "name": "CtsWindowManagerDeviceBackNavigation_com_android_wm_shell_back" } ] } diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING index 6ac969527d89..e52e0b16eca3 100644 --- a/media/TEST_MAPPING +++ b/media/TEST_MAPPING @@ -30,24 +30,14 @@ "file_patterns": ["(?i)drm|crypto"] }, { - "name": "CtsMediaDrmFrameworkTestCases", - "options" : [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - } - ], + "name": "CtsMediaDrmFrameworkTestCases_Presubmit", "file_patterns": ["(?i)drm|crypto"] }, { "file_patterns": [ "[^/]*(LoudnessCodec)[^/]*\\.java" ], - "name": "LoudnessCodecApiTest", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - } - ] + "name": "LoudnessCodecApiTest_Presubmit" } ] } diff --git a/media/java/android/media/projection/TEST_MAPPING b/media/java/android/media/projection/TEST_MAPPING index 7aa9118e45ee..b33097c50002 100644 --- a/media/java/android/media/projection/TEST_MAPPING +++ b/media/java/android/media/projection/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "MediaProjectionTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "MediaProjectionTests" } ] } diff --git a/native/android/TEST_MAPPING b/native/android/TEST_MAPPING index 7c710982e4f6..be84574e6a2c 100644 --- a/native/android/TEST_MAPPING +++ b/native/android/TEST_MAPPING @@ -14,12 +14,7 @@ "file_patterns": ["permission_manager.cpp"] }, { - "name": "CtsOsTestCases", - "options": [ - { - "include-filter": "android.os.cts.PerformanceHintManagerTest" - } - ], + "name": "CtsOsTestCases_cts_performancehintmanagertest", "file_patterns": ["performance_hint.cpp"] } ], diff --git a/native/webview/TEST_MAPPING b/native/webview/TEST_MAPPING index 07f438329e43..38580595dc2d 100644 --- a/native/webview/TEST_MAPPING +++ b/native/webview/TEST_MAPPING @@ -1,28 +1,13 @@ { "presubmit": [ { - "name": "CtsWebkitTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsWebkitTestCases" }, { - "name": "CtsSdkSandboxWebkitTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsSdkSandboxWebkitTestCases" }, { - "name": "CtsHostsideWebViewTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsHostsideWebViewTests" }, { "name": "GtsWebViewTestCases", diff --git a/packages/PrintSpooler/TEST_MAPPING b/packages/PrintSpooler/TEST_MAPPING index ad3b44f1bcce..f8bf8a0d5c84 100644 --- a/packages/PrintSpooler/TEST_MAPPING +++ b/packages/PrintSpooler/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsPrintTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - } - ] + "name": "CtsPrintTestCases_Presubmit" } ], "postsubmit": [ diff --git a/packages/SettingsLib/src/com/android/settingslib/users/TEST_MAPPING b/packages/SettingsLib/src/com/android/settingslib/users/TEST_MAPPING index 71cbcb54a1ff..1346ee565a5d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/users/TEST_MAPPING +++ b/packages/SettingsLib/src/com/android/settingslib/users/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "SettingsLibTests", - "options": [ - { - "include-filter": "com.android.settingslib.users." - } - ] + "name": "SettingsLibTests_settingslib_users" } ] } \ No newline at end of file diff --git a/packages/SettingsProvider/TEST_MAPPING b/packages/SettingsProvider/TEST_MAPPING index 0eed2b7490d4..cf9ed2e6c1df 100644 --- a/packages/SettingsProvider/TEST_MAPPING +++ b/packages/SettingsProvider/TEST_MAPPING @@ -4,12 +4,7 @@ "name": "SettingsProviderTest" }, { - "name": "CtsProviderTestCases", - "options": [ - { - "include-filter": "android.provider.cts.settings." - } - ] + "name": "CtsProviderTestCases_cts_settings" } ], "postsubmit": [ diff --git a/packages/Shell/TEST_MAPPING b/packages/Shell/TEST_MAPPING index 9bb1b4b99207..6b9f1ebd4061 100644 --- a/packages/Shell/TEST_MAPPING +++ b/packages/Shell/TEST_MAPPING @@ -1,23 +1,10 @@ { "presubmit": [ { - "name": "CtsBugreportTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsBugreportTestCases_android_server_os" }, { - "name": "ShellTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ShellTests_android_server_os" }, { "name": "CtsUiAutomationTestCases", diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING index 16dd4e5a800e..07a1e630e1ad 100644 --- a/packages/SystemUI/TEST_MAPPING +++ b/packages/SystemUI/TEST_MAPPING @@ -21,15 +21,7 @@ // v2/android-virtual-infra/test_mapping/presubmit-avd "presubmit": [ { - "name": "SystemUIGoogleTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "SystemUIGoogleTests" }, { // Permission indicators @@ -48,15 +40,7 @@ }, { // Permission indicators - "name": "CtsVoiceRecognitionTestCases", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVoiceRecognitionTestCases" } ], diff --git a/packages/SystemUI/accessibility/accessibilitymenu/TEST_MAPPING b/packages/SystemUI/accessibility/accessibilitymenu/TEST_MAPPING index 4a10108b3e04..1820f39bb180 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/TEST_MAPPING +++ b/packages/SystemUI/accessibility/accessibilitymenu/TEST_MAPPING @@ -2,12 +2,7 @@ // TODO: b/324945360 - Re-enable on presubmit after fixing failures "postsubmit": [ { - "name": "AccessibilityMenuServiceTests", - "options": [ - { - "exclude-annotation": "android.support.test.filters.FlakyTest" - } - ] + "name": "AccessibilityMenuServiceTests" } ] } \ No newline at end of file diff --git a/packages/SystemUI/compose/core/TEST_MAPPING b/packages/SystemUI/compose/core/TEST_MAPPING index b71c5fb29fd7..56e531d2bee0 100644 --- a/packages/SystemUI/compose/core/TEST_MAPPING +++ b/packages/SystemUI/compose/core/TEST_MAPPING @@ -1,26 +1,10 @@ { "presubmit": [ { - "name": "PlatformComposeCoreTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "PlatformComposeCoreTests" }, { - "name": "SystemUIComposeGalleryTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "SystemUIComposeGalleryTests" } ] } \ No newline at end of file diff --git a/packages/SystemUI/compose/scene/TEST_MAPPING b/packages/SystemUI/compose/scene/TEST_MAPPING index f9424ed62d78..65ba037cf995 100644 --- a/packages/SystemUI/compose/scene/TEST_MAPPING +++ b/packages/SystemUI/compose/scene/TEST_MAPPING @@ -1,37 +1,13 @@ { "presubmit": [ { - "name": "PlatformComposeSceneTransitionLayoutTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "PlatformComposeSceneTransitionLayoutTests" }, { - "name": "PlatformComposeCoreTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "PlatformComposeCoreTests" }, { - "name": "SystemUIComposeGalleryTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "SystemUIComposeGalleryTests" } ] } \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/qs/TEST_MAPPING b/packages/SystemUI/src/com/android/systemui/qs/TEST_MAPPING index 66f020f24e80..75140bee3cdd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/TEST_MAPPING +++ b/packages/SystemUI/src/com/android/systemui/qs/TEST_MAPPING @@ -1,28 +1,12 @@ { "presubmit": [ { - "name": "CtsTileServiceTestCases", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTileServiceTestCases" } ], "postsubmit": [ { - "name": "QuickSettingsDeviceResetTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "QuickSettingsDeviceResetTests" } ] } \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/TEST_MAPPING b/packages/SystemUI/src/com/android/systemui/statusbar/TEST_MAPPING index 718c1c0f683b..323268440c4a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/TEST_MAPPING +++ b/packages/SystemUI/src/com/android/systemui/statusbar/TEST_MAPPING @@ -1,18 +1,7 @@ { "presubmit": [ { - "name": "CtsNotificationTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsNotificationTestCases_notification" } ], "postsubmit": [ diff --git a/ravenwood/TEST_MAPPING b/ravenwood/TEST_MAPPING index fbf27fa5bf4b..57548378579c 100644 --- a/ravenwood/TEST_MAPPING +++ b/ravenwood/TEST_MAPPING @@ -17,28 +17,12 @@ }, // The sysui tests should match vendor/unbundled_google/packages/SystemUIGoogle/TEST_MAPPING { - "name": "SystemUIGoogleTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "SystemUIGoogleTests" } ], "presubmit-large": [ { - "name": "SystemUITests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "SystemUITests" } ], "ravenwood-presubmit": [ diff --git a/services/autofill/java/com/android/server/autofill/TEST_MAPPING b/services/autofill/java/com/android/server/autofill/TEST_MAPPING index d8a69177387d..1dbeebe95904 100644 --- a/services/autofill/java/com/android/server/autofill/TEST_MAPPING +++ b/services/autofill/java/com/android/server/autofill/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit-large": [ { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsAutoFillServiceTestCases_android_server_autofill_Presubmit" } ] } diff --git a/services/backup/TEST_MAPPING b/services/backup/TEST_MAPPING index e1532309b78e..0c14e56932df 100644 --- a/services/backup/TEST_MAPPING +++ b/services/backup/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "FrameworksMockingServicesTests", - "options": [ - { - "include-filter": "com.android.server.backup" - } - ] + "name": "FrameworksMockingServicesTests_backup" }, { "name": "CtsBackupTestCases", diff --git a/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING b/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING index caa877c2b964..14579c6fa3ad 100644 --- a/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING +++ b/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING @@ -1,81 +1,32 @@ { "presubmit": [ { - "name": "CtsVirtualDevicesTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVirtualDevicesTestCases" }, { - "name": "CtsVirtualDevicesAudioTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVirtualDevicesAudioTestCases" }, { - "name": "CtsVirtualDevicesSensorTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVirtualDevicesSensorTestCases" }, { - "name": "CtsVirtualDevicesAppLaunchTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVirtualDevicesAppLaunchTestCases" }, { "name": "CtsVirtualDevicesCameraTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ], "keywords": ["primary-device"] }, { - "name": "CtsHardwareTestCases", - "options": [ - { - "include-filter": "android.hardware.input.cts.tests" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ], + "name": "CtsHardwareTestCases_cts_tests", "file_patterns": ["Virtual[^/]*\\.java"] }, { - "name": "CtsAccessibilityServiceTestCases", - "options": [ - { - "include-filter": "android.accessibilityservice.cts.AccessibilityDisplayProxyTest" - }, - { - "exclude-annotation": "android.support.test.filters.FlakyTest" - } - ] + "name": "CtsAccessibilityServiceTestCases_cts_accessibilitydisplayproxytest" } ], "postsubmit": [ { - "name": "CtsMediaAudioTestCases", - "options": [ - { - "include-filter": "android.media.audio.cts.AudioFocusWithVdmTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsMediaAudioTestCases_cts_audiofocuswithvdmtest" }, { "name": "CtsPermissionTestCases", @@ -92,12 +43,7 @@ ] }, { - "name": "CtsPermissionMultiDeviceTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsPermissionMultiDeviceTestCases" } ] } diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING index 825e4fb89d86..f2e4e7319075 100644 --- a/services/core/java/com/android/server/TEST_MAPPING +++ b/services/core/java/com/android/server/TEST_MAPPING @@ -1,13 +1,7 @@ { "presubmit": [ { - "name": "CtsLocationFineTestCases", - "options": [ - { - // TODO: Wait for test to deflake - b/293934372 - "exclude-filter":"android.location.cts.fine.ScanningSettingsTest" - } - ] + "name": "CtsLocationFineTestCases_android_server_location" }, { "name": "CtsLocationCoarseTestCases" @@ -20,12 +14,7 @@ "file_patterns": ["NotificationManagerService\\.java"] }, { - "name": "CtsWindowManagerDeviceWindow", - "options": [ - { - "include-filter": "android.server.wm.window.ToastWindowTest" - } - ], + "name": "CtsWindowManagerDeviceWindow_window_toastwindowtest", "file_patterns": ["NotificationManagerService\\.java"] }, { @@ -103,12 +92,7 @@ "file_patterns": ["VcnManagementService\\.java"] }, { - "name": "FrameworksVpnTests", - "options": [ - { - "exclude-annotation": "com.android.testutils.SkipPresubmit" - } - ], + "name": "FrameworksVpnTests_android_server_connectivity", "file_patterns": ["VpnManagerService\\.java"] }, { diff --git a/services/core/java/com/android/server/am/TEST_MAPPING b/services/core/java/com/android/server/am/TEST_MAPPING index ab5e2d04cecd..6383dcb000ab 100644 --- a/services/core/java/com/android/server/am/TEST_MAPPING +++ b/services/core/java/com/android/server/am/TEST_MAPPING @@ -22,32 +22,10 @@ ] }, { - "name": "CtsAppFgsTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsAppFgsTestCases_pm_Presubmit" }, { - "name": "CtsShortFgsTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsShortFgsTestCases_pm_Presubmit" }, { "name": "FrameworksServicesTests_android_server_am_Presubmit" @@ -73,23 +51,14 @@ }, { "file_patterns": ["Broadcast.*"], - "name": "CtsBroadcastTestCases", - "options": [ - { "exclude-annotation": "androidx.test.filters.LargeTest" }, - { "exclude-annotation": "androidx.test.filters.FlakyTest" }, - { "exclude-annotation": "org.junit.Ignore" } - ] + "name": "CtsBroadcastTestCases_android_server_am" }, { - "name": "CtsBRSTestCases", "file_patterns": [ "ActivityManagerService\\.java", "BroadcastQueue\\.java" ], - "options": [ - { "exclude-annotation": "androidx.test.filters.FlakyTest" }, - { "exclude-annotation": "org.junit.Ignore" } - ] + "name": "CtsBRSTestCases" } ], "postsubmit": [ @@ -110,13 +79,7 @@ ] }, { - "name": "CtsStatsdAtomHostTestCases", - "options": [ - { "include-filter": "android.cts.statsdatom.appexit.AppExitHostTest" }, - { "exclude-annotation": "androidx.test.filters.LargeTest" }, - { "exclude-annotation": "androidx.test.filters.FlakyTest" }, - { "exclude-annotation": "org.junit.Ignore" } - ] + "name": "CtsStatsdAtomHostTestCases_appexit_appexithosttest" }, { "name": "CtsContentTestCases", diff --git a/services/core/java/com/android/server/app/TEST_MAPPING b/services/core/java/com/android/server/app/TEST_MAPPING index b718ce62c118..9e76175ae866 100644 --- a/services/core/java/com/android/server/app/TEST_MAPPING +++ b/services/core/java/com/android/server/app/TEST_MAPPING @@ -1,26 +1,10 @@ { "presubmit": [ { - "name": "CtsGameManagerTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsGameManagerTestCases" }, { - "name": "CtsStatsdAtomHostTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.cts.statsdatom.gamemanager" - } - ], + "name": "CtsStatsdAtomHostTestCases_statsdatom_gamemanager", "file_patterns": [ "(/|^)GameManagerService.java" ] @@ -29,18 +13,7 @@ "name": "FrameworksMockingServicesTests_android_server_app" }, { - "name": "FrameworksCoreGameManagerTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.app" - } - ], + "name": "FrameworksCoreGameManagerTests_android_app", "file_patterns": [ "(/|^)GameManagerService.java", "(/|^)GameManagerSettings.java" ] diff --git a/services/core/java/com/android/server/appop/TEST_MAPPING b/services/core/java/com/android/server/appop/TEST_MAPPING index 9317c1eda088..25dd30b0226a 100644 --- a/services/core/java/com/android/server/appop/TEST_MAPPING +++ b/services/core/java/com/android/server/appop/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsAppOpsTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsAppOpsTestCases" }, { "name": "CtsAppOps2TestCases" @@ -21,12 +16,7 @@ "name": "CtsPermissionTestCases_Platform" }, { - "name": "CtsAppTestCases", - "options": [ - { - "include-filter": "android.app.cts.ActivityManagerApi29Test" - } - ] + "name": "CtsAppTestCases_cts_activitymanagerapi29test" }, { "name": "CtsStatsdAtomHostTestCases", diff --git a/services/core/java/com/android/server/attention/TEST_MAPPING b/services/core/java/com/android/server/attention/TEST_MAPPING index e5b034415824..519ed071830d 100644 --- a/services/core/java/com/android/server/attention/TEST_MAPPING +++ b/services/core/java/com/android/server/attention/TEST_MAPPING @@ -1,24 +1,7 @@ { "presubmit": [ { - "name": "CtsVoiceInteractionTestCases", - "options": [ - { - "include-filter": "android.voiceinteraction.cts.AlwaysOnHotwordDetectorTest" - }, - { - "include-filter": "android.voiceinteraction.cts.unittests.HotwordDetectedResultTest" - }, - { - "include-filter": "android.voiceinteraction.cts.HotwordDetectionServiceBasicTest" - }, - { - "include-filter": "android.voiceinteraction.cts.HotwordDetectionServiceProximityTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVoiceInteractionTestCases_android_server_attention" } ] } diff --git a/services/core/java/com/android/server/display/TEST_MAPPING b/services/core/java/com/android/server/display/TEST_MAPPING index 049b2fd032db..4d7962f467fd 100644 --- a/services/core/java/com/android/server/display/TEST_MAPPING +++ b/services/core/java/com/android/server/display/TEST_MAPPING @@ -1,21 +1,12 @@ { "presubmit": [ { - "name": "DisplayServiceTests", - "options": [ - {"include-filter": "com.android.server.display"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "DisplayServiceTests_server_display" } ], "postsubmit": [ { - "name": "DisplayServiceTests", - "options": [ - {"include-filter": "com.android.server.display"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "DisplayServiceTests_server_display" } ] } diff --git a/services/core/java/com/android/server/hdmi/TEST_MAPPING b/services/core/java/com/android/server/hdmi/TEST_MAPPING index d116087d5e1c..bacacafb1153 100644 --- a/services/core/java/com/android/server/hdmi/TEST_MAPPING +++ b/services/core/java/com/android/server/hdmi/TEST_MAPPING @@ -12,18 +12,7 @@ // Postsubmit tests for TV devices "tv-postsubmit": [ { - "name": "HdmiCecTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.hardware.hdmi" - } - ], + "name": "HdmiCecTests_hardware_hdmi", "file_patterns": [ "(/|^)DeviceFeature[^/]*", "(/|^)Hdmi[^/]*" ] diff --git a/services/core/java/com/android/server/lights/TEST_MAPPING b/services/core/java/com/android/server/lights/TEST_MAPPING index 1d2cd3c6e217..8abdf0069e1f 100644 --- a/services/core/java/com/android/server/lights/TEST_MAPPING +++ b/services/core/java/com/android/server/lights/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsHardwareTestCases", - "options": [ - {"include-filter": "com.android.hardware.lights"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "androidx.test.filters.LargeTest"} - ] + "name": "CtsHardwareTestCases_hardware_lights" }, { "name": "FrameworksServicesTests_android_server_lights" diff --git a/services/core/java/com/android/server/location/TEST_MAPPING b/services/core/java/com/android/server/location/TEST_MAPPING index 64b1ed20656e..b2ac7d1ef7e7 100644 --- a/services/core/java/com/android/server/location/TEST_MAPPING +++ b/services/core/java/com/android/server/location/TEST_MAPPING @@ -1,13 +1,7 @@ { "presubmit": [ { - "name": "CtsLocationFineTestCases", - "options": [ - { - // TODO: Wait for test to deflake - b/293934372 - "exclude-filter":"android.location.cts.fine.ScanningSettingsTest" - } - ] + "name": "CtsLocationFineTestCases_android_server_location" }, { "name": "CtsLocationCoarseTestCases" diff --git a/services/core/java/com/android/server/locksettings/TEST_MAPPING b/services/core/java/com/android/server/locksettings/TEST_MAPPING index ffbdf7f2bf8b..d338c50bb8c1 100644 --- a/services/core/java/com/android/server/locksettings/TEST_MAPPING +++ b/services/core/java/com/android/server/locksettings/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit-large": [ { - "name": "CtsDevicePolicyManagerTestCases", - "options": [ - { - "include-annotation": "com.android.cts.devicepolicy.annotations.LockSettingsTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsDevicePolicyManagerTestCases_LockSettingsTest" } ], "presubmit": [ diff --git a/services/core/java/com/android/server/media/projection/TEST_MAPPING b/services/core/java/com/android/server/media/projection/TEST_MAPPING index 7aa9118e45ee..b33097c50002 100644 --- a/services/core/java/com/android/server/media/projection/TEST_MAPPING +++ b/services/core/java/com/android/server/media/projection/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "MediaProjectionTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "MediaProjectionTests" } ] } diff --git a/services/core/java/com/android/server/net/TEST_MAPPING b/services/core/java/com/android/server/net/TEST_MAPPING index ad6b0ca71527..d95849ec6d6a 100644 --- a/services/core/java/com/android/server/net/TEST_MAPPING +++ b/services/core/java/com/android/server/net/TEST_MAPPING @@ -1,40 +1,16 @@ { "presubmit-large": [ { - "name": "CtsHostsideNetworkPolicyTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "android.platform.test.annotations.FlakyTest" - } - ] + "name": "CtsHostsideNetworkPolicyTests" } ], "presubmit": [ { - "name": "FrameworksServicesTests", - "file_patterns": ["(/|^)Network(Policy|Management)[^/]*\\.java"], - "options": [ - { - "include-filter": "com.android.server.net." - }, - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "FrameworksServicesTests_android_server_net_Presubmit", + "file_patterns": ["(/|^)Network(Policy|Management)[^/]*\\.java"] }, { - "name": "FrameworksVpnTests", - "options": [ - { - "exclude-annotation": "com.android.testutils.SkipPresubmit" - } - ], + "name": "FrameworksVpnTests_android_server_connectivity", "file_patterns": ["VpnManagerService\\.java"] } ] diff --git a/services/core/java/com/android/server/notification/TEST_MAPPING b/services/core/java/com/android/server/notification/TEST_MAPPING index 468c4518602e..dc7129cde5e5 100644 --- a/services/core/java/com/android/server/notification/TEST_MAPPING +++ b/services/core/java/com/android/server/notification/TEST_MAPPING @@ -1,32 +1,10 @@ { "presubmit": [ { - "name": "CtsNotificationTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsNotificationTestCases_notification" }, { - "name": "FrameworksUiServicesTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "FrameworksUiServicesTests_notification" } ], "postsubmit": [ diff --git a/services/core/java/com/android/server/os/TEST_MAPPING b/services/core/java/com/android/server/os/TEST_MAPPING index 50c8964b2aa4..3ffcd186dc4b 100644 --- a/services/core/java/com/android/server/os/TEST_MAPPING +++ b/services/core/java/com/android/server/os/TEST_MAPPING @@ -2,36 +2,18 @@ "presubmit": [ { "file_patterns": ["Bugreport[^/]*\\.java"], - "name": "BugreportManagerTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "BugreportManagerTestCases_android_server_os" }, { "file_patterns": ["Bugreport[^/]*\\.java"], - "name": "CtsBugreportTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsBugreportTestCases_android_server_os" }, { "name": "CtsUsbTests" }, { "file_patterns": ["Bugreport[^/]*\\.java"], - "name": "ShellTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ShellTests_android_server_os" } ], "postsubmit": [ diff --git a/services/core/java/com/android/server/pm/verify/domain/TEST_MAPPING b/services/core/java/com/android/server/pm/verify/domain/TEST_MAPPING index 8a1982a339ea..db98c402eeeb 100644 --- a/services/core/java/com/android/server/pm/verify/domain/TEST_MAPPING +++ b/services/core/java/com/android/server/pm/verify/domain/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "PackageManagerServiceUnitTests", - "options": [ - { - "include-filter": "com.android.server.pm.test.verify.domain" - } - ] + "name": "PackageManagerServiceUnitTests_verify_domain" }, { "name": "CtsDomainVerificationDeviceStandaloneTestCases" diff --git a/services/core/java/com/android/server/policy/TEST_MAPPING b/services/core/java/com/android/server/policy/TEST_MAPPING index bdb174d98137..76a050350393 100644 --- a/services/core/java/com/android/server/policy/TEST_MAPPING +++ b/services/core/java/com/android/server/policy/TEST_MAPPING @@ -1,32 +1,10 @@ { "presubmit": [ { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.policy." - }, - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "FrameworksServicesTests_android_server_policy_Presubmit" }, { - "name": "WmTests", - "options": [ - { - "include-filter": "com.android.server.policy." - }, - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "WmTests_server_policy_Presubmit" }, { "name": "CtsPermissionPolicyTestCases", @@ -49,30 +27,15 @@ "name": "CtsPermissionTestCases_Platform" }, { - "name": "CtsBackupTestCases", - "options": [ - { - "include-filter": "android.backup.cts.PermissionTest" - } - ] + "name": "CtsBackupTestCases_cts_permissiontest" } ], "postsubmit": [ { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.policy." - } - ] + "name": "FrameworksServicesTests_android_server_policy" }, { - "name": "WmTests", - "options": [ - { - "include-filter": "com.android.server.policy." - } - ] + "name": "WmTests_server_policy" }, { "name": "CtsPermissionPolicyTestCases", diff --git a/services/core/java/com/android/server/power/TEST_MAPPING b/services/core/java/com/android/server/power/TEST_MAPPING index 935a238bcee7..f67f56db3c1e 100644 --- a/services/core/java/com/android/server/power/TEST_MAPPING +++ b/services/core/java/com/android/server/power/TEST_MAPPING @@ -1,22 +1,13 @@ { "presubmit": [ { - "name": "CtsBatterySavingTestCases", - "options": [ - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "androidx.test.filters.LargeTest"} - ] + "name": "CtsBatterySavingTestCases_android_server_power" }, { "name": "FrameworksMockingServicesTests_android_server_power_Presubmit" }, { - "name": "PowerServiceTests", - "options": [ - {"include-filter": "com.android.server.power"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "PowerServiceTests_server_power" } ], "postsubmit": [ @@ -24,28 +15,16 @@ "name": "CtsBatterySavingTestCases" }, { - "name": "FrameworksMockingServicesTests", - "options": [ - {"include-filter": "com.android.server.power"} - ] + "name": "FrameworksMockingServicesTests_android_server_power" }, { "name": "FrameworksServicesTests_android_server_power" }, { - "name": "PowerServiceTests", - "options": [ - {"include-filter": "com.android.server.power"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "PowerServiceTests_server_power" }, { - "name": "CtsStatsdAtomHostTestCases", - "options": [ - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"}, - {"include-filter": "android.cts.statsdatom.powermanager"} - ], + "name": "CtsStatsdAtomHostTestCases_statsdatom_powermanager", "file_patterns": [ "(/|^)ThermalManagerService.java" ] diff --git a/services/core/java/com/android/server/security/TEST_MAPPING b/services/core/java/com/android/server/security/TEST_MAPPING index 29d52fff3eff..284e08e1e526 100644 --- a/services/core/java/com/android/server/security/TEST_MAPPING +++ b/services/core/java/com/android/server/security/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsSecurityTestCases", - "options": [ - { - "include-filter": "android.security.cts.FileIntegrityManagerTest" - } - ], + "name": "CtsSecurityTestCases_cts_fileintegritymanagertest", "file_patterns": ["FileIntegrity[^/]*\\.java"] } ] diff --git a/services/core/java/com/android/server/statusbar/TEST_MAPPING b/services/core/java/com/android/server/statusbar/TEST_MAPPING index 67ea557d7806..8c7e74c7e2c5 100644 --- a/services/core/java/com/android/server/statusbar/TEST_MAPPING +++ b/services/core/java/com/android/server/statusbar/TEST_MAPPING @@ -1,29 +1,10 @@ { "presubmit": [ { - "name": "CtsTileServiceTestCases", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTileServiceTestCases" }, { - "name": "CtsAppTestCases", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "include-filter": "android.app.cts.RequestTileServiceAddTest" - } - ] + "name": "CtsAppTestCases_cts_requesttileserviceaddtest" } ] } \ No newline at end of file diff --git a/services/core/java/com/android/server/timedetector/TEST_MAPPING b/services/core/java/com/android/server/timedetector/TEST_MAPPING index 17d327e94d4d..f57b819e241f 100644 --- a/services/core/java/com/android/server/timedetector/TEST_MAPPING +++ b/services/core/java/com/android/server/timedetector/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsTimeTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTimeTestCases" }, { "name": "FrameworksTimeServicesTests" diff --git a/services/core/java/com/android/server/timezonedetector/TEST_MAPPING b/services/core/java/com/android/server/timezonedetector/TEST_MAPPING index 004d79964354..a237c346a637 100644 --- a/services/core/java/com/android/server/timezonedetector/TEST_MAPPING +++ b/services/core/java/com/android/server/timezonedetector/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsTimeTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTimeTestCases" }, { "name": "FrameworksTimeServicesTests" diff --git a/services/core/java/com/android/server/trust/TEST_MAPPING b/services/core/java/com/android/server/trust/TEST_MAPPING index 0de7c28c209b..4c08455f713a 100644 --- a/services/core/java/com/android/server/trust/TEST_MAPPING +++ b/services/core/java/com/android/server/trust/TEST_MAPPING @@ -1,41 +1,17 @@ { "presubmit": [ { - "name": "TrustTests", - "options": [ - { - "include-filter": "android.trust.test" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TrustTests_trust_test" } ], "postsubmit": [ { - "name": "FrameworksMockingServicesTests", - "options": [ - { - "include-filter": "com.android.server.trust" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "FrameworksMockingServicesTests_android_server_trust" } ], "trust-tablet": [ { - "name": "TrustTests", - "options": [ - { - "include-filter": "android.trust.test" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TrustTests_trust_test" } ] } \ No newline at end of file diff --git a/services/core/java/com/android/server/uri/TEST_MAPPING b/services/core/java/com/android/server/uri/TEST_MAPPING index 0d756bb984d1..45e3051d4d5d 100644 --- a/services/core/java/com/android/server/uri/TEST_MAPPING +++ b/services/core/java/com/android/server/uri/TEST_MAPPING @@ -4,24 +4,7 @@ "name": "FrameworksServicesTests_android_server_uri" }, { - "name": "CtsStorageHostTestCases", - "options": [ - { - "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testGrantUriPermission" - }, - { - "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testGrantUriPermission29" - }, - { - "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testMediaNone" - }, - { - "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testMediaNone28" - }, - { - "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testMediaNone29" - } - ] + "name": "CtsStorageHostTestCases_android_server_uri" } ], "postsubmit": [ @@ -34,12 +17,7 @@ ] }, { - "name": "CtsWindowManagerDeviceWindow", - "options": [ - { - "include-filter": "android.server.wm.window.CrossAppDragAndDropTests" - } - ] + "name": "CtsWindowManagerDeviceWindow_window_crossappdraganddroptests" } ] } diff --git a/services/core/java/com/android/server/wm/utils/TEST_MAPPING b/services/core/java/com/android/server/wm/utils/TEST_MAPPING index aa69d2a18948..6f34cd047d5f 100644 --- a/services/core/java/com/android/server/wm/utils/TEST_MAPPING +++ b/services/core/java/com/android/server/wm/utils/TEST_MAPPING @@ -1,18 +1,7 @@ { "presubmit": [ { - "name": "WmTests", - "options": [ - { - "include-filter": "com.android.server.wm.utils" - }, - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "WmTests_wm_utils_Presubmit" } ] } diff --git a/services/foldables/devicestateprovider/TEST_MAPPING b/services/foldables/devicestateprovider/TEST_MAPPING index 47de131803c5..05383814a040 100644 --- a/services/foldables/devicestateprovider/TEST_MAPPING +++ b/services/foldables/devicestateprovider/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "foldable-device-state-provider-tests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "foldable-device-state-provider-tests" } ] } diff --git a/services/incremental/TEST_MAPPING b/services/incremental/TEST_MAPPING index 4c9403c9b21a..cbb99627d918 100644 --- a/services/incremental/TEST_MAPPING +++ b/services/incremental/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsPackageManagerStatsHostTestCases", - "options": [ - { - "include-filter": "com.android.cts.packagemanager.stats.host.PackageInstallerV2StatsTests" - } - ] + "name": "CtsPackageManagerStatsHostTestCases_host_packageinstallerv2statstests" }, { "name": "CtsPackageManagerIncrementalStatsHostTestCases", diff --git a/services/people/java/com/android/server/people/TEST_MAPPING b/services/people/java/com/android/server/people/TEST_MAPPING index 55b355cbc991..867733754967 100644 --- a/services/people/java/com/android/server/people/TEST_MAPPING +++ b/services/people/java/com/android/server/people/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.people.data" - } - ] + "name": "FrameworksServicesTests_people_data" } ] } \ No newline at end of file diff --git a/services/permission/TEST_MAPPING b/services/permission/TEST_MAPPING index 4de4a56aa806..af4aaf9736d8 100644 --- a/services/permission/TEST_MAPPING +++ b/services/permission/TEST_MAPPING @@ -105,26 +105,10 @@ ] }, { - "name": "CtsVirtualDevicesAudioTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "include-filter": "android.virtualdevice.cts.audio.VirtualAudioPermissionTest" - } - ] + "name": "CtsVirtualDevicesAudioTestCases_audio_virtualaudiopermissiontest" }, { - "name": "CtsVirtualDevicesAppLaunchTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "include-filter": "android.virtualdevice.cts.applaunch.VirtualDevicePermissionTest" - } - ] + "name": "CtsVirtualDevicesAppLaunchTestCases_applaunch_virtualdevicepermissiontest" } ], "imports": [ diff --git a/services/print/java/com/android/server/print/TEST_MAPPING b/services/print/java/com/android/server/print/TEST_MAPPING index 4fa882265e53..1033b1a86edb 100644 --- a/services/print/java/com/android/server/print/TEST_MAPPING +++ b/services/print/java/com/android/server/print/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsPrintTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - } - ] + "name": "CtsPrintTestCases_Presubmit" } ] } diff --git a/services/tests/InputMethodSystemServerTests/TEST_MAPPING b/services/tests/InputMethodSystemServerTests/TEST_MAPPING index de9f771a2a36..7313941f57b4 100644 --- a/services/tests/InputMethodSystemServerTests/TEST_MAPPING +++ b/services/tests/InputMethodSystemServerTests/TEST_MAPPING @@ -1,22 +1,12 @@ { "presubmit": [ { - "name": "FrameworksInputMethodSystemServerTests", - "options": [ - {"include-filter": "com.android.server.inputmethod"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "FrameworksInputMethodSystemServerTests_server_inputmethod" } ], "postsubmit": [ { - "name": "FrameworksImeTests", - "options": [ - {"include-filter": "com.android.inputmethodservice"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "FrameworksImeTests_android_inputmethodservice" } ] } diff --git a/services/tests/PackageManagerServiceTests/TEST_MAPPING b/services/tests/PackageManagerServiceTests/TEST_MAPPING index 5d96af9df1fb..13ba3171e455 100644 --- a/services/tests/PackageManagerServiceTests/TEST_MAPPING +++ b/services/tests/PackageManagerServiceTests/TEST_MAPPING @@ -4,21 +4,7 @@ "name": "AppEnumerationInternalTests" }, { - "name": "PackageManagerServiceServerTests", - "options": [ - { - "include-filter": "com.android.server.pm." - }, - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "PackageManagerServiceServerTests_server_pm_Presubmit" } ], "postsubmit": [ @@ -26,21 +12,7 @@ "name": "PackageManagerServiceHostTests" }, { - "name": "PackageManagerServiceServerTests", - "options": [ - { - "include-filter": "com.android.server.pm." - }, - { - "include-annotation": "android.platform.test.annotations.Postsubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "PackageManagerServiceServerTests_server_pm_Postsubmit" } ], "kernel-presubmit": [ diff --git a/services/tests/dreamservicetests/TEST_MAPPING b/services/tests/dreamservicetests/TEST_MAPPING index a644ea690dcd..38d7000ceb6e 100644 --- a/services/tests/dreamservicetests/TEST_MAPPING +++ b/services/tests/dreamservicetests/TEST_MAPPING @@ -1,21 +1,12 @@ { "presubmit": [ { - "name": "DreamServiceTests", - "options": [ - {"include-filter": "com.android.server.dreams"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "DreamServiceTests_server_dreams" } ], "postsubmit": [ { - "name": "DreamServiceTests", - "options": [ - {"include-filter": "com.android.server.dreams"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "DreamServiceTests_server_dreams" } ] } diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/TEST_MAPPING b/services/tests/mockingservicestests/src/com/android/server/rollback/TEST_MAPPING index 4ac4484956fc..ef2d60530a73 100644 --- a/services/tests/mockingservicestests/src/com/android/server/rollback/TEST_MAPPING +++ b/services/tests/mockingservicestests/src/com/android/server/rollback/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "RollbackPackageHealthObserverTests", - "options": [ - { - "include-filter": "com.android.server.rollback" - } - ] + "name": "RollbackPackageHealthObserverTests_server_rollback" } ] } \ No newline at end of file diff --git a/services/tests/powerstatstests/TEST_MAPPING b/services/tests/powerstatstests/TEST_MAPPING index fb243616292d..4e209f473ff3 100644 --- a/services/tests/powerstatstests/TEST_MAPPING +++ b/services/tests/powerstatstests/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "PowerStatsTests", - "options": [ - {"include-filter": "com.android.server.power.stats"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "PowerStatsTests_power_stats" } ], "ravenwood-presubmit": [ @@ -21,11 +16,7 @@ ], "postsubmit": [ { - "name": "PowerStatsTests", - "options": [ - {"include-filter": "com.android.server.power.stats"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "PowerStatsTests_power_stats" } ] } diff --git a/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING index 58f5bb3eb7d0..9b23b4908a78 100644 --- a/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING +++ b/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING @@ -6,23 +6,7 @@ ], "postsubmit": [ { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.location.contexthub." - }, - { - // I believe this include annotation is preventing tests from being run - // as there are no matching tests with the Postsubmit annotation. - "include-annotation": "android.platform.test.annotations.Postsubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksServicesTests_com_android_server_location_contexthub" } ] } diff --git a/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING index 944c1df94b92..dc3b1447c13e 100644 --- a/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING +++ b/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING @@ -4,12 +4,7 @@ "name": "FrameworksServicesTests_om" }, { - "name": "PackageManagerServiceHostTests", - "options": [ - { - "include-filter": "com.android.server.pm.test.OverlayActorVisibilityTest" - } - ] + "name": "PackageManagerServiceHostTests_test_overlayactorvisibilitytest" } ] } diff --git a/services/tests/vibrator/TEST_MAPPING b/services/tests/vibrator/TEST_MAPPING index 39bd238fc202..b17b96add466 100644 --- a/services/tests/vibrator/TEST_MAPPING +++ b/services/tests/vibrator/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "FrameworksVibratorServicesTests", - "options": [ - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "androidx.test.filters.LargeTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "FrameworksVibratorServicesTests" } ], "postsubmit": [ diff --git a/services/tests/voiceinteractiontests/TEST_MAPPING b/services/tests/voiceinteractiontests/TEST_MAPPING index 6cbc49a2a7e1..466ba54fc8a4 100644 --- a/services/tests/voiceinteractiontests/TEST_MAPPING +++ b/services/tests/voiceinteractiontests/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "FrameworksVoiceInteractionTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "FrameworksVoiceInteractionTests" } ], "postsubmit": [ diff --git a/services/translation/java/com/android/server/translation/TEST_MAPPING b/services/translation/java/com/android/server/translation/TEST_MAPPING index 4090b4ab2c75..0b97358d430d 100644 --- a/services/translation/java/com/android/server/translation/TEST_MAPPING +++ b/services/translation/java/com/android/server/translation/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsTranslationTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTranslationTestCases" } ] } diff --git a/services/usage/java/com/android/server/usage/TEST_MAPPING b/services/usage/java/com/android/server/usage/TEST_MAPPING index c8780546865e..79b294c00262 100644 --- a/services/usage/java/com/android/server/usage/TEST_MAPPING +++ b/services/usage/java/com/android/server/usage/TEST_MAPPING @@ -7,33 +7,15 @@ "name": "FrameworksServicesTests_android_server_usage" }, { - "name": "CtsBRSTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "CtsBRSTestCases" } ], "postsubmit": [ { - "name": "CtsUsageStatsTestCases", - "options": [ - { - "include-filter": "android.app.usage.cts.UsageStatsTest" - } - ] + "name": "CtsUsageStatsTestCases_cts_usagestatstest_ExcludeMediumAndLarge" }, { - "name": "CtsShortcutManagerTestCases", - "options": [ - { - "include-filter": "android.content.pm.cts.shortcutmanager.ShortcutManagerUsageTest" - } - ] + "name": "CtsShortcutManagerTestCases_shortcutmanager_shortcutmanagerusagetest" } ] } diff --git a/services/voiceinteraction/TEST_MAPPING b/services/voiceinteraction/TEST_MAPPING index e3d254948f8d..3a68b3327bbd 100644 --- a/services/voiceinteraction/TEST_MAPPING +++ b/services/voiceinteraction/TEST_MAPPING @@ -12,44 +12,19 @@ ] }, { - "name": "CtsAssistTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsAssistTestCases" }, { - "name": "CtsVoiceInteractionHostTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVoiceInteractionHostTestCases" }, { - "name": "CtsLocalVoiceInteraction", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsLocalVoiceInteraction" }, { - "name": "FrameworksVoiceInteractionTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "FrameworksVoiceInteractionTests" }, { - "name": "CtsSoundTriggerTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsSoundTriggerTestCases" } ] } diff --git a/telecomm/TEST_MAPPING b/telecomm/TEST_MAPPING index 775f1b83af94..4f6e55858b8d 100644 --- a/telecomm/TEST_MAPPING +++ b/telecomm/TEST_MAPPING @@ -1,70 +1,30 @@ { "presubmit": [ { - "name": "TeleServiceTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TeleServiceTests" }, { - "name": "TelecomUnitTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TelecomUnitTests" }, { - "name": "TelephonyProviderTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TelephonyProviderTests" }, { - "name": "CtsTelephony2TestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTelephony2TestCases" }, { - "name": "CtsTelephony3TestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTelephony3TestCases" }, { - "name": "CtsSimRestrictedApisTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsSimRestrictedApisTestCases" }, { - "name": "CtsTelephonyProviderTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTelephonyProviderTestCases" } ], "presubmit-large": [ { - "name": "CtsTelecomTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTelecomTestCases" } ] } diff --git a/telephony/TEST_MAPPING b/telephony/TEST_MAPPING index 73e3dcdb8dd0..4a4bae32ed8d 100644 --- a/telephony/TEST_MAPPING +++ b/telephony/TEST_MAPPING @@ -1,60 +1,25 @@ { "presubmit": [ { - "name": "TeleServiceTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TeleServiceTests" }, { - "name": "TelecomUnitTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TelecomUnitTests" }, { - "name": "TelephonyProviderTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TelephonyProviderTests" }, { - "name": "CtsTelephony2TestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTelephony2TestCases" }, { - "name": "CtsTelephony3TestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTelephony3TestCases" }, { - "name": "CtsSimRestrictedApisTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsSimRestrictedApisTestCases" }, { - "name": "CtsTelephonyProviderTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTelephonyProviderTestCases" } ] } diff --git a/tests/TrustTests/TEST_MAPPING b/tests/TrustTests/TEST_MAPPING index 23923eeb83ee..b0dd55100c8a 100644 --- a/tests/TrustTests/TEST_MAPPING +++ b/tests/TrustTests/TEST_MAPPING @@ -1,28 +1,12 @@ { "presubmit": [ { - "name": "TrustTests", - "options": [ - { - "include-filter": "android.trust.test" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TrustTests_trust_test" } ], "trust-tablet": [ { - "name": "TrustTests", - "options": [ - { - "include-filter": "android.trust.test" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TrustTests_trust_test" } ] } \ No newline at end of file diff --git a/tests/utils/testutils/TEST_MAPPING b/tests/utils/testutils/TEST_MAPPING index 52fd5a8779ad..71e9ad37dd3c 100644 --- a/tests/utils/testutils/TEST_MAPPING +++ b/tests/utils/testutils/TEST_MAPPING @@ -1,18 +1,7 @@ { "presubmit": [ { - "name": "frameworks-base-testutils-tests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "frameworks-base-testutils-tests" } ], "postsubmit": [ -- cgit v1.2.3-59-g8ed1b From ab6bbad80961d06caad3fe55b1a0fb48102ae2c5 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Fri, 13 Sep 2024 15:45:41 +0800 Subject: Use a color container surface to animate rotation with wallpaper By default, WallpaperService has a 0.05f dim. And SystemUI's DefaultDeviceEffectsApplier may set 0.6f for battery saver mode. If the wallpaper surface is not opaque, it may be blending with the surface behind. E.g. Before animation starts: z=1 Wallpaper 0.6 alpha z=0 No other layer (black) Animation starts: z=2 Wallpaper 0.6 alpha <--- looks brighter z=1 Bright (assume the content is light color) background layer Animation ends: (flickering when removing the background layer) z=2 Wallpaper 0.6 alpha z=0 No other layer (black) So wrap the surface which contains the wallpaper into a surface with color that will animate from background color to black, then the translucent wallpaper can have a smoother transition. Bug: 326331384 Flag: EXEMPT bugfix Test: Enable home rotation. Set a white color wallpaper. adb shell cmd battery unplug \ && adb shell settings put global low_power 1 (or "adb shell cmd wallpaper set-dim-amount 0.5") Rotate device. The end frame should not flickering from light to dark. Change-Id: Ie869abf59ecd59c976a503aee14880759f4b42e2 --- .../shell/transition/DefaultTransitionHandler.java | 5 +- .../shell/transition/ScreenRotationAnimation.java | 138 +++++++++++++-------- 2 files changed, 87 insertions(+), 56 deletions(-) (limited to 'libs') diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index 3a2820ee3aa9..1573291aef63 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -358,9 +358,12 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { if (mode == TRANSIT_CHANGE && change.hasFlags(FLAG_IS_DISPLAY)) { if (info.getType() == TRANSIT_CHANGE) { - final int anim = getRotationAnimationHint(change, info, mDisplayController); + int anim = getRotationAnimationHint(change, info, mDisplayController); isSeamlessDisplayChange = anim == ROTATION_ANIMATION_SEAMLESS; if (!(isSeamlessDisplayChange || anim == ROTATION_ANIMATION_JUMPCUT)) { + if (wallpaperTransit != WALLPAPER_TRANSITION_NONE) { + anim |= ScreenRotationAnimation.ANIMATION_HINT_HAS_WALLPAPER; + } startRotationAnimation(startTransaction, change, info, anim, animations, onAnimFinish); isDisplayRotationAnimationStarted = true; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java index 5802e2ca8133..b9d11a3d0c06 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java @@ -25,12 +25,9 @@ import static com.android.wm.shell.transition.DefaultTransitionHandler.buildSurf import static com.android.wm.shell.transition.Transitions.TAG; import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ArgbEvaluator; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.content.Context; -import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Rect; import android.hardware.HardwareBuffer; @@ -38,6 +35,7 @@ import android.util.Slog; import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; +import android.view.animation.AccelerateInterpolator; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.window.ScreenCapture; @@ -74,6 +72,9 @@ import java.util.ArrayList; */ class ScreenRotationAnimation { static final int MAX_ANIMATION_DURATION = 10 * 1000; + static final int ANIMATION_HINT_HAS_WALLPAPER = 1 << 8; + /** It must cover all WindowManager#ROTATION_ANIMATION_*. */ + private static final int ANIMATION_TYPE_MASK = 0xff; private final Context mContext; private final TransactionPool mTransactionPool; @@ -81,7 +82,7 @@ class ScreenRotationAnimation { /** The leash of the changing window container. */ private final SurfaceControl mSurfaceControl; - private final int mAnimHint; + private final int mAnimType; private final int mStartWidth; private final int mStartHeight; private final int mEndWidth; @@ -98,6 +99,12 @@ class ScreenRotationAnimation { private SurfaceControl mBackColorSurface; /** The leash using to animate screenshot layer. */ private final SurfaceControl mAnimLeash; + /** + * The container with background color for {@link #mSurfaceControl}. It is only created if + * {@link #mSurfaceControl} may be translucent. E.g. visible wallpaper with alpha < 1 (dimmed). + * That prevents flickering of alpha blending. + */ + private SurfaceControl mBackEffectSurface; // The current active animation to move from the old to the new rotated // state. Which animation is run here will depend on the old and new @@ -115,7 +122,7 @@ class ScreenRotationAnimation { Transaction t, TransitionInfo.Change change, SurfaceControl rootLeash, int animHint) { mContext = context; mTransactionPool = pool; - mAnimHint = animHint; + mAnimType = animHint & ANIMATION_TYPE_MASK; mSurfaceControl = change.getLeash(); mStartWidth = change.getStartAbsBounds().width(); @@ -170,11 +177,20 @@ class ScreenRotationAnimation { } hardwareBuffer.close(); } + if ((animHint & ANIMATION_HINT_HAS_WALLPAPER) != 0) { + mBackEffectSurface = new SurfaceControl.Builder() + .setCallsite("ShellRotationAnimation").setParent(rootLeash) + .setEffectLayer().setOpaque(true).setName("BackEffect").build(); + t.reparent(mSurfaceControl, mBackEffectSurface) + .setColor(mBackEffectSurface, + new float[] {mStartLuma, mStartLuma, mStartLuma}) + .show(mBackEffectSurface); + } t.setLayer(mAnimLeash, SCREEN_FREEZE_LAYER_BASE); t.show(mAnimLeash); // Crop the real content in case it contains a larger child layer, e.g. wallpaper. - t.setCrop(mSurfaceControl, new Rect(0, 0, mEndWidth, mEndHeight)); + t.setCrop(getEnterSurface(), new Rect(0, 0, mEndWidth, mEndHeight)); if (!isCustomRotate()) { mBackColorSurface = new SurfaceControl.Builder() @@ -199,7 +215,12 @@ class ScreenRotationAnimation { } private boolean isCustomRotate() { - return mAnimHint == ROTATION_ANIMATION_CROSSFADE || mAnimHint == ROTATION_ANIMATION_JUMPCUT; + return mAnimType == ROTATION_ANIMATION_CROSSFADE || mAnimType == ROTATION_ANIMATION_JUMPCUT; + } + + /** Returns the surface which contains the real content to animate enter. */ + private SurfaceControl getEnterSurface() { + return mBackEffectSurface != null ? mBackEffectSurface : mSurfaceControl; } private void setScreenshotTransform(SurfaceControl.Transaction t) { @@ -260,7 +281,7 @@ class ScreenRotationAnimation { final boolean customRotate = isCustomRotate(); if (customRotate) { mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, - mAnimHint == ROTATION_ANIMATION_JUMPCUT ? R.anim.rotation_animation_jump_exit + mAnimType == ROTATION_ANIMATION_JUMPCUT ? R.anim.rotation_animation_jump_exit : R.anim.rotation_animation_xfade_exit); mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, R.anim.rotation_animation_enter); @@ -314,7 +335,11 @@ class ScreenRotationAnimation { } else { startDisplayRotation(animations, finishCallback, mainExecutor); startScreenshotRotationAnimation(animations, finishCallback, mainExecutor); - //startColorAnimation(mTransaction, animationScale); + if (mBackEffectSurface != null && mStartLuma > 0.1f) { + // Animate from the color of background to black for smooth alpha blending. + buildLumaAnimation(animations, mStartLuma, 0f /* endLuma */, mBackEffectSurface, + animationScale, finishCallback, mainExecutor); + } } return true; @@ -322,7 +347,7 @@ class ScreenRotationAnimation { private void startDisplayRotation(@NonNull ArrayList animations, @NonNull Runnable finishCallback, @NonNull ShellExecutor mainExecutor) { - buildSurfaceAnimation(animations, mRotateEnterAnimation, mSurfaceControl, finishCallback, + buildSurfaceAnimation(animations, mRotateEnterAnimation, getEnterSurface(), finishCallback, mTransactionPool, mainExecutor, null /* position */, 0 /* cornerRadius */, null /* clipRect */, false /* isActivity */); } @@ -341,40 +366,17 @@ class ScreenRotationAnimation { null /* clipRect */, false /* isActivity */); } - private void startColorAnimation(float animationScale, @NonNull ShellExecutor animExecutor) { - int colorTransitionMs = mContext.getResources().getInteger( - R.integer.config_screen_rotation_color_transition); - final float[] rgbTmpFloat = new float[3]; - final int startColor = Color.rgb(mStartLuma, mStartLuma, mStartLuma); - final int endColor = Color.rgb(mEndLuma, mEndLuma, mEndLuma); - final long duration = colorTransitionMs * (long) animationScale; - final Transaction t = mTransactionPool.acquire(); - - final ValueAnimator va = ValueAnimator.ofFloat(0f, 1f); - // Animation length is already expected to be scaled. - va.overrideDurationScale(1.0f); - va.setDuration(duration); - va.addUpdateListener(animation -> { - final long currentPlayTime = Math.min(va.getDuration(), va.getCurrentPlayTime()); - final float fraction = currentPlayTime / va.getDuration(); - applyColor(startColor, endColor, rgbTmpFloat, fraction, mBackColorSurface, t); - }); - va.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationCancel(Animator animation) { - applyColor(startColor, endColor, rgbTmpFloat, 1f /* fraction */, mBackColorSurface, - t); - mTransactionPool.release(t); - } - - @Override - public void onAnimationEnd(Animator animation) { - applyColor(startColor, endColor, rgbTmpFloat, 1f /* fraction */, mBackColorSurface, - t); - mTransactionPool.release(t); - } - }); - animExecutor.execute(va::start); + private void buildLumaAnimation(@NonNull ArrayList animations, + float startLuma, float endLuma, SurfaceControl surface, float animationScale, + @NonNull Runnable finishCallback, @NonNull ShellExecutor mainExecutor) { + final long durationMillis = (long) (mContext.getResources().getInteger( + R.integer.config_screen_rotation_color_transition) * animationScale); + final LumaAnimation animation = new LumaAnimation(durationMillis); + // Align the end with the enter animation. + animation.setStartOffset(mRotateEnterAnimation.getDuration() - durationMillis); + final LumaAnimationAdapter adapter = new LumaAnimationAdapter(surface, startLuma, endLuma); + buildSurfaceAnimation(animations, animation, finishCallback, mTransactionPool, + mainExecutor, adapter); } public void kill() { @@ -389,21 +391,47 @@ class ScreenRotationAnimation { if (mBackColorSurface != null && mBackColorSurface.isValid()) { t.remove(mBackColorSurface); } + if (mBackEffectSurface != null && mBackEffectSurface.isValid()) { + t.remove(mBackEffectSurface); + } t.apply(); mTransactionPool.release(t); } - private static void applyColor(int startColor, int endColor, float[] rgbFloat, - float fraction, SurfaceControl surface, SurfaceControl.Transaction t) { - final int color = (Integer) ArgbEvaluator.getInstance().evaluate(fraction, startColor, - endColor); - Color middleColor = Color.valueOf(color); - rgbFloat[0] = middleColor.red(); - rgbFloat[1] = middleColor.green(); - rgbFloat[2] = middleColor.blue(); - if (surface.isValid()) { - t.setColor(surface, rgbFloat); + /** A no-op wrapper to provide animation duration. */ + private static class LumaAnimation extends Animation { + LumaAnimation(long durationMillis) { + setDuration(durationMillis); + } + } + + private static class LumaAnimationAdapter extends DefaultTransitionHandler.AnimationAdapter { + final float[] mColorArray = new float[3]; + final float mStartLuma; + final float mEndLuma; + final AccelerateInterpolator mInterpolation; + + LumaAnimationAdapter(@NonNull SurfaceControl leash, float startLuma, float endLuma) { + super(leash); + mStartLuma = startLuma; + mEndLuma = endLuma; + // Make the initial progress color lighter if the background is light. That avoids + // darker content when fading into the entering surface. + final float factor = Math.min(3f, (Math.max(0.5f, mStartLuma) - 0.5f) * 10); + Slog.d(TAG, "Luma=" + mStartLuma + " factor=" + factor); + mInterpolation = factor > 0.5f ? new AccelerateInterpolator(factor) : null; + } + + @Override + void applyTransformation(ValueAnimator animator) { + final float fraction = mInterpolation != null + ? mInterpolation.getInterpolation(animator.getAnimatedFraction()) + : animator.getAnimatedFraction(); + final float luma = mStartLuma + fraction * (mEndLuma - mStartLuma); + mColorArray[0] = luma; + mColorArray[1] = luma; + mColorArray[2] = luma; + mTransaction.setColor(mLeash, mColorArray); } - t.apply(); } } -- cgit v1.2.3-59-g8ed1b From bf48fb23e13bd737fc7fb1197c6650a2b1344236 Mon Sep 17 00:00:00 2001 From: Eghosa Ewansiha-Vlachavas Date: Fri, 13 Sep 2024 14:49:49 +0000 Subject: Enable sclaled resizing for non-resizeable apps Flag: com.android.window.flags.enable_windowing_scaled_resizing Test: atest WMShellUnitTests:VeiledResizeTaskPositionerTest Test: atest WMShellUnitTests:FluidResizeTaskPositionerTest Test: atest WMShellUnitTests:DesktopModeWindowDecorViewModelTests Test: atest WMShellUnitTests:DesktopModeWindowDecorationTests Test: atest WMShellUnitTests:DragPositioningCallbackUtilityTest Test: atest WMShellUnitTests:DragPositioningCallbackProviderTests Test: atest WMShellUnitTests:FixedAspectRatioDragPositioningDecoratorTests Bug: 319844447 Fixes: 365742430 Fixes: 361095335 Fixes: 352589523 Change-Id: Ie76d9954daf48cd4789d6dc7a8ed62159382f5db --- .../shell/windowdecor/CaptionWindowDecoration.java | 4 +++- .../DesktopModeWindowDecorViewModel.java | 27 ++++++++++++++++------ .../windowdecor/DesktopModeWindowDecoration.java | 10 +++++--- .../DesktopModeWindowDecorationTests.java | 2 ++ 4 files changed, 32 insertions(+), 11 deletions(-) (limited to 'libs') diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java index 46fe68f44bed..0caa8e93d4eb 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java @@ -55,6 +55,7 @@ import com.android.wm.shell.common.DisplayLayout; 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.shared.desktopmode.DesktopModeFlags; import com.android.wm.shell.windowdecor.extension.TaskInfoKt; import com.android.wm.shell.windowdecor.viewhost.WindowDecorViewHostSupplier; @@ -240,7 +241,8 @@ public class CaptionWindowDecoration extends WindowDecoration transactionFactory) { - if (!DesktopModeStatus.isVeiledResizeEnabled()) { - return new FluidResizeTaskPositioner( - taskOrganizer, transitions, windowDecoration, displayController, - dragStartListener, transactionFactory); + final TaskPositioner taskPositioner = DesktopModeStatus.isVeiledResizeEnabled() + ? new VeiledResizeTaskPositioner( + taskOrganizer, + windowDecoration, + displayController, + dragStartListener, + transitions, + interactionJankMonitor) + : new FluidResizeTaskPositioner( + taskOrganizer, + transitions, + windowDecoration, + displayController, + dragStartListener, + transactionFactory); + + if (DesktopModeFlags.SCALED_RESIZING.isEnabled(windowDecoration.mContext)) { + return new FixedAspectRatioTaskPositionerDecorator(windowDecoration, + taskPositioner); } - return new VeiledResizeTaskPositioner( - taskOrganizer, windowDecoration, displayController, - dragStartListener, transitions, interactionJankMonitor); + return taskPositioner; } } } 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 1409d3011395..32f461b42da1 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 @@ -439,7 +439,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration Date: Tue, 20 Aug 2024 22:53:04 +0000 Subject: Add reusable WindowDecorViewHosts with a pool-backed supplier Adds a ReusableWindowDecorViewHosts that allows swapping entire View hierarchies (such as when a task is changing from fullscreen<->freeform and thus the App Handle needs to change to an App Header or viceversa). It also allows pre-warming it to avoid creation latency during transition (where window decorations are usually created). To manage their reusability, the new PooledWindowDecorViewHostSupplier handles acquiring/releasing them into a SynchronizedPool, with an initial max capacity set to be equal to the max # of desktop windows allowed in the system. The preWarmSize of 2 was selected as it is the maximum number of simultaneous decorations that may be created at once after a fresh system start (launching a split-pair that requires two App Handles). Bug: 360452034 Flag: com.android.window.flags.enable_desktop_windowing_scvh_cache Test: atest WMShellUnitTests Test: in perfetto trace, launching the first two desktop tasks reduces transition latency by about 5ms for each task, and closing/re-opening windows remains low latency when acquiring pooled view hosts. Change-Id: I08111bfd4728e5223ed078916255313b13a4093f --- .../shared/desktopmode/DesktopModeStatus.java | 17 ++ .../com/android/wm/shell/dagger/WMShellModule.java | 17 +- .../viewhost/DefaultWindowDecorViewHost.kt | 71 ++------ .../viewhost/PooledWindowDecorViewHostSupplier.kt | 105 ++++++++++++ .../viewhost/ReusableWindowDecorViewHost.kt | 161 ++++++++++++++++++ .../viewhost/SurfaceControlViewHostAdapter.kt | 111 +++++++++++++ .../wm/shell/windowdecor/viewhost/Warmable.kt | 23 +++ .../viewhost/DefaultWindowDecorViewHostTest.kt | 81 ++------- .../PooledWindowDecorViewHostSupplierTest.kt | 181 ++++++++++++++++++++ .../viewhost/ReusableWindowDecorViewHostTest.kt | 182 +++++++++++++++++++++ .../viewhost/SurfaceControlViewHostAdapterTest.kt | 144 ++++++++++++++++ 11 files changed, 965 insertions(+), 128 deletions(-) create mode 100644 libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/PooledWindowDecorViewHostSupplier.kt create mode 100644 libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/ReusableWindowDecorViewHost.kt create mode 100644 libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/SurfaceControlViewHostAdapter.kt create mode 100644 libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/Warmable.kt create mode 100644 libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/PooledWindowDecorViewHostSupplierTest.kt create mode 100644 libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/ReusableWindowDecorViewHostTest.kt create mode 100644 libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/SurfaceControlViewHostAdapterTest.kt (limited to 'libs') diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java index 341ca0eb6bed..3f9711718a27 100644 --- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java +++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java @@ -90,6 +90,9 @@ public class DesktopModeStatus { /** The maximum override density allowed for tasks inside the desktop. */ private static final int DESKTOP_DENSITY_MAX = 1000; + /** The number of [WindowDecorViewHost] instances to warm up on system start. */ + private static final int WINDOW_DECOR_PRE_WARM_SIZE = 2; + /** * Sysprop declaring the maximum number of Tasks to show in Desktop Mode at any one time. * @@ -101,6 +104,14 @@ public class DesktopModeStatus { */ private static final String MAX_TASK_LIMIT_SYS_PROP = "persist.wm.debug.desktop_max_task_limit"; + /** + * Sysprop declaring the number of [WindowDecorViewHost] instances to warm up on system start. + * + *

If it is not defined, then [WINDOW_DECOR_PRE_WARM_SIZE] is used. + */ + private static final String WINDOW_DECOR_PRE_WARM_SIZE_SYS_PROP = + "persist.wm.debug.desktop_window_decor_pre_warm_size"; + /** * Return {@code true} if veiled resizing is active. If false, fluid resizing is used. */ @@ -141,6 +152,12 @@ public class DesktopModeStatus { context.getResources().getInteger(R.integer.config_maxDesktopWindowingActiveTasks)); } + /** The number of [WindowDecorViewHost] instances to warm up on system start. */ + public static int getWindowDecorPreWarmSize() { + return SystemProperties.getInt(WINDOW_DECOR_PRE_WARM_SIZE_SYS_PROP, + WINDOW_DECOR_PRE_WARM_SIZE); + } + /** * Return {@code true} if the current device supports desktop mode. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index 8c7dcf295319..b151c8b7e718 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -116,6 +116,8 @@ 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.PooledWindowDecorViewHostSupplier; +import com.android.wm.shell.windowdecor.viewhost.ReusableWindowDecorViewHost; import com.android.wm.shell.windowdecor.viewhost.WindowDecorViewHostSupplier; import dagger.Binds; @@ -380,8 +382,19 @@ public abstract class WMShellModule { @WMSingleton @Provides static WindowDecorViewHostSupplier provideWindowDecorViewHostSupplier( - @ShellMainThread @NonNull CoroutineScope mainScope) { - return new DefaultWindowDecorViewHostSupplier(mainScope); + @NonNull Context context, + @ShellMainThread @NonNull CoroutineScope mainScope, + @NonNull ShellInit shellInit) { + if (DesktopModeStatus.canEnterDesktopMode(context) + && Flags.enableDesktopWindowingScvhCache()) { + final int maxPoolSize = DesktopModeStatus.getMaxTaskLimit(context); + final int preWarmSize = DesktopModeStatus.getWindowDecorPreWarmSize(); + return new PooledWindowDecorViewHostSupplier( + context, mainScope, shellInit, + ReusableWindowDecorViewHost.DefaultFactory.INSTANCE, maxPoolSize, preWarmSize); + } else { + return new DefaultWindowDecorViewHostSupplier(mainScope); + } } // diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/DefaultWindowDecorViewHost.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/DefaultWindowDecorViewHost.kt index 139e6790b744..5156e47cfd13 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/DefaultWindowDecorViewHost.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/DefaultWindowDecorViewHost.kt @@ -19,51 +19,33 @@ import android.content.Context import android.content.res.Configuration import android.view.Display import android.view.SurfaceControl -import android.view.SurfaceControlViewHost import android.view.View import android.view.WindowManager -import android.view.WindowlessWindowManager import androidx.tracing.Trace import com.android.internal.annotations.VisibleForTesting import com.android.wm.shell.shared.annotations.ShellMainThread import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.launch -typealias SurfaceControlViewHostFactory = - (Context, Display, WindowlessWindowManager, String) -> SurfaceControlViewHost /** - * A default implementation of [WindowDecorViewHost] backed by a [SurfaceControlViewHost]. + * A default implementation of [WindowDecorViewHost] backed by a [SurfaceControlViewHostAdapter]. * - * It does not support swapping the root view added to the VRI of the [SurfaceControlViewHost], and - * any attempts to do will throw, which means that once a [View] is added using [updateView] or - * [updateViewAsync], only its properties and binding may be changed, its children views may be - * added, removed or changed and its [WindowManager.LayoutParams] may be changed. - * It also supports asynchronously updating the view hierarchy using [updateViewAsync], in which + * It supports asynchronously updating the view hierarchy using [updateViewAsync], in which * case the update work will be posted on the [ShellMainThread] with no delay. */ class DefaultWindowDecorViewHost( - private val context: Context, + context: Context, @ShellMainThread private val mainScope: CoroutineScope, - private val display: Display, - private val surfaceControlViewHostFactory: SurfaceControlViewHostFactory = { c, d, wwm, s -> - SurfaceControlViewHost(c, d, wwm, s) - } + display: Display, + @VisibleForTesting val viewHostAdapter: SurfaceControlViewHostAdapter = + SurfaceControlViewHostAdapter(context, display) ) : WindowDecorViewHost { - private val rootSurface: SurfaceControl = SurfaceControl.Builder() - .setName("DefaultWindowDecorViewHost surface") - .setContainerLayer() - .setCallsite("DefaultWindowDecorViewHost#init") - .build() - - private var wwm: WindowlessWindowManager? = null - @VisibleForTesting - var viewHost: SurfaceControlViewHost? = null private var currentUpdateJob: Job? = null override val surfaceControl: SurfaceControl - get() = rootSurface + get() = viewHostAdapter.rootSurface override fun updateView( view: View, @@ -92,8 +74,7 @@ class DefaultWindowDecorViewHost( override fun release(t: SurfaceControl.Transaction) { clearCurrentUpdateJob() - viewHost?.release() - t.remove(rootSurface) + viewHostAdapter.release(t) } private fun updateViewHost( @@ -102,45 +83,15 @@ class DefaultWindowDecorViewHost( configuration: Configuration, onDrawTransaction: SurfaceControl.Transaction? ) { - Trace.beginSection("DefaultWindowDecorViewHost#updateViewHost") - if (wwm == null) { - wwm = WindowlessWindowManager(configuration, rootSurface, null) - } - requireWindowlessWindowManager().setConfiguration(configuration) - if (viewHost == null) { - viewHost = surfaceControlViewHostFactory.invoke( - context, - display, - requireWindowlessWindowManager(), - "DefaultWindowDecorViewHost#updateViewHost" - ) - } + viewHostAdapter.prepareViewHost(configuration) onDrawTransaction?.let { - requireViewHost().rootSurfaceControl.applyTransactionOnDraw(it) - } - if (requireViewHost().view == null) { - Trace.beginSection("DefaultWindowDecorViewHost#updateViewHost-setView") - requireViewHost().setView(view, attrs) - Trace.endSection() - } else { - check(requireViewHost().view == view) { "Changing view is not allowed" } - Trace.beginSection("DefaultWindowDecorViewHost#updateViewHost-relayout") - requireViewHost().relayout(attrs) - Trace.endSection() + viewHostAdapter.applyTransactionOnDraw(it) } - Trace.endSection() + viewHostAdapter.updateView(view, attrs) } private fun clearCurrentUpdateJob() { currentUpdateJob?.cancel() currentUpdateJob = null } - - private fun requireWindowlessWindowManager(): WindowlessWindowManager { - return wwm ?: error("Expected non-null windowless window manager") - } - - private fun requireViewHost(): SurfaceControlViewHost { - return viewHost ?: error("Expected non-null view host") - } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/PooledWindowDecorViewHostSupplier.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/PooledWindowDecorViewHostSupplier.kt new file mode 100644 index 000000000000..b04188fa82a8 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/PooledWindowDecorViewHostSupplier.kt @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wm.shell.windowdecor.viewhost + +import android.content.Context +import android.os.Trace +import android.util.Pools +import android.view.Display +import android.view.SurfaceControl +import com.android.wm.shell.shared.annotations.ShellMainThread +import com.android.wm.shell.sysui.ShellInit +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch + +/** + * A [WindowDecorViewHostSupplier] backed by a pool to allow recycling view hosts which may be + * expensive to recreate for each new/updated window decoration. + * + * Callers can obtain [ReusableWindowDecorViewHost] using [acquire], which will return a pooled + * object if available, or create a new instance and return it if needed. When done using a + * [ReusableWindowDecorViewHost], it must be released using [release] to allow it to be sent back + * into the pool and reused later on. + * + * This class also supports pre-warming [ReusableWindowDecorViewHost] instances, which will be put + * into the pool immediately after creation. + */ +class PooledWindowDecorViewHostSupplier( + private val context: Context, + @ShellMainThread private val mainScope: CoroutineScope, + shellInit: ShellInit, + private val viewHostFactory: ReusableWindowDecorViewHost.Factory = + ReusableWindowDecorViewHost.DefaultFactory, + maxPoolSize: Int, + private val preWarmSize: Int, +) : WindowDecorViewHostSupplier { + + private val pool: Pools.Pool = Pools.SynchronizedPool(maxPoolSize) + private var nextDecorViewHostId = 0 + + init { + require(preWarmSize <= maxPoolSize) { "Pre-warm size should not exceed pool size" } + shellInit.addInitCallback(this::onShellInit, this) + } + + private fun onShellInit() { + if (preWarmSize <= 0) { + return + } + preWarmViewHosts(preWarmSize) + } + + private fun preWarmViewHosts(preWarmSize: Int) { + mainScope.launch { + // Applying isn't needed, as the surface was never actually shown. + val t = SurfaceControl.Transaction() + repeat(preWarmSize) { + val warmedViewHost = create(context, context.display).apply { + warmUp() + } + // Put the warmed view host in the pool by releasing it. + release(warmedViewHost, t) + } + } + } + + override fun acquire(context: Context, display: Display): ReusableWindowDecorViewHost { + val reusedDecorViewHost = pool.acquire() + if (reusedDecorViewHost != null) { + return reusedDecorViewHost + } + Trace.beginSection("WindowDecorViewHostPool#acquire-new") + val newDecorViewHost = create(context, display) + Trace.endSection() + return newDecorViewHost + } + + override fun release(viewHost: ReusableWindowDecorViewHost, t: SurfaceControl.Transaction) { + val cached = pool.release(viewHost) + if (!cached) { + viewHost.release(t) + } + } + + private fun create(context: Context, display: Display): ReusableWindowDecorViewHost { + return viewHostFactory.create( + context, + mainScope, + display, + nextDecorViewHostId++ + ) + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/ReusableWindowDecorViewHost.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/ReusableWindowDecorViewHost.kt new file mode 100644 index 000000000000..64536d1a7897 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/ReusableWindowDecorViewHost.kt @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wm.shell.windowdecor.viewhost + +import android.content.Context +import android.content.res.Configuration +import android.graphics.PixelFormat +import android.os.Trace +import android.view.Display +import android.view.SurfaceControl +import android.view.SurfaceControlViewHost +import android.view.View +import android.view.WindowManager +import android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE +import android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH +import android.view.WindowManager.LayoutParams.TYPE_APPLICATION +import android.widget.FrameLayout +import com.android.internal.annotations.VisibleForTesting +import com.android.wm.shell.shared.annotations.ShellMainThread +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch + +/** + * An implementation of [WindowDecorViewHost] that supports: + * 1) Replacing the root [View], meaning [WindowDecorViewHost.updateView] maybe be + * called with different [View] instances. This is useful when reusing [WindowDecorViewHost]s + * instances for vastly different view hierarchies, such as Desktop Windowing's App Handles and + * App Headers. + * 2) Pre-warming of the underlying [SurfaceControlViewHost]s. Useful because their creation and + * first root view assignment are expensive, which is undesirable in latency-sensitive code + * paths like during a shell transition. + */ +class ReusableWindowDecorViewHost( + private val context: Context, + @ShellMainThread private val mainScope: CoroutineScope, + display: Display, + val id: Int, + @VisibleForTesting val viewHostAdapter: SurfaceControlViewHostAdapter = + SurfaceControlViewHostAdapter(context, display) +) : WindowDecorViewHost, Warmable { + + @VisibleForTesting + val rootView = FrameLayout(context) + + private var currentUpdateJob: Job? = null + + override val surfaceControl: SurfaceControl + get() = viewHostAdapter.rootSurface + + override fun warmUp() { + if (viewHostAdapter.isInitialized()) { + // Already warmed up. + return + } + Trace.beginSection("$TAG#warmUp") + viewHostAdapter.prepareViewHost(context.resources.configuration) + viewHostAdapter.updateView( + rootView, + WindowManager.LayoutParams( + 0 /* width*/, + 0 /* height */, + TYPE_APPLICATION, + FLAG_NOT_FOCUSABLE or FLAG_SPLIT_TOUCH, + PixelFormat.TRANSPARENT + ).apply { + setTitle("View root of $TAG#$id") + setTrustedOverlay() + } + ) + Trace.endSection() + } + + override fun updateView( + view: View, + attrs: WindowManager.LayoutParams, + configuration: Configuration, + onDrawTransaction: SurfaceControl.Transaction? + ) { + clearCurrentUpdateJob() + updateViewHost(view, attrs, configuration, onDrawTransaction) + } + + override fun updateViewAsync( + view: View, + attrs: WindowManager.LayoutParams, + configuration: Configuration + ) { + clearCurrentUpdateJob() + currentUpdateJob = mainScope.launch { + updateViewHost(view, attrs, configuration, onDrawTransaction = null) + } + } + + override fun release(t: SurfaceControl.Transaction) { + clearCurrentUpdateJob() + viewHostAdapter.release(t) + } + + private fun updateViewHost( + view: View, + attrs: WindowManager.LayoutParams, + configuration: Configuration, + onDrawTransaction: SurfaceControl.Transaction? + ) { + viewHostAdapter.prepareViewHost(configuration) + onDrawTransaction?.let { + viewHostAdapter.applyTransactionOnDraw(it) + } + rootView.removeAllViews() + rootView.addView(view) + viewHostAdapter.updateView(rootView, attrs) + } + + private fun clearCurrentUpdateJob() { + currentUpdateJob?.cancel() + currentUpdateJob = null + } + + interface Factory { + fun create( + context: Context, + @ShellMainThread mainScope: CoroutineScope, + display: Display, + id: Int + ): ReusableWindowDecorViewHost + } + + object DefaultFactory : Factory { + override fun create( + context: Context, + @ShellMainThread mainScope: CoroutineScope, + display: Display, + id: Int + ): ReusableWindowDecorViewHost { + return ReusableWindowDecorViewHost( + context, + mainScope, + display, + id + ) + } + } + + companion object { + private const val TAG = "ReusableWindowDecorViewHost" + } +} \ No newline at end of file diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/SurfaceControlViewHostAdapter.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/SurfaceControlViewHostAdapter.kt new file mode 100644 index 000000000000..a54c9ba67cf8 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/SurfaceControlViewHostAdapter.kt @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wm.shell.windowdecor.viewhost + +import android.content.Context +import android.content.res.Configuration +import android.view.AttachedSurfaceControl +import android.view.Display +import android.view.SurfaceControl +import android.view.SurfaceControlViewHost +import android.view.View +import android.view.WindowManager +import android.view.WindowlessWindowManager +import androidx.tracing.Trace +import com.android.internal.annotations.VisibleForTesting +typealias SurfaceControlViewHostFactory = + (Context, Display, WindowlessWindowManager, String) -> SurfaceControlViewHost + +/** + * Adapter for a [SurfaceControlViewHost] and its backing [SurfaceControl]. + * + * It does not support swapping the root view added to the VRI of the [SurfaceControlViewHost], and + * any attempts to do will throw, which means that once a [View] is added using [updateView], only + * its properties and binding may be changed, its children views may be added, removed or changed + * and its [WindowManager.LayoutParams] may be changed. + */ +class SurfaceControlViewHostAdapter( + private val context: Context, + private val display: Display, + private val surfaceControlViewHostFactory: SurfaceControlViewHostFactory = { c, d, wwm, s -> + SurfaceControlViewHost(c, d, wwm, s) + } +) { + val rootSurface: SurfaceControl = SurfaceControl.Builder() + .setName("SurfaceControlViewHostAdapter surface") + .setContainerLayer() + .setCallsite("SurfaceControlViewHostAdapter#init") + .build() + + private var wwm: WindowlessWindowManager? = null + @VisibleForTesting + var viewHost: SurfaceControlViewHost? = null + + /** Initialize the [SurfaceControlViewHost] if needed. */ + fun prepareViewHost(configuration: Configuration) { + if (wwm == null) { + wwm = WindowlessWindowManager(configuration, rootSurface, null) + } + requireWindowlessWindowManager().setConfiguration(configuration) + if (viewHost == null) { + viewHost = surfaceControlViewHostFactory.invoke( + context, + display, + requireWindowlessWindowManager(), + "SurfaceControlViewHostAdapter#prepareViewHost" + ) + } + } + + /** + * Request to apply the transaction atomically with the next draw of the view hierarchy. + * See [AttachedSurfaceControl.applyTransactionOnDraw]. + */ + fun applyTransactionOnDraw(t: SurfaceControl.Transaction) { + requireViewHost().rootSurfaceControl.applyTransactionOnDraw(t) + } + + /** Update the view hierarchy of the view host. */ + fun updateView(view: View, attrs: WindowManager.LayoutParams) { + if (requireViewHost().view == null) { + Trace.beginSection("SurfaceControlViewHostAdapter#updateView-setView") + requireViewHost().setView(view, attrs) + Trace.endSection() + } else { + check(requireViewHost().view == view) { "Changing view is not allowed" } + Trace.beginSection("SurfaceControlViewHostAdapter#updateView-relayout") + requireViewHost().relayout(attrs) + Trace.endSection() + } + } + + /** Release the view host and remove the backing surface. */ + fun release(t: SurfaceControl.Transaction) { + viewHost?.release() + t.remove(rootSurface) + } + + /** Whether the view host has had a view hierarchy set. */ + fun isInitialized(): Boolean = viewHost?.view != null + + private fun requireWindowlessWindowManager(): WindowlessWindowManager { + return wwm ?: error("Expected non-null windowless window manager") + } + + private fun requireViewHost(): SurfaceControlViewHost { + return viewHost ?: error("Expected non-null view host") + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/Warmable.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/Warmable.kt new file mode 100644 index 000000000000..0df9bfa2ee78 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewhost/Warmable.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wm.shell.windowdecor.viewhost + +/** + * An interface for an object that can be warmed up before it's needed. + */ +interface Warmable { + fun warmUp() +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/DefaultWindowDecorViewHostTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/DefaultWindowDecorViewHostTest.kt index 1b2ce9e4df36..1b0b7d95e657 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/DefaultWindowDecorViewHostTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/DefaultWindowDecorViewHostTest.kt @@ -18,7 +18,6 @@ package com.android.wm.shell.windowdecor.viewhost import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.view.SurfaceControl -import android.view.SurfaceControlViewHost import android.view.View import android.view.WindowManager import androidx.test.filters.SmallTest @@ -28,7 +27,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest -import org.junit.Assert.assertThrows import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.mock @@ -59,54 +57,8 @@ class DefaultWindowDecorViewHostTest : ShellTestCase() { onDrawTransaction = null ) - assertThat(windowDecorViewHost.viewHost).isNotNull() - assertThat(windowDecorViewHost.viewHost!!.view).isEqualTo(view) - } - - @Test - fun updateView_alreadyLaidOut_relayouts() = runTest { - val windowDecorViewHost = createDefaultViewHost() - val view = View(context) - windowDecorViewHost.updateView( - view = view, - attrs = WindowManager.LayoutParams(100, 100), - configuration = context.resources.configuration, - onDrawTransaction = null - ) - - val otherParams = WindowManager.LayoutParams(200, 200) - windowDecorViewHost.updateView( - view = view, - attrs = otherParams, - configuration = context.resources.configuration, - onDrawTransaction = null - ) - - assertThat(windowDecorViewHost.viewHost!!.view).isEqualTo(view) - assertThat(windowDecorViewHost.viewHost!!.view!!.layoutParams.width) - .isEqualTo(otherParams.width) - } - - @Test - fun updateView_replacingView_throws() = runTest { - val windowDecorViewHost = createDefaultViewHost() - val view = View(context) - windowDecorViewHost.updateView( - view = view, - attrs = WindowManager.LayoutParams(100, 100), - configuration = context.resources.configuration, - onDrawTransaction = null - ) - - val otherView = View(context) - assertThrows(Exception::class.java) { - windowDecorViewHost.updateView( - view = otherView, - attrs = WindowManager.LayoutParams(100, 100), - configuration = context.resources.configuration, - onDrawTransaction = null - ) - } + assertThat(windowDecorViewHost.viewHostAdapter.isInitialized()).isTrue() + assertThat(windowDecorViewHost.view()).isEqualTo(view) } @OptIn(ExperimentalCoroutinesApi::class) @@ -125,7 +77,7 @@ class DefaultWindowDecorViewHostTest : ShellTestCase() { ) // No view host yet, since the coroutine hasn't run. - assertThat(windowDecorViewHost.viewHost).isNull() + assertThat(windowDecorViewHost.viewHostAdapter.isInitialized()).isFalse() windowDecorViewHost.updateView( view = syncView, @@ -137,14 +89,13 @@ class DefaultWindowDecorViewHostTest : ShellTestCase() { // Would run coroutine if it hadn't been cancelled. advanceUntilIdle() - assertThat(windowDecorViewHost.viewHost).isNotNull() - assertThat(windowDecorViewHost.viewHost!!.view).isNotNull() + assertThat(windowDecorViewHost.viewHostAdapter.isInitialized()).isTrue() + assertThat(windowDecorViewHost.view()).isNotNull() // View host view/attrs should match the ones from the sync call, plus, since the // sync/async were made with different views, if the job hadn't been cancelled there // would've been an exception thrown as replacing views isn't allowed. - assertThat(windowDecorViewHost.viewHost!!.view).isEqualTo(syncView) - assertThat(windowDecorViewHost.viewHost!!.view!!.layoutParams.width) - .isEqualTo(syncAttrs.width) + assertThat(windowDecorViewHost.view()).isEqualTo(syncView) + assertThat(windowDecorViewHost.view()!!.layoutParams.width).isEqualTo(syncAttrs.width) } @OptIn(ExperimentalCoroutinesApi::class) @@ -160,11 +111,11 @@ class DefaultWindowDecorViewHostTest : ShellTestCase() { configuration = context.resources.configuration, ) - assertThat(windowDecorViewHost.viewHost).isNull() + assertThat(windowDecorViewHost.viewHostAdapter.isInitialized()).isFalse() advanceUntilIdle() - assertThat(windowDecorViewHost.viewHost).isNotNull() + assertThat(windowDecorViewHost.viewHostAdapter.isInitialized()).isTrue() } @OptIn(ExperimentalCoroutinesApi::class) @@ -187,9 +138,8 @@ class DefaultWindowDecorViewHostTest : ShellTestCase() { advanceUntilIdle() - assertThat(windowDecorViewHost.viewHost).isNotNull() - assertThat(windowDecorViewHost.viewHost!!.view).isNotNull() - assertThat(windowDecorViewHost.viewHost!!.view).isEqualTo(otherView) + assertThat(windowDecorViewHost.viewHostAdapter.isInitialized()).isTrue() + assertThat(windowDecorViewHost.view()).isEqualTo(otherView) } @Test @@ -207,16 +157,15 @@ class DefaultWindowDecorViewHostTest : ShellTestCase() { val t = mock(SurfaceControl.Transaction::class.java) windowDecorViewHost.release(t) - verify(windowDecorViewHost.viewHost!!).release() - verify(t).remove(windowDecorViewHost.surfaceControl) + verify(windowDecorViewHost.viewHostAdapter).release(t) } private fun CoroutineScope.createDefaultViewHost() = DefaultWindowDecorViewHost( context = context, mainScope = this, display = context.display, - surfaceControlViewHostFactory = { c, d, wwm, s -> - spy(SurfaceControlViewHost(c, d, wwm, s)) - } + viewHostAdapter = spy(SurfaceControlViewHostAdapter(context, context.display)), ) + + private fun DefaultWindowDecorViewHost.view(): View? = viewHostAdapter.viewHost?.view } \ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/PooledWindowDecorViewHostSupplierTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/PooledWindowDecorViewHostSupplierTest.kt new file mode 100644 index 000000000000..a7e4213ad01d --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/PooledWindowDecorViewHostSupplierTest.kt @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wm.shell.windowdecor.viewhost + +import android.testing.AndroidTestingRunner +import android.view.SurfaceControl +import androidx.test.filters.SmallTest +import com.android.wm.shell.ShellTestCase +import com.android.wm.shell.TestShellExecutor +import com.android.wm.shell.sysui.ShellInit +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.advanceUntilIdle +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.any +import org.mockito.kotlin.mock +import org.mockito.kotlin.never +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +/** + * Tests for [PooledWindowDecorViewHostSupplier]. + * + * Build/Install/Run: + * atest WMShellUnitTests:PooledWindowDecorViewHostSupplierTest + */ +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(AndroidTestingRunner::class) +class PooledWindowDecorViewHostSupplierTest : ShellTestCase() { + + private val testExecutor = TestShellExecutor() + private val testShellInit = ShellInit(testExecutor) + @Mock + private lateinit var mockViewHostFactory: ReusableWindowDecorViewHost.Factory + + private lateinit var supplier: PooledWindowDecorViewHostSupplier + + @Test + fun setUp() { + MockitoAnnotations.initMocks(this) + } + + @Test + fun onInit_warmsAndPoolsViewHosts() = runTest { + supplier = createSupplier(maxPoolSize = 5, preWarmSize = 2) + val mockViewHost1 = mock() + val mockViewHost2 = mock() + whenever(mockViewHostFactory + .create(context, this, context.display, id = 0)) + .thenReturn(mockViewHost1) + whenever(mockViewHostFactory + .create(context, this, context.display, id = 1)) + .thenReturn(mockViewHost2) + + testExecutor.flushAll() + advanceUntilIdle() + + // Both were warmed up. + verify(mockViewHost1).warmUp() + verify(mockViewHost2).warmUp() + // Both were released, so re-acquiring them provides the same instance. + assertThat(mockViewHost2) + .isEqualTo(supplier.acquire(context, context.display)) + assertThat(mockViewHost1) + .isEqualTo(supplier.acquire(context, context.display)) + } + + @Test(expected = Throwable::class) + fun onInit_warmUpSizeExceedsPoolSize_throws() = runTest { + createSupplier(maxPoolSize = 3, preWarmSize = 4) + } + + @Test + fun acquire_poolHasInstances_reuses() = runTest { + supplier = createSupplier(maxPoolSize = 5, preWarmSize = 0) + + // Prepare the pool with one instance. + val mockViewHost = mock() + supplier.release(mockViewHost, SurfaceControl.Transaction()) + + assertThat(mockViewHost) + .isEqualTo(supplier.acquire(context, context.display)) + verify(mockViewHostFactory, never()).create(any(), any(), any(), any()) + } + + @Test + fun acquire_pooledHasZeroInstances_creates() = runTest { + supplier = createSupplier(maxPoolSize = 5, preWarmSize = 0) + + supplier.acquire(context, context.display) + + verify(mockViewHostFactory).create(context, this, context.display, id = 0) + } + + @Test + fun release_poolBelowLimit_caches() = runTest { + supplier = createSupplier(maxPoolSize = 5, preWarmSize = 0) + + val mockViewHost = mock() + val mockT = mock() + supplier.release(mockViewHost, mockT) + + assertThat(mockViewHost) + .isEqualTo(supplier.acquire(context, context.display)) + } + + @Test + fun release_poolBelowLimit_doesNotReleaseViewHost() = runTest { + supplier = createSupplier(maxPoolSize = 5, preWarmSize = 0) + + val mockViewHost = mock() + val mockT = mock() + supplier.release(mockViewHost, mockT) + + verify(mockViewHost, never()).release(mockT) + } + + @Test + fun release_poolAtLimit_doesNotCache() = runTest { + supplier = createSupplier(maxPoolSize = 1, preWarmSize = 0) + val mockT = mock() + val mockViewHost = mock() + supplier.release(mockViewHost, mockT) // Maxes pool. + + val mockViewHost2 = mock() + supplier.release(mockViewHost2, mockT) // Beyond limit. + + assertThat(mockViewHost) + .isEqualTo(supplier.acquire(context, context.display)) + // Second one wasn't cached, so the acquired one should've been a new instance. + assertThat(mockViewHost2) + .isNotEqualTo(supplier.acquire(context, context.display)) + } + + @Test + fun release_poolAtLimit_releasesViewHost() = runTest { + supplier = createSupplier(maxPoolSize = 1, preWarmSize = 0) + val mockT = mock() + val mockViewHost = mock() + supplier.release(mockViewHost, mockT) // Maxes pool. + + val mockViewHost2 = mock() + supplier.release(mockViewHost2, mockT) // Beyond limit. + + // Second one doesn't fit, so it needs to be released. + verify(mockViewHost2).release(mockT) + } + + private fun CoroutineScope.createSupplier( + maxPoolSize: Int, + preWarmSize: Int + ) = PooledWindowDecorViewHostSupplier( + context, + this, + testShellInit, + mockViewHostFactory, + maxPoolSize, + preWarmSize + ).also { + testShellInit.init() + } +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/ReusableWindowDecorViewHostTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/ReusableWindowDecorViewHostTest.kt new file mode 100644 index 000000000000..de2444e34ca9 --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/ReusableWindowDecorViewHostTest.kt @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wm.shell.windowdecor.viewhost + +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.view.SurfaceControl +import android.view.View +import android.view.WindowManager +import androidx.test.filters.SmallTest +import com.android.wm.shell.ShellTestCase +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.advanceUntilIdle +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.mock +import org.mockito.kotlin.spy +import org.mockito.kotlin.verify + +/** + * Tests for [ReusableWindowDecorViewHost]. + * + * Build/Install/Run: + * atest WMShellUnitTests:ReusableWindowDecorViewHostTest + */ +@SmallTest +@TestableLooper.RunWithLooper +@RunWith(AndroidTestingRunner::class) +class ReusableWindowDecorViewHostTest : ShellTestCase() { + + @Test + fun warmUp_addsRootView() = runTest { + val reusableVH = createReusableViewHost().apply { + warmUp() + } + + assertThat(reusableVH.viewHostAdapter.isInitialized()).isTrue() + assertThat(reusableVH.view()).isEqualTo(reusableVH.rootView) + } + + @Test + fun update_differentView_replacesView() = runTest { + val view = View(context) + val lp = WindowManager.LayoutParams() + val reusableVH = createReusableViewHost() + reusableVH.updateView(view, lp, context.resources.configuration, null) + + assertThat(reusableVH.rootView.childCount).isEqualTo(1) + assertThat(reusableVH.rootView.getChildAt(0)).isEqualTo(view) + + val newView = View(context) + val newLp = WindowManager.LayoutParams() + reusableVH.updateView(newView, newLp, context.resources.configuration, null) + + assertThat(reusableVH.rootView.childCount).isEqualTo(1) + assertThat(reusableVH.rootView.getChildAt(0)).isEqualTo(newView) + } + + @OptIn(ExperimentalCoroutinesApi::class) + @Test + fun updateView_clearsPendingAsyncJob() = runTest { + val reusableVH = createReusableViewHost() + val asyncView = View(context) + val syncView = View(context) + val asyncAttrs = WindowManager.LayoutParams(100, 100) + val syncAttrs = WindowManager.LayoutParams(200, 200) + + reusableVH.updateViewAsync( + view = asyncView, + attrs = asyncAttrs, + configuration = context.resources.configuration, + ) + + // No view host yet, since the coroutine hasn't run. + assertThat(reusableVH.viewHostAdapter.isInitialized()).isFalse() + + reusableVH.updateView( + view = syncView, + attrs = syncAttrs, + configuration = context.resources.configuration, + onDrawTransaction = null + ) + + // Would run coroutine if it hadn't been cancelled. + advanceUntilIdle() + + assertThat(reusableVH.viewHostAdapter.isInitialized()).isTrue() + // View host view/attrs should match the ones from the sync call, plus, since the + // sync/async were made with different views, if the job hadn't been cancelled there + // would've been an exception thrown as replacing views isn't allowed. + assertThat(reusableVH.rootView.getChildAt(0)).isEqualTo(syncView) + assertThat(reusableVH.view()!!.layoutParams.width).isEqualTo(syncAttrs.width) + } + + @OptIn(ExperimentalCoroutinesApi::class) + @Test + fun updateViewAsync() = runTest { + val reusableVH = createReusableViewHost() + val view = View(context) + val attrs = WindowManager.LayoutParams(100, 100) + + reusableVH.updateViewAsync( + view = view, + attrs = attrs, + configuration = context.resources.configuration, + ) + + assertThat(reusableVH.viewHostAdapter.isInitialized()).isFalse() + + advanceUntilIdle() + + assertThat(reusableVH.viewHostAdapter.isInitialized()).isTrue() + } + + @OptIn(ExperimentalCoroutinesApi::class) + @Test + fun updateViewAsync_clearsPendingAsyncJob() = runTest { + val reusableVH = createReusableViewHost() + + val view = View(context) + reusableVH.updateViewAsync( + view = view, + attrs = WindowManager.LayoutParams(100, 100), + configuration = context.resources.configuration, + ) + val otherView = View(context) + reusableVH.updateViewAsync( + view = otherView, + attrs = WindowManager.LayoutParams(100, 100), + configuration = context.resources.configuration, + ) + + advanceUntilIdle() + + assertThat(reusableVH.viewHostAdapter.isInitialized()).isTrue() + assertThat(reusableVH.rootView.getChildAt(0)).isEqualTo(otherView) + } + + @Test + fun release() = runTest { + val reusableVH = createReusableViewHost() + + val view = View(context) + reusableVH.updateView( + view = view, + attrs = WindowManager.LayoutParams(100, 100), + configuration = context.resources.configuration, + onDrawTransaction = null + ) + + val t = mock(SurfaceControl.Transaction::class.java) + reusableVH.release(t) + + verify(reusableVH.viewHostAdapter).release(t) + } + + private fun CoroutineScope.createReusableViewHost() = ReusableWindowDecorViewHost( + context = context, + mainScope = this, + display = context.display, + id = 1, + viewHostAdapter = spy(SurfaceControlViewHostAdapter(context, context.display)), + ) + + private fun ReusableWindowDecorViewHost.view(): View? = viewHostAdapter.viewHost?.view +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/SurfaceControlViewHostAdapterTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/SurfaceControlViewHostAdapterTest.kt new file mode 100644 index 000000000000..d6c80a7fffc1 --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewhost/SurfaceControlViewHostAdapterTest.kt @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wm.shell.windowdecor.viewhost + +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.view.SurfaceControl +import android.view.SurfaceControlViewHost +import android.view.View +import android.view.WindowManager +import androidx.test.filters.SmallTest +import com.android.wm.shell.ShellTestCase +import com.google.common.truth.Truth.assertThat +import org.junit.Assert.assertThrows +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito.mock +import org.mockito.kotlin.spy +import org.mockito.kotlin.verify + +/** + * Tests for [SurfaceControlViewHostAdapter]. + * + * Build/Install/Run: + * atest WMShellUnitTests:SurfaceControlViewHostAdapterTest + */ +@SmallTest +@TestableLooper.RunWithLooper +@RunWith(AndroidTestingRunner::class) +class SurfaceControlViewHostAdapterTest : ShellTestCase() { + + private lateinit var adapter: SurfaceControlViewHostAdapter + + @Before + fun setUp() { + adapter = SurfaceControlViewHostAdapter( + context, + context.display, + surfaceControlViewHostFactory = { c, d, wwm, s -> + spy(SurfaceControlViewHost(c, d, wwm, s)) + } + ) + } + + @Test + fun prepareViewHost() { + adapter.prepareViewHost(context.resources.configuration) + + assertThat(adapter.viewHost).isNotNull() + } + + @Test + fun prepareViewHost_alreadyCreated_skips() { + adapter.prepareViewHost(context.resources.configuration) + + val viewHost = adapter.viewHost!! + + adapter.prepareViewHost(context.resources.configuration) + + assertThat(adapter.viewHost).isEqualTo(viewHost) + } + + @Test + fun updateView_layoutInViewHost() { + val view = View(context) + adapter.prepareViewHost(context.resources.configuration) + + adapter.updateView( + view = view, + attrs = WindowManager.LayoutParams(100, 100) + ) + + assertThat(adapter.isInitialized()).isTrue() + assertThat(adapter.view()).isEqualTo(view) + } + + @Test + fun updateView_alreadyLaidOut_relayouts() { + val view = View(context) + adapter.prepareViewHost(context.resources.configuration) + adapter.updateView( + view = view, + attrs = WindowManager.LayoutParams(100, 100) + ) + + val otherParams = WindowManager.LayoutParams(200, 200) + adapter.updateView( + view = view, + attrs = otherParams + ) + + assertThat(adapter.view()).isEqualTo(view) + assertThat(adapter.view()!!.layoutParams.width).isEqualTo(otherParams.width) + } + + @Test + fun updateView_replacingView_throws() { + val view = View(context) + adapter.prepareViewHost(context.resources.configuration) + adapter.updateView( + view = view, + attrs = WindowManager.LayoutParams(100, 100) + ) + + val otherView = View(context) + assertThrows(Exception::class.java) { + adapter.updateView( + view = otherView, + attrs = WindowManager.LayoutParams(100, 100) + ) + } + } + + @Test + fun release() { + adapter.prepareViewHost(context.resources.configuration) + adapter.updateView( + view = View(context), + attrs = WindowManager.LayoutParams(100, 100) + ) + + val mockT = mock(SurfaceControl.Transaction::class.java) + adapter.release(mockT) + + verify(adapter.viewHost!!).release() + verify(mockT).remove(adapter.rootSurface) + } + + private fun SurfaceControlViewHostAdapter.view(): View? = viewHost?.view +} -- cgit v1.2.3-59-g8ed1b