summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewBinder.kt2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt12
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt91
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/data/repository/SystemStatusEventAnimationRepository.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/domain/interactor/SystemStatusEventAnimationInteractor.kt89
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt114
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt50
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowView.java2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/data/repository/SystemStatusEventAnimationRepositoryKosmos.kt28
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/domain/interactor/SystemStatusEventAnimationInteractorKosmos.kt31
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt2
16 files changed, 434 insertions, 81 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewBinder.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewBinder.kt
index cdc7aa2dea2a..9888574071e6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewBinder.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewBinder.kt
@@ -32,6 +32,8 @@ class FakeHomeStatusBarViewBinder : HomeStatusBarViewBinder {
override fun bind(
view: View,
viewModel: HomeStatusBarViewModel,
+ systemEventChipAnimateIn: ((View) -> Unit)?,
+ systemEventChipAnimateOut: ((View) -> Unit)?,
listener: StatusBarVisibilityChangeListener,
) {
this.listener = listener
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
index 02c1540d3d8b..eef5753cef8a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel
import android.view.View
import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -53,11 +54,14 @@ class FakeHomeStatusBarViewModel : HomeStatusBarViewModel {
)
)
- override val isSystemInfoVisible =
+ override val systemInfoCombinedVis =
MutableStateFlow(
- HomeStatusBarViewModel.VisibilityModel(
- visibility = View.GONE,
- shouldAnimateChange = false,
+ HomeStatusBarViewModel.SystemInfoCombinedVisibilityModel(
+ HomeStatusBarViewModel.VisibilityModel(
+ visibility = View.GONE,
+ shouldAnimateChange = false,
+ ),
+ Idle,
)
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
index b3a73d82122f..c4d2569bba89 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
@@ -60,11 +60,16 @@ import com.android.systemui.statusbar.data.repository.FakeStatusBarModeRepositor
import com.android.systemui.statusbar.data.repository.fakeStatusBarModeRepository
import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel
import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
+import com.android.systemui.statusbar.events.data.repository.systemStatusEventAnimationRepository
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimatingIn
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimatingOut
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle
import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel
import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
+import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel.VisibilityModel
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.emptyFlow
@@ -90,6 +95,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
private val activeNotificationListRepository = kosmos.activeNotificationListRepository
private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
private val disableFlagsRepository = kosmos.fakeDisableFlagsRepository
+ private val systemStatusEventAnimationRepository = kosmos.systemStatusEventAnimationRepository
private lateinit var underTest: HomeStatusBarViewModel
@@ -546,25 +552,50 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
fun isSystemInfoVisible_allowedByDisableFlags_visible() =
testScope.runTest {
- val latest by collectLastValue(underTest.isSystemInfoVisible)
+ val latest by collectLastValue(underTest.systemInfoCombinedVis)
transitionKeyguardToGone()
disableFlagsRepository.disableFlags.value =
DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)
- assertThat(latest!!.visibility).isEqualTo(View.VISIBLE)
+ assertThat(latest!!.baseVisibility.visibility).isEqualTo(View.VISIBLE)
}
@Test
fun isSystemInfoVisible_notAllowedByDisableFlags_gone() =
testScope.runTest {
- val latest by collectLastValue(underTest.isSystemInfoVisible)
+ val latest by collectLastValue(underTest.systemInfoCombinedVis)
transitionKeyguardToGone()
disableFlagsRepository.disableFlags.value =
DisableFlagsModel(DISABLE_SYSTEM_INFO, DISABLE2_NONE)
- assertThat(latest!!.visibility).isEqualTo(View.GONE)
+ assertThat(latest!!.baseVisibility.visibility).isEqualTo(View.GONE)
+ }
+
+ @Test
+ fun systemInfoCombineVis_animationsPassThrough() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.systemInfoCombinedVis)
+ transitionKeyguardToGone()
+
+ assertThat(latest!!.baseVisibility)
+ .isEqualTo(VisibilityModel(visibility = View.VISIBLE, shouldAnimateChange = false))
+ assertThat(latest!!.animationState).isEqualTo(Idle)
+
+ // WHEN the animation state changes, but the visibility state doesn't change
+ systemStatusEventAnimationRepository.animationState.value = AnimatingIn
+
+ // THEN the visibility is the same
+ assertThat(latest!!.baseVisibility)
+ .isEqualTo(VisibilityModel(visibility = View.VISIBLE, shouldAnimateChange = false))
+ // THEN the animation state updates
+ assertThat(latest!!.animationState).isEqualTo(AnimatingIn)
+
+ systemStatusEventAnimationRepository.animationState.value = AnimatingOut
+ assertThat(latest!!.baseVisibility)
+ .isEqualTo(VisibilityModel(visibility = View.VISIBLE, shouldAnimateChange = false))
+ assertThat(latest!!.animationState).isEqualTo(AnimatingOut)
}
@Test
@@ -573,7 +604,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
testScope.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
- val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible)
+ val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.GONE,
@@ -583,7 +614,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
- assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
@Test
@@ -592,13 +623,13 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
testScope.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
- val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible)
+ val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
- assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
@Test
@@ -607,7 +638,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
testScope.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
- val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible)
+ val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.LOCKSCREEN,
@@ -617,7 +648,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
- assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
@Test
@@ -626,13 +657,13 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
testScope.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
- val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible)
+ val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
kosmos.sceneContainerRepository.snapToScene(Scenes.Bouncer)
assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
- assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
@Test
@@ -641,7 +672,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
testScope.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
- val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible)
+ val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
keyguardTransitionRepository.sendTransitionSteps(
from = KeyguardState.LOCKSCREEN,
@@ -651,7 +682,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
assertThat(clockVisible!!.visibility).isEqualTo(View.VISIBLE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.VISIBLE)
- assertThat(systemInfoVisible!!.visibility).isEqualTo(View.VISIBLE)
+ assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.VISIBLE)
}
@Test
@@ -660,14 +691,14 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
testScope.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
- val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible)
+ val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, taskInfo = null)
assertThat(clockVisible!!.visibility).isEqualTo(View.VISIBLE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.VISIBLE)
- assertThat(systemInfoVisible!!.visibility).isEqualTo(View.VISIBLE)
+ assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.VISIBLE)
}
@Test
@@ -676,13 +707,13 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
testScope.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
- val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible)
+ val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
transitionKeyguardToGone()
assertThat(clockVisible!!.visibility).isEqualTo(View.VISIBLE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.VISIBLE)
- assertThat(systemInfoVisible!!.visibility).isEqualTo(View.VISIBLE)
+ assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.VISIBLE)
}
@Test
@@ -691,14 +722,14 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
testScope.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
- val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible)
+ val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
transitionKeyguardToGone()
kosmos.shadeTestUtil.setShadeExpansion(0f)
assertThat(clockVisible!!.visibility).isEqualTo(View.VISIBLE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.VISIBLE)
- assertThat(systemInfoVisible!!.visibility).isEqualTo(View.VISIBLE)
+ assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.VISIBLE)
}
@Test
@@ -707,13 +738,13 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
testScope.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
- val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible)
+ val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
kosmos.sceneContainerRepository.snapToScene(Scenes.Gone)
assertThat(clockVisible!!.visibility).isEqualTo(View.VISIBLE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.VISIBLE)
- assertThat(systemInfoVisible!!.visibility).isEqualTo(View.VISIBLE)
+ assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.VISIBLE)
}
@Test
@@ -722,14 +753,14 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
testScope.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
- val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible)
+ val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
transitionKeyguardToGone()
kosmos.shadeTestUtil.setShadeExpansion(1f)
assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
- assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
@Test
@@ -738,14 +769,14 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
testScope.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
- val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible)
+ val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
transitionKeyguardToGone()
kosmos.sceneContainerRepository.snapToScene(Scenes.Shade)
assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
- assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
@Test
@@ -754,7 +785,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
testScope.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
- val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible)
+ val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
// Secure camera is an occluding activity
keyguardTransitionRepository.sendTransitionSteps(
@@ -766,7 +797,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
- assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
@Test
@@ -775,7 +806,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
testScope.runTest {
val clockVisible by collectLastValue(underTest.isClockVisible)
val notifIconsVisible by collectLastValue(underTest.isNotificationIconContainerVisible)
- val systemInfoVisible by collectLastValue(underTest.isSystemInfoVisible)
+ val systemInfoVisible by collectLastValue(underTest.systemInfoCombinedVis)
kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
// Secure camera is an occluding activity
@@ -784,7 +815,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
assertThat(clockVisible!!.visibility).isEqualTo(View.GONE)
assertThat(notifIconsVisible!!.visibility).isEqualTo(View.GONE)
- assertThat(systemInfoVisible!!.visibility).isEqualTo(View.GONE)
+ assertThat(systemInfoVisible!!.baseVisibility.visibility).isEqualTo(View.GONE)
}
private fun activeNotificationsStore(notifications: List<ActiveNotificationModel>) =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
index 564d52a62cde..1cb4c44d10e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
@@ -27,7 +27,10 @@ import kotlinx.coroutines.flow.StateFlow
interface SystemStatusAnimationScheduler :
CallbackController<SystemStatusAnimationCallback>, Dumpable {
- /** StateFlow holding the current [SystemEventAnimationState] at any time. */
+ /**
+ * The current state of the animation. This can be used from compose functions to coordinate
+ * their animations with the chip
+ */
val animationState: StateFlow<SystemEventAnimationState>
fun onStatusEvent(event: StatusEvent)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/data/repository/SystemStatusEventAnimationRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/data/repository/SystemStatusEventAnimationRepository.kt
new file mode 100644
index 000000000000..971f5d1b04f2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/data/repository/SystemStatusEventAnimationRepository.kt
@@ -0,0 +1,35 @@
+/*
+ * 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.statusbar.events.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState
+import javax.inject.Inject
+import kotlinx.coroutines.flow.StateFlow
+
+/** Repository to expose the [SystemStatusAnimationScheduler] state via flows */
+interface SystemStatusEventAnimationRepository {
+ val animationState: StateFlow<SystemEventAnimationState>
+}
+
+@SysUISingleton
+class SystemStatusEventAnimationRepositoryImpl
+@Inject
+constructor(scheduler: SystemStatusAnimationScheduler) : SystemStatusEventAnimationRepository {
+ override val animationState = scheduler.animationState
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/domain/interactor/SystemStatusEventAnimationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/domain/interactor/SystemStatusEventAnimationInteractor.kt
new file mode 100644
index 000000000000..3e3064223595
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/domain/interactor/SystemStatusEventAnimationInteractor.kt
@@ -0,0 +1,89 @@
+/*
+ * 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.statusbar.events.domain.interactor
+
+import android.view.View
+import androidx.core.animation.Animator
+import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.events.data.repository.SystemStatusEventAnimationRepository
+import com.android.systemui.statusbar.phone.fragment.StatusBarSystemEventDefaultAnimator
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.stateIn
+
+/**
+ * Interactor for dealing with system status event animations. This class can be used to monitor the
+ * current [animationState], and defines some common animation functions that an handle hiding
+ * system chrome in order to make space for the event chips
+ */
+@SysUISingleton
+class SystemStatusEventAnimationInteractor
+@Inject
+constructor(
+ repo: SystemStatusEventAnimationRepository,
+ configurationInteractor: ConfigurationInteractor,
+ @Application scope: CoroutineScope,
+) {
+ private val chipAnimateInTranslationX =
+ configurationInteractor
+ .dimensionPixelSize(R.dimen.ongoing_appops_chip_animation_in_status_bar_translation_x)
+ .stateIn(scope, SharingStarted.Eagerly, 0)
+
+ private val chipAnimateOutTranslationX =
+ configurationInteractor
+ .dimensionPixelSize(R.dimen.ongoing_appops_chip_animation_out_status_bar_translation_x)
+ .stateIn(scope, SharingStarted.Eagerly, 0)
+
+ val animationState = repo.animationState
+
+ private fun getDefaultStatusBarAnimationForChipEnter(
+ setX: (Float) -> Unit,
+ setAlpha: (Float) -> Unit,
+ ): Animator {
+ return StatusBarSystemEventDefaultAnimator.getDefaultStatusBarAnimationForChipEnter(
+ chipAnimateInTranslationX.value,
+ setX,
+ setAlpha,
+ )
+ }
+
+ private fun getDefaultStatusBarAnimationForChipExit(
+ setX: (Float) -> Unit,
+ setAlpha: (Float) -> Unit,
+ ): Animator {
+ return StatusBarSystemEventDefaultAnimator.getDefaultStatusBarAnimationForChipExit(
+ chipAnimateOutTranslationX.value,
+ setX,
+ setAlpha,
+ )
+ }
+
+ fun animateStatusBarContentForChipEnter(v: View) {
+ getDefaultStatusBarAnimationForChipEnter(setX = v::setTranslationX, setAlpha = v::setAlpha)
+ .start()
+ }
+
+ fun animateStatusBarContentForChipExit(v: View) {
+ v.translationX = chipAnimateOutTranslationX.value.toFloat()
+ getDefaultStatusBarAnimationForChipExit(setX = v::setTranslationX, setAlpha = v::setAlpha)
+ .start()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index c55a63c9edf5..23b4b65bb2ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -376,7 +376,11 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
mCarrierConfigTracker.addDefaultDataSubscriptionChangedListener(mDefaultDataListener);
mHomeStatusBarViewBinder.bind(
- mStatusBar, mHomeStatusBarViewModel, mStatusBarVisibilityChangeListener);
+ mStatusBar,
+ mHomeStatusBarViewModel,
+ /* systemEventChipAnimateIn */ null,
+ /* systemEventChipAnimateOut */ null,
+ mStatusBarVisibilityChangeListener);
}
private String getDumpableName() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
index 1f9ea08e602f..fd7bce099d81 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
@@ -71,49 +71,87 @@ constructor(
override fun onSystemEventAnimationBegin(): Animator {
isAnimationRunning = true
- val moveOut =
- ValueAnimator.ofFloat(0f, 1f).apply {
- duration = 23.frames
- interpolator = STATUS_BAR_X_MOVE_OUT
- addUpdateListener {
- onTranslationXChanged(-(translationXIn * animatedValue as Float))
- }
- }
- val alphaOut =
- ValueAnimator.ofFloat(1f, 0f).apply {
- duration = 8.frames
- interpolator = null
- addUpdateListener { onAlphaChanged(animatedValue as Float) }
- }
-
- val animSet = AnimatorSet()
- animSet.playTogether(moveOut, alphaOut)
- return animSet
+ return getDefaultStatusBarAnimationForChipEnter(
+ translationXIn,
+ onTranslationXChanged,
+ onAlphaChanged,
+ )
}
override fun onSystemEventAnimationFinish(hasPersistentDot: Boolean): Animator {
onTranslationXChanged(translationXOut.toFloat())
- val moveIn =
- ValueAnimator.ofFloat(1f, 0f).apply {
- duration = 23.frames
- startDelay = 7.frames
- interpolator = STATUS_BAR_X_MOVE_IN
- addUpdateListener {
- onTranslationXChanged(translationXOut * animatedValue as Float)
+ val anim =
+ getDefaultStatusBarAnimationForChipExit(
+ translationXOut,
+ onTranslationXChanged,
+ onAlphaChanged,
+ )
+ anim.doOnEnd { isAnimationRunning = false }
+ anim.doOnCancel { isAnimationRunning = false }
+
+ return anim
+ }
+
+ /** Static definition of these animations so we can use them more easily from view binders */
+ companion object {
+ /**
+ * Chip: coming in. Animated view: going out.
+ *
+ * Implements the exact spec for animating any status bar elements OUT to make space for the
+ * chip IN animation.
+ */
+ fun getDefaultStatusBarAnimationForChipEnter(
+ targetTranslation: Int,
+ setX: (Float) -> Unit,
+ setAlpha: (Float) -> Unit,
+ ): Animator {
+ val moveOut =
+ ValueAnimator.ofFloat(0f, 1f).apply {
+ duration = 23.frames
+ interpolator = STATUS_BAR_X_MOVE_OUT
+ addUpdateListener { setX(-(targetTranslation * animatedValue as Float)) }
+ }
+ val alphaOut =
+ ValueAnimator.ofFloat(1f, 0f).apply {
+ duration = 8.frames
+ interpolator = null
+ addUpdateListener { setAlpha(animatedValue as Float) }
+ }
+
+ val animSet = AnimatorSet()
+ animSet.playTogether(moveOut, alphaOut)
+ return animSet
+ }
+
+ /**
+ * Chip: going out. Animated view: coming in.
+ *
+ * Implements the exact spec for animating any status bar elements IN as the chip is
+ * animating OUT
+ */
+ fun getDefaultStatusBarAnimationForChipExit(
+ targetTranslation: Int,
+ setX: (Float) -> Unit,
+ setAlpha: (Float) -> Unit,
+ ): Animator {
+ val moveIn =
+ ValueAnimator.ofFloat(1f, 0f).apply {
+ duration = 23.frames
+ startDelay = 7.frames
+ interpolator = STATUS_BAR_X_MOVE_IN
+ addUpdateListener { setX(targetTranslation * animatedValue as Float) }
+ }
+ val alphaIn =
+ ValueAnimator.ofFloat(0f, 1f).apply {
+ duration = 5.frames
+ startDelay = 11.frames
+ interpolator = null
+ addUpdateListener { setAlpha(animatedValue as Float) }
}
- }
- val alphaIn =
- ValueAnimator.ofFloat(0f, 1f).apply {
- duration = 5.frames
- startDelay = 11.frames
- interpolator = null
- addUpdateListener { onAlphaChanged(animatedValue as Float) }
- }
- val animatorSet = AnimatorSet()
- animatorSet.playTogether(moveIn, alphaIn)
- animatorSet.doOnEnd { isAnimationRunning = false }
- animatorSet.doOnCancel { isAnimationRunning = false }
- return animatorSet
+ val animatorSet = AnimatorSet()
+ animatorSet.playTogether(moveIn, alphaIn)
+ return animatorSet
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
index 935b1012be31..bfdc8bd5e4c8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
@@ -23,6 +23,8 @@ import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogBufferFactory
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.log.table.TableLogBufferFactory
+import com.android.systemui.statusbar.events.data.repository.SystemStatusEventAnimationRepository
+import com.android.systemui.statusbar.events.data.repository.SystemStatusEventAnimationRepositoryImpl
import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepository
import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepositoryImpl
import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModel
@@ -85,6 +87,11 @@ abstract class StatusBarPipelineModule {
abstract fun connectivityRepository(impl: ConnectivityRepositoryImpl): ConnectivityRepository
@Binds
+ abstract fun systemStatusEventAnimationRepository(
+ impl: SystemStatusEventAnimationRepositoryImpl
+ ): SystemStatusEventAnimationRepository
+
+ @Binds
abstract fun realDeviceBasedSatelliteRepository(
impl: DeviceBasedSatelliteRepositoryImpl
): RealDeviceBasedSatelliteRepository
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
index 2177e025b976..72df02714d43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
@@ -32,6 +32,10 @@ import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifCh
import com.android.systemui.statusbar.chips.ui.binder.OngoingActivityChipBinder
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.core.StatusBarRootModernization
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimatingIn
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimatingOut
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.RunningChipAnim
import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel
@@ -46,10 +50,16 @@ interface HomeStatusBarViewBinder {
/**
* Binds the view to the view-model. [listener] will be notified whenever an event that may
* change the status bar visibility occurs.
+ *
+ * Null chip animations are used when [StatusBarRootModernization] is off (i.e., when we are
+ * binding from the fragment). If non-null, they control the animation of the system icon area
+ * to support the chip animations.
*/
fun bind(
view: View,
viewModel: HomeStatusBarViewModel,
+ systemEventChipAnimateIn: ((View) -> Unit)?,
+ systemEventChipAnimateOut: ((View) -> Unit)?,
listener: StatusBarVisibilityChangeListener,
)
}
@@ -59,6 +69,8 @@ class HomeStatusBarViewBinderImpl @Inject constructor() : HomeStatusBarViewBinde
override fun bind(
view: View,
viewModel: HomeStatusBarViewModel,
+ systemEventChipAnimateIn: ((View) -> Unit)?,
+ systemEventChipAnimateOut: ((View) -> Unit)?,
listener: StatusBarVisibilityChangeListener,
) {
view.repeatWhenAttached {
@@ -95,6 +107,7 @@ class HomeStatusBarViewBinderImpl @Inject constructor() : HomeStatusBarViewBinde
when (primaryChipModel) {
is OngoingActivityChipModel.Shown ->
primaryChipView.show(shouldAnimateChange = true)
+
is OngoingActivityChipModel.Hidden ->
primaryChipView.hide(
state = View.GONE,
@@ -109,6 +122,7 @@ class HomeStatusBarViewBinderImpl @Inject constructor() : HomeStatusBarViewBinde
hasSecondaryOngoingActivity = false,
shouldAnimate = true,
)
+
is OngoingActivityChipModel.Hidden ->
listener.onOngoingActivityStatusChanged(
hasPrimaryOngoingActivity = false,
@@ -175,10 +189,30 @@ class HomeStatusBarViewBinderImpl @Inject constructor() : HomeStatusBarViewBinde
view.requireViewById<View>(R.id.status_bar_end_side_content)
// TODO(b/364360986): Also handle operator name view.
launch {
- viewModel.isSystemInfoVisible.collect {
- systemInfoView.adjustVisibility(it)
- // TODO(b/364360986): The system info view has a custom alpha controller
- // in CollapsedStatusBarFragment.
+ viewModel.systemInfoCombinedVis.collect { (baseVis, animState) ->
+ // Broadly speaking, the baseVis controls the view.visibility, and
+ // the animation state uses only alpha to achieve its effect. This
+ // means that we can always modify the visibility, and if we're
+ // animating we can use the animState to handle it. If we are not
+ // animating, then we can use the baseVis default animation
+ if (animState.isAnimatingChip()) {
+ // Just apply the visibility of the view, but don't animate
+ systemInfoView.visibility = baseVis.visibility
+ // Now apply the animation state, with its animator
+ when (animState) {
+ AnimatingIn -> {
+ systemEventChipAnimateIn?.invoke(systemInfoView)
+ }
+ AnimatingOut -> {
+ systemEventChipAnimateOut?.invoke(systemInfoView)
+ }
+ else -> {
+ // Nothing to do here
+ }
+ }
+ } else {
+ systemInfoView.adjustVisibility(baseVis)
+ }
}
}
}
@@ -186,6 +220,14 @@ class HomeStatusBarViewBinderImpl @Inject constructor() : HomeStatusBarViewBinde
}
}
+ private fun SystemEventAnimationState.isAnimatingChip() =
+ when (this) {
+ AnimatingIn,
+ AnimatingOut,
+ RunningChipAnim -> true
+ else -> false
+ }
+
private fun OngoingActivityChipModel.toVisibilityModel(): VisibilityModel {
return VisibilityModel(
visibility = if (this is OngoingActivityChipModel.Shown) View.VISIBLE else View.GONE,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
index a9c2f72f7b18..1faa9f32af1f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
@@ -35,6 +35,7 @@ import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.plugins.DarkIconDispatcher
import com.android.systemui.res.R
import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore
+import com.android.systemui.statusbar.events.domain.interactor.SystemStatusEventAnimationInteractor
import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder
import com.android.systemui.statusbar.phone.NotificationIconContainer
import com.android.systemui.statusbar.phone.PhoneStatusBarView
@@ -59,6 +60,7 @@ constructor(
private val iconController: StatusBarIconController,
private val ongoingCallController: OngoingCallController,
private val darkIconDispatcherStore: DarkIconDispatcherStore,
+ private val eventAnimationInteractor: SystemStatusEventAnimationInteractor,
) {
fun create(root: ViewGroup, andThen: (ViewGroup) -> Unit): ComposeView {
val composeView = ComposeView(root.context)
@@ -73,6 +75,7 @@ constructor(
iconController = iconController,
ongoingCallController = ongoingCallController,
darkIconDispatcher = darkIconDispatcherStore.forDisplay(root.context.displayId),
+ eventAnimationInteractor = eventAnimationInteractor,
onViewCreated = andThen,
)
}
@@ -102,6 +105,7 @@ fun StatusBarRoot(
iconController: StatusBarIconController,
ongoingCallController: OngoingCallController,
darkIconDispatcher: DarkIconDispatcher,
+ eventAnimationInteractor: SystemStatusEventAnimationInteractor,
onViewCreated: (ViewGroup) -> Unit,
) {
// None of these methods are used when [StatusBarRootModernization] is on.
@@ -181,6 +185,8 @@ fun StatusBarRoot(
statusBarViewBinder.bind(
phoneStatusBarView,
statusBarViewModel,
+ eventAnimationInteractor::animateStatusBarContentForChipEnter,
+ eventAnimationInteractor::animateStatusBarContentForChipExit,
nopVisibilityChangeListener,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
index 4277a8be64d3..6a9b43c995e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
@@ -35,6 +35,9 @@ import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModel
+import com.android.systemui.statusbar.events.domain.interactor.SystemStatusEventAnimationInteractor
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
import com.android.systemui.statusbar.phone.domain.interactor.LightsOutInteractor
@@ -95,7 +98,12 @@ interface HomeStatusBarViewModel {
val isClockVisible: Flow<VisibilityModel>
val isNotificationIconContainerVisible: Flow<VisibilityModel>
- val isSystemInfoVisible: Flow<VisibilityModel>
+ /**
+ * Pair of (system info visibility, event animation state). The animation state can be used to
+ * respond to the system event chip animations. In all cases, system info visibility correctly
+ * models the View.visibility for the system info area
+ */
+ val systemInfoCombinedVis: StateFlow<SystemInfoCombinedVisibilityModel>
/**
* Apps can request a low profile mode [android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE] where
@@ -114,6 +122,12 @@ interface HomeStatusBarViewModel {
/** True if a visibility change should be animated. */
val shouldAnimateChange: Boolean,
)
+
+ /** The combined visibility + animation state for the system info status bar area */
+ data class SystemInfoCombinedVisibilityModel(
+ val baseVisibility: VisibilityModel,
+ val animationState: SystemEventAnimationState,
+ )
}
@SysUISingleton
@@ -129,6 +143,7 @@ constructor(
sceneContainerOcclusionInteractor: SceneContainerOcclusionInteractor,
shadeInteractor: ShadeInteractor,
ongoingActivityChipsViewModel: OngoingActivityChipsViewModel,
+ animations: SystemStatusEventAnimationInteractor,
@Application coroutineScope: CoroutineScope,
) : HomeStatusBarViewModel {
override val isTransitioningFromLockscreenToOccluded: StateFlow<Boolean> =
@@ -228,7 +243,7 @@ constructor(
visibilityViaDisableFlags.animate,
)
}
- override val isSystemInfoVisible: Flow<VisibilityModel> =
+ private val isSystemInfoVisible =
combine(
shouldHomeStatusBarBeVisible,
collapsedStatusBarInteractor.visibilityViaDisableFlags,
@@ -238,6 +253,22 @@ constructor(
VisibilityModel(showSystemInfo.toVisibilityInt(), visibilityViaDisableFlags.animate)
}
+ override val systemInfoCombinedVis =
+ combine(isSystemInfoVisible, animations.animationState) { sysInfoVisible, animationState ->
+ HomeStatusBarViewModel.SystemInfoCombinedVisibilityModel(
+ sysInfoVisible,
+ animationState,
+ )
+ }
+ .stateIn(
+ coroutineScope,
+ SharingStarted.WhileSubscribed(),
+ HomeStatusBarViewModel.SystemInfoCombinedVisibilityModel(
+ VisibilityModel(View.VISIBLE, false),
+ Idle,
+ ),
+ )
+
@View.Visibility
private fun Boolean.toVisibilityInt(): Int {
return if (this) View.VISIBLE else View.GONE
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowView.java
index b79d39e65682..36d64a9b405e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowView.java
@@ -39,7 +39,7 @@ import com.android.systemui.statusbar.core.StatusBarRootModernization;
import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController;
/**
- * Status bar view.
+ * Status bar view
* We now extend WindowRootView so that we can host Compose views
*/
public class StatusBarWindowView extends FrameLayout {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/data/repository/SystemStatusEventAnimationRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/data/repository/SystemStatusEventAnimationRepositoryKosmos.kt
new file mode 100644
index 000000000000..92eeef97f7c4
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/data/repository/SystemStatusEventAnimationRepositoryKosmos.kt
@@ -0,0 +1,28 @@
+/*
+ * 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.statusbar.events.data.repository
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState
+import kotlinx.coroutines.flow.MutableStateFlow
+
+val Kosmos.systemStatusEventAnimationRepository: FakeSystemStatusEventAnimationRepository by
+ Kosmos.Fixture { FakeSystemStatusEventAnimationRepository() }
+
+class FakeSystemStatusEventAnimationRepository : SystemStatusEventAnimationRepository {
+ override val animationState = MutableStateFlow(SystemEventAnimationState.Idle)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/domain/interactor/SystemStatusEventAnimationInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/domain/interactor/SystemStatusEventAnimationInteractorKosmos.kt
new file mode 100644
index 000000000000..7513fead0187
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/events/domain/interactor/SystemStatusEventAnimationInteractorKosmos.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.statusbar.events.domain.interactor
+
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.statusbar.events.data.repository.systemStatusEventAnimationRepository
+
+val Kosmos.systemStatusEventAnimationInteractor by
+ Kosmos.Fixture {
+ SystemStatusEventAnimationInteractor(
+ repo = systemStatusEventAnimationRepository,
+ configurationInteractor = configurationInteractor,
+ scope = applicationCoroutineScope,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
index 3a7ada2e61b8..03e4c894c2f2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
@@ -24,6 +24,7 @@ import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInter
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.chips.ui.viewmodel.ongoingActivityChipsViewModel
+import com.android.systemui.statusbar.events.domain.interactor.systemStatusEventAnimationInteractor
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.statusbar.phone.domain.interactor.lightsOutInteractor
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.collapsedStatusBarInteractor
@@ -40,6 +41,7 @@ val Kosmos.homeStatusBarViewModel: HomeStatusBarViewModel by
sceneContainerOcclusionInteractor,
shadeInteractor,
ongoingActivityChipsViewModel,
+ systemStatusEventAnimationInteractor,
applicationCoroutineScope,
)
}