md: add widget module to ARCHITECTURE
Add documentation on the widget module to ARCHITECTURE.md.
This commit is contained in:
parent
e81d4b6d17
commit
1d828c7b0a
3 changed files with 37 additions and 5 deletions
|
@ -8,7 +8,9 @@ import org.oxycblt.auxio.settings.SettingsManager
|
|||
|
||||
/**
|
||||
* A wrapper around each [WidgetProvider] that plugs into the main Auxio process and updates the
|
||||
* widget state based off of that. This cannot be rolled into [WidgetProvider] directly.
|
||||
* widget state based off of that. This cannot be rolled into [WidgetProvider] directly, as it may
|
||||
* result in memory leaks if [PlaybackStateManager]/[SettingsManager] gets created and bound
|
||||
* to without being released.
|
||||
*/
|
||||
class WidgetController(private val context: Context) :
|
||||
PlaybackStateManager.Callback,
|
||||
|
@ -22,6 +24,9 @@ class WidgetController(private val context: Context) :
|
|||
settingsManager.addCallback(this)
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the widget.
|
||||
*/
|
||||
fun update() {
|
||||
widget.update(context, playbackManager)
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ import org.oxycblt.auxio.music.Song
|
|||
import org.oxycblt.auxio.playback.state.LoopMode
|
||||
|
||||
/*
|
||||
* A condensed variant of the current playback state, used so that PlaybackStateManager does not
|
||||
* need to be queried directly.
|
||||
* An immutable condensed variant of the current playback state, used so that PlaybackStateManager
|
||||
* does not need to be queried directly.
|
||||
*/
|
||||
data class WidgetState(
|
||||
val song: Song,
|
||||
|
|
|
@ -166,7 +166,7 @@ PlaybackStateManager───────────────────┘
|
|||
|
||||
`PlaybackStateManager` is the shared object that contains the master copy of the playback state, doing all operations on it. This object should ***NEVER*** be used in a UI, as it does not sanitize input and can cause major problems if a Volatile UI interacts with it. It's callback system is also prone to memory leaks if not cleared when done. `PlaybackViewModel` should be used instead, as it exposes stable data and safe functions that UIs can use to interact with the playback state.
|
||||
|
||||
`PlaybackService`'s job is to use the playback state to manage the ExoPlayer instance and notification and also modify the state depending on system events, such as when a button is pressed on a headset. It should **never** be bound to, mostly because there is no need given that `PlaybackViewModel` exposes the same data in a much safer fashion. `PlaybackService` also controls the `PlaybackSessionConnector` and `AudioReactor` classes, which manage the `MediaSession` and `AudioFocus` state respectively.
|
||||
`PlaybackService`'s job is to use the playback state to manage the ExoPlayer instance, the notification, and also modify the state depending on system events, such as when a button is pressed on a headset. It should **never** be bound to, mostly because there is no need given that `PlaybackViewModel` exposes the same data in a much safer fashion. `PlaybackService` also controls the `PlaybackSessionConnector`, `AudioReactor`, and `WidgetController` classes, which manage the `MediaSession`, Audio Focus, and Widgets respectively.
|
||||
|
||||
#### `.recycler`
|
||||
|
||||
|
@ -189,4 +189,31 @@ Package for the songs UI, there is no data management here, only a user interfac
|
|||
Shared User Interface utilities. This is primarily made up of convenience/extension functions relating to Views, Resources, Configurations, and Contexts. It also contains some dedicated utilities, such as:
|
||||
- The Accent Management system
|
||||
- `newMenu` and `ActionMenu`, which automates menu creation for most data types
|
||||
- `memberBinding` and `MemberBinder`, which allows for ViewBindings to be used as a member variable without memory leaks or nullability issues.
|
||||
- `memberBinding` and `MemberBinder`, which allows for ViewBindings to be used as a member variable without memory leaks or nullability issues.
|
||||
|
||||
#### `.widgets`
|
||||
|
||||
The widget sub-module. This module differs heavily from the rest of Auxio, as widget UIs can't be controlled in the same
|
||||
way that UIs in the main process can.
|
||||
|
||||
Widgets are controlled by two pieces of code:
|
||||
|
||||
- `WidgetProvider`, which provides the widget layouts to the system
|
||||
- `WidgetController`, which acts as an intermediary between the Auxio process and the widget [ex. Monitoring the playback state]
|
||||
|
||||
The widget update process is described in this diagram:
|
||||
|
||||
```
|
||||
WidgetController<──────────PlaybackService
|
||||
│ Controls ^
|
||||
│ │
|
||||
│ Updates │
|
||||
│ │
|
||||
│ │
|
||||
v Requests Update │
|
||||
WidgetProvider───────────────────┘
|
||||
```
|
||||
|
||||
When `WidgetProvider` creates a layout, it first turns the `PlaybackStateManager` instance into a `WidgetState`, which is
|
||||
an immutable version of the playback state that negates some of the problems with using a shared object here. It then picks
|
||||
a layout [e.g "Form"] depending on its current dimensions and applies the `WidgetState` object to that.
|
Loading…
Reference in a new issue