Explorar o código

docs: document configurable buttons and app pinning

Krasimir Kazakov hai 1 semana
pai
achega
398915f291

+ 7 - 6
AGENTS.md

@@ -2,7 +2,7 @@
 
 ## 1. Project Overview
 
-CarDash is a Flutter/Dart Android home-screen launcher for a car tablet. It has one configurable home page (clock, battery/Wi-Fi, media volume, five shortcuts), launches other apps full-screen, and offers light/dark/automatic themes plus an optional four-digit PIN requested only on cold start.
+CarDash is a Flutter/Dart Android home-screen launcher for a car tablet. It has one configurable home page (clock, battery/Wi-Fi, media volume, up to 16 home buttons), launches other apps full-screen, keeps the screen awake while foreground, and offers light/dark/automatic themes plus an optional four-digit PIN requested only on cold start.
 
 Stack: Flutter 3.47.8 / Dart 3.13.7, Android minSdk 29 (Android 10), compile/targetSdk 36, Kotlin bridges, AGP 9.1.0, Gradle 9.3.1, JDK 21. Package `com.wasp.cardash_launcher`. Landscape-only, tablet-first (1280×800).
 
@@ -36,12 +36,12 @@ ADB lives at `/opt/android-sdk/platform-tools/adb`; the SDK is at `/opt/android-
 - `lib/core/` — theme tokens (`AppColors`, `AppTheme`), `ThemeController`, reusable widgets.
 - `lib/data/models/` — `AppEntry`, `SlotType`, `SlotAssignment`, `SystemStatus`, `VolumeInfo`.
 - `lib/data/services/` — `NativeBridge` (platform channels), `PinService`, secure-store adapter.
-- `lib/data/repositories/` — `SettingsRepository`, the SSOT for theme, night window and slot assignments.
-- `lib/features/home/` — home screen, `LauncherController` (apps + shortcuts + HOME role), `SystemController` (volume/battery/Wi-Fi polling).
+- `lib/data/repositories/` — `SettingsRepository`, the SSOT for theme, night window, slot assignments, visibility flags and pinned apps.
+- `lib/features/home/` — home screen, `LauncherController` (apps, slots, pinned apps, 16-button cap, HOME role), `SystemController` (volume/battery/Wi-Fi polling).
 - `lib/features/apps/` — All Apps screen and app-picker sheet.
 - `lib/features/settings/` — General and Security pages.
 - `lib/features/lock/` — PIN pad, lock screen, cold-start `LockController`.
-- `android/app/src/main/kotlin/com/wasp/cardash_launcher/` — `MainActivity`, `LauncherBridge` (package manager, role), `SystemBridge` (battery, Wi-Fi, volume).
+- `android/app/src/main/kotlin/com/wasp/cardash_launcher/` — `MainActivity` (keep-screen-on, volume keys), `LauncherBridge` (package manager, role), `SystemBridge` (battery, Wi-Fi, volume).
 - `tool/` — emulator/install/check scripts. `docs/` — implementation plan and design notes.
 
 Rules:
@@ -63,7 +63,7 @@ notifyListeners();
 
 - Use `context.colors` / `AppTheme` tokens, not hard-coded colors in widgets.
 - All UI copy is sentence case (except the CarDash name). Keep copy short and functional.
-- New shortcut slots: extend `SlotType`, add a picker entry, a home `ShortcutSpec`, and repository coverage.
+- New home buttons: extend `SlotType` for fixed slots or use `LauncherController` pinned-app APIs; enforce the 16-button cap in the controller.
 - New native methods: add them to `LauncherPlatform`, `NativeBridge`, the relevant Kotlin bridge, and the test fake if used.
 - Tests: fake `LauncherPlatform`/`SecureStore`; `SharedPreferences.setMockInitialValues({})`; widget tests wrap in `MaterialApp(theme: AppTheme.light())`. Test files live in `test/` and end with `_test.dart`.
 - Run `dart format lib test` before committing. Conventional Commits (`feat:`, `fix:`, `docs:`, `chore:`).
@@ -89,7 +89,8 @@ notifyListeners();
 - The Flutter template uses AGP 9.1 built-in Kotlin support. Do not add the Kotlin Gradle plugin unless the build explicitly requires it.
 - Immersive mode is reapplied on every `resumed` lifecycle event; Android may restore system bars after dialogs or role prompts.
 - The HOME role must be granted for the dashboard to replace the tablet home screen. On the emulator use `cmd role add-role-holder`; the in-app banner and Settings row use `RoleManager`.
-- Screen-space is deliberately finite: test at 1280×800 and 1024×600. Avoid unbounded `ListView`s inside `Column`s.
+- Screen-space is deliberately finite: test the 16-button grid at 1280×800 and 1024×600. Avoid unbounded `ListView`s inside `Column`s.
 - `tool/emulator.sh` starts a headless AVD with the **host GPU**; SwiftShader segfaulted on this machine's API 35 image. Use `CARDASH_GPU=swiftshader_indirect` only as a fallback. Use `adb exec-out screencap -p` for screenshots; there may be multiple `adb` binaries on PATH, so use the absolute one.
 - While CarDash is foreground, `MainActivity` consumes hardware volume keys and adjusts `STREAM_MUSIC` so they match the dashboard. Do not remove that override without providing another sync path; otherwise Android controls the ring stream when no media is playing.
+- `FLAG_KEEP_SCREEN_ON` in `MainActivity` is intentional. It applies while CarDash is the foreground window; do not move it to a permission-based wake lock.
 - Reinstalling the app can clear its HOME role; re-run `tool/install.sh` or use Settings > Home app.

+ 38 - 19
README.md

@@ -3,15 +3,15 @@
 A calm, configurable Android car dashboard launcher, built with Flutter.
 
 CarDash replaces the tablet home screen with one landscape page: a large clock,
-battery and Wi-Fi status, the main media-volume control, and five shortcuts —
-**Navigation**, **Music**, **Radio**, **Settings** and **All apps**. The first
-three are configurable; a long press picks a different installed app. External
-apps open full-screen using the normal Android launcher mechanism. No overlays,
-no root, no kiosk setup.
+battery and Wi-Fi status, the main media-volume control, and up to 16 buttons —
+**Navigation**, **Music**, **Radio**, **Settings**, **All apps**, plus any apps
+you pin from All Apps. The first three can be shown, hidden and assigned to
+installed apps. External apps open full-screen using the normal Android launcher
+mechanism. No overlays, no root, no kiosk setup.
 
 <p align="center">
-  <em>Verified on Android 15 and Android 10 tablet emulators at 1280×800.
-  Landscape only.</em>
+  <em>Verified on Android 15 and Android 10 tablet emulators at 1280×800 and
+  1024×600. Runs on a physical Android 17 HyperOS tablet. Landscape only.</em>
 </p>
 
 ## Screenshots
@@ -20,9 +20,11 @@ no root, no kiosk setup.
 |---|---|
 | ![CarDash light home](docs/screenshots/home-light.png) | ![CarDash dark home](docs/screenshots/home-dark.png) |
 
-Also: [All apps](docs/screenshots/all-apps.png) ·
+Also: [16-button home](docs/screenshots/home-16.png) ·
+[16 buttons at 1024×600](docs/screenshots/home-16-1024.png) ·
+[All apps](docs/screenshots/all-apps.png) ·
 [app picker](docs/screenshots/app-picker.png) ·
-[Settings](docs/screenshots/settings.png) ·
+[Settings · home buttons](docs/screenshots/settings-buttons.png) ·
 [PIN lock](docs/screenshots/pin-lock.png) ·
 [1024×600 layout](docs/screenshots/home-compact-1024.png)
 
@@ -36,9 +38,15 @@ Also: [All apps](docs/screenshots/all-apps.png) ·
   front, the hardware volume keys are routed to the same media stream, so the
   dashboard and the keys always agree. This is the phone's media stream, not a
   private volume.
-- **Configurable shortcuts** for Navigation, Music and Radio. Generic icons on
-  the dashboard; real app icons in the picker and All Apps.
+- **Configurable home buttons** — switches in Settings show or hide Navigation,
+  Music and Radio. Settings and All apps are always present. Dashboard icons
+  stay generic; real app icons appear in the picker and All Apps.
+- **Pin any app from All Apps** — long-press an app to add it to Home. The home
+  page holds up to **16 buttons including Settings and All apps**, and the grid
+  shrinks as it fills. Long-press an added app on Home to remove it completely;
+  add it back with another long press in All Apps.
 - **All apps** — searchable grid of every launchable app, launched full-screen.
+- **Screen stays awake** while CarDash is in the foreground.
 - **Light / Dark / Automatic** theme. Automatic uses a fixed local-time window
   (default 19:00–07:00), editable in Settings.
 - **Optional PIN** — four digits, stored as a salted PBKDF2 hash in
@@ -112,8 +120,12 @@ same thing. Android will not let an app force itself into the home role silently
 | Tap Navigation / Music / Radio | Open the assigned app full-screen |
 | Long-press Navigation / Music / Radio | Pick a different installed app |
 | Tap an unassigned shortcut | Open the app picker |
-| Settings | Theme, home shortcuts, default-home role, PIN |
-| All apps | Search every launchable app; tap to open |
+| Settings → Home buttons switches | Show or hide Navigation, Music, Radio |
+| Long-press an app in All Apps | Add it to Home (up to 16 buttons) |
+| Long-press an added app on Home | Remove it from Home |
+| Settings | Theme, home buttons, default-home role, PIN |
+| All apps | Search every launchable app; tap to open, hold to pin |
+| Screen | Stays awake while CarDash is in front |
 | Volume ring / mute | Toggle media mute |
 | Slider or − / + | Set media volume |
 | Hardware volume keys | Adjust the dashboard's media volume; the ring follows |
@@ -127,7 +139,8 @@ the app resumes.
 **General**
 - Light / Dark / Auto theme.
 - Auto night window (default dark from 19:00, light from 07:00).
-- The three home shortcuts.
+- Home buttons: show/hide Navigation, Music, Radio; live count out of 16.
+- Assign the app for each slot; Settings and All apps are fixed.
 - Home role status and shortcut to the system prompt.
 
 **Security**
@@ -171,10 +184,13 @@ flutter test
 ./tool/check.sh
 ```
 
