OSDN Git Service

Add preference for enabling root access (3/3)
[android-x86/packages-apps-Settings.git] / src / com / android / settings / DevelopmentSettings.java
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.settings;
18
19 import android.Manifest;
20 import android.app.Activity;
21 import android.app.ActivityManagerNative;
22 import android.app.AlertDialog;
23 import android.app.AppOpsManager;
24 import android.app.AppOpsManager.PackageOps;
25 import android.app.Dialog;
26 import android.app.admin.DevicePolicyManager;
27 import android.app.backup.IBackupManager;
28 import android.bluetooth.BluetoothAdapter;
29 import android.content.BroadcastReceiver;
30 import android.content.ComponentName;
31 import android.content.ContentResolver;
32 import android.content.Context;
33 import android.content.DialogInterface;
34 import android.content.Intent;
35 import android.content.IntentFilter;
36 import android.content.pm.ApplicationInfo;
37 import android.content.pm.PackageManager;
38 import android.content.pm.PackageManager.NameNotFoundException;
39 import android.content.pm.ResolveInfo;
40 import android.content.res.Resources;
41 import android.hardware.usb.IUsbManager;
42 import android.hardware.usb.UsbManager;
43 import android.net.wifi.WifiManager;
44 import android.os.AsyncTask;
45 import android.os.BatteryManager;
46 import android.os.Build;
47 import android.os.Bundle;
48 import android.os.IBinder;
49 import android.os.Parcel;
50 import android.os.RemoteException;
51 import android.os.ServiceManager;
52 import android.os.StrictMode;
53 import android.os.SystemProperties;
54 import android.os.UserHandle;
55 import android.os.UserManager;
56 import android.preference.ListPreference;
57 import android.preference.Preference;
58 import android.preference.Preference.OnPreferenceChangeListener;
59 import android.preference.PreferenceGroup;
60 import android.preference.PreferenceScreen;
61 import android.preference.SwitchPreference;
62 import android.provider.SearchIndexableResource;
63 import android.provider.Settings;
64 import android.text.TextUtils;
65 import android.util.Log;
66 import android.view.HardwareRenderer;
67 import android.view.IWindowManager;
68 import android.view.LayoutInflater;
69 import android.view.View;
70 import android.view.ViewGroup;
71 import android.view.accessibility.AccessibilityManager;
72 import android.widget.Switch;
73 import android.widget.TextView;
74
75 import com.android.internal.logging.MetricsLogger;
76 import com.android.settings.fuelgauge.InactiveApps;
77 import com.android.settings.search.BaseSearchIndexProvider;
78 import com.android.settings.search.Indexable;
79 import com.android.settings.widget.SwitchBar;
80
81 import java.util.ArrayList;
82 import java.util.Arrays;
83 import java.util.HashSet;
84 import java.util.List;
85
86 /*
87  * Displays preferences for application developers.
88  */
89 public class DevelopmentSettings extends SettingsPreferenceFragment
90         implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener,
91                 OnPreferenceChangeListener, SwitchBar.OnSwitchChangeListener, Indexable {
92     private static final String TAG = "DevelopmentSettings";
93
94     /**
95      * Preference file were development settings prefs are stored.
96      */
97     public static final String PREF_FILE = "development";
98
99     /**
100      * Whether to show the development settings to the user.  Default is false.
101      */
102     public static final String PREF_SHOW = "show";
103
104     private static final String ENABLE_ADB = "enable_adb";
105     private static final String CLEAR_ADB_KEYS = "clear_adb_keys";
106     private static final String ENABLE_TERMINAL = "enable_terminal";
107     private static final String KEEP_SCREEN_ON = "keep_screen_on";
108     private static final String BT_HCI_SNOOP_LOG = "bt_hci_snoop_log";
109     private static final String ENABLE_OEM_UNLOCK = "oem_unlock_enable";
110     private static final String HDCP_CHECKING_KEY = "hdcp_checking";
111     private static final String HDCP_CHECKING_PROPERTY = "persist.sys.hdcp_checking";
112     private static final String LOCAL_BACKUP_PASSWORD = "local_backup_password";
113     private static final String HARDWARE_UI_PROPERTY = "persist.sys.ui.hw";
114     private static final String MSAA_PROPERTY = "debug.egl.force_msaa";
115     private static final String BUGREPORT = "bugreport";
116     private static final String BUGREPORT_IN_POWER_KEY = "bugreport_in_power";
117     private static final String OPENGL_TRACES_PROPERTY = "debug.egl.trace";
118     private static final String TUNER_UI_KEY = "tuner_ui";
119
120     private static final String DEBUG_APP_KEY = "debug_app";
121     private static final String WAIT_FOR_DEBUGGER_KEY = "wait_for_debugger";
122     private static final String MOCK_LOCATION_APP_KEY = "mock_location_app";
123     private static final String VERIFY_APPS_OVER_USB_KEY = "verify_apps_over_usb";
124     private static final String DEBUG_VIEW_ATTRIBUTES =  "debug_view_attributes";
125     private static final String STRICT_MODE_KEY = "strict_mode";
126     private static final String POINTER_LOCATION_KEY = "pointer_location";
127     private static final String SHOW_TOUCHES_KEY = "show_touches";
128     private static final String SHOW_SCREEN_UPDATES_KEY = "show_screen_updates";
129     private static final String DISABLE_OVERLAYS_KEY = "disable_overlays";
130     private static final String SIMULATE_COLOR_SPACE = "simulate_color_space";
131     private static final String USB_AUDIO_KEY = "usb_audio";
132     private static final String SHOW_CPU_USAGE_KEY = "show_cpu_usage";
133     private static final String FORCE_HARDWARE_UI_KEY = "force_hw_ui";
134     private static final String FORCE_MSAA_KEY = "force_msaa";
135     private static final String TRACK_FRAME_TIME_KEY = "track_frame_time";
136     private static final String SHOW_NON_RECTANGULAR_CLIP_KEY = "show_non_rect_clip";
137     private static final String SHOW_HW_SCREEN_UPDATES_KEY = "show_hw_screen_udpates";
138     private static final String SHOW_HW_LAYERS_UPDATES_KEY = "show_hw_layers_udpates";
139     private static final String DEBUG_HW_OVERDRAW_KEY = "debug_hw_overdraw";
140     private static final String DEBUG_LAYOUT_KEY = "debug_layout";
141     private static final String FORCE_RTL_LAYOUT_KEY = "force_rtl_layout_all_locales";
142     private static final String WINDOW_ANIMATION_SCALE_KEY = "window_animation_scale";
143     private static final String TRANSITION_ANIMATION_SCALE_KEY = "transition_animation_scale";
144     private static final String ANIMATOR_DURATION_SCALE_KEY = "animator_duration_scale";
145     private static final String OVERLAY_DISPLAY_DEVICES_KEY = "overlay_display_devices";
146     private static final String ENABLE_MULTI_WINDOW_KEY = "enable_multi_window";
147     private static final String DEBUG_DEBUGGING_CATEGORY_KEY = "debug_debugging_category";
148     private static final String SELECT_LOGD_SIZE_KEY = "select_logd_size";
149     private static final String SELECT_LOGD_SIZE_PROPERTY = "persist.logd.size";
150     private static final String SELECT_LOGD_DEFAULT_SIZE_PROPERTY = "ro.logd.size";
151
152     private static final String WIFI_DISPLAY_CERTIFICATION_KEY = "wifi_display_certification";
153     private static final String WIFI_VERBOSE_LOGGING_KEY = "wifi_verbose_logging";
154     private static final String WIFI_AGGRESSIVE_HANDOVER_KEY = "wifi_aggressive_handover";
155     private static final String WIFI_ALLOW_SCAN_WITH_TRAFFIC_KEY = "wifi_allow_scan_with_traffic";
156     private static final String USB_CONFIGURATION_KEY = "select_usb_configuration";
157     private static final String WIFI_LEGACY_DHCP_CLIENT_KEY = "legacy_dhcp_client";
158     private static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on";
159     private static final String KEY_COLOR_MODE = "color_mode";
160
161     private static final String INACTIVE_APPS_KEY = "inactive_apps";
162
163     private static final String OPENGL_TRACES_KEY = "enable_opengl_traces";
164
165     private static final String ROOT_ACCESS_KEY = "root_access";
166     private static final String ROOT_ACCESS_PROPERTY = "persist.sys.root_access";
167
168     private static final String IMMEDIATELY_DESTROY_ACTIVITIES_KEY
169             = "immediately_destroy_activities";
170     private static final String APP_PROCESS_LIMIT_KEY = "app_process_limit";
171
172     private static final String SHOW_ALL_ANRS_KEY = "show_all_anrs";
173
174     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
175
176     private static final String TERMINAL_APP_PACKAGE = "com.android.terminal";
177
178     private static final int RESULT_DEBUG_APP = 1000;
179     private static final int RESULT_MOCK_LOCATION_APP = 1001;
180
181     private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
182
183     private static final int REQUEST_CODE_ENABLE_OEM_UNLOCK = 0;
184
185     private static String DEFAULT_LOG_RING_BUFFER_SIZE_IN_BYTES = "262144"; // 256K
186
187     private static final int[] MOCK_LOCATION_APP_OPS = new int[] {AppOpsManager.OP_MOCK_LOCATION};
188
189     private static final String MULTI_WINDOW_SYSTEM_PROPERTY = "persist.sys.debug.multi_window";
190     private IWindowManager mWindowManager;
191     private IBackupManager mBackupManager;
192     private DevicePolicyManager mDpm;
193     private UserManager mUm;
194     private WifiManager mWifiManager;
195
196     private SwitchBar mSwitchBar;
197     private boolean mLastEnabledState;
198     private boolean mHaveDebugSettings;
199     private boolean mDontPokeProperties;
200
201     private SwitchPreference mEnableAdb;
202     private Preference mClearAdbKeys;
203     private SwitchPreference mEnableTerminal;
204     private Preference mBugreport;
205     private SwitchPreference mBugreportInPower;
206     private SwitchPreference mKeepScreenOn;
207     private SwitchPreference mBtHciSnoopLog;
208     private SwitchPreference mEnableOemUnlock;
209     private SwitchPreference mDebugViewAttributes;
210
211     private PreferenceScreen mPassword;
212     private String mDebugApp;
213     private Preference mDebugAppPref;
214
215     private String mMockLocationApp;
216     private Preference mMockLocationAppPref;
217
218     private SwitchPreference mWaitForDebugger;
219     private SwitchPreference mVerifyAppsOverUsb;
220     private SwitchPreference mWifiDisplayCertification;
221     private SwitchPreference mWifiVerboseLogging;
222     private SwitchPreference mWifiAggressiveHandover;
223     private SwitchPreference mLegacyDhcpClient;
224     private SwitchPreference mMobileDataAlwaysOn;
225
226     private SwitchPreference mWifiAllowScansWithTraffic;
227     private SwitchPreference mStrictMode;
228     private SwitchPreference mPointerLocation;
229     private SwitchPreference mShowTouches;
230     private SwitchPreference mShowScreenUpdates;
231     private SwitchPreference mDisableOverlays;
232     private SwitchPreference mEnableMultiWindow;
233     private SwitchPreference mShowCpuUsage;
234     private SwitchPreference mForceHardwareUi;
235     private SwitchPreference mForceMsaa;
236     private SwitchPreference mShowHwScreenUpdates;
237     private SwitchPreference mShowHwLayersUpdates;
238     private SwitchPreference mDebugLayout;
239     private SwitchPreference mForceRtlLayout;
240     private ListPreference mDebugHwOverdraw;
241     private ListPreference mLogdSize;
242     private ListPreference mUsbConfiguration;
243     private ListPreference mTrackFrameTime;
244     private ListPreference mShowNonRectClip;
245     private ListPreference mWindowAnimationScale;
246     private ListPreference mTransitionAnimationScale;
247     private ListPreference mAnimatorDurationScale;
248     private ListPreference mOverlayDisplayDevices;
249     private ListPreference mOpenGLTraces;
250
251     private ListPreference mSimulateColorSpace;
252
253     private SwitchPreference mUSBAudio;
254     private SwitchPreference mImmediatelyDestroyActivities;
255
256     private ListPreference mAppProcessLimit;
257
258     private SwitchPreference mShowAllANRs;
259
260     private ColorModePreference mColorModePreference;
261
262     private PreferenceScreen mProcessStats;
263     private ListPreference mRootAccess;
264     private Object mSelectedRootValue;
265
266     private final ArrayList<Preference> mAllPrefs = new ArrayList<Preference>();
267
268     private final ArrayList<SwitchPreference> mResetSwitchPrefs
269             = new ArrayList<SwitchPreference>();
270
271     private final HashSet<Preference> mDisabledPrefs = new HashSet<Preference>();
272     // To track whether a confirmation dialog was clicked.
273     private boolean mDialogClicked;
274     private Dialog mEnableDialog;
275     private Dialog mAdbDialog;
276
277     private Dialog mAdbKeysDialog;
278     private boolean mUnavailable;
279     private Dialog mRootDialog;
280
281     @Override
282     protected int getMetricsCategory() {
283         return MetricsLogger.DEVELOPMENT;
284     }
285
286     @Override
287     public void onCreate(Bundle icicle) {
288         super.onCreate(icicle);
289
290         mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
291         mBackupManager = IBackupManager.Stub.asInterface(
292                 ServiceManager.getService(Context.BACKUP_SERVICE));
293         mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
294         mUm = (UserManager) getSystemService(Context.USER_SERVICE);
295
296         mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
297
298         if (android.os.Process.myUserHandle().getIdentifier() != UserHandle.USER_OWNER
299                 || mUm.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES)
300                 || Settings.Global.getInt(getActivity().getContentResolver(),
301                         Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
302             // Block access to developer options if the user is not the owner, if user policy
303             // restricts it, or if the device has not been provisioned
304             mUnavailable = true;
305             setPreferenceScreen(new PreferenceScreen(getActivity(), null));
306             return;
307         }
308
309         addPreferencesFromResource(R.xml.development_prefs);
310
311         final PreferenceGroup debugDebuggingCategory = (PreferenceGroup)
312                 findPreference(DEBUG_DEBUGGING_CATEGORY_KEY);
313         mEnableAdb = findAndInitSwitchPref(ENABLE_ADB);
314         mClearAdbKeys = findPreference(CLEAR_ADB_KEYS);
315         if (!SystemProperties.getBoolean("ro.adb.secure", false)) {
316             if (debugDebuggingCategory != null) {
317                 debugDebuggingCategory.removePreference(mClearAdbKeys);
318             }
319         }
320         mAllPrefs.add(mClearAdbKeys);
321         mEnableTerminal = findAndInitSwitchPref(ENABLE_TERMINAL);
322         if (!isPackageInstalled(getActivity(), TERMINAL_APP_PACKAGE)) {
323             debugDebuggingCategory.removePreference(mEnableTerminal);
324             mEnableTerminal = null;
325         }
326
327         mBugreport = findPreference(BUGREPORT);
328         mBugreportInPower = findAndInitSwitchPref(BUGREPORT_IN_POWER_KEY);
329         mKeepScreenOn = findAndInitSwitchPref(KEEP_SCREEN_ON);
330         mBtHciSnoopLog = findAndInitSwitchPref(BT_HCI_SNOOP_LOG);
331         mEnableOemUnlock = findAndInitSwitchPref(ENABLE_OEM_UNLOCK);
332         if (!showEnableOemUnlockPreference()) {
333             removePreference(mEnableOemUnlock);
334             mEnableOemUnlock = null;
335         }
336
337         mDebugViewAttributes = findAndInitSwitchPref(DEBUG_VIEW_ATTRIBUTES);
338         mPassword = (PreferenceScreen) findPreference(LOCAL_BACKUP_PASSWORD);
339         mAllPrefs.add(mPassword);
340
341
342         if (!android.os.Process.myUserHandle().equals(UserHandle.OWNER)) {
343             disableForUser(mEnableAdb);
344             disableForUser(mClearAdbKeys);
345             disableForUser(mEnableTerminal);
346             disableForUser(mPassword);
347         }
348
349         mDebugAppPref = findPreference(DEBUG_APP_KEY);
350         mAllPrefs.add(mDebugAppPref);
351         mWaitForDebugger = findAndInitSwitchPref(WAIT_FOR_DEBUGGER_KEY);
352
353         mMockLocationAppPref = findPreference(MOCK_LOCATION_APP_KEY);
354         mAllPrefs.add(mMockLocationAppPref);
355
356         mVerifyAppsOverUsb = findAndInitSwitchPref(VERIFY_APPS_OVER_USB_KEY);
357         if (!showVerifierSetting()) {
358             if (debugDebuggingCategory != null) {
359                 debugDebuggingCategory.removePreference(mVerifyAppsOverUsb);
360             } else {
361                 mVerifyAppsOverUsb.setEnabled(false);
362             }
363         }
364         mStrictMode = findAndInitSwitchPref(STRICT_MODE_KEY);
365         mPointerLocation = findAndInitSwitchPref(POINTER_LOCATION_KEY);
366         mShowTouches = findAndInitSwitchPref(SHOW_TOUCHES_KEY);
367         mShowScreenUpdates = findAndInitSwitchPref(SHOW_SCREEN_UPDATES_KEY);
368         mDisableOverlays = findAndInitSwitchPref(DISABLE_OVERLAYS_KEY);
369         mShowCpuUsage = findAndInitSwitchPref(SHOW_CPU_USAGE_KEY);
370         mForceHardwareUi = findAndInitSwitchPref(FORCE_HARDWARE_UI_KEY);
371         mForceMsaa = findAndInitSwitchPref(FORCE_MSAA_KEY);
372         mTrackFrameTime = addListPreference(TRACK_FRAME_TIME_KEY);
373         mShowNonRectClip = addListPreference(SHOW_NON_RECTANGULAR_CLIP_KEY);
374         mShowHwScreenUpdates = findAndInitSwitchPref(SHOW_HW_SCREEN_UPDATES_KEY);
375         mShowHwLayersUpdates = findAndInitSwitchPref(SHOW_HW_LAYERS_UPDATES_KEY);
376         mDebugLayout = findAndInitSwitchPref(DEBUG_LAYOUT_KEY);
377         mForceRtlLayout = findAndInitSwitchPref(FORCE_RTL_LAYOUT_KEY);
378         mDebugHwOverdraw = addListPreference(DEBUG_HW_OVERDRAW_KEY);
379         mWifiDisplayCertification = findAndInitSwitchPref(WIFI_DISPLAY_CERTIFICATION_KEY);
380         mWifiVerboseLogging = findAndInitSwitchPref(WIFI_VERBOSE_LOGGING_KEY);
381         mWifiAggressiveHandover = findAndInitSwitchPref(WIFI_AGGRESSIVE_HANDOVER_KEY);
382         mWifiAllowScansWithTraffic = findAndInitSwitchPref(WIFI_ALLOW_SCAN_WITH_TRAFFIC_KEY);
383         mLegacyDhcpClient = findAndInitSwitchPref(WIFI_LEGACY_DHCP_CLIENT_KEY);
384         mMobileDataAlwaysOn = findAndInitSwitchPref(MOBILE_DATA_ALWAYS_ON);
385         mLogdSize = addListPreference(SELECT_LOGD_SIZE_KEY);
386         mUsbConfiguration = addListPreference(USB_CONFIGURATION_KEY);
387
388         mWindowAnimationScale = addListPreference(WINDOW_ANIMATION_SCALE_KEY);
389         mTransitionAnimationScale = addListPreference(TRANSITION_ANIMATION_SCALE_KEY);
390         mAnimatorDurationScale = addListPreference(ANIMATOR_DURATION_SCALE_KEY);
391         mOverlayDisplayDevices = addListPreference(OVERLAY_DISPLAY_DEVICES_KEY);
392         mEnableMultiWindow = findAndInitSwitchPref(ENABLE_MULTI_WINDOW_KEY);
393         if (!showEnableMultiWindowPreference()) {
394             final PreferenceGroup drawingGroup =
395                     (PreferenceGroup)findPreference("debug_drawing_category");
396             if (drawingGroup != null) {
397                 drawingGroup.removePreference(mEnableMultiWindow);
398             } else {
399                 mEnableMultiWindow.setEnabled(false);
400             }
401             removePreference(mEnableMultiWindow);
402             mEnableMultiWindow = null;
403         }
404         mOpenGLTraces = addListPreference(OPENGL_TRACES_KEY);
405         mSimulateColorSpace = addListPreference(SIMULATE_COLOR_SPACE);
406         mUSBAudio = findAndInitSwitchPref(USB_AUDIO_KEY);
407
408         mImmediatelyDestroyActivities = (SwitchPreference) findPreference(
409                 IMMEDIATELY_DESTROY_ACTIVITIES_KEY);
410         mAllPrefs.add(mImmediatelyDestroyActivities);
411         mResetSwitchPrefs.add(mImmediatelyDestroyActivities);
412
413         mAppProcessLimit = addListPreference(APP_PROCESS_LIMIT_KEY);
414
415         mShowAllANRs = (SwitchPreference) findPreference(
416                 SHOW_ALL_ANRS_KEY);
417         mAllPrefs.add(mShowAllANRs);
418         mResetSwitchPrefs.add(mShowAllANRs);
419
420         Preference hdcpChecking = findPreference(HDCP_CHECKING_KEY);
421         if (hdcpChecking != null) {
422             mAllPrefs.add(hdcpChecking);
423             removePreferenceForProduction(hdcpChecking);
424         }
425
426         mColorModePreference = (ColorModePreference) findPreference(KEY_COLOR_MODE);
427         mColorModePreference.updateCurrentAndSupported();
428         if (mColorModePreference.getTransformsCount() < 2) {
429             removePreference(KEY_COLOR_MODE);
430             mColorModePreference = null;
431         }
432
433         mRootAccess = (ListPreference) findPreference(ROOT_ACCESS_KEY);
434         mRootAccess.setOnPreferenceChangeListener(this);
435         if (!removeRootOptionsIfRequired()) {
436             mAllPrefs.add(mRootAccess);
437         }
438     }
439
440     private ListPreference addListPreference(String prefKey) {
441         ListPreference pref = (ListPreference) findPreference(prefKey);
442         mAllPrefs.add(pref);
443         pref.setOnPreferenceChangeListener(this);
444         return pref;
445     }
446
447     private void disableForUser(Preference pref) {
448         if (pref != null) {
449             pref.setEnabled(false);
450             mDisabledPrefs.add(pref);
451         }
452     }
453
454     private SwitchPreference findAndInitSwitchPref(String key) {
455         SwitchPreference pref = (SwitchPreference) findPreference(key);
456         if (pref == null) {
457             throw new IllegalArgumentException("Cannot find preference with key = " + key);
458         }
459         mAllPrefs.add(pref);
460         mResetSwitchPrefs.add(pref);
461         return pref;
462     }
463
464     private boolean removeRootOptionsIfRequired() {
465         // user builds don't get root, and eng always gets root
466         if (!(Build.IS_DEBUGGABLE || "eng".equals(Build.TYPE))) {
467             if (mRootAccess != null) {
468                 getPreferenceScreen().removePreference(mRootAccess);
469                 return true;
470             }
471         }
472
473         return false;
474     }
475
476     @Override
477     public void onActivityCreated(Bundle savedInstanceState) {
478         super.onActivityCreated(savedInstanceState);
479
480         final SettingsActivity activity = (SettingsActivity) getActivity();
481
482         mSwitchBar = activity.getSwitchBar();
483        if (mUnavailable) {
484             mSwitchBar.setEnabled(false);
485             return;
486         }
487
488         mSwitchBar.addOnSwitchChangeListener(this);
489     }
490
491     private boolean removePreferenceForProduction(Preference preference) {
492         if ("user".equals(Build.TYPE)) {
493             removePreference(preference);
494             return true;
495         }
496         return false;
497     }
498
499     private void removePreference(Preference preference) {
500         getPreferenceScreen().removePreference(preference);
501         mAllPrefs.remove(preference);
502         mResetSwitchPrefs.remove(preference);
503     }
504
505     private void setPrefsEnabledState(boolean enabled) {
506         for (int i = 0; i < mAllPrefs.size(); i++) {
507             Preference pref = mAllPrefs.get(i);
508             pref.setEnabled(enabled && !mDisabledPrefs.contains(pref));
509         }
510         updateAllOptions();
511     }
512
513     @Override
514     public void onResume() {
515         super.onResume();
516
517         if (mUnavailable) {
518             // Show error message
519             TextView emptyView = (TextView) getView().findViewById(android.R.id.empty);
520             getListView().setEmptyView(emptyView);
521             if (emptyView != null) {
522                 emptyView.setText(R.string.development_settings_not_available);
523             }
524             return;
525         }
526
527         if (mDpm.getMaximumTimeToLock(null) > 0) {
528             // A DeviceAdmin has specified a maximum time until the device
529             // will lock...  in this case we can't allow the user to turn
530             // on "stay awake when plugged in" because that would defeat the
531             // restriction.
532             mDisabledPrefs.add(mKeepScreenOn);
533         } else {
534             mDisabledPrefs.remove(mKeepScreenOn);
535         }
536
537         final ContentResolver cr = getActivity().getContentResolver();
538         mLastEnabledState = Settings.Global.getInt(cr,
539                 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
540         mSwitchBar.setChecked(mLastEnabledState);
541         setPrefsEnabledState(mLastEnabledState);
542
543         if (mHaveDebugSettings && !mLastEnabledState) {
544             // Overall debugging is disabled, but there are some debug
545             // settings that are enabled.  This is an invalid state.  Switch
546             // to debug settings being enabled, so the user knows there is
547             // stuff enabled and can turn it all off if they want.
548             Settings.Global.putInt(getActivity().getContentResolver(),
549                     Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
550             mLastEnabledState = true;
551             mSwitchBar.setChecked(mLastEnabledState);
552             setPrefsEnabledState(mLastEnabledState);
553         }
554         mSwitchBar.show();
555
556         if (mColorModePreference != null) {
557             mColorModePreference.startListening();
558             mColorModePreference.updateCurrentAndSupported();
559         }
560     }
561
562     @Override
563     public void onPause() {
564         super.onPause();
565         if (mColorModePreference != null) {
566             mColorModePreference.stopListening();
567         }
568     }
569
570     @Override
571     public View onCreateView(LayoutInflater inflater, ViewGroup container,
572             Bundle savedInstanceState) {
573         IntentFilter filter = new IntentFilter();
574         filter.addAction(UsbManager.ACTION_USB_STATE);
575         getActivity().registerReceiver(mUsbReceiver, filter);
576         return super.onCreateView(inflater, container, savedInstanceState);
577     }
578
579     @Override
580     public void onDestroyView() {
581         super.onDestroyView();
582
583         if (mUnavailable) {
584             return;
585         }
586         mSwitchBar.removeOnSwitchChangeListener(this);
587         mSwitchBar.hide();
588         getActivity().unregisterReceiver(mUsbReceiver);
589     }
590
591     void updateSwitchPreference(SwitchPreference switchPreference, boolean value) {
592         switchPreference.setChecked(value);
593         mHaveDebugSettings |= value;
594     }
595
596     private void updateAllOptions() {
597         final Context context = getActivity();
598         final ContentResolver cr = context.getContentResolver();
599         mHaveDebugSettings = false;
600         updateSwitchPreference(mEnableAdb, Settings.Global.getInt(cr,
601                 Settings.Global.ADB_ENABLED, 0) != 0);
602         if (mEnableTerminal != null) {
603             updateSwitchPreference(mEnableTerminal,
604                     context.getPackageManager().getApplicationEnabledSetting(TERMINAL_APP_PACKAGE)
605                             == PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
606         }
607         updateSwitchPreference(mBugreportInPower, Settings.Secure.getInt(cr,
608                 Settings.Secure.BUGREPORT_IN_POWER_MENU, 0) != 0);
609         updateSwitchPreference(mKeepScreenOn, Settings.Global.getInt(cr,
610                 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0) != 0);
611         updateSwitchPreference(mBtHciSnoopLog, Settings.Secure.getInt(cr,
612                 Settings.Secure.BLUETOOTH_HCI_LOG, 0) != 0);
613         if (mEnableOemUnlock != null) {
614             updateSwitchPreference(mEnableOemUnlock, Utils.isOemUnlockEnabled(getActivity()));
615         }
616         updateSwitchPreference(mDebugViewAttributes, Settings.Global.getInt(cr,
617                 Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0);
618         updateHdcpValues();
619         updatePasswordSummary();
620         updateDebuggerOptions();
621         updateMockLocation();
622         updateStrictModeVisualOptions();
623         updatePointerLocationOptions();
624         updateShowTouchesOptions();
625         updateFlingerOptions();
626         updateCpuUsageOptions();
627         updateHardwareUiOptions();
628         updateMsaaOptions();
629         updateTrackFrameTimeOptions();
630         updateShowNonRectClipOptions();
631         updateShowHwScreenUpdatesOptions();
632         updateShowHwLayersUpdatesOptions();
633         updateDebugHwOverdrawOptions();
634         updateDebugLayoutOptions();
635         updateAnimationScaleOptions();
636         updateOverlayDisplayDevicesOptions();
637         if (mEnableMultiWindow != null) {
638             updateSwitchPreference(mEnableMultiWindow,
639                     SystemProperties.getBoolean(MULTI_WINDOW_SYSTEM_PROPERTY, false));
640         }
641         updateOpenGLTracesOptions();
642         updateImmediatelyDestroyActivitiesOptions();
643         updateAppProcessLimitOptions();
644         updateShowAllANRsOptions();
645         updateVerifyAppsOverUsbOptions();
646         updateBugreportOptions();
647         updateForceRtlOptions();
648         updateLogdSizeValues();
649         updateWifiDisplayCertificationOptions();
650         updateWifiVerboseLoggingOptions();
651         updateWifiAggressiveHandoverOptions();
652         updateWifiAllowScansWithTrafficOptions();
653         updateLegacyDhcpClientOptions();
654         updateMobileDataAlwaysOnOptions();
655         updateSimulateColorSpace();
656         updateUSBAudioOptions();
657         updateRootAccessOptions();
658     }
659
660     private void resetDangerousOptions() {
661         mDontPokeProperties = true;
662         for (int i=0; i< mResetSwitchPrefs.size(); i++) {
663             SwitchPreference cb = mResetSwitchPrefs.get(i);
664             if (cb.isChecked()) {
665                 cb.setChecked(false);
666                 onPreferenceTreeClick(null, cb);
667             }
668         }
669         resetDebuggerOptions();
670         writeLogdSizeOption(null);
671         resetRootAccessOptions();
672         writeAnimationScaleOption(0, mWindowAnimationScale, null);
673         writeAnimationScaleOption(1, mTransitionAnimationScale, null);
674         writeAnimationScaleOption(2, mAnimatorDurationScale, null);
675         // Only poke the color space setting if we control it.
676         if (usingDevelopmentColorSpace()) {
677             writeSimulateColorSpace(-1);
678         }
679         writeOverlayDisplayDevicesOptions(null);
680         writeAppProcessLimitOptions(null);
681         mHaveDebugSettings = false;
682         updateAllOptions();
683         mDontPokeProperties = false;
684         pokeSystemProperties();
685     }
686
687     private void updateRootAccessOptions() {
688         String value = SystemProperties.get(ROOT_ACCESS_PROPERTY, "1");
689         mRootAccess.setValue(value);
690         mRootAccess.setSummary(getResources()
691                 .getStringArray(R.array.root_access_entries)[Integer.valueOf(value)]);
692     }
693
694     private void writeRootAccessOptions(Object newValue) {
695         String oldValue = SystemProperties.get(ROOT_ACCESS_PROPERTY, "1");
696         SystemProperties.set(ROOT_ACCESS_PROPERTY, newValue.toString());
697         if (Integer.valueOf(newValue.toString()) < 2 && !oldValue.equals(newValue)
698                 && "1".equals(SystemProperties.get("service.adb.root", "0"))) {
699             SystemProperties.set("service.adb.root", "0");
700             Settings.Secure.putInt(getActivity().getContentResolver(),
701                     Settings.Secure.ADB_ENABLED, 0);
702             Settings.Secure.putInt(getActivity().getContentResolver(),
703                     Settings.Secure.ADB_ENABLED, 1);
704         }
705         updateRootAccessOptions();
706     }
707
708     private void resetRootAccessOptions() {
709         String oldValue = SystemProperties.get(ROOT_ACCESS_PROPERTY, "1");
710         SystemProperties.set(ROOT_ACCESS_PROPERTY, "1");
711         if (!oldValue.equals("1") && "1".equals(SystemProperties.get("service.adb.root", "0"))) {
712             SystemProperties.set("service.adb.root", "0");
713             Settings.Secure.putInt(getActivity().getContentResolver(),
714                     Settings.Secure.ADB_ENABLED, 0);
715             Settings.Secure.putInt(getActivity().getContentResolver(),
716                     Settings.Secure.ADB_ENABLED, 1);
717         }
718         updateRootAccessOptions();
719     }
720
721     private void updateHdcpValues() {
722         ListPreference hdcpChecking = (ListPreference) findPreference(HDCP_CHECKING_KEY);
723         if (hdcpChecking != null) {
724             String currentValue = SystemProperties.get(HDCP_CHECKING_PROPERTY);
725             String[] values = getResources().getStringArray(R.array.hdcp_checking_values);
726             String[] summaries = getResources().getStringArray(R.array.hdcp_checking_summaries);
727             int index = 1; // Defaults to drm-only. Needs to match with R.array.hdcp_checking_values
728             for (int i = 0; i < values.length; i++) {
729                 if (currentValue.equals(values[i])) {
730                     index = i;
731                     break;
732                 }
733             }
734             hdcpChecking.setValue(values[index]);
735             hdcpChecking.setSummary(summaries[index]);
736             hdcpChecking.setOnPreferenceChangeListener(this);
737         }
738     }
739
740     private void updatePasswordSummary() {
741         try {
742             if (mBackupManager.hasBackupPassword()) {
743                 mPassword.setSummary(R.string.local_backup_password_summary_change);
744             } else {
745                 mPassword.setSummary(R.string.local_backup_password_summary_none);
746             }
747         } catch (RemoteException e) {
748             // Not much we can do here
749         }
750     }
751
752     private void writeBtHciSnoopLogOptions() {
753         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
754         adapter.configHciSnoopLog(mBtHciSnoopLog.isChecked());
755         Settings.Secure.putInt(getActivity().getContentResolver(),
756                 Settings.Secure.BLUETOOTH_HCI_LOG,
757                 mBtHciSnoopLog.isChecked() ? 1 : 0);
758     }
759
760     private void writeDebuggerOptions() {
761         try {
762             ActivityManagerNative.getDefault().setDebugApp(
763                 mDebugApp, mWaitForDebugger.isChecked(), true);
764         } catch (RemoteException ex) {
765         }
766     }
767
768     private void writeMockLocation() {
769         AppOpsManager appOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
770
771         // Disable the app op of the previous mock location app if such.
772         List<PackageOps> packageOps = appOpsManager.getPackagesForOps(MOCK_LOCATION_APP_OPS);
773         if (packageOps != null) {
774             // Should be one but in case we are in a bad state due to use of command line tools.
775             for (PackageOps packageOp : packageOps) {
776                 if (packageOp.getOps().get(0).getMode() != AppOpsManager.MODE_ERRORED) {
777                     String oldMockLocationApp = packageOp.getPackageName();
778                     try {
779                         ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(
780                                 oldMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS);
781                         appOpsManager.setMode(AppOpsManager.OP_MOCK_LOCATION, ai.uid,
782                                 oldMockLocationApp, AppOpsManager.MODE_ERRORED);
783                     } catch (NameNotFoundException e) {
784                         /* ignore */
785                     }
786                 }
787             }
788         }
789
790         // Enable the app op of the new mock location app if such.
791         if (!TextUtils.isEmpty(mMockLocationApp)) {
792             try {
793                 ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(
794                         mMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS);
795                 appOpsManager.setMode(AppOpsManager.OP_MOCK_LOCATION, ai.uid,
796                         mMockLocationApp, AppOpsManager.MODE_ALLOWED);
797             } catch (NameNotFoundException e) {
798                 /* ignore */
799             }
800         }
801     }
802
803     private static void resetDebuggerOptions() {
804         try {
805             ActivityManagerNative.getDefault().setDebugApp(
806                     null, false, true);
807         } catch (RemoteException ex) {
808         }
809     }
810
811     private void updateDebuggerOptions() {
812         mDebugApp = Settings.Global.getString(
813                 getActivity().getContentResolver(), Settings.Global.DEBUG_APP);
814         updateSwitchPreference(mWaitForDebugger, Settings.Global.getInt(
815                 getActivity().getContentResolver(), Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0);
816         if (mDebugApp != null && mDebugApp.length() > 0) {
817             String label;
818             try {
819                 ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(mDebugApp,
820                         PackageManager.GET_DISABLED_COMPONENTS);
821                 CharSequence lab = getActivity().getPackageManager().getApplicationLabel(ai);
822                 label = lab != null ? lab.toString() : mDebugApp;
823             } catch (PackageManager.NameNotFoundException e) {
824                 label = mDebugApp;
825             }
826             mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_set, label));
827             mWaitForDebugger.setEnabled(true);
828             mHaveDebugSettings = true;
829         } else {
830             mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_not_set));
831             mWaitForDebugger.setEnabled(false);
832         }
833     }
834
835     private void updateMockLocation() {
836         AppOpsManager appOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
837
838         List<PackageOps> packageOps = appOpsManager.getPackagesForOps(MOCK_LOCATION_APP_OPS);
839         if (packageOps != null) {
840             for (PackageOps packageOp : packageOps) {
841                 if (packageOp.getOps().get(0).getMode() == AppOpsManager.MODE_ALLOWED) {
842                     mMockLocationApp = packageOps.get(0).getPackageName();
843                     break;
844                 }
845             }
846         }
847
848         if (!TextUtils.isEmpty(mMockLocationApp)) {
849             String label = mMockLocationApp;
850             try {
851                 ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(
852                         mMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS);
853                 CharSequence appLabel = getPackageManager().getApplicationLabel(ai);
854                 if (appLabel != null) {
855                     label = appLabel.toString();
856                 }
857             } catch (PackageManager.NameNotFoundException e) {
858                 /* ignore */
859             }
860
861             mMockLocationAppPref.setSummary(getString(R.string.mock_location_app_set, label));
862             mHaveDebugSettings = true;
863         } else {
864             mMockLocationAppPref.setSummary(getString(R.string.mock_location_app_not_set));
865         }
866     }
867
868     private void updateVerifyAppsOverUsbOptions() {
869         updateSwitchPreference(mVerifyAppsOverUsb, Settings.Global.getInt(getActivity().getContentResolver(),
870                 Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0);
871         mVerifyAppsOverUsb.setEnabled(enableVerifierSetting());
872     }
873
874     private void writeVerifyAppsOverUsbOptions() {
875         Settings.Global.putInt(getActivity().getContentResolver(),
876               Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, mVerifyAppsOverUsb.isChecked() ? 1 : 0);
877     }
878
879     private boolean enableVerifierSetting() {
880         final ContentResolver cr = getActivity().getContentResolver();
881         if (Settings.Global.getInt(cr, Settings.Global.ADB_ENABLED, 0) == 0) {
882             return false;
883         }
884         if (Settings.Global.getInt(cr, Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 0) {
885             return false;
886         } else {
887             final PackageManager pm = getActivity().getPackageManager();
888             final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
889             verification.setType(PACKAGE_MIME_TYPE);
890             verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
891             final List<ResolveInfo> receivers = pm.queryBroadcastReceivers(verification, 0);
892             if (receivers.size() == 0) {
893                 return false;
894             }
895         }
896         return true;
897     }
898
899     private boolean showVerifierSetting() {
900         return Settings.Global.getInt(getActivity().getContentResolver(),
901                 Settings.Global.PACKAGE_VERIFIER_SETTING_VISIBLE, 1) > 0;
902     }
903
904     private static boolean showEnableOemUnlockPreference() {
905         return !SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("");
906     }
907
908     private static boolean showEnableMultiWindowPreference() {
909         return !"user".equals(Build.TYPE);
910     }
911
912     private void setEnableMultiWindow(boolean value) {
913         SystemProperties.set(MULTI_WINDOW_SYSTEM_PROPERTY, String.valueOf(value));
914         pokeSystemProperties();
915     }
916
917     private void updateBugreportOptions() {
918         final ComponentName bugreportStorageProviderComponentName =
919                 new ComponentName("com.android.shell",
920                         "com.android.shell.BugreportStorageProvider");
921         if ("user".equals(Build.TYPE)) {
922             final ContentResolver resolver = getActivity().getContentResolver();
923             final boolean adbEnabled = Settings.Global.getInt(
924                     resolver, Settings.Global.ADB_ENABLED, 0) != 0;
925             if (adbEnabled) {
926                 mBugreport.setEnabled(true);
927                 mBugreportInPower.setEnabled(true);
928                 getPackageManager().setComponentEnabledSetting(
929                         bugreportStorageProviderComponentName,
930                         PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
931             } else {
932                 mBugreport.setEnabled(false);
933                 mBugreportInPower.setEnabled(false);
934                 mBugreportInPower.setChecked(false);
935                 Settings.Secure.putInt(resolver, Settings.Secure.BUGREPORT_IN_POWER_MENU, 0);
936                 getPackageManager().setComponentEnabledSetting(
937                         bugreportStorageProviderComponentName,
938                         PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0);
939             }
940         } else {
941             mBugreportInPower.setEnabled(true);
942             getPackageManager().setComponentEnabledSetting(
943                     bugreportStorageProviderComponentName,
944                     PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
945         }
946     }
947
948     // Returns the current state of the system property that controls
949     // strictmode flashes.  One of:
950     //    0: not explicitly set one way or another
951     //    1: on
952     //    2: off
953     private static int currentStrictModeActiveIndex() {
954         if (TextUtils.isEmpty(SystemProperties.get(StrictMode.VISUAL_PROPERTY))) {
955             return 0;
956         }
957         boolean enabled = SystemProperties.getBoolean(StrictMode.VISUAL_PROPERTY, false);
958         return enabled ? 1 : 2;
959     }
960
961     private void writeStrictModeVisualOptions() {
962         try {
963             mWindowManager.setStrictModeVisualIndicatorPreference(mStrictMode.isChecked()
964                     ? "1" : "");
965         } catch (RemoteException e) {
966         }
967     }
968
969     private void updateStrictModeVisualOptions() {
970         updateSwitchPreference(mStrictMode, currentStrictModeActiveIndex() == 1);
971     }
972
973     private void writePointerLocationOptions() {
974         Settings.System.putInt(getActivity().getContentResolver(),
975                 Settings.System.POINTER_LOCATION, mPointerLocation.isChecked() ? 1 : 0);
976     }
977
978     private void updatePointerLocationOptions() {
979         updateSwitchPreference(mPointerLocation,
980                 Settings.System.getInt(getActivity().getContentResolver(),
981                 Settings.System.POINTER_LOCATION, 0) != 0);
982     }
983
984     private void writeShowTouchesOptions() {
985         Settings.System.putInt(getActivity().getContentResolver(),
986                 Settings.System.SHOW_TOUCHES, mShowTouches.isChecked() ? 1 : 0);
987     }
988
989     private void updateShowTouchesOptions() {
990         updateSwitchPreference(mShowTouches,
991                 Settings.System.getInt(getActivity().getContentResolver(),
992                 Settings.System.SHOW_TOUCHES, 0) != 0);
993     }
994
995     private void updateFlingerOptions() {
996         // magic communication with surface flinger.
997         try {
998             IBinder flinger = ServiceManager.getService("SurfaceFlinger");
999             if (flinger != null) {
1000                 Parcel data = Parcel.obtain();
1001                 Parcel reply = Parcel.obtain();
1002                 data.writeInterfaceToken("android.ui.ISurfaceComposer");
1003                 flinger.transact(1010, data, reply, 0);
1004                 @SuppressWarnings("unused")
1005                 int showCpu = reply.readInt();
1006                 @SuppressWarnings("unused")
1007                 int enableGL = reply.readInt();
1008                 int showUpdates = reply.readInt();
1009                 updateSwitchPreference(mShowScreenUpdates, showUpdates != 0);
1010                 @SuppressWarnings("unused")
1011                 int showBackground = reply.readInt();
1012                 int disableOverlays = reply.readInt();
1013                 updateSwitchPreference(mDisableOverlays, disableOverlays != 0);
1014                 reply.recycle();
1015                 data.recycle();
1016             }
1017         } catch (RemoteException ex) {
1018         }
1019     }
1020
1021     private void writeShowUpdatesOption() {
1022         try {
1023             IBinder flinger = ServiceManager.getService("SurfaceFlinger");
1024             if (flinger != null) {
1025                 Parcel data = Parcel.obtain();
1026                 data.writeInterfaceToken("android.ui.ISurfaceComposer");
1027                 final int showUpdates = mShowScreenUpdates.isChecked() ? 1 : 0;
1028                 data.writeInt(showUpdates);
1029                 flinger.transact(1002, data, null, 0);
1030                 data.recycle();
1031
1032                 updateFlingerOptions();
1033             }
1034         } catch (RemoteException ex) {
1035         }
1036     }
1037
1038     private void writeDisableOverlaysOption() {
1039         try {
1040             IBinder flinger = ServiceManager.getService("SurfaceFlinger");
1041             if (flinger != null) {
1042                 Parcel data = Parcel.obtain();
1043                 data.writeInterfaceToken("android.ui.ISurfaceComposer");
1044                 final int disableOverlays = mDisableOverlays.isChecked() ? 1 : 0;
1045                 data.writeInt(disableOverlays);
1046                 flinger.transact(1008, data, null, 0);
1047                 data.recycle();
1048
1049                 updateFlingerOptions();
1050             }
1051         } catch (RemoteException ex) {
1052         }
1053     }
1054
1055     private void updateHardwareUiOptions() {
1056         updateSwitchPreference(mForceHardwareUi, SystemProperties.getBoolean(HARDWARE_UI_PROPERTY, false));
1057     }
1058
1059     private void writeHardwareUiOptions() {
1060         SystemProperties.set(HARDWARE_UI_PROPERTY, mForceHardwareUi.isChecked() ? "true" : "false");
1061         pokeSystemProperties();
1062     }
1063
1064     private void updateMsaaOptions() {
1065         updateSwitchPreference(mForceMsaa, SystemProperties.getBoolean(MSAA_PROPERTY, false));
1066     }
1067
1068     private void writeMsaaOptions() {
1069         SystemProperties.set(MSAA_PROPERTY, mForceMsaa.isChecked() ? "true" : "false");
1070         pokeSystemProperties();
1071     }
1072
1073     private void updateTrackFrameTimeOptions() {
1074         String value = SystemProperties.get(HardwareRenderer.PROFILE_PROPERTY);
1075         if (value == null) {
1076             value = "";
1077         }
1078
1079         CharSequence[] values = mTrackFrameTime.getEntryValues();
1080         for (int i = 0; i < values.length; i++) {
1081             if (value.contentEquals(values[i])) {
1082                 mTrackFrameTime.setValueIndex(i);
1083                 mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[i]);
1084                 return;
1085             }
1086         }
1087         mTrackFrameTime.setValueIndex(0);
1088         mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[0]);
1089     }
1090
1091     private void writeTrackFrameTimeOptions(Object newValue) {
1092         SystemProperties.set(HardwareRenderer.PROFILE_PROPERTY,
1093                 newValue == null ? "" : newValue.toString());
1094         pokeSystemProperties();
1095         updateTrackFrameTimeOptions();
1096     }
1097
1098     private void updateShowNonRectClipOptions() {
1099         String value = SystemProperties.get(
1100                 HardwareRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY);
1101         if (value == null) {
1102             value = "hide";
1103         }
1104
1105         CharSequence[] values = mShowNonRectClip.getEntryValues();
1106         for (int i = 0; i < values.length; i++) {
1107             if (value.contentEquals(values[i])) {
1108                 mShowNonRectClip.setValueIndex(i);
1109                 mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[i]);
1110                 return;
1111             }
1112         }
1113         mShowNonRectClip.setValueIndex(0);
1114         mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[0]);
1115     }
1116
1117     private void writeShowNonRectClipOptions(Object newValue) {
1118         SystemProperties.set(HardwareRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY,
1119                 newValue == null ? "" : newValue.toString());
1120         pokeSystemProperties();
1121         updateShowNonRectClipOptions();
1122     }
1123
1124     private void updateShowHwScreenUpdatesOptions() {
1125         updateSwitchPreference(mShowHwScreenUpdates,
1126                 SystemProperties.getBoolean(HardwareRenderer.DEBUG_DIRTY_REGIONS_PROPERTY, false));
1127     }
1128
1129     private void writeShowHwScreenUpdatesOptions() {
1130         SystemProperties.set(HardwareRenderer.DEBUG_DIRTY_REGIONS_PROPERTY,
1131                 mShowHwScreenUpdates.isChecked() ? "true" : null);
1132         pokeSystemProperties();
1133     }
1134
1135     private void updateShowHwLayersUpdatesOptions() {
1136         updateSwitchPreference(mShowHwLayersUpdates, SystemProperties.getBoolean(
1137                 HardwareRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY, false));
1138     }
1139
1140     private void writeShowHwLayersUpdatesOptions() {
1141         SystemProperties.set(HardwareRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY,
1142                 mShowHwLayersUpdates.isChecked() ? "true" : null);
1143         pokeSystemProperties();
1144     }
1145
1146     private void updateDebugHwOverdrawOptions() {
1147         String value = SystemProperties.get(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY);
1148         if (value == null) {
1149             value = "";
1150         }
1151
1152         CharSequence[] values = mDebugHwOverdraw.getEntryValues();
1153         for (int i = 0; i < values.length; i++) {
1154             if (value.contentEquals(values[i])) {
1155                 mDebugHwOverdraw.setValueIndex(i);
1156                 mDebugHwOverdraw.setSummary(mDebugHwOverdraw.getEntries()[i]);
1157                 return;
1158             }
1159         }
1160         mDebugHwOverdraw.setValueIndex(0);
1161         mDebugHwOverdraw.setSummary(mDebugHwOverdraw.getEntries()[0]);
1162     }
1163
1164     private void writeDebugHwOverdrawOptions(Object newValue) {
1165         SystemProperties.set(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY,
1166                 newValue == null ? "" : newValue.toString());
1167         pokeSystemProperties();
1168         updateDebugHwOverdrawOptions();
1169     }
1170
1171     private void updateDebugLayoutOptions() {
1172         updateSwitchPreference(mDebugLayout,
1173                 SystemProperties.getBoolean(View.DEBUG_LAYOUT_PROPERTY, false));
1174     }
1175
1176     private void writeDebugLayoutOptions() {
1177         SystemProperties.set(View.DEBUG_LAYOUT_PROPERTY,
1178                 mDebugLayout.isChecked() ? "true" : "false");
1179         pokeSystemProperties();
1180     }
1181
1182     private void updateSimulateColorSpace() {
1183         final ContentResolver cr = getContentResolver();
1184         final boolean enabled = Settings.Secure.getInt(
1185                 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0;
1186         if (enabled) {
1187             final String mode = Integer.toString(Settings.Secure.getInt(
1188                     cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
1189                     AccessibilityManager.DALTONIZER_DISABLED));
1190             mSimulateColorSpace.setValue(mode);
1191             final int index = mSimulateColorSpace.findIndexOfValue(mode);
1192             if (index < 0) {
1193                 // We're using a mode controlled by accessibility preferences.
1194                 mSimulateColorSpace.setSummary(getString(R.string.daltonizer_type_overridden,
1195                         getString(R.string.accessibility_display_daltonizer_preference_title)));
1196             } else {
1197                 mSimulateColorSpace.setSummary("%s");
1198             }
1199         } else {
1200             mSimulateColorSpace.setValue(
1201                     Integer.toString(AccessibilityManager.DALTONIZER_DISABLED));
1202         }
1203     }
1204
1205     /**
1206      * @return <code>true</code> if the color space preference is currently
1207      *         controlled by development settings
1208      */
1209     private boolean usingDevelopmentColorSpace() {
1210         final ContentResolver cr = getContentResolver();
1211         final boolean enabled = Settings.Secure.getInt(
1212                 cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0;
1213         if (enabled) {
1214             final String mode = Integer.toString(Settings.Secure.getInt(
1215                     cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
1216                     AccessibilityManager.DALTONIZER_DISABLED));
1217             final int index = mSimulateColorSpace.findIndexOfValue(mode);
1218             if (index >= 0) {
1219                 // We're using a mode controlled by developer preferences.
1220                 return true;
1221             }
1222         }
1223         return false;
1224     }
1225
1226     private void writeSimulateColorSpace(Object value) {
1227         final ContentResolver cr = getContentResolver();
1228         final int newMode = Integer.parseInt(value.toString());
1229         if (newMode < 0) {
1230             Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0);
1231         } else {
1232             Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 1);
1233             Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, newMode);
1234         }
1235     }
1236
1237     private void updateUSBAudioOptions() {
1238         updateSwitchPreference(mUSBAudio, Settings.Secure.getInt(getContentResolver(),
1239                 Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, 0) != 0);
1240     }
1241
1242     private void writeUSBAudioOptions() {
1243         Settings.Secure.putInt(getContentResolver(),
1244                 Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED,
1245                 mUSBAudio.isChecked() ? 1 : 0);
1246     }
1247
1248     private void updateForceRtlOptions() {
1249         updateSwitchPreference(mForceRtlLayout,
1250                 Settings.Global.getInt(getActivity().getContentResolver(),
1251                 Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0);
1252     }
1253
1254     private void writeForceRtlOptions() {
1255         boolean value = mForceRtlLayout.isChecked();
1256         Settings.Global.putInt(getActivity().getContentResolver(),
1257                 Settings.Global.DEVELOPMENT_FORCE_RTL, value ? 1 : 0);
1258         SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, value ? "1" : "0");
1259         LocalePicker.updateLocale(getActivity().getResources().getConfiguration().locale);
1260     }
1261
1262     private void updateWifiDisplayCertificationOptions() {
1263         updateSwitchPreference(mWifiDisplayCertification, Settings.Global.getInt(
1264                 getActivity().getContentResolver(),
1265                 Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 0) != 0);
1266     }
1267
1268     private void writeWifiDisplayCertificationOptions() {
1269         Settings.Global.putInt(getActivity().getContentResolver(),
1270                 Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON,
1271                 mWifiDisplayCertification.isChecked() ? 1 : 0);
1272     }
1273
1274     private void updateWifiVerboseLoggingOptions() {
1275         boolean enabled = mWifiManager.getVerboseLoggingLevel() > 0;
1276         updateSwitchPreference(mWifiVerboseLogging, enabled);
1277     }
1278
1279     private void writeWifiVerboseLoggingOptions() {
1280         mWifiManager.enableVerboseLogging(mWifiVerboseLogging.isChecked() ? 1 : 0);
1281     }
1282
1283     private void updateWifiAggressiveHandoverOptions() {
1284         boolean enabled = mWifiManager.getAggressiveHandover() > 0;
1285         updateSwitchPreference(mWifiAggressiveHandover, enabled);
1286     }
1287
1288     private void writeWifiAggressiveHandoverOptions() {
1289         mWifiManager.enableAggressiveHandover(mWifiAggressiveHandover.isChecked() ? 1 : 0);
1290     }
1291
1292     private void updateWifiAllowScansWithTrafficOptions() {
1293         boolean enabled = mWifiManager.getAllowScansWithTraffic() > 0;
1294         updateSwitchPreference(mWifiAllowScansWithTraffic, enabled);
1295     }
1296
1297     private void writeWifiAllowScansWithTrafficOptions() {
1298         mWifiManager.setAllowScansWithTraffic(mWifiAllowScansWithTraffic.isChecked() ? 1 : 0);
1299     }
1300
1301     private void updateLegacyDhcpClientOptions() {
1302         updateSwitchPreference(mLegacyDhcpClient, Settings.Global.getInt(
1303                 getActivity().getContentResolver(),
1304                 Settings.Global.LEGACY_DHCP_CLIENT, 0) != 0);
1305     }
1306
1307     private void writeLegacyDhcpClientOptions() {
1308         Settings.Global.putInt(getActivity().getContentResolver(),
1309                 Settings.Global.LEGACY_DHCP_CLIENT,
1310                 mLegacyDhcpClient.isChecked() ? 1 : 0);
1311     }
1312
1313     private void updateMobileDataAlwaysOnOptions() {
1314         updateSwitchPreference(mMobileDataAlwaysOn, Settings.Global.getInt(
1315                 getActivity().getContentResolver(),
1316                 Settings.Global.MOBILE_DATA_ALWAYS_ON, 0) != 0);
1317     }
1318
1319     private void writeMobileDataAlwaysOnOptions() {
1320         Settings.Global.putInt(getActivity().getContentResolver(),
1321                 Settings.Global.MOBILE_DATA_ALWAYS_ON,
1322                 mMobileDataAlwaysOn.isChecked() ? 1 : 0);
1323     }
1324
1325     private void updateLogdSizeValues() {
1326         if (mLogdSize != null) {
1327             String currentValue = SystemProperties.get(SELECT_LOGD_SIZE_PROPERTY);
1328             if (currentValue == null) {
1329                 currentValue = SystemProperties.get(SELECT_LOGD_DEFAULT_SIZE_PROPERTY);
1330                 if (currentValue == null) {
1331                     currentValue = "256K";
1332                 }
1333             }
1334             String[] values = getResources().getStringArray(R.array.select_logd_size_values);
1335             String[] titles = getResources().getStringArray(R.array.select_logd_size_titles);
1336             if (SystemProperties.get("ro.config.low_ram").equals("true")) {
1337                 mLogdSize.setEntries(R.array.select_logd_size_lowram_titles);
1338                 titles = getResources().getStringArray(R.array.select_logd_size_lowram_titles);
1339             }
1340             String[] summaries = getResources().getStringArray(R.array.select_logd_size_summaries);
1341             int index = 1; // punt to second entry if not found
1342             for (int i = 0; i < titles.length; i++) {
1343                 if (currentValue.equals(values[i])
1344                         || currentValue.equals(titles[i])) {
1345                     index = i;
1346                     break;
1347                 }
1348             }
1349             mLogdSize.setValue(values[index]);
1350             mLogdSize.setSummary(summaries[index]);
1351             mLogdSize.setOnPreferenceChangeListener(this);
1352         }
1353     }
1354
1355     private void writeLogdSizeOption(Object newValue) {
1356         String currentValue = SystemProperties.get(SELECT_LOGD_DEFAULT_SIZE_PROPERTY);
1357         if (currentValue != null) {
1358             DEFAULT_LOG_RING_BUFFER_SIZE_IN_BYTES = currentValue;
1359         }
1360         final String size = (newValue != null) ?
1361                 newValue.toString() : DEFAULT_LOG_RING_BUFFER_SIZE_IN_BYTES;
1362         SystemProperties.set(SELECT_LOGD_SIZE_PROPERTY, size);
1363         pokeSystemProperties();
1364         try {
1365             Process p = Runtime.getRuntime().exec("logcat -b all -G " + size);
1366             p.waitFor();
1367             Log.i(TAG, "Logcat ring buffer sizes set to: " + size);
1368         } catch (Exception e) {
1369             Log.w(TAG, "Cannot set logcat ring buffer sizes", e);
1370         }
1371         updateLogdSizeValues();
1372     }
1373
1374     private void updateUsbConfigurationValues() {
1375         if (mUsbConfiguration != null) {
1376             UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
1377
1378             String[] values = getResources().getStringArray(R.array.usb_configuration_values);
1379             String[] titles = getResources().getStringArray(R.array.usb_configuration_titles);
1380             int index = 0;
1381             for (int i = 0; i < titles.length; i++) {
1382                 if (manager.isFunctionEnabled(values[i])) {
1383                     index = i;
1384                     break;
1385                 }
1386             }
1387             mUsbConfiguration.setValue(values[index]);
1388             mUsbConfiguration.setSummary(titles[index]);
1389             mUsbConfiguration.setOnPreferenceChangeListener(this);
1390         }
1391     }
1392
1393     private void writeUsbConfigurationOption(Object newValue) {
1394         UsbManager manager = (UsbManager)getActivity().getSystemService(Context.USB_SERVICE);
1395         String function = newValue.toString();
1396         manager.setCurrentFunction(function);
1397         if (function.equals("none")) {
1398             manager.setUsbDataUnlocked(false);
1399         } else {
1400             manager.setUsbDataUnlocked(true);
1401         }
1402     }
1403
1404     private void updateCpuUsageOptions() {
1405         updateSwitchPreference(mShowCpuUsage,
1406                 Settings.Global.getInt(getActivity().getContentResolver(),
1407                 Settings.Global.SHOW_PROCESSES, 0) != 0);
1408     }
1409
1410     private void writeCpuUsageOptions() {
1411         boolean value = mShowCpuUsage.isChecked();
1412         Settings.Global.putInt(getActivity().getContentResolver(),
1413                 Settings.Global.SHOW_PROCESSES, value ? 1 : 0);
1414         Intent service = (new Intent())
1415                 .setClassName("com.android.systemui", "com.android.systemui.LoadAverageService");
1416         if (value) {
1417             getActivity().startService(service);
1418         } else {
1419             getActivity().stopService(service);
1420         }
1421     }
1422
1423     private void writeImmediatelyDestroyActivitiesOptions() {
1424         try {
1425             ActivityManagerNative.getDefault().setAlwaysFinish(
1426                     mImmediatelyDestroyActivities.isChecked());
1427         } catch (RemoteException ex) {
1428         }
1429     }
1430
1431     private void updateImmediatelyDestroyActivitiesOptions() {
1432         updateSwitchPreference(mImmediatelyDestroyActivities, Settings.Global.getInt(
1433                 getActivity().getContentResolver(), Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0);
1434     }
1435
1436     private void updateAnimationScaleValue(int which, ListPreference pref) {
1437         try {
1438             float scale = mWindowManager.getAnimationScale(which);
1439             if (scale != 1) {
1440                 mHaveDebugSettings = true;
1441             }
1442             CharSequence[] values = pref.getEntryValues();
1443             for (int i=0; i<values.length; i++) {
1444                 float val = Float.parseFloat(values[i].toString());
1445                 if (scale <= val) {
1446                     pref.setValueIndex(i);
1447                     pref.setSummary(pref.getEntries()[i]);
1448                     return;
1449                 }
1450             }
1451             pref.setValueIndex(values.length-1);
1452             pref.setSummary(pref.getEntries()[0]);
1453         } catch (RemoteException e) {
1454         }
1455     }
1456
1457     private void updateAnimationScaleOptions() {
1458         updateAnimationScaleValue(0, mWindowAnimationScale);
1459         updateAnimationScaleValue(1, mTransitionAnimationScale);
1460         updateAnimationScaleValue(2, mAnimatorDurationScale);
1461     }
1462
1463     private void writeAnimationScaleOption(int which, ListPreference pref, Object newValue) {
1464         try {
1465             float scale = newValue != null ? Float.parseFloat(newValue.toString()) : 1;
1466             mWindowManager.setAnimationScale(which, scale);
1467             updateAnimationScaleValue(which, pref);
1468         } catch (RemoteException e) {
1469         }
1470     }
1471
1472     private void updateOverlayDisplayDevicesOptions() {
1473         String value = Settings.Global.getString(getActivity().getContentResolver(),
1474                 Settings.Global.OVERLAY_DISPLAY_DEVICES);
1475         if (value == null) {
1476             value = "";
1477         }
1478
1479         CharSequence[] values = mOverlayDisplayDevices.getEntryValues();
1480         for (int i = 0; i < values.length; i++) {
1481             if (value.contentEquals(values[i])) {
1482                 mOverlayDisplayDevices.setValueIndex(i);
1483                 mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[i]);
1484                 return;
1485             }
1486         }
1487         mOverlayDisplayDevices.setValueIndex(0);
1488         mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[0]);
1489     }
1490
1491     private void writeOverlayDisplayDevicesOptions(Object newValue) {
1492         Settings.Global.putString(getActivity().getContentResolver(),
1493                 Settings.Global.OVERLAY_DISPLAY_DEVICES, (String)newValue);
1494         updateOverlayDisplayDevicesOptions();
1495     }
1496
1497     private void updateOpenGLTracesOptions() {
1498         String value = SystemProperties.get(OPENGL_TRACES_PROPERTY);
1499         if (value == null) {
1500             value = "";
1501         }
1502
1503         CharSequence[] values = mOpenGLTraces.getEntryValues();
1504         for (int i = 0; i < values.length; i++) {
1505             if (value.contentEquals(values[i])) {
1506                 mOpenGLTraces.setValueIndex(i);
1507                 mOpenGLTraces.setSummary(mOpenGLTraces.getEntries()[i]);
1508                 return;
1509             }
1510         }
1511         mOpenGLTraces.setValueIndex(0);
1512         mOpenGLTraces.setSummary(mOpenGLTraces.getEntries()[0]);
1513     }
1514
1515     private void writeOpenGLTracesOptions(Object newValue) {
1516         SystemProperties.set(OPENGL_TRACES_PROPERTY, newValue == null ? "" : newValue.toString());
1517         pokeSystemProperties();
1518         updateOpenGLTracesOptions();
1519     }
1520
1521     private void updateAppProcessLimitOptions() {
1522         try {
1523             int limit = ActivityManagerNative.getDefault().getProcessLimit();
1524             CharSequence[] values = mAppProcessLimit.getEntryValues();
1525             for (int i=0; i<values.length; i++) {
1526                 int val = Integer.parseInt(values[i].toString());
1527                 if (val >= limit) {
1528                     if (i != 0) {
1529                         mHaveDebugSettings = true;
1530                     }
1531                     mAppProcessLimit.setValueIndex(i);
1532                     mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[i]);
1533                     return;
1534                 }
1535             }
1536             mAppProcessLimit.setValueIndex(0);
1537             mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[0]);
1538         } catch (RemoteException e) {
1539         }
1540     }
1541
1542     private void writeAppProcessLimitOptions(Object newValue) {
1543         try {
1544             int limit = newValue != null ? Integer.parseInt(newValue.toString()) : -1;
1545             ActivityManagerNative.getDefault().setProcessLimit(limit);
1546             updateAppProcessLimitOptions();
1547         } catch (RemoteException e) {
1548         }
1549     }
1550
1551     private void writeShowAllANRsOptions() {
1552         Settings.Secure.putInt(getActivity().getContentResolver(),
1553                 Settings.Secure.ANR_SHOW_BACKGROUND,
1554                 mShowAllANRs.isChecked() ? 1 : 0);
1555     }
1556
1557     private void updateShowAllANRsOptions() {
1558         updateSwitchPreference(mShowAllANRs, Settings.Secure.getInt(
1559                 getActivity().getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0);
1560     }
1561
1562     private void confirmEnableOemUnlock() {
1563         DialogInterface.OnClickListener onConfirmListener = new DialogInterface.OnClickListener() {
1564             @Override
1565             public void onClick(DialogInterface dialog, int which) {
1566                 Utils.setOemUnlockEnabled(getActivity(), true);
1567                 updateAllOptions();
1568             }
1569         };
1570
1571         new AlertDialog.Builder(getActivity())
1572                 .setTitle(R.string.confirm_enable_oem_unlock_title)
1573                 .setMessage(R.string.confirm_enable_oem_unlock_text)
1574                 .setPositiveButton(R.string.enable_text, onConfirmListener)
1575                 .setNegativeButton(android.R.string.cancel, null)
1576                 .create()
1577                 .show();
1578     }
1579
1580     private void confirmEnableMultiWindowMode() {
1581         DialogInterface.OnClickListener onConfirmListener = new DialogInterface.OnClickListener() {
1582             @Override
1583             public void onClick(DialogInterface dialog, int which) {
1584                 setEnableMultiWindow((which == DialogInterface.BUTTON_POSITIVE) ? true : false);
1585                 updateAllOptions();
1586             }
1587         };
1588
1589         new AlertDialog.Builder(getActivity())
1590                 .setTitle(R.string.confirm_enable_multi_window_title)
1591                 .setMessage(R.string.confirm_enable_multi_window_text)
1592                 .setPositiveButton(R.string.enable_text, onConfirmListener)
1593                 .setNegativeButton(android.R.string.cancel, onConfirmListener)
1594                 .create()
1595                 .show();
1596     }
1597
1598     @Override
1599     public void onSwitchChanged(Switch switchView, boolean isChecked) {
1600         if (switchView != mSwitchBar.getSwitch()) {
1601             return;
1602         }
1603         if (isChecked != mLastEnabledState) {
1604             if (isChecked) {
1605                 mDialogClicked = false;
1606                 if (mEnableDialog != null) dismissDialogs();
1607                 mEnableDialog = new AlertDialog.Builder(getActivity()).setMessage(
1608                         getActivity().getResources().getString(
1609                                 R.string.dev_settings_warning_message))
1610                         .setTitle(R.string.dev_settings_warning_title)
1611                         .setPositiveButton(android.R.string.yes, this)
1612                         .setNegativeButton(android.R.string.no, this)
1613                         .show();
1614                 mEnableDialog.setOnDismissListener(this);
1615             } else {
1616                 resetDangerousOptions();
1617                 Settings.Global.putInt(getActivity().getContentResolver(),
1618                         Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
1619                 mLastEnabledState = isChecked;
1620                 setPrefsEnabledState(mLastEnabledState);
1621             }
1622         }
1623     }
1624
1625     @Override
1626     public void onActivityResult(int requestCode, int resultCode, Intent data) {
1627         if (requestCode == RESULT_DEBUG_APP) {
1628             if (resultCode == Activity.RESULT_OK) {
1629                 mDebugApp = data.getAction();
1630                 writeDebuggerOptions();
1631                 updateDebuggerOptions();
1632             }
1633         } else if (requestCode == RESULT_MOCK_LOCATION_APP) {
1634             if (resultCode == Activity.RESULT_OK) {
1635                 mMockLocationApp = data.getAction();
1636                 writeMockLocation();
1637                 updateMockLocation();
1638             }
1639         } else if (requestCode == REQUEST_CODE_ENABLE_OEM_UNLOCK) {
1640             if (resultCode == Activity.RESULT_OK) {
1641                 if (mEnableOemUnlock.isChecked()) {
1642                     confirmEnableOemUnlock();
1643                 } else {
1644                     Utils.setOemUnlockEnabled(getActivity(), false);
1645                 }
1646             }
1647         } else {
1648             super.onActivityResult(requestCode, resultCode, data);
1649         }
1650     }
1651
1652     @Override
1653     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
1654         if (Utils.isMonkeyRunning()) {
1655             return false;
1656         }
1657
1658         if (preference == mEnableAdb) {
1659             if (mEnableAdb.isChecked()) {
1660                 mDialogClicked = false;
1661                 if (mAdbDialog != null) dismissDialogs();
1662                 mAdbDialog = new AlertDialog.Builder(getActivity()).setMessage(
1663                         getActivity().getResources().getString(R.string.adb_warning_message))
1664                         .setTitle(R.string.adb_warning_title)
1665                         .setPositiveButton(android.R.string.yes, this)
1666                         .setNegativeButton(android.R.string.no, this)
1667                         .show();
1668                 mAdbDialog.setOnDismissListener(this);
1669             } else {
1670                 Settings.Global.putInt(getActivity().getContentResolver(),
1671                         Settings.Global.ADB_ENABLED, 0);
1672                 mVerifyAppsOverUsb.setEnabled(false);
1673                 mVerifyAppsOverUsb.setChecked(false);
1674                 updateBugreportOptions();
1675             }
1676         } else if (preference == mClearAdbKeys) {
1677             if (mAdbKeysDialog != null) dismissDialogs();
1678             mAdbKeysDialog = new AlertDialog.Builder(getActivity())
1679                         .setMessage(R.string.adb_keys_warning_message)
1680                         .setPositiveButton(android.R.string.ok, this)
1681                         .setNegativeButton(android.R.string.cancel, null)
1682                         .show();
1683         } else if (preference == mEnableTerminal) {
1684             final PackageManager pm = getActivity().getPackageManager();
1685             pm.setApplicationEnabledSetting(TERMINAL_APP_PACKAGE,
1686                     mEnableTerminal.isChecked() ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
1687                             : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0);
1688         } else if (preference == mBugreportInPower) {
1689             Settings.Secure.putInt(getActivity().getContentResolver(),
1690                     Settings.Secure.BUGREPORT_IN_POWER_MENU,
1691                     mBugreportInPower.isChecked() ? 1 : 0);
1692         } else if (preference == mKeepScreenOn) {
1693             Settings.Global.putInt(getActivity().getContentResolver(),
1694                     Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
1695                     mKeepScreenOn.isChecked() ?
1696                             (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB) : 0);
1697         } else if (preference == mBtHciSnoopLog) {
1698             writeBtHciSnoopLogOptions();
1699         } else if (preference == mEnableOemUnlock) {
1700             if (!showKeyguardConfirmation(getResources(), REQUEST_CODE_ENABLE_OEM_UNLOCK)) {
1701                 if (mEnableOemUnlock.isChecked()) {
1702                     confirmEnableOemUnlock();
1703                 } else {
1704                     Utils.setOemUnlockEnabled(getActivity(), false);
1705                 }
1706             }
1707         } else if (preference == mMockLocationAppPref) {
1708             Intent intent = new Intent(getActivity(), AppPicker.class);
1709             intent.putExtra(AppPicker.EXTRA_REQUESTIING_PERMISSION,
1710                     Manifest.permission.ACCESS_MOCK_LOCATION);
1711             startActivityForResult(intent, RESULT_MOCK_LOCATION_APP);
1712         } else if (preference == mDebugViewAttributes) {
1713             Settings.Global.putInt(getActivity().getContentResolver(),
1714                     Settings.Global.DEBUG_VIEW_ATTRIBUTES,
1715                     mDebugViewAttributes.isChecked() ? 1 : 0);
1716         } else if (preference == mDebugAppPref) {
1717             Intent intent = new Intent(getActivity(), AppPicker.class);
1718             intent.putExtra(AppPicker.EXTRA_DEBUGGABLE, true);
1719             startActivityForResult(intent, RESULT_DEBUG_APP);
1720         } else if (preference == mWaitForDebugger) {
1721             writeDebuggerOptions();
1722         } else if (preference == mVerifyAppsOverUsb) {
1723             writeVerifyAppsOverUsbOptions();
1724         } else if (preference == mStrictMode) {
1725             writeStrictModeVisualOptions();
1726         } else if (preference == mPointerLocation) {
1727             writePointerLocationOptions();
1728         } else if (preference == mShowTouches) {
1729             writeShowTouchesOptions();
1730         } else if (preference == mShowScreenUpdates) {
1731             writeShowUpdatesOption();
1732         } else if (preference == mDisableOverlays) {
1733             writeDisableOverlaysOption();
1734         } else if (preference == mEnableMultiWindow) {
1735             if (mEnableMultiWindow.isChecked()) {
1736                 confirmEnableMultiWindowMode();
1737             } else {
1738                 setEnableMultiWindow(false);
1739             }
1740         } else if (preference == mShowCpuUsage) {
1741             writeCpuUsageOptions();
1742         } else if (preference == mImmediatelyDestroyActivities) {
1743             writeImmediatelyDestroyActivitiesOptions();
1744         } else if (preference == mShowAllANRs) {
1745             writeShowAllANRsOptions();
1746         } else if (preference == mForceHardwareUi) {
1747             writeHardwareUiOptions();
1748         } else if (preference == mForceMsaa) {
1749             writeMsaaOptions();
1750         } else if (preference == mShowHwScreenUpdates) {
1751             writeShowHwScreenUpdatesOptions();
1752         } else if (preference == mShowHwLayersUpdates) {
1753             writeShowHwLayersUpdatesOptions();
1754         } else if (preference == mDebugLayout) {
1755             writeDebugLayoutOptions();
1756         } else if (preference == mForceRtlLayout) {
1757             writeForceRtlOptions();
1758         } else if (preference == mWifiDisplayCertification) {
1759             writeWifiDisplayCertificationOptions();
1760         } else if (preference == mWifiVerboseLogging) {
1761             writeWifiVerboseLoggingOptions();
1762         } else if (preference == mWifiAggressiveHandover) {
1763             writeWifiAggressiveHandoverOptions();
1764         } else if (preference == mWifiAllowScansWithTraffic) {
1765             writeWifiAllowScansWithTrafficOptions();
1766         } else if (preference == mLegacyDhcpClient) {
1767             writeLegacyDhcpClientOptions();
1768         } else if (preference == mMobileDataAlwaysOn) {
1769             writeMobileDataAlwaysOnOptions();
1770         } else if (preference == mUSBAudio) {
1771             writeUSBAudioOptions();
1772         } else if (INACTIVE_APPS_KEY.equals(preference.getKey())) {
1773             startInactiveAppsFragment();
1774         } else {
1775             return super.onPreferenceTreeClick(preferenceScreen, preference);
1776         }
1777
1778         return false;
1779     }
1780
1781     private void startInactiveAppsFragment() {
1782         ((SettingsActivity) getActivity()).startPreferencePanel(
1783                 InactiveApps.class.getName(),
1784                 null, R.string.inactive_apps_title, null, null, 0);
1785     }
1786
1787     private boolean showKeyguardConfirmation(Resources resources, int requestCode) {
1788         return new ChooseLockSettingsHelper(getActivity(), this).launchConfirmationActivity(
1789                 requestCode, resources.getString(R.string.oem_unlock_enable));
1790     }
1791
1792     @Override
1793     public boolean onPreferenceChange(Preference preference, Object newValue) {
1794         if (HDCP_CHECKING_KEY.equals(preference.getKey())) {
1795             SystemProperties.set(HDCP_CHECKING_PROPERTY, newValue.toString());
1796             updateHdcpValues();
1797             pokeSystemProperties();
1798             return true;
1799         } else if (preference == mLogdSize) {
1800             writeLogdSizeOption(newValue);
1801             return true;
1802         } else if (preference == mUsbConfiguration) {
1803             writeUsbConfigurationOption(newValue);
1804             return true;
1805         } else if (preference == mWindowAnimationScale) {
1806             writeAnimationScaleOption(0, mWindowAnimationScale, newValue);
1807             return true;
1808         } else if (preference == mTransitionAnimationScale) {
1809             writeAnimationScaleOption(1, mTransitionAnimationScale, newValue);
1810             return true;
1811         } else if (preference == mAnimatorDurationScale) {
1812             writeAnimationScaleOption(2, mAnimatorDurationScale, newValue);
1813             return true;
1814         } else if (preference == mOverlayDisplayDevices) {
1815             writeOverlayDisplayDevicesOptions(newValue);
1816             return true;
1817         } else if (preference == mOpenGLTraces) {
1818             writeOpenGLTracesOptions(newValue);
1819             return true;
1820         } else if (preference == mTrackFrameTime) {
1821             writeTrackFrameTimeOptions(newValue);
1822             return true;
1823         } else if (preference == mDebugHwOverdraw) {
1824             writeDebugHwOverdrawOptions(newValue);
1825             return true;
1826         } else if (preference == mShowNonRectClip) {
1827             writeShowNonRectClipOptions(newValue);
1828             return true;
1829         } else if (preference == mAppProcessLimit) {
1830             writeAppProcessLimitOptions(newValue);
1831             return true;
1832         } else if (preference == mSimulateColorSpace) {
1833             writeSimulateColorSpace(newValue);
1834             return true;
1835         } else if (preference == mRootAccess) {
1836             if ("0".equals(SystemProperties.get(ROOT_ACCESS_PROPERTY, "1"))
1837                     && !"0".equals(newValue)) {
1838                 mSelectedRootValue = newValue;
1839                 mDialogClicked = false;
1840                 if (mRootDialog != null) {
1841                     dismissDialogs();
1842                 }
1843                 mRootDialog = new AlertDialog.Builder(getActivity())
1844                         .setMessage(getResources().getString(R.string.root_access_warning_message))
1845                         .setTitle(R.string.root_access_warning_title)
1846                         .setIcon(android.R.drawable.ic_dialog_alert)
1847                         .setPositiveButton(android.R.string.yes, this)
1848                         .setNegativeButton(android.R.string.no, this).show();
1849                 mRootDialog.setOnDismissListener(this);
1850             } else {
1851                 writeRootAccessOptions(newValue);
1852             }
1853             return true;
1854         }
1855         return false;
1856     }
1857
1858     private void dismissDialogs() {
1859         if (mAdbDialog != null) {
1860             mAdbDialog.dismiss();
1861             mAdbDialog = null;
1862         }
1863         if (mAdbKeysDialog != null) {
1864             mAdbKeysDialog.dismiss();
1865             mAdbKeysDialog = null;
1866         }
1867         if (mEnableDialog != null) {
1868             mEnableDialog.dismiss();
1869             mEnableDialog = null;
1870         }
1871         if (mRootDialog != null) {
1872             mRootDialog.dismiss();
1873             mRootDialog = null;
1874         }
1875     }
1876
1877     public void onClick(DialogInterface dialog, int which) {
1878         if (dialog == mAdbDialog) {
1879             if (which == DialogInterface.BUTTON_POSITIVE) {
1880                 mDialogClicked = true;
1881                 Settings.Global.putInt(getActivity().getContentResolver(),
1882                         Settings.Global.ADB_ENABLED, 1);
1883                 mVerifyAppsOverUsb.setEnabled(true);
1884                 updateVerifyAppsOverUsbOptions();
1885                 updateBugreportOptions();
1886             } else {
1887                 // Reset the toggle
1888                 mEnableAdb.setChecked(false);
1889             }
1890         } else if (dialog == mAdbKeysDialog) {
1891             if (which == DialogInterface.BUTTON_POSITIVE) {
1892                 try {
1893                     IBinder b = ServiceManager.getService(Context.USB_SERVICE);
1894                     IUsbManager service = IUsbManager.Stub.asInterface(b);
1895                     service.clearUsbDebuggingKeys();
1896                 } catch (RemoteException e) {
1897                     Log.e(TAG, "Unable to clear adb keys", e);
1898                 }
1899             }
1900         } else if (dialog == mEnableDialog) {
1901             if (which == DialogInterface.BUTTON_POSITIVE) {
1902                 mDialogClicked = true;
1903                 Settings.Global.putInt(getActivity().getContentResolver(),
1904                         Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
1905                 mLastEnabledState = true;
1906                 setPrefsEnabledState(mLastEnabledState);
1907             } else {
1908                 // Reset the toggle
1909                 mSwitchBar.setChecked(false);
1910             }
1911         } else if (dialog == mRootDialog) {
1912             if (which == DialogInterface.BUTTON_POSITIVE) {
1913                 writeRootAccessOptions(mSelectedRootValue);
1914             } else {
1915                 // Reset the option
1916                 writeRootAccessOptions("0");
1917             }
1918         }
1919     }
1920
1921     public void onDismiss(DialogInterface dialog) {
1922         // Assuming that onClick gets called first
1923         if (dialog == mAdbDialog) {
1924             if (!mDialogClicked) {
1925                 mEnableAdb.setChecked(false);
1926             }
1927             mAdbDialog = null;
1928         } else if (dialog == mEnableDialog) {
1929             if (!mDialogClicked) {
1930                 mSwitchBar.setChecked(false);
1931             }
1932             mEnableDialog = null;
1933         }
1934     }
1935
1936     @Override
1937     public void onDestroy() {
1938         dismissDialogs();
1939         super.onDestroy();
1940     }
1941
1942     void pokeSystemProperties() {
1943         if (!mDontPokeProperties) {
1944             //noinspection unchecked
1945             (new SystemPropPoker()).execute();
1946         }
1947     }
1948
1949     private BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
1950         @Override
1951         public void onReceive(Context context, Intent intent) {
1952             updateUsbConfigurationValues();
1953         }
1954     };
1955
1956     static class SystemPropPoker extends AsyncTask<Void, Void, Void> {
1957         @Override
1958         protected Void doInBackground(Void... params) {
1959             String[] services;
1960             try {
1961                 services = ServiceManager.listServices();
1962             } catch (RemoteException e) {
1963                 return null;
1964             }
1965             for (String service : services) {
1966                 IBinder obj = ServiceManager.checkService(service);
1967                 if (obj != null) {
1968                     Parcel data = Parcel.obtain();
1969                     try {
1970                         obj.transact(IBinder.SYSPROPS_TRANSACTION, data, null, 0);
1971                     } catch (RemoteException e) {
1972                     } catch (Exception e) {
1973                         Log.i(TAG, "Someone wrote a bad service '" + service
1974                                 + "' that doesn't like to be poked: " + e);
1975                     }
1976                     data.recycle();
1977                 }
1978             }
1979             return null;
1980         }
1981     }
1982
1983     private static boolean isPackageInstalled(Context context, String packageName) {
1984         try {
1985             return context.getPackageManager().getPackageInfo(packageName, 0) != null;
1986         } catch (NameNotFoundException e) {
1987             return false;
1988         }
1989     }
1990
1991     /**
1992      * For Search.
1993      */
1994     public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
1995             new BaseSearchIndexProvider() {
1996
1997                 private boolean isShowingDeveloperOptions(Context context) {
1998                     return context.getSharedPreferences(DevelopmentSettings.PREF_FILE,
1999                             Context.MODE_PRIVATE).getBoolean(
2000                                     DevelopmentSettings.PREF_SHOW,
2001                                     android.os.Build.TYPE.equals("eng"));
2002                 }
2003
2004                 @Override
2005                 public List<SearchIndexableResource> getXmlResourcesToIndex(
2006                         Context context, boolean enabled) {
2007
2008                     if (!isShowingDeveloperOptions(context)) {
2009                         return null;
2010                     }
2011
2012                     final SearchIndexableResource sir = new SearchIndexableResource(context);
2013                     sir.xmlResId = R.xml.development_prefs;
2014                     return Arrays.asList(sir);
2015                 }
2016
2017                 @Override
2018                 public List<String> getNonIndexableKeys(Context context) {
2019                     if (!isShowingDeveloperOptions(context)) {
2020                         return null;
2021                     }
2022
2023                     final List<String> keys = new ArrayList<String>();
2024                     if (!showEnableOemUnlockPreference()) {
2025                         keys.add(ENABLE_OEM_UNLOCK);
2026                     }
2027                     if (!showEnableMultiWindowPreference()) {
2028                         keys.add(ENABLE_MULTI_WINDOW_KEY);
2029                     }
2030                     return keys;
2031                 }
2032             };
2033 }