/* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.media import javax.inject.Inject /** * Combines [MediaDataManager.Listener] events with [MediaDeviceManager.Listener] events. */ class MediaDataCombineLatest @Inject constructor() : MediaDataManager.Listener, MediaDeviceManager.Listener { private val listeners: MutableSet = mutableSetOf() private val entries: MutableMap> = mutableMapOf() override fun onMediaDataLoaded( key: String, oldKey: String?, data: MediaData, immediately: Boolean, receivedSmartspaceCardLatency: Int ) { if (oldKey != null && oldKey != key && entries.contains(oldKey)) { entries[key] = data to entries.remove(oldKey)?.second update(key, oldKey) } else { entries[key] = data to entries[key]?.second update(key, key) } } override fun onSmartspaceMediaDataLoaded( key: String, data: SmartspaceMediaData, shouldPrioritize: Boolean, isSsReactivated: Boolean ) { listeners.toSet().forEach { it.onSmartspaceMediaDataLoaded(key, data) } } override fun onMediaDataRemoved(key: String) { remove(key) } override fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean) { listeners.toSet().forEach { it.onSmartspaceMediaDataRemoved(key, immediately) } } override fun onMediaDeviceChanged( key: String, oldKey: String?, data: MediaDeviceData? ) { if (oldKey != null && oldKey != key && entries.contains(oldKey)) { entries[key] = entries.remove(oldKey)?.first to data update(key, oldKey) } else { entries[key] = entries[key]?.first to data update(key, key) } } override fun onKeyRemoved(key: String) { remove(key) } /** * Add a listener for [MediaData] changes that has been combined with latest [MediaDeviceData]. */ fun addListener(listener: MediaDataManager.Listener) = listeners.add(listener) /** * Remove a listener registered with addListener. */ fun removeListener(listener: MediaDataManager.Listener) = listeners.remove(listener) private fun update(key: String, oldKey: String?) { val (entry, device) = entries[key] ?: null to null if (entry != null && device != null) { val data = entry.copy(device = device) val listenersCopy = listeners.toSet() listenersCopy.forEach { it.onMediaDataLoaded(key, oldKey, data) } } } private fun remove(key: String) { entries.remove(key)?.let { val listenersCopy = listeners.toSet() listenersCopy.forEach { it.onMediaDataRemoved(key) } } } }