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
|
||||
|
||||
Phase: 3 of 4 (Overlay Refactor)
|
||||
Plan: 2 of 2 complete
|
||||
Status: Phase complete
|
||||
Last activity: 2026-02-11 — Completed 03-02-PLAN.md
|
||||
Phase: 4 of 4 (GPS Power Optimization)
|
||||
Plan: 1 of 2 complete
|
||||
Status: In progress
|
||||
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
|
||||
|
||||
**Velocity:**
|
||||
- Total plans completed: 6
|
||||
- Average duration: 6.3 minutes
|
||||
- Total execution time: 0.63 hours
|
||||
- Total plans completed: 7
|
||||
- Average duration: 6.0 minutes
|
||||
- Total execution time: 0.71 hours
|
||||
|
||||
**By Phase:**
|
||||
|
||||
@@ -30,10 +30,11 @@ Progress: [██████░░░░] 60% (Phase 3: 2/2 plans complete)
|
||||
| 1. Foundation | 2 | 19.6 min | 9.8 min |
|
||||
| 2. Provider Migration | 2 | 11.5 min | 5.75 min |
|
||||
| 3. Overlay Refactor | 2 | 8.25 min | 4.1 min |
|
||||
| 4. GPS Optimization | 1 | 4.9 min | 4.9 min |
|
||||
|
||||
**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)
|
||||
- Trend: Consistent sub-5-minute plans in Phase 3
|
||||
- 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 continuing in Phase 4
|
||||
|
||||
*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 | Staleness opacity via withValues(alpha:) no animation | Implemented |
|
||||
| 03 | 02 | GPS grace period timer created (Phase 4 lifecycle) | Implemented |
|
||||
| 04 | TBD | Speed-adaptive GPS precision (~10 km/h threshold) | Pending |
|
||||
| 04 | TBD | Background GPS only when overlay visible | Pending |
|
||||
| 04 | 01 | Speed-adaptive GPS precision (8/12 km/h hysteresis) | Implemented |
|
||||
| 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
|
||||
|
||||
@@ -125,13 +130,20 @@ Recent decisions affecting current work:
|
||||
- INFO: Manual testing needed to verify overlay reliability improvements on physical device
|
||||
- INFO: All OVRL-01 through OVRL-06 requirements satisfied
|
||||
|
||||
**Phase 4 (GPS Optimization):**
|
||||
- Speed thresholds (8/12 km/h) need field testing validation
|
||||
- Android OEM behavior varies (Samsung, Xiaomi duty-cycling differences)
|
||||
**Phase 4 (GPS Optimization) - In Progress:**
|
||||
- RESOLVED: Core GPS engine complete with lifecycle awareness and precision switching
|
||||
- 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
|
||||
|
||||
Last session: 2026-02-11 (Plan 03-02 execution complete)
|
||||
Stopped at: Completed 03-02-PLAN.md — Phase 3 complete
|
||||
Last session: 2026-02-12 (Plan 04-01 execution complete)
|
||||
Stopped at: Completed 04-01-PLAN.md — Phase 4 in progress (1/2 plans)
|
||||
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