Skip to content

Add allowed-window restriction and harden daily location - #232

Open
patriciojofre wants to merge 3 commits into
masterfrom
feature/daily-location-window
Open

Add allowed-window restriction and harden daily location#232
patriciojofre wants to merge 3 commits into
masterfrom
feature/daily-location-window

Conversation

@patriciojofre

Copy link
Copy Markdown
Member

Summary

Restricts the daily-location report to a server-configured time window and hardens the surrounding flow. The window comes from settings.local.location_schedule in /devices/:key/status.json and is evaluated in UTC. With no config, the location is still sent daily ASAP (unchanged behavior).

Config shape:

{
  "start_at": "10:00", "end_at": "11:00",
  "sunday": false, "monday": true, "tuesday": true, "wednesday": true,
  "thursday": true, "friday": true, "saturday": false
}

Changes

New allowed-window restriction

  • LocationScheduleWindow (new, pure/unit-tested): isWithinAllowedWindow(scheduleJson, now) evaluated in UTC — per-weekday booleans (no flags → any day; otherwise only true days) and inclusive start_at/end_at. Empty/absent/malformed config → send ASAP (fail-open).
  • PreyStatus.initConfig() parses settings.local.location_schedule; PreyConfig gains the LOCATION_SCHEDULE key with get/set.

Hardening / fixes

  • UTC day boundary: DailyLocation uses a dedicated UTC yyyy-MM-dd formatter for the "already sent today" guard and the success write (leaves the shared FORMAT_SDF_AWARE used by the Aware system untouched).
  • Doze resilience: LocationScheduled replaces setInexactRepeating with a self-rescheduling setAndAllowWhileIdle (API 23+) / setExact (21–22) alarm; AlarmLocationReceiver re-arms the next fire before running so a failure can't break the schedule.
  • Acquisition: 6 attempts with longer sleeps, keeps the most-accurate fix, breaks early at ≤50 m, and sends the best fix obtained rather than skipping the day.
  • Cleanup: replaced throw new RuntimeException(e) with logging; removed the duplicate setLastLocation(null).

Guard order in DailyLocation.run: already-sent-today (UTC) → skip · airplane mode OR outside window → skip · else acquire + send · store UTC date only on HTTP 200/201 → one send per allowed UTC day.

Testing

  • New LocationScheduleWindowTest (Robolectric): 12 tests, all passing — no/empty/malformed config, day in/out, time before/in/after, inclusive boundaries, days-only, hours-only.
  • ./gradlew :app:compileDebugJavaWithJavac clean; targeted unit tests green.
  • Not exercised on a device: end-to-end alarm→fix→POST and Doze firing of setAndAllowWhileIdle. Also worth confirming the exact location_schedule key/shape the server emits under settings.local.

patriciojofre and others added 3 commits July 6, 2026 16:19
Restrict daily-location acquisition/send to a server-configured window
(settings.local.location_schedule in status.json), evaluated in UTC. With
no config the location is still sent daily ASAP.

- LocationScheduleWindow: pure, unit-tested UTC window evaluation (per-weekday
  booleans + start_at/end_at, inclusive; fail-open on empty/malformed config).
- PreyStatus: parse settings.local.location_schedule; PreyConfig: LOCATION_SCHEDULE.
- DailyLocation: gate on the window, switch the "already sent today" guard to
  UTC, keep the most-accurate fix over a wider window (send best obtained),
  and replace RuntimeException with logging; drop duplicate setLastLocation.
- LocationScheduled: replace setInexactRepeating with a self-rescheduling
  setAndAllowWhileIdle/setExact alarm so it survives Doze; AlarmLocationReceiver
  re-arms the next fire before running.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant