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 android.util; 18 19 import android.annotation.TestApi; 20 import android.content.Context; 21 import android.os.SystemProperties; 22 import android.provider.Settings; 23 import android.text.TextUtils; 24 25 import java.util.HashMap; 26 import java.util.HashSet; 27 import java.util.Map; 28 import java.util.Set; 29 30 /** 31 * Util class to get feature flag information. 32 * 33 * @hide 34 */ 35 @TestApi 36 public class FeatureFlagUtils { 37 38 public static final String FFLAG_PREFIX = "sys.fflag."; 39 public static final String FFLAG_OVERRIDE_PREFIX = FFLAG_PREFIX + "override."; 40 public static final String PERSIST_PREFIX = "persist." + FFLAG_OVERRIDE_PREFIX; 41 public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid"; 42 public static final String SETTINGS_WIFITRACKER2 = "settings_wifitracker2"; 43 /** @hide */ 44 public static final String SETTINGS_DO_NOT_RESTORE_PRESERVED = 45 "settings_do_not_restore_preserved"; 46 /** @hide */ 47 public static final String SETTINGS_USE_NEW_BACKUP_ELIGIBILITY_RULES 48 = "settings_use_new_backup_eligibility_rules"; 49 /** @hide */ 50 public static final String SETTINGS_ENABLE_SECURITY_HUB = "settings_enable_security_hub"; 51 /** @hide */ 52 public static final String SETTINGS_SUPPORT_LARGE_SCREEN = "settings_support_large_screen"; 53 54 /** 55 * Support locale opt-out and opt-in switch for per app's language. 56 * @hide 57 */ 58 public static final String SETTINGS_APP_LOCALE_OPT_IN_ENABLED = 59 "settings_app_locale_opt_in_enabled"; 60 61 /** 62 * Launch the Volume panel in SystemUI. 63 * @hide 64 */ 65 public static final String SETTINGS_VOLUME_PANEL_IN_SYSTEMUI = 66 "settings_volume_panel_in_systemui"; 67 68 /** @hide */ 69 public static final String SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS = 70 "settings_enable_monitor_phantom_procs"; 71 72 /** 73 * Support dark theme activation at Bedtime. 74 * @hide 75 */ 76 public static final String SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME = 77 "settings_app_allow_dark_theme_activation_at_bedtime"; 78 79 /** 80 * Flag to decouple bluetooth LE Audio Broadcast from Unicast 81 * If the flag is true, the broadcast feature will be enabled when the phone 82 * is connected to the BLE device. 83 * If the flag is false, it is not necessary to connect the BLE device. 84 * @hide 85 */ 86 public static final String SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST = 87 "settings_need_connected_ble_device_for_broadcast"; 88 89 /** 90 * Enable new modifier key settings UI 91 * @hide 92 */ 93 public static final String SETTINGS_NEW_KEYBOARD_MODIFIER_KEY = 94 "settings_new_keyboard_modifier_key"; 95 96 /** 97 * Enable new trackpad settings UI 98 * @hide 99 */ 100 public static final String SETTINGS_NEW_KEYBOARD_TRACKPAD = "settings_new_keyboard_trackpad"; 101 102 /** 103 * Enable the new pages which is implemented with SPA. 104 * @hide 105 */ 106 public static final String SETTINGS_ENABLE_SPA = "settings_enable_spa"; 107 108 /** 109 * Enable new pages implemented with SPA besides the SPA pages controlled by the {@code 110 * settings_enable_spa} flag. 111 * @hide 112 */ 113 public static final String SETTINGS_ENABLE_SPA_PHASE2 = "settings_enable_spa_phase2"; 114 115 /** 116 * Enable the SPA metrics writing. 117 * @hide 118 */ 119 public static final String SETTINGS_ENABLE_SPA_METRICS = "settings_enable_spa_metrics"; 120 121 /** Flag to enable/disable adb log metrics 122 * @hide 123 */ 124 public static final String SETTINGS_ADB_METRICS_WRITER = "settings_adb_metrics_writer"; 125 126 /** 127 * Flag to show stylus-specific preferences in Connected Devices 128 * @hide 129 */ 130 public static final String SETTINGS_SHOW_STYLUS_PREFERENCES = 131 "settings_show_stylus_preferences"; 132 133 /** 134 * Flag to enable/disable FingerprintSettings v2 135 * @hide 136 */ 137 public static final String SETTINGS_BIOMETRICS2_FINGERPRINT_SETTINGS = 138 "settings_biometrics2_fingerprint"; 139 140 /** 141 * Flag to enable/disable remote auth enrollment and settings 142 * @hide 143 */ 144 public static final String SETTINGS_REMOTEAUTH_ENROLLMENT_SETTINGS = 145 "settings_remoteauth_enrollment"; 146 147 /** 148 * Flag to enable/disable preferring the AccessibilityMenu service in the system. 149 * @hide 150 */ 151 public static final String SETTINGS_PREFER_ACCESSIBILITY_MENU_IN_SYSTEM = 152 "settings_prefer_accessibility_menu_in_system"; 153 154 /** Flag to enable/disable audio routing change 155 * @hide 156 */ 157 public static final String SETTINGS_AUDIO_ROUTING = "settings_audio_routing"; 158 159 /** Flag to enable/disable flash notifications 160 * @hide 161 */ 162 public static final String SETTINGS_FLASH_NOTIFICATIONS = "settings_flash_notifications"; 163 164 /** 165 * Flag to enable lock screen credentials transfer API in Android U. 166 * @hide 167 */ 168 public static final String SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API = 169 "settings_enable_lockscreen_transfer_api"; 170 171 /** 172 * Flag to enable remote device credential validation 173 * @hide 174 */ 175 public static final String SETTINGS_REMOTE_DEVICE_CREDENTIAL_VALIDATION = 176 "settings_remote_device_credential_validation"; 177 178 private static final Map<String, String> DEFAULT_FLAGS; 179 180 static { 181 DEFAULT_FLAGS = new HashMap<>(); 182 DEFAULT_FLAGS.put("settings_audio_switcher", "true"); 183 DEFAULT_FLAGS.put("settings_systemui_theme", "true"); DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false")184 DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false"); 185 DEFAULT_FLAGS.put("settings_wifi_details_datausage_header", "false"); 186 DEFAULT_FLAGS.put("settings_skip_direction_mutable", "true"); DEFAULT_FLAGS.put(SETTINGS_WIFITRACKER2, "true")187 DEFAULT_FLAGS.put(SETTINGS_WIFITRACKER2, "true"); 188 DEFAULT_FLAGS.put("settings_controller_loading_enhancement", "true"); 189 DEFAULT_FLAGS.put("settings_conditionals", "false"); 190 // This flags guards a feature introduced in R and will be removed in the next release 191 // (b/148367230). DEFAULT_FLAGS.put(SETTINGS_DO_NOT_RESTORE_PRESERVED, "true")192 DEFAULT_FLAGS.put(SETTINGS_DO_NOT_RESTORE_PRESERVED, "true"); 193 194 DEFAULT_FLAGS.put("settings_tether_all_in_one", "false"); 195 DEFAULT_FLAGS.put("settings_contextual_home", "false"); DEFAULT_FLAGS.put(SETTINGS_USE_NEW_BACKUP_ELIGIBILITY_RULES, "true")196 DEFAULT_FLAGS.put(SETTINGS_USE_NEW_BACKUP_ELIGIBILITY_RULES, "true"); DEFAULT_FLAGS.put(SETTINGS_ENABLE_SECURITY_HUB, "true")197 DEFAULT_FLAGS.put(SETTINGS_ENABLE_SECURITY_HUB, "true"); DEFAULT_FLAGS.put(SETTINGS_SUPPORT_LARGE_SCREEN, "true")198 DEFAULT_FLAGS.put(SETTINGS_SUPPORT_LARGE_SCREEN, "true"); 199 DEFAULT_FLAGS.put("settings_search_always_expand", "true"); DEFAULT_FLAGS.put(SETTINGS_APP_LOCALE_OPT_IN_ENABLED, "true")200 DEFAULT_FLAGS.put(SETTINGS_APP_LOCALE_OPT_IN_ENABLED, "true"); DEFAULT_FLAGS.put(SETTINGS_VOLUME_PANEL_IN_SYSTEMUI, "false")201 DEFAULT_FLAGS.put(SETTINGS_VOLUME_PANEL_IN_SYSTEMUI, "false"); DEFAULT_FLAGS.put(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, "true")202 DEFAULT_FLAGS.put(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, "true"); DEFAULT_FLAGS.put(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME, "true")203 DEFAULT_FLAGS.put(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME, "true"); DEFAULT_FLAGS.put(SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, "true")204 DEFAULT_FLAGS.put(SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, "true"); DEFAULT_FLAGS.put(SETTINGS_NEW_KEYBOARD_MODIFIER_KEY, "true")205 DEFAULT_FLAGS.put(SETTINGS_NEW_KEYBOARD_MODIFIER_KEY, "true"); DEFAULT_FLAGS.put(SETTINGS_NEW_KEYBOARD_TRACKPAD, "true")206 DEFAULT_FLAGS.put(SETTINGS_NEW_KEYBOARD_TRACKPAD, "true"); DEFAULT_FLAGS.put(SETTINGS_ENABLE_SPA, "true")207 DEFAULT_FLAGS.put(SETTINGS_ENABLE_SPA, "true"); DEFAULT_FLAGS.put(SETTINGS_ENABLE_SPA_PHASE2, "false")208 DEFAULT_FLAGS.put(SETTINGS_ENABLE_SPA_PHASE2, "false"); DEFAULT_FLAGS.put(SETTINGS_ENABLE_SPA_METRICS, "true")209 DEFAULT_FLAGS.put(SETTINGS_ENABLE_SPA_METRICS, "true"); DEFAULT_FLAGS.put(SETTINGS_ADB_METRICS_WRITER, "false")210 DEFAULT_FLAGS.put(SETTINGS_ADB_METRICS_WRITER, "false"); DEFAULT_FLAGS.put(SETTINGS_SHOW_STYLUS_PREFERENCES, "true")211 DEFAULT_FLAGS.put(SETTINGS_SHOW_STYLUS_PREFERENCES, "true"); DEFAULT_FLAGS.put(SETTINGS_PREFER_ACCESSIBILITY_MENU_IN_SYSTEM, "false")212 DEFAULT_FLAGS.put(SETTINGS_PREFER_ACCESSIBILITY_MENU_IN_SYSTEM, "false"); DEFAULT_FLAGS.put(SETTINGS_AUDIO_ROUTING, "false")213 DEFAULT_FLAGS.put(SETTINGS_AUDIO_ROUTING, "false"); DEFAULT_FLAGS.put(SETTINGS_FLASH_NOTIFICATIONS, "true")214 DEFAULT_FLAGS.put(SETTINGS_FLASH_NOTIFICATIONS, "true"); DEFAULT_FLAGS.put(SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API, "true")215 DEFAULT_FLAGS.put(SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API, "true"); DEFAULT_FLAGS.put(SETTINGS_REMOTE_DEVICE_CREDENTIAL_VALIDATION, "true")216 DEFAULT_FLAGS.put(SETTINGS_REMOTE_DEVICE_CREDENTIAL_VALIDATION, "true"); DEFAULT_FLAGS.put(SETTINGS_BIOMETRICS2_FINGERPRINT_SETTINGS, "false")217 DEFAULT_FLAGS.put(SETTINGS_BIOMETRICS2_FINGERPRINT_SETTINGS, "false"); 218 // TODO: b/298454866 Replace with Trunk Stable Feature Flag DEFAULT_FLAGS.put(SETTINGS_REMOTEAUTH_ENROLLMENT_SETTINGS, "false")219 DEFAULT_FLAGS.put(SETTINGS_REMOTEAUTH_ENROLLMENT_SETTINGS, "false"); 220 } 221 222 private static final Set<String> PERSISTENT_FLAGS; 223 224 static { 225 PERSISTENT_FLAGS = new HashSet<>(); 226 PERSISTENT_FLAGS.add(SETTINGS_APP_LOCALE_OPT_IN_ENABLED); 227 PERSISTENT_FLAGS.add(SETTINGS_SUPPORT_LARGE_SCREEN); 228 PERSISTENT_FLAGS.add(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS); 229 PERSISTENT_FLAGS.add(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME); 230 PERSISTENT_FLAGS.add(SETTINGS_NEW_KEYBOARD_MODIFIER_KEY); 231 PERSISTENT_FLAGS.add(SETTINGS_NEW_KEYBOARD_TRACKPAD); 232 PERSISTENT_FLAGS.add(SETTINGS_ENABLE_SPA); 233 PERSISTENT_FLAGS.add(SETTINGS_ENABLE_SPA_PHASE2); 234 PERSISTENT_FLAGS.add(SETTINGS_PREFER_ACCESSIBILITY_MENU_IN_SYSTEM); 235 } 236 237 /** 238 * Whether or not a flag is enabled. 239 * 240 * @param feature the flag name 241 * @return true if the flag is enabled (either by default in system, or override by user) 242 */ isEnabled(Context context, String feature)243 public static boolean isEnabled(Context context, String feature) { 244 // Override precedence: 245 // Settings.Global -> sys.fflag.override.* -> static list 246 247 // Step 1: check if feature flag is set in Settings.Global. 248 String value; 249 if (context != null) { 250 value = Settings.Global.getString(context.getContentResolver(), feature); 251 if (!TextUtils.isEmpty(value)) { 252 return Boolean.parseBoolean(value); 253 } 254 } 255 256 // Step 2: check if feature flag has any override. 257 // Flag name: [persist.]sys.fflag.override.<feature> 258 value = SystemProperties.get(getSystemPropertyPrefix(feature) + feature); 259 if (!TextUtils.isEmpty(value)) { 260 return Boolean.parseBoolean(value); 261 } 262 // Step 3: check if feature flag has any default value. 263 value = getAllFeatureFlags().get(feature); 264 return Boolean.parseBoolean(value); 265 } 266 267 /** 268 * Override feature flag to new state. 269 */ setEnabled(Context context, String feature, boolean enabled)270 public static void setEnabled(Context context, String feature, boolean enabled) { 271 SystemProperties.set(getSystemPropertyPrefix(feature) + feature, 272 enabled ? "true" : "false"); 273 } 274 275 /** 276 * Returns all feature flags in their raw form. 277 */ getAllFeatureFlags()278 public static Map<String, String> getAllFeatureFlags() { 279 return DEFAULT_FLAGS; 280 } 281 getSystemPropertyPrefix(String feature)282 private static String getSystemPropertyPrefix(String feature) { 283 return PERSISTENT_FLAGS.contains(feature) ? PERSIST_PREFIX : FFLAG_OVERRIDE_PREFIX; 284 } 285 } 286