OSDN Git Service

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