diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java index dc6968c7d9..312c6f412a 100644 --- a/src/com/android/launcher3/model/LoaderTask.java +++ b/src/com/android/launcher3/model/LoaderTask.java @@ -209,7 +209,7 @@ public class LoaderTask implements Runnable { mApp.getContext().getContentResolver(), "launcher_broadcast_installed_apps", /* def= */ 0); - if (launcherBroadcastInstalledApps == 1) { + if (launcherBroadcastInstalledApps == 1 && mIsRestoreFromBackup) { List broadcastModels = FirstScreenBroadcastHelper.createModelsForFirstScreenBroadcast( mPmHelper, diff --git a/tests/src/com/android/launcher3/model/LoaderTaskTest.kt b/tests/src/com/android/launcher3/model/LoaderTaskTest.kt index 28a001f990..d16674c6c2 100644 --- a/tests/src/com/android/launcher3/model/LoaderTaskTest.kt +++ b/tests/src/com/android/launcher3/model/LoaderTaskTest.kt @@ -1,10 +1,13 @@ package com.android.launcher3.model import android.appwidget.AppWidgetManager +import android.content.Intent import android.os.UserHandle import android.platform.test.flag.junit.SetFlagsRule +import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.dx.mockito.inline.extended.ExtendedMockito import com.android.launcher3.Flags import com.android.launcher3.InvariantDeviceProfile import com.android.launcher3.LauncherAppState @@ -14,6 +17,7 @@ import com.android.launcher3.icons.IconCache import com.android.launcher3.icons.cache.CachingLogic import com.android.launcher3.icons.cache.IconCacheUpdateHandler import com.android.launcher3.pm.UserCache +import com.android.launcher3.provider.RestoreDbTask import com.android.launcher3.ui.TestViewHelpers import com.android.launcher3.util.Executors.MODEL_EXECUTOR import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext @@ -21,21 +25,30 @@ import com.android.launcher3.util.LooperIdleLock import com.android.launcher3.util.UserIconInfo import com.google.common.truth.Truth import java.util.concurrent.CountDownLatch +import junit.framework.Assert.assertEquals import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyInt +import org.mockito.ArgumentMatchers.anyList +import org.mockito.ArgumentMatchers.anyMap import org.mockito.Mock import org.mockito.Mockito import org.mockito.Mockito.times -import org.mockito.Mockito.verify import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations +import org.mockito.MockitoSession import org.mockito.Spy +import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.doReturn +import org.mockito.kotlin.spy +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever +import org.mockito.quality.Strictness private const val INSERTION_STATEMENT_FILE = "databases/workspace_items.sql" @@ -43,6 +56,20 @@ private const val INSERTION_STATEMENT_FILE = "databases/workspace_items.sql" @RunWith(AndroidJUnit4::class) class LoaderTaskTest { private var context = SandboxModelContext() + private val expectedBroadcastModel = + FirstScreenBroadcastModel( + installerPackage = "installerPackage", + pendingCollectionItems = mutableSetOf("pendingCollectionItem"), + pendingWidgetItems = mutableSetOf("pendingWidgetItem"), + pendingHotseatItems = mutableSetOf("pendingHotseatItem"), + pendingWorkspaceItems = mutableSetOf("pendingWorkspaceItem"), + installedHotseatItems = mutableSetOf("installedHotseatItem"), + installedWorkspaceItems = mutableSetOf("installedWorkspaceItem"), + firstScreenInstalledWidgets = mutableSetOf("installedFirstScreenWidget"), + secondaryScreenInstalledWidgets = mutableSetOf("installedSecondaryScreenWidget") + ) + private lateinit var mockitoSession: MockitoSession + @Mock private lateinit var app: LauncherAppState @Mock private lateinit var bgAllAppsList: AllAppsList @Mock private lateinit var modelDelegate: ModelDelegate @@ -61,7 +88,11 @@ class LoaderTaskTest { @Before fun setup() { MockitoAnnotations.initMocks(this) - + mockitoSession = + ExtendedMockito.mockitoSession() + .strictness(Strictness.LENIENT) + .mockStatic(FirstScreenBroadcastHelper::class.java) + .startMocking() val idp = InvariantDeviceProfile().apply { numRows = 5 @@ -90,6 +121,7 @@ class LoaderTaskTest { @After fun tearDown() { context.onDestroy() + mockitoSession.finishMocking() } @Test @@ -166,6 +198,141 @@ class LoaderTaskTest { verify(bgAllAppsList, Mockito.never()) .setFlags(BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED, true) } + + @Test + fun `When launcher_broadcast_installed_apps and is restore then send installed item broadcast`() { + // Given + val spyContext = spy(context) + `when`(app.context).thenReturn(spyContext) + whenever( + FirstScreenBroadcastHelper.createModelsForFirstScreenBroadcast( + anyOrNull(), + anyList(), + anyMap(), + anyList() + ) + ) + .thenReturn(listOf(expectedBroadcastModel)) + + whenever( + FirstScreenBroadcastHelper.sendBroadcastsForModels( + spyContext, + listOf(expectedBroadcastModel) + ) + ) + .thenCallRealMethod() + + Settings.Secure.putInt(spyContext.contentResolver, "launcher_broadcast_installed_apps", 1) + RestoreDbTask.setPending(spyContext) + + // When + LoaderTask(app, bgAllAppsList, BgDataModel(), modelDelegate, launcherBinder) + .runSyncOnBackgroundThread() + + // Then + val argumentCaptor = ArgumentCaptor.forClass(Intent::class.java) + verify(spyContext).sendBroadcast(argumentCaptor.capture()) + val actualBroadcastIntent = argumentCaptor.value + assertEquals(expectedBroadcastModel.installerPackage, actualBroadcastIntent.`package`) + assertEquals( + ArrayList(expectedBroadcastModel.installedWorkspaceItems), + actualBroadcastIntent.getStringArrayListExtra("workspaceInstalledItems") + ) + assertEquals( + ArrayList(expectedBroadcastModel.installedHotseatItems), + actualBroadcastIntent.getStringArrayListExtra("hotseatInstalledItems") + ) + assertEquals( + ArrayList( + expectedBroadcastModel.firstScreenInstalledWidgets + + expectedBroadcastModel.secondaryScreenInstalledWidgets + ), + actualBroadcastIntent.getStringArrayListExtra("widgetInstalledItems") + ) + assertEquals( + ArrayList(expectedBroadcastModel.pendingCollectionItems), + actualBroadcastIntent.getStringArrayListExtra("folderItem") + ) + assertEquals( + ArrayList(expectedBroadcastModel.pendingWorkspaceItems), + actualBroadcastIntent.getStringArrayListExtra("workspaceItem") + ) + assertEquals( + ArrayList(expectedBroadcastModel.pendingHotseatItems), + actualBroadcastIntent.getStringArrayListExtra("hotseatItem") + ) + assertEquals( + ArrayList(expectedBroadcastModel.pendingWidgetItems), + actualBroadcastIntent.getStringArrayListExtra("widgetItem") + ) + } + + @Test + fun `When not a restore then installed item broadcast not sent`() { + // Given + val spyContext = spy(context) + `when`(app.context).thenReturn(spyContext) + whenever( + FirstScreenBroadcastHelper.createModelsForFirstScreenBroadcast( + anyOrNull(), + anyList(), + anyMap(), + anyList() + ) + ) + .thenReturn(listOf(expectedBroadcastModel)) + + whenever( + FirstScreenBroadcastHelper.sendBroadcastsForModels( + spyContext, + listOf(expectedBroadcastModel) + ) + ) + .thenCallRealMethod() + + Settings.Secure.putInt(spyContext.contentResolver, "launcher_broadcast_installed_apps", 1) + + // When + LoaderTask(app, bgAllAppsList, BgDataModel(), modelDelegate, launcherBinder) + .runSyncOnBackgroundThread() + + // Then + verify(spyContext, times(0)).sendBroadcast(any(Intent::class.java)) + } + + @Test + fun `When launcher_broadcast_installed_apps false then installed item broadcast not sent`() { + // Given + val spyContext = spy(context) + `when`(app.context).thenReturn(spyContext) + whenever( + FirstScreenBroadcastHelper.createModelsForFirstScreenBroadcast( + anyOrNull(), + anyList(), + anyMap(), + anyList() + ) + ) + .thenReturn(listOf(expectedBroadcastModel)) + + whenever( + FirstScreenBroadcastHelper.sendBroadcastsForModels( + spyContext, + listOf(expectedBroadcastModel) + ) + ) + .thenCallRealMethod() + + Settings.Secure.putInt(spyContext.contentResolver, "launcher_broadcast_installed_apps", 0) + RestoreDbTask.setPending(spyContext) + + // When + LoaderTask(app, bgAllAppsList, BgDataModel(), modelDelegate, launcherBinder) + .runSyncOnBackgroundThread() + + // Then + verify(spyContext, times(0)).sendBroadcast(any(Intent::class.java)) + } } private fun LoaderTask.runSyncOnBackgroundThread() {