mirror of
https://github.com/bitwarden/android.git
synced 2026-04-29 20:38: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