Skip to content

chore: update Location tracking module config#665

Merged
Shahroz16 merged 12 commits intofeat/real-time-locationfrom
feat/location-tracking-mode
Mar 4, 2026
Merged

chore: update Location tracking module config#665
Shahroz16 merged 12 commits intofeat/real-time-locationfrom
feat/location-tracking-mode

Conversation

@Shahroz16
Copy link
Contributor

@Shahroz16 Shahroz16 commented Mar 2, 2026

Summary

  • Replace enableLocationTracking: Boolean with a 3-state LocationTrackingMode enum (OFF, MANUAL, ON_APP_START)
  • ON_APP_START auto-captures location on cold start, going through the normal sync filter path (cache + 24h/1km filter + track event)
  • OFF mode early-returns in initialize(), skipping all background machinery (no restoration, no enrichment, no event subscriptions)
  • Remove stopLocationUpdates() from public API — not needed for one-shot request pattern
  • Use first-wins request deduplication: if a request is in flight, new calls are ignored (matches iOS behavior)
  • Simplify LocationServicesImpl by removing lock and stop logic

Note

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 enableLocationTracking to a 3-state LocationTrackingMode (OFF, MANUAL, ON_APP_START), with OFF now short-circuiting ModuleLocation.initialize() to skip restoration/enrichment/subscriptions.

Location request behavior is updated: LocationServices.stopLocationUpdates() is removed, LocationServicesImpl switches 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 new ProcessLifecycleOwner observer.

Shared main-thread posting utility is moved into core as MainThreadPoster/HandlerMainThreadPoster and reused by in-app messaging; samples/tests are updated accordingly, including removing the sample UI’s “stop updates” button and adding unit tests for OFF mode no-ops.

Written by Cursor Bugbot for commit d21a04a. This will update automatically on new commits. Configure here.

Shahroz16 and others added 5 commits March 2, 2026 11:14
…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.
@Shahroz16 Shahroz16 requested a review from a team as a code owner March 2, 2026 17:47
@Shahroz16 Shahroz16 self-assigned this Mar 2, 2026
@github-actions
Copy link

github-actions bot commented Mar 2, 2026

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.


@Shahroz16 Shahroz16 changed the title chore: update Location tracking module config chore: update Location tracking module config Mar 2, 2026
@codecov
Copy link

codecov bot commented Mar 2, 2026

Codecov Report

❌ Patch coverage is 0% with 3 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (feat/real-time-location@1f518e8). Learn more about missing BASE report.

Files with missing lines Patch % Lines
...tlin/io/customer/sdk/core/util/MainThreadPoster.kt 0.00% 3 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions
Copy link

github-actions bot commented Mar 2, 2026

  • java_layout: feat/location-tracking-mode (1772473691)

@github-actions
Copy link

github-actions bot commented Mar 2, 2026

  • kotlin_compose: feat/location-tracking-mode (1772473690)

@github-actions
Copy link

github-actions bot commented Mar 2, 2026

Build available to test
Version: feat-location-tracking-mode-SNAPSHOT
Repository: https://central.sonatype.com/repository/maven-snapshots/

@github-actions
Copy link

github-actions bot commented Mar 2, 2026

📏 SDK Binary Size Comparison Report

Module Last Recorded Size Current Size Change in Size
core 30.89 KB 31.29 KB ⬆️ +0.40KB
datapipelines 40.56 KB 40.56 KB ✅ No Change
messagingpush 30.25 KB 30.25 KB ✅ No Change
messaginginapp 106.69 KB 106.32 KB ⬇️ -0.37KB
tracking-migration 22.89 KB 22.89 KB ✅ No Change

@github-actions
Copy link

github-actions bot commented Mar 2, 2026

  • java_layout: feat/location-tracking-mode (1772475518)

@github-actions
Copy link

github-actions bot commented Mar 2, 2026

  • kotlin_compose: feat/location-tracking-mode (1772475525)

@github-actions
Copy link

github-actions bot commented Mar 2, 2026

  • java_layout: feat/location-tracking-mode (1772479516)

@github-actions
Copy link

github-actions bot commented Mar 2, 2026

  • kotlin_compose: feat/location-tracking-mode (1772479524)

private val scope: CoroutineScope
) : LocationServices {

private val lock = ReentrantLock()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a specific reason why we removed that lock?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@mahmoud-elmorabea mahmoud-elmorabea requested a review from a team March 3, 2026 20:02
@github-actions
Copy link

github-actions bot commented Mar 3, 2026

  • java_layout: feat/location-tracking-mode (1772575707)

@github-actions
Copy link

github-actions bot commented Mar 3, 2026

  • kotlin_compose: feat/location-tracking-mode (1772575711)

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@github-actions
Copy link

github-actions bot commented Mar 4, 2026

  • java_layout: feat/location-tracking-mode (1772626190)

@github-actions
Copy link

github-actions bot commented Mar 4, 2026

  • kotlin_compose: feat/location-tracking-mode (1772626187)

@github-actions
Copy link

github-actions bot commented Mar 4, 2026

  • java_layout: feat/location-tracking-mode (1772627597)

@github-actions
Copy link

github-actions bot commented Mar 4, 2026

  • kotlin_compose: feat/location-tracking-mode (1772627591)

@github-actions
Copy link

github-actions bot commented Mar 4, 2026

  • kotlin_compose: feat/location-tracking-mode (1772631155)

@github-actions
Copy link

github-actions bot commented Mar 4, 2026

  • java_layout: feat/location-tracking-mode (1772631129)

@Shahroz16 Shahroz16 merged commit 7293a4e into feat/real-time-location Mar 4, 2026
36 checks passed
@Shahroz16 Shahroz16 deleted the feat/location-tracking-mode branch March 4, 2026 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants