1 /*
2  * Copyright (C) 2015 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.tv.settings.system.development;
18 
19 import android.Manifest;
20 import android.app.Activity;
21 import android.app.ActivityManager;
22 import android.app.AppOpsManager;
23 import android.app.admin.DevicePolicyManager;
24 import android.app.backup.IBackupManager;
25 import android.content.BroadcastReceiver;
26 import android.content.ComponentName;
27 import android.content.ContentResolver;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.content.IntentFilter;
31 import android.content.pm.ApplicationInfo;
32 import android.content.pm.PackageManager;
33 import android.content.pm.ResolveInfo;
34 import android.hardware.usb.UsbManager;
35 import android.net.wifi.WifiManager;
36 import android.os.BatteryManager;
37 import android.os.Build;
38 import android.os.Bundle;
39 import android.os.IBinder;
40 import android.os.Parcel;
41 import android.os.RemoteException;
42 import android.os.ServiceManager;
43 import android.os.StrictMode;
44 import android.os.SystemProperties;
45 import android.os.UserManager;
46 import android.provider.Settings;
47 import android.service.persistentdata.PersistentDataBlockManager;
48 import android.sysprop.AdbProperties;
49 import android.sysprop.DisplayProperties;
50 import android.text.TextUtils;
51 import android.util.Log;
52 import android.view.IWindowManager;
53 import android.view.LayoutInflater;
54 import android.view.ThreadedRenderer;
55 import android.view.View;
56 import android.view.ViewGroup;
57 import android.view.accessibility.AccessibilityManager;
58 import android.widget.Toast;
59 
60 import androidx.preference.ListPreference;
61 import androidx.preference.Preference;
62 import androidx.preference.PreferenceGroup;
63 import androidx.preference.PreferenceScreen;
64 import androidx.preference.SwitchPreference;
65 
66 import com.android.internal.app.LocalePicker;
67 import com.android.internal.logging.nano.MetricsProto;
68 import com.android.settingslib.core.ConfirmationDialogController;
69 import com.android.settingslib.development.DevelopmentSettingsEnabler;
70 import com.android.settingslib.development.SystemPropPoker;
71 import com.android.tv.settings.R;
72 import com.android.tv.settings.SettingsPreferenceFragment;
73 
74 import java.util.ArrayList;
75 import java.util.HashSet;
76 import java.util.List;
77 
78 /**
79  * Displays preferences for application developers.
80  */
81 public class DevelopmentFragment extends SettingsPreferenceFragment
82         implements Preference.OnPreferenceChangeListener,
83         EnableDevelopmentDialog.Callback, OemUnlockDialog.Callback, AdbDialog.Callback {
84     private static final String TAG = "DevelopmentSettings";
85 
86     private static final String ENABLE_DEVELOPER = "development_settings_enable";
87     private static final String ENABLE_ADB = "enable_adb";
88     private static final String CLEAR_ADB_KEYS = "clear_adb_keys";
89     private static final String ENABLE_TERMINAL = "enable_terminal";
90     private static final String KEEP_SCREEN_ON = "keep_screen_on";
91     private static final String BT_HCI_SNOOP_LOG = "bt_hci_snoop_log";
92     private static final String BTSNOOP_LOG_MODE_PROPERTY = "persist.bluetooth.btsnooplogmode";
93     private static final String ENABLE_OEM_UNLOCK = "oem_unlock_enable";
94     private static final String HDCP_CHECKING_KEY = "hdcp_checking";
95     private static final String HDCP_CHECKING_PROPERTY = "persist.sys.hdcp_checking";
96     private static final String LOCAL_BACKUP_PASSWORD = "local_backup_password";
97     private static final String BUGREPORT = "bugreport";
98     private static final String BUGREPORT_IN_POWER_KEY = "bugreport_in_power";
99     private static final String RUNNING_APPS = "running_apps";
100 
101     private static final String DEBUG_APP_KEY = "debug_app";
102     private static final String WAIT_FOR_DEBUGGER_KEY = "wait_for_debugger";
103     private static final String MOCK_LOCATION_APP_KEY = "mock_location_app";
104     private static final String VERIFY_APPS_OVER_USB_KEY = "verify_apps_over_usb";
105     private static final String DEBUG_VIEW_ATTRIBUTES =  "debug_view_attributes";
106     private static final String FORCE_ALLOW_ON_EXTERNAL_KEY = "force_allow_on_external";
107     private static final String STRICT_MODE_KEY = "strict_mode";
108     private static final String POINTER_LOCATION_KEY = "pointer_location";
109     private static final String SHOW_TOUCHES_KEY = "show_touches";
110     private static final String SHOW_SCREEN_UPDATES_KEY = "show_screen_updates";
111     private static final String DISABLE_OVERLAYS_KEY = "disable_overlays";
112     private static final String SIMULATE_COLOR_SPACE = "simulate_color_space";
113     private static final String USB_AUDIO_KEY = "usb_audio";
114     private static final String FORCE_MSAA_KEY = "force_msaa";
115     private static final String TRACK_FRAME_TIME_KEY = "track_frame_time";
116     private static final String SHOW_NON_RECTANGULAR_CLIP_KEY = "show_non_rect_clip";
117     private static final String SHOW_HW_SCREEN_UPDATES_KEY = "show_hw_screen_udpates";
118     private static final String SHOW_HW_LAYERS_UPDATES_KEY = "show_hw_layers_udpates";
119     private static final String DEBUG_HW_OVERDRAW_KEY = "debug_hw_overdraw";
120     private static final String DEBUG_LAYOUT_KEY = "debug_layout";
121     private static final String FORCE_RTL_LAYOUT_KEY = "force_rtl_layout_all_locales";
122     private static final String WINDOW_ANIMATION_SCALE_KEY = "window_animation_scale";
123     private static final String TRANSITION_ANIMATION_SCALE_KEY = "transition_animation_scale";
124     private static final String ANIMATOR_DURATION_SCALE_KEY = "animator_duration_scale";
125     private static final String OVERLAY_DISPLAY_DEVICES_KEY = "overlay_display_devices";
126     private static final String DEBUG_DEBUGGING_CATEGORY_KEY = "debug_debugging_category";
127 
128     private static final String WIFI_DISPLAY_CERTIFICATION_KEY = "wifi_display_certification";
129     private static final String WIFI_VERBOSE_LOGGING_KEY = "wifi_verbose_logging";
130     private static final String USB_CONFIGURATION_KEY = "select_usb_configuration";
131     private static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on";
132     private static final String KEY_COLOR_MODE = "color_mode";
133     private static final String FORCE_RESIZABLE_KEY = "force_resizable_activities";
134 
135     private static final String INACTIVE_APPS_KEY = "inactive_apps";
136 
137     private static final String OPENGL_TRACES_KEY = "enable_opengl_traces";
138 
139     private static final String IMMEDIATELY_DESTROY_ACTIVITIES_KEY
140             = "immediately_destroy_activities";
141     private static final String APP_PROCESS_LIMIT_KEY = "app_process_limit";
142 
143     private static final String SHOW_ALL_ANRS_KEY = "show_all_anrs";
144 
145     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
146 
147     private static final String TERMINAL_APP_PACKAGE = "com.android.terminal";
148 
149     private static final String KEY_CONVERT_FBE = "convert_to_file_encryption";
150 
151     private static final int RESULT_DEBUG_APP = 1000;
152     private static final int RESULT_MOCK_LOCATION_APP = 1001;
153 
154     private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
155 
156     private static String DEFAULT_LOG_RING_BUFFER_SIZE_IN_BYTES = "262144"; // 256K
157 
158     private static final int[] MOCK_LOCATION_APP_OPS = new int[] {AppOpsManager.OP_MOCK_LOCATION};
159 
160     private static final String STATE_SHOWING_DIALOG_KEY = "showing_dialog_key";
161 
162     private String mPendingDialogKey;
163 
164     private IWindowManager mWindowManager;
165     private IBackupManager mBackupManager;
166     private DevicePolicyManager mDpm;
167     private UserManager mUm;
168     private WifiManager mWifiManager;
169     private ContentResolver mContentResolver;
170 
171     private boolean mLastEnabledState;
172     private boolean mHaveDebugSettings;
173 
174     private SwitchPreference mEnableDeveloper;
175     private SwitchPreference mEnableAdb;
176     private Preference mClearAdbKeys;
177     private SwitchPreference mEnableTerminal;
178     private Preference mBugreport;
179     private SwitchPreference mKeepScreenOn;
180     private ListPreference mBtHciSnoopLog;
181     private SwitchPreference mEnableOemUnlock;
182     private SwitchPreference mDebugViewAttributes;
183     private SwitchPreference mForceAllowOnExternal;
184 
185     private PreferenceScreen mPassword;
186     private String mDebugApp;
187     private Preference mDebugAppPref;
188 
189     private String mMockLocationApp;
190     private Preference mMockLocationAppPref;
191 
192     private SwitchPreference mWaitForDebugger;
193     private SwitchPreference mVerifyAppsOverUsb;
194     private SwitchPreference mWifiDisplayCertification;
195     private SwitchPreference mWifiVerboseLogging;
196     private SwitchPreference mMobileDataAlwaysOn;
197 
198     private SwitchPreference mStrictMode;
199     private SwitchPreference mPointerLocation;
200     private SwitchPreference mShowTouches;
201     private SwitchPreference mShowScreenUpdates;
202     private SwitchPreference mDisableOverlays;
203     private SwitchPreference mForceMsaa;
204     private SwitchPreference mShowHwScreenUpdates;
205     private SwitchPreference mShowHwLayersUpdates;
206     private SwitchPreference mDebugLayout;
207     private SwitchPreference mForceRtlLayout;
208     private ListPreference mDebugHwOverdraw;
209     private LogdSizePreferenceController mLogdSizeController;
210     private LogpersistPreferenceController mLogpersistController;
211     private ListPreference mUsbConfiguration;
212     private ListPreference mTrackFrameTime;
213     private ListPreference mShowNonRectClip;
214     private ListPreference mWindowAnimationScale;
215     private ListPreference mTransitionAnimationScale;
216     private ListPreference mAnimatorDurationScale;
217     private ListPreference mOverlayDisplayDevices;
218     private ListPreference mOpenGLTraces;
219 
220     private ListPreference mSimulateColorSpace;
221 
222     private SwitchPreference mUSBAudio;
223     private SwitchPreference mImmediatelyDestroyActivities;
224 
225     private ListPreference mAppProcessLimit;
226 
227     private SwitchPreference mShowAllANRs;
228 
229     private ColorModePreference mColorModePreference;
230 
231     private SwitchPreference mForceResizable;
232 
233     private final ArrayList<Preference> mAllPrefs = new ArrayList<>();
234 
235     private final ArrayList<SwitchPreference> mResetSwitchPrefs
236             = new ArrayList<>();
237 
238     private final HashSet<Preference> mDisabledPrefs = new HashSet<>();
239 
240     private boolean mUnavailable;
241 
newInstance()242     public static DevelopmentFragment newInstance() {
243         return new DevelopmentFragment();
244     }
245 
246     @Override
getMetricsCategory()247     public int getMetricsCategory() {
248         return MetricsProto.MetricsEvent.DEVELOPMENT;
249     }
250 
251     @Override
onCreate(Bundle icicle)252     public void onCreate(Bundle icicle) {
253 
254         if (icicle != null) {
255             // Don't show this in onCreate since we might be on the back stack
256             mPendingDialogKey = icicle.getString(STATE_SHOWING_DIALOG_KEY);
257         }
258 
259         mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
260         mBackupManager = IBackupManager.Stub.asInterface(
261                 ServiceManager.getService(Context.BACKUP_SERVICE));
262         mDpm = (DevicePolicyManager) getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
263         mUm = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
264 
265         mWifiManager = (WifiManager) getActivity().getSystemService(Context.WIFI_SERVICE);
266 
267         mContentResolver = getActivity().getContentResolver();
268 
269         super.onCreate(icicle);
270     }
271 
272     @Override
onCreatePreferences(Bundle savedInstanceState, String rootKey)273     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
274         mLogdSizeController = new LogdSizePreferenceController(getActivity());
275         mLogpersistController = new LogpersistPreferenceController(getActivity(), getLifecycle());
276 
277         if (!mUm.isAdminUser()
278                 || mUm.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES)
279                 || Settings.Global.getInt(mContentResolver,
280                 Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
281             // Block access to developer options if the user is not the owner, if user policy
282             // restricts it, or if the device has not been provisioned
283             mUnavailable = true;
284             addPreferencesFromResource(R.xml.development_prefs_not_available);
285             return;
286         }
287 
288         addPreferencesFromResource(R.xml.development_prefs);
289         final PreferenceScreen preferenceScreen = getPreferenceScreen();
290 
291         // Don't add to prefs lists or it'll disable itself when switched off
292         mEnableDeveloper = (SwitchPreference) findPreference(ENABLE_DEVELOPER);
293 
294         final PreferenceGroup debugDebuggingCategory = (PreferenceGroup)
295                 findPreference(DEBUG_DEBUGGING_CATEGORY_KEY);
296         mEnableAdb = findAndInitSwitchPref(ENABLE_ADB);
297         mClearAdbKeys = findPreference(CLEAR_ADB_KEYS);
298         if (!AdbProperties.secure().orElse(false)) {
299             if (debugDebuggingCategory != null) {
300                 debugDebuggingCategory.removePreference(mClearAdbKeys);
301             }
302         }
303         mAllPrefs.add(mClearAdbKeys);
304         mEnableTerminal = findAndInitSwitchPref(ENABLE_TERMINAL);
305         if (!isPackageInstalled(getActivity(), TERMINAL_APP_PACKAGE)) {
306             if (debugDebuggingCategory != null) {
307                 debugDebuggingCategory.removePreference(mEnableTerminal);
308             }
309             mEnableTerminal = null;
310         }
311 
312         mBugreport = findPreference(BUGREPORT);
313         mLogdSizeController.displayPreference(preferenceScreen);
314         mLogpersistController.displayPreference(preferenceScreen);
315 
316         mKeepScreenOn = findAndInitSwitchPref(KEEP_SCREEN_ON);
317         mBtHciSnoopLog = addListPreference(BT_HCI_SNOOP_LOG);
318         mEnableOemUnlock = findAndInitSwitchPref(ENABLE_OEM_UNLOCK);
319         if (!showEnableOemUnlockPreference()) {
320             removePreference(mEnableOemUnlock);
321             mEnableOemUnlock = null;
322         }
323 
324         // TODO: implement UI for TV
325         removePreference(RUNNING_APPS);
326 
327         mDebugViewAttributes = findAndInitSwitchPref(DEBUG_VIEW_ATTRIBUTES);
328         mForceAllowOnExternal = findAndInitSwitchPref(FORCE_ALLOW_ON_EXTERNAL_KEY);
329         mPassword = (PreferenceScreen) findPreference(LOCAL_BACKUP_PASSWORD);
330         // We don't have a backup password activity on TV
331         mPassword.setVisible(false);
332         mAllPrefs.add(mPassword);
333 
334         if (!mUm.isAdminUser()) {
335             disableForUser(mEnableAdb);
336             disableForUser(mClearAdbKeys);
337             disableForUser(mEnableTerminal);
338             disableForUser(mPassword);
339         }
340 
341         mDebugAppPref = findPreference(DEBUG_APP_KEY);
342         mAllPrefs.add(mDebugAppPref);
343         mWaitForDebugger = findAndInitSwitchPref(WAIT_FOR_DEBUGGER_KEY);
344 
345         mMockLocationAppPref = findPreference(MOCK_LOCATION_APP_KEY);
346         mAllPrefs.add(mMockLocationAppPref);
347 
348         mVerifyAppsOverUsb = findAndInitSwitchPref(VERIFY_APPS_OVER_USB_KEY);
349         if (!showVerifierSetting()) {
350             if (debugDebuggingCategory != null) {
351                 debugDebuggingCategory.removePreference(mVerifyAppsOverUsb);
352             } else {
353                 mVerifyAppsOverUsb.setEnabled(false);
354             }
355         }
356         mStrictMode = findAndInitSwitchPref(STRICT_MODE_KEY);
357         mPointerLocation = findAndInitSwitchPref(POINTER_LOCATION_KEY);
358         mShowTouches = findAndInitSwitchPref(SHOW_TOUCHES_KEY);
359         mShowScreenUpdates = findAndInitSwitchPref(SHOW_SCREEN_UPDATES_KEY);
360         mDisableOverlays = findAndInitSwitchPref(DISABLE_OVERLAYS_KEY);
361         mForceMsaa = findAndInitSwitchPref(FORCE_MSAA_KEY);
362         mTrackFrameTime = addListPreference(TRACK_FRAME_TIME_KEY);
363         mShowNonRectClip = addListPreference(SHOW_NON_RECTANGULAR_CLIP_KEY);
364         mShowHwScreenUpdates = findAndInitSwitchPref(SHOW_HW_SCREEN_UPDATES_KEY);
365         mShowHwLayersUpdates = findAndInitSwitchPref(SHOW_HW_LAYERS_UPDATES_KEY);
366         mDebugLayout = findAndInitSwitchPref(DEBUG_LAYOUT_KEY);
367         mForceRtlLayout = findAndInitSwitchPref(FORCE_RTL_LAYOUT_KEY);
368         mDebugHwOverdraw = addListPreference(DEBUG_HW_OVERDRAW_KEY);
369         mWifiDisplayCertification = findAndInitSwitchPref(WIFI_DISPLAY_CERTIFICATION_KEY);
370         mWifiVerboseLogging = findAndInitSwitchPref(WIFI_VERBOSE_LOGGING_KEY);
371         mMobileDataAlwaysOn = findAndInitSwitchPref(MOBILE_DATA_ALWAYS_ON);
372         mUsbConfiguration = addListPreference(USB_CONFIGURATION_KEY);
373 
374         mWindowAnimationScale = addListPreference(WINDOW_ANIMATION_SCALE_KEY);
375         mTransitionAnimationScale = addListPreference(TRANSITION_ANIMATION_SCALE_KEY);
376         mAnimatorDurationScale = addListPreference(ANIMATOR_DURATION_SCALE_KEY);
377         mOverlayDisplayDevices = addListPreference(OVERLAY_DISPLAY_DEVICES_KEY);
378         mOpenGLTraces = addListPreference(OPENGL_TRACES_KEY);
379         mSimulateColorSpace = addListPreference(SIMULATE_COLOR_SPACE);
380         mUSBAudio = findAndInitSwitchPref(USB_AUDIO_KEY);
381         mForceResizable = findAndInitSwitchPref(FORCE_RESIZABLE_KEY);
382 
383         mImmediatelyDestroyActivities = (SwitchPreference) findPreference(
384                 IMMEDIATELY_DESTROY_ACTIVITIES_KEY);
385         mAllPrefs.add(mImmediatelyDestroyActivities);
386         mResetSwitchPrefs.add(mImmediatelyDestroyActivities);
387 
388         mAppProcessLimit = addListPreference(APP_PROCESS_LIMIT_KEY);
389 
390         mShowAllANRs = (SwitchPreference) findPreference(
391                 SHOW_ALL_ANRS_KEY);
392         mAllPrefs.add(mShowAllANRs);
393         mResetSwitchPrefs.add(mShowAllANRs);
394 
395         Preference hdcpChecking = findPreference(HDCP_CHECKING_KEY);
396         if (hdcpChecking != null) {
397             mAllPrefs.add(hdcpChecking);
398             removePreferenceForProduction(hdcpChecking);
399         }
400 
401         // TODO: implement UI for TV
402         removePreference(KEY_CONVERT_FBE);
403 /*
404         // Please import android.sysprop.CryptoProperties when you uncomment this block.
405         PreferenceScreen convertFbePreference =
406                 (PreferenceScreen) findPreference(KEY_CONVERT_FBE);
407 
408         try {
409             IBinder service = ServiceManager.getService("mount");
410             IMountService mountService = IMountService.Stub.asInterface(service);
411             if (!mountService.isConvertibleToFBE()) {
412                 removePreference(KEY_CONVERT_FBE);
413             } else if (CryptoProperties.type().orElse(CryptoProperties.type_values.NONE) ==
414                        CryptoProperties.type_values.FILE) {
415                 convertFbePreference.setEnabled(false);
416                 convertFbePreference.setSummary(getResources()
417                         .getString(R.string.convert_to_file_encryption_done));
418             }
419         } catch(RemoteException e) {
420             removePreference(KEY_CONVERT_FBE);
421         }
422 */
423 
424         mColorModePreference = (ColorModePreference) findPreference(KEY_COLOR_MODE);
425         mColorModePreference.updateCurrentAndSupported();
426         if (mColorModePreference.getColorModeCount() < 2) {
427             removePreference(KEY_COLOR_MODE);
428             mColorModePreference = null;
429         }
430     }
431 
removePreference(String key)432     private void removePreference(String key) {
433         final Preference preference = findPreference(key);
434         if (preference != null) {
435             getPreferenceScreen().removePreference(preference);
436         }
437     }
438 
addListPreference(String prefKey)439     private ListPreference addListPreference(String prefKey) {
440         ListPreference pref = (ListPreference) findPreference(prefKey);
441         mAllPrefs.add(pref);
442         pref.setOnPreferenceChangeListener(this);
443         return pref;
444     }
445 
disableForUser(Preference pref)446     private void disableForUser(Preference pref) {
447         if (pref != null) {
448             pref.setEnabled(false);
449             mDisabledPrefs.add(pref);
450         }
451     }
452 
findAndInitSwitchPref(String key)453     private SwitchPreference findAndInitSwitchPref(String key) {
454         SwitchPreference pref = (SwitchPreference) findPreference(key);
455         if (pref == null) {
456             throw new IllegalArgumentException("Cannot find preference with key = " + key);
457         }
458         mAllPrefs.add(pref);
459         mResetSwitchPrefs.add(pref);
460         return pref;
461     }
462 
463     @Override
onActivityCreated(Bundle savedInstanceState)464     public void onActivityCreated(Bundle savedInstanceState) {
465         super.onActivityCreated(savedInstanceState);
466 
467         if (mUnavailable) {
468             if (mEnableDeveloper != null) {
469                 mEnableDeveloper.setEnabled(false);
470             }
471         }
472     }
473 
removePreferenceForProduction(Preference preference)474     private boolean removePreferenceForProduction(Preference preference) {
475         if ("user".equals(Build.TYPE)) {
476             removePreference(preference);
477             return true;
478         }
479         return false;
480     }
481 
removePreference(Preference preference)482     private void removePreference(Preference preference) {
483         getPreferenceScreen().removePreference(preference);
484         mAllPrefs.remove(preference);
485         mResetSwitchPrefs.remove(preference);
486     }
487 
setPrefsEnabledState(boolean enabled)488     private void setPrefsEnabledState(boolean enabled) {
489         for (final Preference pref : mAllPrefs) {
490             pref.setEnabled(enabled && !mDisabledPrefs.contains(pref));
491         }
492         mLogdSizeController.enablePreference(enabled);
493         mLogpersistController.enablePreference(enabled);
494         updateAllOptions();
495     }
496 
497     @Override
onResume()498     public void onResume() {
499         super.onResume();
500 
501         if (mUnavailable) {
502             return;
503         }
504 
505         if (mDpm.getMaximumTimeToLock(null) > 0) {
506             // A DeviceAdmin has specified a maximum time until the device
507             // will lock...  in this case we can't allow the user to turn
508             // on "stay awake when plugged in" because that would defeat the
509             // restriction.
510             mDisabledPrefs.add(mKeepScreenOn);
511         } else {
512             mDisabledPrefs.remove(mKeepScreenOn);
513         }
514 
515         mLastEnabledState = DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext());
516         mEnableDeveloper.setChecked(mLastEnabledState);
517         setPrefsEnabledState(mLastEnabledState);
518 
519         if (mHaveDebugSettings && !mLastEnabledState) {
520             // Overall debugging is disabled, but there are some debug
521             // settings that are enabled.  This is an invalid state.  Switch
522             // to debug settings being enabled, so the user knows there is
523             // stuff enabled and can turn it all off if they want.
524             DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), true);
525             mLastEnabledState = true;
526             mEnableDeveloper.setChecked(mLastEnabledState);
527             setPrefsEnabledState(mLastEnabledState);
528         }
529 
530         if (mColorModePreference != null) {
531             mColorModePreference.startListening();
532             mColorModePreference.updateCurrentAndSupported();
533         }
534 
535         if (mPendingDialogKey != null) {
536             recreateDialogForKey(mPendingDialogKey);
537             mPendingDialogKey = null;
538         }
539     }
540 
541     @Override
onPause()542     public void onPause() {
543         super.onPause();
544         if (mColorModePreference != null) {
545             mColorModePreference.stopListening();
546         }
547     }
548 
549     @Override
onSaveInstanceState(Bundle outState)550     public void onSaveInstanceState(Bundle outState) {
551         super.onSaveInstanceState(outState);
552         outState.putString(STATE_SHOWING_DIALOG_KEY, getKeyForShowingDialog());
553     }
554 
555     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)556     public View onCreateView(LayoutInflater inflater, ViewGroup container,
557             Bundle savedInstanceState) {
558         IntentFilter filter = new IntentFilter();
559         filter.addAction(UsbManager.ACTION_USB_STATE);
560         if (getActivity().registerReceiver(mUsbReceiver, filter) == null) {
561             updateUsbConfigurationValues();
562         }
563         return super.onCreateView(inflater, container, savedInstanceState);
564     }
565 
566     @Override
onDestroyView()567     public void onDestroyView() {
568         super.onDestroyView();
569 
570         getActivity().unregisterReceiver(mUsbReceiver);
571     }
572 
573     @Override
onDestroy()574     public void onDestroy() {
575         super.onDestroy();
576         dismissDialogs();
577     }
578 
updateSwitchPreference(SwitchPreference switchPreference, boolean value)579     void updateSwitchPreference(SwitchPreference switchPreference, boolean value) {
580         switchPreference.setChecked(value);
581         mHaveDebugSettings |= value;
582     }
583 
updateAllOptions()584     private void updateAllOptions() {
585         final Context context = getActivity();
586         final ContentResolver cr = context.getContentResolver();
587         mHaveDebugSettings = false;
588         updateSwitchPreference(mEnableAdb, Settings.Global.getInt(cr,
589                 Settings.Global.ADB_ENABLED, 0) != 0);
590         if (mEnableTerminal != null) {
591             updateSwitchPreference(mEnableTerminal,
592                     context.getPackageManager().getApplicationEnabledSetting(TERMINAL_APP_PACKAGE)
593                             == PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
594         }
595         updateSwitchPreference(mKeepScreenOn, Settings.Global.getInt(cr,
596                 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0) != 0);
597         if (mEnableOemUnlock != null) {
598             updateSwitchPreference(mEnableOemUnlock, isOemUnlockEnabled(getActivity()));
599             mEnableOemUnlock.setEnabled(isOemUnlockAllowed());
600         }
601         updateSwitchPreference(mDebugViewAttributes, Settings.Global.getInt(cr,
602                 Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0);
603         updateSwitchPreference(mForceAllowOnExternal, Settings.Global.getInt(cr,
604                 Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0);
605         updateBluetoothHciSnoopLogValues();
606         updateHdcpValues();
607         updatePasswordSummary();
608         updateDebuggerOptions();
609         updateMockLocation();
610         updateStrictModeVisualOptions();
611         updatePointerLocationOptions();
612         updateShowTouchesOptions();
613         updateFlingerOptions();
614         updateMsaaOptions();
615         updateTrackFrameTimeOptions();
616         updateShowNonRectClipOptions();
617         updateShowHwScreenUpdatesOptions();
618         updateShowHwLayersUpdatesOptions();
619         updateDebugHwOverdrawOptions();
620         updateDebugLayoutOptions();
621         updateAnimationScaleOptions();
622         updateOverlayDisplayDevicesOptions();
623         updateOpenGLTracesOptions();
624         updateImmediatelyDestroyActivitiesOptions();
625         updateAppProcessLimitOptions();
626         updateShowAllANRsOptions();
627         updateVerifyAppsOverUsbOptions();
628         updateBugreportOptions();
629         updateForceRtlOptions();
630         mLogdSizeController.updateLogdSizeValues();
631         mLogpersistController.updateLogpersistValues();
632         updateWifiDisplayCertificationOptions();
633         updateWifiVerboseLoggingOptions();
634         updateMobileDataAlwaysOnOptions();
635         updateSimulateColorSpace();
636         updateUSBAudioOptions();
637         updateForceResizableOptions();
638     }
639 
resetDangerousOptions()640     private void resetDangerousOptions() {
641         SystemPropPoker.getInstance().blockPokes();
642         for (final SwitchPreference cb : mResetSwitchPrefs) {
643             if (cb.isChecked()) {
644                 cb.setChecked(false);
645                 onPreferenceTreeClick(cb);
646             }
647         }
648         resetDebuggerOptions();
649         mLogpersistController.writeLogpersistOption(null, true);
650         mLogdSizeController.writeLogdSizeOption(null);
651         writeAnimationScaleOption(0, mWindowAnimationScale, null);
652         writeAnimationScaleOption(1, mTransitionAnimationScale, null);
653         writeAnimationScaleOption(2, mAnimatorDurationScale, null);
654         // Only poke the color space setting if we control it.
655         if (usingDevelopmentColorSpace()) {
656             writeSimulateColorSpace(-1);
657         }
658         writeOverlayDisplayDevicesOptions(null);
659         writeAppProcessLimitOptions(null);
660         mHaveDebugSettings = false;
661         updateAllOptions();
662         SystemPropPoker.getInstance().unblockPokes();
663         SystemPropPoker.getInstance().poke();
664     }
665 
updateBluetoothHciSnoopLogValues()666     private void updateBluetoothHciSnoopLogValues() {
667         ListPreference bluetoothSnoopLog = (ListPreference) findPreference(BT_HCI_SNOOP_LOG);
668         if (bluetoothSnoopLog != null) {
669             String currentValue = SystemProperties.get(BTSNOOP_LOG_MODE_PROPERTY);
670             String[] values = getResources().getStringArray(R.array.bt_hci_snoop_log_values);
671             String[] summaries = getResources().getStringArray(R.array.bt_hci_snoop_log_entries);
672             int disabledIndex = 0; // defaults to DISABLED
673             updateListPreference(bluetoothSnoopLog, currentValue, values, summaries, disabledIndex);
674         }
675     }
676 
updateListPreference(ListPreference preference, String currentValue, String[] values, String[] summaries, int index)677     private void updateListPreference(ListPreference preference, String currentValue,
678             String[] values, String[] summaries, int index) {
679         for (int i = 0; i < values.length; i++) {
680             if (currentValue.equals(values[i])) {
681                 index = i;
682                 break;
683             }
684         }
685         preference.setValue(values[index]);
686         preference.setSummary(summaries[index]);
687         preference.setOnPreferenceChangeListener(this);
688     }
689 
updateHdcpValues()690     private void updateHdcpValues() {
691         ListPreference hdcpChecking = (ListPreference) findPreference(HDCP_CHECKING_KEY);
692         if (hdcpChecking != null) {
693             String currentValue = SystemProperties.get(HDCP_CHECKING_PROPERTY);
694             String[] values = getResources().getStringArray(R.array.hdcp_checking_values);
695             String[] summaries = getResources().getStringArray(R.array.hdcp_checking_summaries);
696             int index = 1; // Defaults to drm-only. Needs to match with R.array.hdcp_checking_values
697             updateListPreference(hdcpChecking, currentValue, values, summaries, index);
698         }
699     }
700 
updatePasswordSummary()701     private void updatePasswordSummary() {
702         try {
703             if (mBackupManager.hasBackupPassword()) {
704                 mPassword.setSummary(R.string.local_backup_password_summary_change);
705             } else {
706                 mPassword.setSummary(R.string.local_backup_password_summary_none);
707             }
708         } catch (RemoteException e) {
709             // ignore
710         }
711     }
712 
writeBtHciSnoopLogOptions(Object newValue)713     private void writeBtHciSnoopLogOptions(Object newValue) {
714         SystemProperties.set(BTSNOOP_LOG_MODE_PROPERTY,
715                 newValue == null ? "" : newValue.toString());
716         updateBluetoothHciSnoopLogValues();
717         SystemPropPoker.getInstance().poke();
718     }
719 
writeDebuggerOptions()720     private void writeDebuggerOptions() {
721         try {
722             ActivityManager.getService().setDebugApp(
723                     mDebugApp, mWaitForDebugger.isChecked(), true);
724         } catch (RemoteException ex) {
725             // ignore
726         }
727     }
728 
writeMockLocation()729     private void writeMockLocation() {
730         AppOpsManager appOpsManager =
731                 (AppOpsManager) getActivity().getSystemService(Context.APP_OPS_SERVICE);
732 
733         // Disable the app op of the previous mock location app if such.
734         List<AppOpsManager.PackageOps> packageOps =
735                 appOpsManager.getPackagesForOps(MOCK_LOCATION_APP_OPS);
736         if (packageOps != null) {
737             // Should be one but in case we are in a bad state due to use of command line tools.
738             for (AppOpsManager.PackageOps packageOp : packageOps) {
739                 if (packageOp.getOps().get(0).getMode() != AppOpsManager.MODE_ERRORED) {
740                     String oldMockLocationApp = packageOp.getPackageName();
741                     try {
742                         ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(
743                                 oldMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS);
744                         appOpsManager.setMode(AppOpsManager.OP_MOCK_LOCATION, ai.uid,
745                                 oldMockLocationApp, AppOpsManager.MODE_ERRORED);
746                     } catch (PackageManager.NameNotFoundException e) {
747                         /* ignore */
748                     }
749                 }
750             }
751         }
752 
753         // Enable the app op of the new mock location app if such.
754         if (!TextUtils.isEmpty(mMockLocationApp)) {
755             try {
756                 ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(
757                         mMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS);
758                 appOpsManager.setMode(AppOpsManager.OP_MOCK_LOCATION, ai.uid,
759                         mMockLocationApp, AppOpsManager.MODE_ALLOWED);
760             } catch (PackageManager.NameNotFoundException e) {
761                 /* ignore */
762             }
763         }
764     }
765 
resetDebuggerOptions()766     private static void resetDebuggerOptions() {
767         try {
768             ActivityManager.getService().setDebugApp(
769                     null, false, true);
770         } catch (RemoteException ex) {
771             // ignore
772         }
773     }
774 
updateDebuggerOptions()775     private void updateDebuggerOptions() {
776         mDebugApp = Settings.Global.getString(mContentResolver, Settings.Global.DEBUG_APP);
777         updateSwitchPreference(mWaitForDebugger, Settings.Global.getInt(mContentResolver,
778                 Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0);
779         if (mDebugApp != null && mDebugApp.length() > 0) {
780             String label;
781             try {
782                 ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(mDebugApp,
783                         PackageManager.GET_DISABLED_COMPONENTS);
784                 CharSequence lab = getActivity().getPackageManager().getApplicationLabel(ai);
785                 label = lab != null ? lab.toString() : mDebugApp;
786             } catch (PackageManager.NameNotFoundException e) {
787                 label = mDebugApp;
788             }
789             mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_set, label));
790             mWaitForDebugger.setEnabled(true);
791             mHaveDebugSettings = true;
792         } else {
793             mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_not_set));
794             mWaitForDebugger.setEnabled(false);
795         }
796     }
797 
updateMockLocation()798     private void updateMockLocation() {
799         AppOpsManager appOpsManager =
800                 (AppOpsManager) getActivity().getSystemService(Context.APP_OPS_SERVICE);
801 
802         List<AppOpsManager.PackageOps> packageOps =
803                 appOpsManager.getPackagesForOps(MOCK_LOCATION_APP_OPS);
804         if (packageOps != null) {
805             for (AppOpsManager.PackageOps packageOp : packageOps) {
806                 if (packageOp.getOps().get(0).getMode() == AppOpsManager.MODE_ALLOWED) {
807                     mMockLocationApp = packageOps.get(0).getPackageName();
808                     break;
809                 }
810             }
811         }
812 
813         if (!TextUtils.isEmpty(mMockLocationApp)) {
814             String label = mMockLocationApp;
815             try {
816                 ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(
817                         mMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS);
818                 CharSequence appLabel = getActivity().getPackageManager().getApplicationLabel(ai);
819                 if (appLabel != null) {
820                     label = appLabel.toString();
821                 }
822             } catch (PackageManager.NameNotFoundException e) {
823                 /* ignore */
824             }
825 
826             mMockLocationAppPref.setSummary(getString(R.string.mock_location_app_set, label));
827             mHaveDebugSettings = true;
828         } else {
829             mMockLocationAppPref.setSummary(getString(R.string.mock_location_app_not_set));
830         }
831     }
832 
updateVerifyAppsOverUsbOptions()833     private void updateVerifyAppsOverUsbOptions() {
834         updateSwitchPreference(mVerifyAppsOverUsb,
835                 Settings.Global.getInt(mContentResolver,
836                 Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0);
837         mVerifyAppsOverUsb.setEnabled(enableVerifierSetting());
838     }
839 
writeVerifyAppsOverUsbOptions()840     private void writeVerifyAppsOverUsbOptions() {
841         Settings.Global.putInt(mContentResolver, Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB,
842                 mVerifyAppsOverUsb.isChecked() ? 1 : 0);
843     }
844 
enableVerifierSetting()845     private boolean enableVerifierSetting() {
846         if (Settings.Global.getInt(mContentResolver, Settings.Global.ADB_ENABLED, 0) == 0) {
847             return false;
848         }
849         if (Settings.Global.getInt(mContentResolver,
850                 Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 0) {
851             return false;
852         } else {
853             final PackageManager pm = getActivity().getPackageManager();
854             final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
855             verification.setType(PACKAGE_MIME_TYPE);
856             verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
857             final List<ResolveInfo> receivers = pm.queryBroadcastReceivers(verification, 0);
858             if (receivers.size() == 0) {
859                 return false;
860             }
861         }
862         return true;
863     }
864 
showVerifierSetting()865     private boolean showVerifierSetting() {
866         return Settings.Global.getInt(mContentResolver,
867                 Settings.Global.PACKAGE_VERIFIER_SETTING_VISIBLE, 1) > 0;
868     }
869 
showEnableOemUnlockPreference()870     private static boolean showEnableOemUnlockPreference() {
871         return !SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("");
872     }
873 
isOemUnlockAllowed()874     private boolean isOemUnlockAllowed() {
875         return !mUm.hasUserRestriction(UserManager.DISALLOW_OEM_UNLOCK);
876     }
877 
updateBugreportOptions()878     private void updateBugreportOptions() {
879         boolean enabled = "1".equals(SystemProperties.get("ro.debuggable"))
880                 || mEnableDeveloper.isChecked();
881         mBugreport.setEnabled(enabled);
882         final ComponentName componentName = new ComponentName("com.android.shell",
883                 "com.android.shell.BugreportStorageProvider");
884         getActivity().getPackageManager().setComponentEnabledSetting(componentName,
885                 enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
886                         : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
887                 0);
888     }
889 
captureBugReport()890     private void captureBugReport() {
891         Toast.makeText(getActivity(), R.string.capturing_bugreport, Toast.LENGTH_SHORT).show();
892         try {
893             ActivityManager.getService()
894                     .requestBugReport(ActivityManager.BUGREPORT_OPTION_FULL);
895         } catch (RemoteException e) {
896             Log.e(TAG, "Error taking bugreport", e);
897         }
898     }
899 
900     // Returns the current state of the system property that controls
901     // strictmode flashes.  One of:
902     //    0: not explicitly set one way or another
903     //    1: on
904     //    2: off
currentStrictModeActiveIndex()905     private static int currentStrictModeActiveIndex() {
906         if (TextUtils.isEmpty(SystemProperties.get(StrictMode.VISUAL_PROPERTY))) {
907             return 0;
908         }
909         boolean enabled = SystemProperties.getBoolean(StrictMode.VISUAL_PROPERTY, false);
910         return enabled ? 1 : 2;
911     }
912 
writeStrictModeVisualOptions()913     private void writeStrictModeVisualOptions() {
914         try {
915             mWindowManager.setStrictModeVisualIndicatorPreference(mStrictMode.isChecked()
916                     ? "1" : "");
917         } catch (RemoteException e) {
918             // ignore
919         }
920     }
921 
updateStrictModeVisualOptions()922     private void updateStrictModeVisualOptions() {
923         updateSwitchPreference(mStrictMode, currentStrictModeActiveIndex() == 1);
924     }
925 
writePointerLocationOptions()926     private void writePointerLocationOptions() {
927         Settings.System.putInt(mContentResolver,
928                 Settings.System.POINTER_LOCATION, mPointerLocation.isChecked() ? 1 : 0);
929     }
930 
updatePointerLocationOptions()931     private void updatePointerLocationOptions() {
932         updateSwitchPreference(mPointerLocation,
933                 Settings.System.getInt(mContentResolver, Settings.System.POINTER_LOCATION, 0) != 0);
934     }
935 
writeShowTouchesOptions()936     private void writeShowTouchesOptions() {
937         Settings.System.putInt(mContentResolver,
938                 Settings.System.SHOW_TOUCHES, mShowTouches.isChecked() ? 1 : 0);
939     }
940 
updateShowTouchesOptions()941     private void updateShowTouchesOptions() {
942         updateSwitchPreference(mShowTouches,
943                 Settings.System.getInt(mContentResolver, Settings.System.SHOW_TOUCHES, 0) != 0);
944     }
945 
updateFlingerOptions()946     private void updateFlingerOptions() {
947         // magic communication with surface flinger.
948         try {
949             IBinder flinger = ServiceManager.getService("SurfaceFlinger");
950             if (flinger != null) {
951                 Parcel data = Parcel.obtain();
952                 Parcel reply = Parcel.obtain();
953                 data.writeInterfaceToken("android.ui.ISurfaceComposer");
954                 flinger.transact(1010, data, reply, 0);
955                 @SuppressWarnings("unused")
956                 int showCpu = reply.readInt();
957                 @SuppressWarnings("unused")
958                 int enableGL = reply.readInt();
959                 int showUpdates = reply.readInt();
960                 updateSwitchPreference(mShowScreenUpdates, showUpdates != 0);
961                 @SuppressWarnings("unused")
962                 int showBackground = reply.readInt();
963                 int disableOverlays = reply.readInt();
964                 updateSwitchPreference(mDisableOverlays, disableOverlays != 0);
965                 reply.recycle();
966                 data.recycle();
967             }
968         } catch (RemoteException ex) {
969             // ignore
970         }
971     }
972 
writeShowUpdatesOption()973     private void writeShowUpdatesOption() {
974         try {
975             IBinder flinger = ServiceManager.getService("SurfaceFlinger");
976             if (flinger != null) {
977                 Parcel data = Parcel.obtain();
978                 data.writeInterfaceToken("android.ui.ISurfaceComposer");
979                 final int showUpdates = mShowScreenUpdates.isChecked() ? 1 : 0;
980                 data.writeInt(showUpdates);
981                 flinger.transact(1002, data, null, 0);
982                 data.recycle();
983 
984                 updateFlingerOptions();
985             }
986         } catch (RemoteException ex) {
987             // ignore
988         }
989     }
990 
writeDisableOverlaysOption()991     private void writeDisableOverlaysOption() {
992         try {
993             IBinder flinger = ServiceManager.getService("SurfaceFlinger");
994             if (flinger != null) {
995                 Parcel data = Parcel.obtain();
996                 data.writeInterfaceToken("android.ui.ISurfaceComposer");
997                 final int disableOverlays = mDisableOverlays.isChecked() ? 1 : 0;
998                 data.writeInt(disableOverlays);
999                 flinger.transact(1008, data, null, 0);
1000                 data.recycle();
1001 
1002                 updateFlingerOptions();
1003             }
1004         } catch (RemoteException ex) {
1005             // ignore
1006         }
1007     }
1008 
updateMsaaOptions()1009     private void updateMsaaOptions() {
1010         updateSwitchPreference(mForceMsaa, DisplayProperties.debug_force_msaa().orElse(false));
1011     }
1012 
writeMsaaOptions()1013     private void writeMsaaOptions() {
1014         DisplayProperties.debug_force_msaa(mForceMsaa.isChecked());
1015         SystemPropPoker.getInstance().poke();
1016     }
1017 
updateTrackFrameTimeOptions()1018     private void updateTrackFrameTimeOptions() {
1019         String value = SystemProperties.get(ThreadedRenderer.PROFILE_PROPERTY);
1020         if (value == null) {
1021             value = "";
1022         }
1023 
1024         CharSequence[] values = mTrackFrameTime.getEntryValues();
1025         for (int i = 0; i < values.length; i++) {
1026             if (value.contentEquals(values[i])) {
1027                 mTrackFrameTime.setValueIndex(i);
1028                 mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[i]);
1029                 return;
1030             }
1031         }
1032         mTrackFrameTime.setValueIndex(0);
1033         mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[0]);
1034     }
1035 
writeTrackFrameTimeOptions(Object newValue)1036     private void writeTrackFrameTimeOptions(Object newValue) {
1037         SystemProperties.set(ThreadedRenderer.PROFILE_PROPERTY,
1038                 newValue == null ? "" : newValue.toString());
1039         SystemPropPoker.getInstance().poke();
1040         updateTrackFrameTimeOptions();
1041     }
1042 
updateShowNonRectClipOptions()1043     private void updateShowNonRectClipOptions() {
1044         String value = SystemProperties.get(
1045                 ThreadedRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY);
1046         if (value == null) {
1047             value = "hide";
1048         }
1049 
1050         CharSequence[] values = mShowNonRectClip.getEntryValues();
1051         for (int i = 0; i < values.length; i++) {
1052             if (value.contentEquals(values[i])) {
1053                 mShowNonRectClip.setValueIndex(i);
1054                 mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[i]);
1055                 return;
1056             }
1057         }
1058         mShowNonRectClip.setValueIndex(0);
1059         mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[0]);
1060     }
1061 
writeShowNonRectClipOptions(Object newValue)1062     private void writeShowNonRectClipOptions(Object newValue) {
1063         SystemProperties.set(ThreadedRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY,
1064                 newValue == null ? "" : newValue.toString());
1065         SystemPropPoker.getInstance().poke();
1066         updateShowNonRectClipOptions();
1067     }
1068 
updateShowHwScreenUpdatesOptions()1069     private void updateShowHwScreenUpdatesOptions() {
1070         updateSwitchPreference(mShowHwScreenUpdates,
1071                 SystemProperties.getBoolean(ThreadedRenderer.DEBUG_DIRTY_REGIONS_PROPERTY, false));
1072     }
1073 
writeShowHwScreenUpdatesOptions()1074     private void writeShowHwScreenUpdatesOptions() {
1075         SystemProperties.set(ThreadedRenderer.DEBUG_DIRTY_REGIONS_PROPERTY,
1076                 mShowHwScreenUpdates.isChecked() ? "true" : null);
1077         SystemPropPoker.getInstance().poke();
1078     }
1079 
updateShowHwLayersUpdatesOptions()1080     private void updateShowHwLayersUpdatesOptions() {
1081         updateSwitchPreference(mShowHwLayersUpdates, SystemProperties.getBoolean(
1082                 ThreadedRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY, false));
1083     }
1084 
writeShowHwLayersUpdatesOptions()1085     private void writeShowHwLayersUpdatesOptions() {
1086         SystemProperties.set(ThreadedRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY,
1087                 mShowHwLayersUpdates.isChecked() ? "true" : null);
1088         SystemPropPoker.getInstance().poke();
1089     }
1090 
updateDebugHwOverdrawOptions()1091     private void updateDebugHwOverdrawOptions() {
1092         String value = SystemProperties.get(ThreadedRenderer.DEBUG_OVERDRAW_PROPERTY);
1093         if (value == null) {
1094             value = "";
1095         }
1096 
1097         CharSequence[] values = mDebugHwOverdraw.getEntryValues();
1098         for (int i = 0; i < values.length; i++) {
1099             if (value.contentEquals(values[i])) {
1100                 mDebugHwOverdraw.setValueIndex(i);
1101                 mDebugHwOverdraw.setSummary(mDebugHwOverdraw.getEntries()[i]);
1102                 return;
1103             }
1104         }
1105         mDebugHwOverdraw.setValueIndex(0);
1106         mDebugHwOverdraw.setSummary(mDebugHwOverdraw.getEntries()[0]);
1107     }
1108 
writeDebugHwOverdrawOptions(Object newValue)1109     private void writeDebugHwOverdrawOptions(Object newValue) {
1110         SystemProperties.set(ThreadedRenderer.DEBUG_OVERDRAW_PROPERTY,
1111                 newValue == null ? "" : newValue.toString());
1112         SystemPropPoker.getInstance().poke();
1113         updateDebugHwOverdrawOptions();
1114     }
1115 
updateDebugLayoutOptions()1116     private void updateDebugLayoutOptions() {
1117         updateSwitchPreference(mDebugLayout,
1118                 DisplayProperties.debug_layout().orElse(false));
1119     }
1120 
writeDebugLayoutOptions()1121     private void writeDebugLayoutOptions() {
1122         DisplayProperties.debug_layout(mDebugLayout.isChecked());
1123         SystemPropPoker.getInstance().poke();
1124     }
1125 
updateSimulateColorSpace()1126     private void updateSimulateColorSpace() {
1127         final boolean enabled = Settings.Secure.getInt(
1128                 mContentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0;
1129         if (enabled) {
1130             final String mode = Integer.toString(Settings.Secure.getInt(
1131                     mContentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
1132                     AccessibilityManager.DALTONIZER_DISABLED));
1133             mSimulateColorSpace.setValue(mode);
1134             final int index = mSimulateColorSpace.findIndexOfValue(mode);
1135             if (index < 0) {
1136                 // We're using a mode controlled by accessibility preferences.
1137                 mSimulateColorSpace.setSummary(getString(R.string.daltonizer_type_overridden,
1138                         getString(R.string.accessibility_display_daltonizer_preference_title)));
1139             } else {
1140                 mSimulateColorSpace.setSummary("%s");
1141             }
1142         } else {
1143             mSimulateColorSpace.setValue(
1144                     Integer.toString(AccessibilityManager.DALTONIZER_DISABLED));
1145         }
1146     }
1147 
1148     /**
1149      * @return <code>true</code> if the color space preference is currently
1150      *         controlled by development settings
1151      */
usingDevelopmentColorSpace()1152     private boolean usingDevelopmentColorSpace() {
1153         final boolean enabled = Settings.Secure.getInt(
1154                 mContentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0;
1155         if (enabled) {
1156             final String mode = Integer.toString(Settings.Secure.getInt(
1157                     mContentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
1158                     AccessibilityManager.DALTONIZER_DISABLED));
1159             final int index = mSimulateColorSpace.findIndexOfValue(mode);
1160             if (index >= 0) {
1161                 // We're using a mode controlled by developer preferences.
1162                 return true;
1163             }
1164         }
1165         return false;
1166     }
1167 
writeSimulateColorSpace(Object value)1168     private void writeSimulateColorSpace(Object value) {
1169         final int newMode = Integer.parseInt(value.toString());
1170         if (newMode < 0) {
1171             Settings.Secure.putInt(mContentResolver,
1172                     Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0);
1173         } else {
1174             Settings.Secure.putInt(mContentResolver,
1175                     Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 1);
1176             Settings.Secure.putInt(mContentResolver,
1177                     Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, newMode);
1178         }
1179     }
1180 
updateUSBAudioOptions()1181     private void updateUSBAudioOptions() {
1182         updateSwitchPreference(mUSBAudio, Settings.Secure.getInt(mContentResolver,
1183                 Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, 0) != 0);
1184     }
1185 
writeUSBAudioOptions()1186     private void writeUSBAudioOptions() {
1187         Settings.Secure.putInt(mContentResolver,
1188                 Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED,
1189                 mUSBAudio.isChecked() ? 1 : 0);
1190     }
1191 
updateForceResizableOptions()1192     private void updateForceResizableOptions() {
1193         updateSwitchPreference(mForceResizable,
1194                 Settings.Global.getInt(mContentResolver,
1195                 Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0);
1196     }
1197 
writeForceResizableOptions()1198     private void writeForceResizableOptions() {
1199         Settings.Global.putInt(mContentResolver,
1200                 Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES,
1201                 mForceResizable.isChecked() ? 1 : 0);
1202     }
1203 
updateForceRtlOptions()1204     private void updateForceRtlOptions() {
1205         updateSwitchPreference(mForceRtlLayout,
1206                 Settings.Global.getInt(mContentResolver,
1207                         Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0);
1208     }
1209 
writeForceRtlOptions()1210     private void writeForceRtlOptions() {
1211         boolean value = mForceRtlLayout.isChecked();
1212         Settings.Global.putInt(mContentResolver,
1213                 Settings.Global.DEVELOPMENT_FORCE_RTL, value ? 1 : 0);
1214         DisplayProperties.debug_force_rtl(value);
1215         LocalePicker.updateLocale(
1216                 getActivity().getResources().getConfiguration().getLocales().get(0));
1217     }
1218 
updateWifiDisplayCertificationOptions()1219     private void updateWifiDisplayCertificationOptions() {
1220         updateSwitchPreference(mWifiDisplayCertification, Settings.Global.getInt(
1221                 mContentResolver, Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 0) != 0);
1222     }
1223 
writeWifiDisplayCertificationOptions()1224     private void writeWifiDisplayCertificationOptions() {
1225         Settings.Global.putInt(mContentResolver,
1226                 Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON,
1227                 mWifiDisplayCertification.isChecked() ? 1 : 0);
1228     }
1229 
updateWifiVerboseLoggingOptions()1230     private void updateWifiVerboseLoggingOptions() {
1231         boolean enabled = mWifiManager.getVerboseLoggingLevel() > 0;
1232         updateSwitchPreference(mWifiVerboseLogging, enabled);
1233     }
1234 
writeWifiVerboseLoggingOptions()1235     private void writeWifiVerboseLoggingOptions() {
1236         mWifiManager.enableVerboseLogging(mWifiVerboseLogging.isChecked() ? 1 : 0);
1237     }
1238 
updateMobileDataAlwaysOnOptions()1239     private void updateMobileDataAlwaysOnOptions() {
1240         updateSwitchPreference(mMobileDataAlwaysOn, Settings.Global.getInt(mContentResolver,
1241                 Settings.Global.MOBILE_DATA_ALWAYS_ON, 0) != 0);
1242     }
1243 
writeMobileDataAlwaysOnOptions()1244     private void writeMobileDataAlwaysOnOptions() {
1245         Settings.Global.putInt(mContentResolver, Settings.Global.MOBILE_DATA_ALWAYS_ON,
1246                 mMobileDataAlwaysOn.isChecked() ? 1 : 0);
1247     }
1248 
updateUsbConfigurationValues()1249     private void updateUsbConfigurationValues() {
1250         if (mUsbConfiguration != null) {
1251             UsbManager manager = (UsbManager) getActivity().getSystemService(Context.USB_SERVICE);
1252 
1253             String[] values = getResources().getStringArray(R.array.usb_configuration_values);
1254             String[] titles = getResources().getStringArray(R.array.usb_configuration_titles);
1255             int index = 0;
1256             long functions = manager.getCurrentFunctions();
1257             for (int i = 0; i < titles.length; i++) {
1258                 if ((functions | UsbManager.usbFunctionsFromString(values[i])) != 0) {
1259                     index = i;
1260                     break;
1261                 }
1262             }
1263             mUsbConfiguration.setValue(values[index]);
1264             mUsbConfiguration.setSummary(titles[index]);
1265             mUsbConfiguration.setOnPreferenceChangeListener(this);
1266         }
1267     }
1268 
writeUsbConfigurationOption(Object newValue)1269     private void writeUsbConfigurationOption(Object newValue) {
1270         UsbManager manager = (UsbManager)getActivity().getSystemService(Context.USB_SERVICE);
1271         String function = newValue.toString();
1272         manager.setCurrentFunctions(UsbManager.usbFunctionsFromString(function));
1273     }
1274 
writeImmediatelyDestroyActivitiesOptions()1275     private void writeImmediatelyDestroyActivitiesOptions() {
1276         try {
1277             ActivityManager.getService().setAlwaysFinish(
1278                     mImmediatelyDestroyActivities.isChecked());
1279         } catch (RemoteException ex) {
1280             // ignore
1281         }
1282     }
1283 
updateImmediatelyDestroyActivitiesOptions()1284     private void updateImmediatelyDestroyActivitiesOptions() {
1285         updateSwitchPreference(mImmediatelyDestroyActivities, Settings.Global.getInt(
1286                 mContentResolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0);
1287     }
1288 
updateAnimationScaleValue(int which, ListPreference pref)1289     private void updateAnimationScaleValue(int which, ListPreference pref) {
1290         try {
1291             float scale = mWindowManager.getAnimationScale(which);
1292             if (scale != 1) {
1293                 mHaveDebugSettings = true;
1294             }
1295             CharSequence[] values = pref.getEntryValues();
1296             for (int i=0; i<values.length; i++) {
1297                 float val = Float.parseFloat(values[i].toString());
1298                 if (scale <= val) {
1299                     pref.setValueIndex(i);
1300                     pref.setSummary(pref.getEntries()[i]);
1301                     return;
1302                 }
1303             }
1304             pref.setValueIndex(values.length-1);
1305             pref.setSummary(pref.getEntries()[0]);
1306         } catch (RemoteException e) {
1307             // ignore
1308         }
1309     }
1310 
updateAnimationScaleOptions()1311     private void updateAnimationScaleOptions() {
1312         updateAnimationScaleValue(0, mWindowAnimationScale);
1313         updateAnimationScaleValue(1, mTransitionAnimationScale);
1314         updateAnimationScaleValue(2, mAnimatorDurationScale);
1315     }
1316 
writeAnimationScaleOption(int which, ListPreference pref, Object newValue)1317     private void writeAnimationScaleOption(int which, ListPreference pref, Object newValue) {
1318         try {
1319             float scale = newValue != null ? Float.parseFloat(newValue.toString()) : 1;
1320             mWindowManager.setAnimationScale(which, scale);
1321             updateAnimationScaleValue(which, pref);
1322         } catch (RemoteException e) {
1323             // ignore
1324         }
1325     }
1326 
updateOverlayDisplayDevicesOptions()1327     private void updateOverlayDisplayDevicesOptions() {
1328         String value = Settings.Global.getString(mContentResolver,
1329                 Settings.Global.OVERLAY_DISPLAY_DEVICES);
1330         if (value == null) {
1331             value = "";
1332         }
1333 
1334         CharSequence[] values = mOverlayDisplayDevices.getEntryValues();
1335         for (int i = 0; i < values.length; i++) {
1336             if (value.contentEquals(values[i])) {
1337                 mOverlayDisplayDevices.setValueIndex(i);
1338                 mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[i]);
1339                 return;
1340             }
1341         }
1342         mOverlayDisplayDevices.setValueIndex(0);
1343         mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[0]);
1344     }
1345 
writeOverlayDisplayDevicesOptions(Object newValue)1346     private void writeOverlayDisplayDevicesOptions(Object newValue) {
1347         Settings.Global.putString(mContentResolver, Settings.Global.OVERLAY_DISPLAY_DEVICES,
1348                 (String)newValue);
1349         updateOverlayDisplayDevicesOptions();
1350     }
1351 
updateOpenGLTracesOptions()1352     private void updateOpenGLTracesOptions() {
1353         String value = DisplayProperties.debug_opengl_trace().orElse("");
1354 
1355         CharSequence[] values = mOpenGLTraces.getEntryValues();
1356         for (int i = 0; i < values.length; i++) {
1357             if (value.contentEquals(values[i])) {
1358                 mOpenGLTraces.setValueIndex(i);
1359                 mOpenGLTraces.setSummary(mOpenGLTraces.getEntries()[i]);
1360                 return;
1361             }
1362         }
1363         mOpenGLTraces.setValueIndex(0);
1364         mOpenGLTraces.setSummary(mOpenGLTraces.getEntries()[0]);
1365     }
1366 
writeOpenGLTracesOptions(Object newValue)1367     private void writeOpenGLTracesOptions(Object newValue) {
1368         DisplayProperties.debug_opengl_trace(newValue == null ? "" : newValue.toString());
1369         SystemPropPoker.getInstance().poke();
1370         updateOpenGLTracesOptions();
1371     }
1372 
updateAppProcessLimitOptions()1373     private void updateAppProcessLimitOptions() {
1374         try {
1375             int limit = ActivityManager.getService().getProcessLimit();
1376             CharSequence[] values = mAppProcessLimit.getEntryValues();
1377             for (int i=0; i<values.length; i++) {
1378                 int val = Integer.parseInt(values[i].toString());
1379                 if (val >= limit) {
1380                     if (i != 0) {
1381                         mHaveDebugSettings = true;
1382                     }
1383                     mAppProcessLimit.setValueIndex(i);
1384                     mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[i]);
1385                     return;
1386                 }
1387             }
1388             mAppProcessLimit.setValueIndex(0);
1389             mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[0]);
1390         } catch (RemoteException e) {
1391             // ignore
1392         }
1393     }
1394 
writeAppProcessLimitOptions(Object newValue)1395     private void writeAppProcessLimitOptions(Object newValue) {
1396         try {
1397             int limit = newValue != null ? Integer.parseInt(newValue.toString()) : -1;
1398             ActivityManager.getService().setProcessLimit(limit);
1399             updateAppProcessLimitOptions();
1400         } catch (RemoteException e) {
1401             // ignore
1402         }
1403     }
1404 
writeShowAllANRsOptions()1405     private void writeShowAllANRsOptions() {
1406         Settings.Secure.putInt(mContentResolver, Settings.Secure.ANR_SHOW_BACKGROUND,
1407                 mShowAllANRs.isChecked() ? 1 : 0);
1408     }
1409 
updateShowAllANRsOptions()1410     private void updateShowAllANRsOptions() {
1411         updateSwitchPreference(mShowAllANRs, Settings.Secure.getInt(
1412                 mContentResolver, Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0);
1413     }
1414 
1415     @Override
onOemUnlockConfirm()1416     public void onOemUnlockConfirm() {
1417         mEnableOemUnlock.setChecked(true);
1418         setOemUnlockEnabled(getActivity(), true);
1419         updateAllOptions();
1420     }
1421 
1422     @Override
onEnableDevelopmentConfirm()1423     public void onEnableDevelopmentConfirm() {
1424         mEnableDeveloper.setChecked(true);
1425         DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), true);
1426         mLastEnabledState = true;
1427         setPrefsEnabledState(true);
1428     }
1429 
1430     @Override
onEnableAdbConfirm()1431     public void onEnableAdbConfirm() {
1432         Settings.Global.putInt(mContentResolver, Settings.Global.ADB_ENABLED, 1);
1433         mEnableAdb.setChecked(true);
1434         updateVerifyAppsOverUsbOptions();
1435     }
1436 
1437     @Override
onActivityResult(int requestCode, int resultCode, Intent data)1438     public void onActivityResult(int requestCode, int resultCode, Intent data) {
1439         if (requestCode == RESULT_DEBUG_APP) {
1440             if (resultCode == Activity.RESULT_OK) {
1441                 mDebugApp = data.getAction();
1442                 writeDebuggerOptions();
1443                 updateDebuggerOptions();
1444             }
1445         } else if (requestCode == RESULT_MOCK_LOCATION_APP) {
1446             if (resultCode == Activity.RESULT_OK) {
1447                 mMockLocationApp = data.getAction();
1448                 writeMockLocation();
1449                 updateMockLocation();
1450             }
1451         } else {
1452             super.onActivityResult(requestCode, resultCode, data);
1453         }
1454     }
1455 
1456     @Override
onPreferenceTreeClick(Preference preference)1457     public boolean onPreferenceTreeClick(Preference preference) {
1458         if (ActivityManager.isUserAMonkey()) {
1459             return false;
1460         }
1461 
1462         if (preference == mEnableDeveloper) {
1463             if (mEnableDeveloper.isChecked()) {
1464                 // Pass to super to launch the dialog, then uncheck until the dialog
1465                 // result comes back
1466                 super.onPreferenceTreeClick(preference);
1467                 mEnableDeveloper.setChecked(false);
1468             } else {
1469                 resetDangerousOptions();
1470                 DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), false);
1471                 mLastEnabledState = false;
1472                 setPrefsEnabledState(false);
1473             }
1474         } else if (preference == mBugreport) {
1475             captureBugReport();
1476         } else if (preference == mEnableAdb) {
1477             if (mEnableAdb.isChecked()) {
1478                 // Pass to super to launch the dialog, then uncheck until the dialog
1479                 // result comes back
1480                 super.onPreferenceTreeClick(preference);
1481                 mEnableAdb.setChecked(false);
1482             } else {
1483                 Settings.Global.putInt(mContentResolver, Settings.Global.ADB_ENABLED, 0);
1484                 mVerifyAppsOverUsb.setEnabled(false);
1485                 mVerifyAppsOverUsb.setChecked(false);
1486             }
1487         } else if (preference == mEnableTerminal) {
1488             final PackageManager pm = getActivity().getPackageManager();
1489             pm.setApplicationEnabledSetting(TERMINAL_APP_PACKAGE,
1490                     mEnableTerminal.isChecked() ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
1491                             : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0);
1492         } else if (preference == mKeepScreenOn) {
1493             Settings.Global.putInt(mContentResolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
1494                     mKeepScreenOn.isChecked() ?
1495                             (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB)
1496                             : 0);
1497         } else if (preference == mEnableOemUnlock) {
1498             if (mEnableOemUnlock.isChecked()) {
1499                 // Pass to super to launch the dialog, then uncheck until the dialog
1500                 // result comes back
1501                 super.onPreferenceTreeClick(preference);
1502                 mEnableOemUnlock.setChecked(false);
1503             } else {
1504                 setOemUnlockEnabled(getActivity(), false);
1505             }
1506         } else if (preference == mMockLocationAppPref) {
1507             Intent intent = new Intent(getActivity(), AppPicker.class);
1508             intent.putExtra(AppPicker.EXTRA_REQUESTIING_PERMISSION,
1509                     Manifest.permission.ACCESS_MOCK_LOCATION);
1510             startActivityForResult(intent, RESULT_MOCK_LOCATION_APP);
1511         } else if (preference == mDebugViewAttributes) {
1512             Settings.Global.putInt(mContentResolver, Settings.Global.DEBUG_VIEW_ATTRIBUTES,
1513                     mDebugViewAttributes.isChecked() ? 1 : 0);
1514         } else if (preference == mForceAllowOnExternal) {
1515             Settings.Global.putInt(mContentResolver, Settings.Global.FORCE_ALLOW_ON_EXTERNAL,
1516                     mForceAllowOnExternal.isChecked() ? 1 : 0);
1517         } else if (preference == mDebugAppPref) {
1518             Intent intent = new Intent(getActivity(), AppPicker.class);
1519             intent.putExtra(AppPicker.EXTRA_DEBUGGABLE, true);
1520             startActivityForResult(intent, RESULT_DEBUG_APP);
1521         } else if (preference == mWaitForDebugger) {
1522             writeDebuggerOptions();
1523         } else if (preference == mVerifyAppsOverUsb) {
1524             writeVerifyAppsOverUsbOptions();
1525         } else if (preference == mStrictMode) {
1526             writeStrictModeVisualOptions();
1527         } else if (preference == mPointerLocation) {
1528             writePointerLocationOptions();
1529         } else if (preference == mShowTouches) {
1530             writeShowTouchesOptions();
1531         } else if (preference == mShowScreenUpdates) {
1532             writeShowUpdatesOption();
1533         } else if (preference == mDisableOverlays) {
1534             writeDisableOverlaysOption();
1535         } else if (preference == mImmediatelyDestroyActivities) {
1536             writeImmediatelyDestroyActivitiesOptions();
1537         } else if (preference == mShowAllANRs) {
1538             writeShowAllANRsOptions();
1539         } else if (preference == mForceMsaa) {
1540             writeMsaaOptions();
1541         } else if (preference == mShowHwScreenUpdates) {
1542             writeShowHwScreenUpdatesOptions();
1543         } else if (preference == mShowHwLayersUpdates) {
1544             writeShowHwLayersUpdatesOptions();
1545         } else if (preference == mDebugLayout) {
1546             writeDebugLayoutOptions();
1547         } else if (preference == mForceRtlLayout) {
1548             writeForceRtlOptions();
1549         } else if (preference == mWifiDisplayCertification) {
1550             writeWifiDisplayCertificationOptions();
1551         } else if (preference == mWifiVerboseLogging) {
1552             writeWifiVerboseLoggingOptions();
1553         } else if (preference == mMobileDataAlwaysOn) {
1554             writeMobileDataAlwaysOnOptions();
1555         } else if (preference == mUSBAudio) {
1556             writeUSBAudioOptions();
1557         } else if (preference == mForceResizable) {
1558             writeForceResizableOptions();
1559         } else {
1560             return super.onPreferenceTreeClick(preference);
1561         }
1562 
1563         return false;
1564     }
1565 
1566     @Override
onPreferenceChange(Preference preference, Object newValue)1567     public boolean onPreferenceChange(Preference preference, Object newValue) {
1568         if (HDCP_CHECKING_KEY.equals(preference.getKey())) {
1569             SystemProperties.set(HDCP_CHECKING_PROPERTY, newValue.toString());
1570             updateHdcpValues();
1571             SystemPropPoker.getInstance().poke();
1572             return true;
1573         } else if (preference == mUsbConfiguration) {
1574             writeUsbConfigurationOption(newValue);
1575             return true;
1576         } else if (preference == mWindowAnimationScale) {
1577             writeAnimationScaleOption(0, mWindowAnimationScale, newValue);
1578             return true;
1579         } else if (preference == mTransitionAnimationScale) {
1580             writeAnimationScaleOption(1, mTransitionAnimationScale, newValue);
1581             return true;
1582         } else if (preference == mAnimatorDurationScale) {
1583             writeAnimationScaleOption(2, mAnimatorDurationScale, newValue);
1584             return true;
1585         } else if (preference == mOverlayDisplayDevices) {
1586             writeOverlayDisplayDevicesOptions(newValue);
1587             return true;
1588         } else if (preference == mOpenGLTraces) {
1589             writeOpenGLTracesOptions(newValue);
1590             return true;
1591         } else if (preference == mTrackFrameTime) {
1592             writeTrackFrameTimeOptions(newValue);
1593             return true;
1594         } else if (preference == mDebugHwOverdraw) {
1595             writeDebugHwOverdrawOptions(newValue);
1596             return true;
1597         } else if (preference == mShowNonRectClip) {
1598             writeShowNonRectClipOptions(newValue);
1599             return true;
1600         } else if (preference == mAppProcessLimit) {
1601             writeAppProcessLimitOptions(newValue);
1602             return true;
1603         } else if (preference == mSimulateColorSpace) {
1604             writeSimulateColorSpace(newValue);
1605             return true;
1606         } else if (preference == mBtHciSnoopLog) {
1607             writeBtHciSnoopLogOptions(newValue);
1608             return true;
1609         }
1610         return false;
1611     }
1612 
1613     /**
1614      * Iterates through preference controllers that show confirmation dialogs and returns the
1615      * preference key for the first currently showing dialog. Ideally there should only ever be one.
1616      * @return Preference key, or null if no dialog is showing
1617      */
getKeyForShowingDialog()1618     private String getKeyForShowingDialog() {
1619         // TODO: iterate through a fragment-wide list of PreferenceControllers and just pick out the
1620         // ConfirmationDialogController objects
1621         final List<ConfirmationDialogController> dialogControllers = new ArrayList<>(2);
1622         dialogControllers.add(mLogpersistController);
1623         for (ConfirmationDialogController dialogController : dialogControllers) {
1624             if (dialogController.isConfirmationDialogShowing()) {
1625                 return dialogController.getPreferenceKey();
1626             }
1627         }
1628         return null;
1629     }
1630 
1631     /**
1632      * Re-show the dialog we lost previously
1633      * @param preferenceKey Key for the preference the dialog is for
1634      */
recreateDialogForKey(String preferenceKey)1635     private void recreateDialogForKey(String preferenceKey) {
1636         // TODO: iterate through a fragment-wide list of PreferenceControllers and just pick out the
1637         // ConfirmationDialogController objects
1638         final List<ConfirmationDialogController> dialogControllers = new ArrayList<>(2);
1639         dialogControllers.add(mLogpersistController);
1640         for (ConfirmationDialogController dialogController : dialogControllers) {
1641             if (TextUtils.equals(preferenceKey, dialogController.getPreferenceKey())) {
1642                 dialogController.showConfirmationDialog(findPreference(preferenceKey));
1643             }
1644         }
1645     }
1646 
dismissDialogs()1647     private void dismissDialogs() {
1648         mLogpersistController.dismissConfirmationDialog();
1649     }
1650 
1651     private BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
1652         @Override
1653         public void onReceive(Context context, Intent intent) {
1654             updateUsbConfigurationValues();
1655         }
1656     };
1657 
isPackageInstalled(Context context, String packageName)1658     private static boolean isPackageInstalled(Context context, String packageName) {
1659         try {
1660             return context.getPackageManager().getPackageInfo(packageName, 0) != null;
1661         } catch (PackageManager.NameNotFoundException e) {
1662             return false;
1663         }
1664     }
1665 
1666     /**
1667      * Returns whether or not this device is able to be OEM unlocked.
1668      */
isOemUnlockEnabled(Context context)1669     static boolean isOemUnlockEnabled(Context context) {
1670         PersistentDataBlockManager manager =(PersistentDataBlockManager)
1671                 context.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
1672         return manager.getOemUnlockEnabled();
1673     }
1674 
1675     /**
1676      * Allows enabling or disabling OEM unlock on this device. OEM unlocked
1677      * devices allow users to flash other OSes to them.
1678      */
setOemUnlockEnabled(Context context, boolean enabled)1679     static void setOemUnlockEnabled(Context context, boolean enabled) {
1680         try {
1681             PersistentDataBlockManager manager = (PersistentDataBlockManager)
1682                     context.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
1683             manager.setOemUnlockEnabled(enabled);
1684         } catch (SecurityException e) {
1685             Log.e(TAG, "Fail to set oem unlock.", e);
1686         }
1687     }
1688 }
1689