# yume-chan/volumemanager architecture

> Architecture diagram of the GitHub repository yume-chan/volumemanager, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/yume-chan/volumemanager
- Repository: https://github.com/yume-chan/volumemanager

## Overview

1. **What this repo is**
   - An Android app called **Volume Manager** that lets the user control **per-app audio volume** on **Android 13+**.
   - It is not a general media app; its core architecture is about **monitoring active audio players** and **writing volume changes into Android’s internal audio APIs**.

2. **High-level runtime shape**
   - The app is a **single Android application module** (`app`) with a small **benchmark/profile module** (`baselineProfile`) for startup/performance optimization.
   - The main UI is built with **Jetpack Compose**.
   - Privileged access is obtained through **Shizuku**, which is explicitly called out in the README as the mechanism used to reach hidden/system APIs.

3. **Primary user-facing entry points**
   - `MainActivity` is the main control screen.
   - `PopupActivity` is the volume popup UI that can replace the system volume panel behavior.
   - The Compose UI lives under `app/src/main/java/moe/chensi/volume/compose`, with separate components for:
     - app volume lists/sliders,
     - system stream sliders,
     - toggle buttons,
     - dialogs such as about and crash reporting.

4. **Core orchestration layer**
   - `Manager` appears to be the central application coordinator: it likely holds current state, bridges UI actions to audio/system operations, and coordinates enabled/disabled behavior.
   - `Service` is the runtime service boundary, likely responsible for always-on monitoring and integrating with accessibility/overlay-like behavior.
   - `MyApplication` and `CrashHandler` provide process-level initialization and crash capture/reporting behavior.

5. **How the volume control mechanism works**
   - The architecture follows the flow described in the README:
     1. query active playback sessions from `AudioManager#getActivePlaybackConfigurations()`,
     2. map each playback session back to an app using process/package information,
     3. call internal player APIs to set the volume multiplier,
     4. register callbacks so new playback sessions receive the current per-app volume automatically.
   - This means the app’s domain model is built around **audio playback configurations**, not around files, tracks, or media libraries.

6. **System integration boundary**
   - The `system` package contains proxy wrappers around privileged Android services:
     - `ActivityTaskManagerProxy`
     - `AudioPlaybackConfigurationProxy`
     - `NotificationManagerProxy`
     - `PackageManagerProxy`
     - `UserManagerProxy`
   - These are the main boundary layer between app code and hidden/system APIs, which is where the app’s privileged capabilities are concentrated.

7. **Hidden binder/API hooking layer**
   - `android/media/IPlaybackConfigDispatcher.aidl` and `ToggleableBinderProxy.kt` indicate the app also interacts with binder-level callbacks/proxies, not just public SDK calls.
   - This suggests a design where the app can **intercept or emulate system dispatch behavior** for playback configuration updates, then enable/disable that behavior dynamically.

8. **Accessibility-driven behavior**
   - The presence of `res/xml/accessibility_service_config.xml` and the README instructions imply an **accessibility service** is part of the product’s control surface.
   - The accessibility button and auto-enabled service are likely used to provide quick access to the popup/control experience and to keep the app responsive to system UI interactions.

9. **State and persistence**
   - The `data` package contains:
     - `App` — app-level domain model,
     - `AppPreferences` — user settings/state,
     - `AppPreferencesStore` — persistence layer.
   - This is the boundary for long-lived configuration such as user preferences, enabling/disabling behavior, and possibly per-app saved volume values.

10. **UI composition structure**
   - The Compose layer is separated by responsibility rather than by screen only:
     - app list + per-app slider,
     - system volume panel,
     - stream volume slider,
     - generic track slider,
     - toggle controls.
   - This indicates a **shared component architecture** where the same slider/toggle primitives are reused across the main screen and popup surfaces.

11. **Error handling and support UX**
   - `CrashHandler` plus `CrashReportDialog` show that crashes are handled as a first-class UX concern.
   - `AboutDialog` suggests an in-app informational/support boundary rather than relying only on external docs.

12. **Assets, branding, and release concerns**
   - The app includes a standard Android resource set for icons, themes, localization, and accessibility service XML.
   - There is Chinese localization (`values-zh-rCN`) alongside default strings, indicating the UI is localized but still centered around the same single core workflow.

