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 flowMainActivity 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).

AutomationAutomationService 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.ktCombinedActionExecutor.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 hookGenAIAutomationService.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.