Iris: "the organization of the rust rewrite is a mess right now... there shouldn't be anything related to the app inside of iris. Iris is supposed to be the UI framework alone." And, on the crate count: "I'm confused why the app only code needs more than one crate though." Nine cargo workspaces become three, and the port's project code -- which sat in five places, four of them inside the framework -- becomes one crate, `ai-app`, in `app-rust/`: client-core -> app-rust/src/client iris/transcript-ui -> app-rust/src/ui iris/transcript-fixture -> app-rust/src/ui/fixture.rs + tests/ + touch/ iris/desktop-app -> app-rust/src/desktop + src/bin_desktop.rs iris/android-app -> app-rust/src/android + android-project/ android-shell -> app-rust/src/shell iris/ keeps core, macro, the iris crate, tabs-ui and rig-input, and now mentions no session, transcript, setup or server anywhere. Only two of the old splits had a reason that survived reading. event-model stays a crate at the repo root because server/ depends on it too, so a crate is what makes the backend and the app agree by construction. The two Android .so names looked like a hard constraint -- a package produces one library artifact -- until P2 turned out to already plan merging those two Android apps into one; both faces now come out of libai_app.so, picked apart by features so `--no-default-features --features shell` keeps wgpu, parley and iris out of the Compose app's APK. docs/RUST.md's "One app crate" has the rest, including what each remaining feature is for. DECISIONS.md and SUBAGENTS.md move into docs/ with everything else. Verified: ./run-tests.sh and `cd iris && cargo test` green, clippy and fmt clean in all five workspaces, `cargo ndk -t x86_64` links libai_app.so, build-apk.sh produces an APK that installs and launches on this checkout's emulator (Gl ... virgl, as expected), and the phone-sized headless screenshot renders the transcript unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
91 lines
4.2 KiB
Groovy
91 lines
4.2 KiB
Groovy
plugins {
|
|
id("com.android.application")
|
|
}
|
|
|
|
// The Rust side (this directory's Cargo.toml) is built separately with
|
|
// `cargo ndk`, straight into src/main/jniLibs/ -- see the repo-root
|
|
// AGENTS.md-style comment at the top of Cargo.toml for why this crate
|
|
// stays outside the main Rust workspace, and RUST.md's I2 for the exact
|
|
// build command.
|
|
android {
|
|
namespace = "dev.iris.android.demo"
|
|
compileSdk = 37
|
|
|
|
defaultConfig {
|
|
applicationId = "dev.iris.android.demo"
|
|
// 29, not 26: `iris::android::view`'s touch handler dates each
|
|
// sample with `MotionEvent.getEventTimeNanos` and
|
|
// `getHistoricalEventTimeNanos`, both API 29, and a missing JNI
|
|
// method there is a hard crash on the first touch rather than a
|
|
// degraded fling. Raised deliberately rather than guarded at
|
|
// runtime: nothing this app is built for runs below 29, and an
|
|
// untested fallback path is its own defect. `build-apk.sh`'s
|
|
// `cargo ndk -P` is kept at the same number.
|
|
minSdk = 29
|
|
// 37, matching `compileSdk` and the Compose app in `app/` -- which
|
|
// is the one part of this that is measured rather than reasoned:
|
|
// that app targets 37 and its keyboard does push the transcript up
|
|
// on Iris's phone, and this one targeted 34 and does not
|
|
// (2026-09-07). The emulator here is API 36 and the push-up works
|
|
// there at either target, so the target is the only difference the
|
|
// two devices do not share.
|
|
//
|
|
// The mechanism, stated as the reading it is: below targetSdk 35
|
|
// a window keeps the legacy behaviour, where `adjustResize` shrinks
|
|
// the window for the IME and `getInsets(ime()).bottom` therefore
|
|
// measures the overlap with an already-shrunk window -- zero, with
|
|
// nothing left to push up. `MainActivity`'s
|
|
// `setDecorFitsSystemWindows(false)` opts out of that, and on API
|
|
// 36 it still takes; Android 16 deprecated it and Android 17 is
|
|
// where it appears not to. At 35+ edge-to-edge is not opt-in, so
|
|
// the app is handed the real overlap without relying on a
|
|
// deprecated call. If the phone still reports `ime_bottom=0` with
|
|
// a nonzero `dispatches` in the Diagnostics pane, this reading was
|
|
// wrong and the `WindowInsetsAnimation.Callback` in
|
|
// `MainActivity` is the other half to look at.
|
|
targetSdk = 37
|
|
versionCode = 1
|
|
versionName = "1.0"
|
|
}
|
|
|
|
// A release build must be signed, and the key is per machine rather than per repo -- same
|
|
// reasoning and the same key as `app/build-apk.sh` (the Compose app): it is what a phone
|
|
// recognises the app by, and a secret never lives in a checkout (the mount is shared with an
|
|
// untrusted VM). `build-apk.sh` generates this key once and points at it through the
|
|
// environment; without it a release build here is unsigned, which is fine for everything
|
|
// except installing.
|
|
def keystore = System.getenv("AI_APP_KEYSTORE")
|
|
signingConfigs {
|
|
if (keystore != null) {
|
|
release {
|
|
storeFile = file(keystore)
|
|
storePassword = System.getenv("AI_APP_KEYSTORE_PASSWORD")
|
|
keyAlias = "ai-app"
|
|
keyPassword = storePassword
|
|
}
|
|
}
|
|
}
|
|
|
|
buildTypes {
|
|
debug {
|
|
}
|
|
// P0's iris half (docs/RUST.md's P0 box): the build a phone actually runs. The `.so`
|
|
// itself is built separately with `cargo ndk --release --features "transcript-screen
|
|
// force-gles bench"` straight into src/main/jniLibs/ (this crate's own Cargo.toml) --
|
|
// Gradle here only packages and signs whatever is already there, the same division as the
|
|
// debug/tabs-screen build this project started with. `applicationIdSuffix` keeps it
|
|
// installable beside a debug build of the tabs demo rather than replacing it.
|
|
release {
|
|
applicationIdSuffix ".bench"
|
|
if (keystore != null) {
|
|
signingConfig = signingConfigs.release
|
|
}
|
|
}
|
|
}
|
|
|
|
compileOptions {
|
|
sourceCompatibility = JavaVersion.VERSION_17
|
|
targetCompatibility = JavaVersion.VERSION_17
|
|
}
|
|
}
|