Create test display and window only if needed

Introduce annotation UseTestDisplay so only the annotated test
class and method will create the extra display and windows when
setting up.

This may reduce the presubmit time of WmTests by 30% (~20min).

Test: atest WmTests
Bug: 154655192

Change-Id: I6ffae4d285d24eac93807bf644b4f2c8c8563b44
This commit is contained in:
Riddle Hsu
2020-07-07 17:58:56 +08:00
parent f51cab9b7a
commit f8d8aea425
22 changed files with 272 additions and 74 deletions

View File

@@ -28,6 +28,7 @@ import static android.view.WindowManager.TRANSIT_TASK_OPEN;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doCallRealMethod;
import android.platform.test.annotations.Presubmit;
import android.util.ArraySet;
@@ -56,6 +57,14 @@ public class AppTransitionControllerTest extends WindowTestsBase {
mAppTransitionController = new AppTransitionController(mWm, mDisplayContent);
}
@Override
ActivityRecord createActivityRecord(DisplayContent dc, int windowingMode, int activityType) {
final ActivityRecord r = super.createActivityRecord(dc, windowingMode, activityType);
// Ensure that ActivityRecord#setOccludesParent takes effect.
doCallRealMethod().when(r).fillsParent();
return r;
}
@Test
@FlakyTest(bugId = 131005232)
public void testTranslucentOpen() {
@@ -191,6 +200,9 @@ public class AppTransitionControllerTest extends WindowTestsBase {
@Test
public void testGetAnimationTargets_exitingBeforeTransition() {
// Create another non-empty task so the animation target won't promote to task display area.
WindowTestUtils.createTestActivityRecord(
mDisplayContent.getDefaultTaskDisplayArea().getOrCreateRootHomeTask());
final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
final ActivityRecord activity = WindowTestUtils.createTestActivityRecord(stack);
activity.setVisible(false);

View File

@@ -158,6 +158,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
mActivity.removeImmediately();
}
@UseTestDisplay(addWindows = W_ACTIVITY)
@Test
@FlakyTest(bugId = 131005232)
public void testLandscapeSeascapeRotationByApp() {
@@ -188,6 +189,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
appWindow.removeImmediately();
}
@UseTestDisplay(addWindows = W_ACTIVITY)
@Test
public void testLandscapeSeascapeRotationByPolicy() {
// This instance has been spied in {@link TestDisplayContent}.
@@ -295,6 +297,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
mWm.mDisplayFrozen = false;
}
@UseTestDisplay
@Test
public void testRespectTopFullscreenOrientation() {
final Configuration displayConfig = mActivity.mDisplayContent.getConfiguration();
@@ -316,6 +319,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
assertEquals(Configuration.ORIENTATION_LANDSCAPE, activityConfig.orientation);
}
@UseTestDisplay
@Test
public void testReportOrientationChange() {
mActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
@@ -343,7 +347,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
@Test
public void testAddRemoveRace() {
// There was once a race condition between adding and removing starting windows
final ActivityRecord appToken = mAppWindow.mActivityRecord;
final ActivityRecord appToken = createIsolatedTestActivityRecord();
for (int i = 0; i < 1000; i++) {
appToken.addStartingWindow(mPackageName,
android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,

View File

@@ -133,6 +133,7 @@ import java.util.List;
@RunWith(WindowTestRunner.class)
public class DisplayContentTests extends WindowTestsBase {
@UseTestDisplay(addAllCommonWindows = true)
@Test
public void testForAllWindows() {
final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
@@ -159,6 +160,7 @@ public class DisplayContentTests extends WindowTestsBase {
mNavBarWindow));
}
@UseTestDisplay(addAllCommonWindows = true)
@Test
public void testForAllWindows_WithAppImeTarget() {
final WindowState imeAppTarget =
@@ -180,6 +182,7 @@ public class DisplayContentTests extends WindowTestsBase {
mNavBarWindow));
}
@UseTestDisplay(addAllCommonWindows = true)
@Test
public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
mDisplayContent.mInputMethodTarget = mChildAppWindowAbove;
@@ -197,6 +200,7 @@ public class DisplayContentTests extends WindowTestsBase {
mNavBarWindow));
}
@UseTestDisplay(addAllCommonWindows = true)
@Test
public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
mDisplayContent.mInputMethodTarget = mStatusBarWindow;
@@ -214,6 +218,7 @@ public class DisplayContentTests extends WindowTestsBase {
mNavBarWindow));
}
@UseTestDisplay(addAllCommonWindows = true)
@Test
public void testForAllWindows_WithNotificationShadeImeTarget() throws Exception {
mDisplayContent.mInputMethodTarget = mNotificationShadeWindow;
@@ -231,6 +236,7 @@ public class DisplayContentTests extends WindowTestsBase {
mNavBarWindow));
}
@UseTestDisplay(addAllCommonWindows = true)
@Test
public void testForAllWindows_WithInBetweenWindowToken() {
// This window is set-up to be z-ordered between some windows that go in the same token like
@@ -252,6 +258,7 @@ public class DisplayContentTests extends WindowTestsBase {
mNavBarWindow));
}
@UseTestDisplay(addAllCommonWindows = true)
@Test
public void testComputeImeTarget() {
// Verify that an app window can be an ime target.
@@ -271,6 +278,7 @@ public class DisplayContentTests extends WindowTestsBase {
assertEquals(childWin, imeTarget);
}
@UseTestDisplay(addAllCommonWindows = true)
@Test
public void testComputeImeTarget_startingWindow() {
ActivityRecord activity = createActivityRecord(mDisplayContent,
@@ -775,6 +783,7 @@ public class DisplayContentTests extends WindowTestsBase {
.setDisplayInfoOverrideFromWindowManager(dc.getDisplayId(), null);
}
@UseTestDisplay
@Test
public void testClearLastFocusWhenReparentingFocusedWindow() {
final DisplayContent defaultDisplay = mWm.getDefaultDisplayContentLocked();
@@ -808,6 +817,7 @@ public class DisplayContentTests extends WindowTestsBase {
assertFalse(isOptionsPanelAtRight(landscapeDisplay.getDisplayId()));
}
@UseTestDisplay(addWindows = W_INPUT_METHOD)
@Test
public void testInputMethodTargetUpdateWhenSwitchingOnDisplays() {
final DisplayContent newDisplay = createNewDisplay();
@@ -921,6 +931,7 @@ public class DisplayContentTests extends WindowTestsBase {
assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
}
@UseTestDisplay(addWindows = W_ACTIVITY)
@Test
public void testComputeImeParent_app_notMatchParentBounds() {
spyOn(mAppWindow.mActivityRecord);
@@ -978,6 +989,7 @@ public class DisplayContentTests extends WindowTestsBase {
assertNotEquals(dc.mInputMethodInputTarget, dc.computeImeControlTarget());
}
@UseTestDisplay(addWindows = W_ACTIVITY)
@Test
public void testComputeImeControlTarget_notMatchParentBounds() throws Exception {
spyOn(mAppWindow.mActivityRecord);
@@ -1096,6 +1108,7 @@ public class DisplayContentTests extends WindowTestsBase {
win.setHasSurface(false);
}
@UseTestDisplay(addWindows = { W_ABOVE_ACTIVITY, W_ACTIVITY})
@Test
public void testRequestResizeForEmptyFrames() {
final WindowState win = mChildAppWindowAbove;
@@ -1135,6 +1148,7 @@ public class DisplayContentTests extends WindowTestsBase {
is(Configuration.ORIENTATION_PORTRAIT));
}
@UseTestDisplay(addWindows = { W_ACTIVITY, W_WALLPAPER, W_STATUS_BAR, W_NAVIGATION_BAR })
@Test
public void testApplyTopFixedRotationTransform() {
final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
@@ -1234,7 +1248,9 @@ public class DisplayContentTests extends WindowTestsBase {
@Test
public void testFinishFixedRotationNoAppTransitioningTask() {
final ActivityRecord app = mAppWindow.mActivityRecord;
unblockDisplayRotation(mDisplayContent);
final ActivityRecord app = createActivityRecord(mDisplayContent, WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD);
final Task task = app.getTask();
final ActivityRecord app2 = new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
.setTask(task).build();
@@ -1255,6 +1271,7 @@ public class DisplayContentTests extends WindowTestsBase {
assertFalse(mDisplayContent.hasTopFixedRotationLaunchingApp());
}
@UseTestDisplay(addWindows = W_ACTIVITY)
@Test
public void testRotateSeamlesslyWithFixedRotation() {
final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
@@ -1275,13 +1292,14 @@ public class DisplayContentTests extends WindowTestsBase {
@Test
public void testNoFixedRotationWithPip() {
final DisplayContent displayContent = mDefaultDisplay;
unblockDisplayRotation(displayContent);
// Make resume-top really update the activity state.
setBooted(mWm.mAtmService);
// Speed up the test by a few seconds.
mWm.mAtmService.deferWindowLayout();
doNothing().when(mWm).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt());
final DisplayContent displayContent = mWm.mRoot.getDefaultDisplay();
final Configuration displayConfig = displayContent.getConfiguration();
final ActivityRecord pinnedActivity = createActivityRecord(displayContent,
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
@@ -1324,11 +1342,13 @@ public class DisplayContentTests extends WindowTestsBase {
@Test
public void testRecentsNotRotatingWithFixedRotation() {
unblockDisplayRotation(mDisplayContent);
final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
doCallRealMethod().when(displayRotation).updateRotationUnchecked(anyBoolean());
// Skip freezing so the unrelated conditions in updateRotationUnchecked won't disturb.
doNothing().when(mWm).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt());
final ActivityRecord activity = createActivityRecord(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
final ActivityRecord recentsActivity = createActivityRecord(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS);
recentsActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
@@ -1345,12 +1365,12 @@ public class DisplayContentTests extends WindowTestsBase {
// Rotation can be updated if the recents animation is animating but it is not on top, e.g.
// switching activities in different orientations by quickstep gesture.
mDisplayContent.mFixedRotationTransitionListener.onStartRecentsAnimation(recentsActivity);
mDisplayContent.setFixedRotationLaunchingAppUnchecked(mAppWindow.mActivityRecord);
mDisplayContent.setFixedRotationLaunchingAppUnchecked(activity);
displayRotation.setRotation((displayRotation.getRotation() + 1) % 4);
assertTrue(displayRotation.updateRotationUnchecked(false));
// The recents activity should not apply fixed rotation if the top activity is not opaque.
mDisplayContent.mFocusedApp = mAppWindow.mActivityRecord;
mDisplayContent.mFocusedApp = activity;
doReturn(false).when(mDisplayContent.mFocusedApp).occludesParent();
doReturn(ROTATION_90).when(mDisplayContent).rotationForActivityInDifferentOrientation(
eq(recentsActivity));

View File

@@ -36,6 +36,8 @@ import org.junit.runner.RunWith;
@SmallTest
@Presubmit
@WindowTestsBase.UseTestDisplay(
addWindows = { WindowTestsBase.W_STATUS_BAR, WindowTestsBase.W_NAVIGATION_BAR })
@RunWith(WindowTestRunner.class)
public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase {

View File

@@ -49,7 +49,6 @@ import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
@@ -65,14 +64,12 @@ import android.util.SparseArray;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.InsetsState;
import android.view.View;
import android.view.WindowInsets.Side;
import android.view.WindowInsets.Type;
import android.view.WindowManager;
import androidx.test.filters.SmallTest;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.wm.utils.WmDisplayCutout;
import org.junit.Before;
@@ -90,6 +87,8 @@ import java.io.StringWriter;
*/
@SmallTest
@Presubmit
@WindowTestsBase.UseTestDisplay(
addWindows = { WindowTestsBase.W_STATUS_BAR, WindowTestsBase.W_NAVIGATION_BAR })
@RunWith(WindowTestRunner.class)
public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
@@ -120,9 +119,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
// Disabling this call for most tests since it can override the systemUiFlags when called.
doReturn(0).when(mDisplayPolicy).updateSystemUiVisibilityLw();
mDisplayPolicy.mLastSystemUiFlags |= View.STATUS_BAR_TRANSPARENT;
mDisplayPolicy.mLastSystemUiFlags |= View.NAVIGATION_BAR_TRANSPARENT;
updateDisplayFrames();
}
@@ -146,10 +142,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mFrames = createDisplayFrames();
mDisplayBounds.set(0, 0, mFrames.mDisplayWidth, mFrames.mDisplayHeight);
mDisplayContent.mDisplayFrames = mFrames;
doReturn(mDisplayBounds).when(mStatusBarWindow).getBounds();
doReturn(mDisplayBounds).when(mNavBarWindow).getBounds();
doReturn(mDisplayBounds).when(mWindow).getBounds();
mDisplayContent.setBounds(mDisplayBounds);
}
private DisplayFrames createDisplayFrames() {

View File

@@ -222,6 +222,7 @@ public class DisplayPolicyTests extends WindowTestsBase {
opaqueDarkNavBar, imeDrawLightNavBar, imeDrawLightNavBar));
}
@UseTestDisplay(addWindows = W_ACTIVITY)
@Test
public void testComputeTopFullscreenOpaqueWindow() {
final WindowManager.LayoutParams attrs = mAppWindow.mAttrs;
@@ -320,6 +321,8 @@ public class DisplayPolicyTests extends WindowTestsBase {
return win;
}
@UseTestDisplay(
addWindows = { W_ACTIVITY, W_STATUS_BAR, W_NAVIGATION_BAR, W_NOTIFICATION_SHADE })
@Test
public void testUpdateHideNavInputEventReceiver() {
final InsetsPolicy insetsPolicy = mDisplayContent.getInsetsPolicy();
@@ -358,6 +361,7 @@ public class DisplayPolicyTests extends WindowTestsBase {
assertNull(displayPolicy.mInputConsumer);
}
@UseTestDisplay(addWindows = { W_NAVIGATION_BAR, W_INPUT_METHOD })
@Test
public void testImeMinimalSourceFrame() {
final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();

View File

@@ -68,6 +68,10 @@ public class DisplayPolicyTestsBase extends WindowTestsBase {
@Before
public void setUpDisplayPolicy() {
// Disable surface placement because it has no direct relation to layout policy and it also
// avoids some noises such as the display info is modified, screen frozen, config change.
mWm.mWindowPlacerLocked.deferLayout();
mDisplayPolicy = mDisplayContent.getDisplayPolicy();
spyOn(mDisplayPolicy);
@@ -100,6 +104,9 @@ public class DisplayPolicyTestsBase extends WindowTestsBase {
mNavBarWindow.mAttrs.gravity = Gravity.BOTTOM;
addWindow(mNavBarWindow);
mDisplayPolicy.mLastSystemUiFlags |= View.NAVIGATION_BAR_TRANSPARENT;
// Update source frame and visibility of insets providers.
mDisplayContent.getInsetsStateController().onPostLayout();
}
void addWindow(WindowState win) {

View File

@@ -77,6 +77,7 @@ import java.nio.charset.StandardCharsets;
*/
@SmallTest
@Presubmit
@WindowTestsBase.UseTestDisplay
@RunWith(WindowTestRunner.class)
public class DisplayWindowSettingsTests extends WindowTestsBase {

View File

@@ -225,6 +225,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
assertEquals(ITYPE_STATUS_BAR, fullscreenAppControls[0].getType());
}
@UseTestDisplay(addWindows = W_ACTIVITY)
@Test
public void testShowTransientBars_bothCanBeTransient_appGetsBothFakeControls() {
addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")
@@ -259,6 +260,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
.getSource(ITYPE_NAVIGATION_BAR).isVisible());
}
@UseTestDisplay(addWindows = W_ACTIVITY)
@Test
public void testShowTransientBars_statusBarCanBeTransient_appGetsStatusBarFakeControl() {
addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")
@@ -288,6 +290,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
}
}
@UseTestDisplay(addWindows = W_ACTIVITY)
@Test
public void testAbortTransientBars_bothCanBeAborted_appGetsBothRealControls() {
addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")

View File

@@ -147,6 +147,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
assertNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_NAVIGATION_BAR));
}
@UseTestDisplay(addWindows = W_INPUT_METHOD)
@Test
public void testStripForDispatch_independentSources() {
getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
@@ -162,6 +163,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
assertTrue(getController().getInsetsForDispatch(app1).getSource(ITYPE_IME).isVisible());
}
@UseTestDisplay(addWindows = W_INPUT_METHOD)
@Test
public void testStripForDispatch_belowIme() {
getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
@@ -173,6 +175,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
assertTrue(getController().getInsetsForDispatch(app).getSource(ITYPE_IME).isVisible());
}
@UseTestDisplay(addWindows = W_INPUT_METHOD)
@Test
public void testStripForDispatch_aboveIme() {
getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
@@ -184,6 +187,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
assertFalse(getController().getInsetsForDispatch(app).getSource(ITYPE_IME).isVisible());
}
@UseTestDisplay(addWindows = W_INPUT_METHOD)
@Test
public void testStripForDispatch_imeOrderChanged() {
// This can be the IME z-order target while app cannot be the IME z-order target.
@@ -232,6 +236,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
assertTrue(getController().getInsetsForDispatch(app).getSource(ITYPE_IME).isVisible());
}
@UseTestDisplay(addWindows = W_INPUT_METHOD)
@Test
public void testStripForDispatch_childWindow_altFocusable() {
getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
@@ -249,6 +254,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
assertFalse(getController().getInsetsForDispatch(child).getSource(ITYPE_IME).isVisible());
}
@UseTestDisplay(addWindows = W_INPUT_METHOD)
@Test
public void testStripForDispatch_childWindow_splitScreen() {
getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);

View File

@@ -92,7 +92,6 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
@Mock RecentsAnimationController.RecentsAnimationCallbacks mAnimationCallbacks;
@Mock TaskSnapshot mMockTaskSnapshot;
private RecentsAnimationController mController;
private DisplayContent mDefaultDisplay;
private ActivityStack mRootHomeTask;
@Before
@@ -100,7 +99,6 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
MockitoAnnotations.initMocks(this);
doNothing().when(mWm.mRoot).performSurfacePlacement();
when(mMockRunner.asBinder()).thenReturn(new Binder());
mDefaultDisplay = mWm.mRoot.getDefaultDisplay();
mController = spy(new RecentsAnimationController(mWm, mMockRunner, mAnimationCallbacks,
DEFAULT_DISPLAY));
mRootHomeTask = mDefaultDisplay.getDefaultTaskDisplayArea().getRootHomeTask();
@@ -321,6 +319,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
@Test
public void testRecentViewInFixedPortraitWhenTopAppInLandscape() {
unblockDisplayRotation(mDefaultDisplay);
mWm.setRecentsAnimationController(mController);
final ActivityRecord homeActivity = createHomeActivity();
@@ -365,6 +364,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
@Test
public void testClearFixedRotationLaunchingAppAfterCleanupAnimation() {
unblockDisplayRotation(mDefaultDisplay);
final ActivityRecord homeActivity = createHomeActivity();
homeActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
@@ -389,6 +389,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
@Test
public void testWallpaperHasFixedRotationApplied() {
unblockDisplayRotation(mDefaultDisplay);
mWm.setRecentsAnimationController(mController);
// Create a portrait home activity, a wallpaper and a landscape activity displayed on top.

View File

@@ -34,6 +34,7 @@ import android.animation.AnimationHandler.AnimationFrameCallbackProvider;
import android.animation.ValueAnimator;
import android.graphics.Matrix;
import android.graphics.Point;
import android.os.Handler;
import android.os.PowerManagerInternal;
import android.platform.test.annotations.Presubmit;
import android.view.Choreographer;
@@ -46,11 +47,12 @@ import android.view.animation.TranslateAnimation;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import com.android.server.AnimationThread;
import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -64,8 +66,7 @@ import java.util.concurrent.CountDownLatch;
*/
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
public class SurfaceAnimationRunnerTest extends WindowTestsBase {
public class SurfaceAnimationRunnerTest {
@Mock SurfaceControl mMockSurface;
@Mock Transaction mMockTransaction;
@@ -75,6 +76,9 @@ public class SurfaceAnimationRunnerTest extends WindowTestsBase {
private SurfaceAnimationRunner mSurfaceAnimationRunner;
private CountDownLatch mFinishCallbackLatch;
private final Handler mAnimationThreadHandler = AnimationThread.getHandler();
private final Handler mSurfaceAnimationHandler = SurfaceAnimationThread.getHandler();
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -84,6 +88,12 @@ public class SurfaceAnimationRunnerTest extends WindowTestsBase {
mMockTransaction, mMockPowerManager);
}
@After
public void tearDown() {
SurfaceAnimationThread.dispose();
AnimationThread.dispose();
}
private void finishedCallback() {
mFinishCallbackLatch.countDown();
}
@@ -101,8 +111,7 @@ public class SurfaceAnimationRunnerTest extends WindowTestsBase {
verify(mMockTransaction, atLeastOnce()).setMatrix(eq(mMockSurface), eq(m), any());
verify(mMockTransaction, atLeastOnce()).setAlpha(eq(mMockSurface), eq(1.0f));
waitHandlerIdle(SurfaceAnimationThread.getHandler());
mFinishCallbackLatch.await(1, SECONDS);
waitHandlerIdle(mSurfaceAnimationHandler);
assertFinishCallbackCalled();
m.setTranslate(10, 0);
@@ -120,7 +129,7 @@ public class SurfaceAnimationRunnerTest extends WindowTestsBase {
.startAnimation(createTranslateAnimation(), mMockSurface, mMockTransaction,
this::finishedCallback);
mSurfaceAnimationRunner.onAnimationCancelled(mMockSurface);
waitUntilHandlersIdle();
waitHandlerIdle(mAnimationThreadHandler);
assertTrue(mSurfaceAnimationRunner.mPendingAnimations.isEmpty());
assertFinishCallbackNotCalled();
}
@@ -135,7 +144,7 @@ public class SurfaceAnimationRunnerTest extends WindowTestsBase {
assertFalse(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
mSurfaceAnimationRunner.onAnimationCancelled(mMockSurface);
assertTrue(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
waitUntilHandlersIdle();
waitHandlerIdle(mAnimationThreadHandler);
assertFinishCallbackNotCalled();
}
@@ -180,9 +189,8 @@ public class SurfaceAnimationRunnerTest extends WindowTestsBase {
assertTrue(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
mSurfaceAnimationRunner.continueStartingAnimations();
waitUntilNextFrame();
waitHandlerIdle(SurfaceAnimationThread.getHandler());
waitHandlerIdle(mSurfaceAnimationHandler);
assertFalse(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
mFinishCallbackLatch.await(1, SECONDS);
assertFinishCallbackCalled();
}
@@ -204,7 +212,15 @@ public class SurfaceAnimationRunnerTest extends WindowTestsBase {
latch.await();
}
private static void waitHandlerIdle(Handler handler) {
handler.runWithScissors(() -> { }, 0 /* timeout */);
}
private void assertFinishCallbackCalled() {
try {
assertTrue(mFinishCallbackLatch.await(5, SECONDS));
} catch (InterruptedException ignored) {
}
assertEquals(0, mFinishCallbackLatch.getCount());
}

View File

@@ -102,6 +102,7 @@ public class SystemServicesTestRule implements TestRule {
private static final int[] TEST_USER_PROFILE_IDS = {};
private Description mDescription;
private Context mContext;
private StaticMockitoSession mMockitoSession;
private ActivityManagerService mAmService;
@@ -121,6 +122,7 @@ public class SystemServicesTestRule implements TestRule {
return new Statement() {
@Override
public void evaluate() throws Throwable {
mDescription = description;
Throwable throwable = null;
try {
runWithDexmakerShareClassLoader(SystemServicesTestRule.this::setUp);
@@ -373,6 +375,10 @@ public class SystemServicesTestRule implements TestRule {
LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
}
Description getDescription() {
return mDescription;
}
WindowManagerService getWindowManagerService() {
return mWmService;
}

View File

@@ -183,6 +183,7 @@ public class TaskSnapshotControllerTest extends WindowTestsBase {
}
}
@UseTestDisplay(addWindows = W_ACTIVITY)
@Test
public void testPrepareTaskSnapshot() {
mAppWindow.mWinAnimator.mLastAlpha = 1f;

View File

@@ -74,6 +74,7 @@ public class TaskStackChangedListenerTest {
private IActivityManager mService;
private ITaskStackListener mTaskStackListener;
private static final int WAIT_TIMEOUT_MS = 5000;
private static final Object sLock = new Object();
@GuardedBy("sLock")
private static boolean sTaskStackChangedCalled;
@@ -490,7 +491,8 @@ public class TaskStackChangedListenerTest {
SystemUtil.runWithShellPermissionIdentity(() -> context.startActivity(
new Intent(context, activityClass).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
options.toBundle()));
final TestActivity activity = (TestActivity) monitor.waitForActivityWithTimeout(1000);
final TestActivity activity =
(TestActivity) monitor.waitForActivityWithTimeout(WAIT_TIMEOUT_MS);
if (activity == null) {
throw new RuntimeException("Timed out waiting for Activity");
}
@@ -508,7 +510,7 @@ public class TaskStackChangedListenerTest {
private void waitForCallback(CountDownLatch latch) {
try {
final boolean result = latch.await(4, TimeUnit.SECONDS);
final boolean result = latch.await(WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
if (!result) {
throw new RuntimeException("Timed out waiting for task stack change notification");
}
@@ -560,7 +562,7 @@ public class TaskStackChangedListenerTest {
if (mIsResumed == isResumed) {
return;
}
wait(5000);
wait(WAIT_TIMEOUT_MS);
}
assertEquals("The activity resume state change timed out", isResumed, mIsResumed);
}

View File

@@ -270,6 +270,7 @@ public class WallpaperControllerTests extends WindowTestsBase {
assertEquals(WINDOWING_MODE_FULLSCREEN, token.getWindowingMode());
}
@UseTestDisplay(addWindows = W_ACTIVITY)
@Test
public void testFixedRotationRecentsAnimatingTask() {
final RecentsAnimationController recentsController = mock(RecentsAnimationController.class);

View File

@@ -46,6 +46,7 @@ import java.util.function.Consumer;
@RunWith(WindowTestRunner.class)
public class WindowContainerTraversalTests extends WindowTestsBase {
@UseTestDisplay(addWindows = { W_DOCK_DIVIDER, W_INPUT_METHOD })
@Test
public void testDockedDividerPosition() {
final WindowState splitScreenWindow = createWindowOnStack(null,

View File

@@ -521,6 +521,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
assertEquals(ACTIVITY_TYPE_UNDEFINED, info1.topActivityType);
}
@UseTestDisplay
@Test
public void testTaskInfoCallback() {
final ArrayList<RunningTaskInfo> lastReportedTiles = new ArrayList<>();
@@ -584,6 +585,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
assertEquals(ACTIVITY_TYPE_UNDEFINED, lastReportedTiles.get(0).topActivityType);
}
@UseTestDisplay
@Test
public void testHierarchyTransaction() {
final ArrayMap<IBinder, RunningTaskInfo> lastReportedTiles = new ArrayMap<>();

View File

@@ -36,7 +36,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -417,10 +416,11 @@ public class WindowStateTests extends WindowTestsBase {
assertFalse(app.canAffectSystemUiFlags());
}
@UseTestDisplay(addWindows = { W_ACTIVITY, W_STATUS_BAR })
@Test
public void testVisibleWithInsetsProvider() {
final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, "statusBar");
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
final WindowState statusBar = mStatusBarWindow;
final WindowState app = mAppWindow;
statusBar.mHasSurface = true;
assertTrue(statusBar.isVisible());
mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR)
@@ -542,6 +542,7 @@ public class WindowStateTests extends WindowTestsBase {
assertTrue(window.isVisibleByPolicy());
}
@UseTestDisplay(addWindows = { W_ABOVE_ACTIVITY, W_NOTIFICATION_SHADE })
@Test
public void testRequestDrawIfNeeded() {
final WindowState startingApp = createWindow(null /* parent */,
@@ -567,6 +568,7 @@ public class WindowStateTests extends WindowTestsBase {
assertEquals(Arrays.asList(keyguardHostWindow, startingWindow), outWaitingForDrawn);
}
@UseTestDisplay(addWindows = W_ABOVE_ACTIVITY)
@Test
public void testReportResizedWithRemoteException() {
final WindowState win = mChildAppWindowAbove;
@@ -597,6 +599,7 @@ public class WindowStateTests extends WindowTestsBase {
assertFalse(win.getOrientationChanging());
}
@UseTestDisplay(addWindows = W_ABOVE_ACTIVITY)
@Test
public void testRequestResizeForBlastSync() {
final WindowState win = mChildAppWindowAbove;
@@ -677,6 +680,7 @@ public class WindowStateTests extends WindowTestsBase {
assertTrue(win0.cantReceiveTouchInput());
}
@UseTestDisplay(addWindows = W_ACTIVITY)
@Test
public void testNeedsRelativeLayeringToIme_notAttached() {
WindowState sameTokenWindow = createWindow(null, TYPE_BASE_APPLICATION, mAppWindow.mToken,
@@ -689,6 +693,7 @@ public class WindowStateTests extends WindowTestsBase {
assertFalse(sameTokenWindow.needsRelativeLayeringToIme());
}
@UseTestDisplay(addWindows = { W_ACTIVITY, W_INPUT_METHOD })
@Test
public void testNeedsRelativeLayeringToIme_startingWindow() {
WindowState sameTokenWindow = createWindow(null, TYPE_APPLICATION_STARTING,

View File

@@ -39,11 +39,11 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat
import static org.mockito.Mockito.mock;
import android.content.Context;
import android.annotation.IntDef;
import android.content.Intent;
import android.hardware.display.DisplayManager;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.IDisplayWindowInsetsController;
@@ -54,23 +54,36 @@ import android.view.SurfaceControl.Transaction;
import android.view.View;
import android.view.WindowManager;
import com.android.internal.util.ArrayUtils;
import com.android.server.AttributeCache;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.runner.Description;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/** Common base class for window manager unit test classes. */
class WindowTestsBase extends SystemServiceTestsBase {
private static final String TAG = WindowTestsBase.class.getSimpleName();
WindowManagerService mWm;
private final IWindow mIWindow = new TestIWindow();
private Session mMockSession;
static int sNextStackId = 1000;
/** Non-default display. */
DisplayContent mDisplayContent;
DisplayInfo mDisplayInfo = new DisplayInfo();
DisplayContent mDefaultDisplay;
/**
* It is {@link #mDefaultDisplay} by default. If the test class or method is annotated with
* {@link UseTestDisplay}, it will be an additional display.
*/
DisplayContent mDisplayContent;
// The following fields are only available depending on the usage of annotation UseTestDisplay.
WindowState mWallpaperWindow;
WindowState mImeWindow;
WindowState mImeDialogWindow;
@@ -97,48 +110,82 @@ class WindowTestsBase extends SystemServiceTestsBase {
mWm = mSystemServicesTestRule.getWindowManagerService();
SystemServicesTestRule.checkHoldsLock(mWm.mGlobalLock);
mDefaultDisplay = mWm.mRoot.getDefaultDisplay();
mTransaction = mSystemServicesTestRule.mTransaction;
mMockSession = mock(Session.class);
final Context context = getInstrumentation().getTargetContext();
// If @Before throws an exception, the error isn't logged. This will make sure any failures
// in the set up are clear. This can be removed when b/37850063 is fixed.
try {
beforeCreateDisplay();
context.getDisplay().getDisplayInfo(mDisplayInfo);
mDisplayContent = createNewDisplay(true /* supportIme */);
getInstrumentation().getTargetContext().getSystemService(DisplayManager.class)
.getDisplay(Display.DEFAULT_DISPLAY).getDisplayInfo(mDisplayInfo);
// Set-up some common windows.
mWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow");
mImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "mImeWindow");
mDisplayContent.mInputMethodWindow = mImeWindow;
mImeDialogWindow = createCommonWindow(null, TYPE_INPUT_METHOD_DIALOG,
"mImeDialogWindow");
mStatusBarWindow = createCommonWindow(null, TYPE_STATUS_BAR, "mStatusBarWindow");
mNotificationShadeWindow = createCommonWindow(null, TYPE_NOTIFICATION_SHADE,
"mNotificationShadeWindow");
mNavBarWindow = createCommonWindow(null, TYPE_NAVIGATION_BAR, "mNavBarWindow");
mDockedDividerWindow = createCommonWindow(null, TYPE_DOCK_DIVIDER,
"mDockedDividerWindow");
mAppWindow = createCommonWindow(null, TYPE_BASE_APPLICATION, "mAppWindow");
mChildAppWindowAbove = createCommonWindow(mAppWindow,
TYPE_APPLICATION_ATTACHED_DIALOG,
"mChildAppWindowAbove");
mChildAppWindowBelow = createCommonWindow(mAppWindow,
TYPE_APPLICATION_MEDIA_OVERLAY,
"mChildAppWindowBelow");
mDisplayContent.getInsetsPolicy().setRemoteInsetsControllerControlsSystemBars(false);
// Adding a display will cause freezing the display. Make sure to wait until it's
// unfrozen to not run into race conditions with the tests.
waitUntilHandlersIdle();
} catch (Exception e) {
Log.e(TAG, "Failed to set up test", e);
throw e;
// Only create an additional test display for annotated test class/method because it may
// significantly increase the execution time.
final Description description = mSystemServicesTestRule.getDescription();
UseTestDisplay testDisplayAnnotation = description.getAnnotation(UseTestDisplay.class);
if (testDisplayAnnotation == null) {
testDisplayAnnotation = description.getTestClass().getAnnotation(UseTestDisplay.class);
}
if (testDisplayAnnotation != null) {
createTestDisplay(testDisplayAnnotation);
} else {
mDisplayContent = mDefaultDisplay;
}
}
void beforeCreateDisplay() {
private void createTestDisplay(UseTestDisplay annotation) {
beforeCreateTestDisplay();
mDisplayContent = createNewDisplay(true /* supportIme */);
final boolean addAll = annotation.addAllCommonWindows();
final @CommonTypes int[] requestedWindows = annotation.addWindows();
if (addAll || ArrayUtils.contains(requestedWindows, W_WALLPAPER)) {
mWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow");
}
if (addAll || ArrayUtils.contains(requestedWindows, W_INPUT_METHOD)) {
mImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "mImeWindow");
mDisplayContent.mInputMethodWindow = mImeWindow;
}
if (addAll || ArrayUtils.contains(requestedWindows, W_INPUT_METHOD_DIALOG)) {
mImeDialogWindow = createCommonWindow(null, TYPE_INPUT_METHOD_DIALOG,
"mImeDialogWindow");
}
if (addAll || ArrayUtils.contains(requestedWindows, W_STATUS_BAR)) {
mStatusBarWindow = createCommonWindow(null, TYPE_STATUS_BAR, "mStatusBarWindow");
}
if (addAll || ArrayUtils.contains(requestedWindows, W_NOTIFICATION_SHADE)) {
mNotificationShadeWindow = createCommonWindow(null, TYPE_NOTIFICATION_SHADE,
"mNotificationShadeWindow");
}
if (addAll || ArrayUtils.contains(requestedWindows, W_NAVIGATION_BAR)) {
mNavBarWindow = createCommonWindow(null, TYPE_NAVIGATION_BAR, "mNavBarWindow");
}
if (addAll || ArrayUtils.contains(requestedWindows, W_DOCK_DIVIDER)) {
mDockedDividerWindow = createCommonWindow(null, TYPE_DOCK_DIVIDER,
"mDockedDividerWindow");
}
final boolean addAboveApp = ArrayUtils.contains(requestedWindows, W_ABOVE_ACTIVITY);
final boolean addBelowApp = ArrayUtils.contains(requestedWindows, W_BELOW_ACTIVITY);
if (addAll || addAboveApp || addBelowApp
|| ArrayUtils.contains(requestedWindows, W_ACTIVITY)) {
mAppWindow = createCommonWindow(null, TYPE_BASE_APPLICATION, "mAppWindow");
}
if (addAll || addAboveApp) {
mChildAppWindowAbove = createCommonWindow(mAppWindow, TYPE_APPLICATION_ATTACHED_DIALOG,
"mChildAppWindowAbove");
}
if (addAll || addBelowApp) {
mChildAppWindowBelow = createCommonWindow(mAppWindow, TYPE_APPLICATION_MEDIA_OVERLAY,
"mChildAppWindowBelow");
}
mDisplayContent.getInsetsPolicy().setRemoteInsetsControllerControlsSystemBars(false);
// Adding a display will cause freezing the display. Make sure to wait until it's
// unfrozen to not run into race conditions with the tests.
waitUntilHandlersIdle();
}
void beforeCreateTestDisplay() {
// Called before display is created.
}
@@ -392,4 +439,66 @@ class WindowTestsBase extends SystemServiceTestsBase {
void removeGlobalMinSizeRestriction() {
mWm.mAtmService.mRootWindowContainer.mDefaultMinSizeOfResizeableTaskDp = 1;
}
/**
* Avoids rotating screen disturbed by some conditions. It is usually used for the default
* display that is not the instance of {@link TestDisplayContent} (it bypasses the conditions).
*
* @see DisplayRotation#updateRotationUnchecked
*/
void unblockDisplayRotation(DisplayContent dc) {
mWm.stopFreezingDisplayLocked();
// The rotation animation won't actually play, it needs to be cleared manually.
dc.setRotationAnimation(null);
}
// The window definition for UseTestDisplay#addWindows. The test can declare to add only
// necessary windows, that avoids adding unnecessary overhead of unused windows.
static final int W_NOTIFICATION_SHADE = TYPE_NOTIFICATION_SHADE;
static final int W_STATUS_BAR = TYPE_STATUS_BAR;
static final int W_NAVIGATION_BAR = TYPE_NAVIGATION_BAR;
static final int W_INPUT_METHOD_DIALOG = TYPE_INPUT_METHOD_DIALOG;
static final int W_INPUT_METHOD = TYPE_INPUT_METHOD;
static final int W_DOCK_DIVIDER = TYPE_DOCK_DIVIDER;
static final int W_ABOVE_ACTIVITY = TYPE_APPLICATION_ATTACHED_DIALOG;
static final int W_ACTIVITY = TYPE_BASE_APPLICATION;
static final int W_BELOW_ACTIVITY = TYPE_APPLICATION_MEDIA_OVERLAY;
static final int W_WALLPAPER = TYPE_WALLPAPER;
/** The common window types supported by {@link UseTestDisplay}. */
@Retention(RetentionPolicy.RUNTIME)
@IntDef(value = {
W_NOTIFICATION_SHADE,
W_STATUS_BAR,
W_NAVIGATION_BAR,
W_INPUT_METHOD_DIALOG,
W_INPUT_METHOD,
W_DOCK_DIVIDER,
W_ABOVE_ACTIVITY,
W_ACTIVITY,
W_BELOW_ACTIVITY,
W_WALLPAPER,
})
@interface CommonTypes {
}
/**
* The annotation for class and method (higher priority) to create a non-default display that
* will be assigned to {@link #mDisplayContent}. It is used if the test needs
* <ul>
* <li>Pure empty display.</li>
* <li>Configured common windows.</li>
* <li>Independent and customizable orientation.</li>
* <li>Cross display operation.</li>
* </ul>
*
* @see TestDisplayContent
* @see #createTestDisplay
**/
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@interface UseTestDisplay {
boolean addAllCommonWindows() default false;
@CommonTypes int[] addWindows() default {};
}
}

View File

@@ -142,6 +142,7 @@ public class WindowTokenTests extends WindowTestsBase {
assertEquals(0, token.getWindowsCount());
}
@UseTestDisplay(addWindows = { W_ACTIVITY, W_WALLPAPER })
@Test
public void testFinishFixedRotationTransform() {
final WindowToken appToken = mAppWindow.mToken;

View File

@@ -62,6 +62,7 @@ import java.util.function.Function;
*/
@SmallTest
@Presubmit
@WindowTestsBase.UseTestDisplay(addAllCommonWindows = true)
@RunWith(WindowTestRunner.class)
public class ZOrderingTests extends WindowTestsBase {
@@ -152,7 +153,7 @@ public class ZOrderingTests extends WindowTestsBase {
private LayerRecordingTransaction mTransaction;
@Override
void beforeCreateDisplay() {
void beforeCreateTestDisplay() {
// We can't use @Before here because it may happen after WindowTestsBase @Before
// which is after construction of the DisplayContent, meaning the HierarchyRecorder
// would miss construction of the top-level layers.