1 /* 2 * Copyright (C) 2021 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 package com.android.launcher3.taskbar; 17 18 import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; 19 import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_CONTENT; 20 import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_FRAME; 21 import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_REGION; 22 23 import android.content.res.Resources; 24 import android.graphics.Rect; 25 26 import com.android.launcher3.AbstractFloatingView; 27 import com.android.launcher3.R; 28 import com.android.launcher3.anim.AlphaUpdateListener; 29 import com.android.quickstep.AnimatedFloat; 30 import com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo; 31 32 /** 33 * Handles properties/data collection, then passes the results to TaskbarDragLayer to render. 34 */ 35 public class TaskbarDragLayerController { 36 37 private final TaskbarActivityContext mActivity; 38 private final TaskbarDragLayer mTaskbarDragLayer; 39 private final int mFolderMargin; 40 41 // Alpha properties for taskbar background. 42 private final AnimatedFloat mBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha); 43 private final AnimatedFloat mBgNavbar = new AnimatedFloat(this::updateBackgroundAlpha); 44 private final AnimatedFloat mKeyguardBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha); 45 private final AnimatedFloat mNotificationShadeBgTaskbar = new AnimatedFloat( 46 this::updateBackgroundAlpha); 47 private final AnimatedFloat mImeBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha); 48 // Used to hide our background color when someone else (e.g. ScrimView) is handling it. 49 private final AnimatedFloat mBgOverride = new AnimatedFloat(this::updateBackgroundAlpha); 50 51 // Translation property for taskbar background. 52 private final AnimatedFloat mBgOffset = new AnimatedFloat(this::updateBackgroundOffset); 53 54 // Initialized in init. 55 private TaskbarControllers mControllers; 56 private AnimatedFloat mNavButtonDarkIntensityMultiplier; 57 58 private float mLastSetBackgroundAlpha; 59 TaskbarDragLayerController(TaskbarActivityContext activity, TaskbarDragLayer taskbarDragLayer)60 public TaskbarDragLayerController(TaskbarActivityContext activity, 61 TaskbarDragLayer taskbarDragLayer) { 62 mActivity = activity; 63 mTaskbarDragLayer = taskbarDragLayer; 64 final Resources resources = mTaskbarDragLayer.getResources(); 65 mFolderMargin = resources.getDimensionPixelSize(R.dimen.taskbar_folder_margin); 66 } 67 init(TaskbarControllers controllers)68 public void init(TaskbarControllers controllers) { 69 mControllers = controllers; 70 mTaskbarDragLayer.init(new TaskbarDragLayerCallbacks()); 71 72 mNavButtonDarkIntensityMultiplier = mControllers.navbarButtonsViewController 73 .getNavButtonDarkIntensityMultiplier(); 74 75 mBgTaskbar.value = 1; 76 mKeyguardBgTaskbar.value = 1; 77 mNotificationShadeBgTaskbar.value = 1; 78 mImeBgTaskbar.value = 1; 79 mBgOverride.value = 1; 80 updateBackgroundAlpha(); 81 } 82 onDestroy()83 public void onDestroy() { 84 mTaskbarDragLayer.onDestroy(); 85 } 86 87 /** 88 * @return Bounds (in TaskbarDragLayer coordinates) where an opened Folder can display. 89 */ getFolderBoundingBox()90 public Rect getFolderBoundingBox() { 91 Rect boundingBox = new Rect(0, 0, mTaskbarDragLayer.getWidth(), 92 mTaskbarDragLayer.getHeight() - mActivity.getDeviceProfile().taskbarSize); 93 boundingBox.inset(mFolderMargin, mFolderMargin); 94 return boundingBox; 95 } 96 getTaskbarBackgroundAlpha()97 public AnimatedFloat getTaskbarBackgroundAlpha() { 98 return mBgTaskbar; 99 } 100 getNavbarBackgroundAlpha()101 public AnimatedFloat getNavbarBackgroundAlpha() { 102 return mBgNavbar; 103 } 104 getKeyguardBgTaskbar()105 public AnimatedFloat getKeyguardBgTaskbar() { 106 return mKeyguardBgTaskbar; 107 } 108 getNotificationShadeBgTaskbar()109 public AnimatedFloat getNotificationShadeBgTaskbar() { 110 return mNotificationShadeBgTaskbar; 111 } 112 getImeBgTaskbar()113 public AnimatedFloat getImeBgTaskbar() { 114 return mImeBgTaskbar; 115 } 116 getOverrideBackgroundAlpha()117 public AnimatedFloat getOverrideBackgroundAlpha() { 118 return mBgOverride; 119 } 120 getTaskbarBackgroundOffset()121 public AnimatedFloat getTaskbarBackgroundOffset() { 122 return mBgOffset; 123 } 124 updateBackgroundAlpha()125 private void updateBackgroundAlpha() { 126 final float bgNavbar = mBgNavbar.value; 127 final float bgTaskbar = mBgTaskbar.value * mKeyguardBgTaskbar.value 128 * mNotificationShadeBgTaskbar.value * mImeBgTaskbar.value; 129 mLastSetBackgroundAlpha = mBgOverride.value * Math.max(bgNavbar, bgTaskbar); 130 mTaskbarDragLayer.setTaskbarBackgroundAlpha(mLastSetBackgroundAlpha); 131 132 updateNavBarDarkIntensityMultiplier(); 133 } 134 updateBackgroundOffset()135 private void updateBackgroundOffset() { 136 mTaskbarDragLayer.setTaskbarBackgroundOffset(mBgOffset.value); 137 138 updateNavBarDarkIntensityMultiplier(); 139 } 140 updateNavBarDarkIntensityMultiplier()141 private void updateNavBarDarkIntensityMultiplier() { 142 // Zero out the app-requested dark intensity when we're drawing our own background. 143 float effectiveBgAlpha = mLastSetBackgroundAlpha * (1 - mBgOffset.value); 144 mNavButtonDarkIntensityMultiplier.updateValue(1 - effectiveBgAlpha); 145 } 146 147 /** 148 * Callbacks for {@link TaskbarDragLayer} to interact with its controller. 149 */ 150 public class TaskbarDragLayerCallbacks { 151 152 /** 153 * Called to update the touchable insets. 154 * @see InsetsInfo#setTouchableInsets(int) 155 */ updateInsetsTouchability(InsetsInfo insetsInfo)156 public void updateInsetsTouchability(InsetsInfo insetsInfo) { 157 insetsInfo.touchableRegion.setEmpty(); 158 // Always have nav buttons be touchable 159 mControllers.navbarButtonsViewController.addVisibleButtonsRegion( 160 mTaskbarDragLayer, insetsInfo.touchableRegion); 161 boolean insetsIsTouchableRegion = true; 162 163 if (mTaskbarDragLayer.getAlpha() < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD) { 164 // Let touches pass through us. 165 insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); 166 } else if (mControllers.navbarButtonsViewController.isImeVisible()) { 167 insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); 168 } else if (!mControllers.uiController.isTaskbarTouchable()) { 169 // Let touches pass through us. 170 insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); 171 } else if (mControllers.taskbarViewController.areIconsVisible() 172 || AbstractFloatingView.getOpenView(mActivity, TYPE_ALL) != null) { 173 // Taskbar has some touchable elements, take over the full taskbar area 174 insetsInfo.setTouchableInsets(mActivity.isTaskbarWindowFullscreen() 175 ? TOUCHABLE_INSETS_FRAME : TOUCHABLE_INSETS_CONTENT); 176 insetsIsTouchableRegion = false; 177 } else { 178 insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); 179 } 180 mActivity.excludeFromMagnificationRegion(insetsIsTouchableRegion); 181 } 182 183 /** 184 * Called to update the {@link InsetsInfo#contentInsets}. This is reported to apps but our 185 * internal launcher will ignore these insets. 186 */ updateContentInsets(Rect outContentInsets)187 public void updateContentInsets(Rect outContentInsets) { 188 int contentHeight = mControllers.taskbarStashController 189 .getContentHeightToReportToApps(); 190 outContentInsets.top = mTaskbarDragLayer.getHeight() - contentHeight; 191 } 192 193 /** 194 * Called when a child is removed from TaskbarDragLayer. 195 */ onDragLayerViewRemoved()196 public void onDragLayerViewRemoved() { 197 if (AbstractFloatingView.getAnyView(mActivity, TYPE_ALL) == null) { 198 mActivity.setTaskbarWindowFullscreen(false); 199 } 200 } 201 202 /** 203 * Returns how tall the background should be drawn at the bottom of the screen. 204 */ getTaskbarBackgroundHeight()205 public int getTaskbarBackgroundHeight() { 206 return mActivity.getDeviceProfile().taskbarSize; 207 } 208 } 209 } 210