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.settings.development; 18 19 import static android.service.quicksettings.TileService.ACTION_QS_TILE_PREFERENCES; 20 21 import android.app.Activity; 22 import android.app.settings.SettingsEnums; 23 import android.bluetooth.BluetoothA2dp; 24 import android.bluetooth.BluetoothAdapter; 25 import android.bluetooth.BluetoothCodecStatus; 26 import android.bluetooth.BluetoothProfile; 27 import android.content.BroadcastReceiver; 28 import android.content.ComponentName; 29 import android.content.Context; 30 import android.content.Intent; 31 import android.content.IntentFilter; 32 import android.os.Bundle; 33 import android.os.SystemProperties; 34 import android.os.UserManager; 35 import android.text.TextUtils; 36 import android.util.Log; 37 import android.view.LayoutInflater; 38 import android.view.View; 39 import android.view.ViewGroup; 40 import android.widget.Switch; 41 42 import androidx.annotation.VisibleForTesting; 43 import androidx.localbroadcastmanager.content.LocalBroadcastManager; 44 45 import com.android.settings.R; 46 import com.android.settings.SettingsActivity; 47 import com.android.settings.Utils; 48 import com.android.settings.core.SubSettingLauncher; 49 import com.android.settings.dashboard.RestrictedDashboardFragment; 50 import com.android.settings.development.autofill.AutofillLoggingLevelPreferenceController; 51 import com.android.settings.development.autofill.AutofillResetOptionsPreferenceController; 52 import com.android.settings.development.bluetooth.AbstractBluetoothDialogPreferenceController; 53 import com.android.settings.development.bluetooth.AbstractBluetoothPreferenceController; 54 import com.android.settings.development.bluetooth.BluetoothBitPerSampleDialogPreferenceController; 55 import com.android.settings.development.bluetooth.BluetoothChannelModeDialogPreferenceController; 56 import com.android.settings.development.bluetooth.BluetoothCodecDialogPreferenceController; 57 import com.android.settings.development.bluetooth.BluetoothHDAudioPreferenceController; 58 import com.android.settings.development.bluetooth.BluetoothQualityDialogPreferenceController; 59 import com.android.settings.development.bluetooth.BluetoothSampleRateDialogPreferenceController; 60 import com.android.settings.development.qstile.DevelopmentTiles; 61 import com.android.settings.development.storage.SharedDataPreferenceController; 62 import com.android.settings.search.BaseSearchIndexProvider; 63 import com.android.settings.search.actionbar.SearchMenuController; 64 import com.android.settings.widget.SettingsMainSwitchBar; 65 import com.android.settingslib.core.AbstractPreferenceController; 66 import com.android.settingslib.core.lifecycle.Lifecycle; 67 import com.android.settingslib.development.DeveloperOptionsPreferenceController; 68 import com.android.settingslib.development.DevelopmentSettingsEnabler; 69 import com.android.settingslib.development.SystemPropPoker; 70 import com.android.settingslib.search.SearchIndexable; 71 import com.android.settingslib.widget.OnMainSwitchChangeListener; 72 73 import com.google.android.setupcompat.util.WizardManagerHelper; 74 75 import java.util.ArrayList; 76 import java.util.List; 77 78 @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC) 79 public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFragment 80 implements OnMainSwitchChangeListener, OemUnlockDialogHost, AdbDialogHost, 81 AdbClearKeysDialogHost, LogPersistDialogHost, 82 BluetoothA2dpHwOffloadRebootDialog.OnA2dpHwDialogConfirmedListener, 83 AbstractBluetoothPreferenceController.Callback { 84 85 private static final String TAG = "DevSettingsDashboard"; 86 87 private final BluetoothA2dpConfigStore mBluetoothA2dpConfigStore = 88 new BluetoothA2dpConfigStore(); 89 90 private boolean mIsAvailable = true; 91 private SettingsMainSwitchBar mSwitchBar; 92 private DevelopmentSwitchBarController mSwitchBarController; 93 private List<AbstractPreferenceController> mPreferenceControllers = new ArrayList<>(); 94 private BluetoothA2dp mBluetoothA2dp; 95 96 private final BroadcastReceiver mEnableAdbReceiver = new BroadcastReceiver() { 97 @Override 98 public void onReceive(Context context, Intent intent) { 99 for (AbstractPreferenceController controller : mPreferenceControllers) { 100 if (controller instanceof AdbOnChangeListener) { 101 ((AdbOnChangeListener) controller).onAdbSettingChanged(); 102 } 103 } 104 } 105 }; 106 107 private final BroadcastReceiver mBluetoothA2dpReceiver = new BroadcastReceiver() { 108 @Override 109 public void onReceive(Context context, Intent intent) { 110 Log.d(TAG, "mBluetoothA2dpReceiver.onReceive intent=" + intent); 111 String action = intent.getAction(); 112 113 if (BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED.equals(action)) { 114 BluetoothCodecStatus codecStatus = intent.getParcelableExtra( 115 BluetoothCodecStatus.EXTRA_CODEC_STATUS); 116 Log.d(TAG, "Received BluetoothCodecStatus=" + codecStatus); 117 for (AbstractPreferenceController controller : mPreferenceControllers) { 118 if (controller instanceof BluetoothServiceConnectionListener) { 119 ((BluetoothServiceConnectionListener) controller).onBluetoothCodecUpdated(); 120 } 121 } 122 } 123 } 124 }; 125 126 127 private final BluetoothProfile.ServiceListener mBluetoothA2dpServiceListener = 128 new BluetoothProfile.ServiceListener() { 129 @Override 130 public void onServiceConnected(int profile, 131 BluetoothProfile proxy) { 132 synchronized (mBluetoothA2dpConfigStore) { 133 mBluetoothA2dp = (BluetoothA2dp) proxy; 134 } 135 for (AbstractPreferenceController controller : mPreferenceControllers) { 136 if (controller instanceof BluetoothServiceConnectionListener) { 137 ((BluetoothServiceConnectionListener) controller) 138 .onBluetoothServiceConnected(mBluetoothA2dp); 139 } 140 } 141 } 142 143 @Override 144 public void onServiceDisconnected(int profile) { 145 synchronized (mBluetoothA2dpConfigStore) { 146 mBluetoothA2dp = null; 147 } 148 for (AbstractPreferenceController controller : mPreferenceControllers) { 149 if (controller instanceof BluetoothServiceConnectionListener) { 150 ((BluetoothServiceConnectionListener) controller) 151 .onBluetoothServiceDisconnected(); 152 } 153 } 154 } 155 }; 156 157 private final Runnable mSystemPropertiesChanged = new Runnable() { 158 @Override 159 public void run() { 160 synchronized (this) { 161 Activity activity = getActivity(); 162 if (activity != null) { 163 activity.runOnUiThread(() -> { 164 updatePreferenceStates(); 165 }); 166 } 167 } 168 } 169 }; 170 DevelopmentSettingsDashboardFragment()171 public DevelopmentSettingsDashboardFragment() { 172 super(UserManager.DISALLOW_DEBUGGING_FEATURES); 173 } 174 175 @Override onCreate(Bundle icicle)176 public void onCreate(Bundle icicle) { 177 super.onCreate(icicle); 178 SearchMenuController.init(this); 179 if (Utils.isMonkeyRunning()) { 180 getActivity().finish(); 181 return; 182 } 183 } 184 185 @Override onActivityCreated(Bundle icicle)186 public void onActivityCreated(Bundle icicle) { 187 super.onActivityCreated(icicle); 188 // Apply page-level restrictions 189 setIfOnlyAvailableForAdmins(true); 190 if (isUiRestricted() || !WizardManagerHelper.isDeviceProvisioned(getActivity())) { 191 // Block access to developer options if the user is not the owner, if user policy 192 // restricts it, or if the device has not been provisioned 193 mIsAvailable = false; 194 // Show error message 195 if (!isUiRestrictedByOnlyAdmin()) { 196 getEmptyTextView().setText(R.string.development_settings_not_available); 197 } 198 getPreferenceScreen().removeAll(); 199 return; 200 } 201 // Set up primary switch 202 mSwitchBar = ((SettingsActivity) getActivity()).getSwitchBar(); 203 mSwitchBar.setTitle(getContext().getString(R.string.developer_options_main_switch_title)); 204 mSwitchBar.show(); 205 mSwitchBarController = new DevelopmentSwitchBarController( 206 this /* DevelopmentSettings */, mSwitchBar, mIsAvailable, 207 getSettingsLifecycle()); 208 209 // Restore UI state based on whether developer options is enabled 210 if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext())) { 211 enableDeveloperOptions(); 212 handleQsTileLongPressActionIfAny(); 213 } else { 214 disableDeveloperOptions(); 215 } 216 } 217 218 /** 219 * Long-pressing a developer options quick settings tile will by default (see 220 * QS_TILE_PREFERENCES in the manifest) take you to the developer options page. 221 * Some tiles may want to go into their own page within the developer options. 222 */ handleQsTileLongPressActionIfAny()223 private void handleQsTileLongPressActionIfAny() { 224 Intent intent = getActivity().getIntent(); 225 if (intent == null || !TextUtils.equals(ACTION_QS_TILE_PREFERENCES, intent.getAction())) { 226 return; 227 } 228 229 Log.d(TAG, "Developer options started from qstile long-press"); 230 final ComponentName componentName = (ComponentName) intent.getParcelableExtra( 231 Intent.EXTRA_COMPONENT_NAME); 232 if (componentName == null) { 233 return; 234 } 235 236 if (DevelopmentTiles.WirelessDebugging.class.getName().equals( 237 componentName.getClassName()) && getDevelopmentOptionsController( 238 WirelessDebuggingPreferenceController.class).isAvailable()) { 239 Log.d(TAG, "Long press from wireless debugging qstile"); 240 new SubSettingLauncher(getContext()) 241 .setDestination(WirelessDebuggingFragment.class.getName()) 242 .setSourceMetricsCategory(SettingsEnums.SETTINGS_ADB_WIRELESS) 243 .launch(); 244 } 245 // Add other qstiles here 246 } 247 248 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)249 public View onCreateView(LayoutInflater inflater, ViewGroup container, 250 Bundle savedInstanceState) { 251 registerReceivers(); 252 SystemProperties.addChangeCallback(mSystemPropertiesChanged); 253 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 254 if (adapter != null) { 255 adapter.getProfileProxy(getActivity(), mBluetoothA2dpServiceListener, 256 BluetoothProfile.A2DP); 257 } 258 return super.onCreateView(inflater, container, savedInstanceState); 259 } 260 261 @Override onDestroyView()262 public void onDestroyView() { 263 super.onDestroyView(); 264 unregisterReceivers(); 265 266 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 267 if (adapter != null) { 268 adapter.closeProfileProxy(BluetoothProfile.A2DP, mBluetoothA2dp); 269 mBluetoothA2dp = null; 270 } 271 SystemProperties.removeChangeCallback(mSystemPropertiesChanged); 272 } 273 274 @Override getMetricsCategory()275 public int getMetricsCategory() { 276 return SettingsEnums.DEVELOPMENT; 277 } 278 279 @Override onSwitchChanged(Switch switchView, boolean isChecked)280 public void onSwitchChanged(Switch switchView, boolean isChecked) { 281 if (switchView != mSwitchBar.getSwitch()) { 282 return; 283 } 284 final boolean developmentEnabledState = 285 DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext()); 286 if (isChecked != developmentEnabledState) { 287 if (isChecked) { 288 EnableDevelopmentSettingWarningDialog.show(this /* host */); 289 } else { 290 final BluetoothA2dpHwOffloadPreferenceController controller = 291 getDevelopmentOptionsController( 292 BluetoothA2dpHwOffloadPreferenceController.class); 293 // If A2DP hardware offload isn't default value, we must reboot after disable 294 // developer options. Show a dialog for the user to confirm. 295 if (controller == null || controller.isDefaultValue()) { 296 disableDeveloperOptions(); 297 } else { 298 DisableDevSettingsDialogFragment.show(this /* host */); 299 } 300 } 301 } 302 } 303 304 @Override onOemUnlockDialogConfirmed()305 public void onOemUnlockDialogConfirmed() { 306 final OemUnlockPreferenceController controller = getDevelopmentOptionsController( 307 OemUnlockPreferenceController.class); 308 controller.onOemUnlockConfirmed(); 309 } 310 311 @Override onOemUnlockDialogDismissed()312 public void onOemUnlockDialogDismissed() { 313 final OemUnlockPreferenceController controller = getDevelopmentOptionsController( 314 OemUnlockPreferenceController.class); 315 controller.onOemUnlockDismissed(); 316 } 317 318 @Override onEnableAdbDialogConfirmed()319 public void onEnableAdbDialogConfirmed() { 320 final AdbPreferenceController controller = getDevelopmentOptionsController( 321 AdbPreferenceController.class); 322 controller.onAdbDialogConfirmed(); 323 324 } 325 326 @Override onEnableAdbDialogDismissed()327 public void onEnableAdbDialogDismissed() { 328 final AdbPreferenceController controller = getDevelopmentOptionsController( 329 AdbPreferenceController.class); 330 controller.onAdbDialogDismissed(); 331 } 332 333 @Override onAdbClearKeysDialogConfirmed()334 public void onAdbClearKeysDialogConfirmed() { 335 final ClearAdbKeysPreferenceController controller = getDevelopmentOptionsController( 336 ClearAdbKeysPreferenceController.class); 337 controller.onClearAdbKeysConfirmed(); 338 } 339 340 @Override onDisableLogPersistDialogConfirmed()341 public void onDisableLogPersistDialogConfirmed() { 342 final LogPersistPreferenceController controller = getDevelopmentOptionsController( 343 LogPersistPreferenceController.class); 344 controller.onDisableLogPersistDialogConfirmed(); 345 } 346 347 @Override onDisableLogPersistDialogRejected()348 public void onDisableLogPersistDialogRejected() { 349 final LogPersistPreferenceController controller = getDevelopmentOptionsController( 350 LogPersistPreferenceController.class); 351 controller.onDisableLogPersistDialogRejected(); 352 } 353 354 @Override onA2dpHwDialogConfirmed()355 public void onA2dpHwDialogConfirmed() { 356 final BluetoothA2dpHwOffloadPreferenceController controller = 357 getDevelopmentOptionsController(BluetoothA2dpHwOffloadPreferenceController.class); 358 controller.onA2dpHwDialogConfirmed(); 359 } 360 361 @Override onActivityResult(int requestCode, int resultCode, Intent data)362 public void onActivityResult(int requestCode, int resultCode, Intent data) { 363 boolean handledResult = false; 364 for (AbstractPreferenceController controller : mPreferenceControllers) { 365 if (controller instanceof OnActivityResultListener) { 366 // We do not break early because it is possible for multiple controllers to 367 // handle the same result code. 368 handledResult |= 369 ((OnActivityResultListener) controller).onActivityResult( 370 requestCode, resultCode, data); 371 } 372 } 373 if (!handledResult) { 374 super.onActivityResult(requestCode, resultCode, data); 375 } 376 } 377 378 @Override getLogTag()379 protected String getLogTag() { 380 return TAG; 381 } 382 383 @Override getHelpResource()384 public int getHelpResource() { 385 return 0; 386 } 387 388 @Override getPreferenceScreenResId()389 protected int getPreferenceScreenResId() { 390 return Utils.isMonkeyRunning() ? R.xml.placeholder_prefs : R.xml.development_settings; 391 } 392 393 @Override createPreferenceControllers(Context context)394 protected List<AbstractPreferenceController> createPreferenceControllers(Context context) { 395 if (Utils.isMonkeyRunning()) { 396 mPreferenceControllers = new ArrayList<>(); 397 return null; 398 } 399 mPreferenceControllers = buildPreferenceControllers(context, getActivity(), 400 getSettingsLifecycle(), this /* devOptionsDashboardFragment */, 401 new BluetoothA2dpConfigStore()); 402 return mPreferenceControllers; 403 } 404 registerReceivers()405 private void registerReceivers() { 406 LocalBroadcastManager.getInstance(getContext()) 407 .registerReceiver(mEnableAdbReceiver, new IntentFilter( 408 AdbPreferenceController.ACTION_ENABLE_ADB_STATE_CHANGED)); 409 410 final IntentFilter filter = new IntentFilter(); 411 filter.addAction(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED); 412 getActivity().registerReceiver(mBluetoothA2dpReceiver, filter); 413 } 414 unregisterReceivers()415 private void unregisterReceivers() { 416 LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mEnableAdbReceiver); 417 getActivity().unregisterReceiver(mBluetoothA2dpReceiver); 418 } 419 enableDeveloperOptions()420 private void enableDeveloperOptions() { 421 if (Utils.isMonkeyRunning()) { 422 return; 423 } 424 DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), true); 425 for (AbstractPreferenceController controller : mPreferenceControllers) { 426 if (controller instanceof DeveloperOptionsPreferenceController) { 427 ((DeveloperOptionsPreferenceController) controller).onDeveloperOptionsEnabled(); 428 } 429 } 430 } 431 disableDeveloperOptions()432 private void disableDeveloperOptions() { 433 if (Utils.isMonkeyRunning()) { 434 return; 435 } 436 DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), false); 437 final SystemPropPoker poker = SystemPropPoker.getInstance(); 438 poker.blockPokes(); 439 for (AbstractPreferenceController controller : mPreferenceControllers) { 440 if (controller instanceof DeveloperOptionsPreferenceController) { 441 ((DeveloperOptionsPreferenceController) controller) 442 .onDeveloperOptionsDisabled(); 443 } 444 } 445 poker.unblockPokes(); 446 poker.poke(); 447 } 448 onEnableDevelopmentOptionsConfirmed()449 void onEnableDevelopmentOptionsConfirmed() { 450 enableDeveloperOptions(); 451 } 452 onEnableDevelopmentOptionsRejected()453 void onEnableDevelopmentOptionsRejected() { 454 // Reset the toggle 455 mSwitchBar.setChecked(false); 456 } 457 onDisableDevelopmentOptionsConfirmed()458 void onDisableDevelopmentOptionsConfirmed() { 459 disableDeveloperOptions(); 460 } 461 onDisableDevelopmentOptionsRejected()462 void onDisableDevelopmentOptionsRejected() { 463 // Reset the toggle 464 mSwitchBar.setChecked(true); 465 } 466 buildPreferenceControllers(Context context, Activity activity, Lifecycle lifecycle, DevelopmentSettingsDashboardFragment fragment, BluetoothA2dpConfigStore bluetoothA2dpConfigStore)467 private static List<AbstractPreferenceController> buildPreferenceControllers(Context context, 468 Activity activity, Lifecycle lifecycle, DevelopmentSettingsDashboardFragment fragment, 469 BluetoothA2dpConfigStore bluetoothA2dpConfigStore) { 470 final List<AbstractPreferenceController> controllers = new ArrayList<>(); 471 controllers.add(new MemoryUsagePreferenceController(context)); 472 controllers.add(new BugReportPreferenceController(context)); 473 controllers.add(new BugReportHandlerPreferenceController(context)); 474 controllers.add(new SystemServerHeapDumpPreferenceController(context)); 475 controllers.add(new LocalBackupPasswordPreferenceController(context)); 476 controllers.add(new StayAwakePreferenceController(context, lifecycle)); 477 controllers.add(new HdcpCheckingPreferenceController(context)); 478 controllers.add(new BluetoothSnoopLogPreferenceController(context)); 479 controllers.add(new OemUnlockPreferenceController(context, activity, fragment)); 480 controllers.add(new FileEncryptionPreferenceController(context)); 481 controllers.add(new PictureColorModePreferenceController(context, lifecycle)); 482 controllers.add(new WebViewAppPreferenceController(context)); 483 controllers.add(new CoolColorTemperaturePreferenceController(context)); 484 controllers.add(new DisableAutomaticUpdatesPreferenceController(context)); 485 controllers.add(new SelectDSUPreferenceController(context)); 486 controllers.add(new AdbPreferenceController(context, fragment)); 487 controllers.add(new ClearAdbKeysPreferenceController(context, fragment)); 488 controllers.add(new WirelessDebuggingPreferenceController(context, lifecycle)); 489 controllers.add(new AdbAuthorizationTimeoutPreferenceController(context)); 490 controllers.add(new LocalTerminalPreferenceController(context)); 491 controllers.add(new BugReportInPowerPreferenceController(context)); 492 controllers.add(new AutomaticSystemServerHeapDumpPreferenceController(context)); 493 controllers.add(new MockLocationAppPreferenceController(context, fragment)); 494 controllers.add(new DebugViewAttributesPreferenceController(context)); 495 controllers.add(new SelectDebugAppPreferenceController(context, fragment)); 496 controllers.add(new WaitForDebuggerPreferenceController(context)); 497 controllers.add(new EnableGpuDebugLayersPreferenceController(context)); 498 controllers.add(new ForcePeakRefreshRatePreferenceController(context)); 499 controllers.add(new EnableVerboseVendorLoggingPreferenceController(context)); 500 controllers.add(new VerifyAppsOverUsbPreferenceController(context)); 501 controllers.add(new ArtVerifierPreferenceController(context)); 502 controllers.add(new LogdSizePreferenceController(context)); 503 controllers.add(new LogPersistPreferenceController(context, fragment, lifecycle)); 504 controllers.add(new CameraLaserSensorPreferenceController(context)); 505 controllers.add(new WifiDisplayCertificationPreferenceController(context)); 506 controllers.add(new WifiVerboseLoggingPreferenceController(context)); 507 controllers.add(new WifiScanThrottlingPreferenceController(context)); 508 controllers.add(new WifiEnhancedMacRandomizationPreferenceController(context)); 509 controllers.add(new MobileDataAlwaysOnPreferenceController(context)); 510 controllers.add(new TetheringHardwareAccelPreferenceController(context)); 511 controllers.add(new BluetoothDeviceNoNamePreferenceController(context)); 512 controllers.add(new BluetoothAbsoluteVolumePreferenceController(context)); 513 controllers.add(new BluetoothGabeldorschePreferenceController(context)); 514 controllers.add(new BluetoothAvrcpVersionPreferenceController(context)); 515 controllers.add(new BluetoothMapVersionPreferenceController(context)); 516 controllers.add(new BluetoothA2dpHwOffloadPreferenceController(context, fragment)); 517 controllers.add(new BluetoothMaxConnectedAudioDevicesPreferenceController(context)); 518 controllers.add(new ShowTapsPreferenceController(context)); 519 controllers.add(new PointerLocationPreferenceController(context)); 520 controllers.add(new ShowSurfaceUpdatesPreferenceController(context)); 521 controllers.add(new ShowLayoutBoundsPreferenceController(context)); 522 controllers.add(new ShowRefreshRatePreferenceController(context)); 523 controllers.add(new RtlLayoutPreferenceController(context)); 524 controllers.add(new WindowAnimationScalePreferenceController(context)); 525 controllers.add(new EmulateDisplayCutoutPreferenceController(context)); 526 controllers.add(new TransitionAnimationScalePreferenceController(context)); 527 controllers.add(new AnimatorDurationScalePreferenceController(context)); 528 controllers.add(new SecondaryDisplayPreferenceController(context)); 529 controllers.add(new GpuViewUpdatesPreferenceController(context)); 530 controllers.add(new HardwareLayersUpdatesPreferenceController(context)); 531 controllers.add(new DebugGpuOverdrawPreferenceController(context)); 532 controllers.add(new DebugNonRectClipOperationsPreferenceController(context)); 533 controllers.add(new ForceDarkPreferenceController(context)); 534 controllers.add(new EnableBlursPreferenceController(context)); 535 controllers.add(new ForceMSAAPreferenceController(context)); 536 controllers.add(new HardwareOverlaysPreferenceController(context)); 537 controllers.add(new SimulateColorSpacePreferenceController(context)); 538 controllers.add(new UsbAudioRoutingPreferenceController(context)); 539 controllers.add(new StrictModePreferenceController(context)); 540 controllers.add(new ProfileGpuRenderingPreferenceController(context)); 541 controllers.add(new KeepActivitiesPreferenceController(context)); 542 controllers.add(new BackgroundProcessLimitPreferenceController(context)); 543 controllers.add(new CachedAppsFreezerPreferenceController(context)); 544 controllers.add(new ShowFirstCrashDialogPreferenceController(context)); 545 controllers.add(new AppsNotRespondingPreferenceController(context)); 546 controllers.add(new NotificationChannelWarningsPreferenceController(context)); 547 controllers.add(new AllowAppsOnExternalPreferenceController(context)); 548 controllers.add(new ResizableActivityPreferenceController(context)); 549 controllers.add(new FreeformWindowsPreferenceController(context)); 550 controllers.add(new DesktopModePreferenceController(context)); 551 controllers.add(new NonResizableMultiWindowPreferenceController(context)); 552 controllers.add(new ShortcutManagerThrottlingPreferenceController(context)); 553 controllers.add(new EnableGnssRawMeasFullTrackingPreferenceController(context)); 554 controllers.add(new DefaultLaunchPreferenceController(context, "running_apps")); 555 controllers.add(new DefaultLaunchPreferenceController(context, "demo_mode")); 556 controllers.add(new DefaultLaunchPreferenceController(context, "quick_settings_tiles")); 557 controllers.add(new DefaultLaunchPreferenceController(context, "feature_flags_dashboard")); 558 controllers.add(new DefaultUsbConfigurationPreferenceController(context)); 559 controllers.add(new DefaultLaunchPreferenceController(context, "density")); 560 controllers.add(new DefaultLaunchPreferenceController(context, "background_check")); 561 controllers.add(new DefaultLaunchPreferenceController(context, "inactive_apps")); 562 controllers.add(new AutofillLoggingLevelPreferenceController(context, lifecycle)); 563 controllers.add(new AutofillResetOptionsPreferenceController(context)); 564 controllers.add(new BluetoothCodecDialogPreferenceController(context, lifecycle, 565 bluetoothA2dpConfigStore, fragment)); 566 controllers.add(new BluetoothSampleRateDialogPreferenceController(context, lifecycle, 567 bluetoothA2dpConfigStore)); 568 controllers.add(new BluetoothBitPerSampleDialogPreferenceController(context, lifecycle, 569 bluetoothA2dpConfigStore)); 570 controllers.add(new BluetoothQualityDialogPreferenceController(context, lifecycle, 571 bluetoothA2dpConfigStore)); 572 controllers.add(new BluetoothChannelModeDialogPreferenceController(context, lifecycle, 573 bluetoothA2dpConfigStore)); 574 controllers.add(new BluetoothHDAudioPreferenceController(context, lifecycle, 575 bluetoothA2dpConfigStore, fragment)); 576 controllers.add(new SharedDataPreferenceController(context)); 577 controllers.add(new OverlaySettingsPreferenceController(context)); 578 579 return controllers; 580 } 581 582 @VisibleForTesting getDevelopmentOptionsController(Class<T> clazz)583 <T extends AbstractPreferenceController> T getDevelopmentOptionsController(Class<T> clazz) { 584 return use(clazz); 585 } 586 587 @Override onBluetoothCodecChanged()588 public void onBluetoothCodecChanged() { 589 for (AbstractPreferenceController controller : mPreferenceControllers) { 590 if (controller instanceof AbstractBluetoothDialogPreferenceController 591 && !(controller instanceof BluetoothCodecDialogPreferenceController)) { 592 ((AbstractBluetoothDialogPreferenceController) controller) 593 .onBluetoothCodecUpdated(); 594 } 595 } 596 } 597 598 @Override onBluetoothHDAudioEnabled(boolean enabled)599 public void onBluetoothHDAudioEnabled(boolean enabled) { 600 for (AbstractPreferenceController controller : mPreferenceControllers) { 601 if (controller instanceof AbstractBluetoothDialogPreferenceController) { 602 ((AbstractBluetoothDialogPreferenceController) controller).onHDAudioEnabled( 603 enabled); 604 } 605 } 606 } 607 608 /** 609 * For Search. 610 */ 611 public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 612 new BaseSearchIndexProvider(R.xml.development_settings) { 613 614 @Override 615 protected boolean isPageSearchEnabled(Context context) { 616 return DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(context); 617 } 618 619 @Override 620 public List<AbstractPreferenceController> createPreferenceControllers(Context 621 context) { 622 return buildPreferenceControllers(context, null /* activity */, 623 null /* lifecycle */, null /* devOptionsDashboardFragment */, 624 null /* bluetoothA2dpConfigStore */); 625 } 626 }; 627 } 628