From 3b307455a093f6ac0eb995d5e344e4aaf303a045 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 26 Mar 2025 23:04:05 -0700 Subject: [PATCH] Revert^2 "Simplifying model testing rules" 35b6d322ab8dab02d4218b2b3f0d9295f9e57910 Change-Id: I3ed574a517dbe350b6dfe5b1d3ed198203d22f44 --- .../util/SystemWindowManagerProxy.java | 11 +- .../model/QuickstepModelDelegateTest.kt | 24 +- .../rules/TaskbarWindowSandboxContext.kt | 2 +- .../quickstep/AbsSwipeUpHandlerTestCase.java | 21 +- .../LauncherRestoreEventLoggerImplTest.kt | 19 +- .../quickstep/LauncherSwipeHandlerV2Test.kt | 13 +- .../recents/window/RecentsDisplayModelTest.kt | 7 +- .../quickstep/util/TaskViewSimulatorTest.java | 129 ++++---- .../WidgetsPredicationUpdateTaskTest.java | 38 +-- .../launcher3/model/LayoutParserFactory.kt | 3 +- .../launcher3/util/DisplayController.java | 2 +- .../util/window/WindowManagerProxy.java | 2 +- .../launcher3/AutoInstallsLayoutTest.kt | 27 +- .../dagger/LauncherComponentProviderTest.kt | 13 +- .../model/AbstractWorkspaceModelTest.kt | 29 +- .../model/AddWorkspaceItemsTaskTest.kt | 11 +- .../launcher3/model/AsyncBindingTest.kt | 32 +- .../model/CacheDataUpdatedTaskTest.java | 44 +-- .../model/DefaultLayoutProviderTest.java | 35 +-- .../launcher3/model/FolderIconLoadTest.kt | 43 ++- .../launcher3/model/GridSizeMigrationTest.kt | 11 +- .../launcher3/model/LoaderCursorTest.java | 11 +- .../PackageInstallStateChangedTaskTest.java | 43 +-- .../launcher3/model/PackageUpdatedTaskTest.kt | 11 +- .../model/WorkspaceItemProcessorTest.kt | 8 +- .../model/WorkspaceItemSpaceFinderTest.kt | 13 +- .../model/data/ItemInfoWithIconTest.kt | 11 +- .../launcher3/pm/InstallSessionTrackerTest.kt | 12 +- .../com/android/launcher3/pm/UserCacheTest.kt | 19 +- .../launcher3/provider/RestoreDbTaskTest.java | 12 +- .../launcher3/ui/BubbleTextViewTest.java | 11 +- .../util/DaggerSingletonDeadlockTest.kt | 10 +- .../launcher3/util/DisplayControllerTest.kt | 15 +- .../launcher3/util/LauncherModelHelper.java | 283 ------------------ .../launcher3/util/ModelTestExtensions.kt | 10 + .../launcher3/util/SandboxApplication.kt | 101 ++++++- .../launcher3/util/VibratorWrapperTest.kt | 4 +- .../util/rule/InstallerSessionRule.kt | 51 ++++ .../launcher3/util/rule/LayoutProviderRule.kt | 67 +++++ .../launcher3/widget/GeneratedPreviewTest.kt | 5 +- .../widget/custom/CustomWidgetManagerTest.kt | 4 +- .../folder/PreviewItemManagerTest.kt | 55 ++-- .../android/launcher3/model/LoaderTaskTest.kt | 5 +- .../model/ModelMultiCallbacksTest.java | 38 +-- .../launcher3/pm/InstallSessionHelperTest.kt | 8 +- .../launcher3/popup/SystemShortcutTest.java | 17 +- 46 files changed, 590 insertions(+), 750 deletions(-) create mode 100644 tests/multivalentTests/src/com/android/launcher3/util/rule/InstallerSessionRule.kt create mode 100644 tests/multivalentTests/src/com/android/launcher3/util/rule/LayoutProviderRule.kt diff --git a/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java b/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java index d92cc86a6d..05eede3ef4 100644 --- a/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java +++ b/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java @@ -48,12 +48,15 @@ import javax.inject.Inject; public class SystemWindowManagerProxy extends WindowManagerProxy { private final DesktopVisibilityController mDesktopVisibilityController; - + private final SystemUiProxy mSystemUiProxy; @Inject - public SystemWindowManagerProxy(DesktopVisibilityController desktopVisibilityController) { + public SystemWindowManagerProxy( + DesktopVisibilityController desktopVisibilityController, + SystemUiProxy systemUiProxy) { super(true); mDesktopVisibilityController = desktopVisibilityController; + mSystemUiProxy = systemUiProxy; } @Override @@ -110,8 +113,8 @@ public class SystemWindowManagerProxy extends WindowManagerProxy { } @Override - public boolean isHomeVisible(Context context) { - return SystemUiProxy.INSTANCE.get(context).getHomeVisibilityState().isHomeVisible(); + public boolean isHomeVisible() { + return mSystemUiProxy.getHomeVisibilityState().isHomeVisible(); } @Override diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/model/QuickstepModelDelegateTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/model/QuickstepModelDelegateTest.kt index 1c7af14667..b5953c7834 100644 --- a/quickstep/tests/multivalentTests/src/com/android/launcher3/model/QuickstepModelDelegateTest.kt +++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/model/QuickstepModelDelegateTest.kt @@ -19,15 +19,16 @@ import android.app.prediction.AppPredictor import android.app.prediction.AppTarget import android.app.prediction.AppTargetEvent import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.launcher3.LauncherAppState import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WALLPAPERS import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION -import com.android.launcher3.util.LauncherModelHelper -import org.junit.After +import com.android.launcher3.util.SandboxApplication import org.junit.Assert.assertNotSame import org.junit.Assert.assertSame import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock @@ -40,8 +41,9 @@ import org.mockito.MockitoAnnotations @RunWith(AndroidJUnit4::class) class QuickstepModelDelegateTest { + @get:Rule val context = SandboxApplication().withModelDependency() + private lateinit var underTest: QuickstepModelDelegate - private lateinit var modelHelper: LauncherModelHelper @Mock private lateinit var target: AppTarget @Mock private lateinit var mockedAppTargetEvent: AppTargetEvent @@ -52,24 +54,18 @@ class QuickstepModelDelegateTest { @Before fun setUp() { MockitoAnnotations.initMocks(this) - modelHelper = LauncherModelHelper() underTest = QuickstepModelDelegate( - modelHelper.sandboxContext, - modelHelper.sandboxContext.appComponent.idp, - modelHelper.sandboxContext.appComponent.packageManagerHelper, + context, + context.appComponent.idp, + context.appComponent.packageManagerHelper, "", /* dbFileName */ ) underTest.mAllAppsState.predictor = allAppsPredictor underTest.mHotseatState.predictor = hotseatPredictor underTest.mWidgetsRecommendationState.predictor = widgetRecommendationPredictor - underTest.mModel = modelHelper.model - underTest.mDataModel = BgDataModel(WidgetsModel(modelHelper.sandboxContext)) - } - - @After - fun tearDown() { - modelHelper.destroy() + underTest.mModel = LauncherAppState.getInstance(context).model + underTest.mDataModel = BgDataModel(WidgetsModel(context)) } @Test diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt index d96e06eca5..579ae6c9e3 100644 --- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt +++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/rules/TaskbarWindowSandboxContext.kt @@ -109,7 +109,7 @@ private constructor( } return TaskbarWindowSandboxContext( - SandboxApplication(base.createDisplayContext(virtualDisplay.display)), + SandboxApplication(base = base.createDisplayContext(virtualDisplay.display)), virtualDisplay, params, ) diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java index 1e2f9ad21c..ea4bd45547 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java @@ -51,7 +51,6 @@ import android.os.SystemClock; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; -import android.view.Display; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.ViewTreeObserver; @@ -64,8 +63,8 @@ import com.android.launcher3.LauncherRootView; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.StatefulContainer; -import com.android.launcher3.util.LauncherModelHelper; import com.android.launcher3.util.MSDLPlayerWrapper; +import com.android.launcher3.util.SandboxApplication; import com.android.launcher3.util.SystemUiController; import com.android.quickstep.util.ContextInitListener; import com.android.quickstep.util.MotionPauseDetector; @@ -95,9 +94,15 @@ public abstract class AbsSwipeUpHandlerTestCase< SWIPE_HANDLER extends AbsSwipeUpHandler, CONTAINER_INTERFACE extends BaseContainerInterface> { - protected final LauncherModelHelper mLauncherModelHelper = new LauncherModelHelper(); - protected final LauncherModelHelper.SandboxModelContext mContext = - mLauncherModelHelper.sandboxContext; + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + @Rule + public final SandboxApplication mContext = new SandboxApplication(); + protected final InputConsumerController mInputConsumerController = InputConsumerController.getRecentsAnimationInputConsumer(); protected final ActivityManager.RunningTaskInfo mRunningTaskInfo = @@ -137,12 +142,6 @@ public abstract class AbsSwipeUpHandlerTestCase< @Mock protected GestureState mGestureState; @Mock protected MSDLPlayerWrapper mMSDLPlayerWrapper; - @Rule - public final MockitoRule mMockitoRule = MockitoJUnit.rule(); - - @Rule - public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @Before public void setUpAnimationTargets() { Bundle extras = new Bundle(); diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherRestoreEventLoggerImplTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherRestoreEventLoggerImplTest.kt index 24f9696437..d4d76c1e76 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherRestoreEventLoggerImplTest.kt +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherRestoreEventLoggerImplTest.kt @@ -22,10 +22,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.launcher3.Flags import com.android.launcher3.LauncherSettings.Favorites -import com.android.launcher3.util.LauncherModelHelper -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext +import com.android.launcher3.util.SandboxApplication import com.google.common.truth.Truth.assertThat -import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test @@ -37,9 +35,8 @@ import org.junit.runner.RunWith class LauncherRestoreEventLoggerImplTest { @get:Rule val setFlagsRule = SetFlagsRule() + @get:Rule val mSandboxContext = SandboxApplication() - private val mLauncherModelHelper = LauncherModelHelper() - private val mSandboxContext: SandboxModelContext = mLauncherModelHelper.sandboxContext private lateinit var loggerUnderTest: LauncherRestoreEventLoggerImpl @Before @@ -47,12 +44,6 @@ class LauncherRestoreEventLoggerImplTest { loggerUnderTest = LauncherRestoreEventLoggerImpl(mSandboxContext) } - @After - fun teardown() { - loggerUnderTest.restoreEventLogger.clearData() - mLauncherModelHelper.destroy() - } - @Test fun `logLauncherItemsRestoreFailed logs multiple items as failing restore`() { // Given @@ -62,7 +53,7 @@ class LauncherRestoreEventLoggerImplTest { loggerUnderTest.logLauncherItemsRestoreFailed( dataType = expectedDataType, count = 5, - error = expectedError + error = expectedError, ) // Then val actualResult = loggerUnderTest.restoreEventLogger.loggingResults.first() @@ -108,7 +99,7 @@ class LauncherRestoreEventLoggerImplTest { // When loggerUnderTest.logSingleFavoritesItemRestoreFailed( favoritesId = Favorites.ITEM_TYPE_APPWIDGET, - error = expectedError + error = expectedError, ) // Then val actualResult = loggerUnderTest.restoreEventLogger.loggingResults.first() @@ -127,7 +118,7 @@ class LauncherRestoreEventLoggerImplTest { loggerUnderTest.logFavoritesItemsRestoreFailed( favoritesId = Favorites.ITEM_TYPE_DEEP_SHORTCUT, count = 5, - error = expectedError + error = expectedError, ) // Then val actualResult = loggerUnderTest.restoreEventLogger.loggingResults.first() diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt index 5661dcf699..5790b6a290 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt @@ -29,8 +29,8 @@ import com.android.launcher3.R import com.android.launcher3.dagger.LauncherAppComponent import com.android.launcher3.dagger.LauncherAppModule import com.android.launcher3.dagger.LauncherAppSingleton -import com.android.launcher3.util.LauncherModelHelper import com.android.launcher3.util.MSDLPlayerWrapper +import com.android.launcher3.util.SandboxApplication import com.android.systemui.contextualeducation.GestureType import com.android.systemui.shared.system.InputConsumerController import dagger.BindsInstance @@ -39,6 +39,7 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mockito.Answers.RETURNS_DEEP_STUBS import org.mockito.Mock import org.mockito.Mockito.mock import org.mockito.Mockito.spy @@ -56,22 +57,19 @@ class LauncherSwipeHandlerV2Test { private lateinit var gestureState: GestureState @Mock private lateinit var inputConsumerController: InputConsumerController - @Mock private lateinit var systemUiProxy: SystemUiProxy + @Mock(answer = RETURNS_DEEP_STUBS) private lateinit var systemUiProxy: SystemUiProxy @Mock private lateinit var msdlPlayerWrapper: MSDLPlayerWrapper private lateinit var underTest: LauncherSwipeHandlerV2 @get:Rule val mockitoRule = MockitoJUnit.rule() - - private val launcherModelHelper = LauncherModelHelper() - private val sandboxContext = launcherModelHelper.sandboxContext + @get:Rule val sandboxContext = SandboxApplication() private val flingSpeed = -(sandboxContext.resources.getDimension(R.dimen.quickstep_fling_threshold_speed) + 1) - private val displayManager: DisplayManager = - sandboxContext.spyService(DisplayManager::class.java) + private lateinit var displayManager: DisplayManager @Before fun setup() { @@ -82,6 +80,7 @@ class LauncherSwipeHandlerV2Test { DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS, ) + displayManager = sandboxContext.spyService(DisplayManager::class.java) whenever(displayManager.getDisplay(eq(DEFAULT_DISPLAY))).thenReturn(display) whenever(displayManager.displays).thenReturn(arrayOf(display)) diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/window/RecentsDisplayModelTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/window/RecentsDisplayModelTest.kt index 0119679681..1028d7cfb7 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/window/RecentsDisplayModelTest.kt +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/window/RecentsDisplayModelTest.kt @@ -28,7 +28,7 @@ import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry import com.android.launcher3.Flags.FLAG_ENABLE_FALLBACK_OVERVIEW_IN_WINDOW import com.android.launcher3.Flags.FLAG_ENABLE_LAUNCHER_OVERVIEW_IN_WINDOW -import com.android.launcher3.util.LauncherModelHelper +import com.android.launcher3.util.SandboxApplication import com.android.launcher3.util.window.CachedDisplayInfo import com.android.quickstep.fallback.window.RecentsDisplayModel import org.junit.Assert @@ -38,7 +38,6 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.mock -import org.mockito.kotlin.spy import org.mockito.kotlin.whenever @SmallTest @@ -46,10 +45,9 @@ import org.mockito.kotlin.whenever @EnableFlags(FLAG_ENABLE_LAUNCHER_OVERVIEW_IN_WINDOW, FLAG_ENABLE_FALLBACK_OVERVIEW_IN_WINDOW) class RecentsDisplayModelTest { @get:Rule val setFlagsRule = SetFlagsRule() + @get:Rule val context = SandboxApplication() // initiate dagger components for injection - private val launcherModelHelper = LauncherModelHelper() - private val context = spy(launcherModelHelper.sandboxContext) private val displayManager: DisplayManager = context.spyService(DisplayManager::class.java) private val display: Display = mock() @@ -64,7 +62,6 @@ class RecentsDisplayModelTest { val displayInfo = CachedDisplayInfo(Point(width, height), Surface.ROTATION_0) whenever(display.rotation).thenReturn(displayInfo.rotation) whenever(display.displayAdjustments).thenReturn(DisplayAdjustments()) - whenever(context.display).thenReturn(display) // Mock displayManager whenever(displayManager.getDisplay(anyInt())).thenReturn(display) diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskViewSimulatorTest.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskViewSimulatorTest.java index be76f9e86d..5d623ac5ca 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskViewSimulatorTest.java +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TaskViewSimulatorTest.java @@ -40,9 +40,9 @@ import com.android.launcher3.dagger.LauncherAppSingleton; import com.android.launcher3.util.AllModulesMinusWMProxy; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.Info; -import com.android.launcher3.util.LauncherModelHelper; import com.android.launcher3.util.NavigationMode; import com.android.launcher3.util.RotationUtils; +import com.android.launcher3.util.SandboxApplication; import com.android.launcher3.util.WindowBounds; import com.android.launcher3.util.window.CachedDisplayInfo; import com.android.launcher3.util.window.WindowManagerProxy; @@ -55,6 +55,7 @@ import dagger.Component; import org.hamcrest.Description; import org.hamcrest.TypeSafeMatcher; import org.junit.Assert; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -65,6 +66,8 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class TaskViewSimulatorTest { + @Rule public final SandboxApplication app = new SandboxApplication(); + @Test public void taskProperlyScaled_portrait_noRotation_sameInsets1() { new TaskMatrixVerifier() @@ -123,7 +126,7 @@ public class TaskViewSimulatorTest { .verifyNoTransforms(); } - private static class TaskMatrixVerifier extends TransformParams { + private class TaskMatrixVerifier extends TransformParams { private Point mDisplaySize = new Point(); private int mDensityDpi = DisplayMetrics.DENSITY_DEFAULT; @@ -163,73 +166,67 @@ public class TaskViewSimulatorTest { } void verifyNoTransforms() { - LauncherModelHelper helper = new LauncherModelHelper(); - try { - DisplayController mockController = mock(DisplayController.class); + DisplayController mockController = mock(DisplayController.class); - helper.sandboxContext.initDaggerComponent( - DaggerTaskViewSimulatorTest_TaskViewSimulatorTestComponent.builder() - .bindDisplayController(mockController)); - int rotation = mDisplaySize.x > mDisplaySize.y - ? Surface.ROTATION_90 : Surface.ROTATION_0; - CachedDisplayInfo cdi = new CachedDisplayInfo(mDisplaySize, rotation); - WindowBounds wm = new WindowBounds( - new Rect(0, 0, mDisplaySize.x, mDisplaySize.y), - mDisplayInsets); - List allBounds = new ArrayList<>(4); - for (int i = 0; i < 4; i++) { - Rect boundsR = new Rect(wm.bounds); - Rect insetsR = new Rect(wm.insets); + app.initDaggerComponent( + DaggerTaskViewSimulatorTest_TaskViewSimulatorTestComponent.builder() + .bindDisplayController(mockController)); + int rotation = mDisplaySize.x > mDisplaySize.y + ? Surface.ROTATION_90 : Surface.ROTATION_0; + CachedDisplayInfo cdi = new CachedDisplayInfo(mDisplaySize, rotation); + WindowBounds wm = new WindowBounds( + new Rect(0, 0, mDisplaySize.x, mDisplaySize.y), + mDisplayInsets); + List allBounds = new ArrayList<>(4); + for (int i = 0; i < 4; i++) { + Rect boundsR = new Rect(wm.bounds); + Rect insetsR = new Rect(wm.insets); - RotationUtils.rotateRect(insetsR, RotationUtils.deltaRotation(rotation, i)); - RotationUtils.rotateRect(boundsR, RotationUtils.deltaRotation(rotation, i)); - boundsR.set(0, 0, Math.abs(boundsR.width()), Math.abs(boundsR.height())); - allBounds.add(new WindowBounds(boundsR, insetsR)); - } - - WindowManagerProxy wmProxy = mock(WindowManagerProxy.class); - doReturn(cdi).when(wmProxy).getDisplayInfo(any()); - doReturn(wm).when(wmProxy).getRealBounds(any(), any()); - doReturn(NavigationMode.NO_BUTTON).when(wmProxy).getNavigationMode(any()); - - ArrayMap> perDisplayBoundsCache = - new ArrayMap<>(); - perDisplayBoundsCache.put(cdi.normalize(wmProxy), allBounds); - - Configuration configuration = new Configuration(); - configuration.densityDpi = mDensityDpi; - Context configurationContext = helper.sandboxContext.createConfigurationContext( - configuration); - - DisplayController.Info info = new Info( - configurationContext, wmProxy, perDisplayBoundsCache); - when(mockController.getInfo()).thenReturn(info); - - mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(helper.sandboxContext) - .getBestMatch(mAppBounds.width(), mAppBounds.height(), rotation); - mDeviceProfile.updateInsets(mLauncherInsets); - - TaskViewSimulator tvs = new TaskViewSimulator(helper.sandboxContext, - FallbackActivityInterface.INSTANCE, false, 0); - tvs.setDp(mDeviceProfile); - - int launcherRotation = info.rotation; - if (mAppRotation < 0) { - mAppRotation = launcherRotation; - } - - tvs.getOrientationState().update(launcherRotation, mAppRotation); - if (mAppInsets == null) { - mAppInsets = new Rect(mLauncherInsets); - } - tvs.setPreviewBounds(mAppBounds, mAppInsets); - - tvs.fullScreenProgress.value = 1; - tvs.recentsViewScale.value = tvs.getFullScreenScale(); - tvs.apply(this); - } finally { - helper.destroy(); + RotationUtils.rotateRect(insetsR, RotationUtils.deltaRotation(rotation, i)); + RotationUtils.rotateRect(boundsR, RotationUtils.deltaRotation(rotation, i)); + boundsR.set(0, 0, Math.abs(boundsR.width()), Math.abs(boundsR.height())); + allBounds.add(new WindowBounds(boundsR, insetsR)); } + + WindowManagerProxy wmProxy = mock(WindowManagerProxy.class); + doReturn(cdi).when(wmProxy).getDisplayInfo(any()); + doReturn(wm).when(wmProxy).getRealBounds(any(), any()); + doReturn(NavigationMode.NO_BUTTON).when(wmProxy).getNavigationMode(any()); + + ArrayMap> perDisplayBoundsCache = + new ArrayMap<>(); + perDisplayBoundsCache.put(cdi.normalize(wmProxy), allBounds); + + Configuration configuration = new Configuration(); + configuration.densityDpi = mDensityDpi; + Context configurationContext = app.createConfigurationContext(configuration); + + DisplayController.Info info = new Info( + configurationContext, wmProxy, perDisplayBoundsCache); + when(mockController.getInfo()).thenReturn(info); + + mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(app) + .getBestMatch(mAppBounds.width(), mAppBounds.height(), rotation); + mDeviceProfile.updateInsets(mLauncherInsets); + + TaskViewSimulator tvs = new TaskViewSimulator(app, + FallbackActivityInterface.INSTANCE, false, 0); + tvs.setDp(mDeviceProfile); + + int launcherRotation = info.rotation; + if (mAppRotation < 0) { + mAppRotation = launcherRotation; + } + + tvs.getOrientationState().update(launcherRotation, mAppRotation); + if (mAppInsets == null) { + mAppInsets = new Rect(mLauncherInsets); + } + tvs.setPreviewBounds(mAppBounds, mAppInsets); + + tvs.fullScreenProgress.value = 1; + tvs.recentsViewScale.value = tvs.getFullScreenScale(); + tvs.apply(this); } @Override diff --git a/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java b/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java index 59ce6370ea..26e08f9f19 100644 --- a/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java +++ b/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java @@ -52,14 +52,17 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.launcher3.Flags; +import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherModel; import com.android.launcher3.model.BgDataModel.FixedContainerItems; import com.android.launcher3.model.QuickstepModelDelegate.PredictorState; import com.android.launcher3.util.LauncherLayoutBuilder; -import com.android.launcher3.util.LauncherModelHelper; +import com.android.launcher3.util.ModelTestExtensions; +import com.android.launcher3.util.SandboxApplication; +import com.android.launcher3.util.rule.LayoutProviderRule; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import com.android.launcher3.widget.PendingAddWidgetInfo; -import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -81,6 +84,10 @@ public final class WidgetsPredicationUpdateTaskTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Rule public SandboxApplication mContext = new SandboxApplication().withModelDependency(); + @Rule public LayoutProviderRule mLayoutProvider = new LayoutProviderRule(mContext); + + private AppWidgetProviderInfo mApp1Provider1; private AppWidgetProviderInfo mApp1Provider2; private AppWidgetProviderInfo mApp2Provider1; @@ -91,7 +98,6 @@ public final class WidgetsPredicationUpdateTaskTest { private List allWidgets; private FakeBgDataModelCallback mCallback = new FakeBgDataModelCallback(); - private LauncherModelHelper mModelHelper; private UserHandle mUserHandle; private LauncherApps mLauncherApps; @@ -99,7 +105,6 @@ public final class WidgetsPredicationUpdateTaskTest { @Before public void setup() throws Exception { mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_CATEGORIZED_WIDGET_SUGGESTIONS); - mModelHelper = new LauncherModelHelper(); mUserHandle = myUserHandle(); mApp1Provider1 = createAppWidgetProviderInfo( @@ -123,7 +128,7 @@ public final class WidgetsPredicationUpdateTaskTest { allWidgets = Arrays.asList(mApp1Provider1, mApp1Provider2, mApp2Provider1, mApp4Provider1, mApp4Provider2, mApp5Provider1, mApp6PinOnlyProvider1); - mLauncherApps = mModelHelper.sandboxContext.spyService(LauncherApps.class); + mLauncherApps = mContext.spyService(LauncherApps.class); doAnswer(i -> { String pkg = i.getArgument(0); ApplicationInfo applicationInfo = new ApplicationInfo(); @@ -135,7 +140,7 @@ public final class WidgetsPredicationUpdateTaskTest { return applicationInfo; }).when(mLauncherApps).getApplicationInfo(anyString(), anyInt(), any()); - AppWidgetManager manager = mModelHelper.sandboxContext.spyService(AppWidgetManager.class); + AppWidgetManager manager = mContext.spyService(AppWidgetManager.class); doReturn(allWidgets).when(manager).getInstalledProviders(); doReturn(allWidgets).when(manager).getInstalledProvidersForProfile(eq(myUserHandle())); doAnswer(i -> { @@ -148,14 +153,9 @@ public final class WidgetsPredicationUpdateTaskTest { LauncherLayoutBuilder builder = new LauncherLayoutBuilder() .atWorkspace(0, 1, 2).putWidget("app4", "provider1", 1, 1) .atWorkspace(0, 1, 3).putWidget("app5", "provider1", 1, 1); - mModelHelper.setupDefaultLayoutProvider(builder); - MAIN_EXECUTOR.submit(() -> mModelHelper.getModel().addCallbacks(mCallback)).get(); - mModelHelper.loadModelSync(); - } - - @After - public void tearDown() { - mModelHelper.destroy(); + mLayoutProvider.setupDefaultLayoutProvider(builder); + MAIN_EXECUTOR.submit(() -> getModel().addCallbacks(mCallback)).get(); + ModelTestExtensions.INSTANCE.loadModelSync(getModel()); } @Test @@ -175,7 +175,7 @@ public final class WidgetsPredicationUpdateTaskTest { AppTarget app5 = new AppTarget(new AppTargetId("app5"), "app5", "provider1", mUserHandle); mCallback.mRecommendedWidgets = null; - mModelHelper.getModel().enqueueModelUpdateTask( + getModel().enqueueModelUpdateTask( newWidgetsPredicationTask(List.of(app5, app3, app2, app4, app1))); runOnExecutorSync(MAIN_EXECUTOR, () -> { }); @@ -216,7 +216,7 @@ public final class WidgetsPredicationUpdateTaskTest { mUserHandle); mCallback.mRecommendedWidgets = null; - mModelHelper.getModel().enqueueModelUpdateTask( + getModel().enqueueModelUpdateTask( newWidgetsPredicationTask(List.of(widget5, widget3, widget4, widget1))); runOnExecutorSync(MAIN_EXECUTOR, () -> { }); @@ -241,7 +241,7 @@ public final class WidgetsPredicationUpdateTaskTest { mUserHandle); mCallback.mRecommendedWidgets = null; - mModelHelper.getModel().enqueueModelUpdateTask( + getModel().enqueueModelUpdateTask( newWidgetsPredicationTask(List.of(widget1, widget6))); runOnExecutorSync(MAIN_EXECUTOR, () -> { }); @@ -268,6 +268,10 @@ public final class WidgetsPredicationUpdateTaskTest { appTargets); } + private LauncherModel getModel() { + return LauncherAppState.getInstance(mContext).getModel(); + } + private final class FakeBgDataModelCallback implements BgDataModel.Callbacks { private FixedContainerItems mRecommendedWidgets = null; diff --git a/src/com/android/launcher3/model/LayoutParserFactory.kt b/src/com/android/launcher3/model/LayoutParserFactory.kt index 32aa58a03b..d6cf20beb1 100644 --- a/src/com/android/launcher3/model/LayoutParserFactory.kt +++ b/src/com/android/launcher3/model/LayoutParserFactory.kt @@ -19,6 +19,7 @@ package com.android.launcher3.model import android.app.blob.BlobHandle import android.app.blob.BlobStoreManager import android.content.Context +import android.content.res.Resources import android.os.ParcelFileDescriptor.AutoCloseInputStream import android.provider.Settings.Secure import android.text.TextUtils @@ -148,7 +149,7 @@ constructor(@ApplicationContext private val context: Context) { widgetHolder: LauncherWidgetHolder, openHelper: DatabaseHelper, xml: String, - res: SourceResources = object : SourceResources {}, + res: SourceResources = SourceResources.wrap(Resources.getSystem()), ): AutoInstallsLayout { val parser = Xml.newPullParser() parser.setInput(StringReader(xml)) diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java index 52f88876cf..ed7c7feb78 100644 --- a/src/com/android/launcher3/util/DisplayController.java +++ b/src/com/android/launcher3/util/DisplayController.java @@ -565,7 +565,7 @@ public class DisplayController implements DesktopVisibilityListener { mShowLockedTaskbarOnHome = wmProxy.showLockedTaskbarOnHome(displayInfoContext); mShowDesktopTaskbarForFreeformDisplay = wmProxy.showDesktopTaskbarForFreeformDisplay( displayInfoContext); - mIsHomeVisible = wmProxy.isHomeVisible(displayInfoContext); + mIsHomeVisible = wmProxy.isHomeVisible(); } /** diff --git a/src/com/android/launcher3/util/window/WindowManagerProxy.java b/src/com/android/launcher3/util/window/WindowManagerProxy.java index 68e032426b..79f39a9c03 100644 --- a/src/com/android/launcher3/util/window/WindowManagerProxy.java +++ b/src/com/android/launcher3/util/window/WindowManagerProxy.java @@ -131,7 +131,7 @@ public class WindowManagerProxy { /** * Returns if the home is visible. */ - public boolean isHomeVisible(Context context) { + public boolean isHomeVisible() { return false; } diff --git a/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt b/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt index 97ecafeeab..c15aaf9974 100644 --- a/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/AutoInstallsLayoutTest.kt @@ -49,8 +49,7 @@ import com.android.launcher3.util.AllModulesMinusApiWrapper import com.android.launcher3.util.ApiWrapper import com.android.launcher3.util.Executors import com.android.launcher3.util.LauncherLayoutBuilder -import com.android.launcher3.util.LauncherModelHelper -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext +import com.android.launcher3.util.SandboxApplication import com.android.launcher3.util.TestUtil import com.android.launcher3.util.UserIconInfo import com.android.launcher3.util.UserIconInfo.TYPE_MAIN @@ -60,12 +59,11 @@ import com.google.common.truth.Truth.assertThat import dagger.BindsInstance import dagger.Component import java.io.StringReader -import org.junit.After -import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock -import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnit import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.whenever @@ -75,27 +73,14 @@ import org.mockito.kotlin.whenever @RunWith(AndroidJUnit4::class) class AutoInstallsLayoutTest { - lateinit var modelHelper: LauncherModelHelper - lateinit var targetContext: SandboxModelContext + @get:Rule val mockitoRule = MockitoJUnit.rule() + @get:Rule val targetContext = SandboxApplication() - lateinit var callback: MyCallback + private val callback: MyCallback = MyCallback() @Mock lateinit var widgetHolder: LauncherWidgetHolder @Mock lateinit var db: SQLiteDatabase - @Before - fun setup() { - MockitoAnnotations.initMocks(this) - modelHelper = LauncherModelHelper() - targetContext = modelHelper.sandboxContext - callback = MyCallback() - } - - @After - fun tearDown() { - modelHelper.destroy() - } - @Test fun pending_icon_added_on_home() { LauncherLayoutBuilder() diff --git a/tests/multivalentTests/src/com/android/launcher3/dagger/LauncherComponentProviderTest.kt b/tests/multivalentTests/src/com/android/launcher3/dagger/LauncherComponentProviderTest.kt index 92558773a7..f7f098ea30 100644 --- a/tests/multivalentTests/src/com/android/launcher3/dagger/LauncherComponentProviderTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/dagger/LauncherComponentProviderTest.kt @@ -22,8 +22,8 @@ import android.view.ContextThemeWrapper import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.launcher3.R -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext import com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE +import com.android.launcher3.util.SandboxApplication import org.junit.Assert.assertNotNull import org.junit.Assert.assertNotSame import org.junit.Assert.assertSame @@ -37,9 +37,14 @@ class LauncherComponentProviderTest { @Test fun `returns same component as Launcher application`() { - val c = SandboxModelContext() - assertSame(c.appComponent, LauncherComponentProvider.get(c)) - assertNotSame(LauncherComponentProvider.get(c), LauncherComponentProvider.get(app)) + val c = SandboxApplication() + c.init() + try { + assertSame(c.appComponent, LauncherComponentProvider.get(c)) + assertNotSame(LauncherComponentProvider.get(c), LauncherComponentProvider.get(app)) + } finally { + c.onDestroy() + } } @Test diff --git a/tests/multivalentTests/src/com/android/launcher3/model/AbstractWorkspaceModelTest.kt b/tests/multivalentTests/src/com/android/launcher3/model/AbstractWorkspaceModelTest.kt index 98191fecf0..22648a4241 100644 --- a/tests/multivalentTests/src/com/android/launcher3/model/AbstractWorkspaceModelTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/model/AbstractWorkspaceModelTest.kt @@ -16,20 +16,23 @@ package com.android.launcher3.model import android.content.ComponentName -import android.content.Context import android.graphics.Rect import com.android.launcher3.InvariantDeviceProfile import com.android.launcher3.LauncherAppState +import com.android.launcher3.LauncherModel import com.android.launcher3.model.data.AppInfo import com.android.launcher3.model.data.WorkspaceItemInfo import com.android.launcher3.util.GridOccupancy import com.android.launcher3.util.IntArray import com.android.launcher3.util.IntSparseArrayMap import com.android.launcher3.util.LauncherLayoutBuilder -import com.android.launcher3.util.LauncherModelHelper import com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY import com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE +import com.android.launcher3.util.ModelTestExtensions.loadModelSync +import com.android.launcher3.util.SandboxApplication +import com.android.launcher3.util.rule.LayoutProviderRule import java.util.UUID +import org.junit.Rule /** Base class for workspace related tests. */ abstract class AbstractWorkspaceModelTest { @@ -39,19 +42,21 @@ abstract class AbstractWorkspaceModelTest { val nonEmptyScreenSpaces = listOf(Rect(1, 2, 3, 4)) } + @get:Rule val mTargetContext: SandboxApplication = SandboxApplication().withModelDependency() + @get:Rule var mLayoutProvider: LayoutProviderRule = LayoutProviderRule(mTargetContext) + protected lateinit var mLayoutBuilder: LauncherLayoutBuilder - protected lateinit var mTargetContext: Context protected lateinit var mIdp: InvariantDeviceProfile protected lateinit var mAppState: LauncherAppState - protected lateinit var mModelHelper: LauncherModelHelper protected lateinit var mExistingScreens: IntArray protected lateinit var mNewScreens: IntArray protected lateinit var mScreenOccupancy: IntSparseArrayMap + val model: LauncherModel + get() = LauncherAppState.getInstance(mTargetContext).model + open fun setup() { mLayoutBuilder = LauncherLayoutBuilder() - mModelHelper = LauncherModelHelper() - mTargetContext = mModelHelper.sandboxContext mIdp = InvariantDeviceProfile.INSTANCE[mTargetContext] mIdp.numRows = 5 mIdp.numColumns = mIdp.numRows @@ -61,17 +66,13 @@ abstract class AbstractWorkspaceModelTest { mNewScreens = IntArray() } - open fun tearDown() { - mModelHelper.destroy() - } - /** Sets up workspaces with the given screen IDs with some items and a 2x2 space. */ fun setupWorkspaces(screenIdsWithItems: List) { screenIdsWithItems.forEach { screenId -> setupWorkspace(screenId, nonEmptyScreenSpaces) } - mModelHelper.setupDefaultLayoutProvider(mLayoutBuilder) + mLayoutProvider.setupDefaultLayoutProvider(mLayoutBuilder) mIdp.numRows = 5 mIdp.numColumns = mIdp.numRows - mModelHelper.loadModelSync() + model.loadModelSync() } /** @@ -84,10 +85,10 @@ abstract class AbstractWorkspaceModelTest { screen3: List? = null, ) { listOf(screen0, screen1, screen2, screen3).let(this::setupWithSpaces) - mModelHelper.setupDefaultLayoutProvider(mLayoutBuilder) + mLayoutProvider.setupDefaultLayoutProvider(mLayoutBuilder) mIdp.numRows = 5 mIdp.numColumns = mIdp.numRows - mModelHelper.loadModelSync() + model.loadModelSync() } private fun setupWithSpaces(workspaceSpaces: List?>) { diff --git a/tests/multivalentTests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt b/tests/multivalentTests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt index 25f4cf15dc..6d366db0e6 100644 --- a/tests/multivalentTests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt @@ -25,7 +25,6 @@ import com.android.launcher3.util.Executors import com.android.launcher3.util.IntArray import com.android.launcher3.util.TestUtil.runOnExecutorSync import com.google.common.truth.Truth.assertThat -import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -50,13 +49,7 @@ class AddWorkspaceItemsTaskTest : AbstractWorkspaceModelTest() { override fun setup() { super.setup() mDataModelCallbacks = MyCallbacks() - Executors.MAIN_EXECUTOR.submit { mModelHelper.model.addCallbacks(mDataModelCallbacks) } - .get() - } - - @After - override fun tearDown() { - super.tearDown() + Executors.MAIN_EXECUTOR.submit { model.addCallbacks(mDataModelCallbacks) }.get() } @Test @@ -175,7 +168,7 @@ class AddWorkspaceItemsTaskTest : AbstractWorkspaceModelTest() { runOnExecutorSync(Executors.MODEL_EXECUTOR) { mDataModelCallbacks.addedItems.clear() - mModelHelper.model.enqueueModelUpdateTask(task) + model.enqueueModelUpdateTask(task) runOnExecutorSync(Executors.MAIN_EXECUTOR) {} addedItems.addAll(mDataModelCallbacks.addedItems) } diff --git a/tests/multivalentTests/src/com/android/launcher3/model/AsyncBindingTest.kt b/tests/multivalentTests/src/com/android/launcher3/model/AsyncBindingTest.kt index ba592532a4..657643e6bd 100644 --- a/tests/multivalentTests/src/com/android/launcher3/model/AsyncBindingTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/model/AsyncBindingTest.kt @@ -24,6 +24,8 @@ import android.view.View import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.launcher3.Flags +import com.android.launcher3.LauncherAppState +import com.android.launcher3.LauncherModel import com.android.launcher3.model.BgDataModel.Callbacks import com.android.launcher3.model.data.ItemInfo import com.android.launcher3.util.Executors.MAIN_EXECUTOR @@ -32,10 +34,11 @@ import com.android.launcher3.util.IntArray import com.android.launcher3.util.IntSet import com.android.launcher3.util.ItemInflater import com.android.launcher3.util.LauncherLayoutBuilder -import com.android.launcher3.util.LauncherModelHelper import com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE +import com.android.launcher3.util.ModelTestExtensions.loadModelSync import com.android.launcher3.util.RunnableList -import org.junit.After +import com.android.launcher3.util.SandboxApplication +import com.android.launcher3.util.rule.LayoutProviderRule import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue @@ -63,29 +66,31 @@ import org.mockito.kotlin.whenever class AsyncBindingTest { @get:Rule val setFlagsRule = SetFlagsRule() + @get:Rule val context = SandboxApplication().withModelDependency() + @get:Rule val layoutProvider = LayoutProviderRule(context) @Spy private var callbacks = MyCallbacks() @Mock private lateinit var itemInflater: ItemInflater<*> private val inflationLooper = SparseArray() - private lateinit var modelHelper: LauncherModelHelper + private val model: LauncherModel + get() = LauncherAppState.getInstance(context).model @Before fun setUp() { setFlagsRule.enableFlags(Flags.FLAG_ENABLE_WORKSPACE_INFLATION) MockitoAnnotations.initMocks(this) - modelHelper = LauncherModelHelper() doAnswer { i -> inflationLooper[(i.arguments[0] as ItemInfo).id] = Looper.myLooper() - View(modelHelper.sandboxContext) + View(context) } .whenever(itemInflater) .inflateItem(any(), any(), isNull()) // Set up the workspace with 3 pages of apps - modelHelper.setupDefaultLayoutProvider( + layoutProvider.setupDefaultLayoutProvider( LauncherLayoutBuilder() .atWorkspace(0, 1, 0) .putApp(TEST_PACKAGE, TEST_PACKAGE) @@ -100,14 +105,9 @@ class AsyncBindingTest { ) } - @After - fun tearDown() { - modelHelper.destroy() - } - @Test fun test_bind_normally_without_itemInflater() { - MAIN_EXECUTOR.execute { modelHelper.model.addCallbacksAndLoad(callbacks) } + MAIN_EXECUTOR.execute { model.addCallbacksAndLoad(callbacks) } waitForLoaderAndTempMainThread() verify(callbacks, never()).bindInflatedItems(any()) @@ -117,7 +117,7 @@ class AsyncBindingTest { @Test fun test_bind_inflates_item_on_background() { callbacks.inflater = itemInflater - MAIN_EXECUTOR.execute { modelHelper.model.addCallbacksAndLoad(callbacks) } + MAIN_EXECUTOR.execute { model.addCallbacksAndLoad(callbacks) } waitForLoaderAndTempMainThread() verify(callbacks, never()).bindItems(any(), any()) @@ -135,14 +135,14 @@ class AsyncBindingTest { @Test fun test_bind_sync_partially_inflates_on_background() { - modelHelper.loadModelSync() - assertTrue(modelHelper.model.isModelLoaded()) + model.loadModelSync() + assertTrue(model.isModelLoaded()) callbacks.inflater = itemInflater val firstPageBindIds = IntSet() MAIN_EXECUTOR.submit { - modelHelper.model.addCallbacksAndLoad(callbacks) + model.addCallbacksAndLoad(callbacks) verify(callbacks, never()).bindItems(any(), any()) verify(callbacks, times(1)) .bindInflatedItems( diff --git a/tests/multivalentTests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java b/tests/multivalentTests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java index 600af42a38..d18fd288e9 100644 --- a/tests/multivalentTests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java +++ b/tests/multivalentTests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java @@ -22,6 +22,7 @@ import static com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY; import static com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY2; import static com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY3; import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE; +import static com.android.launcher3.util.ModelTestExtensions.getBgDataModel; import static com.android.launcher3.util.TestUtil.runOnExecutorSync; import static org.junit.Assert.assertEquals; @@ -29,7 +30,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import android.content.Context; import android.content.pm.PackageInstaller; import androidx.test.core.app.ApplicationProvider; @@ -37,16 +37,19 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherModel; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.LauncherLayoutBuilder; -import com.android.launcher3.util.LauncherModelHelper; +import com.android.launcher3.util.ModelTestExtensions; import com.android.launcher3.util.PackageUserKey; +import com.android.launcher3.util.SandboxApplication; +import com.android.launcher3.util.rule.InstallerSessionRule; +import com.android.launcher3.util.rule.LayoutProviderRule; import com.android.launcher3.util.rule.TestStabilityRule; -import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -65,21 +68,19 @@ import java.util.List; public class CacheDataUpdatedTaskTest { @Rule public TestRule testStabilityRule = new TestStabilityRule(); + @Rule public SandboxApplication mContext = new SandboxApplication(); + @Rule public LayoutProviderRule mLayoutProvider = new LayoutProviderRule(mContext); + @Rule public InstallerSessionRule mInstallerSessionRule = new InstallerSessionRule(); private static final String PENDING_APP_1 = TEST_PACKAGE + ".pending1"; private static final String PENDING_APP_2 = TEST_PACKAGE + ".pending2"; - private LauncherModelHelper mModelHelper; - private Context mContext; - private int mSession1; @Before public void setup() throws Exception { - mModelHelper = new LauncherModelHelper(); - mContext = mModelHelper.sandboxContext; - mSession1 = mModelHelper.createInstallerSession(PENDING_APP_1); - mModelHelper.createInstallerSession(PENDING_APP_2); + mSession1 = mInstallerSessionRule.createInstallerSession(PENDING_APP_1); + mInstallerSessionRule.createInstallerSession(PENDING_APP_2); LauncherLayoutBuilder builder = new LauncherLayoutBuilder() .atHotseat(1).putFolder("MyFolder") @@ -97,14 +98,9 @@ public class CacheDataUpdatedTaskTest { .addApp(PENDING_APP_2, TEST_ACTIVITY2) // 9 .addApp(PENDING_APP_2, TEST_ACTIVITY3) // 10 .build(); - mModelHelper.setupDefaultLayoutProvider(builder); - mModelHelper.loadModelSync(); - assertEquals(10, mModelHelper.getBgDataModel().itemsIdMap.size()); - } - - @After - public void tearDown() { - mModelHelper.destroy(); + mLayoutProvider.setupDefaultLayoutProvider(builder); + ModelTestExtensions.INSTANCE.loadModelSync(getModel()); + assertEquals(10, getBgDataModel(getModel()).itemsIdMap.size()); } private CacheDataUpdatedTask newTask(int op, String... pkg) { @@ -119,7 +115,7 @@ public class CacheDataUpdatedTaskTest { // Clear all icons from apps list so that its easy to check what was updated allItems().forEach(wi -> wi.bitmap = BitmapInfo.LOW_RES_INFO); - mModelHelper.getModel().enqueueModelUpdateTask( + getModel().enqueueModelUpdateTask( newTask(CacheDataUpdatedTask.OP_CACHE_UPDATE, TEST_PACKAGE)); // Verify that only the app icons of TEST_PACKAGE (id 2, 3, 4) are updated. @@ -134,7 +130,7 @@ public class CacheDataUpdatedTaskTest { // Clear all icons from apps list so that its easy to check what was updated allItems().forEach(wi -> wi.bitmap = BitmapInfo.LOW_RES_INFO); - mModelHelper.getModel().enqueueModelUpdateTask( + getModel().enqueueModelUpdateTask( newTask(CacheDataUpdatedTask.OP_SESSION_UPDATE, TEST_PACKAGE)); // TEST_PACKAGE has no restored shortcuts. Verify that nothing was updated. @@ -156,7 +152,7 @@ public class CacheDataUpdatedTaskTest { // Clear all icons from apps list so that its easy to check what was updated allItems().forEach(wi -> wi.bitmap = BitmapInfo.LOW_RES_INFO); - mModelHelper.getModel().enqueueModelUpdateTask( + getModel().enqueueModelUpdateTask( newTask(CacheDataUpdatedTask.OP_SESSION_UPDATE, PENDING_APP_1)); // Only restored apps from PENDING_APP_1 (id 5, 6, 7) are updated @@ -176,6 +172,10 @@ public class CacheDataUpdatedTaskTest { } private List allItems() { - return ((FolderInfo) mModelHelper.getBgDataModel().itemsIdMap.get(1)).getAppContents(); + return ((FolderInfo) getBgDataModel(getModel()).itemsIdMap.get(1)).getAppContents(); + } + + private LauncherModel getModel() { + return LauncherAppState.getInstance(mContext).getModel(); } } diff --git a/tests/multivalentTests/src/com/android/launcher3/model/DefaultLayoutProviderTest.java b/tests/multivalentTests/src/com/android/launcher3/model/DefaultLayoutProviderTest.java index 0ae4d00e94..46e547485e 100644 --- a/tests/multivalentTests/src/com/android/launcher3/model/DefaultLayoutProviderTest.java +++ b/tests/multivalentTests/src/com/android/launcher3/model/DefaultLayoutProviderTest.java @@ -20,6 +20,7 @@ import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT; import static com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY; import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE; +import static com.android.launcher3.util.ModelTestExtensions.getBgDataModel; import static org.junit.Assert.assertEquals; import static org.junit.Assume.assumeTrue; @@ -32,15 +33,18 @@ import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.util.LauncherLayoutBuilder; -import com.android.launcher3.util.LauncherModelHelper; +import com.android.launcher3.util.ModelTestExtensions; +import com.android.launcher3.util.SandboxApplication; +import com.android.launcher3.util.rule.LayoutProviderRule; -import org.junit.After; -import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -53,23 +57,11 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class DefaultLayoutProviderTest { - private LauncherModelHelper mModelHelper; - private LauncherModelHelper.SandboxModelContext mTargetContext; - - @Before - public void setUp() { - mModelHelper = new LauncherModelHelper(); - mTargetContext = mModelHelper.sandboxContext; - } - - @After - public void tearDown() { - mModelHelper.destroy(); - } + @Rule public SandboxApplication mTargetContext = new SandboxApplication().withModelDependency(); + @Rule public LayoutProviderRule mLayoutProvider = new LayoutProviderRule(mTargetContext); private List getWorkspaceItems() { - return mModelHelper - .getBgDataModel() + return getBgDataModel(getModel()) .itemsIdMap .stream() .filter(i -> i.container == CONTAINER_DESKTOP || i.container == CONTAINER_HOTSEAT) @@ -177,6 +169,11 @@ public class DefaultLayoutProviderTest { } private void writeLayoutAndLoad(LauncherLayoutBuilder builder) throws Exception { - mModelHelper.setupDefaultLayoutProvider(builder).loadModelSync(); + mLayoutProvider.setupDefaultLayoutProvider(builder); + ModelTestExtensions.INSTANCE.loadModelSync(getModel()); + } + + private LauncherModel getModel() { + return LauncherAppState.getInstance(mTargetContext).getModel(); } } diff --git a/tests/multivalentTests/src/com/android/launcher3/model/FolderIconLoadTest.kt b/tests/multivalentTests/src/com/android/launcher3/model/FolderIconLoadTest.kt index f357487ae2..676c8a9a0e 100644 --- a/tests/multivalentTests/src/com/android/launcher3/model/FolderIconLoadTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/model/FolderIconLoadTest.kt @@ -17,6 +17,7 @@ package com.android.launcher3.model import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.launcher3.InvariantDeviceProfile import com.android.launcher3.LauncherAppState import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_FOLDER import com.android.launcher3.icons.BitmapInfo @@ -25,13 +26,16 @@ import com.android.launcher3.model.data.FolderInfo import com.android.launcher3.model.data.WorkspaceItemInfo import com.android.launcher3.util.Executors import com.android.launcher3.util.LauncherLayoutBuilder -import com.android.launcher3.util.LauncherModelHelper import com.android.launcher3.util.LauncherModelHelper.* +import com.android.launcher3.util.ModelTestExtensions.bgDataModel +import com.android.launcher3.util.ModelTestExtensions.loadModelSync +import com.android.launcher3.util.SandboxApplication import com.android.launcher3.util.TestUtil +import com.android.launcher3.util.rule.LayoutProviderRule import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import org.junit.After -import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -40,7 +44,8 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class FolderIconLoadTest { - private lateinit var modelHelper: LauncherModelHelper + @get:Rule val context = SandboxApplication() + @get:Rule val layoutProvider = LayoutProviderRule(context) private val uniqueActivities = listOf( @@ -60,15 +65,11 @@ class FolderIconLoadTest { TEST_ACTIVITY14, ) - @Before - fun setUp() { - modelHelper = LauncherModelHelper() - } + fun getIdp() = InvariantDeviceProfile.INSTANCE.get(context) @After @Throws(Exception::class) fun tearDown() { - modelHelper.destroy() TestUtil.uninstallDummyApp() } @@ -92,7 +93,7 @@ class FolderIconLoadTest { @Test @Throws(Exception::class) fun folderLoadedWithHighRes_max_3x3() { - val idp = LauncherAppState.getIDP(modelHelper.sandboxContext) + val idp = getIdp() idp.numFolderColumns = intArrayOf(3, 3, 3, 3) idp.numFolderRows = intArrayOf(3, 3, 3, 3) recreateSupportedDeviceProfiles() @@ -105,7 +106,7 @@ class FolderIconLoadTest { @Test @Throws(Exception::class) fun folderLoadedWithHighRes_max_4x4() { - val idp = LauncherAppState.getIDP(modelHelper.sandboxContext) + val idp = getIdp() idp.numFolderColumns = intArrayOf(4, 4, 4, 4) idp.numFolderRows = intArrayOf(4, 4, 4, 4) recreateSupportedDeviceProfiles() @@ -118,7 +119,7 @@ class FolderIconLoadTest { @Test @Throws(Exception::class) fun folderLoadedWithHighRes_differentFolderConfigurations() { - val idp = LauncherAppState.getIDP(modelHelper.sandboxContext) + val idp = getIdp() idp.numFolderColumns = intArrayOf(4, 3, 4, 4) idp.numFolderRows = intArrayOf(4, 3, 4, 4) recreateSupportedDeviceProfiles() @@ -130,6 +131,8 @@ class FolderIconLoadTest { @Throws(Exception::class) private fun setupAndLoadFolder(itemCount: Int): ArrayList { + val app = LauncherAppState.getInstance(context) + val builder = LauncherLayoutBuilder() .atWorkspace(0, 0, 1) @@ -139,20 +142,19 @@ class FolderIconLoadTest { } .build() - modelHelper.setupDefaultLayoutProvider(builder) - modelHelper.loadModelSync() + layoutProvider.setupDefaultLayoutProvider(builder) + app.model.loadModelSync() // The first load initializes the DB, load again so that icons are now used from the DB // Wait for the icon cache to be updated and then reload - val app = LauncherAppState.getInstance(modelHelper.sandboxContext) app.iconCache.waitForUpdateHandlerToFinish() TestUtil.runOnExecutorSync(Executors.MODEL_EXECUTOR) { app.iconCache.clearMemoryCache() } // Reload again with correct icon state app.model.forceReload() - modelHelper.loadModelSync() + app.model.loadModelSync() val collections = - modelHelper.bgDataModel.itemsIdMap + app.model.bgDataModel.itemsIdMap .filter { it.itemType == ITEM_TYPE_FOLDER } .map { it as FolderInfo } assertThat(collections.size).isEqualTo(1) @@ -183,15 +185,10 @@ class FolderIconLoadTest { } private fun isDefaultIcon(bitmap: BitmapInfo) = - LauncherAppState.getInstance(modelHelper.sandboxContext) - .iconCache - .isDefaultIcon(bitmap, modelHelper.sandboxContext.user) + LauncherAppState.getInstance(context).iconCache.isDefaultIcon(bitmap, context.user) /** Recreate DeviceProfiles after changing InvariantDeviceProfile */ private fun recreateSupportedDeviceProfiles() { - LauncherAppState.getIDP(modelHelper.sandboxContext).supportedProfiles = - LauncherAppState.getIDP(modelHelper.sandboxContext).supportedProfiles.map { - it.copy(modelHelper.sandboxContext) - } + getIdp().supportedProfiles = getIdp().supportedProfiles.map { it.copy(context) } } } diff --git a/tests/multivalentTests/src/com/android/launcher3/model/GridSizeMigrationTest.kt b/tests/multivalentTests/src/com/android/launcher3/model/GridSizeMigrationTest.kt index 5607bb4641..f3ebf7d547 100644 --- a/tests/multivalentTests/src/com/android/launcher3/model/GridSizeMigrationTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/model/GridSizeMigrationTest.kt @@ -16,7 +16,6 @@ package com.android.launcher3.model import android.content.ContentValues -import android.content.Context import android.content.Intent import android.database.Cursor import android.database.sqlite.SQLiteDatabase @@ -34,10 +33,11 @@ import com.android.launcher3.LauncherSettings.Favorites.* import com.android.launcher3.model.GridSizeMigrationDBController.DbReader import com.android.launcher3.pm.UserCache import com.android.launcher3.provider.LauncherDbUtils -import com.android.launcher3.util.LauncherModelHelper +import com.android.launcher3.util.SandboxApplication import com.google.common.truth.Truth.assertThat import org.junit.After import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -46,8 +46,8 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class GridSizeMigrationTest { - private lateinit var modelHelper: LauncherModelHelper - private lateinit var context: Context + @get:Rule val context = SandboxApplication().withModelDependency() + private lateinit var idp: InvariantDeviceProfile private lateinit var dbHelper: DatabaseHelper private lateinit var db: SQLiteDatabase @@ -64,8 +64,6 @@ class GridSizeMigrationTest { @Before fun setUp() { - modelHelper = LauncherModelHelper() - context = modelHelper.sandboxContext dbHelper = DatabaseHelper( context, @@ -83,7 +81,6 @@ class GridSizeMigrationTest { @After fun tearDown() { db.close() - modelHelper.destroy() } @Test diff --git a/tests/multivalentTests/src/com/android/launcher3/model/LoaderCursorTest.java b/tests/multivalentTests/src/com/android/launcher3/model/LoaderCursorTest.java index d1292cf0aa..7790886a6e 100644 --- a/tests/multivalentTests/src/com/android/launcher3/model/LoaderCursorTest.java +++ b/tests/multivalentTests/src/com/android/launcher3/model/LoaderCursorTest.java @@ -76,9 +76,8 @@ import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.util.Executors; -import com.android.launcher3.util.LauncherModelHelper; -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext; import com.android.launcher3.util.PackageManagerHelper; +import com.android.launcher3.util.SandboxApplication; import org.junit.After; import org.junit.Before; @@ -96,13 +95,14 @@ public class LoaderCursorTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT); - private LauncherModelHelper mModelHelper; + @Rule + public final SandboxApplication mContext = new SandboxApplication(); + private LauncherAppState mApp; private LauncherPrefs mPrefs; private MatrixCursor mCursor; private InvariantDeviceProfile mIDP; - private SandboxModelContext mContext; private LoaderCursor mLoaderCursor; @@ -114,8 +114,6 @@ public class LoaderCursorTest { @Before public void setup() { - mModelHelper = new LauncherModelHelper(); - mContext = mModelHelper.sandboxContext; mPrefs = LauncherPrefs.get(mContext); mIDP = InvariantDeviceProfile.INSTANCE.get(mContext); mApp = LauncherAppState.getInstance(mContext); @@ -137,7 +135,6 @@ public class LoaderCursorTest { public void tearDown() { mPrefs.putSync(IS_FIRST_LOAD_AFTER_RESTORE.to(false)); mCursor.close(); - mModelHelper.destroy(); } private void initCursor(int itemType, String title) { diff --git a/tests/multivalentTests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java b/tests/multivalentTests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java index 0f1fc00b9b..7c4b361717 100644 --- a/tests/multivalentTests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java +++ b/tests/multivalentTests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java @@ -20,6 +20,7 @@ import static com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY; import static com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY2; import static com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY3; import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE; +import static com.android.launcher3.util.ModelTestExtensions.getBgDataModel; import static com.android.launcher3.util.TestUtil.runOnExecutorSync; import static org.junit.Assert.assertEquals; @@ -27,16 +28,21 @@ import static org.junit.Assert.assertEquals; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherModel; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.pm.PackageInstallInfo; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.LauncherLayoutBuilder; -import com.android.launcher3.util.LauncherModelHelper; +import com.android.launcher3.util.ModelTestExtensions; +import com.android.launcher3.util.SandboxApplication; +import com.android.launcher3.util.rule.InstallerSessionRule; +import com.android.launcher3.util.rule.LayoutProviderRule; -import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -50,14 +56,16 @@ public class PackageInstallStateChangedTaskTest { private static final String PENDING_APP_1 = TEST_PACKAGE + ".pending1"; private static final String PENDING_APP_2 = TEST_PACKAGE + ".pending2"; - private LauncherModelHelper mModelHelper; + @Rule public SandboxApplication mContext = new SandboxApplication(); + @Rule public LayoutProviderRule mLayoutProvider = new LayoutProviderRule(mContext); + @Rule public InstallerSessionRule mInstallerSessionRule = new InstallerSessionRule(); + private IntSet mDownloadingApps; @Before public void setup() throws Exception { - mModelHelper = new LauncherModelHelper(); - mModelHelper.createInstallerSession(PENDING_APP_1); - mModelHelper.createInstallerSession(PENDING_APP_2); + mInstallerSessionRule.createInstallerSession(PENDING_APP_1); + mInstallerSessionRule.createInstallerSession(PENDING_APP_2); LauncherLayoutBuilder builder = new LauncherLayoutBuilder() .atWorkspace(0, 0, 1).putApp(TEST_PACKAGE, TEST_ACTIVITY) // 1 @@ -74,14 +82,9 @@ public class PackageInstallStateChangedTaskTest { .atWorkspace(0, 0, 10).putApp(PENDING_APP_2, TEST_ACTIVITY3); // 10 mDownloadingApps = IntSet.wrap(4, 5, 6, 7, 8, 9, 10); - mModelHelper.setupDefaultLayoutProvider(builder); - mModelHelper.loadModelSync(); - assertEquals(10, mModelHelper.getBgDataModel().itemsIdMap.size()); - } - - @After - public void tearDown() { - mModelHelper.destroy(); + mLayoutProvider.setupDefaultLayoutProvider(builder); + ModelTestExtensions.INSTANCE.loadModelSync(getModel()); + assertEquals(10, getBgDataModel(getModel()).itemsIdMap.size()); } private PackageInstallStateChangedTask newTask(String pkg, int progress) { @@ -95,7 +98,7 @@ public class PackageInstallStateChangedTaskTest { public void testSessionUpdate_ignore_installed() { // Run on model executor so that no other task runs in the middle. runOnExecutorSync(MODEL_EXECUTOR, () -> { - mModelHelper.getModel().enqueueModelUpdateTask(newTask(TEST_PACKAGE, 30)); + getModel().enqueueModelUpdateTask(newTask(TEST_PACKAGE, 30)); // No shortcuts were updated verifyProgressUpdate(0); @@ -106,7 +109,7 @@ public class PackageInstallStateChangedTaskTest { public void testSessionUpdate_shortcuts_updated() { // Run on model executor so that no other task runs in the middle. runOnExecutorSync(MODEL_EXECUTOR, () -> { - mModelHelper.getModel().enqueueModelUpdateTask(newTask(PENDING_APP_1, 30)); + getModel().enqueueModelUpdateTask(newTask(PENDING_APP_1, 30)); verifyProgressUpdate(30, 4, 5, 6, 7); }); @@ -116,7 +119,7 @@ public class PackageInstallStateChangedTaskTest { public void testSessionUpdate_widgets_updated() { // Run on model executor so that no other task runs in the middle. runOnExecutorSync(MODEL_EXECUTOR, () -> { - mModelHelper.getModel().enqueueModelUpdateTask(newTask(PENDING_APP_2, 30)); + getModel().enqueueModelUpdateTask(newTask(PENDING_APP_2, 30)); verifyProgressUpdate(30, 8, 9, 10); }); @@ -124,7 +127,7 @@ public class PackageInstallStateChangedTaskTest { private void verifyProgressUpdate(int progress, int... idsUpdated) { IntSet updates = IntSet.wrap(idsUpdated); - for (ItemInfo info : mModelHelper.getBgDataModel().itemsIdMap) { + for (ItemInfo info : getBgDataModel(getModel()).itemsIdMap) { int expectedProgress = updates.contains(info.id) ? progress : (mDownloadingApps.contains(info.id) ? 0 : 100); if (info instanceof WorkspaceItemInfo wi) { @@ -134,4 +137,8 @@ public class PackageInstallStateChangedTaskTest { } } } + + private LauncherModel getModel() { + return LauncherAppState.getInstance(mContext).getModel(); + } } diff --git a/tests/multivalentTests/src/com/android/launcher3/model/PackageUpdatedTaskTest.kt b/tests/multivalentTests/src/com/android/launcher3/model/PackageUpdatedTaskTest.kt index 5fd93d13ce..86f19ee9cf 100644 --- a/tests/multivalentTests/src/com/android/launcher3/model/PackageUpdatedTaskTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/model/PackageUpdatedTaskTest.kt @@ -42,12 +42,11 @@ import com.android.launcher3.model.data.AppInfo import com.android.launcher3.model.data.WorkspaceItemInfo import com.android.launcher3.util.AllModulesForTest import com.android.launcher3.util.Executors -import com.android.launcher3.util.LauncherModelHelper +import com.android.launcher3.util.SandboxApplication import com.android.launcher3.util.TestUtil import com.google.common.truth.Truth.assertThat import dagger.BindsInstance import dagger.Component -import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test @@ -63,10 +62,9 @@ import org.mockito.kotlin.whenever class PackageUpdatedTaskTest { @get:Rule val setFlagsRule = SetFlagsRule() + @get:Rule val mContext = SandboxApplication() private val mUser = myUserHandle() - private val mLauncherModelHelper = LauncherModelHelper() - private val mContext = mLauncherModelHelper.sandboxContext private val expectedPackage = "Test.Package" private val expectedComponent = ComponentName(expectedPackage, "TestClass") @@ -121,11 +119,6 @@ class PackageUpdatedTaskTest { } } - @After - fun tearDown() { - mLauncherModelHelper.destroy() - } - @Test fun `OP_ADD triggers model callbacks and adds new items to AllAppsList`() { // Given diff --git a/tests/multivalentTests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt b/tests/multivalentTests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt index cba7b88890..09deb59905 100644 --- a/tests/multivalentTests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt @@ -54,10 +54,9 @@ import com.android.launcher3.pm.UserCache import com.android.launcher3.shortcuts.ShortcutKey import com.android.launcher3.util.ComponentKey import com.android.launcher3.util.ContentWriter -import com.android.launcher3.util.LauncherModelHelper -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext import com.android.launcher3.util.PackageManagerHelper import com.android.launcher3.util.PackageUserKey +import com.android.launcher3.util.SandboxApplication import com.android.launcher3.util.UserIconInfo import com.android.launcher3.widget.LauncherAppWidgetProviderInfo import com.android.launcher3.widget.WidgetInflater @@ -87,6 +86,7 @@ import org.mockito.kotlin.whenever class WorkspaceItemProcessorTest { @get:Rule val setFlagsRule: SetFlagsRule = SetFlagsRule() + @get:Rule val mContext = SandboxApplication() @Mock private lateinit var mockIconRequestInfo: IconRequestInfo @Mock private lateinit var mockWorkspaceInfo: WorkspaceItemInfo @@ -98,8 +98,6 @@ class WorkspaceItemProcessorTest { @Mock private lateinit var mockWidgetInflater: WidgetInflater @Mock private lateinit var mockIconCache: IconCache - lateinit var mModelHelper: LauncherModelHelper - lateinit var mContext: SandboxModelContext lateinit var mLauncherApps: LauncherApps private var mIntent: Intent = Intent() private var mUserHandle: UserHandle = Process.myUserHandle() @@ -118,8 +116,6 @@ class WorkspaceItemProcessorTest { @Before fun setup() { MockitoAnnotations.initMocks(this) - mModelHelper = LauncherModelHelper() - mContext = mModelHelper.sandboxContext mLauncherApps = mContext.spyService(LauncherApps::class.java).apply { doReturn(true).whenever(this).isPackageEnabled("package", mUserHandle) diff --git a/tests/multivalentTests/src/com/android/launcher3/model/WorkspaceItemSpaceFinderTest.kt b/tests/multivalentTests/src/com/android/launcher3/model/WorkspaceItemSpaceFinderTest.kt index a18f93b9dc..624db5b19f 100644 --- a/tests/multivalentTests/src/com/android/launcher3/model/WorkspaceItemSpaceFinderTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/model/WorkspaceItemSpaceFinderTest.kt @@ -18,8 +18,8 @@ package com.android.launcher3.model import android.graphics.Rect import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.launcher3.util.ModelTestExtensions.bgDataModel import com.google.common.truth.Truth.assertThat -import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -34,17 +34,8 @@ class WorkspaceItemSpaceFinderTest : AbstractWorkspaceModelTest() { super.setup() } - @After - override fun tearDown() { - super.tearDown() - } - private fun findSpace(spanX: Int, spanY: Int): NewItemSpace = - WorkspaceItemSpaceFinder( - mModelHelper.bgDataModel, - mAppState.invariantDeviceProfile, - mModelHelper.model, - ) + WorkspaceItemSpaceFinder(model.bgDataModel, mAppState.invariantDeviceProfile, model) .findSpaceForItem(mExistingScreens, mNewScreens, spanX, spanY) .let { NewItemSpace.fromIntArray(it) } diff --git a/tests/multivalentTests/src/com/android/launcher3/model/data/ItemInfoWithIconTest.kt b/tests/multivalentTests/src/com/android/launcher3/model/data/ItemInfoWithIconTest.kt index cfbde98eee..304e72f163 100644 --- a/tests/multivalentTests/src/com/android/launcher3/model/data/ItemInfoWithIconTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/model/data/ItemInfoWithIconTest.kt @@ -19,10 +19,10 @@ package com.android.launcher3.model.data import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.launcher3.pm.PackageInstallInfo -import com.android.launcher3.util.LauncherModelHelper +import com.android.launcher3.util.SandboxApplication import com.google.common.truth.Truth -import org.junit.After import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -30,7 +30,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class ItemInfoWithIconTest { - private var context = LauncherModelHelper.SandboxModelContext() + @get:Rule var context = SandboxApplication() private lateinit var itemInfoWithIcon: ItemInfoWithIcon @Before @@ -43,11 +43,6 @@ class ItemInfoWithIconTest { } } - @After - fun tearDown() { - context.destroy() - } - @Test fun itemInfoWithIconDefaultParamsTest() { Truth.assertThat(itemInfoWithIcon.isDisabled).isFalse() diff --git a/tests/multivalentTests/src/com/android/launcher3/pm/InstallSessionTrackerTest.kt b/tests/multivalentTests/src/com/android/launcher3/pm/InstallSessionTrackerTest.kt index 23c1da98c5..81d327ee0d 100644 --- a/tests/multivalentTests/src/com/android/launcher3/pm/InstallSessionTrackerTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/pm/InstallSessionTrackerTest.kt @@ -27,9 +27,8 @@ import androidx.test.filters.SdkSuppress import androidx.test.filters.SmallTest import com.android.launcher3.Flags.FLAG_ENABLE_SUPPORT_FOR_ARCHIVING import com.android.launcher3.util.Executors.MODEL_EXECUTOR -import com.android.launcher3.util.LauncherModelHelper import com.android.launcher3.util.PackageUserKey -import org.junit.After +import com.android.launcher3.util.SandboxApplication import org.junit.Before import org.junit.Rule import org.junit.Test @@ -45,14 +44,12 @@ import org.mockito.kotlin.whenever @RunWith(AndroidJUnit4::class) class InstallSessionTrackerTest { @get:Rule val setFlagsRule = SetFlagsRule() + @get:Rule val sandboxContext = SandboxApplication() private val mockInstallSessionHelper: InstallSessionHelper = mock() private val mockCallback: InstallSessionTracker.Callback = mock() private val mockPackageInstaller: PackageInstaller = mock() - private val launcherModelHelper = LauncherModelHelper() - private val sandboxContext = launcherModelHelper.sandboxContext - lateinit var launcherApps: LauncherApps lateinit var installSessionTracker: InstallSessionTracker @@ -68,11 +65,6 @@ class InstallSessionTrackerTest { ) } - @After - fun teardown() { - launcherModelHelper.destroy() - } - @Test fun `onCreated triggers callbacks for setting up new install session`() { // Given diff --git a/tests/multivalentTests/src/com/android/launcher3/pm/UserCacheTest.kt b/tests/multivalentTests/src/com/android/launcher3/pm/UserCacheTest.kt index 5f08c31f35..ac042cef9f 100644 --- a/tests/multivalentTests/src/com/android/launcher3/pm/UserCacheTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/pm/UserCacheTest.kt @@ -21,31 +21,20 @@ import android.os.UserHandle import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import com.android.launcher3.util.Executors.MODEL_EXECUTOR -import com.android.launcher3.util.LauncherModelHelper +import com.android.launcher3.util.SandboxApplication import com.android.launcher3.util.TestUtil import com.android.launcher3.util.UserIconInfo import com.google.common.truth.Truth.assertThat -import org.junit.After -import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class UserCacheTest { - private val launcherModelHelper = LauncherModelHelper() - private val sandboxContext = launcherModelHelper.sandboxContext - private lateinit var userCache: UserCache + @get:Rule val sandboxContext = SandboxApplication() - @Before - fun setup() { - userCache = UserCache.getInstance(sandboxContext) - } - - @After - fun teardown() { - launcherModelHelper.destroy() - } + private val userCache: UserCache by lazy { UserCache.getInstance(sandboxContext) } @Test fun `getBadgeDrawable only returns a UserBadgeDrawable given a user in the cache`() { diff --git a/tests/multivalentTests/src/com/android/launcher3/provider/RestoreDbTaskTest.java b/tests/multivalentTests/src/com/android/launcher3/provider/RestoreDbTaskTest.java index 0f4940e7ed..72310d27f7 100644 --- a/tests/multivalentTests/src/com/android/launcher3/provider/RestoreDbTaskTest.java +++ b/tests/multivalentTests/src/com/android/launcher3/provider/RestoreDbTaskTest.java @@ -63,14 +63,14 @@ import com.android.launcher3.model.ModelDbController; import com.android.launcher3.pm.UserCache; import com.android.launcher3.util.AllModulesForTest; import com.android.launcher3.util.IntArray; -import com.android.launcher3.util.LauncherModelHelper; -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext; +import com.android.launcher3.util.SandboxApplication; import dagger.BindsInstance; import dagger.Component; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; @@ -89,8 +89,9 @@ public class RestoreDbTaskTest { private final UserHandle mWorkUser = UserHandle.getUserHandleForUid(PER_USER_RANGE); - private LauncherModelHelper mModelHelper; - private SandboxModelContext mContext; + @Rule + public final SandboxApplication mContext = new SandboxApplication(); + private UserCache mUserCacheSpy; private RestoreDbTask mTask; @@ -105,8 +106,6 @@ public class RestoreDbTaskTest { @Before public void setup() { - mModelHelper = new LauncherModelHelper(); - mContext = mModelHelper.sandboxContext; mUserCacheSpy = spy(UserCache.getInstance(getInstrumentation().getTargetContext())); mContext.initDaggerComponent( @@ -135,7 +134,6 @@ public class RestoreDbTaskTest { if (mWidgetHost != null) { mWidgetHost.deleteHost(); } - mModelHelper.destroy(); LauncherPrefs.get(mContext).removeSync(RESTORE_DEVICE); } diff --git a/tests/multivalentTests/src/com/android/launcher3/ui/BubbleTextViewTest.java b/tests/multivalentTests/src/com/android/launcher3/ui/BubbleTextViewTest.java index 5c326f98c7..e72b9e2005 100644 --- a/tests/multivalentTests/src/com/android/launcher3/ui/BubbleTextViewTest.java +++ b/tests/multivalentTests/src/com/android/launcher3/ui/BubbleTextViewTest.java @@ -69,11 +69,10 @@ import com.android.launcher3.search.StringMatcherUtility; import com.android.launcher3.util.ActivityContextWrapper; import com.android.launcher3.util.FlagOp; import com.android.launcher3.util.IntArray; -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext; +import com.android.launcher3.util.SandboxApplication; import com.android.launcher3.util.TestUtil; import com.android.launcher3.views.BaseDragLayer; -import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -119,7 +118,7 @@ public class BubbleTextViewTest { private static final float SPACE_MULTIPLIER = 1; private static final float SPACE_EXTRA = 0; - private SandboxModelContext mModelContext; + @Rule public SandboxApplication mModelContext = new SandboxApplication(); private BubbleTextView mBubbleTextView; private ItemInfoWithIcon mItemInfoWithIcon; @@ -131,7 +130,6 @@ public class BubbleTextViewTest { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); Utilities.enableRunningInTestHarnessForTests(); - mModelContext = new SandboxModelContext(); LauncherPrefs.get(mModelContext).put(ENABLE_TWOLINE_ALLAPPS_TOGGLE, true); mContext = new ActivityContextWrapper(mModelContext); @@ -160,11 +158,6 @@ public class BubbleTextViewTest { mGmailAppInfo = new AppInfo(componentName, "Gmail", WORK_HANDLE, new Intent()); } - @After - public void tearDown() { - mModelContext.onDestroy(); - } - @Test @EnableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE) public void testEmptyString_flagOn() { diff --git a/tests/multivalentTests/src/com/android/launcher3/util/DaggerSingletonDeadlockTest.kt b/tests/multivalentTests/src/com/android/launcher3/util/DaggerSingletonDeadlockTest.kt index 642c6283be..8e43b6eaf4 100644 --- a/tests/multivalentTests/src/com/android/launcher3/util/DaggerSingletonDeadlockTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/util/DaggerSingletonDeadlockTest.kt @@ -18,12 +18,11 @@ package com.android.launcher3.util import androidx.test.filters.SmallTest import com.android.launcher3.dagger.LauncherAppComponent -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext import java.util.concurrent.TimeUnit.SECONDS import kotlin.reflect.KFunction import kotlin.reflect.full.memberFunctions -import org.junit.After import org.junit.Assert +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import platform.test.runner.parameterized.ParameterizedAndroidJunit4 @@ -33,12 +32,7 @@ import platform.test.runner.parameterized.Parameters @RunWith(ParameterizedAndroidJunit4::class) class DaggerSingletonDeadlockTest(val method: KFunction<*>, val methodName: String) { - private val context = SandboxModelContext() - - @After - fun tearDown() { - context.onDestroy() - } + @get:Rule val context = SandboxApplication() /** Test to verify that the object can be created successfully on the main thread. */ @Test diff --git a/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt b/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt index 0ecb38eb0f..1d8761b0ea 100644 --- a/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/util/DisplayControllerTest.kt @@ -37,7 +37,6 @@ import com.android.launcher3.util.DisplayController.CHANGE_ROTATION import com.android.launcher3.util.DisplayController.CHANGE_SHOW_LOCKED_TASKBAR import com.android.launcher3.util.DisplayController.CHANGE_TASKBAR_PINNING import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext import com.android.launcher3.util.window.CachedDisplayInfo import com.android.launcher3.util.window.WindowManagerProxy import dagger.BindsInstance @@ -47,6 +46,7 @@ import junit.framework.Assert.assertTrue import kotlin.math.min import org.junit.After import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.any @@ -65,7 +65,7 @@ import org.mockito.stubbing.Answer @RunWith(LauncherMultivalentJUnit::class) class DisplayControllerTest { - private val context = spy(SandboxModelContext()) + @get:Rule val context = spy(SandboxApplication()) private val windowManagerProxy: MyWmProxy = mock() private val launcherPrefs: LauncherPrefs = mock() private lateinit var displayManager: DisplayManager @@ -149,7 +149,6 @@ class DisplayControllerTest { // We need to reset the taskbar mode preference override even if a test throws an exception. // Otherwise, it may break the following tests' assumptions. DisplayController.enableTaskbarModePreferenceForTests(false) - context.onDestroy() } @Test @@ -203,7 +202,7 @@ class DisplayControllerTest { @UiThreadTest fun testTaskbarPinningChangeInLockedTaskbarChange() { whenever(windowManagerProxy.showLockedTaskbarOnHome(any())).thenReturn(true) - whenever(windowManagerProxy.isHomeVisible(any())).thenReturn(true) + whenever(windowManagerProxy.isHomeVisible()).thenReturn(true) whenever(windowManagerProxy.isInDesktopMode(any())).thenReturn(false) whenever(launcherPrefs.get(TASKBAR_PINNING)).thenReturn(false) DisplayController.enableTaskbarModePreferenceForTests(true) @@ -224,7 +223,7 @@ class DisplayControllerTest { @UiThreadTest fun testLockedTaskbarChangeOnConfigurationChanged() { whenever(windowManagerProxy.showLockedTaskbarOnHome(any())).thenReturn(true) - whenever(windowManagerProxy.isHomeVisible(any())).thenReturn(true) + whenever(windowManagerProxy.isHomeVisible()).thenReturn(true) whenever(windowManagerProxy.isInDesktopMode(any())).thenReturn(false) whenever(launcherPrefs.get(TASKBAR_PINNING)).thenReturn(false) DisplayController.enableTaskbarModePreferenceForTests(true) @@ -248,7 +247,7 @@ class DisplayControllerTest { whenever(launcherPrefs.get(TASKBAR_PINNING)).thenReturn(false) whenever(launcherPrefs.get(TASKBAR_PINNING_IN_DESKTOP_MODE)).thenReturn(false) whenever(windowManagerProxy.isInDesktopMode(any())).thenReturn(true) - whenever(windowManagerProxy.isHomeVisible(any())).thenReturn(false) + whenever(windowManagerProxy.isHomeVisible()).thenReturn(false) DisplayController.enableTaskbarModePreferenceForTests(true) assertTrue(displayController.getInfo().isTransientTaskbar()) @@ -267,7 +266,7 @@ class DisplayControllerTest { whenever(launcherPrefs.get(TASKBAR_PINNING)).thenReturn(false) whenever(launcherPrefs.get(TASKBAR_PINNING_IN_DESKTOP_MODE)).thenReturn(false) whenever(windowManagerProxy.isInDesktopMode(any())).thenReturn(false) - whenever(windowManagerProxy.isHomeVisible(any())).thenReturn(false) + whenever(windowManagerProxy.isHomeVisible()).thenReturn(false) DisplayController.enableTaskbarModePreferenceForTests(true) assertTrue(displayController.getInfo().isTransientTaskbar()) @@ -286,7 +285,7 @@ class DisplayControllerTest { whenever(launcherPrefs.get(TASKBAR_PINNING)).thenReturn(false) whenever(launcherPrefs.get(TASKBAR_PINNING_IN_DESKTOP_MODE)).thenReturn(false) whenever(windowManagerProxy.isInDesktopMode(any())).thenReturn(false) - whenever(windowManagerProxy.isHomeVisible(any())).thenReturn(true) + whenever(windowManagerProxy.isHomeVisible()).thenReturn(true) DisplayController.enableTaskbarModePreferenceForTests(true) assertTrue(displayController.getInfo().isTransientTaskbar()) diff --git a/tests/multivalentTests/src/com/android/launcher3/util/LauncherModelHelper.java b/tests/multivalentTests/src/com/android/launcher3/util/LauncherModelHelper.java index 4458e8fb01..08c8926e04 100644 --- a/tests/multivalentTests/src/com/android/launcher3/util/LauncherModelHelper.java +++ b/tests/multivalentTests/src/com/android/launcher3/util/LauncherModelHelper.java @@ -15,59 +15,10 @@ */ package com.android.launcher3.util; -import static android.content.pm.PackageInstaller.SessionParams.MODE_FULL_INSTALL; - import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; -import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; -import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; -import static com.android.launcher3.util.TestUtil.grantWriteSecurePermission; -import static com.android.launcher3.util.TestUtil.runOnExecutorSync; - -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; - -import android.content.ContentProvider; -import android.content.ContentResolver; -import android.content.Context; -import android.content.pm.PackageInstaller; -import android.content.pm.PackageInstaller.SessionParams; -import android.content.pm.PackageManager; -import android.content.pm.ProviderInfo; -import android.graphics.Bitmap; -import android.graphics.Bitmap.Config; -import android.graphics.Color; -import android.net.Uri; -import android.os.ParcelFileDescriptor; -import android.os.ParcelFileDescriptor.AutoCloseOutputStream; -import android.provider.Settings; -import android.test.mock.MockContentResolver; -import android.util.ArrayMap; - -import androidx.test.core.app.ApplicationProvider; - -import com.android.launcher3.InvariantDeviceProfile; -import com.android.launcher3.LauncherAppState; -import com.android.launcher3.LauncherModel; -import com.android.launcher3.dagger.LauncherBaseAppComponent; -import com.android.launcher3.model.BgDataModel; -import com.android.launcher3.model.BgDataModel.Callbacks; -import com.android.launcher3.model.ModelDbController; -import com.android.launcher3.testing.TestInformationProvider; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStreamWriter; import java.util.Arrays; import java.util.List; -import java.util.UUID; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; /** * Utility class to help manage Launcher Model and related objects for test. @@ -106,238 +57,4 @@ public class LauncherModelHelper { TEST_ACTIVITY13, TEST_ACTIVITY14 ); - - // Authority for providing a test default-workspace-layout data. - private static final String TEST_PROVIDER_AUTHORITY = - LauncherModelHelper.class.getName().toLowerCase(); - private static final int DEFAULT_BITMAP_SIZE = 10; - private static final int DEFAULT_GRID_SIZE = 4; - - public final SandboxModelContext sandboxContext; - - private final RunnableList mDestroyTask = new RunnableList(); - - private BgDataModel mDataModel; - - public LauncherModelHelper() { - sandboxContext = new SandboxModelContext(); - } - - public void setupProvider(String authority, ContentProvider provider) { - sandboxContext.setupProvider(authority, provider); - } - - public LauncherModel getModel() { - return LauncherAppState.getInstance(sandboxContext).getModel(); - } - - public synchronized BgDataModel getBgDataModel() { - if (mDataModel == null) { - getModel().enqueueModelUpdateTask((taskController, dataModel, apps) -> - mDataModel = dataModel); - runOnExecutorSync(Executors.MODEL_EXECUTOR, () -> { }); - } - return mDataModel; - } - - /** - * Creates a installer session for the provided package. - */ - public int createInstallerSession(String pkg) throws IOException { - SessionParams sp = new SessionParams(MODE_FULL_INSTALL); - sp.setAppPackageName(pkg); - Bitmap icon = Bitmap.createBitmap(100, 100, Config.ARGB_8888); - icon.eraseColor(Color.RED); - sp.setAppIcon(icon); - sp.setAppLabel(pkg); - sp.setInstallerPackageName(ApplicationProvider.getApplicationContext().getPackageName()); - PackageInstaller pi = ApplicationProvider.getApplicationContext().getPackageManager() - .getPackageInstaller(); - int sessionId = pi.createSession(sp); - mDestroyTask.add(() -> pi.abandonSession(sessionId)); - return sessionId; - } - - public void destroy() { - // When destroying the context, make sure that the model thread is blocked, so that no - // new jobs get posted while we are cleaning up - CountDownLatch l1 = new CountDownLatch(1); - CountDownLatch l2 = new CountDownLatch(1); - MODEL_EXECUTOR.execute(() -> { - l1.countDown(); - waitOrThrow(l2); - }); - waitOrThrow(l1); - sandboxContext.onDestroy(); - l2.countDown(); - - mDestroyTask.executeAllAndDestroy(); - } - - private void waitOrThrow(CountDownLatch latch) { - try { - latch.await(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Sets up a mock provider to load the provided layout by default, next time the layout loads - */ - public LauncherModelHelper setupDefaultLayoutProvider(LauncherLayoutBuilder builder) - throws Exception { - grantWriteSecurePermission(); - - InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(sandboxContext); - if (idp.numRows == 0 && idp.numColumns == 0) { - idp.numRows = idp.numColumns = idp.numDatabaseHotseatIcons = DEFAULT_GRID_SIZE; - } - if (idp.iconBitmapSize == 0) { - idp.iconBitmapSize = DEFAULT_BITMAP_SIZE; - } - - Settings.Secure.putString(sandboxContext.getContentResolver(), "launcher3.layout.provider", - TEST_PROVIDER_AUTHORITY); - - // TODO: use a wrapper class to differentiate the behavior - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - builder.build(new OutputStreamWriter(bos)); - ContentProvider cp = new TestInformationProvider() { - - @Override - public ParcelFileDescriptor openFile(Uri uri, String mode) - throws FileNotFoundException { - try { - ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); - AutoCloseOutputStream outputStream = new AutoCloseOutputStream(pipe[1]); - outputStream.write(bos.toByteArray()); - outputStream.flush(); - outputStream.close(); - return pipe[0]; - } catch (Exception e) { - throw new FileNotFoundException(e.getMessage()); - } - } - }; - setupProvider(TEST_PROVIDER_AUTHORITY, cp); - RoboApiWrapper.INSTANCE.registerInputStream(sandboxContext.getContentResolver(), - ModelDbController.getLayoutUri(TEST_PROVIDER_AUTHORITY, sandboxContext), - ()-> new ByteArrayInputStream(bos.toByteArray())); - - mDestroyTask.add(() -> runOnExecutorSync(MODEL_EXECUTOR, () -> - Settings.Secure.putString(sandboxContext.getContentResolver(), - "launcher3.layout.provider", ""))); - return this; - } - - /** - * Loads the model in memory synchronously - */ - public void loadModelSync() throws ExecutionException, InterruptedException { - Callbacks mockCb = new Callbacks() { }; - MAIN_EXECUTOR.submit(() -> getModel().addCallbacksAndLoad(mockCb)).get(); - - Executors.MODEL_EXECUTOR.submit(() -> { }).get(); - getInstrumentation().waitForIdleSync(); - MAIN_EXECUTOR.submit(() -> getModel().removeCallbacks(mockCb)).get(); - } - - public static class SandboxModelContext extends SandboxContext { - - private final MockContentResolver mMockResolver = new MockContentResolver(); - private final ArrayMap mSpiedServices = new ArrayMap<>(); - private final PackageManager mPm; - private final File mDbDir; - - public SandboxModelContext() { - this(ApplicationProvider.getApplicationContext()); - } - - public SandboxModelContext(Context context) { - super(context); - - // System settings cache content provider. Ensure that they are statically initialized - Settings.Secure.getString(context.getContentResolver(), "test"); - Settings.System.getString(context.getContentResolver(), "test"); - Settings.Global.getString(context.getContentResolver(), "test"); - - mPm = spy(getBaseContext().getPackageManager()); - mDbDir = new File(getCacheDir(), UUID.randomUUID().toString()); - } - - @Override - public File getDatabasePath(String name) { - if (!mDbDir.exists()) { - mDbDir.mkdirs(); - } - return new File(mDbDir, name); - } - - @Override - public ContentResolver getContentResolver() { - return mMockResolver; - } - - @Override - protected void cleanUpObjects() { - if (deleteContents(mDbDir)) { - mDbDir.delete(); - } - super.cleanUpObjects(); - } - - @Override - public PackageManager getPackageManager() { - return mPm; - } - - @Override - public Object getSystemService(String name) { - Object service = mSpiedServices.get(name); - return service != null ? service : super.getSystemService(name); - } - - public T spyService(Class tClass) { - String name = getSystemServiceName(tClass); - Object service = mSpiedServices.get(name); - if (service != null) { - return (T) service; - } - - T result = spy(getSystemService(tClass)); - mSpiedServices.put(name, result); - return result; - } - - public void setupProvider(String authority, ContentProvider provider) { - ProviderInfo providerInfo = new ProviderInfo(); - providerInfo.authority = authority; - providerInfo.applicationInfo = getApplicationInfo(); - provider.attachInfo(this, providerInfo); - mMockResolver.addProvider(providerInfo.authority, provider); - doReturn(providerInfo).when(mPm).resolveContentProvider(eq(authority), anyInt()); - } - - private static boolean deleteContents(File dir) { - File[] files = dir.listFiles(); - boolean success = true; - if (files != null) { - for (File file : files) { - if (file.isDirectory()) { - success &= deleteContents(file); - } - if (!file.delete()) { - success = false; - } - } - } - return success; - } - - @Override - public void initDaggerComponent(LauncherBaseAppComponent.Builder componentBuilder) { - super.initDaggerComponent(componentBuilder.iconsDbName(null)); - } - } } diff --git a/tests/multivalentTests/src/com/android/launcher3/util/ModelTestExtensions.kt b/tests/multivalentTests/src/com/android/launcher3/util/ModelTestExtensions.kt index 524acff61d..a76060a91a 100644 --- a/tests/multivalentTests/src/com/android/launcher3/util/ModelTestExtensions.kt +++ b/tests/multivalentTests/src/com/android/launcher3/util/ModelTestExtensions.kt @@ -25,6 +25,7 @@ import com.android.launcher3.LauncherSettings.Favorites.TITLE import com.android.launcher3.LauncherSettings.Favorites._ID import com.android.launcher3.model.BgDataModel import com.android.launcher3.model.ModelDbController +import com.android.launcher3.util.Executors.MODEL_EXECUTOR import java.io.BufferedReader import java.io.InputStreamReader @@ -105,6 +106,15 @@ object ModelTestExtensions { } } + @JvmStatic + val LauncherModel.bgDataModel: BgDataModel + get() { + var data: BgDataModel? = null + enqueueModelUpdateTask { _, dataModel, _ -> data = dataModel } + TestUtil.runOnExecutorSync(MODEL_EXECUTOR) {} + return data!! + } + /** Creates an in-memory sqlite DB and initializes with the data in [insertFile] */ fun createInMemoryDb(insertFile: String): SQLiteDatabase = SQLiteDatabase.createInMemory(SQLiteDatabase.OpenParams.Builder().build()).also { db -> diff --git a/tests/multivalentTests/src/com/android/launcher3/util/SandboxApplication.kt b/tests/multivalentTests/src/com/android/launcher3/util/SandboxApplication.kt index 2fa4cad61d..0fecdae83e 100644 --- a/tests/multivalentTests/src/com/android/launcher3/util/SandboxApplication.kt +++ b/tests/multivalentTests/src/com/android/launcher3/util/SandboxApplication.kt @@ -16,22 +16,37 @@ package com.android.launcher3.util +import android.content.ContentProvider +import android.content.ContentResolver import android.content.Context import android.content.ContextParams import android.content.ContextWrapper import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager +import android.content.pm.ProviderInfo import android.content.res.Configuration import android.os.Bundle import android.os.IBinder import android.os.UserHandle +import android.provider.Settings.Global +import android.provider.Settings.Secure +import android.provider.Settings.System +import android.test.mock.MockContentResolver +import android.util.ArrayMap import android.view.Display import androidx.test.core.app.ApplicationProvider -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext +import com.android.launcher3.dagger.LauncherBaseAppComponent.Builder +import java.io.File +import java.util.UUID +import java.util.concurrent.CountDownLatch import org.junit.Rule import org.junit.rules.ExternalResource import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runners.model.Statement +import org.mockito.ArgumentMatchers +import org.mockito.Mockito +import org.mockito.kotlin.whenever /** * Sandbox application where created [Context] instances are still sandboxed within it. @@ -45,13 +60,27 @@ import org.junit.runners.model.Statement * propagate this application (see [SandboxApplicationWrapper]). */ class SandboxApplication private constructor(private val base: SandboxApplicationWrapper) : - SandboxModelContext(base), TestRule { + SandboxContext(base), TestRule { + + private val mockResolver = MockContentResolver() + private val spiedServices = ArrayMap() + private val packageManager = Mockito.spy(baseContext.packageManager) + private val dbDir = File(cacheDir, UUID.randomUUID().toString()) + + private var lockModelThreadOnDestroy = false @JvmOverloads constructor( base: Context = ApplicationProvider.getApplicationContext() ) : this(SandboxApplicationWrapper(base)) + init { + // System settings cache content provider. Ensure that they are statically initialized + Secure.getString(base.contentResolver, "test") + System.getString(base.contentResolver, "test") + Global.getString(base.contentResolver, "test") + } + /** * Initializes the sandbox application propagation logic. * @@ -71,6 +100,74 @@ class SandboxApplication private constructor(private val base: SandboxApplicatio return (app as? SandboxContext)?.shouldCleanUpOnDestroy() ?: true } + override fun getDatabasePath(name: String) = File(dbDir.apply { if (!exists()) mkdirs() }, name) + + override fun getContentResolver(): ContentResolver = mockResolver + + override fun cleanUpObjects() { + // When destroying the context, make sure that the model thread is blocked, so that no + // new jobs get posted while we are cleaning up + val modelLock = CountDownLatch(1) + val modelRelease = CountDownLatch(1) + if (lockModelThreadOnDestroy) { + Executors.MODEL_EXECUTOR.execute { + modelLock.countDown() + modelRelease.await() + } + modelLock.await() + } + if (deleteContents(dbDir)) { + dbDir.delete() + } + super.cleanUpObjects() + modelRelease.countDown() + } + + private fun deleteContents(dir: File): Boolean { + var success = true + dir.listFiles()?.forEach { + if (it.isDirectory) success = success and deleteContents(it) + if (!it.delete()) success = false + } + return success + } + + override fun initDaggerComponent(componentBuilder: Builder) { + super.initDaggerComponent(componentBuilder.iconsDbName(null)) + } + + override fun getPackageManager(): PackageManager = packageManager + + override fun getSystemService(name: String): Any? = + spiedServices[name] ?: super.getSystemService(name) + + fun spyService(tClass: Class): T { + val name = getSystemServiceName(tClass) + val service = spiedServices[name] + if (service != null) return service as T + + val result = Mockito.spy(getSystemService(tClass)) + spiedServices[name] = result + return result + } + + fun setupProvider(authority: String, provider: ContentProvider) { + val providerInfo = ProviderInfo() + providerInfo.authority = authority + providerInfo.applicationInfo = applicationInfo + provider.attachInfo(this, providerInfo) + mockResolver.addProvider(providerInfo.authority, provider) + Mockito.doReturn(providerInfo) + .whenever(packageManager) + .resolveContentProvider(ArgumentMatchers.eq(authority), ArgumentMatchers.anyInt()) + } + + /** + * Notifies the rule to lock the model thread during cleanup operation so that no new tasks get + * posted + */ + fun withModelDependency() = this.apply { lockModelThreadOnDestroy = true } + override fun apply(statement: Statement, description: Description): Statement { return object : ExternalResource() { override fun before() = init() diff --git a/tests/multivalentTests/src/com/android/launcher3/util/VibratorWrapperTest.kt b/tests/multivalentTests/src/com/android/launcher3/util/VibratorWrapperTest.kt index 0f212ebf9e..82e17a1268 100644 --- a/tests/multivalentTests/src/com/android/launcher3/util/VibratorWrapperTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/util/VibratorWrapperTest.kt @@ -22,12 +22,12 @@ import android.os.VibrationEffect.Composition.PRIMITIVE_LOW_TICK import android.os.VibrationEffect.Composition.PRIMITIVE_TICK import android.os.Vibrator import androidx.test.filters.SmallTest -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext import com.android.launcher3.util.VibratorWrapper.HAPTIC_FEEDBACK_URI import com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC import com.android.launcher3.util.VibratorWrapper.VIBRATION_ATTRS import com.google.common.truth.Truth.assertThat import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor @@ -46,7 +46,7 @@ class VibratorWrapperTest { @Mock private lateinit var settingsCache: SettingsCache private lateinit var vibrator: Vibrator - private val context: SandboxModelContext = SandboxModelContext() + @get:Rule val context = SandboxApplication() @Captor private lateinit var vibrationEffectCaptor: ArgumentCaptor @Mock private lateinit var tracker: DaggerSingletonTracker private lateinit var underTest: VibratorWrapper diff --git a/tests/multivalentTests/src/com/android/launcher3/util/rule/InstallerSessionRule.kt b/tests/multivalentTests/src/com/android/launcher3/util/rule/InstallerSessionRule.kt new file mode 100644 index 0000000000..307b9fa168 --- /dev/null +++ b/tests/multivalentTests/src/com/android/launcher3/util/rule/InstallerSessionRule.kt @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2025 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.launcher3.util.rule + +import android.content.Context +import android.content.pm.PackageInstaller.SessionParams +import android.graphics.Bitmap +import android.graphics.Bitmap.Config.ARGB_8888 +import android.graphics.Color +import androidx.test.core.app.ApplicationProvider.getApplicationContext +import com.android.launcher3.util.RunnableList +import org.junit.rules.ExternalResource + +/** Rule for creating package installer sessions */ +class InstallerSessionRule +@JvmOverloads +constructor(private val ctx: Context = getApplicationContext()) : ExternalResource() { + + private val cleanupActions = RunnableList() + + /** Creates a installer session for the provided package. */ + fun createInstallerSession(pkg: String): Int { + val sp = SessionParams(SessionParams.MODE_FULL_INSTALL) + sp.setAppPackageName(pkg) + val icon = Bitmap.createBitmap(100, 100, ARGB_8888) + icon.eraseColor(Color.RED) + sp.setAppIcon(icon) + sp.setAppLabel(pkg) + sp.setInstallerPackageName(ctx.packageName) + val pi = ctx.packageManager.packageInstaller + val sessionId = pi.createSession(sp) + cleanupActions.add { pi.abandonSession(sessionId) } + return sessionId + } + + override fun after() = cleanupActions.executeAllAndDestroy() +} diff --git a/tests/multivalentTests/src/com/android/launcher3/util/rule/LayoutProviderRule.kt b/tests/multivalentTests/src/com/android/launcher3/util/rule/LayoutProviderRule.kt new file mode 100644 index 0000000000..1ba7c91c23 --- /dev/null +++ b/tests/multivalentTests/src/com/android/launcher3/util/rule/LayoutProviderRule.kt @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2025 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.launcher3.util.rule + +import android.app.blob.BlobStoreManager +import android.os.ParcelFileDescriptor +import android.os.ParcelFileDescriptor.MODE_READ_WRITE +import android.provider.Settings.Secure +import com.android.launcher3.LauncherSettings.Settings +import com.android.launcher3.LauncherSettings.Settings.LAYOUT_PROVIDER_KEY +import com.android.launcher3.util.Executors.MODEL_EXECUTOR +import com.android.launcher3.util.LauncherLayoutBuilder +import com.android.launcher3.util.SandboxApplication +import com.android.launcher3.util.TestUtil +import java.io.File +import java.io.FileWriter +import java.security.MessageDigest +import org.junit.rules.ExternalResource +import org.mockito.kotlin.any +import org.mockito.kotlin.doAnswer +import org.mockito.kotlin.whenever + +/** Rule for providing default model layout */ +class LayoutProviderRule(private val ctx: SandboxApplication) : ExternalResource() { + + override fun before() { + TestUtil.grantWriteSecurePermission() + } + + fun setupDefaultLayoutProvider(builder: LauncherLayoutBuilder) { + val file = File.createTempFile("blobsession", "tmp") + FileWriter(file).use { builder.build(it) } + + val blobManager = ctx.spyService(BlobStoreManager::class.java) + doAnswer { ParcelFileDescriptor.open(file, MODE_READ_WRITE) } + .whenever(blobManager) + .openBlob(any()) + + Secure.putString( + ctx.getContentResolver(), + LAYOUT_PROVIDER_KEY, + Settings.createBlobProviderKey( + MessageDigest.getInstance("SHA-256").digest(byteArrayOf(1, 1, 1)) + ), + ) + } + + override fun after() { + TestUtil.runOnExecutorSync(MODEL_EXECUTOR) { + Secure.putString(ctx.getContentResolver(), LAYOUT_PROVIDER_KEY, "") + } + } +} diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/GeneratedPreviewTest.kt b/tests/multivalentTests/src/com/android/launcher3/widget/GeneratedPreviewTest.kt index 6af095047d..80fa2fa421 100644 --- a/tests/multivalentTests/src/com/android/launcher3/widget/GeneratedPreviewTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/widget/GeneratedPreviewTest.kt @@ -23,7 +23,7 @@ import com.android.launcher3.model.WidgetItem import com.android.launcher3.util.ActivityContextWrapper import com.android.launcher3.util.Executors import com.android.launcher3.util.Executors.MAIN_EXECUTOR -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext +import com.android.launcher3.util.SandboxApplication import com.android.launcher3.util.TestUtil import com.google.common.truth.Truth.assertThat import org.junit.After @@ -52,7 +52,7 @@ class GeneratedPreviewTest { resources.getIdentifier("test_layout_appwidget_blue", "layout", packageName) } - private lateinit var context: SandboxModelContext + @get:Rule val context = SandboxApplication() private lateinit var uiContext: Context private lateinit var generatedPreview: RemoteViews private lateinit var widgetCell: WidgetCell @@ -64,7 +64,6 @@ class GeneratedPreviewTest { @Before fun setup() { MockitoAnnotations.initMocks(this) - context = SandboxModelContext() generatedPreview = RemoteViews(context.packageName, generatedPreviewLayout) uiContext = ActivityContextWrapper(ContextThemeWrapper(context, R.style.WidgetContainerTheme)) diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt b/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt index 1c25db92be..bed860ab2b 100644 --- a/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt @@ -24,9 +24,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import com.android.launcher3.util.DaggerSingletonTracker -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext import com.android.launcher3.util.PluginManagerWrapper import com.android.launcher3.util.SafeCloseable +import com.android.launcher3.util.SandboxApplication import com.android.launcher3.util.WidgetUtils import com.android.launcher3.widget.LauncherAppWidgetHostView import com.android.launcher3.widget.LauncherAppWidgetProviderInfo @@ -55,7 +55,7 @@ class CustomWidgetManagerTest { @get:Rule val setFlagsRule = SetFlagsRule() - private val context = SandboxModelContext() + @get:Rule val context = SandboxApplication() private lateinit var underTest: CustomWidgetManager @Mock private lateinit var pluginManager: PluginManagerWrapper diff --git a/tests/src/com/android/launcher3/folder/PreviewItemManagerTest.kt b/tests/src/com/android/launcher3/folder/PreviewItemManagerTest.kt index c956395503..aa0326412c 100644 --- a/tests/src/com/android/launcher3/folder/PreviewItemManagerTest.kt +++ b/tests/src/com/android/launcher3/folder/PreviewItemManagerTest.kt @@ -17,13 +17,14 @@ package com.android.launcher3.folder import android.R +import android.content.ComponentName import android.os.Process import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn import com.android.launcher3.LauncherAppState import com.android.launcher3.LauncherPrefs -import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_FOLDER +import com.android.launcher3.LauncherSettings.Favorites.DESKTOP_ICON_FLAG import com.android.launcher3.dagger.LauncherAppComponent import com.android.launcher3.dagger.LauncherAppSingleton import com.android.launcher3.graphics.PreloadIconDrawable @@ -34,6 +35,7 @@ import com.android.launcher3.icons.IconCache import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver import com.android.launcher3.icons.PlaceHolderIconDrawable import com.android.launcher3.icons.UserBadgeDrawable +import com.android.launcher3.model.data.AppInfo import com.android.launcher3.model.data.FolderInfo import com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_ARCHIVED import com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE @@ -41,11 +43,15 @@ import com.android.launcher3.model.data.WorkspaceItemInfo import com.android.launcher3.util.ActivityContextWrapper import com.android.launcher3.util.AllModulesForTest import com.android.launcher3.util.Executors +import com.android.launcher3.util.Executors.MODEL_EXECUTOR import com.android.launcher3.util.FakePrefsModule import com.android.launcher3.util.FlagOp -import com.android.launcher3.util.LauncherLayoutBuilder -import com.android.launcher3.util.LauncherModelHelper -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext +import com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY +import com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY2 +import com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY3 +import com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY4 +import com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE +import com.android.launcher3.util.SandboxApplication import com.android.launcher3.util.TestUtil import com.android.launcher3.util.UserIconInfo import com.google.common.truth.Truth.assertThat @@ -54,7 +60,6 @@ import kotlin.annotation.AnnotationRetention.RUNTIME import kotlin.annotation.AnnotationTarget.FUNCTION import kotlin.annotation.AnnotationTarget.PROPERTY_GETTER import kotlin.annotation.AnnotationTarget.PROPERTY_SETTER -import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test @@ -75,20 +80,17 @@ import org.mockito.kotlin.whenever @RunWith(AndroidJUnit4::class) class PreviewItemManagerTest { + @get:Rule val context = SandboxApplication().withModelDependency() @get:Rule val theseStateRule = ThemeStateRule() private lateinit var previewItemManager: PreviewItemManager - private lateinit var context: SandboxModelContext private lateinit var folderItems: ArrayList - private lateinit var modelHelper: LauncherModelHelper private lateinit var folderIcon: FolderIcon private lateinit var iconCache: IconCache @Before fun setup() { MockitoAnnotations.initMocks(this) - modelHelper = LauncherModelHelper() - context = modelHelper.sandboxContext context.initDaggerComponent(DaggerPreviewItemManagerTestComponent.builder()) theseStateRule.themeState?.let { LauncherPrefs.get(context).putSync(ThemeManager.THEMED_ICONS.to(it)) @@ -100,22 +102,15 @@ class PreviewItemManagerTest { doReturn(null).whenever(iconCache).updateIconInBackground(any(), any()) previewItemManager = PreviewItemManager(folderIcon) - modelHelper - .setupDefaultLayoutProvider( - LauncherLayoutBuilder() - .atWorkspace(0, 0, 1) - .putFolder(R.string.copy) - .addApp(LauncherModelHelper.TEST_PACKAGE, LauncherModelHelper.TEST_ACTIVITY) - .addApp(LauncherModelHelper.TEST_PACKAGE, LauncherModelHelper.TEST_ACTIVITY2) - .addApp(LauncherModelHelper.TEST_PACKAGE, LauncherModelHelper.TEST_ACTIVITY3) - .addApp(LauncherModelHelper.TEST_PACKAGE, LauncherModelHelper.TEST_ACTIVITY4) - .build() - ) - .loadModelSync() folderIcon.mInfo = - modelHelper.bgDataModel.itemsIdMap.find { it.itemType == ITEM_TYPE_FOLDER } - as FolderInfo + FolderInfo().apply { + title = context.getString(R.string.copy) + add(buildWorkspaceItemInfo(TEST_ACTIVITY)) + add(buildWorkspaceItemInfo(TEST_ACTIVITY2)) + add(buildWorkspaceItemInfo(TEST_ACTIVITY3)) + add(buildWorkspaceItemInfo(TEST_ACTIVITY4)) + } // Use getAppContents() to "cast" contents to WorkspaceItemInfo so we can set bitmaps folderItems = folderIcon.mInfo.getAppContents() @@ -132,12 +127,6 @@ class PreviewItemManagerTest { folderItems[3].bitmap.themedBitmap = null } - @After - @Throws(Exception::class) - fun tearDown() { - modelHelper.destroy() - } - @Test @MonoThemeEnabled(true) fun checkThemedIconWithThemingOn_iconShouldBeThemed() { @@ -277,6 +266,14 @@ class PreviewItemManagerTest { private fun profileFlagOp(type: Int) = UserIconInfo(Process.myUserHandle(), type).applyBitmapInfoFlags(FlagOp.NO_OP) + + private fun buildWorkspaceItemInfo(targetClass: String) = + WorkspaceItemInfo().apply { + intent = AppInfo.makeLaunchIntent(ComponentName(TEST_PACKAGE, targetClass)) + TestUtil.runOnExecutorSync(MODEL_EXECUTOR) { + iconCache.getTitleAndIcon(this, DESKTOP_ICON_FLAG) + } + } } class ThemeStateRule : TestRule { diff --git a/tests/src/com/android/launcher3/model/LoaderTaskTest.kt b/tests/src/com/android/launcher3/model/LoaderTaskTest.kt index f9c4a1704e..b7688f08ae 100644 --- a/tests/src/com/android/launcher3/model/LoaderTaskTest.kt +++ b/tests/src/com/android/launcher3/model/LoaderTaskTest.kt @@ -41,9 +41,9 @@ import com.android.launcher3.provider.RestoreDbTask import com.android.launcher3.ui.TestViewHelpers import com.android.launcher3.util.AllModulesForTest import com.android.launcher3.util.Executors.MODEL_EXECUTOR -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext import com.android.launcher3.util.LooperIdleLock import com.android.launcher3.util.ModelTestExtensions +import com.android.launcher3.util.SandboxApplication import com.android.launcher3.util.TestUtil import com.android.launcher3.util.UserIconInfo import com.google.common.truth.Truth.assertThat @@ -78,7 +78,7 @@ private const val INSERTION_STATEMENT_FILE = "databases/workspace_items.sql" @SmallTest @RunWith(AndroidJUnit4::class) class LoaderTaskTest { - private var context = SandboxModelContext() + @get:Rule val context = SandboxApplication() private val expectedBroadcastModel = FirstScreenBroadcastModel( installerPackage = "installerPackage", @@ -174,7 +174,6 @@ class LoaderTaskTest { LauncherPrefs.get(context).removeSync(RESTORE_DEVICE) LauncherPrefs.get(context).putSync(IS_FIRST_LOAD_AFTER_RESTORE.to(false)) inMemoryDb.close() - context.onDestroy() mockitoSession.finishMocking() } diff --git a/tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java b/tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java index b140f2efc7..3115899262 100644 --- a/tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java +++ b/tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java @@ -29,6 +29,8 @@ import android.os.Process; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherModel; import com.android.launcher3.model.BgDataModel.Callbacks; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.ItemInfo; @@ -36,13 +38,14 @@ import com.android.launcher3.util.Executors; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.LauncherLayoutBuilder; -import com.android.launcher3.util.LauncherModelHelper; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.RunnableList; +import com.android.launcher3.util.SandboxApplication; import com.android.launcher3.util.TestUtil; +import com.android.launcher3.util.rule.LayoutProviderRule; import org.junit.After; -import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -60,21 +63,16 @@ import java.util.stream.Collectors; @RunWith(AndroidJUnit4.class) public class ModelMultiCallbacksTest { - private LauncherModelHelper mModelHelper; - - @Before - public void setUp() { - mModelHelper = new LauncherModelHelper(); - } + @Rule public SandboxApplication mContext = new SandboxApplication().withModelDependency(); + @Rule public LayoutProviderRule mLayoutProvider = new LayoutProviderRule(mContext); @After public void tearDown() throws Exception { - mModelHelper.destroy(); TestUtil.uninstallDummyApp(); } private ModelLauncherCallbacks getCallbacks() { - return mModelHelper.getModel().newModelCallbacks(); + return getModel().newModelCallbacks(); } @Test @@ -82,7 +80,7 @@ public class ModelMultiCallbacksTest { setupWorkspacePages(3); MyCallbacks cb1 = spy(MyCallbacks.class); - Executors.MAIN_EXECUTOR.execute(() -> mModelHelper.getModel().addCallbacksAndLoad(cb1)); + Executors.MAIN_EXECUTOR.execute(() -> getModel().addCallbacksAndLoad(cb1)); waitForLoaderAndTempMainThread(); cb1.verifySynchronouslyBound(3); @@ -91,7 +89,7 @@ public class ModelMultiCallbacksTest { cb1.reset(); MyCallbacks cb2 = spy(MyCallbacks.class); cb2.mPageToBindSync = IntSet.wrap(2); - Executors.MAIN_EXECUTOR.execute(() -> mModelHelper.getModel().addCallbacksAndLoad(cb2)); + Executors.MAIN_EXECUTOR.execute(() -> getModel().addCallbacksAndLoad(cb2)); waitForLoaderAndTempMainThread(); assertFalse(cb1.bindStarted); @@ -102,13 +100,13 @@ public class ModelMultiCallbacksTest { cb2.reset(); // No effect on callbacks when removing an callback - Executors.MAIN_EXECUTOR.execute(() -> mModelHelper.getModel().removeCallbacks(cb2)); + Executors.MAIN_EXECUTOR.execute(() -> getModel().removeCallbacks(cb2)); waitForLoaderAndTempMainThread(); assertNull(cb1.mPendingTasks); assertNull(cb2.mPendingTasks); // Reloading only loads registered callbacks - mModelHelper.getModel().startLoader(); + getModel().startLoader(); waitForLoaderAndTempMainThread(); cb1.verifySynchronouslyBound(3); assertNull(cb2.mPendingTasks); @@ -122,8 +120,8 @@ public class ModelMultiCallbacksTest { MyCallbacks cb1 = spy(MyCallbacks.class); MyCallbacks cb2 = spy(MyCallbacks.class); - Executors.MAIN_EXECUTOR.execute(() -> mModelHelper.getModel().addCallbacksAndLoad(cb1)); - Executors.MAIN_EXECUTOR.execute(() -> mModelHelper.getModel().addCallbacksAndLoad(cb2)); + Executors.MAIN_EXECUTOR.execute(() -> getModel().addCallbacksAndLoad(cb1)); + Executors.MAIN_EXECUTOR.execute(() -> getModel().addCallbacksAndLoad(cb2)); waitForLoaderAndTempMainThread(); assertTrue(cb1.allApps().contains(TEST_PACKAGE)); @@ -144,7 +142,7 @@ public class ModelMultiCallbacksTest { assertFalse(cb2.allApps().contains(TestUtil.DUMMY_PACKAGE)); // Unregister a callback and verify updates no longer received - Executors.MAIN_EXECUTOR.execute(() -> mModelHelper.getModel().removeCallbacks(cb2)); + Executors.MAIN_EXECUTOR.execute(() -> getModel().removeCallbacks(cb2)); TestUtil.installDummyApp(); getCallbacks().onPackageAdded(TestUtil.DUMMY_PACKAGE, Process.myUserHandle()); waitForLoaderAndTempMainThread(); @@ -166,7 +164,11 @@ public class ModelMultiCallbacksTest { for (int i = 0; i < pageCount; i++) { builder.atWorkspace(1, 1, i).putApp(TEST_PACKAGE, TEST_PACKAGE); } - mModelHelper.setupDefaultLayoutProvider(builder); + mLayoutProvider.setupDefaultLayoutProvider(builder); + } + + private LauncherModel getModel() { + return LauncherAppState.getInstance(mContext).getModel(); } private abstract static class MyCallbacks implements Callbacks { diff --git a/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt b/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt index 707c2c1976..2b945a2ce0 100644 --- a/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt +++ b/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt @@ -31,25 +31,25 @@ import com.android.launcher3.LauncherPrefs import com.android.launcher3.LauncherPrefs.Companion.PROMISE_ICON_IDS import com.android.launcher3.util.Executors.MODEL_EXECUTOR import com.android.launcher3.util.IntArray -import com.android.launcher3.util.LauncherModelHelper +import com.android.launcher3.util.SandboxApplication import com.android.launcher3.util.TestUtil import com.google.common.truth.Truth.assertThat import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.doReturn import org.mockito.kotlin.eq import org.mockito.kotlin.mock -import org.mockito.kotlin.spy import org.mockito.kotlin.whenever @SmallTest @RunWith(AndroidJUnit4::class) class InstallSessionHelperTest { - private val launcherModelHelper = LauncherModelHelper() - private val sandboxContext = spy(launcherModelHelper.sandboxContext) + @get:Rule val sandboxContext = SandboxApplication() + private val packageManager = sandboxContext.packageManager private val expectedAppPackage = "expectedAppPackage" private val expectedInstallerPackage = sandboxContext.packageName diff --git a/tests/src/com/android/launcher3/popup/SystemShortcutTest.java b/tests/src/com/android/launcher3/popup/SystemShortcutTest.java index 2531f6bacf..094c661f04 100644 --- a/tests/src/com/android/launcher3/popup/SystemShortcutTest.java +++ b/tests/src/com/android/launcher3/popup/SystemShortcutTest.java @@ -72,8 +72,8 @@ import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.pm.UserCache; import com.android.launcher3.util.AllModulesForTest; import com.android.launcher3.util.ComponentKey; -import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext; import com.android.launcher3.util.LauncherMultivalentJUnit; +import com.android.launcher3.util.SandboxApplication; import com.android.launcher3.util.TestSandboxModelContextWrapper; import com.android.launcher3.util.TestUtil; import com.android.launcher3.util.UserIconInfo; @@ -81,7 +81,9 @@ import com.android.launcher3.views.Snackbar; import com.android.launcher3.widget.picker.model.WidgetPickerDataProvider; import com.android.launcher3.widget.picker.model.data.WidgetPickerData; -import org.junit.After; +import dagger.BindsInstance; +import dagger.Component; + import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -91,19 +93,17 @@ import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import dagger.BindsInstance; -import dagger.Component; - @SmallTest @RunWith(LauncherMultivalentJUnit.class) public class SystemShortcutTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT); + @Rule public final SandboxApplication mSandboxContext = new SandboxApplication(); + private static final UserHandle PRIVATE_HANDLE = new UserHandle(11); private static final UserHandle MAIN_HANDLE = Process.myUserHandle(); private View mView; private ItemInfo mItemInfo; private TestSandboxModelContextWrapper mTestContext; - private final SandboxModelContext mSandboxContext = new SandboxModelContext(); private PrivateProfileManager mPrivateProfileManager; private WidgetPickerDataProvider mWidgetPickerDataProvider; private AppInfo mAppInfo; @@ -147,11 +147,6 @@ public class SystemShortcutTest { spyOn(mWidgetPickerDataProvider); } - @After - public void tearDown() { - mSandboxContext.onDestroy(); - } - @Test public void testWidgetsForNullComponentName() { assertNull(mItemInfo.getTargetComponent());