Loading packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt +29 −17 Original line number Diff line number Diff line Loading @@ -47,7 +47,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.scan import kotlinx.coroutines.flow.shareIn Loading Loading @@ -155,10 +154,11 @@ constructor( is DisplayEvent.Changed -> previousIds + id } } .shareIn( .distinctUntilChanged() .stateIn( bgApplicationScope, started = SharingStarted.WhileSubscribed(), replay = 1 SharingStarted.WhileSubscribed(), emptySet(), ) } else { oldEnabledDisplays.map { enabledDisplaysSet -> Loading @@ -177,7 +177,8 @@ constructor( enabledDisplayIds .mapElementsLazily { displayId -> getDisplay(displayId) } .flowOn(backgroundCoroutineDispatcher) .debugLog("enabledDisplayIds") .debugLog("enabledDisplays") .stateIn(bgApplicationScope, SharingStarted.WhileSubscribed(), emptySet()) } else { oldEnabledDisplays } Loading Loading @@ -355,20 +356,31 @@ constructor( * [createValue] returns a null element, it will not be added in the output set. */ private fun <T, V> Flow<Set<T>>.mapElementsLazily(createValue: (T) -> V?): Flow<Set<V>> { var initialSet = emptySet<T>() val currentMap = mutableMapOf<T, V>() var resultSet = emptySet<V>() return onEach { currentSet -> val removed = initialSet - currentSet val added = currentSet - initialSet if (added.isNotEmpty() || removed.isNotEmpty()) { added.forEach { key: T -> createValue(key)?.let { currentMap[key] = it } } removed.forEach { key: T -> currentMap.remove(key) } resultSet = currentMap.values.toSet() // Creates a **copy** of values } initialSet = currentSet } .map { resultSet } data class State<T, V>( val previousSet: Set<T>, // Caches T values from the previousSet that were already converted to V val valueMap: Map<T, V>, val resultSet: Set<V> ) val initialState = State(emptySet<T>(), emptyMap(), emptySet<V>()) return this.scan(initialState) { state, currentSet -> if (currentSet == state.previousSet) { state } else { val removed = state.previousSet - currentSet val added = currentSet - state.previousSet val newMap = state.valueMap.toMutableMap() added.forEach { key -> createValue(key)?.let { newMap[key] = it } } removed.forEach { key -> newMap.remove(key) } val resultSet = newMap.values.toSet() State(currentSet, newMap, resultSet) } } .map { it.resultSet } } private companion object { Loading Loading
packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt +29 −17 Original line number Diff line number Diff line Loading @@ -47,7 +47,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.scan import kotlinx.coroutines.flow.shareIn Loading Loading @@ -155,10 +154,11 @@ constructor( is DisplayEvent.Changed -> previousIds + id } } .shareIn( .distinctUntilChanged() .stateIn( bgApplicationScope, started = SharingStarted.WhileSubscribed(), replay = 1 SharingStarted.WhileSubscribed(), emptySet(), ) } else { oldEnabledDisplays.map { enabledDisplaysSet -> Loading @@ -177,7 +177,8 @@ constructor( enabledDisplayIds .mapElementsLazily { displayId -> getDisplay(displayId) } .flowOn(backgroundCoroutineDispatcher) .debugLog("enabledDisplayIds") .debugLog("enabledDisplays") .stateIn(bgApplicationScope, SharingStarted.WhileSubscribed(), emptySet()) } else { oldEnabledDisplays } Loading Loading @@ -355,20 +356,31 @@ constructor( * [createValue] returns a null element, it will not be added in the output set. */ private fun <T, V> Flow<Set<T>>.mapElementsLazily(createValue: (T) -> V?): Flow<Set<V>> { var initialSet = emptySet<T>() val currentMap = mutableMapOf<T, V>() var resultSet = emptySet<V>() return onEach { currentSet -> val removed = initialSet - currentSet val added = currentSet - initialSet if (added.isNotEmpty() || removed.isNotEmpty()) { added.forEach { key: T -> createValue(key)?.let { currentMap[key] = it } } removed.forEach { key: T -> currentMap.remove(key) } resultSet = currentMap.values.toSet() // Creates a **copy** of values } initialSet = currentSet } .map { resultSet } data class State<T, V>( val previousSet: Set<T>, // Caches T values from the previousSet that were already converted to V val valueMap: Map<T, V>, val resultSet: Set<V> ) val initialState = State(emptySet<T>(), emptyMap(), emptySet<V>()) return this.scan(initialState) { state, currentSet -> if (currentSet == state.previousSet) { state } else { val removed = state.previousSet - currentSet val added = currentSet - state.previousSet val newMap = state.valueMap.toMutableMap() added.forEach { key -> createValue(key)?.let { newMap[key] = it } } removed.forEach { key -> newMap.remove(key) } val resultSet = newMap.values.toSet() State(currentSet, newMap, resultSet) } } .map { it.resultSet } } private companion object { Loading