Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java +3 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment; import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger; import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent; import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.window.StatusBarWindowStateController; import com.android.systemui.util.CarrierConfigTracker; Loading Loading @@ -156,6 +157,7 @@ public abstract class StatusBarViewModule { FeatureFlags featureFlags, StatusBarIconController statusBarIconController, StatusBarIconController.DarkIconManager.Factory darkIconManagerFactory, CollapsedStatusBarViewModel collapsedStatusBarViewModel, StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager, KeyguardStateController keyguardStateController, ShadeViewController shadeViewController, Loading @@ -179,6 +181,7 @@ public abstract class StatusBarViewModule { featureFlags, statusBarIconController, darkIconManagerFactory, collapsedStatusBarViewModel, statusBarHideIconsForBouncerManager, keyguardStateController, shadeViewController, Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java +27 −2 Original line number Diff line number Diff line Loading @@ -68,6 +68,8 @@ import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentCom import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent.Startable; import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener; import com.android.systemui.statusbar.pipeline.shared.ui.binder.CollapsedStatusBarViewBinder; import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.window.StatusBarWindowStateController; import com.android.systemui.statusbar.window.StatusBarWindowStateListener; Loading Loading @@ -128,6 +130,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue private final ShadeExpansionStateManager mShadeExpansionStateManager; private final StatusBarIconController mStatusBarIconController; private final CarrierConfigTracker mCarrierConfigTracker; private final CollapsedStatusBarViewModel mCollapsedStatusBarViewModel; private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager; private final StatusBarIconController.DarkIconManager.Factory mDarkIconManagerFactory; private final SecureSettings mSecureSettings; Loading Loading @@ -197,6 +200,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue FeatureFlags featureFlags, StatusBarIconController statusBarIconController, StatusBarIconController.DarkIconManager.Factory darkIconManagerFactory, CollapsedStatusBarViewModel collapsedStatusBarViewModel, StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager, KeyguardStateController keyguardStateController, ShadeViewController shadeViewController, Loading @@ -219,6 +223,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue mShadeExpansionStateManager = shadeExpansionStateManager; mFeatureFlags = featureFlags; mStatusBarIconController = statusBarIconController; mCollapsedStatusBarViewModel = collapsedStatusBarViewModel; mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager; mDarkIconManagerFactory = darkIconManagerFactory; mKeyguardStateController = keyguardStateController; Loading Loading @@ -290,6 +295,9 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue new StatusBarSystemEventAnimator(mEndSideContent, getResources()); mCarrierConfigTracker.addCallback(mCarrierConfigCallback); mCarrierConfigTracker.addDefaultDataSubscriptionChangedListener(mDefaultDataListener); CollapsedStatusBarViewBinder.bind( mStatusBar, mCollapsedStatusBarViewModel, this::updateStatusBarVisibilities); } @Override Loading Loading @@ -415,6 +423,10 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue updateStatusBarVisibilities(animate); } private void updateStatusBarVisibilities() { updateStatusBarVisibilities(/* animate= */ true); } private void updateStatusBarVisibilities(boolean animate) { StatusBarVisibilityModel previousModel = mLastModifiedVisibility; StatusBarVisibilityModel newModel = calculateInternalModel(mLastSystemVisibility); Loading Loading @@ -457,7 +469,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue if (!mKeyguardStateController.isLaunchTransitionFadingAway() && !mKeyguardStateController.isKeyguardFadingAway() && shouldHideNotificationIcons() && shouldHideStatusBar() && !(mStatusBarStateController.getState() == StatusBarState.KEYGUARD && headsUpVisible)) { // Hide everything Loading Loading @@ -505,7 +517,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue mOngoingCallController.notifyChipVisibilityChanged(showOngoingCallChip); } private boolean shouldHideNotificationIcons() { private boolean shouldHideStatusBar() { if (!mShadeExpansionStateManager.isClosed() && mShadeViewController.shouldHideStatusBarIconsWhenExpanded()) { return true; Loading @@ -521,6 +533,9 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue // icons don't remain hidden somehow) we double check that the camera is still showing, the // status bar window isn't hidden, and we're still occluded as well, though these checks // are typically unnecessary. // // TODO(b/273314977): Can this be deleted now that we have the // [isTransitioningFromLockscreenToOccluded] check below? final boolean hideIconsForSecureCamera = (mWaitingForWindowStateChangeAfterCameraLaunch || !mStatusBarWindowStateController.windowIsShowing()) && Loading @@ -531,6 +546,16 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue return true; } // While the status bar is transitioning from lockscreen to an occluded, we don't yet know // if the occluding activity is fullscreen or not. If it *is* fullscreen, we don't want to // briefly show the status bar just to immediately hide it again. So, we wait for the // transition to occluding to finish before allowing us to potentially show the status bar // again. (This status bar is always hidden on keyguard, so it's safe to continue hiding it // during this transition.) See b/273314977. if (mCollapsedStatusBarViewModel.isTransitioningFromLockscreenToOccluded().getValue()) { return true; } return mStatusBarHideIconsForBouncerManager.getShouldHideStatusBarIconsForBouncer(); } Loading packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt +7 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import com.android.systemui.log.LogBufferFactory import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.TableLogBufferFactory import com.android.systemui.log.LogBuffer import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModelImpl 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 Loading Loading @@ -100,6 +102,11 @@ abstract class StatusBarPipelineModule { @ClassKey(CarrierConfigCoreStartable::class) abstract fun bindCarrierConfigStartable(impl: CarrierConfigCoreStartable): CoreStartable @Binds abstract fun collapsedStatusBarViewModel( impl: CollapsedStatusBarViewModelImpl ): CollapsedStatusBarViewModel companion object { @Provides @SysUISingleton Loading packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt 0 → 100644 +52 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.pipeline.shared.ui.binder import android.view.View import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel object CollapsedStatusBarViewBinder { /** * Binds the view to the view-model. [listener] will be notified whenever an event that may * change the status bar visibility occurs. */ @JvmStatic fun bind( view: View, viewModel: CollapsedStatusBarViewModel, listener: StatusBarVisibilityChangeListener, ) { view.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) { viewModel.isTransitioningFromLockscreenToOccluded.collect { listener.onStatusBarVisibilityMaybeChanged() } } } } } /** * Listener to be notified when the status bar visibility might have changed due to the device * moving to a different state. */ fun interface StatusBarVisibilityChangeListener { fun onStatusBarVisibilityMaybeChanged() } packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.pipeline.shared.ui.viewmodel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.TransitionState import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn /** * A view model that manages the visibility of the [CollapsedStatusBarFragment] based on the device * state. * * Right now, most of the status bar visibility management is actually in * [CollapsedStatusBarFragment.calculateInternalModel], which uses * [CollapsedStatusBarFragment.shouldHideNotificationIcons] and * [StatusBarHideIconsForBouncerManager]. We should move those pieces of logic to this class instead * so that it's all in one place and easily testable outside of the fragment. */ interface CollapsedStatusBarViewModel { /** * True if the device is currently transitioning from lockscreen to occluded and false * otherwise. */ val isTransitioningFromLockscreenToOccluded: StateFlow<Boolean> } @SysUISingleton class CollapsedStatusBarViewModelImpl @Inject constructor( keyguardTransitionInteractor: KeyguardTransitionInteractor, @Application coroutineScope: CoroutineScope, ) : CollapsedStatusBarViewModel { override val isTransitioningFromLockscreenToOccluded: StateFlow<Boolean> = keyguardTransitionInteractor.lockscreenToOccludedTransition .map { it.transitionState == TransitionState.STARTED || it.transitionState == TransitionState.RUNNING } .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), initialValue = false) } Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java +3 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment; import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger; import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent; import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.window.StatusBarWindowStateController; import com.android.systemui.util.CarrierConfigTracker; Loading Loading @@ -156,6 +157,7 @@ public abstract class StatusBarViewModule { FeatureFlags featureFlags, StatusBarIconController statusBarIconController, StatusBarIconController.DarkIconManager.Factory darkIconManagerFactory, CollapsedStatusBarViewModel collapsedStatusBarViewModel, StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager, KeyguardStateController keyguardStateController, ShadeViewController shadeViewController, Loading @@ -179,6 +181,7 @@ public abstract class StatusBarViewModule { featureFlags, statusBarIconController, darkIconManagerFactory, collapsedStatusBarViewModel, statusBarHideIconsForBouncerManager, keyguardStateController, shadeViewController, Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java +27 −2 Original line number Diff line number Diff line Loading @@ -68,6 +68,8 @@ import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentCom import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent.Startable; import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener; import com.android.systemui.statusbar.pipeline.shared.ui.binder.CollapsedStatusBarViewBinder; import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.window.StatusBarWindowStateController; import com.android.systemui.statusbar.window.StatusBarWindowStateListener; Loading Loading @@ -128,6 +130,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue private final ShadeExpansionStateManager mShadeExpansionStateManager; private final StatusBarIconController mStatusBarIconController; private final CarrierConfigTracker mCarrierConfigTracker; private final CollapsedStatusBarViewModel mCollapsedStatusBarViewModel; private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager; private final StatusBarIconController.DarkIconManager.Factory mDarkIconManagerFactory; private final SecureSettings mSecureSettings; Loading Loading @@ -197,6 +200,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue FeatureFlags featureFlags, StatusBarIconController statusBarIconController, StatusBarIconController.DarkIconManager.Factory darkIconManagerFactory, CollapsedStatusBarViewModel collapsedStatusBarViewModel, StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager, KeyguardStateController keyguardStateController, ShadeViewController shadeViewController, Loading @@ -219,6 +223,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue mShadeExpansionStateManager = shadeExpansionStateManager; mFeatureFlags = featureFlags; mStatusBarIconController = statusBarIconController; mCollapsedStatusBarViewModel = collapsedStatusBarViewModel; mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager; mDarkIconManagerFactory = darkIconManagerFactory; mKeyguardStateController = keyguardStateController; Loading Loading @@ -290,6 +295,9 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue new StatusBarSystemEventAnimator(mEndSideContent, getResources()); mCarrierConfigTracker.addCallback(mCarrierConfigCallback); mCarrierConfigTracker.addDefaultDataSubscriptionChangedListener(mDefaultDataListener); CollapsedStatusBarViewBinder.bind( mStatusBar, mCollapsedStatusBarViewModel, this::updateStatusBarVisibilities); } @Override Loading Loading @@ -415,6 +423,10 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue updateStatusBarVisibilities(animate); } private void updateStatusBarVisibilities() { updateStatusBarVisibilities(/* animate= */ true); } private void updateStatusBarVisibilities(boolean animate) { StatusBarVisibilityModel previousModel = mLastModifiedVisibility; StatusBarVisibilityModel newModel = calculateInternalModel(mLastSystemVisibility); Loading Loading @@ -457,7 +469,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue if (!mKeyguardStateController.isLaunchTransitionFadingAway() && !mKeyguardStateController.isKeyguardFadingAway() && shouldHideNotificationIcons() && shouldHideStatusBar() && !(mStatusBarStateController.getState() == StatusBarState.KEYGUARD && headsUpVisible)) { // Hide everything Loading Loading @@ -505,7 +517,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue mOngoingCallController.notifyChipVisibilityChanged(showOngoingCallChip); } private boolean shouldHideNotificationIcons() { private boolean shouldHideStatusBar() { if (!mShadeExpansionStateManager.isClosed() && mShadeViewController.shouldHideStatusBarIconsWhenExpanded()) { return true; Loading @@ -521,6 +533,9 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue // icons don't remain hidden somehow) we double check that the camera is still showing, the // status bar window isn't hidden, and we're still occluded as well, though these checks // are typically unnecessary. // // TODO(b/273314977): Can this be deleted now that we have the // [isTransitioningFromLockscreenToOccluded] check below? final boolean hideIconsForSecureCamera = (mWaitingForWindowStateChangeAfterCameraLaunch || !mStatusBarWindowStateController.windowIsShowing()) && Loading @@ -531,6 +546,16 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue return true; } // While the status bar is transitioning from lockscreen to an occluded, we don't yet know // if the occluding activity is fullscreen or not. If it *is* fullscreen, we don't want to // briefly show the status bar just to immediately hide it again. So, we wait for the // transition to occluding to finish before allowing us to potentially show the status bar // again. (This status bar is always hidden on keyguard, so it's safe to continue hiding it // during this transition.) See b/273314977. if (mCollapsedStatusBarViewModel.isTransitioningFromLockscreenToOccluded().getValue()) { return true; } return mStatusBarHideIconsForBouncerManager.getShouldHideStatusBarIconsForBouncer(); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt +7 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import com.android.systemui.log.LogBufferFactory import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.TableLogBufferFactory import com.android.systemui.log.LogBuffer import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModelImpl 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 Loading Loading @@ -100,6 +102,11 @@ abstract class StatusBarPipelineModule { @ClassKey(CarrierConfigCoreStartable::class) abstract fun bindCarrierConfigStartable(impl: CarrierConfigCoreStartable): CoreStartable @Binds abstract fun collapsedStatusBarViewModel( impl: CollapsedStatusBarViewModelImpl ): CollapsedStatusBarViewModel companion object { @Provides @SysUISingleton Loading
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt 0 → 100644 +52 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.pipeline.shared.ui.binder import android.view.View import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel object CollapsedStatusBarViewBinder { /** * Binds the view to the view-model. [listener] will be notified whenever an event that may * change the status bar visibility occurs. */ @JvmStatic fun bind( view: View, viewModel: CollapsedStatusBarViewModel, listener: StatusBarVisibilityChangeListener, ) { view.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) { viewModel.isTransitioningFromLockscreenToOccluded.collect { listener.onStatusBarVisibilityMaybeChanged() } } } } } /** * Listener to be notified when the status bar visibility might have changed due to the device * moving to a different state. */ fun interface StatusBarVisibilityChangeListener { fun onStatusBarVisibilityMaybeChanged() }
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.pipeline.shared.ui.viewmodel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.TransitionState import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn /** * A view model that manages the visibility of the [CollapsedStatusBarFragment] based on the device * state. * * Right now, most of the status bar visibility management is actually in * [CollapsedStatusBarFragment.calculateInternalModel], which uses * [CollapsedStatusBarFragment.shouldHideNotificationIcons] and * [StatusBarHideIconsForBouncerManager]. We should move those pieces of logic to this class instead * so that it's all in one place and easily testable outside of the fragment. */ interface CollapsedStatusBarViewModel { /** * True if the device is currently transitioning from lockscreen to occluded and false * otherwise. */ val isTransitioningFromLockscreenToOccluded: StateFlow<Boolean> } @SysUISingleton class CollapsedStatusBarViewModelImpl @Inject constructor( keyguardTransitionInteractor: KeyguardTransitionInteractor, @Application coroutineScope: CoroutineScope, ) : CollapsedStatusBarViewModel { override val isTransitioningFromLockscreenToOccluded: StateFlow<Boolean> = keyguardTransitionInteractor.lockscreenToOccludedTransition .map { it.transitionState == TransitionState.STARTED || it.transitionState == TransitionState.RUNNING } .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), initialValue = false) }