chore: add manual location API (setLastKnownLocation)#655
chore: add manual location API (setLastKnownLocation)#655Shahroz16 merged 1 commit intofeat/real-time-locationfrom
Conversation
|
|
||
| override fun stopLocationUpdates() { | ||
| // Will be implemented in the SDK-managed location PR | ||
| logger.debug("stopLocationUpdates is not yet implemented.") |
There was a problem hiding this comment.
Location update APIs are non-functional
Medium Severity
requestLocationUpdateOnce() and stopLocationUpdates() are exposed in LocationServices but currently only log messages and perform no location request or cancellation. Calling these APIs appears successful but never emits a TrackLocationEvent, so SDK-managed location tracking is effectively unavailable despite the public contract.
Additional Locations (1)
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✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## feat/real-time-location #655 +/- ##
==========================================================
Coverage ? 68.20%
Complexity ? 760
==========================================================
Files ? 142
Lines ? 4322
Branches ? 582
==========================================================
Hits ? 2948
Misses ? 1148
Partials ? 226 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Build available to test |
|
📏 SDK Binary Size Comparison ReportNo changes detected in SDK binary size ✅ |
|
7843bc0 to
2102026
Compare
cc37ac3 to
2fba264
Compare
|
|
| * | ||
| * @throws UninitializedPropertyAccessException if accessed before initialization | ||
| */ | ||
| lateinit var locationServices: LocationServices |
There was a problem hiding this comment.
I think it would be nice to add a reason why we should be accessing it only after initialize to help avoid breaking when making changes around this in future
2fba264 to
26ec3ae
Compare
| * This guards against race conditions during app startup or incorrect call order. | ||
| */ | ||
| val locationServices: LocationServices | ||
| get() = _locationServices ?: UninitializedLocationServices(SDKComponent.logger) |
There was a problem hiding this comment.
Cached service stays permanently uninitialized
Medium Severity
locationServices returns a new UninitializedLocationServices instance when _locationServices is null. If code reads and stores ModuleLocation.instance().locationServices before module initialization completes, that stored object never switches to LocationServicesImpl, so later setLastKnownLocation calls keep no-oping even after SDK initialization.
Additional Locations (1)
There was a problem hiding this comment.
The getter evaluates on every access, it's not a cached field. Normal usage (ModuleLocation.instance().locationServices.setLastKnownLocation(...)) always hits the getter, so it
picks up the real implementation after init. The only risk is if a caller stores the reference before CustomerIO.initialize() completes, which is a very narrow window since both
happen sequentially in Application.onCreate(). Even in that case, the no-op logs an error on every call, making it easy to spot during development.
| fun instance(): ModuleLocation { | ||
| return SDKComponent.modules[MODULE_NAME] as? ModuleLocation | ||
| ?: throw IllegalStateException("ModuleLocation not initialized") | ||
| ?: throw IllegalStateException("ModuleLocation not initialized. Add ModuleLocation to CustomerIOConfigBuilder before calling CustomerIO.initialize().") |
There was a problem hiding this comment.
Pre-init access still throws via instance
Medium Severity
locationServices has a no-op fallback for pre-initialization access, but the documented access path ModuleLocation.instance().locationServices still throws before SDK initialization. instance() fails before the fallback can run, so early calls can crash instead of no-oping.
Additional Locations (1)
There was a problem hiding this comment.
instance() throwing before registration is intentional and consistent with all other SDK modules (ModuleMessagingInApp.instance(), etc.). It surfaces a configuration error, the
developer forgot to call addCustomerIOModule(ModuleLocation()). The no-op fallback on locationServices covers a different case: the module is registered but initialize() hasn't run yet. These are two separate failure modes with two appropriate behaviors, crash for misconfiguration, no-op for timing.
|
|
Implement the manual location tracking API allowing host apps to send their own location data to Customer.io: - LocationServices interface: public API with setLastKnownLocation (raw lat/lng and Android Location overloads), requestLocationUpdateOnce, and stopLocationUpdates stubs - LocationServicesImpl: validates coordinates, checks config, posts TrackLocationEvent via EventBus - UninitializedLocationServices: error-logging stub for pre-init calls - ModuleLocation: wires LocationServicesImpl on initialize() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
26ec3ae to
b18ac22
Compare
|
|


Summary
LocationServicesinterface withsetLastKnownLocation,requestLocationUpdateOnce,stopLocationUpdatesLocationServicesImplwith coordinate validation and config checks for manual locationlocationServicesonModuleLocationas alateinit var(initialized during SDK init)requestLocationUpdateOnceandstopLocationUpdatesare stubbed (implemented in the next PR)This PR introduces the customer-facing location API. Host apps with their own location system can call
setLastKnownLocation(lat, lng)orpass an Android
Locationobject to send location data to Customer.io.Note
Medium Risk
Introduces a new public API and wiring that emits location events; incorrect initialization order or coordinate handling could lead to missing/extra tracking, though behavior is mostly guarded by validation and config checks.
Overview
Adds a new public
LocationServicesinterface and exposes it viaModuleLocation.locationServices, initialized during module startup with a no-op fallback that logs errors if accessed beforeCustomerIO.initialize().Implements manual location tracking in
LocationServicesImpl.setLastKnownLocation(...)by validating coordinates, honoringenableLocationTracking, and publishing aTrackLocationEvent;requestLocationUpdateOnce()/stopLocationUpdates()are added to the API but currently stubbed to log only.Written by Cursor Bugbot for commit b18ac22. This will update automatically on new commits. Configure here.