• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.util.settings.repository
18 
19 import com.android.systemui.dagger.qualifiers.Background
20 import com.android.systemui.user.data.repository.UserRepository
21 import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
22 import com.android.systemui.util.settings.UserSettingsProxy
23 import kotlin.coroutines.CoroutineContext
24 import kotlinx.coroutines.CoroutineDispatcher
25 import kotlinx.coroutines.flow.Flow
26 import kotlinx.coroutines.flow.distinctUntilChanged
27 import kotlinx.coroutines.flow.flatMapLatest
28 import kotlinx.coroutines.flow.flowOn
29 import kotlinx.coroutines.flow.map
30 import kotlinx.coroutines.flow.onStart
31 import kotlinx.coroutines.withContext
32 
33 /**
34  * Repository for observing values of a [UserSettingsProxy], for the currently active user. That
35  * means that when the user is switched and the new user has a different value, the flow will emit
36  * the new value. For any system that tracks the desired user internally (e.g. the Quick Settings
37  * tiles system), use a [SettingsForUserRepository] instead.
38  */
39 // TODO: b/377244768 - Make internal when UserAwareSecureSettingsRepository can be made internal.
40 abstract class UserAwareSettingsRepository(
41     private val userSettings: UserSettingsProxy,
42     private val userRepository: UserRepository,
43     @Background private val backgroundDispatcher: CoroutineDispatcher,
44     @Background private val bgContext: CoroutineContext,
45 ) {
46 
47     fun boolSetting(name: String, defaultValue: Boolean): Flow<Boolean> =
48         userRepository.selectedUserInfo
49             .flatMapLatest { userInfo ->
50                 settingObserver(name, userInfo.id) {
51                     userSettings.getBoolForUser(name, defaultValue, userInfo.id)
52                 }
53             }
54             .distinctUntilChanged()
55             .flowOn(backgroundDispatcher)
56 
57     fun intSetting(name: String, defaultValue: Int): Flow<Int> {
58         return userRepository.selectedUserInfo
59             .flatMapLatest { userInfo ->
60                 settingObserver(name, userInfo.id) {
61                     userSettings.getIntForUser(name, defaultValue, userInfo.id)
62                 }
63             }
64             .distinctUntilChanged()
65             .flowOn(backgroundDispatcher)
66     }
67 
68     private fun <T> settingObserver(name: String, userId: Int, settingsReader: () -> T): Flow<T> {
69         return userSettings
70             .observerFlow(userId, name)
71             .onStart { emit(Unit) }
72             .map { settingsReader.invoke() }
73     }
74 
75     suspend fun setInt(name: String, value: Int) {
76         withContext(bgContext) {
77             userSettings.putIntForUser(name, value, userRepository.getSelectedUserInfo().id)
78         }
79     }
80 
81     suspend fun getInt(name: String, defaultValue: Int): Int {
82         return withContext(bgContext) {
83             userSettings.getIntForUser(name, defaultValue, userRepository.getSelectedUserInfo().id)
84         }
85     }
86 
87     suspend fun setBoolean(name: String, value: Boolean) {
88         withContext(bgContext) {
89             userSettings.putBoolForUser(name, value, userRepository.getSelectedUserInfo().id)
90         }
91     }
92 
93     suspend fun getString(name: String): String? {
94         return withContext(bgContext) {
95             userSettings.getStringForUser(name, userRepository.getSelectedUserInfo().id)
96         }
97     }
98 }
99