-Current tests cover PIN hashing/persistence, settings persistence, theme
-resolution and the shortcut tile widget. Native package enumeration, the HOME
-role, volume, app launching and PIN flows were verified on both API 35 and
-API 29 tablet emulators, including the release APK.
+The 17 tests cover PIN hashing/persistence, settings persistence, theme
+resolution, slot visibility, pinned apps, the 16-button cap and the dense
+shortcut grid. Native package enumeration, the HOME role, volume, app launching
+and PIN flows were verified on API 35 and API 29 emulators, including the release
+APK. The home-button, pinning and keep-awake flows were checked at 1280×800 and
+1024×600. Release 0.2.0 is also installed on a physical Android 17 HyperOS
+tablet.
 
 ## Troubleshooting the emulator
 
@@ -197,6 +213,10 @@ Android 15 AVD is left running headlessly after development; use
   requires a newer Android release.
 - **Landscape only** (`sensorLandscape`). The home page is designed for
   1280×800 and remains usable at 1024×600.
+- **16-button cap** includes Settings and All apps. Added apps use the generic
+  dashboard icon and their name; real icons remain in the picker and All Apps.
+- **Screen-on** applies while CarDash is the foreground window. Android can
+  still sleep while another app is in front.
 - **No embedded third-party app UI.** Navigation/Music/Radio are launched in
   their own full-screen windows.
 - **No global play/pause control.** Volume is on the home screen; playback
