OSDN Git Service

Guard against missing terminal 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 static android.Manifest.permission.READ_EXTERNAL_STORAGE;
20
21 import android.app.ActionBar;
22 import android.app.Activity;
23 import android.app.ActivityManagerNative;
24 import android.app.ActivityThread;
25 import android.app.AlertDialog;
26 import android.app.Dialog;
27 import android.app.DialogFragment;
28 import android.app.admin.DevicePolicyManager;
29 import android.app.backup.IBackupManager;
30 import android.content.ContentResolver;
31 import android.content.Context;
32 import android.content.DialogInterface;
33 import android.content.DialogInterface.OnClickListener;
34 import android.content.Intent;
35 import android.content.pm.ApplicationInfo;
36 import android.content.pm.PackageManager;
37 import android.content.pm.PackageManager.NameNotFoundException;
38 import android.content.pm.ResolveInfo;
39 import android.hardware.usb.IUsbManager;
40 import android.os.AsyncTask;
41 import android.os.BatteryManager;
42 import android.os.Build;
43 import android.os.Bundle;
44 import android.os.IBinder;
45 import android.os.Parcel;
46 import android.os.RemoteException;
47 import android.os.ServiceManager;
48 import android.os.StrictMode;
49 import android.os.SystemProperties;
50 import android.os.UserHandle;
51 import android.preference.CheckBoxPreference;
52 import android.preference.ListPreference;
53 import android.preference.Preference;
54 import android.preference.Preference.OnPreferenceChangeListener;
55 import android.preference.PreferenceFragment;
56 import android.preference.PreferenceGroup;
57 import android.preference.PreferenceScreen;
58 import android.provider.Settings;
59 import android.text.TextUtils;
60 import android.util.Log;
61 import android.view.Gravity;
62 import android.view.HardwareRenderer;
63 import android.view.IWindowManager;
64 import android.view.View;
65 import android.widget.CompoundButton;
66 import android.widget.Switch;
67
68 import java.util.ArrayList;
69 import java.util.HashSet;
70 import java.util.List;
71
72 /*
73  * Displays preferences for application developers.
74  */
75 public class DevelopmentSettings extends PreferenceFragment
76         implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener,
77                 OnPreferenceChangeListener, CompoundButton.OnCheckedChangeListener {
78     private static final String TAG = "DevelopmentSettings";
79
80     /**
81      * Preference file were development settings prefs are stored.
82      */
83     public static final String PREF_FILE = "development";
84
85     /**
86      * Whether to show the development settings to the user.  Default is false.
87      */
88     public static final String PREF_SHOW = "show";
89
90     private static final String ENABLE_ADB = "enable_adb";
91     private static final String CLEAR_ADB_KEYS = "clear_adb_keys";
92     private static final String ENABLE_TERMINAL = "enable_terminal";
93     private static final String KEEP_SCREEN_ON = "keep_screen_on";
94     private static final String ALLOW_MOCK_LOCATION = "allow_mock_location";
95     private static final String HDCP_CHECKING_KEY = "hdcp_checking";
96     private static final String HDCP_CHECKING_PROPERTY = "persist.sys.hdcp_checking";
97     private static final String ENFORCE_READ_EXTERNAL = "enforce_read_external";
98     private static final String LOCAL_BACKUP_PASSWORD = "local_backup_password";
99     private static final String HARDWARE_UI_PROPERTY = "persist.sys.ui.hw";
100     private static final String MSAA_PROPERTY = "debug.egl.force_msaa";
101     private static final String BUGREPORT = "bugreport";
102     private static final String BUGREPORT_IN_POWER_KEY = "bugreport_in_power";
103     private static final String OPENGL_TRACES_PROPERTY = "debug.egl.trace";
104
105     private static final String DEBUG_APP_KEY = "debug_app";
106     private static final String WAIT_FOR_DEBUGGER_KEY = "wait_for_debugger";
107     private static final String VERIFY_APPS_OVER_USB_KEY = "verify_apps_over_usb";
108     private static final String STRICT_MODE_KEY = "strict_mode";
109     private static final String POINTER_LOCATION_KEY = "pointer_location";
110     private static final String SHOW_TOUCHES_KEY = "show_touches";
111     private static final String SHOW_SCREEN_UPDATES_KEY = "show_screen_updates";
112     private static final String DISABLE_OVERLAYS_KEY = "disable_overlays";
113     private static final String SHOW_CPU_USAGE_KEY = "show_cpu_usage";
114     private static final String FORCE_HARDWARE_UI_KEY = "force_hw_ui";
115     private static final String FORCE_MSAA_KEY = "force_msaa";
116     private static final String TRACK_FRAME_TIME_KEY = "track_frame_time";
117     private static final String SHOW_NON_RECTANGULAR_CLIP_KEY = "show_non_rect_clip";
118     private static final String SHOW_HW_SCREEN_UPDATES_KEY = "show_hw_screen_udpates";
119     private static final String SHOW_HW_LAYERS_UPDATES_KEY = "show_hw_layers_udpates";
120     private static final String SHOW_HW_OVERDRAW_KEY = "show_hw_overdraw";
121     private static final String DEBUG_LAYOUT_KEY = "debug_layout";
122     private static final String WINDOW_ANIMATION_SCALE_KEY = "window_animation_scale";
123     private static final String TRANSITION_ANIMATION_SCALE_KEY = "transition_animation_scale";
124     private static final String ANIMATOR_DURATION_SCALE_KEY = "animator_duration_scale";
125     private static final String OVERLAY_DISPLAY_DEVICES_KEY = "overlay_display_devices";
126     private static final String DEBUG_DEBUGGING_CATEGORY_KEY = "debug_debugging_category";
127     private static final String OPENGL_TRACES_KEY = "enable_opengl_traces";
128
129     private static final String IMMEDIATELY_DESTROY_ACTIVITIES_KEY
130             = "immediately_destroy_activities";
131     private static final String APP_PROCESS_LIMIT_KEY = "app_process_limit";
132
133     private static final String SHOW_ALL_ANRS_KEY = "show_all_anrs";
134
135     private static final String TAG_CONFIRM_ENFORCE = "confirm_enforce";
136
137     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
138
139     private static final String TERMINAL_APP_PACKAGE = "com.android.terminal";
140
141     private static final int RESULT_DEBUG_APP = 1000;
142
143     private IWindowManager mWindowManager;
144     private IBackupManager mBackupManager;
145     private DevicePolicyManager mDpm;
146
147     private Switch mEnabledSwitch;
148     private boolean mLastEnabledState;
149     private boolean mHaveDebugSettings;
150     private boolean mDontPokeProperties;
151
152     private CheckBoxPreference mEnableAdb;
153     private Preference mClearAdbKeys;
154     private CheckBoxPreference mEnableTerminal;
155     private Preference mBugreport;
156     private CheckBoxPreference mBugreportInPower;
157     private CheckBoxPreference mKeepScreenOn;
158     private CheckBoxPreference mEnforceReadExternal;
159     private CheckBoxPreference mAllowMockLocation;
160     private PreferenceScreen mPassword;
161
162     private String mDebugApp;
163     private Preference mDebugAppPref;
164     private CheckBoxPreference mWaitForDebugger;
165     private CheckBoxPreference mVerifyAppsOverUsb;
166
167     private CheckBoxPreference mStrictMode;
168     private CheckBoxPreference mPointerLocation;
169     private CheckBoxPreference mShowTouches;
170     private CheckBoxPreference mShowScreenUpdates;
171     private CheckBoxPreference mDisableOverlays;
172     private CheckBoxPreference mShowCpuUsage;
173     private CheckBoxPreference mForceHardwareUi;
174     private CheckBoxPreference mForceMsaa;
175     private CheckBoxPreference mShowHwScreenUpdates;
176     private CheckBoxPreference mShowHwLayersUpdates;
177     private CheckBoxPreference mShowHwOverdraw;
178     private CheckBoxPreference mDebugLayout;
179     private ListPreference mTrackFrameTime;
180     private ListPreference mShowNonRectClip;
181     private ListPreference mWindowAnimationScale;
182     private ListPreference mTransitionAnimationScale;
183     private ListPreference mAnimatorDurationScale;
184     private ListPreference mOverlayDisplayDevices;
185     private ListPreference mOpenGLTraces;
186
187     private CheckBoxPreference mImmediatelyDestroyActivities;
188     private ListPreference mAppProcessLimit;
189
190     private CheckBoxPreference mShowAllANRs;
191
192     private final ArrayList<Preference> mAllPrefs = new ArrayList<Preference>();
193     private final ArrayList<CheckBoxPreference> mResetCbPrefs
194             = new ArrayList<CheckBoxPreference>();
195
196     private final HashSet<Preference> mDisabledPrefs = new HashSet<Preference>();
197
198     // To track whether a confirmation dialog was clicked.
199     private boolean mDialogClicked;
200     private Dialog mEnableDialog;
201     private Dialog mAdbDialog;
202     private Dialog mAdbKeysDialog;
203
204     @Override
205     public void onCreate(Bundle icicle) {
206         super.onCreate(icicle);
207
208         mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
209         mBackupManager = IBackupManager.Stub.asInterface(
210                 ServiceManager.getService(Context.BACKUP_SERVICE));
211         mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
212
213         addPreferencesFromResource(R.xml.development_prefs);
214
215         final PreferenceGroup debugDebuggingCategory = (PreferenceGroup)
216                 findPreference(DEBUG_DEBUGGING_CATEGORY_KEY);
217
218         mEnableAdb = findAndInitCheckboxPref(ENABLE_ADB);
219         mClearAdbKeys = findPreference(CLEAR_ADB_KEYS);
220         if (!SystemProperties.getBoolean("ro.adb.secure", false)) {
221             if (debugDebuggingCategory != null) {
222                 debugDebuggingCategory.removePreference(mClearAdbKeys);
223             }
224         }
225         mEnableTerminal = findAndInitCheckboxPref(ENABLE_TERMINAL);
226         if (!isPackageInstalled(getActivity(), TERMINAL_APP_PACKAGE)) {
227             debugDebuggingCategory.removePreference(mEnableTerminal);
228             mEnableTerminal = null;
229         }
230
231         mBugreport = findPreference(BUGREPORT);
232         mBugreportInPower = findAndInitCheckboxPref(BUGREPORT_IN_POWER_KEY);
233         mKeepScreenOn = findAndInitCheckboxPref(KEEP_SCREEN_ON);
234         mEnforceReadExternal = findAndInitCheckboxPref(ENFORCE_READ_EXTERNAL);
235         mAllowMockLocation = findAndInitCheckboxPref(ALLOW_MOCK_LOCATION);
236         mPassword = (PreferenceScreen) findPreference(LOCAL_BACKUP_PASSWORD);
237         mAllPrefs.add(mPassword);
238
239         if (!android.os.Process.myUserHandle().equals(UserHandle.OWNER)) {
240             disableForUser(mEnableAdb);
241             disableForUser(mClearAdbKeys);
242             disableForUser(mEnableTerminal);
243             disableForUser(mPassword);
244         }
245
246         mDebugAppPref = findPreference(DEBUG_APP_KEY);
247         mAllPrefs.add(mDebugAppPref);
248         mWaitForDebugger = findAndInitCheckboxPref(WAIT_FOR_DEBUGGER_KEY);
249         mVerifyAppsOverUsb = findAndInitCheckboxPref(VERIFY_APPS_OVER_USB_KEY);
250         if (!showVerifierSetting()) {
251             if (debugDebuggingCategory != null) {
252                 debugDebuggingCategory.removePreference(mVerifyAppsOverUsb);
253             } else {
254                 mVerifyAppsOverUsb.setEnabled(false);
255             }
256         }
257         mStrictMode = findAndInitCheckboxPref(STRICT_MODE_KEY);
258         mPointerLocation = findAndInitCheckboxPref(POINTER_LOCATION_KEY);
259         mShowTouches = findAndInitCheckboxPref(SHOW_TOUCHES_KEY);
260         mShowScreenUpdates = findAndInitCheckboxPref(SHOW_SCREEN_UPDATES_KEY);
261         mDisableOverlays = findAndInitCheckboxPref(DISABLE_OVERLAYS_KEY);
262         mShowCpuUsage = findAndInitCheckboxPref(SHOW_CPU_USAGE_KEY);
263         mForceHardwareUi = findAndInitCheckboxPref(FORCE_HARDWARE_UI_KEY);
264         mForceMsaa = findAndInitCheckboxPref(FORCE_MSAA_KEY);
265         mTrackFrameTime = addListPreference(TRACK_FRAME_TIME_KEY);
266         mShowNonRectClip = addListPreference(SHOW_NON_RECTANGULAR_CLIP_KEY);
267         mShowHwScreenUpdates = findAndInitCheckboxPref(SHOW_HW_SCREEN_UPDATES_KEY);
268         mShowHwLayersUpdates = findAndInitCheckboxPref(SHOW_HW_LAYERS_UPDATES_KEY);
269         mShowHwOverdraw = findAndInitCheckboxPref(SHOW_HW_OVERDRAW_KEY);
270         mDebugLayout = findAndInitCheckboxPref(DEBUG_LAYOUT_KEY);
271         mWindowAnimationScale = addListPreference(WINDOW_ANIMATION_SCALE_KEY);
272         mTransitionAnimationScale = addListPreference(TRANSITION_ANIMATION_SCALE_KEY);
273         mAnimatorDurationScale = addListPreference(ANIMATOR_DURATION_SCALE_KEY);
274         mOverlayDisplayDevices = addListPreference(OVERLAY_DISPLAY_DEVICES_KEY);
275         mOpenGLTraces = addListPreference(OPENGL_TRACES_KEY);
276
277         mImmediatelyDestroyActivities = (CheckBoxPreference) findPreference(
278                 IMMEDIATELY_DESTROY_ACTIVITIES_KEY);
279         mAllPrefs.add(mImmediatelyDestroyActivities);
280         mResetCbPrefs.add(mImmediatelyDestroyActivities);
281         mAppProcessLimit = addListPreference(APP_PROCESS_LIMIT_KEY);
282
283         mShowAllANRs = (CheckBoxPreference) findPreference(
284                 SHOW_ALL_ANRS_KEY);
285         mAllPrefs.add(mShowAllANRs);
286         mResetCbPrefs.add(mShowAllANRs);
287
288         Preference hdcpChecking = findPreference(HDCP_CHECKING_KEY);
289         if (hdcpChecking != null) {
290             mAllPrefs.add(hdcpChecking);
291         }
292         removeHdcpOptionsForProduction();
293     }
294
295     private ListPreference addListPreference(String prefKey) {
296         ListPreference pref = (ListPreference) findPreference(prefKey);
297         mAllPrefs.add(pref);
298         pref.setOnPreferenceChangeListener(this);
299         return pref;
300     }
301
302     private void disableForUser(Preference pref) {
303         if (pref != null) {
304             pref.setEnabled(false);
305             mDisabledPrefs.add(pref);
306         }
307     }
308
309     private CheckBoxPreference findAndInitCheckboxPref(String key) {
310         CheckBoxPreference pref = (CheckBoxPreference) findPreference(key);
311         if (pref == null) {
312             throw new IllegalArgumentException("Cannot find preference with key = " + key);
313         }
314         mAllPrefs.add(pref);
315         mResetCbPrefs.add(pref);
316         return pref;
317     }
318
319     @Override
320     public void onActivityCreated(Bundle savedInstanceState) {
321         super.onActivityCreated(savedInstanceState);
322
323         final Activity activity = getActivity();
324         mEnabledSwitch = new Switch(activity);
325
326         final int padding = activity.getResources().getDimensionPixelSize(
327                 R.dimen.action_bar_switch_padding);
328         mEnabledSwitch.setPaddingRelative(0, 0, padding, 0);
329         mEnabledSwitch.setOnCheckedChangeListener(this);
330     }
331
332     @Override
333     public void onStart() {
334         super.onStart();
335         final Activity activity = getActivity();
336         activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
337                 ActionBar.DISPLAY_SHOW_CUSTOM);
338         activity.getActionBar().setCustomView(mEnabledSwitch, new ActionBar.LayoutParams(
339                 ActionBar.LayoutParams.WRAP_CONTENT,
340                 ActionBar.LayoutParams.WRAP_CONTENT,
341                 Gravity.CENTER_VERTICAL | Gravity.END));
342     }
343
344     @Override
345     public void onStop() {
346         super.onStop();
347         final Activity activity = getActivity();
348         activity.getActionBar().setDisplayOptions(0, ActionBar.DISPLAY_SHOW_CUSTOM);
349         activity.getActionBar().setCustomView(null);
350     }
351
352     private void removeHdcpOptionsForProduction() {
353         if ("user".equals(Build.TYPE)) {
354             Preference hdcpChecking = findPreference(HDCP_CHECKING_KEY);
355             if (hdcpChecking != null) {
356                 // Remove the preference
357                 getPreferenceScreen().removePreference(hdcpChecking);
358                 mAllPrefs.remove(hdcpChecking);
359             }
360         }
361     }
362
363     private void setPrefsEnabledState(boolean enabled) {
364         for (int i = 0; i < mAllPrefs.size(); i++) {
365             Preference pref = mAllPrefs.get(i);
366             pref.setEnabled(enabled && !mDisabledPrefs.contains(pref));
367         }
368         updateAllOptions();
369     }
370
371     @Override
372     public void onResume() {
373         super.onResume();
374
375         if (mDpm.getMaximumTimeToLock(null) > 0) {
376             // A DeviceAdmin has specified a maximum time until the device
377             // will lock...  in this case we can't allow the user to turn
378             // on "stay awake when plugged in" because that would defeat the
379             // restriction.
380             mDisabledPrefs.add(mKeepScreenOn);
381         } else {
382             mDisabledPrefs.remove(mKeepScreenOn);
383         }
384
385         final ContentResolver cr = getActivity().getContentResolver();
386         mLastEnabledState = Settings.Global.getInt(cr,
387                 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
388         mEnabledSwitch.setChecked(mLastEnabledState);
389         setPrefsEnabledState(mLastEnabledState);
390
391         if (mHaveDebugSettings && !mLastEnabledState) {
392             // Overall debugging is disabled, but there are some debug
393             // settings that are enabled.  This is an invalid state.  Switch
394             // to debug settings being enabled, so the user knows there is
395             // stuff enabled and can turn it all off if they want.
396             Settings.Global.putInt(getActivity().getContentResolver(),
397                     Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
398             mLastEnabledState = true;
399             mEnabledSwitch.setChecked(mLastEnabledState);
400             setPrefsEnabledState(mLastEnabledState);
401         }
402     }
403
404     void updateCheckBox(CheckBoxPreference checkBox, boolean value) {
405         checkBox.setChecked(value);
406         mHaveDebugSettings |= value;
407     }
408
409     private void updateAllOptions() {
410         final Context context = getActivity();
411         final ContentResolver cr = context.getContentResolver();
412         mHaveDebugSettings = false;
413         updateCheckBox(mEnableAdb, Settings.Global.getInt(cr,
414                 Settings.Global.ADB_ENABLED, 0) != 0);
415         if (mEnableTerminal != null) {
416             updateCheckBox(mEnableTerminal,
417                     context.getPackageManager().getApplicationEnabledSetting(TERMINAL_APP_PACKAGE)
418                     == PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
419         }
420         updateCheckBox(mBugreportInPower, Settings.Secure.getInt(cr,
421                 Settings.Secure.BUGREPORT_IN_POWER_MENU, 0) != 0);
422         updateCheckBox(mKeepScreenOn, Settings.Global.getInt(cr,
423                 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0) != 0);
424         updateCheckBox(mEnforceReadExternal, isPermissionEnforced(READ_EXTERNAL_STORAGE));
425         updateCheckBox(mAllowMockLocation, Settings.Secure.getInt(cr,
426                 Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0);
427         updateHdcpValues();
428         updatePasswordSummary();
429         updateDebuggerOptions();
430         updateStrictModeVisualOptions();
431         updatePointerLocationOptions();
432         updateShowTouchesOptions();
433         updateFlingerOptions();
434         updateCpuUsageOptions();
435         updateHardwareUiOptions();
436         updateMsaaOptions();
437         updateTrackFrameTimeOptions();
438         updateShowNonRectClipOptions();
439         updateShowHwScreenUpdatesOptions();
440         updateShowHwLayersUpdatesOptions();
441         updateShowHwOverdrawOptions();
442         updateDebugLayoutOptions();
443         updateAnimationScaleOptions();
444         updateOverlayDisplayDevicesOptions();
445         updateOpenGLTracesOptions();
446         updateImmediatelyDestroyActivitiesOptions();
447         updateAppProcessLimitOptions();
448         updateShowAllANRsOptions();
449         updateVerifyAppsOverUsbOptions();
450         updateBugreportOptions();
451     }
452
453     private void resetDangerousOptions() {
454         mDontPokeProperties = true;
455         for (int i=0; i<mResetCbPrefs.size(); i++) {
456             CheckBoxPreference cb = mResetCbPrefs.get(i);
457             if (cb.isChecked()) {
458                 cb.setChecked(false);
459                 onPreferenceTreeClick(null, cb);
460             }
461         }
462         resetDebuggerOptions();
463         writeAnimationScaleOption(0, mWindowAnimationScale, null);
464         writeAnimationScaleOption(1, mTransitionAnimationScale, null);
465         writeAnimationScaleOption(2, mAnimatorDurationScale, null);
466         writeOverlayDisplayDevicesOptions(null);
467         writeAppProcessLimitOptions(null);
468         mHaveDebugSettings = false;
469         updateAllOptions();
470         mDontPokeProperties = false;
471         pokeSystemProperties();
472     }
473
474     private void updateHdcpValues() {
475         int index = 1; // Defaults to drm-only. Needs to match with R.array.hdcp_checking_values
476         ListPreference hdcpChecking = (ListPreference) findPreference(HDCP_CHECKING_KEY);
477         if (hdcpChecking != null) {
478             String currentValue = SystemProperties.get(HDCP_CHECKING_PROPERTY);
479             String[] values = getResources().getStringArray(R.array.hdcp_checking_values);
480             String[] summaries = getResources().getStringArray(R.array.hdcp_checking_summaries);
481             for (int i = 0; i < values.length; i++) {
482                 if (currentValue.equals(values[i])) {
483                     index = i;
484                     break;
485                 }
486             }
487             hdcpChecking.setValue(values[index]);
488             hdcpChecking.setSummary(summaries[index]);
489             hdcpChecking.setOnPreferenceChangeListener(this);
490         }
491     }
492
493     private void updatePasswordSummary() {
494         try {
495             if (mBackupManager.hasBackupPassword()) {
496                 mPassword.setSummary(R.string.local_backup_password_summary_change);
497             } else {
498                 mPassword.setSummary(R.string.local_backup_password_summary_none);
499             }
500         } catch (RemoteException e) {
501             // Not much we can do here
502         }
503     }
504
505     private void writeDebuggerOptions() {
506         try {
507             ActivityManagerNative.getDefault().setDebugApp(
508                 mDebugApp, mWaitForDebugger.isChecked(), true);
509         } catch (RemoteException ex) {
510         }
511     }
512
513     private static void resetDebuggerOptions() {
514         try {
515             ActivityManagerNative.getDefault().setDebugApp(
516                     null, false, true);
517         } catch (RemoteException ex) {
518         }
519     }
520
521     private void updateDebuggerOptions() {
522         mDebugApp = Settings.Global.getString(
523                 getActivity().getContentResolver(), Settings.Global.DEBUG_APP);
524         updateCheckBox(mWaitForDebugger, Settings.Global.getInt(
525                 getActivity().getContentResolver(), Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0);
526         if (mDebugApp != null && mDebugApp.length() > 0) {
527             String label;
528             try {
529                 ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(mDebugApp,
530                         PackageManager.GET_DISABLED_COMPONENTS);
531                 CharSequence lab = getActivity().getPackageManager().getApplicationLabel(ai);
532                 label = lab != null ? lab.toString() : mDebugApp;
533             } catch (PackageManager.NameNotFoundException e) {
534                 label = mDebugApp;
535             }
536             mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_set, label));
537             mWaitForDebugger.setEnabled(true);
538             mHaveDebugSettings = true;
539         } else {
540             mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_not_set));
541             mWaitForDebugger.setEnabled(false);
542         }
543     }
544
545     private void updateVerifyAppsOverUsbOptions() {
546         updateCheckBox(mVerifyAppsOverUsb, Settings.Global.getInt(getActivity().getContentResolver(),
547                 Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0);
548         mVerifyAppsOverUsb.setEnabled(enableVerifierSetting());
549     }
550
551     private void writeVerifyAppsOverUsbOptions() {
552         Settings.Global.putInt(getActivity().getContentResolver(),
553               Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, mVerifyAppsOverUsb.isChecked() ? 1 : 0);
554     }
555
556     private boolean enableVerifierSetting() {
557         final ContentResolver cr = getActivity().getContentResolver();
558         if (Settings.Global.getInt(cr, Settings.Global.ADB_ENABLED, 0) == 0) {
559             return false;
560         }
561         if (Settings.Global.getInt(cr, Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 0) {
562             return false;
563         } else {
564             final PackageManager pm = getActivity().getPackageManager();
565             final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
566             verification.setType(PACKAGE_MIME_TYPE);
567             verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
568             final List<ResolveInfo> receivers = pm.queryBroadcastReceivers(verification, 0);
569             if (receivers.size() == 0) {
570                 return false;
571             }
572         }
573         return true;
574     }
575
576     private boolean showVerifierSetting() {
577         return Settings.Global.getInt(getActivity().getContentResolver(),
578                 Settings.Global.PACKAGE_VERIFIER_SETTING_VISIBLE, 1) > 0;
579     }
580
581     private void updateBugreportOptions() {
582         if ("user".equals(Build.TYPE)) {
583             final ContentResolver resolver = getActivity().getContentResolver();
584             final boolean adbEnabled = Settings.Global.getInt(
585                     resolver, Settings.Global.ADB_ENABLED, 0) != 0;
586             if (adbEnabled) {
587                 mBugreport.setEnabled(true);
588                 mBugreportInPower.setEnabled(true);
589             } else {
590                 mBugreport.setEnabled(false);
591                 mBugreportInPower.setEnabled(false);
592                 mBugreportInPower.setChecked(false);
593                 Settings.Secure.putInt(resolver, Settings.Secure.BUGREPORT_IN_POWER_MENU, 0);
594             }
595         } else {
596             mBugreportInPower.setEnabled(true);
597         }
598     }
599
600     // Returns the current state of the system property that controls
601     // strictmode flashes.  One of:
602     //    0: not explicitly set one way or another
603     //    1: on
604     //    2: off
605     private static int currentStrictModeActiveIndex() {
606         if (TextUtils.isEmpty(SystemProperties.get(StrictMode.VISUAL_PROPERTY))) {
607             return 0;
608         }
609         boolean enabled = SystemProperties.getBoolean(StrictMode.VISUAL_PROPERTY, false);
610         return enabled ? 1 : 2;
611     }
612
613     private void writeStrictModeVisualOptions() {
614         try {
615             mWindowManager.setStrictModeVisualIndicatorPreference(mStrictMode.isChecked()
616                     ? "1" : "");
617         } catch (RemoteException e) {
618         }
619     }
620
621     private void updateStrictModeVisualOptions() {
622         updateCheckBox(mStrictMode, currentStrictModeActiveIndex() == 1);
623     }
624
625     private void writePointerLocationOptions() {
626         Settings.System.putInt(getActivity().getContentResolver(),
627                 Settings.System.POINTER_LOCATION, mPointerLocation.isChecked() ? 1 : 0);
628     }
629
630     private void updatePointerLocationOptions() {
631         updateCheckBox(mPointerLocation, Settings.System.getInt(getActivity().getContentResolver(),
632                 Settings.System.POINTER_LOCATION, 0) != 0);
633     }
634
635     private void writeShowTouchesOptions() {
636         Settings.System.putInt(getActivity().getContentResolver(),
637                 Settings.System.SHOW_TOUCHES, mShowTouches.isChecked() ? 1 : 0);
638     }
639
640     private void updateShowTouchesOptions() {
641         updateCheckBox(mShowTouches, Settings.System.getInt(getActivity().getContentResolver(),
642                 Settings.System.SHOW_TOUCHES, 0) != 0);
643     }
644
645     private void updateFlingerOptions() {
646         // magic communication with surface flinger.
647         try {
648             IBinder flinger = ServiceManager.getService("SurfaceFlinger");
649             if (flinger != null) {
650                 Parcel data = Parcel.obtain();
651                 Parcel reply = Parcel.obtain();
652                 data.writeInterfaceToken("android.ui.ISurfaceComposer");
653                 flinger.transact(1010, data, reply, 0);
654                 @SuppressWarnings("unused")
655                 int showCpu = reply.readInt();
656                 @SuppressWarnings("unused")
657                 int enableGL = reply.readInt();
658                 int showUpdates = reply.readInt();
659                 updateCheckBox(mShowScreenUpdates, showUpdates != 0);
660                 @SuppressWarnings("unused")
661                 int showBackground = reply.readInt();
662                 int disableOverlays = reply.readInt();
663                 updateCheckBox(mDisableOverlays, disableOverlays != 0);
664                 reply.recycle();
665                 data.recycle();
666             }
667         } catch (RemoteException ex) {
668         }
669     }
670
671     private void writeShowUpdatesOption() {
672         try {
673             IBinder flinger = ServiceManager.getService("SurfaceFlinger");
674             if (flinger != null) {
675                 Parcel data = Parcel.obtain();
676                 data.writeInterfaceToken("android.ui.ISurfaceComposer");
677                 final int showUpdates = mShowScreenUpdates.isChecked() ? 1 : 0; 
678                 data.writeInt(showUpdates);
679                 flinger.transact(1002, data, null, 0);
680                 data.recycle();
681
682                 updateFlingerOptions();
683             }
684         } catch (RemoteException ex) {
685         }
686     }
687
688     private void writeDisableOverlaysOption() {
689         try {
690             IBinder flinger = ServiceManager.getService("SurfaceFlinger");
691             if (flinger != null) {
692                 Parcel data = Parcel.obtain();
693                 data.writeInterfaceToken("android.ui.ISurfaceComposer");
694                 final int disableOverlays = mDisableOverlays.isChecked() ? 1 : 0; 
695                 data.writeInt(disableOverlays);
696                 flinger.transact(1008, data, null, 0);
697                 data.recycle();
698
699                 updateFlingerOptions();
700             }
701         } catch (RemoteException ex) {
702         }
703     }
704
705     private void updateHardwareUiOptions() {
706         updateCheckBox(mForceHardwareUi, SystemProperties.getBoolean(HARDWARE_UI_PROPERTY, false));
707     }
708     
709     private void writeHardwareUiOptions() {
710         SystemProperties.set(HARDWARE_UI_PROPERTY, mForceHardwareUi.isChecked() ? "true" : "false");
711         pokeSystemProperties();
712     }
713
714     private void updateMsaaOptions() {
715         updateCheckBox(mForceMsaa, SystemProperties.getBoolean(MSAA_PROPERTY, false));
716     }
717
718     private void writeMsaaOptions() {
719         SystemProperties.set(MSAA_PROPERTY, mForceMsaa.isChecked() ? "true" : "false");
720         pokeSystemProperties();
721     }
722
723     private void updateTrackFrameTimeOptions() {
724         String value = SystemProperties.get(HardwareRenderer.PROFILE_PROPERTY);
725         if (value == null) {
726             value = "";
727         }
728
729         CharSequence[] values = mTrackFrameTime.getEntryValues();
730         for (int i = 0; i < values.length; i++) {
731             if (value.contentEquals(values[i])) {
732                 mTrackFrameTime.setValueIndex(i);
733                 mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[i]);
734                 return;
735             }
736         }
737         mTrackFrameTime.setValueIndex(0);
738         mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[0]);
739     }
740
741     private void writeTrackFrameTimeOptions(Object newValue) {
742         SystemProperties.set(HardwareRenderer.PROFILE_PROPERTY,
743                 newValue == null ? "" : newValue.toString());
744         pokeSystemProperties();
745         updateTrackFrameTimeOptions();
746     }
747
748     private void updateShowNonRectClipOptions() {
749         String value = SystemProperties.get(
750                 HardwareRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY);
751         if (value == null) {
752             value = "hide";
753         }
754
755         CharSequence[] values = mShowNonRectClip.getEntryValues();
756         for (int i = 0; i < values.length; i++) {
757             if (value.contentEquals(values[i])) {
758                 mShowNonRectClip.setValueIndex(i);
759                 mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[i]);
760                 return;
761             }
762         }
763         mShowNonRectClip.setValueIndex(0);
764         mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[0]);
765     }
766
767     private void writeShowNonRectClipOptions(Object newValue) {
768         SystemProperties.set(HardwareRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY,
769                 newValue == null ? "" : newValue.toString());
770         pokeSystemProperties();
771         updateShowNonRectClipOptions();
772     }
773
774     private void updateShowHwScreenUpdatesOptions() {
775         updateCheckBox(mShowHwScreenUpdates,
776                 SystemProperties.getBoolean(HardwareRenderer.DEBUG_DIRTY_REGIONS_PROPERTY, false));
777     }
778
779     private void writeShowHwScreenUpdatesOptions() {
780         SystemProperties.set(HardwareRenderer.DEBUG_DIRTY_REGIONS_PROPERTY,
781                 mShowHwScreenUpdates.isChecked() ? "true" : null);
782         pokeSystemProperties();
783     }
784
785     private void updateShowHwLayersUpdatesOptions() {
786         updateCheckBox(mShowHwLayersUpdates, SystemProperties.getBoolean(
787                 HardwareRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY, false));
788     }
789
790     private void writeShowHwLayersUpdatesOptions() {
791         SystemProperties.set(HardwareRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY,
792                 mShowHwLayersUpdates.isChecked() ? "true" : null);
793         pokeSystemProperties();
794     }
795
796     private void updateShowHwOverdrawOptions() {
797         updateCheckBox(mShowHwOverdraw, SystemProperties.getBoolean(
798                 HardwareRenderer.DEBUG_SHOW_OVERDRAW_PROPERTY, false));
799     }
800
801     private void writeShowHwOverdrawOptions() {
802         SystemProperties.set(HardwareRenderer.DEBUG_SHOW_OVERDRAW_PROPERTY,
803                 mShowHwOverdraw.isChecked() ? "true" : null);
804         pokeSystemProperties();
805     }
806
807     private void updateDebugLayoutOptions() {
808         updateCheckBox(mDebugLayout,
809                 SystemProperties.getBoolean(View.DEBUG_LAYOUT_PROPERTY, false));
810     }
811
812     private void writeDebugLayoutOptions() {
813         SystemProperties.set(View.DEBUG_LAYOUT_PROPERTY,
814                 mDebugLayout.isChecked() ? "true" : "false");
815         pokeSystemProperties();
816     }
817
818     private void updateCpuUsageOptions() {
819         updateCheckBox(mShowCpuUsage, Settings.Global.getInt(getActivity().getContentResolver(),
820                 Settings.Global.SHOW_PROCESSES, 0) != 0);
821     }
822     
823     private void writeCpuUsageOptions() {
824         boolean value = mShowCpuUsage.isChecked();
825         Settings.Global.putInt(getActivity().getContentResolver(),
826                 Settings.Global.SHOW_PROCESSES, value ? 1 : 0);
827         Intent service = (new Intent())
828                 .setClassName("com.android.systemui", "com.android.systemui.LoadAverageService");
829         if (value) {
830             getActivity().startService(service);
831         } else {
832             getActivity().stopService(service);
833         }
834     }
835
836     private void writeImmediatelyDestroyActivitiesOptions() {
837         try {
838             ActivityManagerNative.getDefault().setAlwaysFinish(
839                     mImmediatelyDestroyActivities.isChecked());
840         } catch (RemoteException ex) {
841         }
842     }
843
844     private void updateImmediatelyDestroyActivitiesOptions() {
845         updateCheckBox(mImmediatelyDestroyActivities, Settings.Global.getInt(
846             getActivity().getContentResolver(), Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0);
847     }
848
849     private void updateAnimationScaleValue(int which, ListPreference pref) {
850         try {
851             float scale = mWindowManager.getAnimationScale(which);
852             if (scale != 1) {
853                 mHaveDebugSettings = true;
854             }
855             CharSequence[] values = pref.getEntryValues();
856             for (int i=0; i<values.length; i++) {
857                 float val = Float.parseFloat(values[i].toString());
858                 if (scale <= val) {
859                     pref.setValueIndex(i);
860                     pref.setSummary(pref.getEntries()[i]);
861                     return;
862                 }
863             }
864             pref.setValueIndex(values.length-1);
865             pref.setSummary(pref.getEntries()[0]);
866         } catch (RemoteException e) {
867         }
868     }
869
870     private void updateAnimationScaleOptions() {
871         updateAnimationScaleValue(0, mWindowAnimationScale);
872         updateAnimationScaleValue(1, mTransitionAnimationScale);
873         updateAnimationScaleValue(2, mAnimatorDurationScale);
874     }
875
876     private void writeAnimationScaleOption(int which, ListPreference pref, Object newValue) {
877         try {
878             float scale = newValue != null ? Float.parseFloat(newValue.toString()) : 1;
879             mWindowManager.setAnimationScale(which, scale);
880             updateAnimationScaleValue(which, pref);
881         } catch (RemoteException e) {
882         }
883     }
884
885     private void updateOverlayDisplayDevicesOptions() {
886         String value = Settings.Global.getString(getActivity().getContentResolver(),
887                 Settings.Global.OVERLAY_DISPLAY_DEVICES);
888         if (value == null) {
889             value = "";
890         }
891
892         CharSequence[] values = mOverlayDisplayDevices.getEntryValues();
893         for (int i = 0; i < values.length; i++) {
894             if (value.contentEquals(values[i])) {
895                 mOverlayDisplayDevices.setValueIndex(i);
896                 mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[i]);
897                 return;
898             }
899         }
900         mOverlayDisplayDevices.setValueIndex(0);
901         mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[0]);
902     }
903
904     private void writeOverlayDisplayDevicesOptions(Object newValue) {
905         Settings.Global.putString(getActivity().getContentResolver(),
906                 Settings.Global.OVERLAY_DISPLAY_DEVICES, (String)newValue);
907         updateOverlayDisplayDevicesOptions();
908     }
909
910     private void updateOpenGLTracesOptions() {
911         String value = SystemProperties.get(OPENGL_TRACES_PROPERTY);
912         if (value == null) {
913             value = "";
914         }
915
916         CharSequence[] values = mOpenGLTraces.getEntryValues();
917         for (int i = 0; i < values.length; i++) {
918             if (value.contentEquals(values[i])) {
919                 mOpenGLTraces.setValueIndex(i);
920                 mOpenGLTraces.setSummary(mOpenGLTraces.getEntries()[i]);
921                 return;
922             }
923         }
924         mOpenGLTraces.setValueIndex(0);
925         mOpenGLTraces.setSummary(mOpenGLTraces.getEntries()[0]);
926     }
927
928     private void writeOpenGLTracesOptions(Object newValue) {
929         SystemProperties.set(OPENGL_TRACES_PROPERTY, newValue == null ? "" : newValue.toString());
930         pokeSystemProperties();
931         updateOpenGLTracesOptions();
932     }
933
934     private void updateAppProcessLimitOptions() {
935         try {
936             int limit = ActivityManagerNative.getDefault().getProcessLimit();
937             CharSequence[] values = mAppProcessLimit.getEntryValues();
938             for (int i=0; i<values.length; i++) {
939                 int val = Integer.parseInt(values[i].toString());
940                 if (val >= limit) {
941                     if (i != 0) {
942                         mHaveDebugSettings = true;
943                     }
944                     mAppProcessLimit.setValueIndex(i);
945                     mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[i]);
946                     return;
947                 }
948             }
949             mAppProcessLimit.setValueIndex(0);
950             mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[0]);
951         } catch (RemoteException e) {
952         }
953     }
954
955     private void writeAppProcessLimitOptions(Object newValue) {
956         try {
957             int limit = newValue != null ? Integer.parseInt(newValue.toString()) : -1;
958             ActivityManagerNative.getDefault().setProcessLimit(limit);
959             updateAppProcessLimitOptions();
960         } catch (RemoteException e) {
961         }
962     }
963
964     private void writeShowAllANRsOptions() {
965         Settings.Secure.putInt(getActivity().getContentResolver(),
966                 Settings.Secure.ANR_SHOW_BACKGROUND,
967                 mShowAllANRs.isChecked() ? 1 : 0);
968     }
969
970     private void updateShowAllANRsOptions() {
971         updateCheckBox(mShowAllANRs, Settings.Secure.getInt(
972             getActivity().getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0);
973     }
974
975     @Override
976     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
977         if (buttonView == mEnabledSwitch) {
978             if (isChecked != mLastEnabledState) {
979                 if (isChecked) {
980                     mDialogClicked = false;
981                     if (mEnableDialog != null) dismissDialogs();
982                     mEnableDialog = new AlertDialog.Builder(getActivity()).setMessage(
983                             getActivity().getResources().getString(
984                                     R.string.dev_settings_warning_message))
985                             .setTitle(R.string.dev_settings_warning_title)
986                             .setIconAttribute(android.R.attr.alertDialogIcon)
987                             .setPositiveButton(android.R.string.yes, this)
988                             .setNegativeButton(android.R.string.no, this)
989                             .show();
990                     mEnableDialog.setOnDismissListener(this);
991                 } else {
992                     resetDangerousOptions();
993                     Settings.Global.putInt(getActivity().getContentResolver(),
994                             Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
995                     mLastEnabledState = isChecked;
996                     setPrefsEnabledState(mLastEnabledState);
997                 }
998             }
999         }
1000     }
1001
1002     @Override
1003     public void onActivityResult(int requestCode, int resultCode, Intent data) {
1004         if (requestCode == RESULT_DEBUG_APP) {
1005             if (resultCode == Activity.RESULT_OK) {
1006                 mDebugApp = data.getAction();
1007                 writeDebuggerOptions();
1008                 updateDebuggerOptions();
1009             }
1010         } else {
1011             super.onActivityResult(requestCode, resultCode, data);
1012         }
1013     }
1014
1015     @Override
1016     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
1017
1018         if (Utils.isMonkeyRunning()) {
1019             return false;
1020         }
1021
1022         if (preference == mEnableAdb) {
1023             if (mEnableAdb.isChecked()) {
1024                 mDialogClicked = false;
1025                 if (mAdbDialog != null) dismissDialogs();
1026                 mAdbDialog = new AlertDialog.Builder(getActivity()).setMessage(
1027                         getActivity().getResources().getString(R.string.adb_warning_message))
1028                         .setTitle(R.string.adb_warning_title)
1029                         .setIconAttribute(android.R.attr.alertDialogIcon)
1030                         .setPositiveButton(android.R.string.yes, this)
1031                         .setNegativeButton(android.R.string.no, this)
1032                         .show();
1033                 mAdbDialog.setOnDismissListener(this);
1034             } else {
1035                 Settings.Global.putInt(getActivity().getContentResolver(),
1036                         Settings.Global.ADB_ENABLED, 0);
1037                 mVerifyAppsOverUsb.setEnabled(false);
1038                 mVerifyAppsOverUsb.setChecked(false);
1039                 updateBugreportOptions();
1040             }
1041         } else if (preference == mClearAdbKeys) {
1042             if (mAdbKeysDialog != null) dismissDialogs();
1043             mAdbKeysDialog = new AlertDialog.Builder(getActivity())
1044                         .setMessage(R.string.adb_keys_warning_message)
1045                         .setPositiveButton(android.R.string.ok, this)
1046                         .setNegativeButton(android.R.string.cancel, null)
1047                         .show();
1048         } else if (preference == mEnableTerminal) {
1049             final PackageManager pm = getActivity().getPackageManager();
1050             pm.setApplicationEnabledSetting(TERMINAL_APP_PACKAGE,
1051                     mEnableTerminal.isChecked() ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
1052                             : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0);
1053         } else if (preference == mBugreportInPower) {
1054             Settings.Secure.putInt(getActivity().getContentResolver(),
1055                     Settings.Secure.BUGREPORT_IN_POWER_MENU, 
1056                     mBugreportInPower.isChecked() ? 1 : 0);
1057         } else if (preference == mKeepScreenOn) {
1058             Settings.Global.putInt(getActivity().getContentResolver(),
1059                     Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
1060                     mKeepScreenOn.isChecked() ? 
1061                     (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB) : 0);
1062         } else if (preference == mEnforceReadExternal) {
1063             if (mEnforceReadExternal.isChecked()) {
1064                 ConfirmEnforceFragment.show(this);
1065             } else {
1066                 setPermissionEnforced(getActivity(), READ_EXTERNAL_STORAGE, false);
1067             }
1068         } else if (preference == mAllowMockLocation) {
1069             Settings.Secure.putInt(getActivity().getContentResolver(),
1070                     Settings.Secure.ALLOW_MOCK_LOCATION,
1071                     mAllowMockLocation.isChecked() ? 1 : 0);
1072         } else if (preference == mDebugAppPref) {
1073             startActivityForResult(new Intent(getActivity(), AppPicker.class), RESULT_DEBUG_APP);
1074         } else if (preference == mWaitForDebugger) {
1075             writeDebuggerOptions();
1076         } else if (preference == mVerifyAppsOverUsb) {
1077             writeVerifyAppsOverUsbOptions();
1078         } else if (preference == mStrictMode) {
1079             writeStrictModeVisualOptions();
1080         } else if (preference == mPointerLocation) {
1081             writePointerLocationOptions();
1082         } else if (preference == mShowTouches) {
1083             writeShowTouchesOptions();
1084         } else if (preference == mShowScreenUpdates) {
1085             writeShowUpdatesOption();
1086         } else if (preference == mDisableOverlays) {
1087             writeDisableOverlaysOption();
1088         } else if (preference == mShowCpuUsage) {
1089             writeCpuUsageOptions();
1090         } else if (preference == mImmediatelyDestroyActivities) {
1091             writeImmediatelyDestroyActivitiesOptions();
1092         } else if (preference == mShowAllANRs) {
1093             writeShowAllANRsOptions();
1094         } else if (preference == mForceHardwareUi) {
1095             writeHardwareUiOptions();
1096         } else if (preference == mForceMsaa) {
1097             writeMsaaOptions();
1098         } else if (preference == mShowHwScreenUpdates) {
1099             writeShowHwScreenUpdatesOptions();
1100         } else if (preference == mShowHwLayersUpdates) {
1101             writeShowHwLayersUpdatesOptions();
1102         } else if (preference == mShowHwOverdraw) {
1103             writeShowHwOverdrawOptions();
1104         } else if (preference == mDebugLayout) {
1105             writeDebugLayoutOptions();
1106         }
1107
1108         return false;
1109     }
1110
1111     @Override
1112     public boolean onPreferenceChange(Preference preference, Object newValue) {
1113         if (HDCP_CHECKING_KEY.equals(preference.getKey())) {
1114             SystemProperties.set(HDCP_CHECKING_PROPERTY, newValue.toString());
1115             updateHdcpValues();
1116             pokeSystemProperties();
1117             return true;
1118         } else if (preference == mWindowAnimationScale) {
1119             writeAnimationScaleOption(0, mWindowAnimationScale, newValue);
1120             return true;
1121         } else if (preference == mTransitionAnimationScale) {
1122             writeAnimationScaleOption(1, mTransitionAnimationScale, newValue);
1123             return true;
1124         } else if (preference == mAnimatorDurationScale) {
1125             writeAnimationScaleOption(2, mAnimatorDurationScale, newValue);
1126             return true;
1127         } else if (preference == mOverlayDisplayDevices) {
1128             writeOverlayDisplayDevicesOptions(newValue);
1129             return true;
1130         } else if (preference == mOpenGLTraces) {
1131             writeOpenGLTracesOptions(newValue);
1132             return true;
1133         } else if (preference == mTrackFrameTime) {
1134             writeTrackFrameTimeOptions(newValue);
1135             return true;
1136         } else if (preference == mShowNonRectClip) {
1137             writeShowNonRectClipOptions(newValue);
1138             return true;
1139         } else if (preference == mAppProcessLimit) {
1140             writeAppProcessLimitOptions(newValue);
1141             return true;
1142         }
1143         return false;
1144     }
1145
1146     private void dismissDialogs() {
1147         if (mAdbDialog != null) {
1148             mAdbDialog.dismiss();
1149             mAdbDialog = null;
1150         }
1151         if (mAdbKeysDialog != null) {
1152             mAdbKeysDialog.dismiss();
1153             mAdbKeysDialog = null;
1154         }
1155         if (mEnableDialog != null) {
1156             mEnableDialog.dismiss();
1157             mEnableDialog = null;
1158         }
1159     }
1160
1161     public void onClick(DialogInterface dialog, int which) {
1162         if (dialog == mAdbDialog) {
1163             if (which == DialogInterface.BUTTON_POSITIVE) {
1164                 mDialogClicked = true;
1165                 Settings.Global.putInt(getActivity().getContentResolver(),
1166                         Settings.Global.ADB_ENABLED, 1);
1167                 mVerifyAppsOverUsb.setEnabled(true);
1168                 updateVerifyAppsOverUsbOptions();
1169                 updateBugreportOptions();
1170             } else {
1171                 // Reset the toggle
1172                 mEnableAdb.setChecked(false);
1173             }
1174         } else if (dialog == mAdbKeysDialog) {
1175             if (which == DialogInterface.BUTTON_POSITIVE) {
1176                 try {
1177                     IBinder b = ServiceManager.getService(Context.USB_SERVICE);
1178                     IUsbManager service = IUsbManager.Stub.asInterface(b);
1179                     service.clearUsbDebuggingKeys();
1180                 } catch (RemoteException e) {
1181                     Log.e(TAG, "Unable to clear adb keys", e);
1182                 }
1183             }
1184         } else if (dialog == mEnableDialog) {
1185             if (which == DialogInterface.BUTTON_POSITIVE) {
1186                 mDialogClicked = true;
1187                 Settings.Global.putInt(getActivity().getContentResolver(),
1188                         Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
1189                 mLastEnabledState = true;
1190                 setPrefsEnabledState(mLastEnabledState);
1191             } else {
1192                 // Reset the toggle
1193                 mEnabledSwitch.setChecked(false);
1194             }
1195         }
1196     }
1197
1198     public void onDismiss(DialogInterface dialog) {
1199         // Assuming that onClick gets called first
1200         if (dialog == mAdbDialog) {
1201             if (!mDialogClicked) {
1202                 mEnableAdb.setChecked(false);
1203             }
1204             mAdbDialog = null;
1205         } else if (dialog == mEnableDialog) {
1206             if (!mDialogClicked) {
1207                 mEnabledSwitch.setChecked(false);
1208             }
1209             mEnableDialog = null;
1210         }
1211     }
1212
1213     @Override
1214     public void onDestroy() {
1215         dismissDialogs();
1216         super.onDestroy();
1217     }
1218
1219     void pokeSystemProperties() {
1220         if (!mDontPokeProperties) {
1221             //noinspection unchecked
1222             (new SystemPropPoker()).execute();
1223         }
1224     }
1225
1226     static class SystemPropPoker extends AsyncTask<Void, Void, Void> {
1227         @Override
1228         protected Void doInBackground(Void... params) {
1229             String[] services;
1230             try {
1231                 services = ServiceManager.listServices();
1232             } catch (RemoteException e) {
1233                 return null;
1234             }
1235             for (String service : services) {
1236                 IBinder obj = ServiceManager.checkService(service);
1237                 if (obj != null) {
1238                     Parcel data = Parcel.obtain();
1239                     try {
1240                         obj.transact(IBinder.SYSPROPS_TRANSACTION, data, null, 0);
1241                     } catch (RemoteException e) {
1242                     } catch (Exception e) {
1243                         Log.i(TAG, "Somone wrote a bad service '" + service
1244                                 + "' that doesn't like to be poked: " + e);
1245                     }
1246                     data.recycle();
1247                 }
1248             }
1249             return null;
1250         }
1251     }
1252
1253     /**
1254      * Dialog to confirm enforcement of {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}.
1255      */
1256     public static class ConfirmEnforceFragment extends DialogFragment {
1257         public static void show(DevelopmentSettings parent) {
1258             final ConfirmEnforceFragment dialog = new ConfirmEnforceFragment();
1259             dialog.setTargetFragment(parent, 0);
1260             dialog.show(parent.getFragmentManager(), TAG_CONFIRM_ENFORCE);
1261         }
1262
1263         @Override
1264         public Dialog onCreateDialog(Bundle savedInstanceState) {
1265             final Context context = getActivity();
1266
1267             final AlertDialog.Builder builder = new AlertDialog.Builder(context);
1268             builder.setTitle(R.string.enforce_read_external_confirm_title);
1269             builder.setMessage(R.string.enforce_read_external_confirm_message);
1270
1271             builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
1272                 @Override
1273                 public void onClick(DialogInterface dialog, int which) {
1274                     setPermissionEnforced(context, READ_EXTERNAL_STORAGE, true);
1275                     ((DevelopmentSettings) getTargetFragment()).updateAllOptions();
1276                 }
1277             });
1278             builder.setNegativeButton(android.R.string.cancel, new OnClickListener() {
1279                 @Override
1280                 public void onClick(DialogInterface dialog, int which) {
1281                     ((DevelopmentSettings) getTargetFragment()).updateAllOptions();
1282                 }
1283             });
1284
1285             return builder.create();
1286         }
1287     }
1288
1289     private static boolean isPermissionEnforced(String permission) {
1290         try {
1291             return ActivityThread.getPackageManager().isPermissionEnforced(permission);
1292         } catch (RemoteException e) {
1293             throw new RuntimeException("Problem talking with PackageManager", e);
1294         }
1295     }
1296
1297     private static void setPermissionEnforced(
1298             Context context, String permission, boolean enforced) {
1299         try {
1300             // TODO: offload to background thread
1301             ActivityThread.getPackageManager()
1302                     .setPermissionEnforced(READ_EXTERNAL_STORAGE, enforced);
1303         } catch (RemoteException e) {
1304             throw new RuntimeException("Problem talking with PackageManager", e);
1305         }
1306     }
1307
1308     private static boolean isPackageInstalled(Context context, String packageName) {
1309         try {
1310             return context.getPackageManager().getPackageInfo(packageName, 0) != null;
1311         } catch (NameNotFoundException e) {
1312             return false;
1313         }
1314     }
1315 }