Loading packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt +15 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import com.android.systemui.settings.fakeUserTracker import com.android.systemui.testKosmos import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.util.settings.fakeSettings import com.google.common.truth.Truth.assertThat import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull Loading Loading @@ -102,6 +103,20 @@ class CommunalSettingsInteractorTest : SysuiTestCase() { assertEquals(startCondition, WhenToStartHub.WHILE_CHARGING) } @Test fun allowedForCurrentUserByDevicePolicy_reportsFalseWithPartialUserInfo() = kosmos.runTest { val lastValue by collectLastValue(underTest.allowedForCurrentUserByDevicePolicy) assertThat(lastValue).isTrue() val userInfo = UserInfo(fakeUserRepository.getMainUser()) userInfo.partial = true fakeUserRepository.setUserInfos(listOf(userInfo)) assertThat(lastValue).isFalse() } private fun setKeyguardFeaturesDisabled(user: UserInfo, disabledFlags: Int) { whenever( kosmos.devicePolicyManager.getKeyguardDisabledFeatures( Loading packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt +13 −4 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.android.systemui.communal.shared.model.CommunalBackgroundType import com.android.systemui.communal.shared.model.WhenToStartHub import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.process.domain.interactor.ProcessInteractor import com.android.systemui.settings.UserTracker import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow Loading @@ -52,6 +53,7 @@ constructor( @Background private val bgDispatcher: CoroutineDispatcher, @Background private val bgExecutor: Executor, private val repository: CommunalSettingsRepository, private val processInteractor: ProcessInteractor, userInteractor: SelectedUserInteractor, private val userTracker: UserTracker, ) { Loading Loading @@ -82,7 +84,7 @@ constructor( /** Whether communal hub is allowed by device policy for the current user */ val allowedForCurrentUserByDevicePolicy: Flow<Boolean> = userInteractor.selectedUserInfo.flatMapLatestConflated { user -> repository.getAllowedByDevicePolicy(user) getAllowedByDevicePolicy(user) } /** Whether the hub is enabled for the current user */ Loading Loading @@ -159,9 +161,7 @@ constructor( workProfileUserInfoCallbackFlow .flatMapLatest { workProfile -> workProfile?.let { repository.getAllowedByDevicePolicy(it).map { allowed -> if (!allowed) it else null } getAllowedByDevicePolicy(it).map { allowed -> if (!allowed) it else null } } ?: flowOf(null) } .stateIn( Loading @@ -169,4 +169,13 @@ constructor( started = SharingStarted.WhileSubscribed(), initialValue = null, ) private fun getAllowedByDevicePolicy(user: UserInfo): Flow<Boolean> = processInteractor.processUserReady.flatMapLatestConflated { ready -> if (ready) { repository.getAllowedByDevicePolicy(user) } else { flowOf(false) } } } packages/SystemUI/src/com/android/systemui/process/domain/interactor/ProcessInteractor.kt 0 → 100644 +48 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.process.domain.interactor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.process.ProcessWrapper import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOn @SysUISingleton class ProcessInteractor @Inject constructor( userRepository: UserRepository, private val processWrapper: ProcessWrapper, @Background val bgDispatcher: CoroutineDispatcher, ) { val processUserReady: Flow<Boolean> = userRepository.userInfos .flatMapLatestConflated { infos -> flowOf( infos.count { info -> !info.partial && info.userHandle == processWrapper.myUserHandle() } > 0 ) } .flowOn(bgDispatcher) } packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.testDispatcher import com.android.systemui.process.domain.interactor.processInteractor import com.android.systemui.settings.userTracker import com.android.systemui.user.domain.interactor.selectedUserInteractor Loading @@ -32,6 +33,7 @@ val Kosmos.communalSettingsInteractor by Fixture { bgDispatcher = testDispatcher, repository = communalSettingsRepository, userInteractor = selectedUserInteractor, processInteractor = processInteractor, userTracker = userTracker, ) } packages/SystemUI/tests/utils/src/com/android/systemui/process/domain/interactor/ProcessInteractorKosmos.kt 0 → 100644 +31 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.process.domain.interactor import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.testDispatcher import com.android.systemui.process.processWrapper import com.android.systemui.user.data.repository.userRepository val Kosmos.processInteractor by Fixture { ProcessInteractor( userRepository = userRepository, processWrapper = processWrapper, bgDispatcher = testDispatcher, ) } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt +15 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import com.android.systemui.settings.fakeUserTracker import com.android.systemui.testKosmos import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.util.settings.fakeSettings import com.google.common.truth.Truth.assertThat import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull Loading Loading @@ -102,6 +103,20 @@ class CommunalSettingsInteractorTest : SysuiTestCase() { assertEquals(startCondition, WhenToStartHub.WHILE_CHARGING) } @Test fun allowedForCurrentUserByDevicePolicy_reportsFalseWithPartialUserInfo() = kosmos.runTest { val lastValue by collectLastValue(underTest.allowedForCurrentUserByDevicePolicy) assertThat(lastValue).isTrue() val userInfo = UserInfo(fakeUserRepository.getMainUser()) userInfo.partial = true fakeUserRepository.setUserInfos(listOf(userInfo)) assertThat(lastValue).isFalse() } private fun setKeyguardFeaturesDisabled(user: UserInfo, disabledFlags: Int) { whenever( kosmos.devicePolicyManager.getKeyguardDisabledFeatures( Loading
packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt +13 −4 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.android.systemui.communal.shared.model.CommunalBackgroundType import com.android.systemui.communal.shared.model.WhenToStartHub import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.process.domain.interactor.ProcessInteractor import com.android.systemui.settings.UserTracker import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow Loading @@ -52,6 +53,7 @@ constructor( @Background private val bgDispatcher: CoroutineDispatcher, @Background private val bgExecutor: Executor, private val repository: CommunalSettingsRepository, private val processInteractor: ProcessInteractor, userInteractor: SelectedUserInteractor, private val userTracker: UserTracker, ) { Loading Loading @@ -82,7 +84,7 @@ constructor( /** Whether communal hub is allowed by device policy for the current user */ val allowedForCurrentUserByDevicePolicy: Flow<Boolean> = userInteractor.selectedUserInfo.flatMapLatestConflated { user -> repository.getAllowedByDevicePolicy(user) getAllowedByDevicePolicy(user) } /** Whether the hub is enabled for the current user */ Loading Loading @@ -159,9 +161,7 @@ constructor( workProfileUserInfoCallbackFlow .flatMapLatest { workProfile -> workProfile?.let { repository.getAllowedByDevicePolicy(it).map { allowed -> if (!allowed) it else null } getAllowedByDevicePolicy(it).map { allowed -> if (!allowed) it else null } } ?: flowOf(null) } .stateIn( Loading @@ -169,4 +169,13 @@ constructor( started = SharingStarted.WhileSubscribed(), initialValue = null, ) private fun getAllowedByDevicePolicy(user: UserInfo): Flow<Boolean> = processInteractor.processUserReady.flatMapLatestConflated { ready -> if (ready) { repository.getAllowedByDevicePolicy(user) } else { flowOf(false) } } }
packages/SystemUI/src/com/android/systemui/process/domain/interactor/ProcessInteractor.kt 0 → 100644 +48 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.process.domain.interactor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.process.ProcessWrapper import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOn @SysUISingleton class ProcessInteractor @Inject constructor( userRepository: UserRepository, private val processWrapper: ProcessWrapper, @Background val bgDispatcher: CoroutineDispatcher, ) { val processUserReady: Flow<Boolean> = userRepository.userInfos .flatMapLatestConflated { infos -> flowOf( infos.count { info -> !info.partial && info.userHandle == processWrapper.myUserHandle() } > 0 ) } .flowOn(bgDispatcher) }
packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.testDispatcher import com.android.systemui.process.domain.interactor.processInteractor import com.android.systemui.settings.userTracker import com.android.systemui.user.domain.interactor.selectedUserInteractor Loading @@ -32,6 +33,7 @@ val Kosmos.communalSettingsInteractor by Fixture { bgDispatcher = testDispatcher, repository = communalSettingsRepository, userInteractor = selectedUserInteractor, processInteractor = processInteractor, userTracker = userTracker, ) }
packages/SystemUI/tests/utils/src/com/android/systemui/process/domain/interactor/ProcessInteractorKosmos.kt 0 → 100644 +31 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.process.domain.interactor import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.testDispatcher import com.android.systemui.process.processWrapper import com.android.systemui.user.data.repository.userRepository val Kosmos.processInteractor by Fixture { ProcessInteractor( userRepository = userRepository, processWrapper = processWrapper, bgDispatcher = testDispatcher, ) }