feat : implement gesture assistantHandler option

- closes : #5240
This commit is contained in:
MrSluffy
2025-02-13 19:24:20 +08:00
parent aaca2964a6
commit d67eded848
5 changed files with 71 additions and 0 deletions
+1
View File
@@ -472,6 +472,7 @@
<string name="gesture_handler_open_app_drawer">Open app drawer</string>
<string name="gesture_handler_open_app_search">Open app search</string>
<string name="gesture_handler_open_search">Open search</string>
<string name="gesture_handler_open_assistant">Open assistant</string>
<string name="pick_app_for_gesture">Pick app</string>
@@ -7,6 +7,7 @@ import app.lawnchair.gestures.handlers.OpenAppDrawerGestureHandler
import app.lawnchair.gestures.handlers.OpenAppGestureHandler
import app.lawnchair.gestures.handlers.OpenAppSearchGestureHandler
import app.lawnchair.gestures.handlers.OpenAppTarget
import app.lawnchair.gestures.handlers.OpenAssistantHandler
import app.lawnchair.gestures.handlers.OpenNotificationsHandler
import app.lawnchair.gestures.handlers.OpenSearchGestureHandler
import app.lawnchair.gestures.handlers.RecentsGestureHandler
@@ -61,6 +62,10 @@ sealed class GestureHandlerConfig {
@SerialName("openSearch")
data object OpenSearch : Simple(R.string.gesture_handler_open_search, ::OpenSearchGestureHandler)
@Serializable
@SerialName("openAssistant")
data object OpenAssistant : Simple(R.string.gesture_handler_open_assistant, ::OpenAssistantHandler)
@Serializable
@SerialName("openApp")
data class OpenApp(val appName: String, val target: OpenAppTarget) : GestureHandlerConfig() {
@@ -30,6 +30,7 @@ sealed class GestureHandlerOption(
data object OpenAppDrawer : Simple(GestureHandlerConfig.OpenAppDrawer)
data object OpenAppSearch : Simple(GestureHandlerConfig.OpenAppSearch)
data object OpenSearch : Simple(GestureHandlerConfig.OpenSearch)
data object OpenAssistant : Simple(GestureHandlerConfig.OpenAssistant)
data object OpenApp : GestureHandlerOption(
R.string.gesture_handler_open_app_option,
@@ -0,0 +1,63 @@
package app.lawnchair.gestures.handlers
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.provider.Settings
import android.util.Log
import app.lawnchair.LawnchairLauncher
class OpenAssistantHandler(context: Context) : GestureHandler(context) {
override suspend fun onTrigger(launcher: LawnchairLauncher) {
try {
val component = getCurrentlySelectedDefaultAssistant(context)
Log.d(TAG, "Detected assistant: $component")
when {
component == null -> noValidAssistantFound()
isActivity(component) -> launchIntent(Intent(Intent.ACTION_ASSIST).setComponent(component))
isService(component) -> launchIntent(Intent(Intent.ACTION_VOICE_COMMAND))
isInstalled(component.packageName) -> launchIntent(context.packageManager.getLaunchIntentForPackage(component.packageName))
else -> noValidAssistantFound()
}
} catch (e: Exception) {
Log.e(TAG, "Error launching assistant", e)
noValidAssistantFound()
}
}
private fun launchIntent(intent: Intent?) {
intent?.apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
runCatching { context.startActivity(this) }
.onFailure { Log.e(TAG, "Failed to launch intent: $intent", it) }
} ?: Log.e(TAG, "Intent is null, cannot launch.")
}
private fun noValidAssistantFound() {
Log.e(TAG, "No valid assistant found, opening voice input settings.")
launchIntent(Intent(Settings.ACTION_VOICE_INPUT_SETTINGS))
}
private fun getCurrentlySelectedDefaultAssistant(context: Context): ComponentName? = Settings.Secure.getString(context.contentResolver, "assistant")
?.takeIf { it.isNotEmpty() }
?.let(ComponentName::unflattenFromString)
?: context.packageManager.resolveActivity(Intent(Intent.ACTION_ASSIST), PackageManager.MATCH_DEFAULT_ONLY)
?.activityInfo?.let { ComponentName(it.packageName, it.name) }
private fun isActivity(component: ComponentName) = context.packageManager.queryIntentActivities(Intent().setComponent(component), PackageManager.MATCH_DEFAULT_ONLY).isNotEmpty()
private fun isService(component: ComponentName) = context.packageManager.getInstalledPackages(PackageManager.GET_SERVICES)
.any { it.packageName == component.packageName && it.services?.any { service -> service.name == component.className } == true }
private fun isInstalled(packageName: String) = runCatching {
context.packageManager.getPackageInfo(packageName, 0)
true
}.getOrDefault(false)
companion object {
private const val TAG = "OpenAssistantHandler"
}
}
@@ -32,6 +32,7 @@ val options = listOf(
GestureHandlerOption.OpenAppSearch,
GestureHandlerOption.OpenSearch,
GestureHandlerOption.OpenApp,
GestureHandlerOption.OpenAssistant,
)
@Composable