mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-05-24 14:50:26 -04:00
fix(specs): remove 23 stale map/POI references after deferral
Clean up references to MapScreen, PlaceListMapTemplate, POI category, and related models across all spec artifacts following the map strategy deferral decision. All map-related items are now properly marked as DEFERRED or N/A. Affected artifacts: - contracts/car-app-service.md: screen hierarchy, tabs, template section - contracts/manifest-declarations.md: POI category removed - plan.md: file tree cleaned - spec.md: component table, assumptions, clarification Q2 - data-model.md: MapUiState/NodePlace/LatLngWrapper commented out - research.md: R6 marked UNDER REVIEW with options table - tasks.md: T005, T014, delivery strategy - checklists/car-integration.md: CHK020/030/038/043 marked N/A Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
|
||||
## Requirement Consistency
|
||||
|
||||
- [ ] CHK020 — Do FR-009 (PlaceListMapTemplate under POI) and Non-Goals (NAVIGATION deferred to v2) consistently align with map update latency requirement SC-009 (< 5s)? [Consistency, Spec §FR-009, §SC-009]
|
||||
- [x] CHK020 — ~~Do FR-009 (PlaceListMapTemplate under POI) and Non-Goals (NAVIGATION deferred to v2) consistently align with map update latency requirement SC-009 (< 5s)?~~ N/A — FR-009 and SC-009 deferred with map feature [Consistency]
|
||||
- [ ] CHK021 — Are voice input requirements consistent between US-1 (reply), US-7 (in-context), and FR-003 (primary method)? [Consistency]
|
||||
- [ ] CHK022 — Does "no parked-mode differentiation" (Clarifications) conflict with any acceptance scenario implying driving-only behavior? [Consistency, Spec §Edge Cases]
|
||||
- [ ] CHK023 — Are emergency handling requirements consistent between FR-005 (banner), FR-006 (spotlight), and US-2 (all scenarios)? [Consistency]
|
||||
@@ -44,7 +44,7 @@
|
||||
- [ ] CHK027 — Is SC-010 ("zero crashes in 2-hour session") sufficient as a release gate — what about ANRs, OOM, or session drops? [Measurability, Spec §SC-010]
|
||||
- [ ] CHK028 — Is SC-007 ("passes Android Auto App Quality review") measurable before actual store submission? [Measurability, Spec §SC-007]
|
||||
- [ ] CHK029 — Is SC-001 ("15 seconds total interaction time") measured from notification appearance or screen wake? [Measurability, Spec §SC-001]
|
||||
- [ ] CHK030 — Are acceptance scenarios for US-5 (map) testable on DHU given DHU's limited map rendering capabilities? [Measurability, Spec §US-5]
|
||||
- [x] CHK030 — ~~Are acceptance scenarios for US-5 (map) testable on DHU?~~ N/A — US-5 deferred [Measurability]
|
||||
|
||||
## Scenario Coverage
|
||||
|
||||
@@ -58,12 +58,12 @@
|
||||
|
||||
## Edge Case Coverage
|
||||
|
||||
- [ ] CHK038 — Is behavior defined when PlaceListMapTemplate's item limit is reached (max 6 items per CAL docs)? [Edge Case, Spec §FR-009]
|
||||
- [x] CHK038 — ~~Is behavior defined when PlaceListMapTemplate's item limit is reached?~~ N/A — map deferred [Edge Case]
|
||||
- [ ] CHK039 — Is behavior defined when a channel has zero messages (empty state for messaging screen per channel)? [Edge Case, Gap]
|
||||
- [ ] CHK040 — Are requirements defined for handling very long node names that exceed Condensed Item text bounds? [Edge Case, Spec §FR-007]
|
||||
- [ ] CHK041 — Is behavior defined when voice recognition returns empty/null result or times out? [Edge Case, Spec §FR-003]
|
||||
- [ ] CHK042 — Is behavior defined for rapid consecutive emergency alerts from multiple nodes? [Edge Case, Spec §Edge Cases]
|
||||
- [ ] CHK043 — Are requirements defined for handling GPS-less nodes on the map screen (nodes without position data)? [Edge Case, Spec §FR-009]
|
||||
- [x] CHK043 — ~~Are requirements defined for handling GPS-less nodes on the map screen?~~ N/A — map deferred [Edge Case]
|
||||
- [ ] CHK044 — Is behavior defined when the message being composed via voice exceeds mesh packet size limit (228 bytes)? [Edge Case, Gap]
|
||||
- [ ] CHK045 — Is behavior defined when Minimized Control Panel data sources become stale (BLE connected but no mesh traffic)? [Edge Case, Spec §FR-010]
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ The `MeshtasticCarAppService` is the entry point for Android Auto and AAOS hosts
|
||||
<intent-filter>
|
||||
<action android:name="androidx.car.app.CarAppService" />
|
||||
<category android:name="androidx.car.app.category.MESSAGING" />
|
||||
<category android:name="androidx.car.app.category.POI" />
|
||||
<!-- Secondary category (POI or NAVIGATION) deferred pending map strategy decision -->
|
||||
</intent-filter>
|
||||
</service>
|
||||
```
|
||||
@@ -26,7 +26,7 @@ The `MeshtasticCarAppService` is the entry point for Android Auto and AAOS hosts
|
||||
| Category | Purpose | Justification |
|
||||
|----------|---------|---------------|
|
||||
| `MESSAGING` | Primary — enables ConversationItem, voice reply | Core use case: read/reply to mesh messages |
|
||||
| `POI` | Secondary — enables PlaceListMapTemplate | Node map with static pins (not navigation) |
|
||||
| ~~`POI`~~ | ~~Secondary — enables PlaceListMapTemplate~~ | **DEFERRED** — pending NAVIGATION vs POI decision |
|
||||
|
||||
### Car API Level
|
||||
|
||||
@@ -75,10 +75,8 @@ class MeshtasticCarSession(private val sessionInfo: SessionInfo) : Session() {
|
||||
HomeScreen (root, never popped)
|
||||
├── MessagingScreen (tab 1)
|
||||
│ └── ConversationScreen (push on conversation tap)
|
||||
├── NodeDashboardScreen (tab 2)
|
||||
│ └── NodeDetailScreen (push on node tap)
|
||||
└── MapScreen (tab 3)
|
||||
└── NodeDetailScreen (push on map item tap)
|
||||
└── NodeDashboardScreen (tab 2)
|
||||
└── NodeDetailScreen (push on node tap)
|
||||
```
|
||||
|
||||
Maximum screen depth: 3 (compliant with CAL template depth limits).
|
||||
@@ -92,7 +90,6 @@ TabTemplate {
|
||||
tabs: [
|
||||
Tab("Messages", messagingIcon),
|
||||
Tab("Nodes", nodeIcon),
|
||||
Tab("Map", mapIcon),
|
||||
]
|
||||
headerAction: Action.APP_ICON
|
||||
}
|
||||
@@ -170,25 +167,9 @@ PaneTemplate {
|
||||
}
|
||||
```
|
||||
|
||||
### MapScreen → PlaceListMapTemplate
|
||||
### ~~MapScreen → PlaceListMapTemplate~~ (DEFERRED)
|
||||
|
||||
```
|
||||
PlaceListMapTemplate {
|
||||
title: "Node Map"
|
||||
itemList: ItemList {
|
||||
items: [
|
||||
Row(
|
||||
title: node.name,
|
||||
text: "Updated {timeAgo} • {distanceFormatted}",
|
||||
metadata: Place(LatLng(lat, lng)),
|
||||
onClickListener: → push NodeDetailScreen
|
||||
) for each node with position
|
||||
]
|
||||
}
|
||||
anchor: LatLng(ownLat, ownLng) // if own position available
|
||||
isCurrentLocationEnabled: true
|
||||
}
|
||||
```
|
||||
> Map implementation deferred pending NAVIGATION vs POI category decision. Template contract will be defined when map strategy is resolved.
|
||||
|
||||
### MeshStatusPanel → Minimized Control Panel
|
||||
|
||||
@@ -224,7 +205,7 @@ AppManager.showAlert(
|
||||
| BLE disconnected | Banner shown; screens degrade to cached data (read-only) |
|
||||
| No channels configured | Show onboarding PaneTemplate directing to phone app |
|
||||
| No nodes in range | Empty state in NodeDashboard: "No nodes heard" |
|
||||
| No positions available | MapScreen shows empty map with "No positions reported" |
|
||||
| No positions available | ~~MapScreen shows empty map~~ (DEFERRED with map feature) |
|
||||
| Template item limit exceeded | Paginate with "Load more" action row |
|
||||
| Voice input fails | Fall back to quick-reply template list |
|
||||
| Session crash | Crashlytics captures with `car_session` tag; session restarts cleanly |
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<intent-filter>
|
||||
<action android:name="androidx.car.app.CarAppService" />
|
||||
<category android:name="androidx.car.app.category.MESSAGING" />
|
||||
<category android:name="androidx.car.app.category.POI" />
|
||||
<!-- POI or NAVIGATION category deferred pending map strategy decision -->
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
|
||||
@@ -139,10 +139,11 @@ data class TopologyHeader(
|
||||
|
||||
**Source**: `NodeRepository.nodeDBbyNum`, `NodeRepository.onlineNodeCount`
|
||||
|
||||
### MapUiState
|
||||
### ~~MapUiState~~ (DEFERRED)
|
||||
|
||||
State for the PlaceListMapTemplate.
|
||||
> Map models deferred pending NAVIGATION vs POI category decision. These models will be defined when map strategy is resolved.
|
||||
|
||||
<!--
|
||||
```kotlin
|
||||
data class MapUiState(
|
||||
val places: List<NodePlace>,
|
||||
@@ -165,6 +166,7 @@ data class LatLngWrapper(
|
||||
```
|
||||
|
||||
**Source**: `NodeRepository.nodeDBbyNum` filtered to nodes with valid positions
|
||||
-->
|
||||
|
||||
### EmergencyAlert
|
||||
|
||||
|
||||
@@ -85,12 +85,11 @@ feature/car/
|
||||
│ │ │ │ ├── MeshtasticCarAppService.kt # CarAppService entry point
|
||||
│ │ │ │ └── MeshtasticCarSession.kt # Session lifecycle, screen manager
|
||||
│ │ │ ├── screens/
|
||||
│ │ │ │ ├── HomeScreen.kt # Tab-based entry (messaging, nodes, map)
|
||||
│ │ │ │ ├── HomeScreen.kt # Tab-based entry (messaging, nodes)
|
||||
│ │ │ │ ├── MessagingScreen.kt # ConversationItem list, channel chips
|
||||
│ │ │ │ ├── ConversationScreen.kt # Single conversation with voice reply
|
||||
│ │ │ │ ├── NodeDashboardScreen.kt # Condensed Items node grid
|
||||
│ │ │ │ ├── NodeDetailScreen.kt # Expanded node info
|
||||
│ │ │ │ ├── MapScreen.kt # PlaceListMapTemplate
|
||||
│ │ │ │ └── ChannelManagementScreen.kt # Channel selection/switching
|
||||
│ │ │ ├── alerts/
|
||||
│ │ │ │ └── EmergencyHandler.kt # Banner management for emergencies
|
||||
@@ -110,8 +109,7 @@ feature/car/
|
||||
│ │ └── MeshtasticCarSessionTest.kt
|
||||
│ ├── screens/
|
||||
│ │ ├── MessagingScreenTest.kt
|
||||
│ │ ├── NodeDashboardScreenTest.kt
|
||||
│ │ └── MapScreenTest.kt
|
||||
│ │ └── NodeDashboardScreenTest.kt
|
||||
│ └── alerts/
|
||||
│ └── EmergencyHandlerTest.kt
|
||||
|
||||
|
||||
@@ -90,24 +90,28 @@ The existing `SendMessageUseCase` in `core/repository` accepts `(text, contactKe
|
||||
- Custom speech recognition → Rejected: CAL handles this automatically; would duplicate system capabilities
|
||||
- Google Assistant App Actions → Rejected: Separate concern handled by AppFunctions feature
|
||||
|
||||
## R6: PlaceListMapTemplate for Node Map (POI Category)
|
||||
## R6: Map Template Strategy (UNDER REVIEW)
|
||||
|
||||
**Decision**: Use `PlaceListMapTemplate` under POI category for static node position display
|
||||
**Status**: ⚠️ **Decision deferred** — pending further research on NAVIGATION vs POI implications.
|
||||
|
||||
**Rationale**: POI category avoids NAVIGATION category requirements (turn-by-turn guidance, active routing), which would trigger additional Play Store review burden and potential conflicts with navigation apps. `PlaceListMapTemplate` renders a map with place items (pins) + a scrollable list — perfect for showing node positions.
|
||||
**Options under consideration**:
|
||||
|
||||
**Implementation approach**:
|
||||
- Each node with known GPS position becomes a `Place` item with `LatLng`
|
||||
- List items show node name + distance + last update time
|
||||
- Map auto-zooms to fit all visible pins
|
||||
- Tap a list item → NodeDetailScreen with message option
|
||||
- Refresh interval: 5 seconds (matches NFR map update latency requirement)
|
||||
| Option | Template | Pros | Cons |
|
||||
|--------|----------|------|------|
|
||||
| POI | `PlaceListMapTemplate` | Simple, no nav conflicts, static pins | 6-item cap, limited interactivity |
|
||||
| NAVIGATION | `MapWithContentTemplate` | Full map control, live tracking | Exclusive with Google Maps/Waze, stricter review |
|
||||
|
||||
**Limitation**: No live tracking line or animated position updates (NAVIGATION category feature, deferred to v2)
|
||||
**Previous analysis** (preserved for reference):
|
||||
- POI category avoids NAVIGATION requirements (turn-by-turn guidance, active routing), which would trigger additional Play Store review burden and conflicts with navigation apps
|
||||
- `PlaceListMapTemplate` renders a map with place items (pins) + a scrollable list — suitable for showing node positions
|
||||
- MapWithContentTemplate offers richer UX but requires NAVIGATION category declaration
|
||||
|
||||
**Alternatives considered**:
|
||||
- MapWithContentTemplate + NAVIGATION category → Rejected by spec decision; deferred to v2
|
||||
- No map at all → Rejected: Location awareness is core Meshtastic differentiator
|
||||
**Open questions**:
|
||||
1. Does NAVIGATION category preclude simultaneous Google Maps use on car display?
|
||||
2. Would Google Maps SDK for AAOS (announced I/O 2026) change the calculus?
|
||||
3. Is 6-item cap on PlaceListMapTemplate acceptable for typical mesh networks?
|
||||
|
||||
**Implementation approach**: TBD after decision is made
|
||||
|
||||
## R7: Koin DI Integration for Car Module
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ Integrate the Android Car App Library 1.9.0-alpha01 into Meshtastic-Android to d
|
||||
### Session 2026-05-21
|
||||
|
||||
- Q: How should voice commands be implemented — CAL built-in voice input, full Assistant App Actions, or both? → A: CAL built-in voice input only (tap reply → dictate → send). System-level "Hey Google" commands are handled separately by the AppFunctions feature (`specs/20260521-091500-app-functions/`), which exposes `sendMessage`, `getMeshStatus`, `listNodes`, `getRecentMessages`, and `getNodePosition` to Android system AI (Gemini) automatically — including on car displays.
|
||||
- Q: Should the app declare NAVIGATION category for MapWithContentTemplate, or use PlaceListMapTemplate under POI? → A: Stay with POI category, use PlaceListMapTemplate (static pin list, refreshable). Avoids nav app conflicts and Play Store review burden. Live position tracking under NAVIGATION category deferred to v2.
|
||||
- Q: Should the app declare NAVIGATION category for MapWithContentTemplate, or use PlaceListMapTemplate under POI? → A: **DECISION DEFERRED** — originally selected POI/PlaceListMapTemplate but reopened for further research. See US-5 deferral note for open questions on NAVIGATION vs POI implications.
|
||||
- Q: Should the CarAppService maintain an independent BLE connection or share the phone app's existing connection? → A: Shared connection — single Application-scoped BleConnectionManager instance via Koin. CarAppService keeps the process alive via Android Auto host; BLE connection persists at the Service/Application level, not Activity level.
|
||||
- Q: What observability approach should the car module use? → A: Reuse existing Crashlytics with `car_session` custom key tagging for car-specific filtering. No new observability infrastructure; tag existing analytics paths.
|
||||
- Q: Should the car app unlock additional features when the vehicle is parked? → A: No parked-mode differentiation. Templated messaging apps provide a uniform experience regardless of driving state. Voice reply is built into ConversationItem. The Android Auto host enforces its own driving restrictions; the app just provides templates.
|
||||
@@ -225,7 +225,7 @@ A driver uses CAL's built-in voice input to compose messages and perform actions
|
||||
| MeshtasticCarAppService | `feature/car/service/` | CAL Session host, entry point for Android Auto/AAOS |
|
||||
| MessagingScreen | `feature/car/screens/` | Message list with channel chips, voice reply, quick-reply |
|
||||
| NodeDashboardScreen | `feature/car/screens/` | Condensed Items grid of all mesh nodes |
|
||||
| MapScreen | `feature/car/screens/` | PlaceListMapTemplate showing node positions as place items |
|
||||
| ~~MapScreen~~ | ~~`feature/car/screens/`~~ | ~~PlaceListMapTemplate showing node positions~~ — **DEFERRED** |
|
||||
| EmergencyHandler | `feature/car/alerts/` | Banner management for emergency messages |
|
||||
| MeshStatusPanel | `feature/car/panels/` | Minimized Control Panel with mesh health |
|
||||
| CarMessageRepository | `core/data/` | Existing message repository (reused) |
|
||||
@@ -313,7 +313,7 @@ A driver uses CAL's built-in voice input to compose messages and perform actions
|
||||
- The `google` build flavor is the distribution target; F-Droid/GitHub flavors do not include car support
|
||||
- Quick-reply templates are configurable via the phone app's settings; the car app consumes them read-only
|
||||
- Voice input quality depends on the car's microphone hardware; the app delegates to Android's speech recognition system
|
||||
- MapWithContentTemplate availability depends on NAVIGATION category declaration (deferred to v2); v1 uses PlaceListMapTemplate under POI which is widely supported
|
||||
- Map template strategy (POI vs NAVIGATION category) is deferred; no map screen in initial implementation
|
||||
- Minimum Car API Level 8 is required; older Android Auto hosts will not show the app (graceful absence, not crash)
|
||||
- Koin dependency injection is used consistently with Koin Annotations for the new module
|
||||
- TTS (text-to-speech) for reading messages aloud uses Android's built-in TTS engine
|
||||
@@ -453,7 +453,7 @@ ConversationItem.Builder()
|
||||
**Android-exclusive features (exceeding Apple):**
|
||||
- Node dashboard with Condensed Items (Apple has no node visibility)
|
||||
- Emergency Banner overlays with audio alerts (Apple shows emergencies as regular messages)
|
||||
- Map integration via PlaceListMapTemplate (Apple has no map)
|
||||
- ~~Map integration~~ (DEFERRED pending NAVIGATION vs POI decision)
|
||||
- Channel Chips for instant switching (Apple requires tab navigation)
|
||||
- Quick-reply templates (Apple only offers Siri voice)
|
||||
- Visual hierarchy via Spotlight/Section Headers/Expanded Headers
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
- [ ] T002 Add `include(":feature:car")` to settings.gradle.kts
|
||||
- [ ] T003 Create module build file at feature/car/build.gradle.kts with android-library, flavors, koin plugins, and all dependencies per contracts/manifest-declarations.md
|
||||
- [ ] T004 [P] Add `"googleImplementation"(projects.feature.car)` dependency in androidApp/build.gradle.kts
|
||||
- [ ] T005 [P] Create AndroidManifest.xml at feature/car/src/main/AndroidManifest.xml with CarAppService, MESSAGING+POI categories, and minCarApiLevel 8 meta-data
|
||||
- [ ] T005 [P] Create AndroidManifest.xml at feature/car/src/main/AndroidManifest.xml with CarAppService, MESSAGING category, and minCarApiLevel 8 meta-data
|
||||
- [ ] T006 [P] Create AAOS descriptor at feature/car/src/main/res/xml/automotive_app_desc.xml
|
||||
- [ ] T007 [P] Create car-specific strings file at feature/car/src/main/res/values/strings.xml with initial string resources
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
- [ ] T011 [P] Create TemplateBuilders helper extensions at feature/car/src/main/kotlin/org/meshtastic/feature/car/util/TemplateBuilders.kt with reusable CAL template construction helpers
|
||||
- [ ] T012 Create MeshtasticCarAppService at feature/car/src/main/kotlin/org/meshtastic/feature/car/service/MeshtasticCarAppService.kt extending CarAppService, creating sessions via Koin
|
||||
- [ ] T013 Create MeshtasticCarSession at feature/car/src/main/kotlin/org/meshtastic/feature/car/service/MeshtasticCarSession.kt with onCreateScreen (returns HomeScreen), onNewIntent, onCarConfigurationChanged, Crashlytics tagging, 300ms invalidation debouncing
|
||||
- [ ] T014 Create presentation state models (CarSessionState, ConnectionStatus, MessagingUiState, ChannelUi, ConversationUi, NodeDashboardUiState, NodeUi, SignalQuality, TopologyHeader, MapUiState, NodePlace, LatLngWrapper, EmergencyAlert) at feature/car/src/main/kotlin/org/meshtastic/feature/car/model/CarUiModels.kt
|
||||
- [ ] T014 Create presentation state models (CarSessionState, ConnectionStatus, MessagingUiState, ChannelUi, ConversationUi, NodeDashboardUiState, NodeUi, SignalQuality, TopologyHeader, EmergencyAlert) at feature/car/src/main/kotlin/org/meshtastic/feature/car/model/CarUiModels.kt
|
||||
- [ ] T015 Create HomeScreen (TabTemplate with Messages/Nodes tabs; Map tab placeholder deferred) at feature/car/src/main/kotlin/org/meshtastic/feature/car/screens/HomeScreen.kt
|
||||
|
||||
**Checkpoint**: Foundation ready — CarAppService binds, session creates, HomeScreen renders tabs. User story implementation can now begin in parallel.
|
||||
@@ -245,7 +245,7 @@ Task: T031 "Register panel in session"
|
||||
1. Setup + Foundational → Module compiles and binds to Android Auto
|
||||
2. Add US1 (Messaging) → Core value delivered (MVP!)
|
||||
3. Add US2 (Emergency) → Safety-critical alerts operational
|
||||
4. Add US3 + US5 (Nodes + Map) → Location awareness complete
|
||||
4. Add US3 (Nodes) → Node awareness complete
|
||||
5. Add US4 (Channels) → Multi-channel workflows enabled
|
||||
6. Add US6 + US7 (Panel + Voice) → Polish and hands-free refinement
|
||||
7. Each increment is independently testable with the Desktop Head Unit (DHU)
|
||||
@@ -254,8 +254,8 @@ Task: T031 "Register panel in session"
|
||||
|
||||
With multiple developers after Phase 2:
|
||||
- Developer A: US1 (Messaging) → US4 (Channels) → US7 (Voice)
|
||||
- Developer B: US3 (Nodes) → US5 (Map)
|
||||
- Developer C: US2 (Emergency) + US6 (Status Panel)
|
||||
- Developer B: US3 (Nodes) + US6 (Status Panel)
|
||||
- Developer C: US2 (Emergency)
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user