1 /* <lambda>null2 * 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.shade.data.repository 18 19 import android.content.IntentFilter 20 import android.os.UserHandle 21 import android.safetycenter.SafetyCenterManager 22 import com.android.systemui.broadcast.BroadcastDispatcher 23 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow 24 import com.android.systemui.dagger.SysUISingleton 25 import com.android.systemui.dagger.qualifiers.Application 26 import com.android.systemui.dagger.qualifiers.Background 27 import com.android.systemui.privacy.PrivacyConfig 28 import com.android.systemui.privacy.PrivacyItem 29 import com.android.systemui.privacy.PrivacyItemController 30 import javax.inject.Inject 31 import kotlinx.coroutines.CoroutineDispatcher 32 import kotlinx.coroutines.CoroutineScope 33 import kotlinx.coroutines.channels.awaitClose 34 import kotlinx.coroutines.flow.SharingStarted 35 import kotlinx.coroutines.flow.StateFlow 36 import kotlinx.coroutines.flow.flowOn 37 import kotlinx.coroutines.flow.onStart 38 import kotlinx.coroutines.flow.stateIn 39 40 interface PrivacyChipRepository { 41 /** Whether or not the Safety Center is enabled. */ 42 val isSafetyCenterEnabled: StateFlow<Boolean> 43 44 /** The list of PrivacyItems to be displayed by the privacy chip. */ 45 val privacyItems: StateFlow<List<PrivacyItem>> 46 47 /** Whether or not mic & camera indicators are enabled in the device privacy config. */ 48 val isMicCameraIndicationEnabled: StateFlow<Boolean> 49 50 /** Whether or not location indicators are enabled in the device privacy config. */ 51 val isLocationIndicationEnabled: StateFlow<Boolean> 52 } 53 54 @SysUISingleton 55 class PrivacyChipRepositoryImpl 56 @Inject 57 constructor( 58 @Application applicationScope: CoroutineScope, 59 private val privacyConfig: PrivacyConfig, 60 private val privacyItemController: PrivacyItemController, 61 @Background private val backgroundDispatcher: CoroutineDispatcher, 62 broadcastDispatcher: BroadcastDispatcher, 63 private val safetyCenterManager: SafetyCenterManager, 64 ) : PrivacyChipRepository { 65 override val isSafetyCenterEnabled: StateFlow<Boolean> = 66 broadcastDispatcher 67 .broadcastFlow( 68 filter = <lambda>null69 IntentFilter().apply { 70 addAction(SafetyCenterManager.ACTION_SAFETY_CENTER_ENABLED_CHANGED) 71 }, 72 user = UserHandle.SYSTEM, _null73 map = { _, _ -> safetyCenterManager.isSafetyCenterEnabled } 74 ) <lambda>null75 .onStart { emit(safetyCenterManager.isSafetyCenterEnabled) } 76 .flowOn(backgroundDispatcher) 77 .stateIn( 78 scope = applicationScope, 79 started = SharingStarted.WhileSubscribed(), 80 initialValue = false, 81 ) 82 83 override val privacyItems: StateFlow<List<PrivacyItem>> = <lambda>null84 conflatedCallbackFlow { 85 val callback = 86 object : PrivacyItemController.Callback { 87 override fun onPrivacyItemsChanged(privacyItems: List<PrivacyItem>) { 88 trySend(privacyItems) 89 } 90 } 91 privacyItemController.addCallback(callback) 92 awaitClose { privacyItemController.removeCallback(callback) } 93 } 94 .stateIn( 95 scope = applicationScope, 96 started = SharingStarted.Eagerly, 97 initialValue = emptyList(), 98 ) 99 100 override val isMicCameraIndicationEnabled: StateFlow<Boolean> = <lambda>null101 conflatedCallbackFlow { 102 val callback = 103 object : PrivacyConfig.Callback { 104 override fun onFlagMicCameraChanged(flag: Boolean) { 105 trySend(flag) 106 } 107 } 108 privacyConfig.addCallback(callback) 109 awaitClose { privacyConfig.removeCallback(callback) } 110 } 111 .stateIn( 112 scope = applicationScope, 113 started = SharingStarted.Eagerly, 114 initialValue = privacyItemController.micCameraAvailable, 115 ) 116 117 override val isLocationIndicationEnabled: StateFlow<Boolean> = <lambda>null118 conflatedCallbackFlow { 119 val callback = 120 object : PrivacyConfig.Callback { 121 override fun onFlagLocationChanged(flag: Boolean) { 122 trySend(flag) 123 } 124 } 125 privacyConfig.addCallback(callback) 126 awaitClose { privacyConfig.removeCallback(callback) } 127 } 128 .stateIn( 129 scope = applicationScope, 130 started = SharingStarted.Eagerly, 131 initialValue = privacyItemController.locationAvailable, 132 ) 133 } 134