chore: update Location tracking module config#665
chore: update Location tracking module config#665Shahroz16 merged 12 commits intofeat/real-time-locationfrom
Conversation
…de enum Introduce a 3-state LocationTrackingMode enum (OFF, MANUAL, ON_APP_START) replacing the boolean enableLocationTracking config. OFF disables all location machinery including identify enrichment and track events. MANUAL preserves existing behavior. ON_APP_START auto-captures location on cold start with cacheOnly mode for identify context enrichment. - Add LocationTrackingMode enum with OFF, MANUAL, ON_APP_START - Update LocationModuleConfig to use trackingMode with isEnabled guard - Add cacheOnly parameter to LocationTracker.onLocationReceived() - Guard restore/enrich/subscribe setup behind isEnabled in ModuleLocation - Remove stopLocationUpdates() (only relevant for continuous tracking) - Add request deduplication via job cancellation in LocationServicesImpl - Update public API surface, tests, and sample app Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ON_APP_START auto-captured location now goes through the normal path (cache + sync filter + track event if filter passes) instead of skipping the track event. This aligns with iOS SDK behavior where all location updates are treated uniformly regardless of source. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…OT_DETERMINED auth status Split the monolithic LocationTracker into LocationEnrichmentProvider (identify context enrichment) and LocationSyncCoordinator (persistence + sync filter + track events) to match iOS SDK architecture. Both register as IdentifyHook with their own reset responsibilities. Add NOT_DETERMINED to AuthorizationStatus and PERMISSION_NOT_DETERMINED to LocationProviderError for API completeness with iOS. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…s, add NOT_DETERMINED auth status" This reverts commit e480d68.
Sample app builds 📱Below you will find the list of the latest versions of the sample apps. It's recommended to always download the latest builds of the sample apps to accurately test the pull request. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## feat/real-time-location #665 +/- ##
==========================================================
Coverage ? 67.34%
Complexity ? 764
==========================================================
Files ? 146
Lines ? 4382
Branches ? 591
==========================================================
Hits ? 2951
Misses ? 1204
Partials ? 227 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
|
|
Build available to test |
📏 SDK Binary Size Comparison Report
|
|
|
|
|
| private val scope: CoroutineScope | ||
| ) : LocationServices { | ||
|
|
||
| private val lock = ReentrantLock() |
There was a problem hiding this comment.
Is there a specific reason why we removed that lock?
There was a problem hiding this comment.
The lock was originally added when we used last-wins dedup (cancel old → start new). That pattern creates a concurrent jobs scenario where the lock was needed to atomically cancel-then-relaunch.
We switched to first-wins dedup (if a request is in flight, ignore the new call) what iOS is doing. With first-wins, there's only ever one job at a time — no concurrent job scenario, so the lock's original purpose is gone.
The only theoretical race is two threads calling requestLocationUpdate() simultaneously when no job is active, both could launch a job. The consequence is one redundant GPS request
| // If permissions are denied or services disabled, orchestrator silently no-ops. | ||
| if (moduleConfig.trackingMode == LocationTrackingMode.ON_APP_START) { | ||
| services.requestLocationUpdate() | ||
| } |
There was a problem hiding this comment.
I think we should actually do this in onStart of the lifecycle observer to be completely sure we are not doing this in the bacgkround
There was a problem hiding this comment.
In practice, CustomerIO.initialize() runs during Application.onCreate(), and if the process started for a background reason, Android's background location restrictions (API 29+) silently fail the GPS request. Our onStop observer would also cancel it. So the current approach is safe without the extra indirection.
Can still add it to have parity with iOS
location/src/main/kotlin/io/customer/location/LocationLifecycleObserver.kt
Show resolved
Hide resolved
|
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
|
|
|
|
|
|
Summary
enableLocationTracking: Booleanwith a 3-stateLocationTrackingModeenum (OFF,MANUAL,ON_APP_START)ON_APP_STARTauto-captures location on cold start, going through the normal sync filter path (cache + 24h/1km filter + track event)OFFmode early-returns ininitialize(), skipping all background machinery (no restoration, no enrichment, no event subscriptions)stopLocationUpdates()from public API — not needed for one-shot request patternLocationServicesImplby removing lock and stop logicNote
Medium Risk
Changes the public location module API/config and alters lifecycle-driven behavior (auto-capture on startup and cancellation on background), which could affect when/if location is collected or jobs are dropped. Also introduces new dependency on process lifecycle and changes in-flight request semantics from cancel-and-replace to first-wins.
Overview
Location module config is redesigned from a boolean
enableLocationTrackingto a 3-stateLocationTrackingMode(OFF,MANUAL,ON_APP_START), withOFFnow short-circuitingModuleLocation.initialize()to skip restoration/enrichment/subscriptions.Location request behavior is updated:
LocationServices.stopLocationUpdates()is removed,LocationServicesImplswitches to first-wins in-flight dedup (ignore new calls while a request is active), and in-flight requests are cancelled automatically when the app backgrounds via a newProcessLifecycleOwnerobserver.Shared main-thread posting utility is moved into
coreasMainThreadPoster/HandlerMainThreadPosterand reused by in-app messaging; samples/tests are updated accordingly, including removing the sample UI’s “stop updates” button and adding unit tests forOFFmode no-ops.Written by Cursor Bugbot for commit d21a04a. This will update automatically on new commits. Configure here.