1 /* 2 * Copyright (C) 2024 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.annotation.MainThread 20 import android.view.Display.DEFAULT_DISPLAY 21 import com.android.systemui.dagger.SysUISingleton 22 import com.android.systemui.dagger.qualifiers.Background 23 import com.android.systemui.log.LogBuffer 24 import com.android.systemui.log.core.LogLevel 25 import com.android.systemui.log.dagger.FocusedDisplayRepoLog 26 import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow 27 import com.android.wm.shell.shared.FocusTransitionListener 28 import com.android.wm.shell.shared.ShellTransitions 29 import java.util.concurrent.Executor 30 import javax.inject.Inject 31 import kotlinx.coroutines.CoroutineScope 32 import kotlinx.coroutines.channels.awaitClose 33 import kotlinx.coroutines.flow.Flow 34 import kotlinx.coroutines.flow.SharingStarted 35 import kotlinx.coroutines.flow.StateFlow 36 import kotlinx.coroutines.flow.onEach 37 import kotlinx.coroutines.flow.stateIn 38 39 /** Repository tracking display focus. */ 40 interface FocusedDisplayRepository { 41 /** Provides the currently focused display. */ 42 val focusedDisplayId: StateFlow<Int> 43 } 44 45 @SysUISingleton 46 @MainThread 47 class FocusedDisplayRepositoryImpl 48 @Inject 49 constructor( 50 @Background val backgroundScope: CoroutineScope, 51 @Background private val backgroundExecutor: Executor, 52 transitions: ShellTransitions, 53 @FocusedDisplayRepoLog logBuffer: LogBuffer, 54 ) : FocusedDisplayRepository { 55 val focusedTask: Flow<Int> = <lambda>null56 conflatedCallbackFlow<Int> { 57 val listener = 58 object : FocusTransitionListener { 59 override fun onFocusedDisplayChanged(displayId: Int) { 60 trySend(displayId) 61 } 62 } 63 transitions.setFocusTransitionListener(listener, backgroundExecutor) 64 awaitClose { transitions.unsetFocusTransitionListener(listener) } 65 } <lambda>null66 .onEach { 67 logBuffer.log( 68 "FocusedDisplayRepository", 69 LogLevel.INFO, 70 { str1 = it.toString() }, 71 { "Newly focused display: $str1" }, 72 ) 73 } 74 75 override val focusedDisplayId: StateFlow<Int> 76 get() = focusedTask.stateIn(backgroundScope, SharingStarted.Eagerly, DEFAULT_DISPLAY) 77 } 78