tools.hermes-voice: Android wrapper as digital assistant
packages.hermes-voice-android builds an unsigned APK (us.lassul.assist,
"Assist") that opens https://assist.lassul.us/ as a Trusted Web
Activity, so Chrome handles the mic permission and the stored access
token exactly as in the browser. Its single activity is the launcher
entry and handles android.intent.action.ASSIST. That is enough to be
offered under Default apps > Digital assistant app: the ASSISTANT
role's AssistantRoleBehavior (packages/modules/Permission) qualifies a
package either by an assist-capable VoiceInteractionService or by an
exported activity resolving ACTION_ASSIST, with no system-app check.
The activity binds the first browser offering the TWA category, opens
a session and launches the TWA intent; without such a browser it opens
a Custom Tab, which other browsers treat as a plain VIEW intent. It
stays below the page in the task and finishes when returned to.
The build is plain aapt2 + javac + d8 from androidenv (build-tools and
platform 36; the SDK is unfree, so androidenv comes from a nixpkgs
instance with allowUnfree and the license accepted). The only library
is androidx.browser 1.10.0's classes.jar (AAR from Google Maven, 289
KB): the client, session and TWA intent builder used here need none of
its dependencies (androidx.core is only referenced by launchUrl-style
helpers, which are not called). The APK is 72 KB and byte-identical
across rebuilds (fixed zip timestamps).
packages.hermes-voice-android-sign zipaligns and signs it with
apksigner (v1-v3, no .idsig) from a keystore and password file, by
default the packaged unsigned APK, and prints the certificate so it
can be compared with assetlinks.json.
tools.hermes-voice: Android wrapper as digital assistant
packages.hermes-voice-android builds an unsigned APK (us.lassul.assist,
"Assist") that opens https://assist.lassul.us/ as a Trusted Web
Activity, so Chrome handles the mic permission and the stored access
token exactly as in the browser. Its single activity is the launcher
entry and handles android.intent.action.ASSIST. That is enough to be
offered under Default apps > Digital assistant app: the ASSISTANT
role's AssistantRoleBehavior (packages/modules/Permission) qualifies a
package either by an assist-capable VoiceInteractionService or by an
exported activity resolving ACTION_ASSIST, with no system-app check.
The activity binds the first browser offering the TWA category, opens
a session and launches the TWA intent; without such a browser it opens
a Custom Tab, which other browsers treat as a plain VIEW intent. It
stays below the page in the task and finishes when returned to.
The build is plain aapt2 + javac + d8 from androidenv (build-tools and
platform 36; the SDK is unfree, so androidenv comes from a nixpkgs
instance with allowUnfree and the license accepted). The only library
is androidx.browser 1.10.0's classes.jar (AAR from Google Maven, 289
KB): the client, session and TWA intent builder used here need none of
its dependencies (androidx.core is only referenced by launchUrl-style
helpers, which are not called). The APK is 72 KB and byte-identical
across rebuilds (fixed zip timestamps).
packages.hermes-voice-android-sign zipaligns and signs it with
apksigner (v1-v3, no .idsig) from a keystore and password file, by
default the packaged unsigned APK, and prints the certificate so it
can be compared with assetlinks.json.
tools.hermes-voice: Android wrapper as digital assistant
packages.hermes-voice-android builds an unsigned APK (us.lassul.assist,
"Assist") that opens https://assist.lassul.us/ as a Trusted Web
Activity, so Chrome handles the mic permission and the stored access
token exactly as in the browser. Its single activity is the launcher
entry and handles android.intent.action.ASSIST. That is enough to be
offered under Default apps > Digital assistant app: the ASSISTANT
role's AssistantRoleBehavior (packages/modules/Permission) qualifies a
package either by an assist-capable VoiceInteractionService or by an
exported activity resolving ACTION_ASSIST, with no system-app check.
The activity binds the first browser offering the TWA category, opens
a session and launches the TWA intent; without such a browser it opens
a Custom Tab, which other browsers treat as a plain VIEW intent. It
stays below the page in the task and finishes when returned to.
The build is plain aapt2 + javac + d8 from androidenv (build-tools and
platform 36; the SDK is unfree, so androidenv comes from a nixpkgs
instance with allowUnfree and the license accepted). The only library
is androidx.browser 1.10.0's classes.jar (AAR from Google Maven, 289
KB): the client, session and TWA intent builder used here need none of
its dependencies (androidx.core is only referenced by launchUrl-style
helpers, which are not called). The APK is 72 KB and byte-identical
across rebuilds (fixed zip timestamps).
packages.hermes-voice-android-sign zipaligns and signs it with
apksigner (v1-v3, no .idsig) from a keystore and password file, by
default the packaged unsigned APK, and prints the certificate so it
can be compared with assetlinks.json.