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 17 package com.android.launcher3.config; 18 19 import static com.android.launcher3.config.FeatureFlags.BooleanFlag.DISABLED; 20 import static com.android.launcher3.config.FeatureFlags.BooleanFlag.ENABLED; 21 import static com.android.wm.shell.Flags.enableTaskbarNavbarUnification; 22 import static com.android.wm.shell.Flags.enableTaskbarOnPhones; 23 24 import android.content.res.Resources; 25 26 import androidx.annotation.VisibleForTesting; 27 28 import com.android.launcher3.BuildConfig; 29 import com.android.launcher3.Flags; 30 31 /** 32 * Defines a set of flags used to control various launcher behaviors. 33 * <p> 34 * <p>All the flags should be defined here with appropriate default values. 35 */ 36 public final class FeatureFlags { 37 FeatureFlags()38 private FeatureFlags() { } 39 40 /** 41 * True when the build has come from Android Studio and is being used for local debugging. 42 * @deprecated Use {@link BuildConfig#IS_STUDIO_BUILD} directly 43 */ 44 @Deprecated 45 public static final boolean IS_STUDIO_BUILD = BuildConfig.IS_STUDIO_BUILD; 46 47 /** 48 * Enable moving the QSB on the 0th screen of the workspace. This is not a configuration feature 49 * and should be modified at a project level. 50 * @deprecated Use {@link BuildConfig#QSB_ON_FIRST_SCREEN} directly 51 */ 52 @Deprecated 53 public static final boolean QSB_ON_FIRST_SCREEN = BuildConfig.QSB_ON_FIRST_SCREEN; 54 55 /** 56 * Feature flag to handle define config changes dynamically instead of killing the process. 57 * <p> 58 * 59 * To add a new flag that can be toggled through the flags UI: 60 * <p> 61 * Declare a new ToggleableFlag below. Give it a unique key (e.g. "QSB_ON_FIRST_SCREEN"), 62 * and set a default value for the flag. This will be the default value on Debug builds. 63 * <p> 64 */ 65 // TODO(Block 6): Clean up flags 66 public static final BooleanFlag SECONDARY_DRAG_N_DROP_TO_PIN = getDebugFlag(270395140, 67 "SECONDARY_DRAG_N_DROP_TO_PIN", DISABLED, 68 "Enable dragging and dropping to pin apps within secondary display"); 69 70 // TODO(Block 8): Clean up flags 71 72 // TODO(Block 9): Clean up flags 73 public static final BooleanFlag MULTI_SELECT_EDIT_MODE = getDebugFlag(270709220, 74 "MULTI_SELECT_EDIT_MODE", DISABLED, "Enable new multi-select edit mode " 75 + "for home screen"); 76 77 // TODO(Block 11): Clean up flags 78 public static final BooleanFlag FOLDABLE_SINGLE_PAGE = getDebugFlag(270395274, 79 "FOLDABLE_SINGLE_PAGE", DISABLED, "Use a single page for the workspace"); 80 81 // TODO(Block 12): Clean up flags 82 public static final BooleanFlag ENABLE_MULTI_INSTANCE = getDebugFlag(270396680, 83 "ENABLE_MULTI_INSTANCE", DISABLED, 84 "Enables creation and filtering of multiple task instances in overview"); 85 86 // TODO(Block 13): Clean up flags 87 public static final BooleanFlag ENABLE_DEVICE_SEARCH_PERFORMANCE_LOGGING = getReleaseFlag( 88 270391397, "ENABLE_DEVICE_SEARCH_PERFORMANCE_LOGGING", DISABLED, 89 "Allows on device search in all apps logging"); 90 91 // TODO(Block 14): Cleanup flags 92 public static final BooleanFlag NOTIFY_CRASHES = getDebugFlag(270393108, "NOTIFY_CRASHES", 93 DISABLED, "Sends a notification whenever launcher encounters an uncaught exception."); 94 95 public static final boolean ENABLE_TASKBAR_NAVBAR_UNIFICATION = 96 enableTaskbarNavbarUnification() && (!isPhone() || enableTaskbarOnPhones()); 97 isPhone()98 private static boolean isPhone() { 99 final boolean isPhone; 100 int foldedDeviceStatesId = Resources.getSystem().getIdentifier( 101 "config_foldedDeviceStates", "array", "android"); 102 if (foldedDeviceStatesId != 0) { 103 isPhone = Resources.getSystem().getIntArray(foldedDeviceStatesId).length == 0; 104 } else { 105 isPhone = true; 106 } 107 return isPhone; 108 } 109 110 // Aconfig migration complete for ENABLE_TASKBAR_NO_RECREATION. 111 public static final BooleanFlag ENABLE_TASKBAR_NO_RECREATION = getDebugFlag(299193589, 112 "ENABLE_TASKBAR_NO_RECREATION", DISABLED, 113 "Enables taskbar with no recreation from lifecycle changes of TaskbarActivityContext."); enableTaskbarNoRecreate()114 public static boolean enableTaskbarNoRecreate() { 115 return ENABLE_TASKBAR_NO_RECREATION.get() || Flags.enableTaskbarNoRecreate() 116 // Task bar pinning and task bar nav bar unification are both dependent on 117 // ENABLE_TASKBAR_NO_RECREATION. We want to turn ENABLE_TASKBAR_NO_RECREATION on 118 // when either of the dependent features is turned on. 119 || enableTaskbarPinning() || ENABLE_TASKBAR_NAVBAR_UNIFICATION; 120 } 121 122 // TODO(Block 16): Clean up flags 123 // When enabled the promise icon is visible in all apps while installation an app. 124 public static final BooleanFlag PROMISE_APPS_IN_ALL_APPS = getDebugFlag(270390012, 125 "PROMISE_APPS_IN_ALL_APPS", DISABLED, "Add promise icon in all-apps"); 126 127 // Aconfig migration complete for ENABLE_EXPANDING_PAUSE_WORK_BUTTON. 128 public static final BooleanFlag ENABLE_EXPANDING_PAUSE_WORK_BUTTON = getDebugFlag(270390779, 129 "ENABLE_EXPANDING_PAUSE_WORK_BUTTON", DISABLED, 130 "Expand and collapse pause work button while scrolling"); 131 132 public static final BooleanFlag INJECT_FALLBACK_APP_CORPUS_RESULTS = getReleaseFlag(270391706, 133 "INJECT_FALLBACK_APP_CORPUS_RESULTS", DISABLED, 134 "Inject fallback app corpus result when AiAi fails to return it."); 135 136 // TODO(Block 17): Clean up flags 137 // Aconfig migration complete for ENABLE_TASKBAR_PINNING. 138 private static final BooleanFlag ENABLE_TASKBAR_PINNING = getDebugFlag(296231746, 139 "ENABLE_TASKBAR_PINNING", DISABLED, 140 "Enables taskbar pinning to allow user to switch between transient and persistent " 141 + "taskbar flavors"); 142 enableTaskbarPinning()143 public static boolean enableTaskbarPinning() { 144 return ENABLE_TASKBAR_PINNING.get() || Flags.enableTaskbarPinning(); 145 } 146 147 // TODO(Block 20): Clean up flags 148 // Aconfig migration complete for ENABLE_HOME_TRANSITION_LISTENER. 149 public static final BooleanFlag ENABLE_HOME_TRANSITION_LISTENER = getDebugFlag(306053414, 150 "ENABLE_HOME_TRANSITION_LISTENER", DISABLED, 151 "Enables launcher to listen to all transitions that include home activity."); 152 enableHomeTransitionListener()153 public static boolean enableHomeTransitionListener() { 154 return ENABLE_HOME_TRANSITION_LISTENER.get() || Flags.enableHomeTransitionListener(); 155 } 156 157 // TODO(Block 21): Clean up flags 158 public static final BooleanFlag ENABLE_APP_ICON_FOR_INLINE_SHORTCUTS = getDebugFlag(270395087, 159 "ENABLE_APP_ICON_IN_INLINE_SHORTCUTS", DISABLED, "Show app icon for inline shortcut"); 160 161 // TODO(Block 22): Clean up flags 162 public static final BooleanFlag ENABLE_WIDGET_TRANSITION_FOR_RESIZING = getDebugFlag(268553314, 163 "ENABLE_WIDGET_TRANSITION_FOR_RESIZING", DISABLED, 164 "Enable widget transition animation when resizing the widgets"); 165 166 // TODO(Block 27): Clean up flags 167 public static final BooleanFlag ENABLE_OVERLAY_CONNECTION_OPTIM = getDebugFlag(270392629, 168 "ENABLE_OVERLAY_CONNECTION_OPTIM", DISABLED, 169 "Enable optimizing overlay service connection"); 170 171 /** 172 * Enables region sampling for text color: Needs system health assessment before turning on 173 */ 174 public static final BooleanFlag ENABLE_REGION_SAMPLING = getDebugFlag(270391669, 175 "ENABLE_REGION_SAMPLING", DISABLED, 176 "Enable region sampling to determine color of text on screen."); 177 178 public static final BooleanFlag ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS = 179 getDebugFlag(270393096, "ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS", 180 DISABLED, "Always use hardware optimization for folder animations."); 181 182 public static final BooleanFlag SEPARATE_RECENTS_ACTIVITY = getDebugFlag(270392980, 183 "SEPARATE_RECENTS_ACTIVITY", DISABLED, 184 "Uses a separate recents activity instead of using the integrated recents+Launcher UI"); 185 186 public static final BooleanFlag USE_LOCAL_ICON_OVERRIDES = getDebugFlag(270394973, 187 "USE_LOCAL_ICON_OVERRIDES", ENABLED, 188 "Use inbuilt monochrome icons if app doesn't provide one"); 189 190 // TODO(Block 29): Clean up flags 191 // Aconfig migration complete for ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT. 192 public static final BooleanFlag ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT = getDebugFlag(270393897, 193 "ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT", DISABLED, 194 "Enables displaying the all apps button in the hotseat."); 195 enableAllAppsButtonInHotseat()196 public static boolean enableAllAppsButtonInHotseat() { 197 return ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT.get() || Flags.enableAllAppsButtonInHotseat(); 198 } 199 200 // TODO(Block 30): Clean up flags 201 public static final BooleanFlag USE_SEARCH_REQUEST_TIMEOUT_OVERRIDES = getDebugFlag(270395010, 202 "USE_SEARCH_REQUEST_TIMEOUT_OVERRIDES", DISABLED, 203 "Use local overrides for search request timeout"); 204 205 // TODO(Block 31): Clean up flags 206 207 // TODO(Block 32): Clean up flags 208 // Aconfig migration complete for ENABLE_RESPONSIVE_WORKSPACE. 209 @VisibleForTesting 210 public static final BooleanFlag ENABLE_RESPONSIVE_WORKSPACE = getDebugFlag(241386436, 211 "ENABLE_RESPONSIVE_WORKSPACE", DISABLED, 212 "Enables new workspace grid calculations method."); enableResponsiveWorkspace()213 public static boolean enableResponsiveWorkspace() { 214 return ENABLE_RESPONSIVE_WORKSPACE.get() || Flags.enableResponsiveWorkspace(); 215 } 216 getDebugFlag( int bugId, String key, BooleanFlag flagState, String description)217 public static BooleanFlag getDebugFlag( 218 int bugId, String key, BooleanFlag flagState, String description) { 219 return flagState; 220 } 221 getReleaseFlag( int bugId, String key, BooleanFlag flagState, String description)222 public static BooleanFlag getReleaseFlag( 223 int bugId, String key, BooleanFlag flagState, String description) { 224 return flagState; 225 } 226 227 /** 228 * Enabled state for a flag 229 */ 230 public enum BooleanFlag { 231 ENABLED(true), 232 DISABLED(false); 233 234 private final boolean mValue; 235 BooleanFlag(boolean value)236 BooleanFlag(boolean value) { 237 mValue = value; 238 } 239 get()240 public boolean get() { 241 return mValue; 242 } 243 } 244 } 245