IMPLEMENTATION_PLAN.md 7.1 KB

CarDash implementation plan

Last updated: 2026-10-29

1. What we are building

CarDash is a Flutter/Dart Android home-screen launcher for a landscape car tablet. It deliberately trades the reference head-unit chrome for maximum compatibility:

  • One home page. No top bar, no bottom dock, no pages.
  • Clock/date, battery/charging and Wi-Fi on the page.
  • A prominent media-volume card (ring, slider, −/+, mute).
  • Five shortcuts: Navigation, Music, Radio, Settings, All apps.
  • Navigation/Music/Radio are app slots. They can be assigned, changed and cleared. Dashboard icons stay generic.
  • Every external app opens full-screen through a normal Android Intent.
  • Settings: light/dark/automatic theme, fixed night window, slot assignment, HOME-role setup, four-digit PIN.
  • PIN is requested only on a cold start, never on resume or screen-off.
  • Landscape-only; tablet-first 1280×800; Android 10 minimum.
  • Package: com.wasp.cardash_launcher. Display name: CarDash.

2. Decisions and why

Decision Choice Rationale
Central app content Launcher-native; apps open full-screen Android cannot embed another app; overlay chrome was rejected as fragile and app-obstructing.
UI chrome None (no bars) Removes the mismatch between launcher chrome and full-screen apps; cleaner, more compatible.
Home layout Single page, info + volume + five shortcuts Matches the refined brief: one configurable home screen.
App slots Navigation, Music, Radio Kept from the original brief; Settings and All apps are fixed.
Icons Generic for dashboard; real icons in pickers/All Apps Keeps the car interface consistent while making app identification possible.
Theme Light / Dark / Automatic with fixed 19:00–07:00 window No location permission or network; time pickers make the window adjustable.
PIN Four digits, salted PBKDF2 hash, cold start only Matches the explicit instruction; no re-lock while running.
Min Android API 29 (Android 10) Requested minimum; no in-scope API requires newer.
Target/compile 36 Current Flutter toolchain defaults; runs on API 29.
Orientation sensorLandscape + Dart orientation lock Car/tablet form factor; portrait is intentionally unsupported.
AVD 10.1" WXGA tablet, 1280×800, 160 dpi, API 35 and API 29 Matches a dashboard tablet and the reference resolution class.
HOME role Standard RoleManager request + Settings row A launcher must be chosen as the system home app; never silently forced.
Overlay/kiosk/root Out of scope Rejected for compatibility.

3. Architecture

Flutter
  HomeScreen
    ClockBlock / StatusCluster / VolumeCard / ShortcutGrid
    LauncherController  -> apps, slots, default-home state
    SystemController    -> battery/Wi-Fi/volume polling
  AllAppsScreen / AppPickerSheet
  SettingsScreen -> General / Security
  PinSetupScreen / LockScreen -> LockController -> PinService
Android (Kotlin)
  MainActivity -> LauncherBridge (apps, launch, role)
              -> SystemBridge (battery, Wi-Fi, volume)
  • SettingsRepository is the only persistence path for theme, night window and slots. flutter_secure_storage holds the salted PIN hash.
  • Package enumeration and icon rendering happen on a worker thread in Kotlin and are returned as PNG bytes.
  • Timers for volume/status are stopped when the app leaves the foreground.
  • The PIN check is awaited before runApp, so there is no dashboard flash on a locked cold start.
  • No INTERNET permission, no weather, no telemetry.

4. Milestones

# Milestone State
M0 Local git repo, Flutter scaffold, launcher config, package ID, icons, docs Done
M1 x86_64 API 35/API 29 images, 1280×800 landscape tablet AVDs, emulator/install scripts Done
M2 Theme system, single home layout, clock/status, volume card, shortcut grid Done (initial visual pass)
M3 Kotlin bridges: app list/icons/launch, HOME role, volume, battery/Wi-Fi Done
M4 App picker, All Apps, slot persistence, long-press flows, launch errors Done
M5 Settings, theme auto window, PIN setup/change/remove, cold-start lock Done
M6 Interaction testing, light/dark screenshots, layout polish, API 29 verification Done
M7 Release build, final docs, screenshots, last commits Done

5. Verification checklist

  • flutter analyze clean.
  • Unit/widget tests pass (PIN, repository, theme, shortcut tile).
  • Debug APK builds with JDK 21.
  • Installs on API 35 1280×800 tablet.
  • HOME role granted; Home opens CarDash.
  • Immersive full-screen; no Android bars.
  • Real app list and icons in All Apps.
  • App picker assign / long-press change / clear, with persistence across restart.
  • Launch Navigation/Music/Radio full-screen and return Home (verified with Maps and YouTube Music).
  • Volume slider, mute and hardware-key synchronization (keys are routed to STREAM_MUSIC while the dashboard is foreground).
  • Light theme, dark theme and automatic switch.
  • PIN set/change/remove; cold start shows lock; wrong PIN; no re-lock after returning from an app.
  • Verify 1024×600 compact layout (adb shell wm size 1024x600).
  • Boot and verify on Android 10 (API 29) AVD, including PIN and release APK.
  • Release APK on both AVDs (54 MB universal APK).
  • Screenshots in docs/screenshots/; README/AGENTS/plan updated.

6. Known risks and mitigations

  1. Media-volume polling is every 900 ms while foreground. It is cheap and handles hardware keys, but a future native ContentObserver would remove the polling. No global play/pause is in scope.
  2. QUERY_ALL_PACKAGES is required for a launcher app list. It is documented and acceptable for sideloading; a Play distribution needs policy work.
  3. PIN security scope: cold-start only by design; it does not replace the Android keyguard or protect against adb/data extraction. README explains it.
  4. Emulator stability: software-rendered headless emulator can be killed by the host; scripts use managed background boot and swiftshader_indirect.
  5. Flutter 3.47 / AGP 9.1 / JDK 21: works on this machine; Java 27 is not the validated toolchain.
  6. Uninstall/reinstall may drop the HOME role; Settings and the installer script can restore it.

7. Out of scope (for now)

  • Embedded third-party apps, overlay bars, split screen, kiosk/device-owner.
  • Global play/pause or now-playing metadata.
  • Weather, Bluetooth, calls, climate, reverse camera.
  • An app drawer with folders/pages; a single searchable All Apps page is enough.
  • Play Store packaging/signing, remote git, CI.

8. Change log

  • 2026-10-29: Pivoted from an overlay/head-unit chrome design to a launcher-native single home page, no top/bottom bars, full-screen external apps. Implemented core UI, Kotlin bridges, settings, PIN and documentation. Verified initial home, app picker, All Apps, volume, themes and cold-start PIN on the API 35 AVD; then verified the release build and PIN flows on the API 29 AVD. Added hardware volume-key routing and PIN verification progress. Screenshots captured at 1280×800 and 1024×600.