@@ -222,7 +242,6 @@ large numerals and quiet line icons. It is not a copy of that UI.
 ## Roadmap
 
 - Optional compact now-playing control beside the volume card.
-- Configurable home layout or additional shortcut slots.
 - Release signing configuration.
 - Real-device soak test on an Android 10 car tablet.
 

+ 42 - 17
docs/IMPLEMENTATION_PLAN.md

@@ -11,13 +11,18 @@ 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.
+- Up to **16 home buttons**: Navigation, Music, Radio, Settings, All apps, plus
+  apps pinned from All Apps.
+- Navigation/Music/Radio are **app slots** with show/hide switches. They can be
+  assigned, changed and cleared. Settings and All apps are always present.
+- Pinned apps are added by long-pressing an app in All Apps and removed by
+  long-pressing the added button on Home. Dashboard icons stay generic.
+- The grid adapts from 2 to 6 columns and shrinks its tiles as the count grows.
 - 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.
+- Settings: light/dark/automatic theme, fixed night window, home-button switches,
+  slot assignment, HOME-role setup, four-digit PIN.
 - PIN is requested **only on a cold start**, never on resume or screen-off.
+- The screen stays awake while CarDash is the foreground window.
 - Landscape-only; tablet-first 1280×800; Android 10 minimum.
 - Package: `com.wasp.cardash_launcher`. Display name: **CarDash**.
 
@@ -27,9 +32,12 @@ compatibility:
 |---|---|---|
 | 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. |
