OSDN Git Service

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