mirror of
https://github.com/bitwarden/android.git
synced 2025-12-10 19:17:16 -06:00
[BWA-162] Add getPackageInstallationSourceOrNull to BitwardenPackageManager (#5418)
This commit is contained in:
parent
b94d59ba6b
commit
5f525d9d95
@ -4,6 +4,14 @@ package com.bitwarden.data.manager
|
||||
* Abstraction for interacting with Android package manager.
|
||||
*/
|
||||
interface BitwardenPackageManager {
|
||||
|
||||
/**
|
||||
* Gets the package installation source. The result may be `null` if the package is not
|
||||
* installed, the package is a system application, or the installing application has been
|
||||
* uninstalled.
|
||||
*/
|
||||
fun getPackageInstallationSourceOrNull(packageName: String): String?
|
||||
|
||||
/**
|
||||
* Checks if the package is installed.
|
||||
*/
|
||||
|
||||
@ -2,6 +2,7 @@ package com.bitwarden.data.manager
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import com.bitwarden.core.util.isBuildVersionAtLeast
|
||||
|
||||
/**
|
||||
* Primary implementation of [BitwardenPackageManager].
|
||||
@ -12,9 +13,24 @@ class BitwardenPackageManagerImpl(
|
||||
|
||||
private val nativePackageManager = context.packageManager
|
||||
|
||||
override fun getPackageInstallationSourceOrNull(packageName: String): String? =
|
||||
try {
|
||||
if (isBuildVersionAtLeast(Build.VERSION_CODES.R)) {
|
||||
nativePackageManager
|
||||
.getInstallSourceInfo(packageName)
|
||||
.installingPackageName
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
nativePackageManager
|
||||
.getInstallerPackageName(packageName)
|
||||
}
|
||||
} catch (_: PackageManager.NameNotFoundException) {
|
||||
null
|
||||
}
|
||||
|
||||
override fun isPackageInstalled(packageName: String): Boolean {
|
||||
return try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
if (isBuildVersionAtLeast(Build.VERSION_CODES.TIRAMISU)) {
|
||||
nativePackageManager.getApplicationInfo(
|
||||
packageName,
|
||||
PackageManager.ApplicationInfoFlags.of(0L),
|
||||
|
||||
@ -3,13 +3,19 @@ package com.bitwarden.data.manager
|
||||
import android.content.Context
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.PackageManager
|
||||
import com.bitwarden.core.util.isBuildVersionAtLeast
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.unmockkStatic
|
||||
import io.mockk.verify
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertNull
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class BitwardenPackageManagerTest {
|
||||
|
||||
@ -19,10 +25,33 @@ class BitwardenPackageManagerTest {
|
||||
}
|
||||
private val bitwardenPackageManager = BitwardenPackageManagerImpl(context)
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
mockkStatic(
|
||||
PackageManager.ApplicationInfoFlags::of,
|
||||
::isBuildVersionAtLeast,
|
||||
)
|
||||
// Set the default API level to simulate the latest version
|
||||
every { isBuildVersionAtLeast(any()) } returns true
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
unmockkStatic(
|
||||
PackageManager.ApplicationInfoFlags::of,
|
||||
::isBuildVersionAtLeast,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isPackageInstalled returns true for installed package`() {
|
||||
val packageName = "com.example.installed"
|
||||
every { mockPackageManager.getApplicationInfo(packageName, 0) } returns ApplicationInfo()
|
||||
every {
|
||||
mockPackageManager.getApplicationInfo(
|
||||
packageName,
|
||||
PackageManager.ApplicationInfoFlags.of(0L),
|
||||
)
|
||||
} returns ApplicationInfo()
|
||||
val result = bitwardenPackageManager.isPackageInstalled(packageName)
|
||||
assertTrue(result)
|
||||
}
|
||||
@ -31,7 +60,10 @@ class BitwardenPackageManagerTest {
|
||||
fun `isPackageInstalled returns false for non existent package`() {
|
||||
val packageName = "com.example.nonexistent"
|
||||
every {
|
||||
mockPackageManager.getApplicationInfo(packageName, 0)
|
||||
mockPackageManager.getApplicationInfo(
|
||||
packageName,
|
||||
PackageManager.ApplicationInfoFlags.of(0L),
|
||||
)
|
||||
} throws PackageManager.NameNotFoundException()
|
||||
val result = bitwardenPackageManager.isPackageInstalled(packageName)
|
||||
assertFalse(result)
|
||||
@ -41,7 +73,10 @@ class BitwardenPackageManagerTest {
|
||||
fun `isPackageInstalled handles empty package name`() {
|
||||
val packageName = ""
|
||||
every {
|
||||
mockPackageManager.getApplicationInfo(packageName, 0)
|
||||
mockPackageManager.getApplicationInfo(
|
||||
packageName,
|
||||
PackageManager.ApplicationInfoFlags.of(0L),
|
||||
)
|
||||
} throws PackageManager.NameNotFoundException()
|
||||
val result = bitwardenPackageManager.isPackageInstalled(packageName)
|
||||
assertFalse(result)
|
||||
@ -51,12 +86,27 @@ class BitwardenPackageManagerTest {
|
||||
fun `isPackageInstalled handles package name with special characters`() {
|
||||
val packageName = "com.example.invalid name!"
|
||||
every {
|
||||
mockPackageManager.getApplicationInfo(packageName, 0)
|
||||
mockPackageManager.getApplicationInfo(
|
||||
packageName,
|
||||
PackageManager.ApplicationInfoFlags.of(0L),
|
||||
)
|
||||
} throws PackageManager.NameNotFoundException()
|
||||
val result = bitwardenPackageManager.isPackageInstalled(packageName)
|
||||
assertFalse(result)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `isPackageInstalled invokes correct getApplicationInfo overload when API level is below 33`() {
|
||||
val packageName = "com.example.installed"
|
||||
every { isBuildVersionAtLeast(33) } returns false
|
||||
every {
|
||||
mockPackageManager.getApplicationInfo(packageName, 0)
|
||||
} returns mockk()
|
||||
bitwardenPackageManager.isPackageInstalled(packageName)
|
||||
verify { mockPackageManager.getApplicationInfo(packageName, 0) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getAppLabelForPackageOrNull returns correct label for installed package`() {
|
||||
val packageName = "com.example.installed"
|
||||
@ -107,4 +157,59 @@ class BitwardenPackageManagerTest {
|
||||
val result = bitwardenPackageManager.getAppLabelForPackageOrNull(packageName)
|
||||
assertNull(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getPackageInstallationSourceOrNull returns correct source for installed package`() {
|
||||
val packageName = "com.example.installed"
|
||||
val installationSource = "com.example.source"
|
||||
every { mockPackageManager.getInstallSourceInfo(packageName) } returns mockk {
|
||||
every { installingPackageName } returns installationSource
|
||||
}
|
||||
val result = bitwardenPackageManager.getPackageInstallationSourceOrNull(packageName)
|
||||
assertEquals(installationSource, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getPackageInstallationSourceOrNull returns null when installation source is null`() {
|
||||
val packageName = "com.example.installed"
|
||||
every {
|
||||
mockPackageManager.getInstallSourceInfo(packageName)
|
||||
} returns mockk {
|
||||
every { installingPackageName } returns null
|
||||
}
|
||||
val result = bitwardenPackageManager.getPackageInstallationSourceOrNull(packageName)
|
||||
assertNull(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getPackageInstallationSourceOrNull returns null for non existent package`() {
|
||||
val packageName = "com.example.nonexistent"
|
||||
every {
|
||||
mockPackageManager.getInstallSourceInfo(packageName)
|
||||
} throws PackageManager.NameNotFoundException()
|
||||
val result = bitwardenPackageManager.getPackageInstallationSourceOrNull(packageName)
|
||||
assertNull(result)
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
@Test
|
||||
fun `getPackageInstallationSourceOrNull invokes getInstallerPackageName on API 29 or lower`() {
|
||||
val packageName = "com.example.installed"
|
||||
val installationSource = "com.example.source"
|
||||
every { isBuildVersionAtLeast(30) } returns false
|
||||
every { mockPackageManager.getInstallerPackageName(packageName) } returns installationSource
|
||||
bitwardenPackageManager.getPackageInstallationSourceOrNull(packageName)
|
||||
verify { mockPackageManager.getInstallerPackageName(packageName) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getPackageInstallationSourceOrNull invokes getInstallSourceInfo on API 30 or higher`() {
|
||||
val packageName = "com.example.installed"
|
||||
val installationSource = "com.example.source"
|
||||
every { mockPackageManager.getInstallSourceInfo(packageName) } returns mockk {
|
||||
every { installingPackageName } returns installationSource
|
||||
}
|
||||
bitwardenPackageManager.getPackageInstallationSourceOrNull(packageName)
|
||||
verify { mockPackageManager.getInstallSourceInfo(packageName) }
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user