Skip to content

Commit bdc5ae0

Browse files
committed
feat: unlock watcher
1 parent d1ed166 commit bdc5ae0

2 files changed

Lines changed: 68 additions & 5 deletions

File tree

mobile/src/main/java/net/activitywatch/android/parser/SessionParser.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,40 @@ class SessionParser(private val context: Context) {
9595
return parseUsageEventsForPeriod(lastUpdateTimestamp, currentTime)
9696
}
9797

98+
/**
99+
* Parse unlock (KEYGUARD_HIDDEN) events for a period starting from a timestamp
100+
*/
101+
fun parseUnlockEventsForPeriod(startTimestamp: Long, endTimestamp: Long): List<Long> {
102+
val usageEvents = usageStatsManager.queryEvents(startTimestamp, endTimestamp)
103+
val unlockTimestamps = mutableListOf<Long>()
104+
105+
while (usageEvents.hasNextEvent()) {
106+
val event = UsageEvents.Event()
107+
usageEvents.getNextEvent(event)
108+
if (event.eventType == UsageEvents.Event.KEYGUARD_HIDDEN) {
109+
unlockTimestamps.add(event.timeStamp)
110+
}
111+
}
112+
113+
return unlockTimestamps.sorted()
114+
}
115+
116+
/**
117+
* Parse unlock events since a specific timestamp
118+
*/
119+
fun parseUnlockEventsSince(lastUpdateTimestamp: Long): List<Long> {
120+
val currentTime = System.currentTimeMillis()
121+
return parseUnlockEventsForPeriod(lastUpdateTimestamp, currentTime)
122+
}
123+
124+
/**
125+
* Parse unlock events for a given day
126+
*/
127+
fun parseUnlockEventsForDay(dayStartMs: Long): List<Long> {
128+
val dayEndMs = dayStartMs + 24 * 60 * 60 * 1000 // 24 hours later
129+
return parseUnlockEventsForPeriod(dayStartMs, dayEndMs)
130+
}
131+
98132
/**
99133
* Extract raw events from UsageEvents iterator
100134
*/

mobile/src/main/java/net/activitywatch/android/watcher/SessionEventWatcher.kt

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class SessionEventWatcher(val context: Context) {
7373

7474
val startTimestamp = lastUpdated?.toEpochMilli() ?: 0L
7575
val sessions = sessionParser.parseUsageEventsSince(startTimestamp)
76+
val unlockTimestamps = sessionParser.parseUnlockEventsSince(startTimestamp)
7677

7778
var eventsSent = 0
7879

@@ -82,7 +83,12 @@ class SessionEventWatcher(val context: Context) {
8283
eventsSent++
8384
}
8485

85-
Log.i(TAG, "Finished processing events, sent $eventsSent session events")
86+
for (timestamp in unlockTimestamps) {
87+
val instant = DateTimeUtils.toInstant(java.util.Date(timestamp))
88+
ri.heartbeatHelper(UNLOCK_BUCKET_ID, instant, 0.0, JSONObject(), 0.0)
89+
}
90+
91+
Log.i(TAG, "Finished processing events, sent $eventsSent session events and ${unlockTimestamps.size} unlock events")
8692
return eventsSent
8793
}
8894

@@ -110,16 +116,23 @@ class SessionEventWatcher(val context: Context) {
110116
Log.i(TAG, "Sending session events for specific day: ${SessionUtils.formatDate(dayStartMs)}")
111117

112118
val timeline = sessionParser.parseUsageEventsForDay(dayStartMs)
119+
val unlockTimestamps = sessionParser.parseUnlockEventsForDay(dayStartMs)
113120

114121
ri.createBucketHelper(SESSION_BUCKET_ID, "currentwindow")
122+
ri.createBucketHelper(UNLOCK_BUCKET_ID, "os.lockscreen.unlocks")
115123

116124
var eventsSent = 0
117125
for (session in timeline.sessions) {
118126
insertSessionAsEvent(session)
119127
eventsSent++
120128
}
121129

122-
Log.i(TAG, "Sent $eventsSent session events for day")
130+
for (timestamp in unlockTimestamps) {
131+
val instant = DateTimeUtils.toInstant(java.util.Date(timestamp))
132+
ri.heartbeatHelper(UNLOCK_BUCKET_ID, instant, 0.0, JSONObject(), 0.0)
133+
}
134+
135+
Log.i(TAG, "Sent $eventsSent session events and ${unlockTimestamps.size} unlock events for day")
123136
}
124137

