Skip to content

chore(android): port NeurophoneService Kotlin→Java JNI shim (#83)#123

Open
hyperpolymath wants to merge 2 commits into
mainfrom
chore/gossamer-service
Open

chore(android): port NeurophoneService Kotlin→Java JNI shim (#83)#123
hyperpolymath wants to merge 2 commits into
mainfrom
chore/gossamer-service

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Sub-PR #5 — Port NeurophoneService (Kotlin → Java JNI shim)

Part of the Android Kotlin→Rust/Gossamer migration: epic #83, RFC PR #97, sub-issue #111.

Draft / depends on unmerged work. Sub-PR #3 (Gossamer scaffolding) and #4 (NativeLib→Rust JNI in crates/neurophone-android) are being built in parallel and are not merged. This PR bases off main, assumes their structure, and marks integration seams TODO(#83 rebase).

What changed

  • Removed android/app/src/main/java/ai/neurophone/NeurophoneService.kt (Kotlin foreground service that carried business logic + synthetic salience + widget publishing).
  • Added android/app/src/main/java/ai/neurophone/NeurophoneService.java — a minimal hand-written Java Service shim. Same class name (ai.neurophone.NeurophoneService), so the existing BootReceiver.kt, widget/NeurophoneAppWidget.kt, and the AndroidManifest.xml .NeurophoneService entry resolve to it unchanged.

JNI calls used (NativeLib, Kotlin objectNativeLib.INSTANCE)

  • onCreate()NativeLib.init(null) then NativeLib.start()
  • onDestroy()NativeLib.stop()
  • onSensorChanged()NativeLib.processSensor(typeId, values, timestampNs, accuracy)

All JNI calls are wrapped in try/catch (Throwable) so dev hardware without the native lib still runs (matches prior Kotlin behaviour).

Convenience mapping replicated

Sensor type → compact id (mirrors the old NativeLib.pushSensorEvent table):

sensor id
accelerometer 1
magnetometer 2
gyroscope 4
light 5
proximity 8
(else) 0

Timestamp converted ms → ns (System.currentTimeMillis() * 1_000_000L). Accuracy defaults to 3 (SENSOR_STATUS_ACCURACY_HIGH).

Kept thin (in scope)

Business logic stays in Rust. The shim keeps only the Android-owned concerns: foreground notification + channel, partial wake lock, and sensor registration (accelerometer only for now). Widgets / boot receiver / UI not ported.

Verification

  • Diff touches only files under android/ (one Java add, one Kotlin delete). No Rust or Cargo.* files changed → cargo behaviour is identical to main.
  • cargo build --workspace and cargo test --workspace fail on main already, in crates/lsm and crates/esn only (pre-existing rand 0.10 API drift: random()/sample() no longer resolve). This is unrelated to this PR and unaffected by it. The neurophone-android crate is an untouched stub and compiles.

TODOs / risks

  • TODO(#83 rebase): NativeLib JNI signatures depend on sub-PR chore(deps): update thiserror requirement from 1.0 to 2.0 #4 landing the Rust exports (init/start/stop/processSensor).
  • TODO(#83): widen sensor registration beyond accelerometer once the Rust core consumes the full set (the id mapping already covers them).
  • TODO(#83): foreground notification / wake lock should migrate behind Gossamer/Rust, shrinking or removing this shim with the rest of android/.
  • Risk: Java↔Kotlin-object interop uses NativeLib.INSTANCE; if chore(deps): update thiserror requirement from 1.0 to 2.0 #4 reimplements NativeLib as a Java class or changes the singleton shape, the call sites need a trivial rebase (flagged).

https://claude.ai/code/session_01Gu1JFCZHuBtBhAWPr4sMQw


Generated by Claude Code

Replace the Kotlin foreground Service with a minimal hand-written Java
Service shim that delegates all business logic to Rust via the
neurophone-android JNI boundary.

The shim:
- onCreate  -> NativeLib.init(null) + NativeLib.start()
- onDestroy -> NativeLib.stop()
- streams sensor events via
  NativeLib.processSensor(typeId, values, timestampNs, accuracy)

Replicates the prior Kotlin convenience mapping (sensor type -> id:
accelerometer=1, magnetometer=2, gyroscope=4, light=5, proximity=8,
else=0) and the ms->ns timestamp conversion. Synthetic salience and
widget publishing are dropped; those now belong to Rust.

Hand-written Java is permitted only under android/ (exempt via
.hypatia-baseline.json). Integration seams marked TODO(#83 rebase)
pending sub-PR #3 (Gossamer scaffolding) and #4 (NativeLib->Rust JNI).

No Rust/Cargo files touched; cargo workspace behaviour unchanged.

https://claude.ai/code/session_01Gu1JFCZHuBtBhAWPr4sMQw
@hyperpolymath hyperpolymath marked this pull request as ready for review June 3, 2026 21:08
@hyperpolymath hyperpolymath enabled auto-merge (squash) June 3, 2026 21:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants