feat: app repository for list and launch apps
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
package top.yeij.hearth.app
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
|
||||
data class AppInfo(val packageName: String, val label: String, val iconBase64: String?)
|
||||
|
||||
interface AppSource {
|
||||
fun queryLaunchableApps(): List<AppInfo>
|
||||
fun launch(packageName: String): Boolean
|
||||
}
|
||||
|
||||
class AndroidAppSource(private val context: Context) : AppSource {
|
||||
override fun queryLaunchableApps(): List<AppInfo> {
|
||||
val pm = context.packageManager
|
||||
val intent = Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
return pm.queryIntentActivities(intent, 0).map { ri ->
|
||||
val pkg = ri.activityInfo.packageName
|
||||
AppInfo(pkg, ri.loadLabel(pm).toString(), null /* 图标 base64 在 Task 5 补 */)
|
||||
}
|
||||
}
|
||||
|
||||
override fun launch(packageName: String): Boolean {
|
||||
val i = context.packageManager.getLaunchIntentForPackage(packageName) ?: return false
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
context.startActivity(i)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
class AppRepository(private val source: AppSource) {
|
||||
private val gson = com.google.gson.Gson()
|
||||
|
||||
fun listApps(): String {
|
||||
Log.d("HearthBridge", "listApps: ${source.queryLaunchableApps().size} apps")
|
||||
return gson.toJson(source.queryLaunchableApps())
|
||||
}
|
||||
|
||||
fun launchApp(packageName: String): Boolean = source.launch(packageName)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package top.yeij.hearth.app
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
class AppRepositoryTest {
|
||||
@Test
|
||||
fun listApps_returnsLauncherAppsJson() {
|
||||
val repo = AppRepository(FakeAppSource(listOf(FakeApp("com.x.music", "音乐"))))
|
||||
val json = repo.listApps()
|
||||
assertTrue(json.contains("\"packageName\":\"com.x.music\""))
|
||||
assertTrue(json.contains("\"label\":\"音乐\""))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun launchApp_unknownPackage_returnsFalse() {
|
||||
val repo = AppRepository(FakeAppSource(emptyList()))
|
||||
assertEquals(false, repo.launchApp("com.nope"))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package top.yeij.hearth.app
|
||||
|
||||
// 测试用假源:返回固定应用列表,避免依赖 Android Context/PackageManager
|
||||
// Test fake source: returns a fixed app list, avoiding dependency on Android Context/PackageManager
|
||||
class FakeAppSource(private val apps: List<AppInfo>) : AppSource {
|
||||
override fun queryLaunchableApps(): List<AppInfo> = apps
|
||||
|
||||
override fun launch(packageName: String): Boolean = apps.any { it.packageName == packageName }
|
||||
}
|
||||
|
||||
// 测试用 AppInfo 构造辅助函数
|
||||
// Test helper to construct an AppInfo
|
||||
fun FakeApp(packageName: String, label: String): AppInfo = AppInfo(packageName, label, null)
|
||||
Reference in New Issue
Block a user