mirror of
https://github.com/bitwarden/android.git
synced 2026-03-09 11:44:41 -05:00
[PM-22665] Add BitwardenPackageManager abstraction (#5360)
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
package com.bitwarden.data.manager
|
||||
|
||||
/**
|
||||
* Abstraction for interacting with Android package manager.
|
||||
*/
|
||||
interface BitwardenPackageManager {
|
||||
/**
|
||||
* Checks if the package is installed.
|
||||
*/
|
||||
fun isPackageInstalled(packageName: String): Boolean
|
||||
|
||||
/**
|
||||
* Gets the app name from the package name or null if the package name is not found.
|
||||
*/
|
||||
fun getAppLabelForPackageOrNull(packageName: String): String?
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.bitwarden.data.manager
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
|
||||
/**
|
||||
* Primary implementation of [BitwardenPackageManager].
|
||||
*/
|
||||
class BitwardenPackageManagerImpl(
|
||||
context: Context,
|
||||
) : BitwardenPackageManager {
|
||||
|
||||
private val nativePackageManager = context.packageManager
|
||||
|
||||
override fun isPackageInstalled(packageName: String): Boolean {
|
||||
return try {
|
||||
nativePackageManager.getApplicationInfo(packageName, 0)
|
||||
true
|
||||
} catch (_: PackageManager.NameNotFoundException) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
override fun getAppLabelForPackageOrNull(packageName: String): String? {
|
||||
return try {
|
||||
val appInfo = nativePackageManager.getApplicationInfo(packageName, 0)
|
||||
nativePackageManager
|
||||
.getApplicationLabel(appInfo)
|
||||
.toString()
|
||||
} catch (_: PackageManager.NameNotFoundException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.bitwarden.data.manager.di
|
||||
|
||||
import android.content.Context
|
||||
import com.bitwarden.data.manager.BitwardenPackageManager
|
||||
import com.bitwarden.data.manager.BitwardenPackageManagerImpl
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Provides managers in the data module.
|
||||
*/
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object DataManagerModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideBitwardenPackageManager(
|
||||
@ApplicationContext context: Context,
|
||||
): BitwardenPackageManager = BitwardenPackageManagerImpl(context = context)
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.bitwarden.data.manager
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.PackageManager
|
||||
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
|
||||
|
||||
class BitwardenPackageManagerTest {
|
||||
|
||||
private val mockPackageManager: PackageManager = mockk()
|
||||
private val context: Context = mockk {
|
||||
every { packageManager } returns mockPackageManager
|
||||
}
|
||||
private val bitwardenPackageManager = BitwardenPackageManagerImpl(context)
|
||||
|
||||
@Test
|
||||
fun `isPackageInstalled returns true for installed package`() {
|
||||
val packageName = "com.example.installed"
|
||||
every { mockPackageManager.getApplicationInfo(packageName, 0) } returns ApplicationInfo()
|
||||
val result = bitwardenPackageManager.isPackageInstalled(packageName)
|
||||
assertTrue(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isPackageInstalled returns false for non existent package`() {
|
||||
val packageName = "com.example.nonexistent"
|
||||
every {
|
||||
mockPackageManager.getApplicationInfo(packageName, 0)
|
||||
} throws PackageManager.NameNotFoundException()
|
||||
val result = bitwardenPackageManager.isPackageInstalled(packageName)
|
||||
assertFalse(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isPackageInstalled handles empty package name`() {
|
||||
val packageName = ""
|
||||
every {
|
||||
mockPackageManager.getApplicationInfo(packageName, 0)
|
||||
} throws PackageManager.NameNotFoundException()
|
||||
val result = bitwardenPackageManager.isPackageInstalled(packageName)
|
||||
assertFalse(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isPackageInstalled handles package name with special characters`() {
|
||||
val packageName = "com.example.invalid name!"
|
||||
every {
|
||||
mockPackageManager.getApplicationInfo(packageName, 0)
|
||||
} throws PackageManager.NameNotFoundException()
|
||||
val result = bitwardenPackageManager.isPackageInstalled(packageName)
|
||||
assertFalse(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getAppLabelForPackageOrNull returns correct label for installed package`() {
|
||||
val packageName = "com.example.installed"
|
||||
val appLabel = "Example App"
|
||||
val applicationInfo = ApplicationInfo()
|
||||
every { mockPackageManager.getApplicationInfo(packageName, 0) } returns applicationInfo
|
||||
every { mockPackageManager.getApplicationLabel(applicationInfo) } returns appLabel
|
||||
val result = bitwardenPackageManager.getAppLabelForPackageOrNull(packageName)
|
||||
assertEquals(appLabel, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getAppLabelForPackageOrNull returns null for non existent package`() {
|
||||
val packageName = "com.example.nonexistent"
|
||||
every {
|
||||
mockPackageManager.getApplicationInfo(packageName, 0)
|
||||
} throws PackageManager.NameNotFoundException()
|
||||
val result = bitwardenPackageManager.getAppLabelForPackageOrNull(packageName)
|
||||
assertNull(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getAppLabelForPackageOrNull handles package with no label`() {
|
||||
val packageName = "com.example.nolabel"
|
||||
val applicationInfo = ApplicationInfo()
|
||||
every { mockPackageManager.getApplicationInfo(packageName, 0) } returns applicationInfo
|
||||
every { mockPackageManager.getApplicationLabel(applicationInfo) } returns ""
|
||||
val result = bitwardenPackageManager.getAppLabelForPackageOrNull(packageName)
|
||||
assertEquals("", result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getAppLabelForPackageOrNull handles empty package name`() {
|
||||
val packageName = ""
|
||||
every {
|
||||
mockPackageManager.getApplicationInfo(packageName, 0)
|
||||
} throws PackageManager.NameNotFoundException()
|
||||
val result = bitwardenPackageManager.getAppLabelForPackageOrNull(packageName)
|
||||
assertNull(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getAppLabelForPackageOrNull handles package name with special characters`() {
|
||||
val packageName = "com.example.invalid name!"
|
||||
every {
|
||||
mockPackageManager.getApplicationInfo(packageName, 0)
|
||||
} throws PackageManager.NameNotFoundException()
|
||||
val result = bitwardenPackageManager.getAppLabelForPackageOrNull(packageName)
|
||||
assertNull(result)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user