The processors module acts as the Transformation Layer of the application. It follows a Batch-Processing strategy where raw, low-level system events (like screen locks, app resumes, and accessibility events) are aggregated into high-level and domain models.This module does not own the data; instead, it implements the business logic to define the “Truth” of a user’s digital habits. It uses a Heuristic-Based Analysis to distinguish between passive usage (watching a video) and active engagement (typing or scrolling).
The logic is divided into specialized calculators coordinated by the DailyDataProcessor:
DailyDataProcessor: The orchestrator that takes a list of RawAppEvent and NotificationRecord objects and produces a DailyProcessingResult.
UnlockSessionCalculator: Determines the duration and intent of device usage. It classifies sessions as “Glance” (short) or “Intentional” (long) and identifies “Compulsive” checks.
ScrollSessionCalculator: Aggregates pixel-level or micrometer-level movement into ScrollSessionRecord objects, prioritizing high-accuracy measured data over inferred estimates.
AppUsageCalculator: The core engine for calculating “Active Time” vs. “Total Usage.” It uses app categories (e.g., Social vs. Productivity) to apply different time-decay windows to interactions.
InsightGenerator: A post-processor that extracts narrative trends, such as “Busiest Hour,” “Night Owl” behavior, and “Notification Response Time.”
The processors generate several key entities that are eventually persisted via a :
DailyAppUsageRecord: Aggregates usage per package. Key columns include usageTimeMillis, activeTimeMillis, and appOpenCount.
DailyDeviceSummary: A high-level snapshot of the day, including total unlocks and total notification counts.
UnlockSessionRecord: Tracks every time the device was used, including the triggeringNotificationPackageName to identify what pulled the user into their phone.
Unlike standard Android “Usage Stats” which only track if an app is in the foreground, this module calculates Active Time based on interaction windows:
Category
Window (TTL)
Logic
Passive (Video/Books)
30s
Long window; assumes engagement continues while watching/reading.
Social/Games
5s
Medium window; requires frequent interaction to stay “active.”
Data processing is computationally expensive and is never performed on the Main Thread.
Coroutines: All entry points are .
Safety: The DailyDataProcessor is designed to be called from a background (typically Dispatchers.IO or a custom background pool).
Race Conditions: Since processing is usually triggered by a foreground service or a periodic worker, the logic assumes a single-writer model for a specific dateString to avoid .