Loading packages/SystemUI/multivalentTests/src/com/android/systemui/util/kotlin/BooleanFlowOperatorsTest.kt +31 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos import com.android.systemui.util.kotlin.BooleanFlowOperators.and Loading @@ -27,6 +28,7 @@ import com.android.systemui.util.kotlin.BooleanFlowOperators.not import com.android.systemui.util.kotlin.BooleanFlowOperators.or import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Test Loading Loading @@ -61,6 +63,21 @@ class BooleanFlowOperatorsTest : SysuiTestCase() { assertThat(result).isFalse() } @Test fun and_onlyEmitsWhenValueChanges() = testScope.runTest { val flow1 = MutableStateFlow(false) val flow2 = MutableStateFlow(false) val values by collectValues(and(flow1, flow2)) assertThat(values).containsExactly(false) flow1.value = true // Overall value is still false, we should not have emitted again. assertThat(values).containsExactly(false) flow2.value = true assertThat(values).containsExactly(false, true).inOrder() } @Test fun or_allTrue_returnsTrue() = testScope.runTest { Loading @@ -82,6 +99,20 @@ class BooleanFlowOperatorsTest : SysuiTestCase() { assertThat(result).isFalse() } @Test fun or_onlyEmitsWhenValueChanges() = testScope.runTest { val flow1 = MutableStateFlow(false) val flow2 = MutableStateFlow(false) val values by collectValues(or(flow1, flow2)) assertThat(values).containsExactly(false) flow1.value = true assertThat(values).containsExactly(false, true).inOrder() flow2.value = true assertThat(values).containsExactly(false, true).inOrder() } @Test fun not_true_returnsFalse() = testScope.runTest { Loading packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt +3 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.content.ComponentName import android.os.UserHandle import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.SceneKey import com.android.compose.animation.scene.TransitionKey import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.communal.widgets.WidgetConfigurator Loading Loading @@ -52,8 +53,8 @@ abstract class BaseCommunalViewModel( communalInteractor.signalUserInteraction() } fun changeScene(scene: SceneKey) { communalInteractor.changeScene(scene) fun changeScene(scene: SceneKey, transitionKey: TransitionKey? = null) { communalInteractor.changeScene(scene, transitionKey) } /** Loading packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt +5 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.android.compose.theme.PlatformTheme import com.android.internal.logging.UiEventLogger import com.android.systemui.communal.shared.log.CommunalUiEvent import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.communal.shared.model.CommunalTransitionKeys import com.android.systemui.communal.ui.compose.CommunalHub import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel import com.android.systemui.communal.util.WidgetPickerIntentUtils.getWidgetExtraFromIntent Loading Loading @@ -149,7 +150,10 @@ constructor( private fun onEditDone() { try { communalViewModel.changeScene(CommunalScenes.Communal) communalViewModel.changeScene( CommunalScenes.Communal, CommunalTransitionKeys.SimpleFade ) checkNotNull(windowManagerService).lockNow(/* options */ null) finish() } catch (e: RemoteException) { Loading packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt +3 −1 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.android.systemui.res.R import com.android.systemui.scene.shared.model.SceneDataSourceDelegator import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.phone.SystemUIDialogFactory import com.android.systemui.util.kotlin.BooleanFlowOperators.or import com.android.systemui.util.kotlin.collectFlow import javax.inject.Inject import kotlinx.coroutines.flow.Flow Loading Loading @@ -137,7 +138,8 @@ constructor( private var isDreaming = false /** Returns a flow that tracks whether communal hub is available. */ fun communalAvailable(): Flow<Boolean> = communalInteractor.isCommunalAvailable fun communalAvailable(): Flow<Boolean> = or(communalInteractor.isCommunalAvailable, communalInteractor.editModeOpen) /** * Creates the container view containing the glanceable hub UI. Loading packages/SystemUI/src/com/android/systemui/util/kotlin/BooleanFlowOperators.kt +3 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.util.kotlin import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map object BooleanFlowOperators { Loading @@ -31,7 +32,7 @@ object BooleanFlowOperators { * ``` */ fun and(vararg flows: Flow<Boolean>): Flow<Boolean> = combine(flows.asIterable()) { values -> values.all { it } } combine(flows.asIterable()) { values -> values.all { it } }.distinctUntilChanged() /** * Logical NOT operator for a boolean flow. Loading @@ -48,5 +49,5 @@ object BooleanFlowOperators { * determine the result. */ fun or(vararg flows: Flow<Boolean>): Flow<Boolean> = combine(flows.asIterable()) { values -> values.any { it } } combine(flows.asIterable()) { values -> values.any { it } }.distinctUntilChanged() } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/util/kotlin/BooleanFlowOperatorsTest.kt +31 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos import com.android.systemui.util.kotlin.BooleanFlowOperators.and Loading @@ -27,6 +28,7 @@ import com.android.systemui.util.kotlin.BooleanFlowOperators.not import com.android.systemui.util.kotlin.BooleanFlowOperators.or import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Test Loading Loading @@ -61,6 +63,21 @@ class BooleanFlowOperatorsTest : SysuiTestCase() { assertThat(result).isFalse() } @Test fun and_onlyEmitsWhenValueChanges() = testScope.runTest { val flow1 = MutableStateFlow(false) val flow2 = MutableStateFlow(false) val values by collectValues(and(flow1, flow2)) assertThat(values).containsExactly(false) flow1.value = true // Overall value is still false, we should not have emitted again. assertThat(values).containsExactly(false) flow2.value = true assertThat(values).containsExactly(false, true).inOrder() } @Test fun or_allTrue_returnsTrue() = testScope.runTest { Loading @@ -82,6 +99,20 @@ class BooleanFlowOperatorsTest : SysuiTestCase() { assertThat(result).isFalse() } @Test fun or_onlyEmitsWhenValueChanges() = testScope.runTest { val flow1 = MutableStateFlow(false) val flow2 = MutableStateFlow(false) val values by collectValues(or(flow1, flow2)) assertThat(values).containsExactly(false) flow1.value = true assertThat(values).containsExactly(false, true).inOrder() flow2.value = true assertThat(values).containsExactly(false, true).inOrder() } @Test fun not_true_returnsFalse() = testScope.runTest { Loading
packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt +3 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.content.ComponentName import android.os.UserHandle import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.SceneKey import com.android.compose.animation.scene.TransitionKey import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.communal.widgets.WidgetConfigurator Loading Loading @@ -52,8 +53,8 @@ abstract class BaseCommunalViewModel( communalInteractor.signalUserInteraction() } fun changeScene(scene: SceneKey) { communalInteractor.changeScene(scene) fun changeScene(scene: SceneKey, transitionKey: TransitionKey? = null) { communalInteractor.changeScene(scene, transitionKey) } /** Loading
packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt +5 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.android.compose.theme.PlatformTheme import com.android.internal.logging.UiEventLogger import com.android.systemui.communal.shared.log.CommunalUiEvent import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.communal.shared.model.CommunalTransitionKeys import com.android.systemui.communal.ui.compose.CommunalHub import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel import com.android.systemui.communal.util.WidgetPickerIntentUtils.getWidgetExtraFromIntent Loading Loading @@ -149,7 +150,10 @@ constructor( private fun onEditDone() { try { communalViewModel.changeScene(CommunalScenes.Communal) communalViewModel.changeScene( CommunalScenes.Communal, CommunalTransitionKeys.SimpleFade ) checkNotNull(windowManagerService).lockNow(/* options */ null) finish() } catch (e: RemoteException) { Loading
packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt +3 −1 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.android.systemui.res.R import com.android.systemui.scene.shared.model.SceneDataSourceDelegator import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.phone.SystemUIDialogFactory import com.android.systemui.util.kotlin.BooleanFlowOperators.or import com.android.systemui.util.kotlin.collectFlow import javax.inject.Inject import kotlinx.coroutines.flow.Flow Loading Loading @@ -137,7 +138,8 @@ constructor( private var isDreaming = false /** Returns a flow that tracks whether communal hub is available. */ fun communalAvailable(): Flow<Boolean> = communalInteractor.isCommunalAvailable fun communalAvailable(): Flow<Boolean> = or(communalInteractor.isCommunalAvailable, communalInteractor.editModeOpen) /** * Creates the container view containing the glanceable hub UI. Loading
packages/SystemUI/src/com/android/systemui/util/kotlin/BooleanFlowOperators.kt +3 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.util.kotlin import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map object BooleanFlowOperators { Loading @@ -31,7 +32,7 @@ object BooleanFlowOperators { * ``` */ fun and(vararg flows: Flow<Boolean>): Flow<Boolean> = combine(flows.asIterable()) { values -> values.all { it } } combine(flows.asIterable()) { values -> values.all { it } }.distinctUntilChanged() /** * Logical NOT operator for a boolean flow. Loading @@ -48,5 +49,5 @@ object BooleanFlowOperators { * determine the result. */ fun or(vararg flows: Flow<Boolean>): Flow<Boolean> = combine(flows.asIterable()) { values -> values.any { it } } combine(flows.asIterable()) { values -> values.any { it } }.distinctUntilChanged() }