1 /* 2 * 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 package com.android.launcher3.taskbar.bubbles.stashing 18 19 import android.graphics.Rect 20 import android.view.InsetsController 21 import android.view.MotionEvent 22 import android.view.View 23 import com.android.launcher3.taskbar.TaskbarInsetsController 24 import com.android.launcher3.taskbar.bubbles.BubbleBarView 25 import com.android.launcher3.taskbar.bubbles.BubbleBarViewController 26 import com.android.launcher3.taskbar.bubbles.BubbleStashedHandleViewController 27 import com.android.launcher3.util.MultiPropertyFactory 28 import com.android.wm.shell.shared.animation.PhysicsAnimator 29 import com.android.wm.shell.shared.bubbles.BubbleBarLocation 30 import java.io.PrintWriter 31 32 /** StashController that defines stashing behaviour for the taskbar modes. */ 33 interface BubbleStashController { 34 35 /** 36 * Abstraction on the task bar activity context to only provide the dimensions required for 37 * [BubbleBarView] translation Y computation. 38 */ 39 interface TaskbarHotseatDimensionsProvider { 40 41 /** Provides taskbar bottom space in pixels. */ getTaskbarBottomSpacenull42 fun getTaskbarBottomSpace(): Int 43 44 /** Provides taskbar height in pixels. */ 45 fun getTaskbarHeight(): Int 46 } 47 48 /** Execute passed action only after controllers are initiated. */ 49 interface ControllersAfterInitAction { 50 /** Execute action after controllers are initiated. */ 51 fun runAfterInit(action: Runnable) 52 } 53 54 /** Launcher states bubbles cares about */ 55 enum class BubbleLauncherState { 56 /* When launcher is in overview */ 57 OVERVIEW, 58 /* When launcher is on home */ 59 HOME, 60 /* We're in an app */ 61 IN_APP, 62 } 63 64 /** The current launcher state */ 65 var launcherState: BubbleLauncherState 66 67 /** Whether bubble bar is currently stashed */ 68 val isStashed: Boolean 69 70 /** Whether launcher enters or exits the home page. */ 71 val isBubblesShowingOnHome: Boolean 72 get() = launcherState == BubbleLauncherState.HOME 73 74 /** Whether launcher enters or exits the overview page. */ 75 val isBubblesShowingOnOverview: Boolean 76 get() = launcherState == BubbleLauncherState.OVERVIEW 77 78 /** Bubble bar vertical center for launcher home. */ 79 var bubbleBarVerticalCenterForHome: Int 80 81 /** Updated when sysui locked state changes, when locked, bubble bar is not shown. */ 82 var isSysuiLocked: Boolean 83 84 /** Whether there is a transient taskbar mode */ 85 val isTransientTaskBar: Boolean 86 87 /** Whether stash control has a handle view */ 88 val hasHandleView: Boolean 89 90 /** Initialize controller */ initnull91 fun init( 92 taskbarInsetsController: TaskbarInsetsController, 93 bubbleBarViewController: BubbleBarViewController, 94 bubbleStashedHandleViewController: BubbleStashedHandleViewController?, 95 controllersAfterInitAction: ControllersAfterInitAction, 96 ) 97 98 /** Shows the bubble bar at [bubbleBarTranslationY] position immediately without animation. */ 99 fun showBubbleBarImmediate() 100 101 /** Shows the bubble bar at [bubbleBarTranslationY] position immediately without animation. */ 102 fun showBubbleBarImmediate(bubbleBarTranslationY: Float) 103 104 /** Stashes the bubble bar immediately without animation. */ 105 fun stashBubbleBarImmediate() 106 107 /** Returns the touchable height of the bubble bar based on it's stashed state. */ 108 fun getTouchableHeight(): Int 109 110 /** Whether bubble bar is currently visible */ 111 fun isBubbleBarVisible(): Boolean 112 113 /** 114 * Updates the values of the internal animators after the new bubble animation was interrupted 115 * 116 * @param isStashed whether the current state should be stashed 117 * @param bubbleBarTranslationY the current bubble bar translation. this is only used if the 118 * bubble bar is showing to ensure that the stash animator runs smoothly. 119 */ 120 fun onNewBubbleAnimationInterrupted(isStashed: Boolean, bubbleBarTranslationY: Float) 121 122 /** Checks whether the motion event is over the stash handle or bubble bar. */ 123 fun isEventOverBubbleBarViews(ev: MotionEvent): Boolean 124 125 /** Set a bubble bar location */ 126 fun setBubbleBarLocation(bubbleBarLocation: BubbleBarLocation) 127 128 /** 129 * Stashes the bubble bar (transform to the handle view), or just shrink width of the expanded 130 * bubble bar based on the controller implementation. 131 */ 132 fun stashBubbleBar() 133 134 /** 135 * Animates the bubble bar to the handle at provided location. Does not update bubble bar 136 * location. 137 */ 138 fun stashBubbleBarToLocation(fromLocation: BubbleBarLocation, toLocation: BubbleBarLocation) {} 139 140 /** Shows the bubble bar, and expands bubbles depending on [expandBubbles]. */ showBubbleBarnull141 fun showBubbleBar(expandBubbles: Boolean) { 142 showBubbleBar(expandBubbles = expandBubbles, bubbleBarGesture = false) 143 } 144 145 /** 146 * Shows the bubble bar, and expands bubbles depending on [expandBubbles]. 147 * 148 * Set [bubbleBarGesture] to true if this request originates from a touch gesture on the bubble 149 * bar. 150 */ showBubbleBarnull151 fun showBubbleBar(expandBubbles: Boolean, bubbleBarGesture: Boolean) 152 153 /** Animates the bubble bar at the provided location. Does not update bubble bar location. */ 154 fun showBubbleBarAtLocation(fromLocation: BubbleBarLocation, toLocation: BubbleBarLocation) {} 155 156 // TODO(b/354218264): Move to BubbleBarViewAnimator 157 /** 158 * The difference on the Y axis between the center of the handle and the center of the bubble 159 * bar. 160 */ getDiffBetweenHandleAndBarCentersnull161 fun getDiffBetweenHandleAndBarCenters(): Float 162 163 // TODO(b/354218264): Move to BubbleBarViewAnimator 164 /** The distance the handle moves as part of the new bubble animation. */ 165 fun getStashedHandleTranslationForNewBubbleAnimation(): Float 166 167 // TODO(b/354218264): Move to BubbleBarViewAnimator 168 /** Returns the [PhysicsAnimator] for the stashed handle view. */ 169 fun getStashedHandlePhysicsAnimator(): PhysicsAnimator<View>? 170 171 // TODO(b/354218264): Move to BubbleBarViewAnimator 172 /** Notifies taskbar that it should update its touchable region. */ 173 fun updateTaskbarTouchRegion() 174 175 // TODO(b/354218264): Move to BubbleBarViewAnimator 176 /** Set the translation Y for the stashed handle. */ 177 fun setHandleTranslationY(translationY: Float) 178 179 /** Returns the translation of the handle. */ 180 fun getHandleTranslationY(): Float? 181 182 /** Returns bounds of the handle */ 183 fun getHandleBounds(bounds: Rect) 184 185 /** Returns MultiValueAlpha of the handle view when the handle view is shown. */ 186 fun getHandleViewAlpha(): MultiPropertyFactory<View>.MultiProperty? = null 187 188 /** 189 * Returns bubble bar Y position according to [isBubblesShowingOnHome] and 190 * [isBubblesShowingOnOverview] values. Default implementation only analyse 191 * [isBubblesShowingOnHome] and return translationY to align with the hotseat vertical center. 192 * For Other cases align bubbles with the taskbar. 193 */ 194 val bubbleBarTranslationY: Float 195 get() = 196 if (isBubblesShowingOnHome) { 197 bubbleBarTranslationYForHotseat 198 } else { 199 bubbleBarTranslationYForTaskbar 200 } 201 202 /** Translation Y to align the bubble bar with the taskbar. */ 203 val bubbleBarTranslationYForTaskbar: Float 204 205 /** Return translation Y to align the bubble bar with the hotseat. */ 206 val bubbleBarTranslationYForHotseat: Float 207 208 /** 209 * Show bubble bar is if it were in-app while launcher state is still on home. Set as a progress 210 * value between 0 and 1: 0 - use home layout, 1 - use in-app layout. 211 */ 212 var inAppDisplayOverrideProgress: Float 213 214 /** Dumps the state of BubbleStashController. */ dumpnull215 fun dump(pw: PrintWriter) { 216 pw.println("Bubble stash controller state:") 217 pw.println(" isStashed: $isStashed") 218 pw.println(" isBubblesShowingOnOverview: $isBubblesShowingOnOverview") 219 pw.println(" isBubblesShowingOnHome: $isBubblesShowingOnHome") 220 pw.println(" isSysuiLocked: $isSysuiLocked") 221 } 222 223 companion object { 224 /** How long to stash/unstash. */ 225 const val BAR_STASH_DURATION = InsetsController.ANIMATION_DURATION_RESIZE.toLong() 226 227 /** How long to translate Y coordinate of the BubbleBar. */ 228 const val BAR_TRANSLATION_DURATION = 300L 229 } 230 } 231