-
@Serializable() public final class MiscConfiguration
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description public classMiscConfiguration.Companion
-
Field Summary
-
Constructor Summary
Constructors Constructor Description MiscConfiguration(MetadataCollectionConfiguration collectMetadata, Boolean sdkEnabled, Boolean holdWakeLock, Long uploadWakeLockTimeoutMs, Boolean sessionWatchdogEnabled, Double defaultSessionTimeoutSeconds, Double autoStopAfterDropoffSeconds, Long dataPushDelayIntervalSeconds, Long drainIntervalSeconds, Integer maxBatchesDrainedPerTick, Integer maxBatchRetries, Long retryBaseDelayMs, Long retryMaxDelayMs, Integer maxCacheSizePerStream, Long flushIntervalSeconds, Integer flushBatchSize, Boolean binaryEncoding, String payloadFormat, Boolean dualTimestamp, Long pendingBatchesMaxBytes, Long pendingBatchesMaxAgeMs, Integer pendingBatchesMaxCount, GeofenceConfiguration geofence)
-
Method Summary
Modifier and Type Method Description final MetadataCollectionConfigurationgetCollectMetadata()final BooleangetSdkEnabled()Server-driven master switch. final BooleangetHoldWakeLock()Hold a continuous PARTIAL_WAKE_LOCK for the whole tracking lifetime. final LonggetUploadWakeLockTimeoutMs()Timeout (ms) for the short-duration wake lock wrapped around each upload tick when holdWakeLock is false, so an upload that started inside a location-callback wake window isn't truncated by re-suspend.final BooleangetSessionWatchdogEnabled()Periodic (~15 min) WorkManager watchdog that re-asserts TrackingService when the durable session registry says deliveries are in flight but the service is dead (OEM task killers, FGS start denials). final DoublegetDefaultSessionTimeoutSeconds()final DoublegetAutoStopAfterDropoffSeconds()Server-side default for the post-dropoff auto-stop wind-down timer, in seconds. final LonggetDataPushDelayIntervalSeconds()Sensor batch upload timer delay between upload loops, in seconds. final LonggetDrainIntervalSeconds()Minimum seconds between FIFO drains (radio bursts), DECOUPLED from the snapshot tick. final IntegergetMaxBatchesDrainedPerTick()Maximum number of persisted batches the FIFO drain ships per upload tick. final IntegergetMaxBatchRetries()Max retryable send failures for a single persisted batch before it is dead-lettered (dropped) instead of retried forever — prevents a poison batch from blocking the FIFO head indefinitely. final LonggetRetryBaseDelayMs()Base delay (ms) for the drain's full-jitter exponential backoff: the Nth retry of a row waits a random duration in 0, min(retryMaxDelayMs, base·2^N). final LonggetRetryMaxDelayMs()Ceiling (ms) for the drain retry backoff. final IntegergetMaxCacheSizePerStream()HARD per-stream cap (samples) on the in-memory capture buffers — drop-oldest ring semantics enforced in DataManager.appendBounded.final LonggetFlushIntervalSeconds()final IntegergetFlushBatchSize()final BooleangetBinaryEncoding()When true, the SDK sends DSDP v2 binary payloads (S-011) instead of JSON. final StringgetPayloadFormat()Selects the dataPush wire format: "json"(verbose JSON+deflate, the safe default),"dsdpv2"(the columnar float32 binary, S-011), or"v3"(the compact columnar quantize+delta+varint protobuf format —telemetry.proto).final BooleangetDualTimestamp()When true, every sample emits both wallClockTimestamp (capture-time unix epoch seconds) and sensorTimestamp (native sensor / boot-relative clock) (S-001). final LonggetPendingBatchesMaxBytes()Total byte ceiling for the on-disk pending-batches store. final LonggetPendingBatchesMaxAgeMs()Maximum age of a persisted batch before it's pruned. final IntegergetPendingBatchesMaxCount()Hard cap on the number of persisted batches. final GeofenceConfigurationgetGeofence()In-SDK route-geofencing tuning (see GeofenceConfiguration). final PayloadFormatresolvedPayloadFormat()Resolve the effective wire format from payloadFormat, falling back to the legacy binaryEncoding flag and finally to JSON. -
-
Constructor Detail
-
MiscConfiguration
MiscConfiguration(MetadataCollectionConfiguration collectMetadata, Boolean sdkEnabled, Boolean holdWakeLock, Long uploadWakeLockTimeoutMs, Boolean sessionWatchdogEnabled, Double defaultSessionTimeoutSeconds, Double autoStopAfterDropoffSeconds, Long dataPushDelayIntervalSeconds, Long drainIntervalSeconds, Integer maxBatchesDrainedPerTick, Integer maxBatchRetries, Long retryBaseDelayMs, Long retryMaxDelayMs, Integer maxCacheSizePerStream, Long flushIntervalSeconds, Integer flushBatchSize, Boolean binaryEncoding, String payloadFormat, Boolean dualTimestamp, Long pendingBatchesMaxBytes, Long pendingBatchesMaxAgeMs, Integer pendingBatchesMaxCount, GeofenceConfiguration geofence)
-
-
Method Detail
-
getCollectMetadata
final MetadataCollectionConfiguration getCollectMetadata()
-
getSdkEnabled
final Boolean getSdkEnabled()
Server-driven master switch. When
false, the SDK refuses to start a new session —startDeliveryByX(...)callbacks fire with com.doorstepai.sdks.tracking.internal.SdkError.SdkDisabled and nonewSessionrequest is made. Defaults totrueso older config responses (without the field) keep working unchanged. Honored immediately on the nextensureLoaded().
-
getHoldWakeLock
final Boolean getHoldWakeLock()
Hold a continuous PARTIAL_WAKE_LOCK for the whole tracking lifetime.
true(default) = legacy behavior.false= the Play-compliant mode: wake-up batched IMU sensors carry continuity through AP suspend, location callbacks arrive under the platform's brief exempt wake lock, and uploads use the short-duration uploadWakeLockTimeoutMs lock instead. Since March 1, 2026 Google Play enforces against non-exempt partial wake locks held >=2h average screen-off in >5% of sessions (wake locks under a foreground service COUNT), so fleets should be migrated tofalseonce the device class passes the untethered screen-off yield gate (devices with no wake-up IMU variants — see the "CAP" capability log — should staytrue).
-
getUploadWakeLockTimeoutMs
final Long getUploadWakeLockTimeoutMs()
Timeout (ms) for the short-duration wake lock wrapped around each upload tick when holdWakeLock is
false, so an upload that started inside a location-callback wake window isn't truncated by re-suspend. Short bounded locks don't approach the Play enforcement metric. 0 disables the upload lock entirely.
-
getSessionWatchdogEnabled
final Boolean getSessionWatchdogEnabled()
Periodic (~15 min) WorkManager watchdog that re-asserts TrackingService when the durable session registry says deliveries are in flight but the service is dead (OEM task killers, FGS start denials). Checked at fire time, so a server flip takes effect without reschedule.
-
getDefaultSessionTimeoutSeconds
final Double getDefaultSessionTimeoutSeconds()
-
getAutoStopAfterDropoffSeconds
final Double getAutoStopAfterDropoffSeconds()
Server-side default for the post-dropoff auto-stop wind-down timer, in seconds. When non-null (and 0), an explicit com.doorstepai.sdks.tracking.DoorstepAI.stopDelivery call is DEFERRED by this many seconds — collection keeps running, then the session tears down. A per-call
autoStopAfterDropoffSecondsargument tostartDelivery*always wins; this server value applies only when the caller omits it. com.doorstepai.sdks.tracking.DoorstepAI.markDropoff does NOT arm it, and internal stops (session-timeout, geofence EXIT, route-clear) tear down immediately.The timer is backed by android.app.AlarmManager with
setAndAllowWhileIdle, so it is Doze-safe and reliable for long values (tens of minutes to hours).
-
getDataPushDelayIntervalSeconds
final Long getDataPushDelayIntervalSeconds()
Sensor batch upload timer delay between upload loops, in seconds. Drives the period of
DataManager.startUploadTimer— every N seconds the SDK snapshots all in-memory capture buffers into aBatchData, persists it to the pending-batches store, and (when online) drains the store FIFO to the server.
-
getDrainIntervalSeconds
final Long getDrainIntervalSeconds()
Minimum seconds between FIFO drains (radio bursts), DECOUPLED from the snapshot tick. Snapshot+persist keeps running every dataPushDelayIntervalSeconds (durability is unchanged — batches hit disk before any send), but the radio only wakes every
drainIntervalSeconds(±20% jitter, so a fleet doesn't synchronize) and ships the accumulated batches in one burst. With one HTTPS request per 10 s and an RRC tail of ~10 s, the cellular radio never left the high-power state; batching sends 3-6 windows per burst and lets it idle between. <= dataPushDelayIntervalSeconds disables the decoupling (drain every tick, the old behavior). Byte-pressure and session-stop both force an immediate drain regardless of the interval.
-
getMaxBatchesDrainedPerTick
final Integer getMaxBatchesDrainedPerTick()
Maximum number of persisted batches the FIFO drain ships per upload tick. Caps radio time after a long offline window so one tick can't monopolise the network; the rest are picked up on subsequent ticks.
-
getMaxBatchRetries
final Integer getMaxBatchRetries()
Max retryable send failures for a single persisted batch before it is dead-lettered (dropped) instead of retried forever — prevents a poison batch from blocking the FIFO head indefinitely.
-
getRetryBaseDelayMs
final Long getRetryBaseDelayMs()
Base delay (ms) for the drain's full-jitter exponential backoff: the Nth retry of a row waits a random duration in 0, min(retryMaxDelayMs, base·2^N). A server
Retry-Afterheader overrides this when present.
-
getRetryMaxDelayMs
final Long getRetryMaxDelayMs()
Ceiling (ms) for the drain retry backoff.
-
getMaxCacheSizePerStream
final Integer getMaxCacheSizePerStream()
HARD per-stream cap (samples) on the in-memory capture buffers — drop-oldest ring semantics enforced in
DataManager.appendBounded. Server-defined and read live on every append. It MUST cover one drain interval's worth of samples at the maximum expected rate (fastestHz × dataPushDelayIntervalSeconds); the buffer is drained once per push interval, so a value that only covers a shorter interval silently drops data on the fastest streams. At 130 Hz × 30 s ≈ 3900, hence the 4096 default (the old 1024 was sized for a 10 s interval and dropped ~59% of accel once the server moved to 30 s). CAUTION: raise this wheneverdataPushDelayIntervalSecondsgrows or a high-rate stream (accel/mag/ble) overflows —DataManager.applyConfiglogs a "TOO SMALL" warning when this is under-provisioned. Under normal operation buffers never reach the cap; when upload ticks stall (CPU starvation, long suspend) it bounds memory so the SDK can't amplify the host's memory pressure into an OS process kill. Overflow drops are counted in the pipeline heartbeat (droppedOverflow). Also used as theArrayList.ensureCapacitypre-size on everyapplyConfig. Floor 64.
-
getFlushIntervalSeconds
final Long getFlushIntervalSeconds()
-
getFlushBatchSize
final Integer getFlushBatchSize()
-
getBinaryEncoding
final Boolean getBinaryEncoding()
When true, the SDK sends DSDP v2 binary payloads (S-011) instead of JSON. Default
falseso older server builds receive JSON unchanged.Legacy flag: prefer payloadFormat which supersedes it. Kept for backward compatibility — if payloadFormat is unset/
"json"butbinaryEncodingistrue, the SDK treats it as PayloadFormat.DSDPV2.
-
getPayloadFormat
final String getPayloadFormat()
Selects the dataPush wire format:
"json"(verbose JSON+deflate, the safe default),"dsdpv2"(the columnar float32 binary, S-011), or"v3"(the compact columnar quantize+delta+varint protobuf format —telemetry.proto). Unknown values fall back to"json". Roll out per fleet viagroup; the format is persisted per queued row so a mid-rollout app upgrade drains old JSON rows and new v3 rows correctly.A String (not an enum) so an unrecognized server value can't throw during config decode; parse via MiscConfiguration.resolvedPayloadFormat.
-
getDualTimestamp
final Boolean getDualTimestamp()
When true, every sample emits both wallClockTimestamp (capture-time unix epoch seconds) and sensorTimestamp (native sensor / boot-relative clock) (S-001). Default
falseso older server builds receive only the legacytimestampfield.
-
getPendingBatchesMaxBytes
final Long getPendingBatchesMaxBytes()
Total byte ceiling for the on-disk pending-batches store. Once exceeded, the pruner drops oldest batches first. Mirrors iOS's
maxPendingBatchesTotalBytes = 16 MBbut defaults higher on Android because we have private app storage rather than a sandbox file. Set to 0 to disable the byte budget.
-
getPendingBatchesMaxAgeMs
final Long getPendingBatchesMaxAgeMs()
Maximum age of a persisted batch before it's pruned. Sensor data older than the default (24 h) is rarely useful for delivery analysis. 0 disables the age budget.
-
getPendingBatchesMaxCount
final Integer getPendingBatchesMaxCount()
Hard cap on the number of persisted batches. Mirrors iOS's
maxPendingBatchesCount = 240. 0 disables the count budget.
-
getGeofence
final GeofenceConfiguration getGeofence()
In-SDK route-geofencing tuning (see GeofenceConfiguration). Defaults to the proven field values; the host opts in by calling com.doorstepai.sdks.tracking.DoorstepAI.startRouteGeofencing.
-
resolvedPayloadFormat
final PayloadFormat resolvedPayloadFormat()
Resolve the effective wire format from payloadFormat, falling back to the legacy binaryEncoding flag and finally to JSON. Never throws on an unrecognized server value.
-
-
-
-