13. **Build, test, and release pipeline**
   - The repo uses **Gradle Kotlin DSL** and ships via GitHub Actions (`.github/workflows/build.yml`).
   - It also has **baseline profile generation** to improve app startup on Android.
   - `fastlane` metadata is present for store/release distribution assets and descriptions.

14. **Architecture summary for a diagram**
   - The clearest diagram is:
     - **User touches Compose UI / popup / accessibility entry points**
     - → **Manager / Service coordinate state**
     - → **Preferences store provides saved settings**
     - → **System proxy layer + Shizuku-backed privileged access**
     - → **Android audio/process/package services**
     - → **active playback configs are mapped to apps**
     - → **volume is applied via internal player APIs**
     - → **callbacks keep new sessions in sync**
   - The central boundary is between **ordinary app UI/state** and **privileged hidden Android audio/system APIs**.

Main entry points: [`app/src/main/java/moe/chensi/volume/Manager.kt`](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/Manager.kt) (Manager), [`app/src/main/java/moe/chensi/volume/compose`](https://github.com/yume-chan/volumemanager/tree/main/app/src/main/java/moe/chensi/volume/compose) (Compose UI), [`app/src/main/java/moe/chensi/volume/system`](https://github.com/yume-chan/volumemanager/tree/main/app/src/main/java/moe/chensi/volume/system) (System proxies), [`app/src/main/java/moe/chensi/volume/MyApplication.kt`](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/MyApplication.kt) (MyApplication)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["App runtime"]
  node_main_activity["MainActivity<br/>screen<br/>[MainActivity.kt]"]
  node_popup_activity["PopupActivity<br/>popup screen<br/>[PopupActivity.kt]"]
  node_manager{{"Manager<br/>orchestrator<br/>[Manager.kt]"}}
  node_service["Service<br/>[Service.kt]"]
  node_application(("MyApplication<br/>app init<br/>[MyApplication.kt]"))
  node_crash_handler["CrashHandler<br/>crash handler<br/>[CrashHandler.kt]"]
  node_compose_ui["Compose UI<br/>ui components"]
  node_app_volume_list["App list<br/>compose list<br/>[AppVolumeList.kt]"]
  node_app_volume_slider["App slider<br/>compose control<br/>[AppVolumeSlider.kt]"]
  node_system_volume_panel["System panel<br/>compose panel"]
  node_toggle_button["Toggle<br/>compose control<br/>[ToggleButton.kt]"]
end

subgraph group_system["Privileged system"]
  node_system_proxies["System proxies<br/>hidden API wrappers"]
  node_audio_proxy["Audio config<br/>audio proxy"]
  node_binder_proxy["Binder proxy<br/>binder hook"]
  node_aidl_dispatcher["Playback AIDL<br/>binder interface"]
  node_shizuku_access{{"Shizuku<br/>privileged access"}}
end

subgraph group_state["State & persistence"]
  node_app_model["App model<br/>domain model<br/>[App.kt]"]
  node_preferences["Preferences<br/>settings model<br/>[AppPreferences.kt]"]
  node_preferences_store[("Prefs store<br/>persistence")]
end

subgraph group_release["Build & release"]
  node_baseline_profile["Baseline profile<br/>performance module"]
  node_release_assets["Store assets<br/>release metadata"]
end

node_application -->|"starts"| node_main_activity
node_application -->|"initializes"| node_service
node_application -->|"installs"| node_crash_handler
node_main_activity -->|"controls"| node_manager
node_popup_activity -->|"controls"| node_manager
node_service -->|"hosts"| node_manager
node_manager -->|"renders"| node_compose_ui
node_compose_ui -->|"contains"| node_app_volume_list
node_compose_ui -->|"contains"| node_app_volume_slider
node_compose_ui -->|"contains"| node_system_volume_panel
node_compose_ui -->|"contains"| node_toggle_button
node_manager -->|"loads/saves"| node_preferences_store
node_preferences_store -->|"stores"| node_preferences
node_manager -->|"uses"| node_app_model
node_manager -->|"invokes"| node_system_proxies
node_system_proxies -->|"includes"| node_audio_proxy
node_system_proxies -->|"includes"| node_binder_proxy
node_binder_proxy -->|"implements"| node_aidl_dispatcher
node_system_proxies -->|"backed by"| node_shizuku_access
node_audio_proxy -->|"maps to"| node_app_model
node_audio_proxy -->|"feeds"| node_manager
node_manager -->|"registers callbacks"| node_service
node_manager -->|"reports"| node_crash_handler
node_baseline_profile -.->|"optimizes"| node_main_activity
node_release_assets -.->|"documents"| node_compose_ui

click node_main_activity "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/MainActivity.kt"
click node_popup_activity "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/PopupActivity.kt"
click node_manager "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/Manager.kt"
click node_service "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/Service.kt"
click node_application "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/MyApplication.kt"
click node_crash_handler "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/CrashHandler.kt"
click node_compose_ui "https://github.com/yume-chan/volumemanager/tree/main/app/src/main/java/moe/chensi/volume/compose"
click node_app_volume_list "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/compose/AppVolumeList.kt"
click node_app_volume_slider "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/compose/AppVolumeSlider.kt"
click node_system_volume_panel "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/compose/SystemVolumePanel.kt"
click node_toggle_button "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/compose/ToggleButton.kt"
click node_app_model "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/data/App.kt"
click node_preferences "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/data/AppPreferences.kt"
click node_preferences_store "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/data/AppPreferencesStore.kt"
click node_system_proxies "https://github.com/yume-chan/volumemanager/tree/main/app/src/main/java/moe/chensi/volume/system"
click node_audio_proxy "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/system/AudioPlaybackConfigurationProxy.kt"
click node_binder_proxy "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/ToggleableBinderProxy.kt"
click node_aidl_dispatcher "https://github.com/yume-chan/volumemanager/blob/main/app/src/main/aidl/android/media/IPlaybackConfigDispatcher.aidl"
click node_baseline_profile "https://github.com/yume-chan/volumemanager/tree/main/baselineProfile"
click node_release_assets "https://github.com/yume-chan/volumemanager/tree/main/fastlane"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main_activity,node_popup_activity,node_manager,node_service,node_application,node_crash_handler,node_compose_ui,node_app_volume_list,node_app_volume_slider,node_system_volume_panel,node_toggle_button toneBlue
class node_system_proxies,node_audio_proxy,node_binder_proxy,node_aidl_dispatcher,node_shizuku_access toneAmber
class node_app_model,node_preferences,node_preferences_store toneMint
class node_baseline_profile,node_release_assets toneRose
```

## Components

### App runtime

Main Android application entry points, orchestration, and UI.

- [MainActivity](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/MainActivity.kt): screen · Primary control screen for managing per-app audio volume. · `app/src/main/java/moe/chensi/volume/MainActivity.kt`
- [PopupActivity](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/PopupActivity.kt): popup screen · Overlay-style volume popup surface. · `app/src/main/java/moe/chensi/volume/PopupActivity.kt`
- [Manager](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/Manager.kt): orchestrator · Central coordinator for app state, UI actions, and volume operations. · `app/src/main/java/moe/chensi/volume/Manager.kt`
- [Service](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/Service.kt): runtime service · Always-on service boundary for monitoring and system interaction. · `app/src/main/java/moe/chensi/volume/Service.kt`
- [MyApplication](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/MyApplication.kt): app init · Process-level initialization entry point. · `app/src/main/java/moe/chensi/volume/MyApplication.kt`
- [CrashHandler](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/CrashHandler.kt): crash handler · Global crash capture and reporting setup. · `app/src/main/java/moe/chensi/volume/CrashHandler.kt`
- [Compose UI](https://github.com/yume-chan/volumemanager/tree/main/app/src/main/java/moe/chensi/volume/compose): ui components · Shared Jetpack Compose component layer for screens, sliders, toggles, and dialogs. · `app/src/main/java/moe/chensi/volume/compose`
- [App list](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/compose/AppVolumeList.kt): compose list · Per-app volume list presentation. · `app/src/main/java/moe/chensi/volume/compose/AppVolumeList.kt`
- [App slider](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/compose/AppVolumeSlider.kt): compose control · Per-app volume slider component. · `app/src/main/java/moe/chensi/volume/compose/AppVolumeSlider.kt`
- [System panel](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/compose/SystemVolumePanel.kt): compose panel · System volume panel UI surface. · `app/src/main/java/moe/chensi/volume/compose/SystemVolumePanel.kt`
- [Toggle](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/compose/ToggleButton.kt): compose control · Shared enable/disable control component. · `app/src/main/java/moe/chensi/volume/compose/ToggleButton.kt`

### Privileged system

Hidden API wrappers, binder hooks, and Android service integration.

- [System proxies](https://github.com/yume-chan/volumemanager/tree/main/app/src/main/java/moe/chensi/volume/system): hidden API wrappers · Wrapper layer around privileged Android services and hidden system interfaces. · `app/src/main/java/moe/chensi/volume/system`
- [Audio config](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/system/AudioPlaybackConfigurationProxy.kt): audio proxy · Access to playback configuration and audio session mapping. · `app/src/main/java/moe/chensi/volume/system/AudioPlaybackConfigurationProxy.kt`
- [Binder proxy](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/ToggleableBinderProxy.kt): binder hook · Toggleable binder-level interception for playback config dispatch. · `app/src/main/java/moe/chensi/volume/ToggleableBinderProxy.kt`
- [Playback AIDL](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/aidl/android/media/IPlaybackConfigDispatcher.aidl): binder interface · AIDL definition for playback configuration dispatch callbacks. · `app/src/main/aidl/android/media/IPlaybackConfigDispatcher.aidl`
- **Shizuku**: privileged access · Mechanism used to reach hidden and system APIs.

### State & persistence

Domain models and stored preferences.

- [App model](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/data/App.kt): domain model · App-level domain object used for playback-to-app mapping and saved settings. · `app/src/main/java/moe/chensi/volume/data/App.kt`
- [Preferences](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/data/AppPreferences.kt): settings model · User settings and persisted app state. · `app/src/main/java/moe/chensi/volume/data/AppPreferences.kt`
- [Prefs store](https://github.com/yume-chan/volumemanager/blob/main/app/src/main/java/moe/chensi/volume/data/AppPreferencesStore.kt): persistence · Storage boundary for application preferences. · `app/src/main/java/moe/chensi/volume/data/AppPreferencesStore.kt`

### Build & release

Performance profiling and distribution support.

- [Baseline profile](https://github.com/yume-chan/volumemanager/tree/main/baselineProfile): performance module · Startup and performance profiling module. · `baselineProfile`
- [Store assets](https://github.com/yume-chan/volumemanager/tree/main/fastlane): release metadata · Fastlane metadata and localized release materials. · `fastlane`

## Connections

- MyApplication → MainActivity: starts · Launches the primary UI entry point.
- MyApplication → Service: initializes · Sets up long-lived runtime behavior.
- MyApplication → CrashHandler: installs · Registers process-wide crash capture.
- MainActivity → Manager: controls · Sends user actions to the coordinator.
- PopupActivity → Manager: controls · Routes popup interactions to the coordinator.
- Service → Manager: hosts · Keeps orchestration active in the background.
- Manager → Compose UI: renders · Binds state into shared Compose surfaces.
- Compose UI → App list: contains · List of managed apps.
- Compose UI → App slider: contains · Per-app slider control.
- Compose UI → System panel: contains · System volume panel surface.
- Compose UI → Toggle: contains · Shared toggle controls.
- Manager → Prefs store: loads/saves · Reads and persists configuration.
- Prefs store → Preferences: stores · Persists app settings and user choices.
- Manager → App model: uses · Represents apps and their volume state.
- Manager → System proxies: invokes · Calls privileged Android service wrappers.
- System proxies → Audio config: includes · Audio/session configuration access.
- System proxies → Binder proxy: includes · Dynamic binder interception layer.
- Binder proxy → Playback AIDL: implements · Hooks playback config callbacks.
- System proxies → Shizuku: backed by · Uses Shizuku to reach hidden/system APIs.
- Audio config → App model: maps to · Maps playback sessions back to apps.
- Audio config → Manager: feeds · Provides active playback configuration updates.
- Manager → Service: registers callbacks · Keeps new playback sessions in sync.
- Manager → CrashHandler: reports · Routes crash context to support UX.
- Baseline profile → MainActivity: optimizes · Profiles startup and launch paths.
- Store assets → Compose UI: documents · Contains store-facing screenshots and descriptions.
