Skip to main content

Overview

The Limit Module is the core “enforcement” engine of the application. It allows users to define time boundaries for specific apps or categories (Groups). Unlike standard system limits, this module focuses on mindful friction, providing “Snooze” mechanics with exponential cooldowns and “Coach” suggestions that adapt to the user’s actual behavior. To the user, this manifests as:
  1. Limits Dashboard: A central hub to see time remaining and manage groups.
  2. Smart Suggestions: Automated prompts to limit high-usage apps or categories.
  3. Blocking Overlay: A full-screen intervention (BlockingActivity) that appears when a limit is reached.

Architecture & Data Flow

The module follows a strict pattern, orchestrated by a central ViewModel and supported by background monitoring services.

Key Components

1. ViewModels & Delegates

  • LimitsViewModel: The primary orchestrator. It combines streams from usage data and limit configurations to produce a complex LimitsScreenUiState. It handles the logic for creating, editing, and deleting groups.
  • LimitViewModelDelegateImpl: A specialized delegate used to handle the “Quick Limit” sheet logic, separating the heavy calculation of “Smart Suggestions” from the main ViewModel.
  • BlockingViewModel: Manages the state of the enforcement screen, specifically handling the logic and cooldown timers.

2. Enforcement Services

  • LimitMonitor: A -level component that runs in the background. It calculates “Usage Snapshots” by combining database records with live session data to decide exactly when to trigger a block.
  • BlockingStateManager: A that acts as the “Source of Truth” for which apps are currently restricted. The Accessibility Service listens to this state to perform the actual window intervention.

3. UI Components

  • BlockingActivity: A transparent, full-screen activity designed to interrupt the user. It uses a “Destructive Countdown Button” to ensure the user pauses before snoozing.
  • SelectAppGroupsScreen: A sophisticated selection UI that groups apps by category and usage, allowing for bulk limit creation.

Operational Logic

Real-time Enforcement

The system does not rely solely on periodic database polls. Instead, LimitMonitor uses a Usage Projection Engine:
  1. Baseline: It fetches the total usage for a group from the ScrollDataRepository (DB).
  2. Live Delta: It adds the duration of the current active session (tracked in memory).
  3. Prediction: It calculates the remainingMs and schedules a delay to trigger the block exactly when the limit is hit.

The Snooze Friction Loop

When a user hits a limit, they aren’t just “blocked.” They enter a friction loop managed by the SnoozeManager:
  • Phases: Snoozes move through phases (Compassion -> Reflection -> Deliberate).
  • Cooldowns: As the user snoozes more in a single day, the system enforces a “Cooldown” period where the snooze button is disabled, forcing a break.
  • Usage Allowance: Unlike time-based snoozes, the system grants a specific usage delta (e.g., 5 more minutes of actual app use), which is more accurate than a simple wall-clock timer.

Data Engineering & Transformation

Usage Aggregation

The LimitsViewModel performs heavy data transformation using combinations:
  • Source: It joins LimitsRepository.getAllLimitedApps() with ScrollDataRepository.getUsageRecordsForDateRange().
  • Transformation: It groups usage by groupId, calculates the percentage of the limit used, and determines if the group is “effectively” active (considering manual pauses and snooze states).
  • Category Mapping: Uses CategoryUtil to normalize system category strings (e.g., GAME_ACTION -> Games) for cleaner UI grouping.

Smart Suggestion Logic

The module uses a SmartLimitPolicy to analyze the last 7 days of usage:
  • Filtering: It excludes apps already under a limit.
  • Clustering: It identifies high-usage categories (e.g., “Social”) and suggests creating a group limit if multiple apps in that category are heavily used.
  • Goal Setting: It suggests limits based on the 80th percentile of usage, aiming for “Easy” or “Ambitious” goals.

Dependencies

  • LimitsRepository: Manages the for limit groups and app assignments.
  • ScrollDataRepository: Provides the raw usage metrics (time spent, opens, notifications).
  • NudgeMonitor: Used to show “Approaching Limit” overlays (50%, 70%, 90%) before the hard block occurs.
  • Hilt: Used for across all ViewModels and Services.
Last modified on January 22, 2026