Android¶
Sioul on Android is an experiment: the same window, built for 64-bit ARM phones running Android 9 or later, installed by hand (an APK). It is not in a store, and parts of Sioul do not work there yet (below).
Building it¶
On GitHub: .github/workflows/android.yml runs on each push to main that touches the code or android/, and by hand (Actions, "Android", "Run workflow"). The APK is the run's artifact, sioul-android-arm64.
By hand, with:
- Qt for Android 6.11 (
android_arm64_v8a) with Qt Multimedia, Qt Positioning, Qt Location, Qt Image Formats and Qt SerialPort, and the desktop Qt of the same version, whose tools build for Android; - the Android SDK with the NDK Qt 6.11 is built with (r27c,
27.2.12479018), a platform (android-36) and its build tools; - Java 17 or newer, for Gradle;
- Rust with the phone's target:
rustup target add aarch64-linux-android.
<Qt for Android>/bin/qt-cmake -S android -B build-android -G Ninja \
-DCMAKE_BUILD_TYPE=Release -DQT_HOST_PATH=<desktop Qt> \
-DANDROID_SDK_ROOT=<SDK> -DANDROID_NDK_ROOT=<NDK> \
-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON
cmake --build build-android --target apk
build-android/…/outputs/apk/release/; apksigner (the SDK's build tools) signs it, as the workflow does.
How it is made¶
- The window is a library (
crates/sioul-app/src/lib.rs,run()): the desktop program (main.rs) calls it, and so does Android's (android/main.cpp, throughsioul_app_run). - Qt for Android builds the app around it with CMake (
android/CMakeLists.txt): Corrosion builds the crate with Cargo as a static library for the phone (OVERRIDE_CRATE_TYPE, so that desktop builds make the program alone); it is linked withmain.cppinto the library Qt's Java side loads,libsioul_arm64-v8a.so;androiddeployqtand Gradle make the APK, with the QML modules the pages import. - CXX-Qt's part is done by hand. CXX-Qt's own CMake function (
cxx_qt_import_crate) names a crate's export folder after its library (sioul_app), and its build script after its package (sioul-app): the CMake file sets the build script's variables itself and links the two object files it leaves (the QML module's registration). - What a desktop gives a program and Android does not,
main.cppsets before the window starts: the XDG folders, in the app's private storage (configuration, data and state among its files, the cache where Android may empty it);LANG, from the phone's language;SSL_CERT_DIR, the system's certificates; stdout and stderr sent to logcat (adb logcat -s sioul); and the JavaVM and the application's Context, lent to Rust (sioul_sync::android::init). - The manifest (
android/package/) is Qt 6.11's own with Sioul's name, its icon (the quill on its green, in Android's vector drawings, fromtools/make-icons.py), the network permissions, and no cloud backup: mail, notes, health readings and passwords stay on the phone. Moving to a new phone (cable or Wi-Fi between the two) takes everything but the passwords. - 16 KB memory pages: Android 15 runs on phones whose memory pages are 16 KB, where a library aligned for 4 KB does not load. The library is linked for them, and the workflow checks each library of the APK (its summary lists them).
What differs on Android¶
- Sites: Qt WebEngine has no Android version. The Sites page lists your sites and opens each in the browser (
qml/android/SitesPage.qml): no logins kept in Sioul, no notifications gathered. - PDFs: Qt PDF has no Android version either; a PDF of the notes opens with "Open with…" (
qml/android/PdfView.qml). Both pages keep the names of the computer's, so the module'sqmldirfinds them (build.rslists one or the other). - Passwords go to Android's KeyStore, through android-keyring: a key the KeyStore keeps, and never lets out, encrypts each password (AES-GCM) into the app's private storage. Its author calls it experimental.
- Sender checks ask the network's DNS servers, which Android gives through Java (hickory reads them with the Context lent at start).
- Certificates: Android's own (its Conscrypt module, else the system image's), for IMAP and SMTP alike. On computers SMTP checks them with the system's verifier (
rustls-platform-verifier), which on Android needs Java code Sioul does not ship.
Not done yet¶
- Notifications: none on Android (codes, reminders, doses); they need Android's own, through Java.
- A window for a phone: the pages are laid out for a computer's screen, a mouse and a keyboard.
- In the background: Android suspends an app it does not show; mail is fetched while Sioul is open.
- Files from Android's pickers come as
content://addresses, which the core does not read yet; downloads stay in the app's own folder. - Other programs Sioul calls on a computer (Tesseract for paper letters, ClamAV for attachments) do not exist on a phone.
- Permissions asked at the time (the microphone for memos, the position for maps), as Android wants them.
- Signing: with no key in the repository's secrets, each build is signed with a key of its own, so a phone takes the next one for another app (uninstall first). A store needs a key kept for good, and Google Play an Android App Bundle; F-Droid builds everything from source, Qt included.