Add ApplicationInfosTest for Spa privileged lib

And some other tests.

Bug: 260660819
Test: Unit test
Change-Id: I8ed1835cab50030a9dd8652d6a454ed5510ba519
This commit is contained in:
Chaohui Wang
2022-12-15 14:22:04 +08:00
parent 818be438cd
commit 0ed06e0e15
4 changed files with 371 additions and 39 deletions

View File

@@ -21,11 +21,8 @@ import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED
import android.content.pm.PackageManager
import android.util.Log
import com.android.settingslib.spa.framework.util.asyncFilter
private const val TAG = "PackageManagers"
interface IPackageManagers {
fun getPackageInfoAsUser(packageName: String, userId: Int): PackageInfo?
fun getApplicationInfoAsUser(packageName: String, userId: Int): ApplicationInfo?
@@ -94,12 +91,7 @@ internal class PackageManagersImpl(
}.toSet()
override fun getPackageInfoAsUser(packageName: String, flags: Int, userId: Int): PackageInfo? =
try {
packageManagerWrapper.getPackageInfoAsUserCached(packageName, flags.toLong(), userId)
} catch (e: PackageManager.NameNotFoundException) {
Log.w(TAG, "getPackageInfoAsUserCached() failed", e)
null
}
packageManagerWrapper.getPackageInfoAsUserCached(packageName, flags.toLong(), userId)
private fun Int.hasFlag(flag: Int) = (this and flag) > 0
}

View File

@@ -17,13 +17,17 @@
package com.android.settingslib.spaprivileged.model.app
import android.content.Context
import android.content.pm.ActivityInfo
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.PackageManager.ApplicationInfoFlags
import android.content.pm.PackageManager.ResolveInfoFlags
import android.content.pm.ResolveInfo
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Rule
@@ -51,24 +55,10 @@ class AppListRepositoryTest {
private lateinit var repository: AppListRepository
private val normalApp = ApplicationInfo().apply {
packageName = "normal"
enabled = true
}
private val instantApp = ApplicationInfo().apply {
packageName = "instant"
enabled = true
privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT
}
@Before
fun setUp() {
whenever(context.packageManager).thenReturn(packageManager)
whenever(packageManager.getInstalledModules(anyInt())).thenReturn(emptyList())
whenever(
packageManager.getInstalledApplicationsAsUser(any<ApplicationInfoFlags>(), eq(USER_ID))
).thenReturn(listOf(normalApp, instantApp))
whenever(
packageManager.queryIntentActivitiesAsUser(any(), any<ResolveInfoFlags>(), eq(USER_ID))
).thenReturn(emptyList())
@@ -76,25 +66,151 @@ class AppListRepositoryTest {
repository = AppListRepositoryImpl(context)
}
private fun mockInstalledApplications(apps: List<ApplicationInfo>) {
whenever(
packageManager.getInstalledApplicationsAsUser(any<ApplicationInfoFlags>(), eq(USER_ID))
).thenReturn(apps)
}
@Test
fun notShowInstantApps() = runTest {
fun loadApps_notShowInstantApps() = runTest {
mockInstalledApplications(listOf(NORMAL_APP, INSTANT_APP))
val appListConfig = AppListConfig(userId = USER_ID, showInstantApps = false)
val appListFlow = repository.loadApps(appListConfig)
assertThat(appListFlow).containsExactly(normalApp)
assertThat(appListFlow).containsExactly(NORMAL_APP)
}
@Test
fun showInstantApps() = runTest {
fun loadApps_showInstantApps() = runTest {
mockInstalledApplications(listOf(NORMAL_APP, INSTANT_APP))
val appListConfig = AppListConfig(userId = USER_ID, showInstantApps = true)
val appListFlow = repository.loadApps(appListConfig)
assertThat(appListFlow).containsExactly(normalApp, instantApp)
assertThat(appListFlow).containsExactly(NORMAL_APP, INSTANT_APP)
}
@Test
fun loadApps_isDisabledUntilUsed() = runTest {
val app = ApplicationInfo().apply {
packageName = "is.disabled.until.used"
enabled = false
enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
}
mockInstalledApplications(listOf(app))
val appListConfig = AppListConfig(userId = USER_ID, showInstantApps = false)
val appListFlow = repository.loadApps(appListConfig)
assertThat(appListFlow).containsExactly(app)
}
@Test
fun loadApps_disabled() = runTest {
val app = ApplicationInfo().apply {
packageName = "disabled"
enabled = false
}
mockInstalledApplications(listOf(app))
val appListConfig = AppListConfig(userId = USER_ID, showInstantApps = false)
val appListFlow = repository.loadApps(appListConfig)
assertThat(appListFlow).isEmpty()
}
@Test
fun showSystemPredicate_showSystem() = runTest {
val app = ApplicationInfo().apply {
flags = ApplicationInfo.FLAG_SYSTEM
}
val showSystemPredicate = getShowSystemPredicate(showSystem = true)
assertThat(showSystemPredicate(app)).isTrue()
}
@Test
fun showSystemPredicate_notShowSystemAndIsSystemApp() = runTest {
val app = ApplicationInfo().apply {
flags = ApplicationInfo.FLAG_SYSTEM
}
val showSystemPredicate = getShowSystemPredicate(showSystem = false)
assertThat(showSystemPredicate(app)).isFalse()
}
@Test
fun showSystemPredicate_isUpdatedSystemApp() = runTest {
val app = ApplicationInfo().apply {
flags = ApplicationInfo.FLAG_SYSTEM or ApplicationInfo.FLAG_UPDATED_SYSTEM_APP
}
val showSystemPredicate = getShowSystemPredicate(showSystem = false)
assertThat(showSystemPredicate(app)).isTrue()
}
@Test
fun showSystemPredicate_isHome() = runTest {
val app = ApplicationInfo().apply {
flags = ApplicationInfo.FLAG_SYSTEM
packageName = "home.app"
}
whenever(packageManager.getHomeActivities(any())).thenAnswer {
@Suppress("UNCHECKED_CAST")
val resolveInfos = it.arguments[0] as MutableList<ResolveInfo>
resolveInfos.add(resolveInfoOf(packageName = app.packageName))
null
}
val showSystemPredicate = getShowSystemPredicate(showSystem = false)
assertThat(showSystemPredicate(app)).isTrue()
}
@Test
fun showSystemPredicate_appInLauncher() = runTest {
val app = ApplicationInfo().apply {
flags = ApplicationInfo.FLAG_SYSTEM
packageName = "app.in.launcher"
}
whenever(
packageManager.queryIntentActivitiesAsUser(any(), any<ResolveInfoFlags>(), eq(USER_ID))
).thenReturn(listOf(resolveInfoOf(packageName = app.packageName)))
val showSystemPredicate = getShowSystemPredicate(showSystem = false)
assertThat(showSystemPredicate(app)).isTrue()
}
private suspend fun getShowSystemPredicate(showSystem: Boolean) =
repository.showSystemPredicate(
userIdFlow = flowOf(USER_ID),
showSystemFlow = flowOf(showSystem),
).first()
private companion object {
const val USER_ID = 0
val NORMAL_APP = ApplicationInfo().apply {
packageName = "normal"
enabled = true
}
val INSTANT_APP = ApplicationInfo().apply {
packageName = "instant"
enabled = true
privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT
}
fun resolveInfoOf(packageName: String) = ResolveInfo().apply {
activityInfo = ActivityInfo().apply {
this.packageName = packageName
}
}
}
}

View File

@@ -0,0 +1,157 @@
/*
* Copyright (C) 2022 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.settingslib.spaprivileged.model.app
import android.app.admin.DevicePolicyManager
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.os.UserManager
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager
import com.android.settingslib.spaprivileged.framework.common.userManager
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.Mock
import org.mockito.Spy
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
import org.mockito.Mockito.`when` as whenever
@RunWith(AndroidJUnit4::class)
class ApplicationInfosTest {
@get:Rule
val mockito: MockitoRule = MockitoJUnit.rule()
@Spy
private val context: Context = ApplicationProvider.getApplicationContext()
@Mock
private lateinit var userManager: UserManager
@Mock
private lateinit var devicePolicyManager: DevicePolicyManager
@Before
fun setUp() {
whenever(context.userManager).thenReturn(userManager)
whenever(context.devicePolicyManager).thenReturn(devicePolicyManager)
}
@Test
fun userId() {
val app = ApplicationInfo().apply {
uid = 123
}
val userId = app.userId
assertThat(userId).isEqualTo(0)
}
@Test
fun userHandle() {
val app = ApplicationInfo().apply {
uid = 123
}
val userHandle = app.userHandle
assertThat(userHandle.identifier).isEqualTo(0)
}
@Test
fun hasFlag() {
val app = ApplicationInfo().apply {
flags = ApplicationInfo.FLAG_INSTALLED
}
val hasFlag = app.hasFlag(ApplicationInfo.FLAG_INSTALLED)
assertThat(hasFlag).isTrue()
}
@Test
fun installed() {
val app = ApplicationInfo().apply {
flags = ApplicationInfo.FLAG_INSTALLED
}
val installed = app.installed
assertThat(installed).isTrue()
}
@Test
fun isDisabledUntilUsed() {
val app = ApplicationInfo().apply {
enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
}
val isDisabledUntilUsed = app.isDisabledUntilUsed
assertThat(isDisabledUntilUsed).isTrue()
}
@Test
fun isDisallowControl() {
val app = ApplicationInfo().apply {
uid = 123
}
whenever(
userManager.hasBaseUserRestriction(UserManager.DISALLOW_APPS_CONTROL, app.userHandle)
).thenReturn(true)
val isDisallowControl = app.isDisallowControl(context)
assertThat(isDisallowControl).isTrue()
}
@Test
fun isActiveAdmin() {
val app = ApplicationInfo().apply {
packageName = PACKAGE_NAME
uid = 123
}
whenever(devicePolicyManager.packageHasActiveAdmins(PACKAGE_NAME, app.userId))
.thenReturn(true)
val isActiveAdmin = app.isActiveAdmin(context)
assertThat(isActiveAdmin).isTrue()
}
@Test
fun toRoute() {
val app = ApplicationInfo().apply {
packageName = PACKAGE_NAME
uid = 123
}
val route = app.toRoute()
assertThat(route).isEqualTo("package.name/0")
}
private companion object {
const val PACKAGE_NAME = "package.name"
}
}

View File

@@ -30,6 +30,74 @@ class PackageManagersTest {
private val packageManagersImpl = PackageManagersImpl(fakePackageManagerWrapper)
@Test
fun getPackageInfoAsUser_notFound() {
fakePackageManagerWrapper.fakePackageInfo = null
val packageInfo = packageManagersImpl.getPackageInfoAsUser(PACKAGE_NAME, 0)
assertThat(packageInfo).isNull()
}
@Test
fun getPackageInfoAsUser_found() {
fakePackageManagerWrapper.fakePackageInfo = PackageInfo()
val packageInfo = packageManagersImpl.getPackageInfoAsUser(PACKAGE_NAME, 0)
assertThat(packageInfo).isSameInstanceAs(fakePackageManagerWrapper.fakePackageInfo)
}
@Test
fun hasRequestPermission_packageInfoIsNull_returnFalse() {
fakePackageManagerWrapper.fakePackageInfo = null
val hasRequestPermission = with(packageManagersImpl) {
APP.hasRequestPermission(PERMISSION_A)
}
assertThat(hasRequestPermission).isFalse()
}
@Test
fun hasRequestPermission_requestedPermissionsIsNull_returnFalse() {
fakePackageManagerWrapper.fakePackageInfo = PackageInfo().apply {
requestedPermissions = null
}
val hasRequestPermission = with(packageManagersImpl) {
APP.hasRequestPermission(PERMISSION_A)
}
assertThat(hasRequestPermission).isFalse()
}
@Test
fun hasRequestPermission_notRequested_returnFalse() {
fakePackageManagerWrapper.fakePackageInfo = PackageInfo().apply {
requestedPermissions = emptyArray()
}
val hasRequestPermission = with(packageManagersImpl) {
APP.hasRequestPermission(PERMISSION_A)
}
assertThat(hasRequestPermission).isFalse()
}
@Test
fun hasRequestPermission_requested_returnTrue() {
fakePackageManagerWrapper.fakePackageInfo = PackageInfo().apply {
requestedPermissions = arrayOf(PERMISSION_A)
}
val hasRequestPermission = with(packageManagersImpl) {
APP.hasRequestPermission(PERMISSION_A)
}
assertThat(hasRequestPermission).isTrue()
}
@Test
fun hasGrantPermission_packageInfoIsNull_returnFalse() {
fakePackageManagerWrapper.fakePackageInfo = null
@@ -43,7 +111,9 @@ class PackageManagersTest {
@Test
fun hasGrantPermission_requestedPermissionsIsNull_returnFalse() {
fakePackageManagerWrapper.fakePackageInfo = PackageInfo()
fakePackageManagerWrapper.fakePackageInfo = PackageInfo().apply {
requestedPermissions = null
}
val hasGrantPermission = with(packageManagersImpl) {
APP.hasGrantPermission(PERMISSION_A)
@@ -94,18 +164,8 @@ class PackageManagersTest {
assertThat(hasGrantPermission).isTrue()
}
private inner class FakePackageManagerWrapper : PackageManagerWrapper {
var fakePackageInfo: PackageInfo? = null
override fun getPackageInfoAsUserCached(
packageName: String,
flags: Long,
userId: Int,
): PackageInfo? = fakePackageInfo
}
private companion object {
const val PACKAGE_NAME = "packageName"
const val PACKAGE_NAME = "package.name"
const val PERMISSION_A = "permission.A"
const val PERMISSION_B = "permission.B"
const val UID = 123
@@ -115,3 +175,10 @@ class PackageManagersTest {
}
}
}
private class FakePackageManagerWrapper : PackageManagerWrapper {
var fakePackageInfo: PackageInfo? = null
override fun getPackageInfoAsUserCached(packageName: String, flags: Long, userId: Int) =
fakePackageInfo
}