-
Notifications
You must be signed in to change notification settings - Fork 79
Description
1) backgroundInactivityTimeout miscounts on Android due to a clock that pauses in deep sleep
Component(s): android-agent, android, SessionManager, SessionConfig
Environment: Android (device enters Doze / deep sleep)
Summary
backgroundInactivityTimeout in SessionConfig behaves incorrectly on Android when devices enter deep sleep. The default Clock uses System.nanoTime() which maps to a monotonic source that does not advance during deep sleep. Background duration is undercounted, so sessions may not rotate when they should.
Expected behavior
Background inactivity should be measured against a time base that continues through device sleep so a configured timeout triggers after the intended real elapsed duration.
Actual behavior
When the app is backgrounded and the device sleeps, System.nanoTime() stops. On resume, SessionIdTimeoutHandler/SessionManager see a shorter elapsed interval than real time, preventing or delaying session rotation.
Why this happens (Android specifics)
System.nanoTime()≈CLOCK_MONOTONIC→ pauses during deep sleep.SystemClock.elapsedRealtime()/elapsedRealtimeNanos()→ includes deep sleep; correct for elapsed-wall semantics.
Minimal reproduction
- Set
backgroundInactivityTimeoutto a small value (e.g., 5 min). - Background the app; allow the device to enter deep sleep > timeout.
- Resume the app.
- Observe that the session did not rotate as expected.
Proposed change
- Provide an Android-aware
Clockthat usesSystemClock.elapsedRealtimeNanos()for elapsed measurements. - Pass this
ClocktoSessionManagerandSessionIdTimeoutHandlerduring init. - Remove the secondary
SessionManagerconstructor (marked “for tests”) and add a factory method to ensure consistent wiring in prod/tests.