Dopamine Lock is a modern Android productivity and focus-enforcement application built with Kotlin and Jetpack Compose. Designed with a tactical black-and-white UI, the app helps users eliminate distractions, manage deep work sessions, track productivity, and build discipline through analytics, streaks, and mission-based focus systems.
Dopamine Lock is a native Android productivity and focus-enforcement application built with Kotlin and Jetpack Compose. It helps users run focus sessions and time-boxed missions, manage tasks and goals, block distracting apps at the system level, and track their discipline through streaks, analytics, and a rank-based scoring system.
Dopamine Lock goes beyond a simple countdown timer. A standard Pomodoro app trusts the user to stay off distracting apps during a session; Dopamine Lock backs that intention with real enforcement: accessibility-service-based app blocking, Do Not Disturb activation, and a foreground service that keeps a mission alive even if the app is backgrounded. On top of that enforcement layer, it layers a full productivity system: tasks linked to goals, daily/weekly/monthly goal tracking, session and mission history, weekly/monthly analytics, and a discipline XP/rank system that rewards completed sessions and penalizes abandoned ones.
Every session, mission, task, and goal is backed by Firebase Realtime Database and scoped to the authenticated Firebase Auth user, so progress persists across devices logged into the same account.
Only features with a corresponding implementation in the codebase are listed below.
AuthViewModel, AuthRepositoryImpl)AuthProviderButtons.kt)PomodoroTimerService) so timing continues in the backgroundMissionEnforcementService, monitoring the foreground app in real timeGoalType, GoalUnit)GoalResetManager)InstalledAppsProvider, BlockedAppsRepository)DopamineAccessibilityService) that intercepts blocked apps during an active missionUsageStatsMonitor)AnalyticsRepository, AnalyticsViewModel)DisciplineRepository)DisciplineRankCalculator)DailyGoalReminderWorker)StreakProtectionWorker)GoalProgressWorker)MissionReminderWorker)MilestoneWorker)Explore the main screens and productivity workflows available in Dopamine Lock.
|
App Icon Dopamine Lock application identity. |
![]() Splash Screen Initial launch and authentication-state loading. |
![]() Login Secure account access through Firebase Authentication. |
![]() Dashboard Overview of productivity, goals, sessions, and progress. |
![]() Focus Configuration Configure focus duration, break duration, and session preferences. |
![]() Active Pomodoro Session Live countdown with pause, resume, and session controls. |
![]() Mission Section Create and manage high-commitment focus objectives. |
![]() Create Mission Define the mission title, duration, and focus conditions. |
![]() Active Mission Mode Protected mission session with remaining time and progress. |
![]() Mission Abandonment Confirmation and penalty warning before ending a mission early. |
![]() Task Management Organize tasks by status, goal, category, and priority. |
![]() Goal Tracking Monitor daily, weekly, and monthly mission objectives. |
![]() Productivity Analytics Weekly focus hours, session totals, trends, and performance. |
![]() Discipline Score Rank progression, experience points, achievements, and score history. |
![]() Streak Calendar Daily consistency and long-term discipline tracking. |
![]() Settings Account, focus protection, permissions, and notification preferences. |
| Technology | Purpose |
|---|---|
| Kotlin | Primary application language |
| Jetpack Compose | Declarative UI toolkit for all screens |
| Material 3 | Component library and theming |
| Navigation Compose | In-app screen navigation and back-stack management |
| Firebase Authentication | Email/password, Google, and GitHub sign-in |
| Firebase Realtime Database | User profiles, sessions, missions, tasks, goals, discipline events |
| Kotlin Coroutines / Flow | Asynchronous work and reactive data streams |
| DataStore Preferences | Local persistence for app/focus/enforcement preferences |
| WorkManager | Scheduled reminders (goal, streak, mission, milestone) |
| Android Foreground Services | Persistent focus-timer and mission-enforcement notifications |
| AccessibilityService | Detecting and blocking restricted apps during a mission |
| Credential Manager / Google Identity | Google Sign-In |
| JUnit 4 | Unit testing framework |
| Mockito / mockito-kotlin | Mocking repositories in ViewModel unit tests |
| kotlinx-coroutines-test | Coroutine test dispatchers and scheduling |
| AndroidX Test / Espresso | Instrumented UI test infrastructure |
| Compose UI Test (JUnit4) | Compose-based instrumented UI assertions |
The project follows MVVM architecture with the Repository pattern:
Compose UI
↓
ViewModel
↓
Repository Interface
↓
Repository Implementation
↓
Firebase / DataStore / Android Services
model/): Plain data classes and enums representing domain state (FocusSession, Mission, Task, Goal, DisciplineEvent, User, etc.).ui/): Jetpack Compose screens and reusable components, organized by feature (auth, dashboard, focus, mission, tasks, goals, analytics, discipline, history, streak, blocked apps, settings, onboarding, splash, theme).viewModel/): Holds UI state (StateFlow) per feature and exposes intent functions that call into repository interfaces; contains no Android framework or Firebase code directly.repo/*Repo.kt / repo/*Repository.kt): Defines the contract each feature depends on, decoupling ViewModels from the data source.repo/*RepoImpl.kt / repo/*RepositoryImpl.kt): Implements the contract against Firebase Auth/Realtime Database or DataStore.service/): Foreground services (PomodoroTimerService, MissionEnforcementService) and the DopamineAccessibilityService that perform enforcement work independent of the UI lifecycle.worker/): WorkManager CoroutineWorkers for scheduled reminders and milestone checks.util/): Pure calculation helpers such as DisciplineRankCalculator, FocusTimerMath, AnalyticsCalculator, SessionStatsCalculator, and GoalResetManager.app/src/main/java/com/teamdobermans/dopamine_lock/
├── model/ # Data classes and enums (FocusSession, Mission, Task, Goal, User, ...)
├── repo/ # Repository interfaces and Firebase/DataStore implementations
├── viewModel/ # Feature ViewModels and UI state holders
├── ui/ # Compose screens, grouped by feature, plus shared components/theme
│ ├── auth/
│ ├── dashboard/
│ ├── focus/
│ ├── mission/
│ ├── tasks/
│ ├── goals/
│ ├── analytics/
│ ├── discipline/
│ ├── history/
│ ├── streak/
│ ├── blockedapps/
│ ├── settings/
│ ├── onboarding/
│ ├── splash/
│ ├── components/
│ ├── navigation/
│ └── theme/
├── service/ # Foreground services and the accessibility service
├── worker/ # WorkManager workers for reminders and milestones
├── notification/ # Notification channels and notification builder
├── enforcement/ # Permission checks, usage-stats monitor, installed-apps provider
├── firebase/ # Firebase Auth/Database instance provider
└── util/ # Calculators and helper logic
google-services.json for your Firebase Android app and place it in app/.GOOGLE_WEB_CLIENT_ID Gradle property (see below).Google Sign-In requires a Web Client ID from your Firebase project. Provide it via a Gradle property instead of hard-coding it in source, for example in your user-level ~/.gradle/gradle.properties:
GOOGLE_WEB_CLIENT_ID=your-web-client-id.apps.googleusercontent.com
{
"rules": {
"users": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
},
"focusSessions": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
},
"missions": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
}
}
}
google-services.json: place it at app/google-services.json. It is intentionally excluded from version control (see .gitignore): do not commit it.".read": true / ".write": true in a production project.POST_NOTIFICATIONS: foreground-service and reminder notifications (Android 13+).FOREGROUND_SERVICE / FOREGROUND_SERVICE_SPECIAL_USE: keeps the focus timer and mission enforcement running while the app is backgrounded.PACKAGE_USAGE_STATS (Usage Access, granted via system settings): required to detect which app is currently in the foreground during an active mission.DopamineAccessibilityService to intercept and block restricted apps.SYSTEM_ALERT_WINDOW (Overlay): shows the blocked-app interstitial screen over other apps.ACCESS_NOTIFICATION_POLICY (Do Not Disturb access): lets the app enable DND automatically during a mission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS: recommended so manufacturer battery optimizers don’t kill the enforcement foreground service.Accessibility, usage access, overlay, DND, and battery-optimization permissions should only be granted by users who want strict mission-protection and app-blocking behavior; the app is functional for focus timing, tasks, and goals without them.
Unit tests:
./gradlew test
Windows:
gradlew.bat test
Instrumented tests (requires a connected device or running emulator):
./gradlew connectedAndroidTest
FocusSessionViewModelTest: verifies FocusSessionViewModel.startSession calls the repository with the correct parameters and updates UI state on success.MissionViewModelTest: verifies MissionViewModel.createMission on both a successful creation and a blank-title validation failure.AppFlowInstrumentedTest: end-to-end Compose UI test covering login → dashboard, bottom-navigation across all main screens, and logout back to the login screen.Debug APK:
./gradlew assembleDebug
Output: app/build/outputs/apk/debug/app-debug.apk (debug-signed).
Release APK:
./gradlew assembleRelease
Output: app/build/outputs/apk/release/app-release.apk. Signed with the keystore in keystore.properties if present, otherwise falls back to the debug key (see Release Build Safety below): not suitable for Play Store distribution until a real release keystore is configured.
Release bundle:
./gradlew bundleRelease
Output: app/build/outputs/bundle/release/app-release.aab, signed the same way as the release APK.
Current stable release: v1.0.0
Highlights: Firebase-backed authentication (email/password, Google, GitHub), foreground-service-backed focus sessions with pause/resume, mission mode with real app-blocking enforcement, task/goal management, weekly/monthly analytics, a discipline XP and rank system, streak tracking, and configurable reminder notifications.
To enable proper release signing, copy keystore.properties.example to keystore.properties at the project root, fill in your real keystore path and credentials, and keep the file untracked (it is already covered by .gitignore).
GOOGLE_WEB_CLIENT_ID Gradle property and matching Firebase/Google Cloud configuration.keystore.properties is provided; this is intended for local development only.Dopamine Lock requests Usage Access and Accessibility Service permissions solely to detect when a blocked app is brought to the foreground during an active mission, so it can enforce the block. These permissions are not used to read app content, log browsing activity, or transmit unrelated data. All session, mission, task, goal, and discipline data is stored under the authenticated Firebase user’s own account. Users should review the Android permissions granted to the app in system settings and only enable Accessibility, Usage Access, Overlay, and Do Not Disturb access if they want strict distraction-blocking behavior.
app/src/test) cover ViewModel logic in isolation using mocked repositories: currently FocusSessionViewModel and MissionViewModel.app/src/androidTest) exercise the full Compose UI stack against a real Android environment: currently the authentication and core navigation flow.Aayush Kumar Raut
GitHub: @AayuAmor
Repository: github.com/AayuAmor/DOPAMINE_LOCK
This project was developed as coursework for an Android Application Development with Kotlin course.
No license file is currently included in this repository. All rights are reserved by the author unless a license is added.