• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.media
18 
19 import javax.inject.Inject
20 
21 /**
22  * Combines [MediaDataManager.Listener] events with [MediaDeviceManager.Listener] events.
23  */
24 class MediaDataCombineLatest @Inject constructor() : MediaDataManager.Listener,
25         MediaDeviceManager.Listener {
26 
27     private val listeners: MutableSet<MediaDataManager.Listener> = mutableSetOf()
28     private val entries: MutableMap<String, Pair<MediaData?, MediaDeviceData?>> = mutableMapOf()
29 
onMediaDataLoadednull30     override fun onMediaDataLoaded(
31         key: String,
32         oldKey: String?,
33         data: MediaData,
34         immediately: Boolean,
35         isSsReactivated: Boolean
36     ) {
37         if (oldKey != null && oldKey != key && entries.contains(oldKey)) {
38             entries[key] = data to entries.remove(oldKey)?.second
39             update(key, oldKey)
40         } else {
41             entries[key] = data to entries[key]?.second
42             update(key, key)
43         }
44     }
45 
onSmartspaceMediaDataLoadednull46     override fun onSmartspaceMediaDataLoaded(
47         key: String,
48         data: SmartspaceMediaData,
49         shouldPrioritize: Boolean
50     ) {
51         listeners.toSet().forEach { it.onSmartspaceMediaDataLoaded(key, data) }
52     }
53 
onMediaDataRemovednull54     override fun onMediaDataRemoved(key: String) {
55         remove(key)
56     }
57 
onSmartspaceMediaDataRemovednull58     override fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean) {
59         listeners.toSet().forEach { it.onSmartspaceMediaDataRemoved(key, immediately) }
60     }
61 
onMediaDeviceChangednull62     override fun onMediaDeviceChanged(
63         key: String,
64         oldKey: String?,
65         data: MediaDeviceData?
66     ) {
67         if (oldKey != null && oldKey != key && entries.contains(oldKey)) {
68             entries[key] = entries.remove(oldKey)?.first to data
69             update(key, oldKey)
70         } else {
71             entries[key] = entries[key]?.first to data
72             update(key, key)
73         }
74     }
75 
onKeyRemovednull76     override fun onKeyRemoved(key: String) {
77         remove(key)
78     }
79 
80     /**
81      * Add a listener for [MediaData] changes that has been combined with latest [MediaDeviceData].
82      */
addListenernull83     fun addListener(listener: MediaDataManager.Listener) = listeners.add(listener)
84 
85     /**
86      * Remove a listener registered with addListener.
87      */
88     fun removeListener(listener: MediaDataManager.Listener) = listeners.remove(listener)
89 
90     private fun update(key: String, oldKey: String?) {
91         val (entry, device) = entries[key] ?: null to null
92         if (entry != null && device != null) {
93             val data = entry.copy(device = device)
94             val listenersCopy = listeners.toSet()
95             listenersCopy.forEach {
96                 it.onMediaDataLoaded(key, oldKey, data)
97             }
98         }
99     }
100 
removenull101     private fun remove(key: String) {
102         entries.remove(key)?.let {
103             val listenersCopy = listeners.toSet()
104             listenersCopy.forEach {
105                 it.onMediaDataRemoved(key)
106             }
107         }
108     }
109 }
110