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