E3: the Kotlin/Java shell over a JNI bridge into Rust (RUST.md)
Two Java classes (MainActivity, NotificationService) hand their lifecycle to a new android-shell crate built on client-core; client-core gains notifications.rs (the /notifications SSE parse and attention_line, ported from Notifications.kt). Packaged as a new app/shellApp Gradle module rather than a rewrite of app/androidApp in place, so that module's working Compose UI is untouched. Both pass conditions held on the emulator: a notification arrived in Android's drawer with the app closed, and a shared text share landed as a real message in a sandbox session's transcript. Found and fixed three real bugs along the way (a silently-wrong JNI signature from a generic JObject parameter, a class-by-name lookup failing on this crate's own background thread for lack of an app ClassLoader, and onStartCommand opening two /notifications connections per enrollment -- the last a latent bug in Notifications.kt itself). Full account, exact commands and what was deliberately cut are in RUST.md's E3 box. Co-Authored-By: Claude Sonnet <noreply@anthropic.com>
This commit is contained in:
1 parent
8adda94a7a
commit
c9b273ff16
16 files changed
+2996
-6
No files matched your search
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Mirrors androidApp's manifest (AGENTS.md: reuse it rather than
|
||||
re-deriving it) for the permissions and declarations E3 actually
|
||||
exercises. Not carried over: the QR scanner activity (this
|
||||
experiment enrolls via the aiappshell://enroll deep link directly,
|
||||
per AGENTS.md's ui-sandbox.sh banner) and the app icon warning
|
||||
suppression below, for the same reason androidApp's is there. -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_LOCAL_NETWORK" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
|
||||
|
||||
<application
|
||||
android:label="AI Sessions (shell)"
|
||||
android:allowBackup="true"
|
||||
android:theme="@android:style/Theme.Material.Light.NoActionBar"
|
||||
tools:ignore="MissingApplicationIcon">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<!-- Enrollment: aiappshell://enroll?host=...&port=...&token=...,
|
||||
per AGENTS.md's ui-sandbox.sh banner (fed to this app with
|
||||
`adb shell am start -a android.intent.action.VIEW -d
|
||||
'aiappshell://enroll?...'`, or -n'd at this component
|
||||
directly if a second app also claims the aiapp scheme). -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="aiappshell" android:host="enroll" />
|
||||
</intent-filter>
|
||||
<!-- The share sheet - see android-shell's share.rs. -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="*/*" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- specialUse, not dataSync, for the reason androidApp's manifest
|
||||
gives: a connection that has to keep listening overnight
|
||||
cannot accept dataSync's six-hour cap. -->
|
||||
<service
|
||||
android:name=".NotificationService"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="specialUse">
|
||||
<property
|
||||
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
|
||||
android:value="E3 experiment: holds one connection to the sandbox server so a
|
||||
session that needs an answer can be reported while the app is closed." />
|
||||
</service>
|
||||
</application>
|
||||
</manifest>
|
||||
Reference in new issue
Block a user