|
| 1 | +package net.activitywatch.android.data |
| 2 | + |
| 3 | +import org.json.JSONObject |
| 4 | + |
| 5 | +/** |
| 6 | + * Represents a single app usage session |
| 7 | + */ |
| 8 | +data class AppSession( |
| 9 | + val packageName: String, |
| 10 | + val appName: String, |
| 11 | + val className: String = "", |
| 12 | + val startTime: Long, |
| 13 | + val endTime: Long, |
| 14 | + val durationMs: Long = endTime - startTime |
| 15 | +) { |
| 16 | + val durationMinutes: Double get() = durationMs / 60000.0 |
| 17 | + val durationHours: Double get() = durationMs / 3600000.0 |
| 18 | + val durationSeconds: Double get() = durationMs / 1000.0 |
| 19 | + |
| 20 | + /** |
| 21 | + * Convert session to ActivityWatch Event JSON format for heartbeats |
| 22 | + */ |
| 23 | + fun toEventData(): JSONObject { |
| 24 | + val data = JSONObject() |
| 25 | + data.put("app", appName) |
| 26 | + data.put("package", packageName) |
| 27 | + if (className.isNotEmpty()) { |
| 28 | + data.put("classname", className) |
| 29 | + } |
| 30 | + return data |
| 31 | + } |
| 32 | +} |
| 33 | + |
| 34 | +/** |
| 35 | + * Represents aggregated usage data for a single app |
| 36 | + */ |
| 37 | +data class AppUsageSummary( |
| 38 | + val packageName: String, |
| 39 | + val appName: String, |
| 40 | + val totalTimeMs: Long, |
| 41 | + val sessionCount: Int, |
| 42 | + val sessions: List<AppSession> |
| 43 | +) { |
| 44 | + val totalMinutes: Double get() = totalTimeMs / 60000.0 |
| 45 | + val totalHours: Double get() = totalTimeMs / 3600000.0 |
| 46 | + val averageSessionMs: Long get() = if (sessionCount > 0) totalTimeMs / sessionCount else 0 |
| 47 | + val averageSessionMinutes: Double get() = averageSessionMs / 60000.0 |
| 48 | +} |
| 49 | + |
| 50 | +/** |
| 51 | + * Represents a complete timeline for a single day |
| 52 | + */ |
| 53 | +data class DayTimeline( |
| 54 | + val date: Long, // timestamp of the day start |
| 55 | + val sessions: List<AppSession>, |
| 56 | + val appSummaries: List<AppUsageSummary>, |
| 57 | + val totalScreenTimeMs: Long |
| 58 | +) { |
| 59 | + val totalScreenTimeHours: Double get() = totalScreenTimeMs / 3600000.0 |
| 60 | + val totalScreenTimeMinutes: Double get() = totalScreenTimeMs / 60000.0 |
| 61 | + val uniqueAppsCount: Int get() = appSummaries.size |
| 62 | +} |
| 63 | + |
| 64 | +/** |
| 65 | + * Internal model for tracking active activities during parsing |
| 66 | + */ |
| 67 | +internal data class ActivityState( |
| 68 | + val packageName: String, |
| 69 | + val className: String, |
| 70 | + val appName: String, |
| 71 | + val startTime: Long |
| 72 | +) |
| 73 | + |
| 74 | +/** |
| 75 | + * Internal model for raw usage events during parsing |
| 76 | + */ |
| 77 | +internal data class UsageEvent( |
| 78 | + val eventType: Int, |
| 79 | + val timeStamp: Long, |
| 80 | + val packageName: String, |
| 81 | + val className: String |
| 82 | +) |
| 83 | + |
| 84 | +/** |
| 85 | + * Represents session statistics for analysis |
| 86 | + */ |
| 87 | +data class SessionStats( |
| 88 | + val totalSessions: Int, |
| 89 | + val averageSessionDuration: Long, |
| 90 | + val longestSession: AppSession?, |
| 91 | + val shortestSession: AppSession?, |
| 92 | + val mostUsedApp: AppUsageSummary? |
| 93 | +) |
0 commit comments