• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2025 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.display.data.repository
18 
19 import android.view.IWindowManager
20 import com.android.systemui.dagger.SysUISingleton
21 import com.android.systemui.dagger.qualifiers.Background
22 import com.android.systemui.statusbar.CommandQueue
23 import javax.inject.Inject
24 import kotlinx.coroutines.CoroutineScope
25 import kotlinx.coroutines.channels.awaitClose
26 import kotlinx.coroutines.flow.Flow
27 import kotlinx.coroutines.flow.SharingStarted
28 import kotlinx.coroutines.flow.StateFlow
29 import kotlinx.coroutines.flow.callbackFlow
30 import kotlinx.coroutines.flow.distinctUntilChanged
31 import kotlinx.coroutines.flow.map
32 import kotlinx.coroutines.flow.merge
33 import kotlinx.coroutines.flow.scan
34 import kotlinx.coroutines.flow.stateIn
35 
36 /** Provides the displays with decorations. */
37 interface DisplaysWithDecorationsRepository {
38     /** A [StateFlow] that maintains a set of display IDs that should have system decorations. */
39     val displayIdsWithSystemDecorations: StateFlow<Set<Int>>
40 }
41 
42 @SysUISingleton
43 class DisplaysWithDecorationsRepositoryImpl
44 @Inject
45 constructor(
46     private val commandQueue: CommandQueue,
47     private val windowManager: IWindowManager,
48     @Background bgApplicationScope: CoroutineScope,
49     displayRepository: com.android.app.displaylib.DisplayRepository,
50 ) : DisplaysWithDecorationsRepository {
51 
<lambda>null52     private val decorationEvents: Flow<Event> = callbackFlow {
53         val callback =
54             object : CommandQueue.Callbacks {
55                 override fun onDisplayAddSystemDecorations(displayId: Int) {
56                     trySend(Event.Add(displayId))
57                 }
58 
59                 override fun onDisplayRemoveSystemDecorations(displayId: Int) {
60                     trySend(Event.Remove(displayId))
61                 }
62             }
63         commandQueue.addCallback(callback)
64         awaitClose { commandQueue.removeCallback(callback) }
65     }
66 
67     private val initialDisplayIdsWithDecorations: Set<Int> =
68         displayRepository.displayIds.value
<lambda>null69             .filter { windowManager.shouldShowSystemDecors(it) }
70             .toSet()
71 
72     /**
73      * A [StateFlow] that maintains a set of display IDs that should have system decorations.
74      *
75      * Updates to the set are triggered by:
76      * - Adding displays via [CommandQueue.Callbacks.onDisplayAddSystemDecorations].
77      * - Removing displays via [CommandQueue.Callbacks.onDisplayRemoveSystemDecorations].
78      * - Removing displays via [displayRemovalEvent] emissions.
79      *
80      * The set is initialized with displays that qualify for system decorations based on
81      * [WindowManager.shouldShowSystemDecors].
82      */
83     override val displayIdsWithSystemDecorations: StateFlow<Set<Int>> =
<lambda>null84         merge(decorationEvents, displayRepository.displayRemovalEvent.map { Event.Remove(it) })
displayIdsnull85             .scan(initialDisplayIdsWithDecorations) { displayIds: Set<Int>, event: Event ->
86                 when (event) {
87                     is Event.Add -> displayIds + event.displayId
88                     is Event.Remove -> displayIds - event.displayId
89                 }
90             }
91             .distinctUntilChanged()
92             .stateIn(
93                 scope = bgApplicationScope,
94                 started = SharingStarted.WhileSubscribed(),
95                 initialValue = initialDisplayIdsWithDecorations,
96             )
97 
98     private sealed class Event(val displayId: Int) {
99         class Add(displayId: Int) : Event(displayId)
100 
101         class Remove(displayId: Int) : Event(displayId)
102     }
103 }
104