1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel
18 
19 import com.android.systemui.dagger.SysUISingleton
20 import com.android.systemui.dagger.qualifiers.Application
21 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
22 import com.android.systemui.keyguard.shared.model.TransitionState
23 import javax.inject.Inject
24 import kotlinx.coroutines.CoroutineScope
25 import kotlinx.coroutines.flow.Flow
26 import kotlinx.coroutines.flow.SharingStarted
27 import kotlinx.coroutines.flow.StateFlow
28 import kotlinx.coroutines.flow.filter
29 import kotlinx.coroutines.flow.map
30 import kotlinx.coroutines.flow.stateIn
31 
32 /**
33  * A view model that manages the visibility of the [CollapsedStatusBarFragment] based on the device
34  * state.
35  *
36  * Right now, most of the status bar visibility management is actually in
37  * [CollapsedStatusBarFragment.calculateInternalModel], which uses
38  * [CollapsedStatusBarFragment.shouldHideNotificationIcons] and
39  * [StatusBarHideIconsForBouncerManager]. We should move those pieces of logic to this class instead
40  * so that it's all in one place and easily testable outside of the fragment.
41  */
42 interface CollapsedStatusBarViewModel {
43     /**
44      * True if the device is currently transitioning from lockscreen to occluded and false
45      * otherwise.
46      */
47     val isTransitioningFromLockscreenToOccluded: StateFlow<Boolean>
48 
49     /** Emits whenever a transition from lockscreen to dream has started. */
50     val transitionFromLockscreenToDreamStartedEvent: Flow<Unit>
51 }
52 
53 @SysUISingleton
54 class CollapsedStatusBarViewModelImpl
55 @Inject
56 constructor(
57     keyguardTransitionInteractor: KeyguardTransitionInteractor,
58     @Application coroutineScope: CoroutineScope,
59 ) : CollapsedStatusBarViewModel {
60     override val isTransitioningFromLockscreenToOccluded: StateFlow<Boolean> =
61         keyguardTransitionInteractor.lockscreenToOccludedTransition
62             .map {
63                 it.transitionState == TransitionState.STARTED ||
64                     it.transitionState == TransitionState.RUNNING
65             }
66             .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), initialValue = false)
67 
68     override val transitionFromLockscreenToDreamStartedEvent: Flow<Unit> =
69         keyguardTransitionInteractor.lockscreenToDreamingTransition
70             .filter { it.transitionState == TransitionState.STARTED }
71             .map {}
72 }
73