• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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