docs(04-01): complete core GPS engine plan
- Created SUMMARY.md documenting lifecycle-aware GPS engine implementation - Updated STATE.md to Phase 4 Plan 1 of 2 complete (70% progress) - Added 6 key decisions to STATE.md decisions table - Updated performance metrics: 7 plans, 4.9 min average for Phase 4 - Updated session continuity and blockers sections - Documented self-check results: all files and commits verified Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+30
-18
@@ -9,19 +9,19 @@ See: .planning/PROJECT.md (updated 2026-02-09)
|
|||||||
|
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 3 of 4 (Overlay Refactor)
|
Phase: 4 of 4 (GPS Power Optimization)
|
||||||
Plan: 2 of 2 complete
|
Plan: 1 of 2 complete
|
||||||
Status: Phase complete
|
Status: In progress
|
||||||
Last activity: 2026-02-11 — Completed 03-02-PLAN.md
|
Last activity: 2026-02-12 — Completed 04-01-PLAN.md
|
||||||
|
|
||||||
Progress: [██████░░░░] 60% (Phase 3: 2/2 plans complete)
|
Progress: [███████░░░] 70% (Phase 4: 1/2 plans complete)
|
||||||
|
|
||||||
## Performance Metrics
|
## Performance Metrics
|
||||||
|
|
||||||
**Velocity:**
|
**Velocity:**
|
||||||
- Total plans completed: 6
|
- Total plans completed: 7
|
||||||
- Average duration: 6.3 minutes
|
- Average duration: 6.0 minutes
|
||||||
- Total execution time: 0.63 hours
|
- Total execution time: 0.71 hours
|
||||||
|
|
||||||
**By Phase:**
|
**By Phase:**
|
||||||
|
|
||||||
@@ -30,10 +30,11 @@ Progress: [██████░░░░] 60% (Phase 3: 2/2 plans complete)
|
|||||||
| 1. Foundation | 2 | 19.6 min | 9.8 min |
|
| 1. Foundation | 2 | 19.6 min | 9.8 min |
|
||||||
| 2. Provider Migration | 2 | 11.5 min | 5.75 min |
|
| 2. Provider Migration | 2 | 11.5 min | 5.75 min |
|
||||||
| 3. Overlay Refactor | 2 | 8.25 min | 4.1 min |
|
| 3. Overlay Refactor | 2 | 8.25 min | 4.1 min |
|
||||||
|
| 4. GPS Optimization | 1 | 4.9 min | 4.9 min |
|
||||||
|
|
||||||
**Recent Trend:**
|
**Recent Trend:**
|
||||||
- Last 5 plans: 02-01 (7.7 min), 02-02 (3.8 min), 03-01 (4.0 min), 03-02 (4.25 min)
|
- Last 5 plans: 02-02 (3.8 min), 03-01 (4.0 min), 03-02 (4.25 min), 04-01 (4.9 min)
|
||||||
- Trend: Consistent sub-5-minute plans in Phase 3
|
- Trend: Consistent sub-5-minute plans continuing in Phase 4
|
||||||
|
|
||||||
*Updated after each plan completion*
|
*Updated after each plan completion*
|
||||||
|
|
||||||
@@ -70,8 +71,12 @@ Recent decisions affecting current work:
|
|||||||
| 03 | 02 | Error callback pattern for provider-to-screen comm | Implemented |
|
| 03 | 02 | Error callback pattern for provider-to-screen comm | Implemented |
|
||||||
| 03 | 02 | Staleness opacity via withValues(alpha:) no animation | Implemented |
|
| 03 | 02 | Staleness opacity via withValues(alpha:) no animation | Implemented |
|
||||||
| 03 | 02 | GPS grace period timer created (Phase 4 lifecycle) | Implemented |
|
| 03 | 02 | GPS grace period timer created (Phase 4 lifecycle) | Implemented |
|
||||||
| 04 | TBD | Speed-adaptive GPS precision (~10 km/h threshold) | Pending |
|
| 04 | 01 | Speed-adaptive GPS precision (8/12 km/h hysteresis) | Implemented |
|
||||||
| 04 | TBD | Background GPS only when overlay visible | Pending |
|
| 04 | 01 | Precision switching gated until 5s after first fix | Implemented |
|
||||||
|
| 04 | 01 | Background grace period re-checks overlay at expiry | Implemented |
|
||||||
|
| 04 | 01 | Wake lock contextual: GPS + (overlay OR foreground) | Implemented |
|
||||||
|
| 04 | 01 | GPS stop preserves last data for staleness display | Implemented |
|
||||||
|
| 04 | 01 | BACKGROUND_GRACE_PERIOD (7s) replaces GPS_GRACE_PERIOD| Implemented |
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@@ -125,13 +130,20 @@ Recent decisions affecting current work:
|
|||||||
- INFO: Manual testing needed to verify overlay reliability improvements on physical device
|
- INFO: Manual testing needed to verify overlay reliability improvements on physical device
|
||||||
- INFO: All OVRL-01 through OVRL-06 requirements satisfied
|
- INFO: All OVRL-01 through OVRL-06 requirements satisfied
|
||||||
|
|
||||||
**Phase 4 (GPS Optimization):**
|
**Phase 4 (GPS Optimization) - In Progress:**
|
||||||
- Speed thresholds (8/12 km/h) need field testing validation
|
- RESOLVED: Core GPS engine complete with lifecycle awareness and precision switching
|
||||||
- Android OEM behavior varies (Samsung, Xiaomi duty-cycling differences)
|
- RESOLVED: ProcessedGpsData timestamp field added for staleness detection
|
||||||
|
- RESOLVED: Background grace period (7s) with race condition protection
|
||||||
|
- RESOLVED: Conditional wake lock (GPS active + visible)
|
||||||
|
- INFO: Plan 04-01 complete (4.9 min) — ready for Plan 04-02 (UI Integration)
|
||||||
|
- PENDING: SpeedometerScreen needs gpsDataManager.setOverlayProvider() call
|
||||||
|
- PENDING: Background heartbeat (5s) may need adjustment vs 7s grace period
|
||||||
|
- FIELD TESTING: Speed thresholds (8/12 km/h) need validation on physical device
|
||||||
|
- FIELD TESTING: Android OEM behavior varies (Samsung, Xiaomi duty-cycling differences)
|
||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-02-11 (Plan 03-02 execution complete)
|
Last session: 2026-02-12 (Plan 04-01 execution complete)
|
||||||
Stopped at: Completed 03-02-PLAN.md — Phase 3 complete
|
Stopped at: Completed 04-01-PLAN.md — Phase 4 in progress (1/2 plans)
|
||||||
Resume file: None
|
Resume file: None
|
||||||
Next action: Begin Phase 4 (GPS Optimization) planning
|
Next action: Execute Plan 04-02 (UI Integration)
|
||||||
|
|||||||
@@ -0,0 +1,191 @@
|
|||||||
|
---
|
||||||
|
phase: 04-gps-power-optimization
|
||||||
|
plan: 01
|
||||||
|
subsystem: gps
|
||||||
|
tags: [geolocator, wakelock, lifecycle, precision-switching]
|
||||||
|
|
||||||
|
requires:
|
||||||
|
- phase: 03-overlay-refactor
|
||||||
|
provides: OverlayProvider with isOverlayActive, OverlayService, staleness constants
|
||||||
|
provides:
|
||||||
|
- Lifecycle-aware GpsDataManager with WidgetsBindingObserver
|
||||||
|
- Speed-adaptive precision switching (8/12 km/h hysteresis)
|
||||||
|
- Background GPS management with 7s grace period
|
||||||
|
- Conditional wake lock (GPS active + visible)
|
||||||
|
- ProcessedGpsData with timestamp field
|
||||||
|
- Dynamic GPS stream via GpsService.createPositionStream()
|
||||||
|
affects: [04-02-ui-integration]
|
||||||
|
|
||||||
|
tech-stack:
|
||||||
|
added: [wakelock_plus (already dependency)]
|
||||||
|
patterns: [WidgetsBindingObserver for lifecycle, hysteresis threshold switching, race condition protection]
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created: []
|
||||||
|
modified:
|
||||||
|
- lib/models/processed_gps_data.dart
|
||||||
|
- lib/config/gps_constants.dart
|
||||||
|
- lib/config/timing_constants.dart
|
||||||
|
- lib/gps_service.dart
|
||||||
|
- lib/services/gps_data_manager.dart
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "Speed-adaptive precision switching uses hysteresis (8/12 km/h) to prevent thrashing"
|
||||||
|
- "Precision switching gated until 5s after first GPS fix for stability"
|
||||||
|
- "Background grace period re-checks overlay state at expiry to handle race conditions"
|
||||||
|
- "Wake lock is contextual: enabled when GPS active AND (overlay visible OR app in foreground)"
|
||||||
|
- "GPS stop preserves last known data for staleness display (no data clearing)"
|
||||||
|
- "Deprecated GPS_GRACE_PERIOD (30s) in favor of BACKGROUND_GRACE_PERIOD (7s) for lifecycle"
|
||||||
|
|
||||||
|
duration: 4.9min
|
||||||
|
completed: 2026-02-12
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 4 Plan 01: Core GPS Engine Summary
|
||||||
|
|
||||||
|
**Lifecycle-aware GPS manager with speed-adaptive precision switching, 7s background grace period, and conditional wake lock control**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** 4.9 minutes
|
||||||
|
- **Start:** 2026-02-11 23:57:48 UTC
|
||||||
|
- **End:** 2026-02-12 00:02:42 UTC
|
||||||
|
- **Tasks completed:** 2
|
||||||
|
- **Files modified:** 5
|
||||||
|
- **Commits:** 2
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
Successfully transformed GpsDataManager into a fully lifecycle-aware GPS engine with intelligent power management:
|
||||||
|
|
||||||
|
1. **ProcessedGpsData Timestamp Field**
|
||||||
|
- Added `timestamp` field to enable staleness detection in overlay
|
||||||
|
- Updated `copyWith()` to support timestamp parameter
|
||||||
|
- Changed default initialization from `const` to non-const with `DateTime.now()`
|
||||||
|
|
||||||
|
2. **Precision Switching Constants**
|
||||||
|
- Added `PRECISION_UP_THRESHOLD_MPS` (3.33 m/s / 12 km/h) for high precision
|
||||||
|
- Added `PRECISION_DOWN_THRESHOLD_MPS` (2.22 m/s / 8 km/h) for balanced precision
|
||||||
|
- Added `PRECISION_SWITCH_FIRST_FIX_DELAY` (5s) safety gate
|
||||||
|
- Hysteresis prevents precision thrashing in 8-12 km/h range
|
||||||
|
|
||||||
|
3. **Lifecycle Constants**
|
||||||
|
- Added `BACKGROUND_GRACE_PERIOD` (7s) for responsive background management
|
||||||
|
- Deprecated `GPS_GRACE_PERIOD` (30s) with clear documentation
|
||||||
|
|
||||||
|
4. **Dynamic GPS Stream**
|
||||||
|
- Changed `GpsService.positionStream` from hardcoded `bestForNavigation` to `createPositionStream()`
|
||||||
|
- Accepts `LocationAccuracy` parameter for dynamic precision control
|
||||||
|
- Kept deprecated wrapper for backward compatibility during transition
|
||||||
|
|
||||||
|
5. **Lifecycle-Aware GPS Manager**
|
||||||
|
- Implemented `WidgetsBindingObserver` mixin for app lifecycle tracking
|
||||||
|
- Added overlay provider reference for background decision-making
|
||||||
|
- Tracks foreground/background state, GPS active state, current accuracy
|
||||||
|
- Registers/removes lifecycle observer in initialize()/dispose()
|
||||||
|
|
||||||
|
6. **Precision Switching Logic**
|
||||||
|
- Speed-based hysteresis switching (HIGH ↔ MEDIUM at 8/12 km/h boundaries)
|
||||||
|
- Gated until 5s after first GPS fix for stability
|
||||||
|
- Seamless stream recreation with new accuracy on switch
|
||||||
|
- Debug logging only (invisible to user per project decision)
|
||||||
|
|
||||||
|
7. **Background GPS Management**
|
||||||
|
- 7s grace period when app backgrounds without overlay visible
|
||||||
|
- Immediate GPS continuation when app backgrounds with overlay active
|
||||||
|
- Grace period re-checks overlay state at expiry (race condition protection)
|
||||||
|
- GPS restart on app foreground resume if previously stopped
|
||||||
|
|
||||||
|
8. **Conditional Wake Lock**
|
||||||
|
- Wake lock enabled when GPS active AND (overlay visible OR app in foreground)
|
||||||
|
- Wake lock disabled when GPS stops or app backgrounds without overlay
|
||||||
|
- Updated on all state transitions (GPS start/stop, lifecycle change)
|
||||||
|
- Disabled in dispose() as safety net
|
||||||
|
|
||||||
|
9. **State Preservation**
|
||||||
|
- GPS stop does NOT clear `_currentData` (preserves last known speed/heading)
|
||||||
|
- Staleness detection shows last data as stale per existing timer logic
|
||||||
|
- Fresh data immediately replaces stale display on GPS restart
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
| Task | Name | Commit | Files Modified |
|
||||||
|
| ---- | ----------------------------------------------------- | ------- | -------------- |
|
||||||
|
| 1 | Add timestamp and precision/lifecycle constants | c4d4032 | 4 files |
|
||||||
|
| 2 | Implement lifecycle-aware GPS engine with wake lock | 1618cfe | 1 file |
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
**Modified:**
|
||||||
|
- `lib/models/processed_gps_data.dart` — Added timestamp field and copyWith support
|
||||||
|
- `lib/config/gps_constants.dart` — Added precision switching thresholds (3.33/2.22 m/s, 5s delay)
|
||||||
|
- `lib/config/timing_constants.dart` — Added BACKGROUND_GRACE_PERIOD (7s), deprecated GPS_GRACE_PERIOD
|
||||||
|
- `lib/gps_service.dart` — Added createPositionStream() with dynamic accuracy, deprecated static getter
|
||||||
|
- `lib/services/gps_data_manager.dart` — Added lifecycle awareness, precision switching, wake lock control
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
1. **Hysteresis Thresholds:** 8/12 km/h boundaries prevent precision thrashing in transition zone
|
||||||
|
2. **First-Fix Gate:** 5s delay before precision switching prevents instability during initial acquisition
|
||||||
|
3. **Race Condition Protection:** Background grace period re-checks overlay state at expiry (not just at start)
|
||||||
|
4. **Wake Lock Strategy:** Conditional on GPS active + visible (overlay OR foreground) for minimal battery impact
|
||||||
|
5. **Data Preservation:** GPS stop preserves last known data, relying on existing staleness timer for UI feedback
|
||||||
|
6. **Grace Period Duration:** 7s chosen for responsive UX (short enough to save battery, long enough for quick returns)
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. [Rule 1 - Cleanup] Removed unnecessary flutter/foundation.dart import**
|
||||||
|
- **Found during:** Task 2 verification
|
||||||
|
- **Issue:** flutter analyze reported unnecessary import (flutter/widgets.dart provides ChangeNotifier)
|
||||||
|
- **Fix:** Removed `import 'package:flutter/foundation.dart';` from gps_data_manager.dart
|
||||||
|
- **Files modified:** lib/services/gps_data_manager.dart
|
||||||
|
- **Commit:** 1618cfe (included in Task 2 commit)
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
None. Plan executed exactly as written with only one minor cleanup deviation (unnecessary import removal).
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
**Ready for Plan 04-02 (UI Integration):**
|
||||||
|
- ✅ GpsDataManager implements full lifecycle awareness
|
||||||
|
- ✅ ProcessedGpsData carries timestamps for staleness detection
|
||||||
|
- ✅ Precision switching functional with hysteresis
|
||||||
|
- ✅ Background GPS management with grace period
|
||||||
|
- ✅ Wake lock contextual control implemented
|
||||||
|
- ✅ All timers properly canceled in dispose()
|
||||||
|
- ✅ Flutter analyze passes (only expected SCREAMING_SNAKE info warnings)
|
||||||
|
|
||||||
|
**Integration points for Plan 04-02:**
|
||||||
|
- SpeedometerScreen needs to call `gpsDataManager.setOverlayProvider(overlayProvider)` after provider wiring
|
||||||
|
- No UI changes needed for precision switching (silent/invisible per user decision)
|
||||||
|
- Background heartbeat may need adjustment (currently 5s, may conflict with 7s grace period)
|
||||||
|
- Staleness detection in overlay should consume `ProcessedGpsData.timestamp` field
|
||||||
|
|
||||||
|
**Testing considerations:**
|
||||||
|
- Field testing needed for 8/12 km/h hysteresis validation
|
||||||
|
- Android OEM behavior varies (Samsung, Xiaomi duty-cycling differences documented in research)
|
||||||
|
- Wake lock effectiveness depends on Android version and OEM power management
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
|
|
||||||
|
**Files exist:**
|
||||||
|
```
|
||||||
|
FOUND: lib/models/processed_gps_data.dart
|
||||||
|
FOUND: lib/config/gps_constants.dart
|
||||||
|
FOUND: lib/config/timing_constants.dart
|
||||||
|
FOUND: lib/gps_service.dart
|
||||||
|
FOUND: lib/services/gps_data_manager.dart
|
||||||
|
```
|
||||||
|
|
||||||
|
**Commits exist:**
|
||||||
|
```
|
||||||
|
FOUND: c4d4032
|
||||||
|
FOUND: 1618cfe
|
||||||
|
```
|
||||||
|
|
||||||
|
**Flutter analyze status:** 30 issues (all expected SCREAMING_SNAKE info warnings, no errors)
|
||||||
|
|
||||||
|
All claims verified. Plan execution complete.
|
||||||
Reference in New Issue
Block a user