Skip to content

feat(app): add an F-Droid flavor without Google libraries and model import from a file - #14

Merged
IgnacioLD merged 1 commit into
mainfrom
feat/fdroid-flavor-v2
Nov 10, 2026
Merged

IgnacioLD merged 1 commit into
mainfrom
feat/fdroid-flavor-v2

Conversation

@IgnacioLD

Copy link
Copy Markdown
Owner

What

Prepares the Android app for F-Droid. The rules that apply, with sources, are in docs/FDROID.md.

  • Product flavors playstore (today's behaviour) and fdroid in :androidApp.
    • androidx.credentials, credentials-play-services-auth and googleid move from :shared to playstoreImplementation.
    • GoogleSignIn moves to androidApp/src/playstore.
    • accountSignIn in :shared is now a plain var that defaults to UnavailableSignIn. Only the playstore Flavor.install() replaces it, so "Change phone" is hidden in fdroid.
  • Usage statistics are off by default in fdroid (Tracking anti-feature: opt-in and disabled by default). Onboarding shows a new notice saying so. Playstore is unchanged.
  • dependenciesInfo.includeInApk = false. The Play-encrypted dependency block is flagged by fdroid scanner. AABs keep it.
  • Import the on-device scoring model from a file, in both flavors.
    • New "Import from a file" action wherever the model download is offered (Settings, Offline, onboarding).
    • Uses the system picker (SAF), so no storage permission is needed.
    • Each picked file is copied while its SHA-256 is computed. It is installed only if the digest matches the pinned digest of the released pack or the one the server publishes, which is the same check a download uses.
    • File names do not matter. Anything else is deleted, and a localized error is shown.
    • Lesson packs are not importable: they have no file format yet.
  • Licensing gate: one runtime-classpath lock per flavor (tools/licensing/runtime-classpath-{fdroid,playstore}.txt). Each flavor's preBuild checks its own lock. The catalogue covers the union of both, and licenses.json is unchanged.
  • F-Droid metadata:
    • fastlane/metadata/android/{en-US,es-ES,fr-FR,de-DE}: title, short and full description, and changelogs/2226.txt.
    • Three en-US phone screenshots.
    • Draft recipe metadata/me.shirobyte42.glosso.yml (AntiFeatures: TetheredNet).
  • Docs: README build instructions for both flavors, the NOTICE Play-services entry, CONTRIBUTING, and task names that no longer exist with flavors (testDebugUnitTest, lintDebug, installDebug, connectedDebugAndroidTest).

Proof

  • fdroid release runtime classpath (:androidApp:dependencies --configuration fdroidReleaseRuntimeClasspath):
    • 0 matches for com.google.android.gms, com.google.firebase, com.google.android.libraries.identity, com.android.billingclient, com.google.android.play, credentials-play-services.
    • The only com.google artifacts are accompanist-drawablepainter and guava:listenablefuture (both Apache-2.0).
    • The playstore classpath has 32 matching lines.
  • fdroid release APK: none of those packages appears in its dex. fdroid scanner (fdroidserver 2.4.5, refreshed signatures) reports 0 problems.
  • Source scan: the fdroidserver source scanner, run with gradle: [fdroid] on the unmodified tree, reports 0 problems. As a control, moving googleid to a plain implementation gives 1. So the recipe needs no prebuild stripping.
  • Recipe: fdroid readmeta and fdroid lint pass, using fdroiddata's config/.

Tests

Check Result
:engine:jvmTest 463 passed
LC_ALL=en_US.UTF-8 :server:test 347 passed
:androidApp:testFdroidDebugUnitTest 292 passed
:androidApp:testPlaystoreDebugUnitTest 291 passed
:shared:testDebugUnitTest 142 passed
:androidApp:lintFdroidDebug 0 errors, 73 warnings, the same 73 as on the base branch
:androidApp:assembleFdroidRelease, :androidApp:assemblePlaystoreDebug OK
:shared:compileKotlinIosSimulatorArm64 OK
gitleaks dir . --redact only the 2 known false positives

New tests:

  • ModelPackImportTest:
    • valid files in any order install;
    • a corrupt or truncated file is rejected and leaves nothing behind;
    • a partial pick reports the pack as incomplete;
    • an unreadable file leaves no partial copy.
  • FdroidFlavorTest:
    • no sign-in is installed;
    • no googleid, Play services or credentials-play-services class is on the classpath;
    • statistics default to off.
  • PlaystoreFlavorTest: Google sign-in is still wired.
  • An AnalyticsTest case for the default-off build.

UI check on emulator-5558 (1080x2340, density 480), fdroid debug build:

  • the onboarding statistics-off notice shows;
  • importing a corrupt file is rejected with the error;
  • importing the real model plus vocabulary installs it ("Ready on this device");
  • Settings has no Account / "Change phone" section and the statistics switch is off.

Open decisions for the owner

  • TetheredNet: an in-app server URL setting would remove it.
  • NonFreeAssets risk: the licence of the lesson texts and audio (glosso-data) needs to be stated.
  • Signing: F-Droid signs with its own key (the default), or developer-signed reproducible builds (Binaries + AllowedAPKSigningKeys). This has to be decided before the first F-Droid release.
  • Donate field: left out of the recipe because the Ko-fi URL is still empty.

https://claude.ai/code/session_01FcVpZoyr8VdRLp1QecX1Ng

Replaces #13, rebased onto main after #12 was squash-merged (same diff, single commit).

https://claude.ai/code/session_01FcVpZoyr8VdRLp1QecX1Ng

…mport from a file

- Split :androidApp into `playstore` and `fdroid` product flavors. Credential
  Manager, its Play services provider and googleid move from :shared to
  playstoreImplementation; Google sign-in lives in src/playstore and :shared
  defaults to UnavailableSignIn, so "Change phone" is hidden in fdroid.
- fdroid starts with usage statistics off (F-Droid Tracking anti-feature);
  onboarding says so.
- Leave AGP's Play-encrypted dependency block out of APKs.
- Import the on-device scoring pack from files picked with the system picker
  (SAF, no storage permission), installed only when the SHA-256 matches the
  pinned or the server-published digest. Available in both flavors.
- One runtime classpath lock per flavor for the licensing gate.
- Fastlane metadata for every app locale, a draft fdroiddata recipe and
  docs/FDROID.md with the rules that apply.

Claude-Session: https://claude.ai/code/session_01FcVpZoyr8VdRLp1QecX1Ng
@IgnacioLD
IgnacioLD merged commit efc37b2 into main Nov 10, 2026
4 checks passed
@IgnacioLD
IgnacioLD deleted the feat/fdroid-flavor-v2 branch November 10, 2026 13:53
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