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