To enable building ink-notes for Android, the workspace must be configured to produce a dynamic C library (cdylib) alongside the desktop binary, and provide an entrypoint that binds winit to Android's activity lifecycle.
Scope of Work
Update Cargo.toml:
Add crate-type = ["cdylib", "rlib"] under [lib].
Add conditional target dependencies for cfg(target_os = "android"): android-activity, winit (with matching Android feature flags to current eframe), and android_logger.
Configure [package.metadata.android] with package identifier eu.pansi.inknotes, min SDK 26, target SDK 34.
Abstract application entrypoint:
Ensure the core application initialization logic lives in lib.rs.
Keep src/main.rs guarded with #[cfg(not(target_os = "android"))] for desktop execution.
Implement #[no_mangle] fn android_main(app: AndroidApp) in src/lib.rs (guarded with #[cfg(target_os = "android")]).
Configure eframe::NativeOptions with options.event_loop_builder passing builder.with_android_app(app).
Initialize android_logger at start of android_main.
Acceptance Criteria
cargo check --target aarch64-linux-android succeeds without compiler errors.
Desktop builds (cargo build) continue to compile and run unaffected.
### Description
To enable building `ink-notes` for Android, the workspace must be configured to produce a dynamic C library (`cdylib`) alongside the desktop binary, and provide an entrypoint that binds `winit` to Android's activity lifecycle.
### Scope of Work
1. Update `Cargo.toml`:
- Add `crate-type = ["cdylib", "rlib"]` under `[lib]`.
- Add conditional target dependencies for `cfg(target_os = "android")`: `android-activity`, `winit` (with matching Android feature flags to current `eframe`), and `android_logger`.
- Configure `[package.metadata.android]` with package identifier `eu.pansi.inknotes`, min SDK 26, target SDK 34.
2. Abstract application entrypoint:
- Ensure the core application initialization logic lives in `lib.rs`.
- Keep `src/main.rs` guarded with `#[cfg(not(target_os = "android"))]` for desktop execution.
- Implement `#[no_mangle] fn android_main(app: AndroidApp)` in `src/lib.rs` (guarded with `#[cfg(target_os = "android")]`).
- Configure `eframe::NativeOptions` with `options.event_loop_builder` passing `builder.with_android_app(app)`.
- Initialize `android_logger` at start of `android_main`.
### Acceptance Criteria
- `cargo check --target aarch64-linux-android` succeeds without compiler errors.
- Desktop builds (`cargo build`) continue to compile and run unaffected.
Corrections after checking the code (planned for the future, not started)
ink-notes does not use eframe. It drives winit 0.29 (vendored and patched in vendor/winit), egui-winit 0.27 and wgpu 0.19 directly, so there is no eframe::NativeOptions. On Android:
enable the winit feature android-native-activity;
build the event loop with EventLoopBuilder::new().with_android_app(app) (winit::platform::android::EventLoopBuilderExtAndroid).
The Wayland patch in vendor/winit does not affect Android.
There is no InkNotesApp struct. The whole app is one event loop in src/main.rs (~4300 lines, fn main plus helpers). src/lib.rs only exports the modules. The first and largest step is to move the event loop into the library, e.g. ink_notes::run(event_loop, options), so that both main() and android_main() call it. The desktop behaviour must not change.
Several dependencies are Linux/desktop only and have to be gated with cfg(not(target_os = "android")) or replaced:
**Corrections after checking the code** (planned for the future, not started)
- ink-notes does not use **eframe**. It drives winit 0.29 (vendored and patched in `vendor/winit`), egui-winit 0.27 and wgpu 0.19 directly, so there is no `eframe::NativeOptions`. On Android:
- enable the winit feature `android-native-activity`;
- build the event loop with `EventLoopBuilder::new().with_android_app(app)` (`winit::platform::android::EventLoopBuilderExtAndroid`).
- The Wayland patch in `vendor/winit` does not affect Android.
- There is no `InkNotesApp` struct. The whole app is one event loop in `src/main.rs` (~4300 lines, `fn main` plus helpers). `src/lib.rs` only exports the modules. The first and largest step is to move the event loop into the library, e.g. `ink_notes::run(event_loop, options)`, so that both `main()` and `android_main()` call it. The desktop behaviour must not change.
- Several dependencies are Linux/desktop only and have to be gated with `cfg(not(target_os = "android"))` or replaced:
- `octotablet` (pen input, see #44)
- `wayland-client`, `wayland-backend` and `wayland-protocols` (on-screen keyboard, `src/osk.rs`)
- `arboard` (clipboard)
- `webbrowser`
- the self-updater (`src/updater.rs`)
- the built-in file picker that reads XDG user dirs (`src/file_picker.rs`)
- `fs2` file locks (probably fine, to be checked)
- wgpu on Android must create the surface only after `Resumed`, and drop it on `Suspended`. Currently the window and surface are created once at startup.
- `android_logger` is optional. The app logs with `eprintln!`, which goes nowhere on Android, so logging would need to switch to `log`.
Revised acceptance criteria stay the same:
- `cargo check --target aarch64-linux-android` passes.
- The desktop build and its tests are unchanged.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Description
To enable building
ink-notesfor Android, the workspace must be configured to produce a dynamic C library (cdylib) alongside the desktop binary, and provide an entrypoint that bindswinitto Android's activity lifecycle.Scope of Work
Cargo.toml:crate-type = ["cdylib", "rlib"]under[lib].cfg(target_os = "android"):android-activity,winit(with matching Android feature flags to currenteframe), andandroid_logger.[package.metadata.android]with package identifiereu.pansi.inknotes, min SDK 26, target SDK 34.lib.rs.src/main.rsguarded with#[cfg(not(target_os = "android"))]for desktop execution.#[no_mangle] fn android_main(app: AndroidApp)insrc/lib.rs(guarded with#[cfg(target_os = "android")]).eframe::NativeOptionswithoptions.event_loop_builderpassingbuilder.with_android_app(app).android_loggerat start ofandroid_main.Acceptance Criteria
cargo check --target aarch64-linux-androidsucceeds without compiler errors.cargo build) continue to compile and run unaffected.Corrections after checking the code (planned for the future, not started)
vendor/winit), egui-winit 0.27 and wgpu 0.19 directly, so there is noeframe::NativeOptions. On Android:android-native-activity;EventLoopBuilder::new().with_android_app(app)(winit::platform::android::EventLoopBuilderExtAndroid).vendor/winitdoes not affect Android.InkNotesAppstruct. The whole app is one event loop insrc/main.rs(~4300 lines,fn mainplus helpers).src/lib.rsonly exports the modules. The first and largest step is to move the event loop into the library, e.g.ink_notes::run(event_loop, options), so that bothmain()andandroid_main()call it. The desktop behaviour must not change.cfg(not(target_os = "android"))or replaced:octotablet(pen input, see #44)wayland-client,wayland-backendandwayland-protocols(on-screen keyboard,src/osk.rs)arboard(clipboard)webbrowsersrc/updater.rs)src/file_picker.rs)fs2file locks (probably fine, to be checked)Resumed, and drop it onSuspended. Currently the window and surface are created once at startup.android_loggeris optional. The app logs witheprintln!, which goes nowhere on Android, so logging would need to switch tolog.Revised acceptance criteria stay the same:
cargo check --target aarch64-linux-androidpasses.