Add a unique ID to MediaDeviceData

Both InfoMediaDevice and PhoneMediaDevice implement getIcon by calling
mContext.getDrawable and do not cache the result. Each time, they appear
to supply a fresh icon object inside MediaDeviceManager.updateCurrent,
causing it to always update the field MediaDeviceManager.current in its
setter. This resulted in a lot of unnecessary work being sent to the
fgExecutor on every volume change event, causing jank in the volume
dialog. Adding each device's unique ID to the media data and not setting
the field on ID matches eliminates the unnecessary calls.

Fixes: 225624315
Test: Manually tested and verified lack of dropped frames in Perfetto
Change-Id: I5d8fdcdf18c30a87274a8bf07e3f6a07afd650e1
This commit is contained in:
Justin Weir
2022-05-23 17:24:29 -04:00
parent 851b2e6a4d
commit be0adabd7a
2 changed files with 7 additions and 3 deletions

View File

@@ -212,5 +212,8 @@ data class MediaDeviceData
val name: CharSequence?,
/** Optional intent to override the default output switcher for this control */
val intent: PendingIntent? = null
val intent: PendingIntent? = null,
/** Unique id for this device */
val id: String? = null
)

View File

@@ -155,7 +155,8 @@ class MediaDeviceManager @Inject constructor(
private var playbackType = PLAYBACK_TYPE_UNKNOWN
private var current: MediaDeviceData? = null
set(value) {
if (!started || value != field) {
val hasSameId = value?.id != null && value.id == field?.id
if (!started || (!hasSameId && value != field)) {
field = value
fgExecutor.execute {
processDevice(key, oldKey, value)
@@ -263,7 +264,7 @@ class MediaDeviceManager @Inject constructor(
// If we have a controller but get a null route, then don't trust the device
val enabled = device != null && (controller == null || route != null)
val name = route?.name?.toString() ?: device?.name
current = MediaDeviceData(enabled, device?.iconWithoutBackground, name)
current = MediaDeviceData(enabled, device?.iconWithoutBackground, name, id = device?.id)
}
}
}