Skip to main content

Summary

The Limit Enforcement Engine is the core system responsible for tracking app usage and enforcing blocks when limits are reached. It combines real-time monitoring (active when you use an app) with background workers (safety checks) to ensure limits are respected even if the app is killed or restarted. It also manages “snooze” and “pause” timers to temporarily lift restrictions.

Overview Diagram

Workers

The app uses to handle tasks that must run even if the app is closed.

LimitEnforcementWorker

What it does: Acts as a safety net by periodically verifying usage against limits for all app groups to ensure no blocks were missed.
PropertyValue
TypePeriodic
IntervalRegular intervals (approx. 15 min)
ConstraintsNone specified
1

Fetch Data

Retrieves all limit groups and the current day’s usage statistics from the repository.
2

Verify Limits

Compares total usage against the allowed time limit for each group.
3

Enforce

If usage exceeds the limit (minus a small buffer), it commands the BlockingStateManager to block the apps. If usage is under the limit, it ensures they are unblocked.
Triggered by: Periodic scheduler to ensure consistency between the database and the blocking state.

PauseExpiryWorker

What it does: Runs when a user-initiated “Pause” (e.g., “Unblock for 30 mins”) expires to re-enable limits.
PropertyValue
TypeOneTime
IntervalScheduled for specific duration (30m, 2h, etc.)
ConstraintsNone
1

Wake Up

Wakes up exactly when the pause duration ends.
2

Resume Group

Updates the database to remove the “Paused” state for the specific limit group.
3

Notify & Re-evaluate

Sends a notification that the limit is active again and triggers the LimitMonitor to immediately re-check if the apps should be blocked.
Triggered by: The PauseManager when a user selects a pause duration in the UI.

Core Services & Managers

While not all are standard Android “Services,” these singletons run continuously or persist state across the app lifecycle.

LimitMonitor

What it does: The “Brain” of the operation. It tracks the currently open app, calculates real-time usage, and schedules the exact moment an app should be blocked.
FeatureDescription
Live TrackingDetects when you open/close an app and starts a session timer.
Predictive BlockingCalculates exactly how many milliseconds remain and schedules a timer to block the app the moment time runs out.
Midnight ResetSchedules a task to run at 12:00 AM to reset usage counters and unblock apps for the new day.
DebouncingIgnores rapid screen toggles (e.g., turning screen off/on quickly) to prevent calculation errors.

BlockingStateManager

What it does: The central source of truth for which apps are currently blocked.
  • State Holder: Maintains a list of blocked package names.
  • Thread Safe: Uses thread-safe flows so UI and Services can observe changes instantly.
  • Atomic Operations: Can block/unblock entire groups of apps simultaneously to prevent race conditions.

OverlayEnforcer

What it does: Manages the physical drawing of the “Stop” screen over other apps.
  • System Overlay: Uses Android’s “Draw over other apps” permission for newer Android versions.
  • Accessibility Overlay: Falls back to Accessibility Window layers if necessary.
  • Visibility Check: Ensures the overlay isn’t added twice.

FocusModeService

What it does: A ConditionProviderService intended to integrate with Android’s Digital Wellbeing or Do Not Disturb features. Currently acts as a placeholder for future system-level integrations.

Scheduling Flow

This diagram shows how the system decides when to block an app after you open it.

Pause & Snooze Logic

The system handles temporary exceptions to the rules via the PauseManager.
TypeDurationMechanism
SnoozeShort (e.g., 1 min)Handled in-memory by LimitMonitor. Delays the blocking timer.
PauseLong (e.g., 30 min)Persisted to Database. Uses WorkManager to schedule a PauseExpiryWorker to resume limits later.
IndefiniteUntil turned offPersisted to Database. No worker scheduled; requires manual resumption.

Receivers & Triggers

ComponentListens ForAction
LimitMonitorApp LaunchStarts timing session; checks limits.
LimitMonitorApp CloseStops timing session; saves data.
LimitMonitorMidnightResets daily usage counters; unblocks all apps.
LimitMonitorLimit UpdateClears cached thresholds; re-evaluates current app.
Last modified on January 25, 2026