Conversation
WebWatcher hard-coded audible=false on every aw-watcher-android-web event. aw-webui uses audible browser events as not-AFK evidence, so the field was worthless on Android. BrowserAudibleDetector reports whether the browser package owns a media session in STATE_PLAYING via MediaSessionManager, which is the precise per-app signal but needs the MediaWatcher notification-listener access. Without that access it falls back to AudioManager.isMusicActive(), which is global and can't tell browser audio from a background music app. The result is cached for one second because accessibility events arrive many times a second while scrolling. BrowserSessionTracker now carries audible per session and splits the session when it flips, so each logged event has the right value for its stretch of time (the desktop web watcher likewise starts a new event when data changes). Url, browser and title carry over across the split. incognito is still hard-coded to false; detecting it needs per-browser accessibility-tree heuristics and is left for a follow-up.
|
… fallback handleUrl returned early when the url and browser were unchanged, so an audible transition sampled on a same-page event was discarded and the session logged with a stale value. Same-page calls now route through handleAudible. The AudioManager.isMusicActive() fallback is removed: it is device-wide, so a background music app would have marked silent browser sessions audible, which aw-webui counts as not-AFK evidence. Without notification access audible is now always false, as before this change.
|
@greptile review |
|
@0xbrayo I'm wondering if we should just keep a separate "audible" bucket and not make it browser-only. There is no "AFK" bucket/state on Android anyway to filter by, so it doesn't affect filtering. |
|
Agree — this does not change Android filtering. The non-browser-only source already exists: URL-level "this page was playing" is a join (web URL ∩ browser-package media session), not a reason to duplicate the flag. Filling the field is schema-complete for #106, but it is not the Android audible design. |
WebWatcherhard-codesaudible=falseon everyaw-watcher-android-webevent (// TODO). aw-webui uses audible browser events as not-AFK evidence (include_audibleinqueries.ts), so the field was worthless on Android.Changes
BrowserAudibleDetector— reports whether the browser package owns a media session inSTATE_PLAYINGviaMediaSessionManager.getActiveSessions(). This is the precise per-app signal (Chrome/Firefox publish a media session for page audio/video) but needs the existing MediaWatcher notification-listener access. Without that access it falls back toAudioManager.isMusicActive(), which is global and can't tell browser audio from a background music app. Result is cached for 1s since accessibility events arrive many times a second while scrolling.BrowserSessionTracker— carriesaudibleper session and splits the session when it flips, so each logged event has the right value for its stretch of time (desktop aw-watcher-web likewise starts a new event when data changes). Url, browser and title carry over across the split.WebWatcher— samples audible on every browser accessibility event and feeds it to the tracker.Known limitations
incognitois still hard-coded tofalse; detecting it needs per-browser accessibility-tree heuristics and is out of scope here.Addresses the
audiblehalf of #106.Validation
:mobile:testStandardDebugUnitTest --tests 'net.activitywatch.android.watcher.*': 39 tests pass (4 new tracker tests, 2 new detector tests). Not yet exercised on a device — draft until I've checked Chrome + Firefox with and without notification access.