Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0ed06e0e authored by Chaohui Wang's avatar Chaohui Wang
Browse files

Add ApplicationInfosTest for Spa privileged lib

And some other tests.

Bug: 260660819
Test: Unit test
Change-Id: I8ed1835cab50030a9dd8652d6a454ed5510ba519
parent 818be438
Loading
Loading
Loading
Loading
+1 −9
Original line number Diff line number Diff line
@@ -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
        }

    private fun Int.hasFlag(flag: Int) = (this and flag) > 0
}
+134 −18
Original line number Diff line number Diff line
@@ -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
            }
        }
    }
}
+157 −0
Original line number Diff line number Diff line
/*
 * 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"
    }
}
+79 −12
Original line number Diff line number Diff line
@@ -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
}