Loading packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SecureSettingsRepository.kt +5 −1 Original line number Diff line number Diff line Loading @@ -27,7 +27,11 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.withContext /** Defines interface for classes that can provide access to data from [Settings.Secure]. */ /** * Defines interface for classes that can provide access to data from [Settings.Secure]. * This repository doesn't guarantee to provide value across different users. For that * see: [UserAwareSecureSettingsRepository] */ interface SecureSettingsRepository { /** Returns a [Flow] tracking the value of a setting as an [Int]. */ Loading packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/data/repository/StickyKeysRepository.kt +5 −28 Original line number Diff line number Diff line Loading @@ -32,19 +32,13 @@ import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.ALT_GR import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.CTRL import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.META import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.SHIFT import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.util.settings.SecureSettings import com.android.systemui.util.settings.SettingsProxyExt.observerFlow import com.android.systemui.util.settings.repository.UserAwareSecureSettingsRepository import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart import javax.inject.Inject interface StickyKeysRepository { Loading @@ -53,14 +47,12 @@ interface StickyKeysRepository { } @SysUISingleton @OptIn(ExperimentalCoroutinesApi::class) class StickyKeysRepositoryImpl @Inject constructor( private val inputManager: InputManager, @Background private val backgroundDispatcher: CoroutineDispatcher, private val secureSettings: SecureSettings, userRepository: UserRepository, secureSettingsRepository: UserAwareSecureSettingsRepository, private val stickyKeysLogger: StickyKeysLogger, ) : StickyKeysRepository { Loading @@ -78,25 +70,10 @@ constructor( .flowOn(backgroundDispatcher) override val settingEnabled: Flow<Boolean> = userRepository.selectedUserInfo .flatMapLatest { stickyKeySettingObserver(it.id) } .flowOn(backgroundDispatcher) private fun stickyKeySettingObserver(userId: Int): Flow<Boolean> { return secureSettings .observerFlow(userId, SETTING_KEY) .onStart { emit(Unit) } .map { isSettingEnabledForCurrentUser(userId) } .distinctUntilChanged() secureSettingsRepository .boolSettingForActiveUser(SETTING_KEY, defaultValue = false) .onEach { stickyKeysLogger.logNewSettingValue(it) } } private fun isSettingEnabledForCurrentUser(userId: Int) = secureSettings.getIntForUser( /* name= */ SETTING_KEY, /* default= */ 0, /* userHandle= */ userId ) != 0 .flowOn(backgroundDispatcher) private fun toStickyKeysMap(state: StickyModifierState): LinkedHashMap<ModifierKey, Locked> { val keys = linkedMapOf<ModifierKey, Locked>() Loading packages/SystemUI/src/com/android/systemui/util/settings/SettingsUtilModule.java +8 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.systemui.util.settings; import com.android.systemui.util.settings.repository.UserAwareSecureSettingsRepository; import com.android.systemui.util.settings.repository.UserAwareSecureSettingsRepositoryImpl; import dagger.Binds; import dagger.Module; Loading @@ -36,4 +39,9 @@ public interface SettingsUtilModule { /** Bind GlobalSettingsImpl to GlobalSettings. */ @Binds GlobalSettings bindsGlobalSettings(GlobalSettingsImpl impl); /** Bind UserAwareSecureSettingsRepositoryImpl to UserAwareSecureSettingsRepository. */ @Binds UserAwareSecureSettingsRepository bindsUserAwareSecureSettingsRepository( UserAwareSecureSettingsRepositoryImpl impl); } packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSecureSettingsRepository.kt 0 → 100644 +70 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.util.settings.repository import android.provider.Settings import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.util.settings.SecureSettings import com.android.systemui.util.settings.SettingsProxy import com.android.systemui.util.settings.SettingsProxyExt.observerFlow import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart import javax.inject.Inject /** * Repository for observing values of [Settings.Secure] for the currently active user. That means * when user is switched and the new user has different value, flow will emit new value. */ interface UserAwareSecureSettingsRepository { /** * Emits boolean value of the setting for active user. Also emits starting value when * subscribed. * See: [SettingsProxy.getBool]. */ fun boolSettingForActiveUser(name: String, defaultValue: Boolean = false): Flow<Boolean> } @SysUISingleton @OptIn(ExperimentalCoroutinesApi::class) class UserAwareSecureSettingsRepositoryImpl @Inject constructor( private val secureSettings: SecureSettings, private val userRepository: UserRepository, @Background private val backgroundDispatcher: CoroutineDispatcher, ) : UserAwareSecureSettingsRepository { override fun boolSettingForActiveUser(name: String, defaultValue: Boolean): Flow<Boolean> = userRepository.selectedUserInfo .flatMapLatest { userInfo -> settingObserver(name, defaultValue, userInfo.id) } .distinctUntilChanged() .flowOn(backgroundDispatcher) private fun settingObserver(name: String, defaultValue: Boolean, userId: Int): Flow<Boolean> { return secureSettings .observerFlow(userId, name) .onStart { emit(Unit) } .map { secureSettings.getBoolForUser(name, defaultValue, userId) } } } No newline at end of file packages/SystemUI/tests/src/com/android/systemui/keyboard/stickykeys/ui/viewmodel/StickyKeysIndicatorViewModelTest.kt +7 −2 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.settings.FakeSettings import com.android.systemui.util.settings.repository.UserAwareSecureSettingsRepositoryImpl import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.StandardTestDispatcher Loading Loading @@ -68,11 +69,15 @@ class StickyKeysIndicatorViewModelTest : SysuiTestCase() { @Before fun setup() { val settingsRepository = UserAwareSecureSettingsRepositoryImpl( secureSettings, userRepository, dispatcher ) val stickyKeysRepository = StickyKeysRepositoryImpl( inputManager, dispatcher, secureSettings, userRepository, settingsRepository, mock<StickyKeysLogger>() ) setStickyKeySetting(enabled = false) Loading Loading
packages/SystemUI/customization/src/com/android/systemui/shared/settings/data/repository/SecureSettingsRepository.kt +5 −1 Original line number Diff line number Diff line Loading @@ -27,7 +27,11 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.withContext /** Defines interface for classes that can provide access to data from [Settings.Secure]. */ /** * Defines interface for classes that can provide access to data from [Settings.Secure]. * This repository doesn't guarantee to provide value across different users. For that * see: [UserAwareSecureSettingsRepository] */ interface SecureSettingsRepository { /** Returns a [Flow] tracking the value of a setting as an [Int]. */ Loading
packages/SystemUI/src/com/android/systemui/keyboard/stickykeys/data/repository/StickyKeysRepository.kt +5 −28 Original line number Diff line number Diff line Loading @@ -32,19 +32,13 @@ import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.ALT_GR import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.CTRL import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.META import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.SHIFT import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.util.settings.SecureSettings import com.android.systemui.util.settings.SettingsProxyExt.observerFlow import com.android.systemui.util.settings.repository.UserAwareSecureSettingsRepository import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart import javax.inject.Inject interface StickyKeysRepository { Loading @@ -53,14 +47,12 @@ interface StickyKeysRepository { } @SysUISingleton @OptIn(ExperimentalCoroutinesApi::class) class StickyKeysRepositoryImpl @Inject constructor( private val inputManager: InputManager, @Background private val backgroundDispatcher: CoroutineDispatcher, private val secureSettings: SecureSettings, userRepository: UserRepository, secureSettingsRepository: UserAwareSecureSettingsRepository, private val stickyKeysLogger: StickyKeysLogger, ) : StickyKeysRepository { Loading @@ -78,25 +70,10 @@ constructor( .flowOn(backgroundDispatcher) override val settingEnabled: Flow<Boolean> = userRepository.selectedUserInfo .flatMapLatest { stickyKeySettingObserver(it.id) } .flowOn(backgroundDispatcher) private fun stickyKeySettingObserver(userId: Int): Flow<Boolean> { return secureSettings .observerFlow(userId, SETTING_KEY) .onStart { emit(Unit) } .map { isSettingEnabledForCurrentUser(userId) } .distinctUntilChanged() secureSettingsRepository .boolSettingForActiveUser(SETTING_KEY, defaultValue = false) .onEach { stickyKeysLogger.logNewSettingValue(it) } } private fun isSettingEnabledForCurrentUser(userId: Int) = secureSettings.getIntForUser( /* name= */ SETTING_KEY, /* default= */ 0, /* userHandle= */ userId ) != 0 .flowOn(backgroundDispatcher) private fun toStickyKeysMap(state: StickyModifierState): LinkedHashMap<ModifierKey, Locked> { val keys = linkedMapOf<ModifierKey, Locked>() Loading
packages/SystemUI/src/com/android/systemui/util/settings/SettingsUtilModule.java +8 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.systemui.util.settings; import com.android.systemui.util.settings.repository.UserAwareSecureSettingsRepository; import com.android.systemui.util.settings.repository.UserAwareSecureSettingsRepositoryImpl; import dagger.Binds; import dagger.Module; Loading @@ -36,4 +39,9 @@ public interface SettingsUtilModule { /** Bind GlobalSettingsImpl to GlobalSettings. */ @Binds GlobalSettings bindsGlobalSettings(GlobalSettingsImpl impl); /** Bind UserAwareSecureSettingsRepositoryImpl to UserAwareSecureSettingsRepository. */ @Binds UserAwareSecureSettingsRepository bindsUserAwareSecureSettingsRepository( UserAwareSecureSettingsRepositoryImpl impl); }
packages/SystemUI/src/com/android/systemui/util/settings/repository/UserAwareSecureSettingsRepository.kt 0 → 100644 +70 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.util.settings.repository import android.provider.Settings import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.util.settings.SecureSettings import com.android.systemui.util.settings.SettingsProxy import com.android.systemui.util.settings.SettingsProxyExt.observerFlow import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart import javax.inject.Inject /** * Repository for observing values of [Settings.Secure] for the currently active user. That means * when user is switched and the new user has different value, flow will emit new value. */ interface UserAwareSecureSettingsRepository { /** * Emits boolean value of the setting for active user. Also emits starting value when * subscribed. * See: [SettingsProxy.getBool]. */ fun boolSettingForActiveUser(name: String, defaultValue: Boolean = false): Flow<Boolean> } @SysUISingleton @OptIn(ExperimentalCoroutinesApi::class) class UserAwareSecureSettingsRepositoryImpl @Inject constructor( private val secureSettings: SecureSettings, private val userRepository: UserRepository, @Background private val backgroundDispatcher: CoroutineDispatcher, ) : UserAwareSecureSettingsRepository { override fun boolSettingForActiveUser(name: String, defaultValue: Boolean): Flow<Boolean> = userRepository.selectedUserInfo .flatMapLatest { userInfo -> settingObserver(name, defaultValue, userInfo.id) } .distinctUntilChanged() .flowOn(backgroundDispatcher) private fun settingObserver(name: String, defaultValue: Boolean, userId: Int): Flow<Boolean> { return secureSettings .observerFlow(userId, name) .onStart { emit(Unit) } .map { secureSettings.getBoolForUser(name, defaultValue, userId) } } } No newline at end of file
packages/SystemUI/tests/src/com/android/systemui/keyboard/stickykeys/ui/viewmodel/StickyKeysIndicatorViewModelTest.kt +7 −2 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.settings.FakeSettings import com.android.systemui.util.settings.repository.UserAwareSecureSettingsRepositoryImpl import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.StandardTestDispatcher Loading Loading @@ -68,11 +69,15 @@ class StickyKeysIndicatorViewModelTest : SysuiTestCase() { @Before fun setup() { val settingsRepository = UserAwareSecureSettingsRepositoryImpl( secureSettings, userRepository, dispatcher ) val stickyKeysRepository = StickyKeysRepositoryImpl( inputManager, dispatcher, secureSettings, userRepository, settingsRepository, mock<StickyKeysLogger>() ) setStickyKeySetting(enabled = false) Loading