Skip to main content

Overview

The in.util module serves as the intelligence layer and behavioral engine of the Scrollless application. Rather than being a collection of disparate helper functions, it defines the system’s “personality” and its approach to digital wellbeing. This module is responsible for:
  1. Adaptive Coaching: Analyzing usage history to suggest realistic time limits.
  2. Psychological Friction: Implementing an “Exponential Snooze” strategy to discourage compulsive app use.
  3. Physicalization: Converting abstract digital metrics (pixels, sessions) into physical units (meters, kilometers).
  4. System Orchestration: Managing complex Android and system-level interactions.

Architecture & Data Flow

The utility module operates as a set of domain-specific engines that bridge the gap between raw data (from ) and the UI.

Key Components

The Coaching Engine

  • CoachSuggestionService: Orchestrates a tiered coaching logic. It uses “Phases” (1-3) based on how many days of data are available, moving from simple averages to complex trends.
  • SmartAdaptationPolicy: The mathematical core that calculates limit adjustments. It includes “Recovery Mode” to prevent user burnout by suggesting limit increases if a user is failing consistently.
  • CoachWording: A specialized builder that generates human-friendly, semi-randomized subtitles (e.g., “It has been a bit heavy lately…”) to make the AI coach feel more empathetic.

The Friction Engine

  • ExponentialSnoozeStrategy: Implements a three-phase psychological model:
    1. Compassion: Generous snoozes for early attempts.
    2. Reflection: Reduced time and short mandatory pauses.
    3. Deliberate: Minimal time, long cooldowns, and forced reflection prompts.
  • SnoozeManager: Manages the runtime state of these snoozes, persisting them in and scheduling enforcement via WorkManager.

The Physicalization Engine

  • ScrollPhysics & ConversionUtil: Translates screen pixels into physical meters. It accounts for device-specific to ensure that “100 meters of scrolling” is physically accurate regardless of the phone’s screen size.

Operational Logic

Adaptive Limit Lifecycle

The system doesn’t just set a limit; it evolves with the user:
  1. Observation: UsageStatsHelper queries the Android system for foreground time.
  2. Analysis: SmartLimitPolicy computes “Easy,” “Maintain,” and “Ambitious” goals.
  3. Hysteresis: CoachSuggestionManager ensures the user isn’t bombarded with suggestions, enforcing a 7-day “cool down” between limit changes to allow habits to form.

Permission Orchestration

Because Scrollless relies on sensitive Android APIs, PermissionManager provides a reactive of the system’s permission state. It handles the complex intent-routing required to send users to specific system settings pages (Accessibility, Usage Access, Overlay).

Data Engineering & Transformation

The module treats usage data as a stream to be cleaned and interpreted:
  • Outlier Exclusion: In SmartAdaptationPolicy, the system calculates the standard deviation of usage and ignores “outlier days” (e.g., a one-off 6-hour binge) so they don’t skew the long-term coaching logic.
  • Normalization: CategoryUtil maps messy Android package categories (like GAME_ACTION or GAME_RPG) into clean, user-facing groups like “Games.”
  • Rounding Logic: DateUtil implements “Rounded Remaining Duration.” This prevents the “instant penalty” where 1 second of usage might look like a full minute lost, instead rounding usage to the nearest minute for a fairer user experience.

Dependencies

  • WorkManager: Used by SnoozeManager to trigger limit enforcement even if the app is in the background.
  • Hilt: Provides for utility classes like ScrollPhysics and ConversionUtil.
  • UsageStatsManager: The primary source of truth for app foreground time.
  • AccessibilityService: Used to detect scroll events and content changes for physical distance calculation.
Last modified on January 22, 2026