diff options
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, ) } |