Skip to content

afnan0304/FocusBlocker

Repository files navigation

FocusBlocker

FocusBlocker is an Android productivity application that enforces app-usage limits using a foreground monitoring service, policy-based blocking rules, and a dedicated block screen experience.

It is built with modern Android tooling and a security-first baseline suitable for personal hardening and extension into a production deployment pipeline.

Table of Contents

  1. Overview
  2. Core Capabilities
  3. Tech Stack
  4. Architecture
  5. Permission and Runtime Model
  6. Security Model
  7. Getting Started
  8. Build and Release
  9. Testing
  10. Project Conventions
  11. Contributing
  12. License

Overview

FocusBlocker tracks foreground app usage and applies configurable daily quotas per package. Once quota is exhausted, the app presents a full-screen block activity and keeps monitoring in the background through a foreground service.

The app is designed around:

  • Deterministic quota tracking by logical day.
  • Continuous monitoring with restart resilience (boot/package-updated receiver).
  • Secure preference storage for sensitive settings.
  • A Compose-first UI with permission gateway and focused workflows.

Core Capabilities

  • Foreground app monitoring via UsageStatsManager in AppMonitorService.
  • App-level policy persistence with Room (AppPolicy, Task, DAOs, and AppDatabase).
  • Quota accumulation and automatic daily reset based on a configurable day-start hour.
  • Full-screen blocking UX using BlockScreenActivity when a policy limit is reached.
  • Boot and package-replaced recovery through BootReceiver.
  • Permission gateway flow for usage access, overlay permission, and battery optimization exemption.
  • Encrypted sensitive preferences through EncryptedSharedPreferences.

Tech Stack

  • Language: Kotlin
  • UI: Jetpack Compose + Material 3
  • Architecture primitives: ViewModel, Navigation Compose, Kotlin Coroutines/Flow
  • Dependency Injection: Hilt
  • Local persistence: Room + KSP
  • Security: Android Keystore + AndroidX Security Crypto
  • Build system: Gradle (Kotlin DSL)

Current project baselines:

  • Android Gradle Plugin: 9.0.1
  • Kotlin: 2.3.10
  • Compile SDK: 36
  • Target SDK: 35
  • Min SDK: 26

Architecture

The project currently uses a single app module (:app) with clean package boundaries.

app/src/main/java/com/focusblocker/app/
	data/
		local/
			dao/
			entity/
			AppDatabase.kt
	di/
	security/
	service/
	ui/
		screens/
		block/
		theme/

High-level flow:

  1. User grants required special permissions in the permission gateway.
  2. AppMonitorService starts as foreground service.
  3. Service polls recent usage events and resolves current foreground package.
  4. Policy and quota state are read/updated in Room.
  5. If quota is exhausted, BlockScreenActivity is launched.

Permission and Runtime Model

FocusBlocker requires the following permissions/special access for enforcement:

  • PACKAGE_USAGE_STATS for foreground usage events.
  • SYSTEM_ALERT_WINDOW for overlay/blocking UX compatibility.
  • REQUEST_IGNORE_BATTERY_OPTIMIZATIONS to reduce service kill risk.
  • RECEIVE_BOOT_COMPLETED for automatic restart after reboot.
  • Foreground service permissions for persistent monitoring.

At runtime, the app gates entry through a dedicated permission screen and starts the monitor service only after required access is granted.

Security Model

Sensitive state is stored in encrypted preferences:

  • Backend: EncryptedSharedPreferences
  • Key management: Android Keystore (MasterKey AES-256-GCM)
  • Preference file: focusblocker_secure_prefs

Additional anti-tamper logic exists in SecurityManager:

  • Logical-day computation using configurable day-start hour.
  • Forward clock-drift detection using SystemClock.elapsedRealtime() baseline.

Getting Started

Prerequisites

  • Android Studio (latest stable recommended)
  • JDK 17+
  • Android SDK with platform level 35+ installed

Clone and Open

git clone <your-fork-or-repo-url>
cd FocusBlocker

Open the project in Android Studio and allow Gradle sync to complete.

Build Debug APK

./gradlew :app:assembleDebug

Install on Connected Device

./gradlew :app:installDebug

Build and Release

Release Signing Configuration

Release signing values are read from Gradle properties or environment variables:

  • RELEASE_STORE_FILE
  • RELEASE_STORE_PASSWORD
  • RELEASE_KEY_ALIAS
  • RELEASE_KEY_PASSWORD

You can start from signing.properties.template and place values in user-level Gradle properties or exported environment variables.

Build Release APK

./gradlew :app:assembleRelease

If release signing values are missing, the build fails fast with explicit missing keys.

Testing

Unit Tests

./gradlew :app:testDebugUnitTest

Instrumented Tests

./gradlew :app:connectedDebugAndroidTest

Full Verification Pass

./gradlew :app:lint :app:testDebugUnitTest

Project Conventions

  • Base package must remain com.focusblocker.app.
  • Keep Room schemas exported under app/schemas/.
  • Use Hilt for dependency wiring in app scope and Android components.
  • Prefer immutable UI state and coroutine-based asynchronous flows.
  • Keep release-signing secrets out of version control.

Contributing

Contributions are welcome. Please review CONTRIBUTING.md before opening a pull request.

Recommended pull request quality bar:

  • Focused, single-purpose changes.
  • Updated tests for behavioral changes.
  • No debug logging or temporary scaffolding left in final diff.
  • Clear migration notes for permission, schema, or signing behavior changes.

License

This project is licensed under the Apache License 2.0. See LICENSE.

Acknowledgments

This repository originated from Android architecture template foundations and has been adapted into the FocusBlocker application domain.

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages