Conversation
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…657) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…661) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Resolve conflict in strings.xml — keep both location and inbox strings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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 @@
## main #666 +/- ##
============================================
- Coverage 69.07% 68.07% -1.01%
- Complexity 838 842 +4
============================================
Files 149 153 +4
Lines 4601 4679 +78
Branches 628 637 +9
============================================
+ Hits 3178 3185 +7
- Misses 1189 1259 +70
- Partials 234 235 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| currentLocationJob = null | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Non-atomic check-then-act on volatile job field
Low Severity
requestLocationUpdate() performs a non-atomic check-then-act on currentLocationJob — reading isActive and then assigning a new job. Similarly, cancelInFlightRequest() reads and nulls the field without synchronization. Since @Volatile only ensures visibility (not atomicity of compound operations), two concurrent calls to requestLocationUpdate() can both pass the active check and launch duplicate coroutines, with the second overwriting the first's reference. The orphaned job still runs to completion but is untracked.
Additional Locations (1)
|
|
||
| if (!isLocationServicesEnabled()) { | ||
| throw LocationRequestException(error = LocationProviderError.SERVICES_DISABLED) | ||
| } |
There was a problem hiding this comment.
Redundant authorization check in provider and orchestrator
Low Severity
LocationOrchestrator.requestLocationUpdate() checks currentAuthorizationStatus().isAuthorized and returns early if denied. Then FusedLocationProvider.requestLocation() performs the exact same authorization check and throws LocationRequestException if denied. The orchestrator's check makes the provider's check unreachable via the normal call path, adding unnecessary duplication.
Additional Locations (1)
|
|
Build available to test |
📏 SDK Binary Size Comparison Report
|
|
|
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.
|
|
||
| logger.debug("Re-evaluating cached location: lat=$lat, lng=$lng") | ||
| trySendLocationTrack(lat, lng) | ||
| } |
There was a problem hiding this comment.
Cold start location sync relies on unreceived event
Medium Severity
The comment on syncCachedLocationIfNeeded says it's called "on cold start (via replayed UserChangedEvent)," but postUserIdentificationEvents() publishes UserChangedEvent in the CustomerIO init block — before ModuleLocation.initialize() subscribes to the event bus. If EventBus doesn't replay cached events to new subscribers, the location module never receives the initial UserChangedEvent, so syncCachedLocationIfNeeded() is never called on cold start for an already-identified user, silently skipping the supplementary "CIO Location Update" track event.
Additional Locations (2)
|
mahmoud-elmorabea
left a comment
There was a problem hiding this comment.
✅ Collection of approved PRs
## [4.17.0](4.16.1...4.17.0) (2026-03-09) ### Features * Location enrichment ([#666](#666)) ([8d856bc](8d856bc))


Note
Medium Risk
Adds a new module that handles location (PII), persistence/encryption, and hooks into identify/reset flows; mistakes could leak data, mis-enrich profiles, or increase event volume despite the gating/filter safeguards.
Overview
Adds a new
locationmodule that can cache device coordinates, enrichidentify()event context with lat/lng, and optionally emit a gatedCIO Location Updatetrack event (24h/1km filter) via a new internalDataPipelineinterface.Introduces internal plumbing to support module-driven enrichment:
IdentifyHook+IdentifyHookRegistryincore, a SegmentIdentifyContextPluginindatapipelines(also propagating synchronous resets), and updatesCustomerIOto implement/registerDataPipelineand to publishUserChangedEventafteranalytics.identify().Adds encrypted-at-rest preference storage via
PreferenceCrypto(Android Keystore w/ plaintext fallback), a newlocationScopecoroutine scope, a sharedMainThreadPosterabstraction (moved from in-app), plus build/dep updates (Play Services Location) and sample app wiring/UI to exercise location APIs.Written by Cursor Bugbot for commit 0616b22. This will update automatically on new commits. Configure here.