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