1 /* 2 * Copyright (C) 2017 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.uioverrides.states; 17 18 import static com.android.app.animation.Interpolators.DECELERATE_2; 19 import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation; 20 import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS; 21 22 import android.content.Context; 23 24 import com.android.internal.jank.Cuj; 25 import com.android.launcher3.DeviceProfile; 26 import com.android.launcher3.Flags; 27 import com.android.launcher3.Launcher; 28 import com.android.launcher3.LauncherState; 29 import com.android.launcher3.R; 30 import com.android.launcher3.util.Themes; 31 import com.android.launcher3.views.ActivityContext; 32 import com.android.quickstep.util.BaseDepthController; 33 import com.android.systemui.shared.system.InteractionJankMonitorWrapper; 34 35 import java.util.concurrent.TimeUnit; 36 37 /** 38 * Definition for AllApps state 39 */ 40 public class AllAppsState extends LauncherState { 41 42 private static final int STATE_FLAGS = 43 FLAG_WORKSPACE_INACCESSIBLE | FLAG_CLOSE_POPUPS | FLAG_HOTSEAT_INACCESSIBLE; 44 private static final long BACK_CUJ_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(5); 45 46 AllAppsState(int id)47 public AllAppsState(int id) { 48 super(id, LAUNCHER_STATE_ALLAPPS, STATE_FLAGS); 49 } 50 51 @Override getTransitionDuration(ActivityContext context, boolean isToState)52 public int getTransitionDuration(ActivityContext context, boolean isToState) { 53 return isToState 54 ? context.getDeviceProfile().allAppsOpenDuration 55 : context.getDeviceProfile().allAppsCloseDuration; 56 } 57 58 @Override onBackStarted(Launcher launcher)59 public void onBackStarted(Launcher launcher) { 60 // Because the back gesture can take longer time depending on when user release the finger, 61 // we pass BACK_CUJ_TIMEOUT_MS as timeout to the jank monitor. 62 InteractionJankMonitorWrapper.begin(launcher.getAppsView(), 63 Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK, BACK_CUJ_TIMEOUT_MS); 64 super.onBackStarted(launcher); 65 } 66 67 @Override onBackInvoked(Launcher launcher)68 public void onBackInvoked(Launcher launcher) { 69 // In predictive back swipe, onBackInvoked() will be called after onBackStarted(). 70 // In 3 button mode, onBackStarted() is not called but onBackInvoked() will be called. 71 // Thus In onBackInvoked(), we should only begin instrumenting if we didn't call 72 // onBackStarted() to start instrumenting CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK. 73 if (!InteractionJankMonitorWrapper.isInstrumenting(Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK)) { 74 InteractionJankMonitorWrapper.begin( 75 launcher.getAppsView(), Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK); 76 } 77 super.onBackInvoked(launcher); 78 } 79 80 /** Called when predictive back swipe is cancelled. */ 81 @Override onBackCancelled(Launcher launcher)82 public void onBackCancelled(Launcher launcher) { 83 super.onBackCancelled(launcher); 84 InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK); 85 } 86 87 @Override onBackAnimationCompleted(boolean success)88 protected void onBackAnimationCompleted(boolean success) { 89 if (success) { 90 // Animation was successful. 91 InteractionJankMonitorWrapper.end(Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK); 92 } else { 93 // Animation was canceled. 94 InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK); 95 } 96 } 97 98 @Override getDescription(Launcher launcher)99 public String getDescription(Launcher launcher) { 100 return launcher.getAppsView().getDescription(); 101 } 102 103 @Override getTitle()104 public int getTitle() { 105 return R.string.all_apps_list_label; 106 } 107 108 @Override getVerticalProgress(Launcher launcher)109 public float getVerticalProgress(Launcher launcher) { 110 return 0f; 111 } 112 113 @Override getWorkspaceScaleAndTranslation(Launcher launcher)114 public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) { 115 return new ScaleAndTranslation(launcher.getDeviceProfile().workspaceContentScale, NO_OFFSET, 116 NO_OFFSET); 117 } 118 119 @Override getHotseatScaleAndTranslation(Launcher launcher)120 public ScaleAndTranslation getHotseatScaleAndTranslation(Launcher launcher) { 121 if (launcher.getDeviceProfile().shouldShowAllAppsOnSheet()) { 122 return getWorkspaceScaleAndTranslation(launcher); 123 } else { 124 ScaleAndTranslation overviewScaleAndTranslation = LauncherState.OVERVIEW 125 .getWorkspaceScaleAndTranslation(launcher); 126 return new ScaleAndTranslation( 127 launcher.getDeviceProfile().workspaceContentScale, 128 overviewScaleAndTranslation.translationX, 129 overviewScaleAndTranslation.translationY); 130 } 131 } 132 133 @Override 134 protected <DEVICE_PROFILE_CONTEXT extends Context & ActivityContext> getDepthUnchecked(DEVICE_PROFILE_CONTEXT context)135 float getDepthUnchecked(DEVICE_PROFILE_CONTEXT context) { 136 if (context.getDeviceProfile().shouldShowAllAppsOnSheet()) { 137 return context.getDeviceProfile().bottomSheetDepth; 138 } else { 139 // The scrim fades in at approximately 50% of the swipe gesture. 140 if (enableScalingRevealHomeAnimation()) { 141 // This means that the depth should be twice of what we want, in order to fully zoom 142 // out during the visible portion of the animation. 143 return BaseDepthController.DEPTH_60_PERCENT; 144 } else { 145 // This means that the depth should be greater than 1, in order to fully zoom out. 146 return 2f; 147 } 148 } 149 } 150 151 @Override getWorkspacePageAlphaProvider(Launcher launcher)152 public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) { 153 PageAlphaProvider superPageAlphaProvider = super.getWorkspacePageAlphaProvider(launcher); 154 return new PageAlphaProvider(DECELERATE_2) { 155 @Override 156 public float getPageAlpha(int pageIndex) { 157 return isWorkspaceVisible(launcher.getDeviceProfile()) 158 ? superPageAlphaProvider.getPageAlpha(pageIndex) 159 : 0; 160 } 161 }; 162 } 163 164 @Override 165 public int getVisibleElements(Launcher launcher) { 166 int elements = ALL_APPS_CONTENT | FLOATING_SEARCH_BAR; 167 if (isWorkspaceVisible(launcher.getDeviceProfile())) { 168 elements |= HOTSEAT_ICONS; 169 } 170 return elements; 171 } 172 173 private static boolean isWorkspaceVisible(DeviceProfile deviceProfile) { 174 // Currently we hide the workspace with the all apps blur flag for simplicity. 175 return deviceProfile.isTablet && !Flags.allAppsBlur(); 176 } 177 178 @Override 179 public int getFloatingSearchBarRestingMarginBottom(Launcher launcher) { 180 return 0; 181 } 182 183 @Override 184 public int getFloatingSearchBarRestingMarginStart(Launcher launcher) { 185 DeviceProfile dp = launcher.getDeviceProfile(); 186 return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin(launcher); 187 } 188 189 @Override 190 public int getFloatingSearchBarRestingMarginEnd(Launcher launcher) { 191 DeviceProfile dp = launcher.getDeviceProfile(); 192 return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin(launcher); 193 } 194 195 @Override 196 public boolean shouldFloatingSearchBarUsePillWhenUnfocused(Launcher launcher) { 197 DeviceProfile dp = launcher.getDeviceProfile(); 198 return dp.isPhone && !dp.isLandscape; 199 } 200 201 @Override 202 public LauncherState getHistoryForState(LauncherState previousState) { 203 return previousState == BACKGROUND_APP ? QUICK_SWITCH_FROM_HOME 204 : previousState == OVERVIEW ? OVERVIEW : NORMAL; 205 } 206 207 @Override 208 public int getWorkspaceScrimColor(Launcher launcher) { 209 if (!launcher.getDeviceProfile().shouldShowAllAppsOnSheet()) { 210 return Themes.getAttrColor(launcher, R.attr.allAppsScrimColor); 211 } 212 if (Flags.allAppsBlur()) { 213 return Themes.getAttrColor(launcher, R.attr.allAppsScrimColorOverBlur); 214 } 215 return launcher.getResources().getColor(R.color.widgets_picker_scrim); 216 } 217 } 218