125138
/**
@@ -129,16 +142,23 @@ class SessionEventWatcher(val context: Context) {
129142
Log.i(TAG, "Sending session events for period: ${SessionUtils.formatDateTime(startTimestamp)} to ${SessionUtils.formatDateTime(endTimestamp)}")
130143

131144
val sessions = sessionParser.parseUsageEventsForPeriod(startTimestamp, endTimestamp)
145+
val unlockTimestamps = sessionParser.parseUnlockEventsForPeriod(startTimestamp, endTimestamp)
132146

133147
ri.createBucketHelper(SESSION_BUCKET_ID, "currentwindow")
148+
ri.createBucketHelper(UNLOCK_BUCKET_ID, "os.lockscreen.unlocks")
134149

135150
var eventsSent = 0
136151
for (session in sessions) {
137152
insertSessionAsEvent(session)
138153
eventsSent++
139154
}
140155

141-
Log.i(TAG, "Sent $eventsSent session events for period")
156+
for (timestamp in unlockTimestamps) {
157+
val instant = DateTimeUtils.toInstant(java.util.Date(timestamp))
158+
ri.heartbeatHelper(UNLOCK_BUCKET_ID, instant, 0.0, JSONObject(), 0.0)
159+
}
160+
161+
Log.i(TAG, "Sent $eventsSent session events and ${unlockTimestamps.size} unlock events for period")
142162
}
143163

144164
/**
@@ -186,22 +206,31 @@ class SessionEventWatcher(val context: Context) {
186206
Log.i(TAG, "Sending session events for last $numberOfDays days")
187207

188208
ri.createBucketHelper(SESSION_BUCKET_ID, "currentwindow")
209+
ri.createBucketHelper(UNLOCK_BUCKET_ID, "os.lockscreen.unlocks")
189210

190211
var totalEventsSent = 0
212+
var totalUnlocksSent = 0
191213

192214
for (i in 0 until numberOfDays) {
193215
val dayStart = SessionUtils.getStartOfDayDaysAgo(i)
194216
val timeline = sessionParser.parseUsageEventsForDay(dayStart)
217+
val unlockTimestamps = sessionParser.parseUnlockEventsForDay(dayStart)
195218

196219
for (session in timeline.sessions) {
197220
insertSessionAsEvent(session)
198221
totalEventsSent++
199222
}
200223

201-
Log.d(TAG, "Sent ${timeline.sessions.size} session events for day ${SessionUtils.formatDate(dayStart)}")
224+
for (timestamp in unlockTimestamps) {
225+
val instant = DateTimeUtils.toInstant(java.util.Date(timestamp))
226+
ri.heartbeatHelper(UNLOCK_BUCKET_ID, instant, 0.0, JSONObject(), 0.0)
227+
totalUnlocksSent++
228+
}
229+
230+
Log.d(TAG, "Sent ${timeline.sessions.size} session events and ${unlockTimestamps.size} unlock events for day ${SessionUtils.formatDate(dayStart)}")
202231
}
203232

204-
Log.i(TAG, "Sent total of $totalEventsSent session events for last $numberOfDays days")
233+
Log.i(TAG, "Sent total of $totalEventsSent session events and $totalUnlocksSent unlock events for last $numberOfDays days")
205234
}
206235

207236
/**

0 commit comments

Comments
 (0)