Show installed packages in Agent picker

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Iliyan Malchev
2026-03-21 23:42:49 -07:00
parent 4b8c2098c9
commit 7a19620340
2 changed files with 34 additions and 19 deletions

View File

@@ -154,19 +154,39 @@ class CreateSessionDialogController(
}
private fun showInstalledAppPicker(onSelected: (InstalledApp) -> Unit) {
val apps = InstalledAppCatalog.listLaunchableApps(activity, sessionController)
val apps = InstalledAppCatalog.listInstalledApps(activity, sessionController)
if (apps.isEmpty()) {
AlertDialog.Builder(activity)
.setMessage("No launchable target apps are available for Agent sessions.")
.setMessage("No installed target packages are available.")
.setPositiveButton(android.R.string.ok, null)
.show()
return
}
val labels = apps.map { app -> "${app.label} (${app.packageName})" }.toTypedArray()
val labels = apps.map { app ->
buildString {
append(app.label)
append(" (")
append(app.packageName)
append(")")
if (!app.eligibleTarget) {
append(" — unavailable")
}
}
}.toTypedArray()
AlertDialog.Builder(activity)
.setTitle("Choose app")
.setTitle("Choose package")
.setItems(labels) { _, which ->
onSelected(apps[which])
val app = apps[which]
if (!app.eligibleTarget) {
AlertDialog.Builder(activity)
.setMessage(
"The current framework rejected ${app.packageName} as a target for Genie sessions on this device.",
)
.setPositiveButton(android.R.string.ok, null)
.show()
return@setItems
}
onSelected(app)
}
.setNegativeButton(android.R.string.cancel, null)
.show()

View File

@@ -1,13 +1,13 @@
package com.openai.codex.agent
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
data class InstalledApp(
val packageName: String,
val label: String,
val eligibleTarget: Boolean,
)
object InstalledAppCatalog {
@@ -17,32 +17,27 @@ object InstalledAppCatalog {
"com.openai.codexd",
)
fun listLaunchableApps(
fun listInstalledApps(
context: Context,
sessionController: AgentSessionController,
): List<InstalledApp> {
val pm = context.packageManager
val launcherIntent = Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_LAUNCHER)
val launchableActivities = pm.queryIntentActivities(launcherIntent, PackageManager.MATCH_ALL)
val installedApplications = pm.getInstalledApplications(PackageManager.MATCH_ALL)
val appsByPackage = linkedMapOf<String, InstalledApp>()
launchableActivities.forEach { resolveInfo ->
val packageName = resolveInfo.packageNameOrNull() ?: return@forEach
if (packageName in excludedPackages || !sessionController.canStartSessionForTarget(packageName)) {
installedApplications.forEach { applicationInfo ->
val packageName = applicationInfo.packageName.takeIf(String::isNotBlank) ?: return@forEach
if (packageName in excludedPackages) {
return@forEach
}
val label = resolveInfo.loadLabel(pm)?.toString().orEmpty().ifBlank { packageName }
val label = applicationInfo.loadLabel(pm)?.toString().orEmpty().ifBlank { packageName }
appsByPackage[packageName] = InstalledApp(
packageName = packageName,
label = label,
eligibleTarget = sessionController.canStartSessionForTarget(packageName),
)
}
return appsByPackage.values.sortedWith(
compareBy<InstalledApp>({ it.label.lowercase() }).thenBy { it.packageName },
)
}
private fun ResolveInfo.packageNameOrNull(): String? {
return activityInfo?.applicationInfo?.packageName?.takeIf(String::isNotBlank)
}
}