1 /* <lambda>null2 * Copyright (C) 2024 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 @file:OptIn(ExperimentalCoroutinesApi::class) 18 19 package com.android.systemui.shade.domain.interactor 20 21 import com.android.compose.animation.scene.ObservableTransitionState 22 import com.android.compose.animation.scene.SceneKey 23 import com.android.systemui.dagger.SysUISingleton 24 import com.android.systemui.scene.domain.interactor.SceneInteractor 25 import com.android.systemui.scene.shared.model.Scenes 26 import com.android.systemui.statusbar.SysuiStatusBarStateController 27 import javax.inject.Inject 28 import kotlinx.coroutines.ExperimentalCoroutinesApi 29 import kotlinx.coroutines.flow.Flow 30 import kotlinx.coroutines.flow.flatMapLatest 31 import kotlinx.coroutines.flow.flowOf 32 import kotlinx.coroutines.flow.map 33 34 @SysUISingleton 35 class PanelExpansionInteractorImpl 36 @Inject 37 constructor( 38 private val sceneInteractor: SceneInteractor, 39 private val shadeInteractor: ShadeInteractor, 40 private val shadeAnimationInteractor: ShadeAnimationInteractor, 41 private val statusBarStateController: SysuiStatusBarStateController, 42 ) : PanelExpansionInteractor { 43 44 /** 45 * The amount by which the "panel" has been expanded (`0` when fully collapsed, `1` when fully 46 * expanded). 47 * 48 * This is a legacy concept from the time when the "panel" included the notification/QS shades 49 * as well as the keyguard (lockscreen and bouncer). This value is meant only for 50 * backwards-compatibility and should not be consumed by newer code. 51 */ 52 @Deprecated("Use SceneInteractor.currentScene instead.") 53 override val legacyPanelExpansion: Flow<Float> = 54 sceneInteractor.transitionState.flatMapLatest { state -> 55 when (state) { 56 is ObservableTransitionState.Idle -> 57 flowOf( 58 if (state.currentScene != Scenes.Gone) { 59 // When resting on a non-Gone scene, the panel is fully expanded. 60 1f 61 } else { 62 // When resting on the Gone scene, the panel is considered fully 63 // collapsed. 64 0f 65 } 66 ) 67 is ObservableTransitionState.Transition -> 68 when { 69 state.fromScene == Scenes.Gone -> 70 if (state.toScene.isExpandable()) { 71 // Moving from Gone to a scene that can animate-expand has a 72 // panel expansion that tracks with the transition. 73 state.progress 74 } else { 75 // Moving from Gone to a scene that doesn't animate-expand 76 // immediately makes the panel fully expanded. 77 flowOf(1f) 78 } 79 state.toScene == Scenes.Gone -> 80 if (state.fromScene.isExpandable()) { 81 // Moving to Gone from a scene that can animate-expand has a 82 // panel expansion that tracks with the transition. 83 state.progress.map { 1 - it } 84 } else { 85 // Moving to Gone from a scene that doesn't animate-expand 86 // immediately makes the panel fully collapsed. 87 flowOf(0f) 88 } 89 else -> flowOf(1f) 90 } 91 } 92 } 93 94 @Deprecated( 95 "depends on the state you check, use {@link #isShadeFullyExpanded()},\n" + 96 "{@link #isOnAod()}, {@link #isOnKeyguard()} instead." 97 ) 98 override val isFullyExpanded 99 get() = shadeInteractor.isAnyFullyExpanded.value 100 101 @Deprecated("Use !ShadeInteractor.isAnyExpanded instead") 102 override val isFullyCollapsed 103 get() = !shadeInteractor.isAnyExpanded.value 104 105 @Deprecated("Use ShadeAnimationInteractor instead") 106 override val isCollapsing 107 get() = 108 shadeAnimationInteractor.isAnyCloseAnimationRunning.value || 109 shadeAnimationInteractor.isLaunchingActivity.value 110 111 @Deprecated("Use sceneInteractor.isTransitionUserInputOngoing instead") 112 override val isTracking 113 get() = sceneInteractor.isTransitionUserInputOngoing.value 114 115 @Deprecated("Use ShadeInteractor.isAnyExpanded instead.") 116 override val isPanelExpanded 117 get() = shadeInteractor.isAnyExpanded.value 118 119 @Deprecated("Use SceneInteractor or ShadeInteractor instead") 120 override val barState 121 get() = statusBarStateController.state 122 123 @Deprecated("No longer supported. Do not add new calls to this.") 124 override fun shouldHideStatusBarIconsWhenExpanded(): Boolean { 125 if (shadeAnimationInteractor.isLaunchingActivity.value) { 126 return false 127 } 128 // TODO(b/325936094) if a HUN is showing, return false 129 return sceneInteractor.currentScene.value == Scenes.Lockscreen 130 } 131 132 private fun SceneKey.isExpandable(): Boolean { 133 return this == Scenes.Shade || this == Scenes.QuickSettings 134 } 135 } 136