The Problem
Android power users need a single, installable package that bundles low‑level tweaks (e.g., battery‑optimisation, custom quick‑tiles, input remapping) without scattering code across many independent apps. Maintaining each tweak separately leads to fragmented updates, duplicated permissions, and a poor user experience.
What This Does
Essentials is an Android application that aggregates over 900 Kotlin classes into a modular framework. Core UI lives in app/src/main/java/com/sameerasw/essentials/MainActivity.kt and EssentialsApp.kt. Feature implementations are split into services, tiles, and handlers (e.g., BatteryNotificationService.kt, FlashlightTileService.kt, ButtonRemapHandler.kt). Data persistence is handled by repository classes under app/src/main/java/com/sameerasw/essentials/data/repository/ – for example, SettingsRepository.kt stores user preferences, while GitHubRepository.kt fetches remote release information.
Automation logic lives in services/automation/AutomationManager.kt and AutomationService.kt, which consume JSON‑defined actions (domain/diy/Action.kt, Automation.kt). Gen‑AI suggestions are exposed via domain/genai/GenAIAutomationService.kt. The app also ships a small set of assets (assets/emojis.json, kaomoji.json) used by the input method (ime/EssentialsInputMethodService.kt).
How It Is Wired
Entry point – Android launches EssentialsApp.kt (registered in AndroidManifest.xml). It creates the DI container and registers MainActivity.
UI → Service flow – MainActivity interacts with AppFunctionAvailabilityManager.kt to query which tiles/handlers are active. When a user taps a Quick‑Tile, Android sends an intent to the corresponding *TileService (e.g., FlashlightTileService.kt). Each tile service calls its handler (FlashlightHandler.kt) which executes the low‑level operation via the appropriate system API (e.g., CameraManager for torch control).
Automation – AutomationService runs as a foreground service started by AutomationManager. It loads automation definitions from domain/diy/Automation.kt (JSON stored in app assets). The manager instantiates module classes (BluetoothModule.kt, TimeModule.kt, etc.) which implement AutomationModule. When a trigger condition fires (e.g., time change via TimeAutomationReceiver.kt), the module executes its ActionExecutor chain (ActionExecutor.kt → CombinedActionExecutor.kt).
External interaction – Broadcast receivers in services/receivers/ (e.g., AppBootReceiver.kt, BatteryAutomationReceiver.kt) listen for system events and forward them to the automation engine or directly to service handlers.
Data layer – Repository classes abstract Room/SharedPreferences access. SettingsRepository.kt is the sole writer for user‑tuned flags; GitHubRepository.kt contacts the upstream repo for update checks, using Retrofit defined in build.gradle.kts.
Gen‑AI hook – GenAIAutomationService.kt calls out to a remote model (URL configured in assets/adi‑registration.properties) and returns AutomationSuggestion objects consumed by the UI.
All external effects (system settings, files, network) originate from the service/handler classes; the rest of the codebase is pure Kotlin data models.
How To Use It
# Clone the repo
git clone https://github.com/moses-y/essentials.git
cd essentials
# Build the APK (Gradle wrapper provided)
./gradlew :app:assembleRelease
# The generated APK is at
app/build/outputs/apk/release/app-release.apk
No additional configuration files are required for a local build; the app reads default assets and uses runtime permissions. To test a custom automation, place a JSON file under app/src/main/assets/ matching the Automation schema and enable it via the Settings UI.
Real‑World Use
A power user wants the device to mute all notifications and enable “caffeinate” mode when a specific Bluetooth headset connects. They create an automation JSON:
{
"trigger": {"type":"bluetooth","device":"MyHeadset"},
"actions": [
{"type":"notification_lighting","mode":"off"},
{"type":"caffeinate","duration":3600}
]
}
The file is dropped into assets/automations/. AutomationManager loads it, BluetoothModule detects the headset, and the two actions are dispatched to NotificationLightingHandler.kt and CaffeinateTileService.kt respectively—no manual toggling required.
Code Health & Issues
- Low – Limited test coverage – only 3 test files (e.g.,
ExampleInstrumentedTest.kt) for an app with >400 Kotlin classes. - Low – No explicit static analysis reports – the repo includes GitHub Actions (
.github/workflows/validate-translations.yml) but no lint or code‑quality checks. - Low – No secrets – no API keys are committed; external services are referenced via placeholder assets.
All expected Android project files (proguard-rules.pro, gradle/, CI scripts) are present.
The Bottom Line
Essentials delivers a dense, feature‑rich Android mod package with a clear modular structure: UI → service/handler → repository. The wiring is straightforward, but the paucity of tests and lack of automated linting increase maintenance risk. It is suitable for developers comfortable navigating Android services and who need a single codebase to extend or customise power‑user tweaks.