SA-99 - Add wake on leave to sleep screen#963
Conversation
lukeduncan-scot
commented
Jul 20, 2026
- Added wake on leave to sleep screen
- Device wakes up when user navigates 12 metres from start location using CheapRuler.distance()) function
-
- Refactored to encapsulate all logic into ViewModel, exposing state and effects to the composable that instantiates the VM.
- Hoisted state out into parent composable.
…function. - Implementing functionality for GeoFence.
…ly invoke start in SharedSleepScreen - Removed "context" from "start" as it was no longer required - Moved AndroidLocationProvider back to app module and used AppCallback for function to provide LocationProvider in shared module
- Managing exit of screen - Created events shared flow to manage button clicks and trigger functionality required.
- Using a Channel to send effects to the composable - Removed onExit and onWakeUp as they are no longer required.
davecraig
left a comment
There was a problem hiding this comment.
I'm worried that this approach may consume too much battery. Users may leave the app in sleep-until-wake for days at a time. As mentioned in the Jira issue there are geo-fencing APIs for iOS and Android which are designed to allow low-power geo-fencing support. The app already requests "Background Battery Usage" so that when running with the phone locked it doesn't get put too much to sleep, but that will also affect the app when running in sleep-until-wake. I suspect that means that the app would be polling at 1Hz as each new GPS comes in.
FWIW Claude says:
The "wake on leave" feature (SharedSleepScreen.kt) implements geofencing entirely in shared Kotlin business logic, polling raw GPS and computing distance manually ? it does not use either platform's OS-level geofencing:
What it actually does (SharedSleepScreen.kt:170-210):
- Starts continuous location updates via locationProvider.start()
- On every emission, computes distance from the start point with CheapRuler
- If distance > 12 m, calls destroy() to wake up
Android ? GooglePlayLocationProvider.start() (app/.../GooglePlayLocationProvider.kt:73-84):
- Uses Priority.PRIORITY_HIGH_ACCURACY with a 1-second update interval and setMinUpdateDistanceMeters(1f)
- This is continuous high-accuracy GPS polling, the opposite of low-power. The right API here is GeofencingClient/GeofencingRequest from com.google.android.gms.location (Play Services), which lets the OS handle region
entry/exit at the hardware level with far lower power draw, and works even if the app/process is killed.
iOS ? IosLocationProvider (shared/.../IosLocationProvider.kt:19-23):
- Uses kCLLocationAccuracyBest, distanceFilter = kCLDistanceFilterNone, allowsBackgroundLocationUpdates = true, pausesLocationUpdatesAutomatically = false ? again continuous best-accuracy tracking.
- The low-power equivalent is CLLocationManager.startMonitoring(for: CLCircularRegion), which uses cell/Wi-Fi-based region monitoring and doesn't require the app to stay active polling GPS.
Note: CLCircularRegion is already imported elsewhere in the codebase (IosGeocoder.kt:10) for an unrelated purpose, so the type is available but isn't being used for this feature.
Practical impact: for a "sleep with wake-on-leave" feature ? likely used overnight or for extended periods ? continuously polling GPS at 1 Hz with best accuracy will drain the battery significantly compared to OS-level
geofencing, which is the main reason these APIs exist. This is worth flagging before merge; switching to GeofencingClient (Android) and region monitoring (iOS) would be a more substantial change than what's in this branch, so
it's a design question for the team rather than a quick fix.
|
That's fine, thanks for the summary. FWIW, Claude has missed the fact that I have used either the Fused client or the base Android Location APIs depending on whether the user has Play Services installed or not, as not every phone has it. I was just using the functionality similar to that used in routes, which, upon looking at the API for geofencing, might actually be a candidate for replacing if we want to further reduce battery use. I guess it all depends on how these are implemented. The implementation I have only receives an update when the LocationProvider emits a new location. I'll take a look into the Geofencing APIs though it appears that the APIs are only available on Google Play Services: https://developers.google.com/android/reference/com/google/android/gms/location/Geofence.Builder.html |
|
…ow power location monitoring for geofencing. - Left original "start()" function in LocationProvider that now defaults to previous behaviour so to not break API.
…for less frequent updates in snooze mode.
…aving 2 functions. API will still be the same for consumers, they can just now add a parameter to request accuracy. - Using Accuracy parameter in IosLocationProvider.
|
I'm having issues replicating the failures in the actions on my local Mac. I'm investigating. |
|
Ideally the actions would fail fast, when one fails (meaning the PR will be rejected) the others won't run, as it's a waste of compute here. |