Deep Focus
Deep Focus is implemented as a per-goal blocking flow that is activated when tracking starts and deactivated when tracking stops.
Main files
HomeScreen.kt/AddGoalScreen.kt/EditGoalScreen.kt: expose thedeepFocusflag on goals and guard start-up with the accessibility setup dialog.TrackingViewModel.kt: starts/stops tracking and toggles blocking state through the repository/service layer.DeepFocusAccessibilityService.kt: observes foreground window changes, filters launcher/system surfaces, and decides when to show or remove the overlay.DeepFocusOverlayController.kt: builds and removes the accessibility overlay UI.DeepFocusConfig.kt: stores the shared preference key that enables/disables blocking.
Runtime flow
- A goal is saved with
deepFocus = true. - Starting tracking enables the blocking flag.
- The accessibility service reacts to
TYPE_WINDOW_STATE_CHANGEDevents and shows the overlay for non-allowed apps. - The overlay’s return action launches
Purrsistenceagain and uses a short grace window to avoid immediate re-attach. stopTracking()clears blocking and removes any active overlay.
Notes
- Android does not provide a built-in API for fully disabling an app; Deep Focus uses accessibility services to display an overlay instead.
- This is different from iOS, where Screen Time provides a dedicated API for app restriction.
- Accessibility must be enabled manually in Android Settings before Deep Focus can block apps.
- Launcher and system UI packages are intentionally excluded from blocking to avoid trapping the user.