Files
lawnchair/tests/multivalentTests/src/com/android/launcher3/icons/IconCacheUpdateHandlerTest.kt

150 lines
5.2 KiB
Kotlin
Raw Normal View History

/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.icons
import android.content.ComponentName
import android.content.pm.ApplicationInfo
import android.database.MatrixCursor
import android.os.Process.myUserHandle
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.launcher3.icons.cache.BaseIconCache
import com.android.launcher3.icons.cache.BaseIconCache.IconDB
import com.android.launcher3.icons.cache.CachedObject
import com.android.launcher3.icons.cache.CachedObjectCachingLogic
import com.android.launcher3.icons.cache.IconCacheUpdateHandler
import com.android.launcher3.util.RoboApiWrapper
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.FutureTask
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.whenever
@SmallTest
@RunWith(AndroidJUnit4::class)
class IconCacheUpdateHandlerTest {
@Mock private lateinit var iconProvider: IconProvider
@Mock private lateinit var baseIconCache: BaseIconCache
private var cursor: MatrixCursor? = null
private var cachingLogic = CachedObjectCachingLogic
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
doReturn(iconProvider).whenever(baseIconCache).iconProvider
}
@After
fun tearDown() {
cursor?.close()
}
@Test
fun `IconCacheUpdateHandler returns null if the component name is malformed`() {
val updateHandlerUnderTest = IconCacheUpdateHandler(baseIconCache)
val cn = ComponentName.unflattenFromString("com.android.fake/.FakeActivity")!!
val result =
updateHandlerUnderTest.updateOrDeleteIcon(
createCursor(1, cn.flattenToString() + "#", "freshId-old"),
hashMapOf(cn to TestCachedObject(cn, "freshId")),
setOf(),
myUserHandle(),
cachingLogic,
)
assertThat(result).isNull()
}
@Test
fun `IconCacheUpdateHandler returns null if the freshId match`() {
val updateHandlerUnderTest = IconCacheUpdateHandler(baseIconCache)
val cn = ComponentName.unflattenFromString("com.android.fake/.FakeActivity")!!
val result =
updateHandlerUnderTest.updateOrDeleteIcon(
createCursor(1, cn.flattenToString(), "freshId"),
hashMapOf(cn to TestCachedObject(cn, "freshId")),
setOf(),
myUserHandle(),
cachingLogic,
)
assertThat(result).isNull()
}
@Test
fun `IconCacheUpdateHandler returns non-null if the freshId do not match`() {
val updateHandlerUnderTest = IconCacheUpdateHandler(baseIconCache)
val cn = ComponentName.unflattenFromString("com.android.fake/.FakeActivity")!!
val testObj = TestCachedObject(cn, "freshId")
val result =
updateHandlerUnderTest.updateOrDeleteIcon(
createCursor(1, cn.flattenToString(), "freshId-old"),
hashMapOf(cn to testObj),
setOf(),
myUserHandle(),
cachingLogic,
)
assertThat(result).isEqualTo(testObj)
}
private fun createCursor(row: Long, component: String, appState: String) =
MatrixCursor(
arrayOf(IconDB.COLUMN_ROWID, IconDB.COLUMN_COMPONENT, IconDB.COLUMN_FRESHNESS_ID)
)
.apply { addRow(arrayOf(row, component, appState)) }
.apply {
cursor = this
moveToNext()
}
}
/** Utility method to wait for the icon update handler to finish */
fun IconCache.waitForUpdateHandlerToFinish() {
var cacheUpdateInProgress = true
while (cacheUpdateInProgress) {
val cacheCheck = FutureTask {
// Check for pending message on the worker thread itself as some task may be
// running currently
workerHandler.hasMessages(0, iconUpdateToken)
}
workerHandler.postDelayed(cacheCheck, 10)
RoboApiWrapper.waitForLooperSync(workerHandler.looper)
cacheUpdateInProgress = cacheCheck.get()
}
}
class TestCachedObject(val cn: ComponentName, val freshnessId: String) : CachedObject {
override fun getComponent() = cn
override fun getUser() = myUserHandle()
override fun getLabel(): CharSequence? = null
override fun getApplicationInfo(): ApplicationInfo? = null
override fun getFreshnessIdentifier(iconProvider: IconProvider): String? = freshnessId
}