676 lines
26 KiB
Kotlin
676 lines
26 KiB
Kotlin
package com.android.launcher3.model
|
|
|
|
import android.appwidget.AppWidgetManager
|
|
import android.content.ComponentName
|
|
import android.content.Intent
|
|
import android.content.pm.ApplicationInfo
|
|
import android.content.pm.LauncherActivityInfo
|
|
import android.database.sqlite.SQLiteDatabase
|
|
import android.os.Process
|
|
import android.os.UserHandle
|
|
import android.platform.test.annotations.DisableFlags
|
|
import android.platform.test.annotations.EnableFlags
|
|
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.dx.mockito.inline.extended.ExtendedMockito.spyOn
|
|
import com.android.launcher3.Flags
|
|
import com.android.launcher3.LauncherModel
|
|
import com.android.launcher3.LauncherModel.LoaderTransaction
|
|
import com.android.launcher3.LauncherPrefs
|
|
import com.android.launcher3.LauncherPrefs.Companion.IS_FIRST_LOAD_AFTER_RESTORE
|
|
import com.android.launcher3.LauncherPrefs.Companion.RESTORE_DEVICE
|
|
import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP
|
|
import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT
|
|
import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR
|
|
import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_FOLDER
|
|
import com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME
|
|
import com.android.launcher3.dagger.LauncherAppComponent
|
|
import com.android.launcher3.dagger.LauncherAppSingleton
|
|
import com.android.launcher3.icons.IconCache
|
|
import com.android.launcher3.icons.cache.CachingLogic
|
|
import com.android.launcher3.icons.cache.IconCacheUpdateHandler
|
|
import com.android.launcher3.model.LoaderTask.LoaderTaskFactory
|
|
import com.android.launcher3.model.data.AppInfo
|
|
import com.android.launcher3.model.data.IconRequestInfo
|
|
import com.android.launcher3.model.data.WorkspaceItemInfo
|
|
import com.android.launcher3.pm.UserCache
|
|
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.TestUtil
|
|
import com.android.launcher3.util.UserIconInfo
|
|
import com.google.common.truth.Truth.assertThat
|
|
import dagger.BindsInstance
|
|
import dagger.Component
|
|
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.Mock
|
|
import org.mockito.Mockito
|
|
import org.mockito.Mockito.times
|
|
import org.mockito.Mockito.`when`
|
|
import org.mockito.MockitoAnnotations
|
|
import org.mockito.MockitoSession
|
|
import org.mockito.Spy
|
|
import org.mockito.kotlin.any
|
|
import org.mockito.kotlin.anyOrNull
|
|
import org.mockito.kotlin.doAnswer
|
|
import org.mockito.kotlin.doReturn
|
|
import org.mockito.kotlin.mock
|
|
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"
|
|
|
|
@SmallTest
|
|
@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 bgAllAppsList: AllAppsList
|
|
@Mock private lateinit var modelDelegate: ModelDelegate
|
|
@Mock private lateinit var launcherModel: LauncherModel
|
|
@Mock private lateinit var iconCache: IconCache
|
|
@Mock private lateinit var userCache: UserCache
|
|
@Mock private lateinit var modelDbController: ModelDbController
|
|
|
|
@Mock private lateinit var launcherBinder: BaseLauncherBinder
|
|
@Mock private lateinit var transaction: LoaderTransaction
|
|
@Mock private lateinit var idleLock: LooperIdleLock
|
|
@Mock private lateinit var iconCacheUpdateHandler: IconCacheUpdateHandler
|
|
|
|
@Spy private var userManagerState: UserManagerState = UserManagerState()
|
|
|
|
@get:Rule val setFlagsRule = SetFlagsRule()
|
|
|
|
private val testComponent: TestComponent
|
|
get() = context.appComponent as TestComponent
|
|
|
|
private val bgDataModel: BgDataModel
|
|
get() = testComponent.getDataModel()
|
|
|
|
private val inMemoryDb: SQLiteDatabase by lazy {
|
|
ModelTestExtensions.createInMemoryDb(INSERTION_STATEMENT_FILE)
|
|
}
|
|
|
|
@Before
|
|
fun setup() {
|
|
MockitoAnnotations.initMocks(this)
|
|
mockitoSession =
|
|
ExtendedMockito.mockitoSession()
|
|
.strictness(Strictness.LENIENT)
|
|
.mockStatic(FirstScreenBroadcastHelper::class.java)
|
|
.startMocking()
|
|
doReturn(TestViewHelpers.findWidgetProvider(false))
|
|
.`when`(context.spyService(AppWidgetManager::class.java))
|
|
.getAppWidgetInfo(any())
|
|
|
|
`when`(launcherModel.beginLoader(any())).thenReturn(transaction)
|
|
|
|
`when`(launcherModel.modelDbController).thenReturn(modelDbController)
|
|
doAnswer {}.whenever(modelDbController).loadDefaultFavoritesIfNecessary()
|
|
doAnswer { i ->
|
|
inMemoryDb.query(
|
|
TABLE_NAME,
|
|
i.getArgument(0),
|
|
i.getArgument(1),
|
|
i.getArgument(2),
|
|
null,
|
|
null,
|
|
i.getArgument(3),
|
|
)
|
|
}
|
|
.whenever(modelDbController)
|
|
.query(anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull())
|
|
|
|
`when`(launcherModel.modelDelegate).thenReturn(modelDelegate)
|
|
`when`(launcherBinder.newIdleLock(any())).thenReturn(idleLock)
|
|
`when`(idleLock.awaitLocked(1000)).thenReturn(false)
|
|
`when`(iconCache.getUpdateHandler()).thenReturn(iconCacheUpdateHandler)
|
|
|
|
context.initDaggerComponent(
|
|
DaggerLoaderTaskTest_TestComponent.builder()
|
|
.bindUserCache(userCache)
|
|
.bindIconCache(iconCache)
|
|
.bindLauncherModel(launcherModel)
|
|
.bindAllAppsList(bgAllAppsList)
|
|
)
|
|
context.appComponent.idp.apply {
|
|
numRows = 5
|
|
numColumns = 6
|
|
numDatabaseHotseatIcons = 5
|
|
}
|
|
TestUtil.grantWriteSecurePermission()
|
|
}
|
|
|
|
@After
|
|
fun tearDown() {
|
|
LauncherPrefs.get(context).removeSync(RESTORE_DEVICE)
|
|
LauncherPrefs.get(context).putSync(IS_FIRST_LOAD_AFTER_RESTORE.to(false))
|
|
inMemoryDb.close()
|
|
context.onDestroy()
|
|
mockitoSession.finishMocking()
|
|
}
|
|
|
|
@Test
|
|
fun loadsDataProperly() =
|
|
with(bgDataModel) {
|
|
val MAIN_HANDLE = Process.myUserHandle()
|
|
val mockUserHandles = arrayListOf<UserHandle>(MAIN_HANDLE)
|
|
`when`(userCache.userProfiles).thenReturn(mockUserHandles)
|
|
`when`(userCache.getUserInfo(MAIN_HANDLE)).thenReturn(UserIconInfo(MAIN_HANDLE, 1))
|
|
testComponent
|
|
.getLoaderTaskFactory()
|
|
.newLoaderTask(launcherBinder, userManagerState)
|
|
.runSyncOnBackgroundThread()
|
|
assertThat(
|
|
itemsIdMap
|
|
.filter {
|
|
it.container == CONTAINER_DESKTOP || it.container == CONTAINER_HOTSEAT
|
|
}
|
|
.size
|
|
)
|
|
.isAtLeast(32)
|
|
assertThat(itemsIdMap.filter { ModelUtils.WIDGET_FILTER.test(it) }.size).isAtLeast(7)
|
|
assertThat(
|
|
itemsIdMap
|
|
.filter {
|
|
it.itemType == ITEM_TYPE_FOLDER || it.itemType == ITEM_TYPE_APP_PAIR
|
|
}
|
|
.size
|
|
)
|
|
.isAtLeast(8)
|
|
assertThat(itemsIdMap.size()).isAtLeast(40)
|
|
}
|
|
|
|
@Test
|
|
fun bindsLoadedDataCorrectly() {
|
|
testComponent
|
|
.getLoaderTaskFactory()
|
|
.newLoaderTask(launcherBinder, userManagerState)
|
|
.runSyncOnBackgroundThread()
|
|
|
|
verify(launcherBinder).bindWorkspace(true, false)
|
|
verify(modelDelegate).workspaceLoadComplete()
|
|
verify(modelDelegate).loadAndBindAllAppsItems(any(), anyOrNull(), any())
|
|
verify(launcherBinder).bindAllApps()
|
|
verify(iconCacheUpdateHandler, times(4)).updateIcons(any(), any<CachingLogic<Any>>(), any())
|
|
verify(launcherBinder).bindDeepShortcuts()
|
|
verify(launcherBinder).bindWidgets()
|
|
verify(modelDelegate).loadAndBindOtherItems(anyOrNull())
|
|
verify(iconCacheUpdateHandler).finish()
|
|
verify(modelDelegate).modelLoadComplete()
|
|
verify(transaction).commit()
|
|
}
|
|
|
|
@Test
|
|
fun setsQuietModeFlagCorrectlyForWorkProfile() =
|
|
with(bgDataModel) {
|
|
setFlagsRule.enableFlags(Flags.FLAG_ENABLE_PRIVATE_SPACE)
|
|
val MAIN_HANDLE = Process.myUserHandle()
|
|
val mockUserHandles = arrayListOf<UserHandle>(MAIN_HANDLE)
|
|
`when`(userCache.userProfiles).thenReturn(mockUserHandles)
|
|
`when`(userManagerState?.isUserQuiet(MAIN_HANDLE)).thenReturn(true)
|
|
`when`(userCache.getUserInfo(MAIN_HANDLE)).thenReturn(UserIconInfo(MAIN_HANDLE, 1))
|
|
|
|
testComponent
|
|
.getLoaderTaskFactory()
|
|
.newLoaderTask(launcherBinder, userManagerState)
|
|
.runSyncOnBackgroundThread()
|
|
|
|
verify(bgAllAppsList)
|
|
.setFlags(BgDataModel.Callbacks.FLAG_WORK_PROFILE_QUIET_MODE_ENABLED, true)
|
|
verify(bgAllAppsList)
|
|
.setFlags(BgDataModel.Callbacks.FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED, false)
|
|
verify(bgAllAppsList, Mockito.never())
|
|
.setFlags(BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED, true)
|
|
}
|
|
|
|
@Test
|
|
fun setsQuietModeFlagCorrectlyForPrivateProfile() =
|
|
with(bgDataModel) {
|
|
setFlagsRule.enableFlags(Flags.FLAG_ENABLE_PRIVATE_SPACE)
|
|
val MAIN_HANDLE = Process.myUserHandle()
|
|
val mockUserHandles = arrayListOf<UserHandle>(MAIN_HANDLE)
|
|
`when`(userCache.userProfiles).thenReturn(mockUserHandles)
|
|
`when`(userManagerState?.isUserQuiet(MAIN_HANDLE)).thenReturn(true)
|
|
`when`(userCache.getUserInfo(MAIN_HANDLE)).thenReturn(UserIconInfo(MAIN_HANDLE, 3))
|
|
|
|
testComponent
|
|
.getLoaderTaskFactory()
|
|
.newLoaderTask(launcherBinder, userManagerState)
|
|
.runSyncOnBackgroundThread()
|
|
|
|
verify(bgAllAppsList)
|
|
.setFlags(BgDataModel.Callbacks.FLAG_WORK_PROFILE_QUIET_MODE_ENABLED, false)
|
|
verify(bgAllAppsList)
|
|
.setFlags(BgDataModel.Callbacks.FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED, true)
|
|
verify(bgAllAppsList, Mockito.never())
|
|
.setFlags(BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED, true)
|
|
}
|
|
|
|
@Test
|
|
@EnableFlags(Flags.FLAG_ENABLE_FIRST_SCREEN_BROADCAST_ARCHIVING_EXTRAS)
|
|
fun `When broadcast flag on and is restore and secure setting off then send new broadcast`() {
|
|
// Given
|
|
spyOn(context)
|
|
val spyContext = context
|
|
whenever(
|
|
FirstScreenBroadcastHelper.createModelsForFirstScreenBroadcast(
|
|
any(),
|
|
any(),
|
|
any(),
|
|
any(),
|
|
)
|
|
)
|
|
.thenReturn(listOf(expectedBroadcastModel))
|
|
|
|
whenever(
|
|
FirstScreenBroadcastHelper.sendBroadcastsForModels(
|
|
spyContext,
|
|
listOf(expectedBroadcastModel),
|
|
)
|
|
)
|
|
.thenCallRealMethod()
|
|
|
|
Settings.Secure.putInt(spyContext.contentResolver, "launcher_broadcast_installed_apps", 0)
|
|
RestoreDbTask.setPending(spyContext)
|
|
|
|
// When
|
|
testComponent
|
|
.getLoaderTaskFactory()
|
|
.newLoaderTask(launcherBinder, userManagerState)
|
|
.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
|
|
@EnableFlags(Flags.FLAG_ENABLE_FIRST_SCREEN_BROADCAST_ARCHIVING_EXTRAS)
|
|
fun `When not a restore then installed item broadcast not sent`() {
|
|
// Given
|
|
spyOn(context)
|
|
val spyContext = context
|
|
whenever(
|
|
FirstScreenBroadcastHelper.createModelsForFirstScreenBroadcast(
|
|
any(),
|
|
any(),
|
|
any(),
|
|
any(),
|
|
)
|
|
)
|
|
.thenReturn(listOf(expectedBroadcastModel))
|
|
|
|
whenever(
|
|
FirstScreenBroadcastHelper.sendBroadcastsForModels(
|
|
spyContext,
|
|
listOf(expectedBroadcastModel),
|
|
)
|
|
)
|
|
.thenCallRealMethod()
|
|
|
|
Settings.Secure.putInt(spyContext.contentResolver, "launcher_broadcast_installed_apps", 0)
|
|
|
|
// When
|
|
testComponent
|
|
.getLoaderTaskFactory()
|
|
.newLoaderTask(launcherBinder, userManagerState)
|
|
.runSyncOnBackgroundThread()
|
|
|
|
// Then
|
|
verify(spyContext, times(0)).sendBroadcast(any())
|
|
}
|
|
|
|
@Test
|
|
@DisableFlags(Flags.FLAG_ENABLE_FIRST_SCREEN_BROADCAST_ARCHIVING_EXTRAS)
|
|
fun `When broadcast flag off then installed item broadcast not sent`() {
|
|
// Given
|
|
spyOn(context)
|
|
val spyContext = context
|
|
whenever(
|
|
FirstScreenBroadcastHelper.createModelsForFirstScreenBroadcast(
|
|
any(),
|
|
any(),
|
|
any(),
|
|
any(),
|
|
)
|
|
)
|
|
.thenReturn(listOf(expectedBroadcastModel))
|
|
|
|
whenever(
|
|
FirstScreenBroadcastHelper.sendBroadcastsForModels(
|
|
spyContext,
|
|
listOf(expectedBroadcastModel),
|
|
)
|
|
)
|
|
.thenCallRealMethod()
|
|
|
|
Settings.Secure.putInt(
|
|
spyContext.contentResolver,
|
|
"disable_launcher_broadcast_installed_apps",
|
|
0,
|
|
)
|
|
RestoreDbTask.setPending(spyContext)
|
|
|
|
// When
|
|
testComponent
|
|
.getLoaderTaskFactory()
|
|
.newLoaderTask(launcherBinder, userManagerState)
|
|
.runSyncOnBackgroundThread()
|
|
|
|
// Then
|
|
verify(spyContext, times(0)).sendBroadcast(any())
|
|
}
|
|
|
|
@Test
|
|
@EnableFlags(Flags.FLAG_ENABLE_FIRST_SCREEN_BROADCAST_ARCHIVING_EXTRAS)
|
|
fun `When failsafe secure setting on then installed item broadcast not sent`() {
|
|
// Given
|
|
spyOn(context)
|
|
val spyContext = context
|
|
whenever(
|
|
FirstScreenBroadcastHelper.createModelsForFirstScreenBroadcast(
|
|
any(),
|
|
any(),
|
|
any(),
|
|
any(),
|
|
)
|
|
)
|
|
.thenReturn(listOf(expectedBroadcastModel))
|
|
|
|
whenever(
|
|
FirstScreenBroadcastHelper.sendBroadcastsForModels(
|
|
spyContext,
|
|
listOf(expectedBroadcastModel),
|
|
)
|
|
)
|
|
.thenCallRealMethod()
|
|
|
|
Settings.Secure.putInt(
|
|
spyContext.contentResolver,
|
|
"disable_launcher_broadcast_installed_apps",
|
|
1,
|
|
)
|
|
RestoreDbTask.setPending(spyContext)
|
|
|
|
// When
|
|
testComponent
|
|
.getLoaderTaskFactory()
|
|
.newLoaderTask(launcherBinder, userManagerState)
|
|
.runSyncOnBackgroundThread()
|
|
|
|
// Then
|
|
verify(spyContext, times(0)).sendBroadcast(any())
|
|
}
|
|
|
|
@Test
|
|
@EnableFlags(Flags.FLAG_RESTORE_ARCHIVED_APP_ICONS_FROM_DB)
|
|
fun `When flag on and restore then archived AllApps icons on Workspace load from db`() {
|
|
// Given
|
|
val activityInfo: LauncherActivityInfo = mock()
|
|
val applicationInfo: ApplicationInfo = mock<ApplicationInfo>().apply { isArchived = true }
|
|
whenever(activityInfo.applicationInfo).thenReturn(applicationInfo)
|
|
val expectedIconBlob = byteArrayOf(0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08)
|
|
val expectedComponent = ComponentName("package", "class")
|
|
val workspaceIconRequests =
|
|
listOf(
|
|
IconRequestInfo<WorkspaceItemInfo>(
|
|
WorkspaceItemInfo().apply {
|
|
intent = Intent().apply { component = expectedComponent }
|
|
},
|
|
activityInfo,
|
|
expectedIconBlob,
|
|
false, /* useLowResIcon */
|
|
)
|
|
)
|
|
val expectedAppInfo = AppInfo().apply { componentName = expectedComponent }
|
|
// When
|
|
val loader =
|
|
testComponent.getLoaderTaskFactory().newLoaderTask(launcherBinder, userManagerState)
|
|
val actualIconRequest =
|
|
loader.getAppInfoIconRequestInfo(
|
|
expectedAppInfo,
|
|
activityInfo,
|
|
workspaceIconRequests,
|
|
/* isRestoreFromBackup */ true,
|
|
)
|
|
// Then
|
|
assertThat(actualIconRequest.iconBlob).isEqualTo(expectedIconBlob)
|
|
assertThat(actualIconRequest.itemInfo).isEqualTo(expectedAppInfo)
|
|
}
|
|
|
|
@Test
|
|
@EnableFlags(Flags.FLAG_RESTORE_ARCHIVED_APP_ICONS_FROM_DB)
|
|
fun `When flag on and not restore then archived AllApps icons do not load from db`() {
|
|
// Given
|
|
val activityInfo: LauncherActivityInfo = mock()
|
|
val applicationInfo: ApplicationInfo = mock<ApplicationInfo>().apply { isArchived = true }
|
|
whenever(activityInfo.applicationInfo).thenReturn(applicationInfo)
|
|
val expectedIconBlob = byteArrayOf(0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08)
|
|
val expectedComponent = ComponentName("package", "class")
|
|
val workspaceIconRequests =
|
|
listOf(
|
|
IconRequestInfo<WorkspaceItemInfo>(
|
|
WorkspaceItemInfo().apply {
|
|
intent = Intent().apply { component = expectedComponent }
|
|
},
|
|
activityInfo,
|
|
expectedIconBlob,
|
|
false, /* useLowResIcon */
|
|
)
|
|
)
|
|
val expectedAppInfo = AppInfo().apply { componentName = expectedComponent }
|
|
// When
|
|
val loader =
|
|
testComponent.getLoaderTaskFactory().newLoaderTask(launcherBinder, userManagerState)
|
|
val actualIconRequest =
|
|
loader.getAppInfoIconRequestInfo(
|
|
expectedAppInfo,
|
|
activityInfo,
|
|
workspaceIconRequests,
|
|
/* isRestoreFromBackup */ false,
|
|
)
|
|
// Then
|
|
assertThat(actualIconRequest.iconBlob).isNull()
|
|
assertThat(actualIconRequest.itemInfo).isEqualTo(expectedAppInfo)
|
|
}
|
|
|
|
@Test
|
|
@EnableFlags(Flags.FLAG_RESTORE_ARCHIVED_APP_ICONS_FROM_DB)
|
|
fun `When flag on and restore then unarchived AllApps icons not loaded from db`() {
|
|
// Given
|
|
val activityInfo: LauncherActivityInfo = mock()
|
|
val applicationInfo: ApplicationInfo = mock<ApplicationInfo>().apply { isArchived = false }
|
|
whenever(activityInfo.applicationInfo).thenReturn(applicationInfo)
|
|
val expectedIconBlob = byteArrayOf(0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08)
|
|
val expectedComponent = ComponentName("package", "class")
|
|
val workspaceIconRequests =
|
|
listOf(
|
|
IconRequestInfo<WorkspaceItemInfo>(
|
|
WorkspaceItemInfo().apply {
|
|
intent = Intent().apply { component = expectedComponent }
|
|
},
|
|
activityInfo,
|
|
expectedIconBlob,
|
|
false, /* useLowResIcon */
|
|
)
|
|
)
|
|
val expectedAppInfo = AppInfo().apply { componentName = expectedComponent }
|
|
// When
|
|
val loader =
|
|
testComponent.getLoaderTaskFactory().newLoaderTask(launcherBinder, userManagerState)
|
|
val actualIconRequest =
|
|
loader.getAppInfoIconRequestInfo(
|
|
expectedAppInfo,
|
|
activityInfo,
|
|
workspaceIconRequests,
|
|
/* isRestoreFromBackup */ true,
|
|
)
|
|
// Then
|
|
assertThat(actualIconRequest.iconBlob).isNull()
|
|
assertThat(actualIconRequest.itemInfo).isEqualTo(expectedAppInfo)
|
|
}
|
|
|
|
@Test
|
|
@EnableFlags(Flags.FLAG_RESTORE_ARCHIVED_APP_ICONS_FROM_DB)
|
|
fun `When flag on and restore then all apps icon not on workspace is not loaded from db`() {
|
|
// Given
|
|
val activityInfo: LauncherActivityInfo = mock()
|
|
val applicationInfo: ApplicationInfo = mock<ApplicationInfo>().apply { isArchived = true }
|
|
whenever(activityInfo.applicationInfo).thenReturn(applicationInfo)
|
|
val expectedIconBlob = byteArrayOf(0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08)
|
|
val expectedComponent = ComponentName("package", "class")
|
|
val workspaceIconRequests =
|
|
listOf(
|
|
IconRequestInfo<WorkspaceItemInfo>(
|
|
WorkspaceItemInfo().apply {
|
|
intent = Intent().apply { component = expectedComponent }
|
|
},
|
|
activityInfo,
|
|
expectedIconBlob,
|
|
false, /* useLowResIcon */
|
|
)
|
|
)
|
|
val expectedAppInfo =
|
|
AppInfo().apply { componentName = ComponentName("differentPkg", "differentClass") }
|
|
// When
|
|
val loader =
|
|
testComponent.getLoaderTaskFactory().newLoaderTask(launcherBinder, userManagerState)
|
|
val actualIconRequest =
|
|
loader.getAppInfoIconRequestInfo(
|
|
expectedAppInfo,
|
|
activityInfo,
|
|
workspaceIconRequests,
|
|
/* isRestoreFromBackup */ true,
|
|
)
|
|
// Then
|
|
assertThat(actualIconRequest.iconBlob).isNull()
|
|
assertThat(actualIconRequest.itemInfo).isEqualTo(expectedAppInfo)
|
|
}
|
|
|
|
@Test
|
|
@DisableFlags(Flags.FLAG_RESTORE_ARCHIVED_APP_ICONS_FROM_DB)
|
|
fun `When flag off and restore then archived AllApps icons not loaded from db`() {
|
|
// Given
|
|
val activityInfo: LauncherActivityInfo = mock()
|
|
val applicationInfo: ApplicationInfo = mock<ApplicationInfo>().apply { isArchived = true }
|
|
whenever(activityInfo.applicationInfo).thenReturn(applicationInfo)
|
|
val expectedIconBlob = byteArrayOf(0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08)
|
|
val workspaceIconRequests =
|
|
listOf(
|
|
IconRequestInfo<WorkspaceItemInfo>(
|
|
WorkspaceItemInfo(),
|
|
activityInfo,
|
|
expectedIconBlob,
|
|
false, /* useLowResIcon */
|
|
)
|
|
)
|
|
val expectedAppInfo = AppInfo()
|
|
// When
|
|
val loader =
|
|
testComponent.getLoaderTaskFactory().newLoaderTask(launcherBinder, userManagerState)
|
|
val actualIconRequest =
|
|
loader.getAppInfoIconRequestInfo(
|
|
expectedAppInfo,
|
|
activityInfo,
|
|
workspaceIconRequests,
|
|
/* isRestoreFromBackup */ true,
|
|
)
|
|
// Then
|
|
assertThat(actualIconRequest.iconBlob).isNull()
|
|
assertThat(actualIconRequest.itemInfo).isEqualTo(expectedAppInfo)
|
|
}
|
|
|
|
@LauncherAppSingleton
|
|
@Component(modules = [AllModulesForTest::class])
|
|
interface TestComponent : LauncherAppComponent {
|
|
|
|
fun getLoaderTaskFactory(): LoaderTaskFactory
|
|
|
|
fun getDataModel(): BgDataModel
|
|
|
|
@Component.Builder
|
|
interface Builder : LauncherAppComponent.Builder {
|
|
@BindsInstance fun bindUserCache(userCache: UserCache): Builder
|
|
|
|
@BindsInstance fun bindLauncherModel(model: LauncherModel): Builder
|
|
|
|
@BindsInstance fun bindIconCache(iconCache: IconCache): Builder
|
|
|
|
@BindsInstance fun bindAllAppsList(list: AllAppsList): Builder
|
|
|
|
override fun build(): TestComponent
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun LoaderTask.runSyncOnBackgroundThread() {
|
|
val latch = CountDownLatch(1)
|
|
MODEL_EXECUTOR.execute {
|
|
run()
|
|
latch.countDown()
|
|
}
|
|
latch.await()
|
|
}
|