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