+| Home layout | Single page, info + volume + up to 16 buttons | Matches the refined brief; tiles scale from 2 to 6 columns. |
+| App slots | Navigation, Music, Radio with visibility switches | Kept from the original brief; Settings and All apps are fixed. |
+| Pinned apps | All Apps long-press adds, Home long-press removes | Makes any installed app reachable from Home without editing a separate layout screen. |
+| Home cap | 16 buttons total, including Settings and All apps | Keeps the single page legible at tablet resolutions; enforced in `LauncherController`. |
+| Icons | Generic for all Home buttons; real icons in pickers/All Apps | Keeps the car interface consistent; names identify pinned apps. |
+| Screen | `FLAG_KEEP_SCREEN_ON` while foreground | The dashboard is the car display; no wake-lock permission needed. |
 | 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. |
@@ -45,18 +53,20 @@ compatibility:
 Flutter
   HomeScreen
     ClockBlock / StatusCluster / VolumeCard / ShortcutGrid
-    LauncherController  -> apps, slots, default-home state
+    LauncherController  -> apps, slots, pinned apps, 16-button cap, 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)
+  MainActivity -> keep-screen-on, volume keys
+               -> 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.
+- `SettingsRepository` is the only persistence path for theme, night window,
+  slot visibility/assignments and pinned apps. `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.
@@ -76,11 +86,12 @@ Android (Kotlin)
 | 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 |
+| M8 | Home-button visibility switches, All Apps pinning, 16-button adaptive grid, keep-awake | Done |
 
 ## 5. Verification checklist
 
 - [x] `flutter analyze` clean.
-- [x] Unit/widget tests pass (PIN, repository, theme, shortcut tile).
+- [x] Unit/widget tests pass (17 tests: PIN, repository, theme, slot visibility, pinned apps, cap, dense grid).
 - [x] Debug APK builds with JDK 21.
 - [x] Installs on API 35 1280×800 tablet.
 - [x] HOME role granted; Home opens CarDash.
@@ -94,6 +105,12 @@ Android (Kotlin)
 - [x] Verify 1024×600 compact layout (`adb shell wm size 1024x600`).
 - [x] Boot and verify on Android 10 (API 29) AVD, including PIN and release APK.
 - [x] Release APK on both AVDs (54 MB universal APK).
+- [x] Navigation/Music/Radio switches hide/show buttons, persist, and preserve assignments.
+- [x] All Apps long-press pins apps; the 16-button cap rejects a 17th button.
+- [x] Long-press on an added app removes it; it can be re-added from All Apps.
+- [x] 16 buttons fit at 1280×800 and 1024×600; the grid uses 2–6 columns.
+- [x] `FLAG_KEEP_SCREEN_ON` is present on the dashboard window.
+- [x] Release 0.2.0 installed on a physical Android 17 HyperOS tablet.
 - [x] Screenshots in `docs/screenshots/`; README/AGENTS/plan updated.
 
 ## 6. Known risks and mitigations
@@ -105,12 +122,16 @@ Android (Kotlin)
    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`.
+4. **Emulator stability**: headless emulators can be killed by the host; scripts
+   use managed boot and the host GPU. SwiftShader is only a fallback.
 5. **Flutter 3.47 / AGP 9.1 / JDK 21**: works on this machine; Java 27 is not the
    validated toolchain. The emulator uses the host GPU; SwiftShader segfaulted
    on the API 35 image, so the helper script defaults to `-gpu host`.
-6. **Uninstall/reinstall** may drop the HOME role; Settings and the installer
+6. **16-button density**: generic icons plus small labels are the trade-off for
+   a single page. The Settings count and grid scaling make the limit explicit.
+7. **Screen-on battery use**: the flag applies only while the dashboard is
+   foreground; it is not a background wake lock.
+8. **Uninstall/reinstall** may drop the HOME role; Settings and the installer
    script can restore it.
 
 ## 7. Out of scope (for now)
@@ -130,3 +151,7 @@ Android (Kotlin)
   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.
+- 2026-10-29: Added home-button visibility switches, All Apps long-press pinning,
+  a 16-button cap with an adaptive 2–6 column grid, pinned-app removal, and a
+  foreground keep-screen-on flag. Verified 17 tests, 16-button layouts at
+  1280×800 and 1024×600, cap/removal/re-add, and 0.2.0 on the physical tablet.

BIN=BIN
docs/screenshots/all-apps.png


BIN=BIN
docs/screenshots/home-16-1024.png


BIN=BIN
docs/screenshots/home-16.png


BIN=BIN
docs/screenshots/settings-buttons.png