Skip to content

Restructure on the Android Studio project layout and update the toolchain - #123

Merged
in-jun merged 2 commits into
mainfrom
refactor/studio-project-layout
Sep 8, 2026
Merged

Restructure on the Android Studio project layout and update the toolchain#123
in-jun merged 2 commits into
mainfrom
refactor/studio-project-layout

Conversation

@in-jun

@in-jun in-jun commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Moves the project onto the standard Android Studio layout and the current toolchain, so that remote-sync and port-relay-android are built the same way from the same version catalog. Behaviour is unchanged except where a deprecated API had to go.

  • Toolchain — Gradle 9.7.1, AGP 9.4.0, Kotlin 2.4.20, Compose BOM 2026.08.00, compileSdk/targetSdk 37. gradle/libs.versions.toml is byte-identical to the one in port-relay-android.
  • Layoutjava/ source sets in both modules, theme/, ui/<feature>/, per-module .gitignore, backup and data-extraction rules that exclude every app file (the config store holds SMB credentials).
  • Navigation 3NavigationKeys + MainNavigation replace the hand-rolled Screen enum in MainActivity. The back stack is saveable, so the setup form survives process death; the first-run picker stays the root until a pair exists, and Home becomes the root once one does.
  • SecurePreferences — Jetpack Security is deprecated as of 1.1.0, so pairs and settings now go through a small AES-256-GCM store keyed in the Android Keystore, with the preference key bound as GCM associated data. The old remote-sync-secure file is deleted on first load; pre-release installs re-enter their pairs.
  • Battery exemptionREQUEST_IGNORE_BATTERY_OPTIMIZATIONS is dropped; Settings now opens the system optimization list instead of the direct dialog.
  • R8 — the release build is minified and resource-shrunk (14.8 MB → 3.0 MB). proguard-rules.pro keeps smbj and declares the exact javax.el / org.ietf.jgss classes its dormant EL-filter and Kerberos paths reference; neither exists on Android and neither path is taken with NTLM.
  • Zero-warning buildallWarningsAsErrors in both modules and lint { warningsAsErrors = true }. The one acknowledged lint is ScopedStorage on MANAGE_EXTERNAL_STORAGE; the manifest comment records why SAF cannot replace it yet (no atomic replace-rename) and that it is the planned follow-up.
  • Tests — the 96 existing JVM tests pass unchanged. New: a Compose UI test for ProtocolPickerScreen and an instrumented round-trip/tamper test for SecurePreferences (compile-checked only; no device in this run).
  • CI — unit tests and lint run before assembleRelease; lint and test reports are uploaded alongside the APK.

Not yet verified on a device: the R8-minified release path through an actual SMB sync.

Release signing (second commit)app/build.gradle.kts loads keystore.properties from the project root (or ~/.android/release/ on a developer machine) exactly as the Android signing guide describes, and leaves the release unsigned when neither exists. release.yml runs on a vX.Y.Z tag: it writes keystore.properties from the four SIGNING_* secrets, runs tests and lint, builds with -PreleaseVersion=X.Y.Z (versionName from the tag, versionCode derived as major*10000 + minor*100 + patch), verifies the signature with apksigner, publishes the APK to a GitHub Release with the preinstalled gh CLI, and deletes the keystore in an always() step. Verified locally: the signed APK's certificate digest matches the keystore.

…hain

- Gradle 9.7.1, AGP 9.4.0, Kotlin 2.4.20, Compose BOM 2026.08.00,
  compileSdk/targetSdk 37; version catalog shared with port-relay
- Standard Android Studio layout: java/ source sets in both modules,
  theme/, ui/<feature>/, backup and data-extraction rules that exclude
  all app data, per-module .gitignore
- Navigation 3 back stack (NavigationKeys + MainNavigation) replaces
  the hand-rolled Screen enum in MainActivity
- SecurePreferences (AndroidKeyStore AES-256-GCM) replaces the
  deprecated Jetpack Security EncryptedSharedPreferences; the old
  store file is deleted on first load
- Battery exemption: open the system optimization list instead of
  requesting REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
- Notification permission checked inline before notify(); KTX
  edit/toUri; obsolete SDK_INT branches removed (minSdk 26)
- Release build minified with R8; smbj keep rules and precise
  dontwarn entries for its dormant javax.el / Kerberos paths
- Kotlin warnings and lint warnings fail the build in every module
- Compose UI test for ProtocolPickerScreen, instrumented test for
  SecurePreferences
- CI runs unit tests and lint before the release build and uploads
  reports
- app/build.gradle.kts loads keystore.properties (project root, or
  ~/.android/release/ on a developer machine) the way the Android
  signing guide describes; without it the release stays unsigned
- -PreleaseVersion=X.Y.Z sets versionName and a derived monotonic
  versionCode; release.yml passes it from the vX.Y.Z tag
- release.yml: on a version tag, install the keystore from secrets,
  run unit tests and lint, build and verify the signed APK, attach it
  to a GitHub Release with gh, and remove the keystore afterwards
- keystore files ignored by git
@in-jun
in-jun merged commit 7b94e90 into main Sep 8, 2026
1 check passed
@in-jun
in-jun deleted the refactor/studio-project-layout branch September 8, 2026 05:38
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.

1 participant