Skip to content

feat: surface update availability and add one-tap APK install#54

Merged
ErikChevalier merged 1 commit into
mainfrom
feat/update-notifier
Jun 3, 2026
Merged

feat: surface update availability and add one-tap APK install#54
ErikChevalier merged 1 commit into
mainfrom
feat/update-notifier

Conversation

@ErikChevalier
Copy link
Copy Markdown
Contributor

Android parity for the desktop update-notifier (sibling PR FlintWave/SearchMob-Desktop#70).

Why

The launch-time GitHub check already worked but barely notified — a found update only showed as a one-shot dialog. This makes it visible and actionable while the app is open, and adds an in-app install path.

What

  • Notify while open — a system notification (own App updates channel) and a dismissible banner pinned at the top of the app. Both are driven by a persisted pending-update record, so they survive a restart and self-clear once the user is current.
  • Owner-only served-page banner — the home + results pages show the notice to the loopback owner only (a network/LAN visitor never sees it, and the owner's version isn't leaked).
  • One-tap install — re-fetch the latest release, download the APK, verify its SHA-256 against the release SHA256SUMS, then hand it to the system PackageInstaller (which shows its own install confirmation — nothing installs silently). Falls back to the release page when there's no usable asset or on failure.
  • New REQUEST_INSTALL_PACKAGES permission + PackageInstallReceiver to launch the system install-confirmation UI.

Honest limitation

The system install UI always appears (the app isn't a device owner), and "install unknown apps" must be granted once — by design.

New / changed

  • update/UpdateChecker.ktReleaseAsset + assets parsing + apkAsset/checksumsAsset.
  • update/UpdateInstaller.kt, UpdateFlow.kt, UpdateNotifier.kt, PackageInstallReceiver.kt (new).
  • update/UpdateCheckCoordinator.kt — persists pending state.
  • ui/prefs/* — pending-update fields + flows.
  • server/SearchServer.kt — owner-only updateBanner provider on home + results (+ CSS); service/SearchMobService.kt wiring.
  • MainActivity.kt — banner replaces the dialog; one-tap flow + progress; notification on found update.
  • AndroidManifest.xml, strings.xml.

Tests / checks

Added: assets parsing/selection, installer SHA-256 verify (match / mismatch / missing-entry / oversize), coordinator pending persistence, served-banner owner route. ktlintCheck + lintDebug + testDebugUnitTest + assembleDebug all green.

On-device verification (API 35 emulator)

Built a throwaway 26.05.00 APK so the published v26.06.00 reads as newer. Confirmed: the in-app banner ("SearchMob 26.06.00 is available." + Update/Dismiss), the system notification (Update available), and the served-page banner (/ and /search) all appear. Version reverted to 26.06.00; no version bump in this PR.

🤖 Generated with Claude Code

…d A-parity)

Mirrors the desktop update-notifier work. The launch-time GitHub check already
worked but barely notified (a one-shot dialog). This makes a found update
visible and actionable while the app is open, and adds an in-app install path.

- Notify while open: a system notification (own "App updates" channel) plus a
  dismissible top banner. Both driven by a persisted pending-update record so
  they survive a restart and self-clear once the user is current.
- Owner-only served-page banner: home + results show the notice to the loopback
  owner only (a network visitor never sees it / the version is not leaked).
- One-tap install: re-fetch the latest release, download the APK, verify its
  SHA-256 against the release SHA256SUMS, then hand it to the system
  PackageInstaller (which shows its own confirmation; nothing installs
  silently). Linux-style fallback to the release page on no-asset/failure.
- New REQUEST_INSTALL_PACKAGES permission + PackageInstallReceiver to launch the
  system install-confirmation UI.

UpdateInfo gains assets parsing (apkAsset/checksumsAsset); UpdateInstaller
(download+verify+install), UpdateFlow (orchestration), UpdateNotifier (channel +
post). Coordinator persists pending state; PreferencesRepository gains the
pending fields. SearchServer threads an owner-only updateBanner provider.

Tests: assets parsing/selection, installer SHA-256 verify (match/mismatch/
missing/oversize), coordinator pending persistence, served-banner owner route.
ktlintCheck + lintDebug + testDebugUnitTest + assembleDebug all green. Verified
on the API 35 emulator: in-app banner, system notification, and served-page
banner all appear for a build older than the published release.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ErikChevalier ErikChevalier merged commit 794eceb into main Jun 3, 2026
2 checks passed
@ErikChevalier ErikChevalier deleted the feat/update-notifier branch June 3, 2026 08:15
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