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 android.app.Activity;
20import android.app.ActivityManagerNative;
21import android.app.AlertDialog;
22import android.app.Dialog;
23import android.app.admin.DevicePolicyManager;
24import android.app.backup.IBackupManager;
25import android.bluetooth.BluetoothAdapter;
26import android.content.ContentResolver;
27import android.content.Context;
28import android.content.DialogInterface;
29import android.content.Intent;
30import android.content.pm.ApplicationInfo;
31import android.content.pm.PackageManager;
32import android.content.pm.PackageManager.NameNotFoundException;
33import android.content.pm.ResolveInfo;
34import android.hardware.usb.IUsbManager;
35import android.net.wifi.WifiManager;
36import android.os.AsyncTask;
37import android.os.BatteryManager;
38import android.os.Build;
39import android.os.Bundle;
40import android.os.IBinder;
41import android.os.Parcel;
42import android.os.RemoteException;
43import android.os.ServiceManager;
44import android.os.StrictMode;
45import android.os.SystemProperties;
46import android.os.UserHandle;
47import android.os.UserManager;
48import android.preference.CheckBoxPreference;
49import android.preference.ListPreference;
50import android.preference.Preference;
51import android.preference.Preference.OnPreferenceChangeListener;
52import android.preference.PreferenceGroup;
53import android.preference.PreferenceScreen;
54import android.provider.SearchIndexableResource;
55import android.provider.Settings;
56import android.text.TextUtils;
57import android.util.Log;
58import android.view.HardwareRenderer;
59import android.view.IWindowManager;
60import android.view.View;
61import android.view.accessibility.AccessibilityManager;
62import android.widget.Switch;
63import android.widget.TextView;
64
65import com.android.settings.search.BaseSearchIndexProvider;
66import com.android.settings.search.Indexable;
67import com.android.settings.widget.SwitchBar;
68import dalvik.system.VMRuntime;
69
70import java.util.ArrayList;
71import java.util.Arrays;
72import java.util.HashSet;
73import java.util.List;
74
75/*
76 * Displays preferences for application developers.
77 */
78public class DevelopmentSettings extends SettingsPreferenceFragment
79        implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener,
80                OnPreferenceChangeListener, SwitchBar.OnSwitchChangeListener, Indexable {
81    private static final String TAG = "DevelopmentSettings";
82
83    /**
84     * Preference file were development settings prefs are stored.
85     */
86    public static final String PREF_FILE = "development";
87
88    /**
89     * Whether to show the development settings to the user.  Default is false.
90     */
91    public static final String PREF_SHOW = "show";
92
93    private static final String ENABLE_ADB = "enable_adb";
94    private static final String CLEAR_ADB_KEYS = "clear_adb_keys";
95    private static final String ENABLE_TERMINAL = "enable_terminal";
96    private static final String KEEP_SCREEN_ON = "keep_screen_on";
97    private static final String BT_HCI_SNOOP_LOG = "bt_hci_snoop_log";
98    private static final String ENABLE_OEM_UNLOCK = "oem_unlock_enable";
99    private static final String ALLOW_MOCK_LOCATION = "allow_mock_location";
100    private static final String HDCP_CHECKING_KEY = "hdcp_checking";
101    private static final String HDCP_CHECKING_PROPERTY = "persist.sys.hdcp_checking";
102    private static final String LOCAL_BACKUP_PASSWORD = "local_backup_password";
103    private static final String HARDWARE_UI_PROPERTY = "persist.sys.ui.hw";
104    private static final String MSAA_PROPERTY = "debug.egl.force_msaa";
105    private static final String BUGREPORT = "bugreport";
106    private static final String BUGREPORT_IN_POWER_KEY = "bugreport_in_power";
107    private static final String OPENGL_TRACES_PROPERTY = "debug.egl.trace";
108
109    private static final String DEBUG_APP_KEY = "debug_app";
110    private static final String WAIT_FOR_DEBUGGER_KEY = "wait_for_debugger";
111    private static final String VERIFY_APPS_OVER_USB_KEY = "verify_apps_over_usb";
112    private static final String DEBUG_VIEW_ATTRIBUTES =  "debug_view_attributes";
113    private static final String STRICT_MODE_KEY = "strict_mode";
114    private static final String POINTER_LOCATION_KEY = "pointer_location";
115    private static final String SHOW_TOUCHES_KEY = "show_touches";
116    private static final String SHOW_SCREEN_UPDATES_KEY = "show_screen_updates";
117    private static final String DISABLE_OVERLAYS_KEY = "disable_overlays";
118    private static final String SIMULATE_COLOR_SPACE = "simulate_color_space";
119    private static final String USE_NUPLAYER_KEY = "use_nuplayer";
120    private static final String USB_AUDIO_KEY = "usb_audio";
121    private static final String USE_AWESOMEPLAYER_PROPERTY = "persist.sys.media.use-awesome";
122    private static final String SHOW_CPU_USAGE_KEY = "show_cpu_usage";
123    private static final String FORCE_HARDWARE_UI_KEY = "force_hw_ui";
124    private static final String FORCE_MSAA_KEY = "force_msaa";
125    private static final String TRACK_FRAME_TIME_KEY = "track_frame_time";
126    private static final String SHOW_NON_RECTANGULAR_CLIP_KEY = "show_non_rect_clip";
127    private static final String SHOW_HW_SCREEN_UPDATES_KEY = "show_hw_screen_udpates";
128    private static final String SHOW_HW_LAYERS_UPDATES_KEY = "show_hw_layers_udpates";
129    private static final String DEBUG_HW_OVERDRAW_KEY = "debug_hw_overdraw";
130    private static final String DEBUG_LAYOUT_KEY = "debug_layout";
131    private static final String FORCE_RTL_LAYOUT_KEY = "force_rtl_layout_all_locales";
132    private static final String WINDOW_ANIMATION_SCALE_KEY = "window_animation_scale";
133    private static final String TRANSITION_ANIMATION_SCALE_KEY = "transition_animation_scale";
134    private static final String ANIMATOR_DURATION_SCALE_KEY = "animator_duration_scale";
135    private static final String OVERLAY_DISPLAY_DEVICES_KEY = "overlay_display_devices";
136    private static final String DEBUG_DEBUGGING_CATEGORY_KEY = "debug_debugging_category";
137    private static final String DEBUG_APPLICATIONS_CATEGORY_KEY = "debug_applications_category";
138    private static final String WIFI_DISPLAY_CERTIFICATION_KEY = "wifi_display_certification";
139    private static final String WIFI_VERBOSE_LOGGING_KEY = "wifi_verbose_logging";
140    private static final String WIFI_AGGRESSIVE_HANDOVER_KEY = "wifi_aggressive_handover";
141    private static final String WIFI_ALLOW_SCAN_WITH_TRAFFIC_KEY = "wifi_allow_scan_with_traffic";
142    private static final String SELECT_LOGD_SIZE_KEY = "select_logd_size";
143    private static final String SELECT_LOGD_SIZE_PROPERTY = "persist.logd.size";
144    private static final String SELECT_LOGD_DEFAULT_SIZE_PROPERTY = "ro.logd.size";
145
146    private static final String OPENGL_TRACES_KEY = "enable_opengl_traces";
147
148    private static final String IMMEDIATELY_DESTROY_ACTIVITIES_KEY
149            = "immediately_destroy_activities";
150    private static final String APP_PROCESS_LIMIT_KEY = "app_process_limit";
151
152    private static final String SHOW_ALL_ANRS_KEY = "show_all_anrs";
153
154    private static final String PROCESS_STATS = "proc_stats";
155
156    private static final String TAG_CONFIRM_ENFORCE = "confirm_enforce";
157
158    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
159
160    private static final String TERMINAL_APP_PACKAGE = "com.android.terminal";
161
162    private static final int RESULT_DEBUG_APP = 1000;
163
164    private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
165
166    private static String DEFAULT_LOG_RING_BUFFER_SIZE_IN_BYTES = "262144"; // 256K
167
168    private IWindowManager mWindowManager;
169    private IBackupManager mBackupManager;
170    private DevicePolicyManager mDpm;
171    private UserManager mUm;
172    private WifiManager mWifiManager;
173
174    private SwitchBar mSwitchBar;
175    private boolean mLastEnabledState;
176    private boolean mHaveDebugSettings;
177    private boolean mDontPokeProperties;
178
179    private CheckBoxPreference mEnableAdb;
180    private Preference mClearAdbKeys;
181    private CheckBoxPreference mEnableTerminal;
182    private Preference mBugreport;
183    private CheckBoxPreference mBugreportInPower;
184    private CheckBoxPreference mKeepScreenOn;
185    private CheckBoxPreference mBtHciSnoopLog;
186    private CheckBoxPreference mEnableOemUnlock;
187    private CheckBoxPreference mAllowMockLocation;
188    private CheckBoxPreference mDebugViewAttributes;
189
190    private PreferenceScreen mPassword;
191    private String mDebugApp;
192    private Preference mDebugAppPref;
193    private CheckBoxPreference mWaitForDebugger;
194    private CheckBoxPreference mVerifyAppsOverUsb;
195    private CheckBoxPreference mWifiDisplayCertification;
196    private CheckBoxPreference mWifiVerboseLogging;
197    private CheckBoxPreference mWifiAggressiveHandover;
198
199    private CheckBoxPreference mWifiAllowScansWithTraffic;
200    private CheckBoxPreference mStrictMode;
201    private CheckBoxPreference mPointerLocation;
202    private CheckBoxPreference mShowTouches;
203    private CheckBoxPreference mShowScreenUpdates;
204    private CheckBoxPreference mDisableOverlays;
205    private CheckBoxPreference mShowCpuUsage;
206    private CheckBoxPreference mForceHardwareUi;
207    private CheckBoxPreference mForceMsaa;
208    private CheckBoxPreference mShowHwScreenUpdates;
209    private CheckBoxPreference mShowHwLayersUpdates;
210    private CheckBoxPreference mDebugLayout;
211    private CheckBoxPreference mForceRtlLayout;
212    private ListPreference mDebugHwOverdraw;
213    private ListPreference mLogdSize;
214    private ListPreference mTrackFrameTime;
215    private ListPreference mShowNonRectClip;
216    private ListPreference mWindowAnimationScale;
217    private ListPreference mTransitionAnimationScale;
218    private ListPreference mAnimatorDurationScale;
219    private ListPreference mOverlayDisplayDevices;
220    private ListPreference mOpenGLTraces;
221
222    private ListPreference mSimulateColorSpace;
223
224    private CheckBoxPreference mUseNuplayer;
225    private CheckBoxPreference mUSBAudio;
226    private CheckBoxPreference mImmediatelyDestroyActivities;
227
228    private ListPreference mAppProcessLimit;
229
230    private CheckBoxPreference mShowAllANRs;
231
232    private PreferenceScreen mProcessStats;
233    private final ArrayList<Preference> mAllPrefs = new ArrayList<Preference>();
234
235    private final ArrayList<CheckBoxPreference> mResetCbPrefs
236            = new ArrayList<CheckBoxPreference>();
237
238    private final HashSet<Preference> mDisabledPrefs = new HashSet<Preference>();
239    // To track whether a confirmation dialog was clicked.
240    private boolean mDialogClicked;
241    private Dialog mEnableDialog;
242    private Dialog mAdbDialog;
243
244    private Dialog mAdbKeysDialog;
245    private boolean mUnavailable;
246
247    @Override
248    public void onCreate(Bundle icicle) {
249        super.onCreate(icicle);
250
251        mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
252        mBackupManager = IBackupManager.Stub.asInterface(
253                ServiceManager.getService(Context.BACKUP_SERVICE));
254        mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
255        mUm = (UserManager) getSystemService(Context.USER_SERVICE);
256
257        mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
258
259        if (android.os.Process.myUserHandle().getIdentifier() != UserHandle.USER_OWNER
260                || mUm.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES)) {
261            mUnavailable = true;
262            setPreferenceScreen(new PreferenceScreen(getActivity(), null));
263            return;
264        }
265
266        addPreferencesFromResource(R.xml.development_prefs);
267
268        final PreferenceGroup debugDebuggingCategory = (PreferenceGroup)
269                findPreference(DEBUG_DEBUGGING_CATEGORY_KEY);
270
271        mEnableAdb = findAndInitCheckboxPref(ENABLE_ADB);
272        mClearAdbKeys = findPreference(CLEAR_ADB_KEYS);
273        if (!SystemProperties.getBoolean("ro.adb.secure", false)) {
274            if (debugDebuggingCategory != null) {
275                debugDebuggingCategory.removePreference(mClearAdbKeys);
276            }
277        }
278        mAllPrefs.add(mClearAdbKeys);
279        mEnableTerminal = findAndInitCheckboxPref(ENABLE_TERMINAL);
280        if (!isPackageInstalled(getActivity(), TERMINAL_APP_PACKAGE)) {
281            debugDebuggingCategory.removePreference(mEnableTerminal);
282            mEnableTerminal = null;
283        }
284
285        mBugreport = findPreference(BUGREPORT);
286        mBugreportInPower = findAndInitCheckboxPref(BUGREPORT_IN_POWER_KEY);
287        mKeepScreenOn = findAndInitCheckboxPref(KEEP_SCREEN_ON);
288        mBtHciSnoopLog = findAndInitCheckboxPref(BT_HCI_SNOOP_LOG);
289        mEnableOemUnlock = findAndInitCheckboxPref(ENABLE_OEM_UNLOCK);
290        if (!showEnableOemUnlockPreference()) {
291            removePreference(mEnableOemUnlock);
292            mEnableOemUnlock = null;
293        }
294        mAllowMockLocation = findAndInitCheckboxPref(ALLOW_MOCK_LOCATION);
295        mDebugViewAttributes = findAndInitCheckboxPref(DEBUG_VIEW_ATTRIBUTES);
296        mPassword = (PreferenceScreen) findPreference(LOCAL_BACKUP_PASSWORD);
297        mAllPrefs.add(mPassword);
298
299
300        if (!android.os.Process.myUserHandle().equals(UserHandle.OWNER)) {
301            disableForUser(mEnableAdb);
302            disableForUser(mClearAdbKeys);
303            disableForUser(mEnableTerminal);
304            disableForUser(mPassword);
305        }
306
307        mDebugAppPref = findPreference(DEBUG_APP_KEY);
308        mAllPrefs.add(mDebugAppPref);
309        mWaitForDebugger = findAndInitCheckboxPref(WAIT_FOR_DEBUGGER_KEY);
310        mVerifyAppsOverUsb = findAndInitCheckboxPref(VERIFY_APPS_OVER_USB_KEY);
311        if (!showVerifierSetting()) {
312            if (debugDebuggingCategory != null) {
313                debugDebuggingCategory.removePreference(mVerifyAppsOverUsb);
314            } else {
315                mVerifyAppsOverUsb.setEnabled(false);
316            }
317        }
318        mStrictMode = findAndInitCheckboxPref(STRICT_MODE_KEY);
319        mPointerLocation = findAndInitCheckboxPref(POINTER_LOCATION_KEY);
320        mShowTouches = findAndInitCheckboxPref(SHOW_TOUCHES_KEY);
321        mShowScreenUpdates = findAndInitCheckboxPref(SHOW_SCREEN_UPDATES_KEY);
322        mDisableOverlays = findAndInitCheckboxPref(DISABLE_OVERLAYS_KEY);
323        mShowCpuUsage = findAndInitCheckboxPref(SHOW_CPU_USAGE_KEY);
324        mForceHardwareUi = findAndInitCheckboxPref(FORCE_HARDWARE_UI_KEY);
325        mForceMsaa = findAndInitCheckboxPref(FORCE_MSAA_KEY);
326        mTrackFrameTime = addListPreference(TRACK_FRAME_TIME_KEY);
327        mShowNonRectClip = addListPreference(SHOW_NON_RECTANGULAR_CLIP_KEY);
328        mShowHwScreenUpdates = findAndInitCheckboxPref(SHOW_HW_SCREEN_UPDATES_KEY);
329        mShowHwLayersUpdates = findAndInitCheckboxPref(SHOW_HW_LAYERS_UPDATES_KEY);
330        mDebugLayout = findAndInitCheckboxPref(DEBUG_LAYOUT_KEY);
331        mForceRtlLayout = findAndInitCheckboxPref(FORCE_RTL_LAYOUT_KEY);
332        mDebugHwOverdraw = addListPreference(DEBUG_HW_OVERDRAW_KEY);
333        mWifiDisplayCertification = findAndInitCheckboxPref(WIFI_DISPLAY_CERTIFICATION_KEY);
334        mWifiVerboseLogging = findAndInitCheckboxPref(WIFI_VERBOSE_LOGGING_KEY);
335        mWifiAggressiveHandover = findAndInitCheckboxPref(WIFI_AGGRESSIVE_HANDOVER_KEY);
336        mWifiAllowScansWithTraffic = findAndInitCheckboxPref(WIFI_ALLOW_SCAN_WITH_TRAFFIC_KEY);
337        mLogdSize = addListPreference(SELECT_LOGD_SIZE_KEY);
338
339        mWindowAnimationScale = addListPreference(WINDOW_ANIMATION_SCALE_KEY);
340        mTransitionAnimationScale = addListPreference(TRANSITION_ANIMATION_SCALE_KEY);
341        mAnimatorDurationScale = addListPreference(ANIMATOR_DURATION_SCALE_KEY);
342        mOverlayDisplayDevices = addListPreference(OVERLAY_DISPLAY_DEVICES_KEY);
343        mOpenGLTraces = addListPreference(OPENGL_TRACES_KEY);
344        mSimulateColorSpace = addListPreference(SIMULATE_COLOR_SPACE);
345        mUseNuplayer = findAndInitCheckboxPref(USE_NUPLAYER_KEY);
346        mUSBAudio = findAndInitCheckboxPref(USB_AUDIO_KEY);
347
348        mImmediatelyDestroyActivities = (CheckBoxPreference) findPreference(
349                IMMEDIATELY_DESTROY_ACTIVITIES_KEY);
350        mAllPrefs.add(mImmediatelyDestroyActivities);
351        mResetCbPrefs.add(mImmediatelyDestroyActivities);
352
353        mAppProcessLimit = addListPreference(APP_PROCESS_LIMIT_KEY);
354
355        mShowAllANRs = (CheckBoxPreference) findPreference(
356                SHOW_ALL_ANRS_KEY);
357        mAllPrefs.add(mShowAllANRs);
358        mResetCbPrefs.add(mShowAllANRs);
359
360        Preference hdcpChecking = findPreference(HDCP_CHECKING_KEY);
361        if (hdcpChecking != null) {
362            mAllPrefs.add(hdcpChecking);
363            removePreferenceForProduction(hdcpChecking);
364        }
365
366        mProcessStats = (PreferenceScreen) findPreference(PROCESS_STATS);
367        mAllPrefs.add(mProcessStats);
368    }
369
370    private ListPreference addListPreference(String prefKey) {
371        ListPreference pref = (ListPreference) findPreference(prefKey);
372        mAllPrefs.add(pref);
373        pref.setOnPreferenceChangeListener(this);
374        return pref;
375    }
376
377    private void disableForUser(Preference pref) {
378        if (pref != null) {
379            pref.setEnabled(false);
380            mDisabledPrefs.add(pref);
381        }
382    }
383
384    private CheckBoxPreference findAndInitCheckboxPref(String key) {
385        CheckBoxPreference pref = (CheckBoxPreference) findPreference(key);
386        if (pref == null) {
387            throw new IllegalArgumentException("Cannot find preference with key = " + key);
388        }
389        mAllPrefs.add(pref);
390        mResetCbPrefs.add(pref);
391        return pref;
392    }
393
394    @Override
395    public void onActivityCreated(Bundle savedInstanceState) {
396        super.onActivityCreated(savedInstanceState);
397
398        final SettingsActivity activity = (SettingsActivity) getActivity();
399
400        mSwitchBar = activity.getSwitchBar();
401       if (mUnavailable) {
402            mSwitchBar.setEnabled(false);
403            return;
404        }
405
406        mSwitchBar.addOnSwitchChangeListener(this);
407    }
408
409    private boolean removePreferenceForProduction(Preference preference) {
410        if ("user".equals(Build.TYPE)) {
411            removePreference(preference);
412            return true;
413        }
414        return false;
415    }
416
417    private void removePreference(Preference preference) {
418        getPreferenceScreen().removePreference(preference);
419        mAllPrefs.remove(preference);
420    }
421
422    private void setPrefsEnabledState(boolean enabled) {
423        for (int i = 0; i < mAllPrefs.size(); i++) {
424            Preference pref = mAllPrefs.get(i);
425            pref.setEnabled(enabled && !mDisabledPrefs.contains(pref));
426        }
427        updateAllOptions();
428    }
429
430    @Override
431    public void onResume() {
432        super.onResume();
433
434        if (mUnavailable) {
435            // Show error message
436            TextView emptyView = (TextView) getView().findViewById(android.R.id.empty);
437            getListView().setEmptyView(emptyView);
438            if (emptyView != null) {
439                emptyView.setText(R.string.development_settings_not_available);
440            }
441            return;
442        }
443
444        if (mDpm.getMaximumTimeToLock(null) > 0) {
445            // A DeviceAdmin has specified a maximum time until the device
446            // will lock...  in this case we can't allow the user to turn
447            // on "stay awake when plugged in" because that would defeat the
448            // restriction.
449            mDisabledPrefs.add(mKeepScreenOn);
450        } else {
451            mDisabledPrefs.remove(mKeepScreenOn);
452        }
453
454        final ContentResolver cr = getActivity().getContentResolver();
455        mLastEnabledState = Settings.Global.getInt(cr,
456                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
457        mSwitchBar.setChecked(mLastEnabledState);
458        setPrefsEnabledState(mLastEnabledState);
459
460        if (mHaveDebugSettings && !mLastEnabledState) {
461            // Overall debugging is disabled, but there are some debug
462            // settings that are enabled.  This is an invalid state.  Switch
463            // to debug settings being enabled, so the user knows there is
464            // stuff enabled and can turn it all off if they want.
465            Settings.Global.putInt(getActivity().getContentResolver(),
466                    Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
467            mLastEnabledState = true;
468            mSwitchBar.setChecked(mLastEnabledState);
469            setPrefsEnabledState(mLastEnabledState);
470        }
471        mSwitchBar.show();
472    }
473
474    @Override
475    public void onDestroyView() {
476        super.onDestroyView();
477
478        if (mUnavailable) {
479            return;
480        }
481        mSwitchBar.removeOnSwitchChangeListener(this);
482        mSwitchBar.hide();
483    }
484
485    void updateCheckBox(CheckBoxPreference checkBox, boolean value) {
486        checkBox.setChecked(value);
487        mHaveDebugSettings |= value;
488    }
489
490    private void updateAllOptions() {
491        final Context context = getActivity();
492        final ContentResolver cr = context.getContentResolver();
493        mHaveDebugSettings = false;
494        updateCheckBox(mEnableAdb, Settings.Global.getInt(cr,
495                Settings.Global.ADB_ENABLED, 0) != 0);
496        if (mEnableTerminal != null) {
497            updateCheckBox(mEnableTerminal,
498                    context.getPackageManager().getApplicationEnabledSetting(TERMINAL_APP_PACKAGE)
499                    == PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
500        }
501        updateCheckBox(mBugreportInPower, Settings.Secure.getInt(cr,
502                Settings.Secure.BUGREPORT_IN_POWER_MENU, 0) != 0);
503        updateCheckBox(mKeepScreenOn, Settings.Global.getInt(cr,
504                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0) != 0);
505        updateCheckBox(mBtHciSnoopLog, Settings.Secure.getInt(cr,
506                Settings.Secure.BLUETOOTH_HCI_LOG, 0) != 0);
507        if (mEnableOemUnlock != null) {
508            updateCheckBox(mEnableOemUnlock, Utils.isOemUnlockEnabled(getActivity()));
509        }
510        updateCheckBox(mAllowMockLocation, Settings.Secure.getInt(cr,
511                Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0);
512        updateCheckBox(mDebugViewAttributes, Settings.Global.getInt(cr,
513                Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0);
514        updateHdcpValues();
515        updatePasswordSummary();
516        updateDebuggerOptions();
517        updateStrictModeVisualOptions();
518        updatePointerLocationOptions();
519        updateShowTouchesOptions();
520        updateFlingerOptions();
521        updateCpuUsageOptions();
522        updateHardwareUiOptions();
523        updateMsaaOptions();
524        updateTrackFrameTimeOptions();
525        updateShowNonRectClipOptions();
526        updateShowHwScreenUpdatesOptions();
527        updateShowHwLayersUpdatesOptions();
528        updateDebugHwOverdrawOptions();
529        updateDebugLayoutOptions();
530        updateAnimationScaleOptions();
531        updateOverlayDisplayDevicesOptions();
532        updateOpenGLTracesOptions();
533        updateImmediatelyDestroyActivitiesOptions();
534        updateAppProcessLimitOptions();
535        updateShowAllANRsOptions();
536        updateVerifyAppsOverUsbOptions();
537        updateBugreportOptions();
538        updateForceRtlOptions();
539        updateLogdSizeValues();
540        updateWifiDisplayCertificationOptions();
541        updateWifiVerboseLoggingOptions();
542        updateWifiAggressiveHandoverOptions();
543        updateWifiAllowScansWithTrafficOptions();
544        updateSimulateColorSpace();
545        updateUseNuplayerOptions();
546        updateUSBAudioOptions();
547    }
548
549    private void resetDangerousOptions() {
550        mDontPokeProperties = true;
551        for (int i=0; i<mResetCbPrefs.size(); i++) {
552            CheckBoxPreference cb = mResetCbPrefs.get(i);
553            if (cb.isChecked()) {
554                cb.setChecked(false);
555                onPreferenceTreeClick(null, cb);
556            }
557        }
558        resetDebuggerOptions();
559        writeLogdSizeOption(null);
560        writeAnimationScaleOption(0, mWindowAnimationScale, null);
561        writeAnimationScaleOption(1, mTransitionAnimationScale, null);
562        writeAnimationScaleOption(2, mAnimatorDurationScale, null);
563        // Only poke the color space setting if we control it.
564        if (usingDevelopmentColorSpace()) {
565            writeSimulateColorSpace(-1);
566        }
567        writeOverlayDisplayDevicesOptions(null);
568        writeAppProcessLimitOptions(null);
569        mHaveDebugSettings = false;
570        updateAllOptions();
571        mDontPokeProperties = false;
572        pokeSystemProperties();
573    }
574
575    private void updateHdcpValues() {
576        ListPreference hdcpChecking = (ListPreference) findPreference(HDCP_CHECKING_KEY);
577        if (hdcpChecking != null) {
578            String currentValue = SystemProperties.get(HDCP_CHECKING_PROPERTY);
579            String[] values = getResources().getStringArray(R.array.hdcp_checking_values);
580            String[] summaries = getResources().getStringArray(R.array.hdcp_checking_summaries);
581            int index = 1; // Defaults to drm-only. Needs to match with R.array.hdcp_checking_values
582            for (int i = 0; i < values.length; i++) {
583                if (currentValue.equals(values[i])) {
584                    index = i;
585                    break;
586                }
587            }
588            hdcpChecking.setValue(values[index]);
589            hdcpChecking.setSummary(summaries[index]);
590            hdcpChecking.setOnPreferenceChangeListener(this);
591        }
592    }
593
594    private void updatePasswordSummary() {
595        try {
596            if (mBackupManager.hasBackupPassword()) {
597                mPassword.setSummary(R.string.local_backup_password_summary_change);
598            } else {
599                mPassword.setSummary(R.string.local_backup_password_summary_none);
600            }
601        } catch (RemoteException e) {
602            // Not much we can do here
603        }
604    }
605
606    private void writeBtHciSnoopLogOptions() {
607        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
608        adapter.configHciSnoopLog(mBtHciSnoopLog.isChecked());
609        Settings.Secure.putInt(getActivity().getContentResolver(),
610                Settings.Secure.BLUETOOTH_HCI_LOG,
611                mBtHciSnoopLog.isChecked() ? 1 : 0);
612    }
613
614    private void writeDebuggerOptions() {
615        try {
616            ActivityManagerNative.getDefault().setDebugApp(
617                mDebugApp, mWaitForDebugger.isChecked(), true);
618        } catch (RemoteException ex) {
619        }
620    }
621
622    private static void resetDebuggerOptions() {
623        try {
624            ActivityManagerNative.getDefault().setDebugApp(
625                    null, false, true);
626        } catch (RemoteException ex) {
627        }
628    }
629
630    private void updateDebuggerOptions() {
631        mDebugApp = Settings.Global.getString(
632                getActivity().getContentResolver(), Settings.Global.DEBUG_APP);
633        updateCheckBox(mWaitForDebugger, Settings.Global.getInt(
634                getActivity().getContentResolver(), Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0);
635        if (mDebugApp != null && mDebugApp.length() > 0) {
636            String label;
637            try {
638                ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(mDebugApp,
639                        PackageManager.GET_DISABLED_COMPONENTS);
640                CharSequence lab = getActivity().getPackageManager().getApplicationLabel(ai);
641                label = lab != null ? lab.toString() : mDebugApp;
642            } catch (PackageManager.NameNotFoundException e) {
643                label = mDebugApp;
644            }
645            mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_set, label));
646            mWaitForDebugger.setEnabled(true);
647            mHaveDebugSettings = true;
648        } else {
649            mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_not_set));
650            mWaitForDebugger.setEnabled(false);
651        }
652    }
653
654    private void updateVerifyAppsOverUsbOptions() {
655        updateCheckBox(mVerifyAppsOverUsb, Settings.Global.getInt(getActivity().getContentResolver(),
656                Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0);
657        mVerifyAppsOverUsb.setEnabled(enableVerifierSetting());
658    }
659
660    private void writeVerifyAppsOverUsbOptions() {
661        Settings.Global.putInt(getActivity().getContentResolver(),
662              Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, mVerifyAppsOverUsb.isChecked() ? 1 : 0);
663    }
664
665    private boolean enableVerifierSetting() {
666        final ContentResolver cr = getActivity().getContentResolver();
667        if (Settings.Global.getInt(cr, Settings.Global.ADB_ENABLED, 0) == 0) {
668            return false;
669        }
670        if (Settings.Global.getInt(cr, Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 0) {
671            return false;
672        } else {
673            final PackageManager pm = getActivity().getPackageManager();
674            final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
675            verification.setType(PACKAGE_MIME_TYPE);
676            verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
677            final List<ResolveInfo> receivers = pm.queryBroadcastReceivers(verification, 0);
678            if (receivers.size() == 0) {
679                return false;
680            }
681        }
682        return true;
683    }
684
685    private boolean showVerifierSetting() {
686        return Settings.Global.getInt(getActivity().getContentResolver(),
687                Settings.Global.PACKAGE_VERIFIER_SETTING_VISIBLE, 1) > 0;
688    }
689
690    private static boolean showEnableOemUnlockPreference() {
691        return !SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("");
692    }
693
694    private void updateBugreportOptions() {
695        if ("user".equals(Build.TYPE)) {
696            final ContentResolver resolver = getActivity().getContentResolver();
697            final boolean adbEnabled = Settings.Global.getInt(
698                    resolver, Settings.Global.ADB_ENABLED, 0) != 0;
699            if (adbEnabled) {
700                mBugreport.setEnabled(true);
701                mBugreportInPower.setEnabled(true);
702            } else {
703                mBugreport.setEnabled(false);
704                mBugreportInPower.setEnabled(false);
705                mBugreportInPower.setChecked(false);
706                Settings.Secure.putInt(resolver, Settings.Secure.BUGREPORT_IN_POWER_MENU, 0);
707            }
708        } else {
709            mBugreportInPower.setEnabled(true);
710        }
711    }
712
713    // Returns the current state of the system property that controls
714    // strictmode flashes.  One of:
715    //    0: not explicitly set one way or another
716    //    1: on
717    //    2: off
718    private static int currentStrictModeActiveIndex() {
719        if (TextUtils.isEmpty(SystemProperties.get(StrictMode.VISUAL_PROPERTY))) {
720            return 0;
721        }
722        boolean enabled = SystemProperties.getBoolean(StrictMode.VISUAL_PROPERTY, false);
723        return enabled ? 1 : 2;
724    }
725
726    private void writeStrictModeVisualOptions() {
727        try {
728            mWindowManager.setStrictModeVisualIndicatorPreference(mStrictMode.isChecked()
729                    ? "1" : "");
730        } catch (RemoteException e) {
731        }
732    }
733
734    private void updateStrictModeVisualOptions() {
735        updateCheckBox(mStrictMode, currentStrictModeActiveIndex() == 1);
736    }
737
738    private void writePointerLocationOptions() {
739        Settings.System.putInt(getActivity().getContentResolver(),
740                Settings.System.POINTER_LOCATION, mPointerLocation.isChecked() ? 1 : 0);
741    }
742
743    private void updatePointerLocationOptions() {
744        updateCheckBox(mPointerLocation, Settings.System.getInt(getActivity().getContentResolver(),
745                Settings.System.POINTER_LOCATION, 0) != 0);
746    }
747
748    private void writeShowTouchesOptions() {
749        Settings.System.putInt(getActivity().getContentResolver(),
750                Settings.System.SHOW_TOUCHES, mShowTouches.isChecked() ? 1 : 0);
751    }
752
753    private void updateShowTouchesOptions() {
754        updateCheckBox(mShowTouches, Settings.System.getInt(getActivity().getContentResolver(),
755                Settings.System.SHOW_TOUCHES, 0) != 0);
756    }
757
758    private void updateFlingerOptions() {
759        // magic communication with surface flinger.
760        try {
761            IBinder flinger = ServiceManager.getService("SurfaceFlinger");
762            if (flinger != null) {
763                Parcel data = Parcel.obtain();
764                Parcel reply = Parcel.obtain();
765                data.writeInterfaceToken("android.ui.ISurfaceComposer");
766                flinger.transact(1010, data, reply, 0);
767                @SuppressWarnings("unused")
768                int showCpu = reply.readInt();
769                @SuppressWarnings("unused")
770                int enableGL = reply.readInt();
771                int showUpdates = reply.readInt();
772                updateCheckBox(mShowScreenUpdates, showUpdates != 0);
773                @SuppressWarnings("unused")
774                int showBackground = reply.readInt();
775                int disableOverlays = reply.readInt();
776                updateCheckBox(mDisableOverlays, disableOverlays != 0);
777                reply.recycle();
778                data.recycle();
779            }
780        } catch (RemoteException ex) {
781        }
782    }
783
784    private void writeShowUpdatesOption() {
785        try {
786            IBinder flinger = ServiceManager.getService("SurfaceFlinger");
787            if (flinger != null) {
788                Parcel data = Parcel.obtain();
789                data.writeInterfaceToken("android.ui.ISurfaceComposer");
790                final int showUpdates = mShowScreenUpdates.isChecked() ? 1 : 0;
791                data.writeInt(showUpdates);
792                flinger.transact(1002, data, null, 0);
793                data.recycle();
794
795                updateFlingerOptions();
796            }
797        } catch (RemoteException ex) {
798        }
799    }
800
801    private void writeDisableOverlaysOption() {
802        try {
803            IBinder flinger = ServiceManager.getService("SurfaceFlinger");
804            if (flinger != null) {
805                Parcel data = Parcel.obtain();
806                data.writeInterfaceToken("android.ui.ISurfaceComposer");
807                final int disableOverlays = mDisableOverlays.isChecked() ? 1 : 0;
808                data.writeInt(disableOverlays);
809                flinger.transact(1008, data, null, 0);
810                data.recycle();
811
812                updateFlingerOptions();
813            }
814        } catch (RemoteException ex) {
815        }
816    }
817
818    private void updateHardwareUiOptions() {
819        updateCheckBox(mForceHardwareUi, SystemProperties.getBoolean(HARDWARE_UI_PROPERTY, false));
820    }
821
822    private void writeHardwareUiOptions() {
823        SystemProperties.set(HARDWARE_UI_PROPERTY, mForceHardwareUi.isChecked() ? "true" : "false");
824        pokeSystemProperties();
825    }
826
827    private void updateMsaaOptions() {
828        updateCheckBox(mForceMsaa, SystemProperties.getBoolean(MSAA_PROPERTY, false));
829    }
830
831    private void writeMsaaOptions() {
832        SystemProperties.set(MSAA_PROPERTY, mForceMsaa.isChecked() ? "true" : "false");
833        pokeSystemProperties();
834    }
835
836    private void updateTrackFrameTimeOptions() {
837        String value = SystemProperties.get(HardwareRenderer.PROFILE_PROPERTY);
838        if (value == null) {
839            value = "";
840        }
841
842        CharSequence[] values = mTrackFrameTime.getEntryValues();
843        for (int i = 0; i < values.length; i++) {
844            if (value.contentEquals(values[i])) {
845                mTrackFrameTime.setValueIndex(i);
846                mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[i]);
847                return;
848            }
849        }
850        mTrackFrameTime.setValueIndex(0);
851        mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[0]);
852    }
853
854    private void writeTrackFrameTimeOptions(Object newValue) {
855        SystemProperties.set(HardwareRenderer.PROFILE_PROPERTY,
856                newValue == null ? "" : newValue.toString());
857        pokeSystemProperties();
858        updateTrackFrameTimeOptions();
859    }
860
861    private void updateShowNonRectClipOptions() {
862        String value = SystemProperties.get(
863                HardwareRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY);
864        if (value == null) {
865            value = "hide";
866        }
867
868        CharSequence[] values = mShowNonRectClip.getEntryValues();
869        for (int i = 0; i < values.length; i++) {
870            if (value.contentEquals(values[i])) {
871                mShowNonRectClip.setValueIndex(i);
872                mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[i]);
873                return;
874            }
875        }
876        mShowNonRectClip.setValueIndex(0);
877        mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[0]);
878    }
879
880    private void writeShowNonRectClipOptions(Object newValue) {
881        SystemProperties.set(HardwareRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY,
882                newValue == null ? "" : newValue.toString());
883        pokeSystemProperties();
884        updateShowNonRectClipOptions();
885    }
886
887    private void updateShowHwScreenUpdatesOptions() {
888        updateCheckBox(mShowHwScreenUpdates,
889                SystemProperties.getBoolean(HardwareRenderer.DEBUG_DIRTY_REGIONS_PROPERTY, false));
890    }
891
892    private void writeShowHwScreenUpdatesOptions() {
893        SystemProperties.set(HardwareRenderer.DEBUG_DIRTY_REGIONS_PROPERTY,
894                mShowHwScreenUpdates.isChecked() ? "true" : null);
895        pokeSystemProperties();
896    }
897
898    private void updateShowHwLayersUpdatesOptions() {
899        updateCheckBox(mShowHwLayersUpdates, SystemProperties.getBoolean(
900                HardwareRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY, false));
901    }
902
903    private void writeShowHwLayersUpdatesOptions() {
904        SystemProperties.set(HardwareRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY,
905                mShowHwLayersUpdates.isChecked() ? "true" : null);
906        pokeSystemProperties();
907    }
908
909    private void updateDebugHwOverdrawOptions() {
910        String value = SystemProperties.get(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY);
911        if (value == null) {
912            value = "";
913        }
914
915        CharSequence[] values = mDebugHwOverdraw.getEntryValues();
916        for (int i = 0; i < values.length; i++) {
917            if (value.contentEquals(values[i])) {
918                mDebugHwOverdraw.setValueIndex(i);
919                mDebugHwOverdraw.setSummary(mDebugHwOverdraw.getEntries()[i]);
920                return;
921            }
922        }
923        mDebugHwOverdraw.setValueIndex(0);
924        mDebugHwOverdraw.setSummary(mDebugHwOverdraw.getEntries()[0]);
925    }
926
927    private void writeDebugHwOverdrawOptions(Object newValue) {
928        SystemProperties.set(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY,
929                newValue == null ? "" : newValue.toString());
930        pokeSystemProperties();
931        updateDebugHwOverdrawOptions();
932    }
933
934    private void updateDebugLayoutOptions() {
935        updateCheckBox(mDebugLayout,
936                SystemProperties.getBoolean(View.DEBUG_LAYOUT_PROPERTY, false));
937    }
938
939    private void writeDebugLayoutOptions() {
940        SystemProperties.set(View.DEBUG_LAYOUT_PROPERTY,
941                mDebugLayout.isChecked() ? "true" : "false");
942        pokeSystemProperties();
943    }
944
945    private void updateSimulateColorSpace() {
946        final ContentResolver cr = getContentResolver();
947        final boolean enabled = Settings.Secure.getInt(
948                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0;
949        if (enabled) {
950            final String mode = Integer.toString(Settings.Secure.getInt(
951                    cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
952                    AccessibilityManager.DALTONIZER_DISABLED));
953            mSimulateColorSpace.setValue(mode);
954            final int index = mSimulateColorSpace.findIndexOfValue(mode);
955            if (index < 0) {
956                // We're using a mode controlled by accessibility preferences.
957                mSimulateColorSpace.setSummary(getString(R.string.daltonizer_type_overridden,
958                        getString(R.string.accessibility_display_daltonizer_preference_title)));
959            } else {
960                mSimulateColorSpace.setSummary("%s");
961            }
962        } else {
963            mSimulateColorSpace.setValue(
964                    Integer.toString(AccessibilityManager.DALTONIZER_DISABLED));
965        }
966    }
967
968    /**
969     * @return <code>true</code> if the color space preference is currently
970     *         controlled by development settings
971     */
972    private boolean usingDevelopmentColorSpace() {
973        final ContentResolver cr = getContentResolver();
974        final boolean enabled = Settings.Secure.getInt(
975                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0;
976        if (enabled) {
977            final String mode = Integer.toString(Settings.Secure.getInt(
978                    cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
979                    AccessibilityManager.DALTONIZER_DISABLED));
980            final int index = mSimulateColorSpace.findIndexOfValue(mode);
981            if (index >= 0) {
982                // We're using a mode controlled by developer preferences.
983                return true;
984            }
985        }
986        return false;
987    }
988
989    private void writeSimulateColorSpace(Object value) {
990        final ContentResolver cr = getContentResolver();
991        final int newMode = Integer.parseInt(value.toString());
992        if (newMode < 0) {
993            Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0);
994        } else {
995            Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 1);
996            Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, newMode);
997        }
998    }
999
1000    private void updateUseNuplayerOptions() {
1001        updateCheckBox(
1002                mUseNuplayer, !SystemProperties.getBoolean(USE_AWESOMEPLAYER_PROPERTY, false));
1003    }
1004
1005    private void writeUseNuplayerOptions() {
1006        SystemProperties.set(
1007                USE_AWESOMEPLAYER_PROPERTY, mUseNuplayer.isChecked() ? "false" : "true");
1008        pokeSystemProperties();
1009    }
1010
1011    private void updateUSBAudioOptions() {
1012        updateCheckBox(mUSBAudio, Settings.Secure.getInt(getContentResolver(),
1013                Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, 0) != 0);
1014    }
1015
1016    private void writeUSBAudioOptions() {
1017        Settings.Secure.putInt(getContentResolver(),
1018                Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED,
1019                mUSBAudio.isChecked() ? 1 : 0);
1020    }
1021
1022    private void updateForceRtlOptions() {
1023        updateCheckBox(mForceRtlLayout, Settings.Global.getInt(getActivity().getContentResolver(),
1024                Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0);
1025    }
1026
1027    private void writeForceRtlOptions() {
1028        boolean value = mForceRtlLayout.isChecked();
1029        Settings.Global.putInt(getActivity().getContentResolver(),
1030                Settings.Global.DEVELOPMENT_FORCE_RTL, value ? 1 : 0);
1031        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, value ? "1" : "0");
1032        LocalePicker.updateLocale(getActivity().getResources().getConfiguration().locale);
1033    }
1034
1035    private void updateWifiDisplayCertificationOptions() {
1036        updateCheckBox(mWifiDisplayCertification, Settings.Global.getInt(
1037                getActivity().getContentResolver(),
1038                Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 0) != 0);
1039    }
1040
1041    private void writeWifiDisplayCertificationOptions() {
1042        Settings.Global.putInt(getActivity().getContentResolver(),
1043                Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON,
1044                mWifiDisplayCertification.isChecked() ? 1 : 0);
1045    }
1046
1047    private void updateWifiVerboseLoggingOptions() {
1048        boolean enabled = mWifiManager.getVerboseLoggingLevel() > 0;
1049        updateCheckBox(mWifiVerboseLogging, enabled);
1050    }
1051
1052    private void writeWifiVerboseLoggingOptions() {
1053        mWifiManager.enableVerboseLogging(mWifiVerboseLogging.isChecked() ? 1 : 0);
1054    }
1055
1056    private void updateWifiAggressiveHandoverOptions() {
1057        boolean enabled = mWifiManager.getAggressiveHandover() > 0;
1058        updateCheckBox(mWifiAggressiveHandover, enabled);
1059    }
1060
1061    private void writeWifiAggressiveHandoverOptions() {
1062        mWifiManager.enableAggressiveHandover(mWifiAggressiveHandover.isChecked() ? 1 : 0);
1063    }
1064
1065    private void updateWifiAllowScansWithTrafficOptions() {
1066        boolean enabled = mWifiManager.getAllowScansWithTraffic() > 0;
1067        updateCheckBox(mWifiAllowScansWithTraffic, enabled);
1068    }
1069
1070    private void writeWifiAllowScansWithTrafficOptions() {
1071        mWifiManager.setAllowScansWithTraffic(mWifiAllowScansWithTraffic.isChecked() ? 1 : 0);
1072    }
1073
1074    private void updateLogdSizeValues() {
1075        if (mLogdSize != null) {
1076            String currentValue = SystemProperties.get(SELECT_LOGD_SIZE_PROPERTY);
1077            if (currentValue == null) {
1078                currentValue = SystemProperties.get(SELECT_LOGD_DEFAULT_SIZE_PROPERTY);
1079                if (currentValue == null) {
1080                    currentValue = "256K";
1081                }
1082            }
1083            String[] values = getResources().getStringArray(R.array.select_logd_size_values);
1084            String[] titles = getResources().getStringArray(R.array.select_logd_size_titles);
1085            if (SystemProperties.get("ro.config.low_ram").equals("true")) {
1086                mLogdSize.setEntries(R.array.select_logd_size_lowram_titles);
1087                titles = getResources().getStringArray(R.array.select_logd_size_lowram_titles);
1088            }
1089            String[] summaries = getResources().getStringArray(R.array.select_logd_size_summaries);
1090            int index = 1; // punt to second entry if not found
1091            for (int i = 0; i < titles.length; i++) {
1092                if (currentValue.equals(values[i])
1093                        || currentValue.equals(titles[i])) {
1094                    index = i;
1095                    break;
1096                }
1097            }
1098            mLogdSize.setValue(values[index]);
1099            mLogdSize.setSummary(summaries[index]);
1100            mLogdSize.setOnPreferenceChangeListener(this);
1101        }
1102    }
1103
1104    private void writeLogdSizeOption(Object newValue) {
1105        String currentValue = SystemProperties.get(SELECT_LOGD_DEFAULT_SIZE_PROPERTY);
1106        if (currentValue != null) {
1107            DEFAULT_LOG_RING_BUFFER_SIZE_IN_BYTES = currentValue;
1108        }
1109        final String size = (newValue != null) ?
1110                newValue.toString() : DEFAULT_LOG_RING_BUFFER_SIZE_IN_BYTES;
1111        SystemProperties.set(SELECT_LOGD_SIZE_PROPERTY, size);
1112        pokeSystemProperties();
1113        try {
1114            Process p = Runtime.getRuntime().exec("logcat -b all -G " + size);
1115            p.waitFor();
1116            Log.i(TAG, "Logcat ring buffer sizes set to: " + size);
1117        } catch (Exception e) {
1118            Log.w(TAG, "Cannot set logcat ring buffer sizes", e);
1119        }
1120        updateLogdSizeValues();
1121    }
1122
1123    private void updateCpuUsageOptions() {
1124        updateCheckBox(mShowCpuUsage, Settings.Global.getInt(getActivity().getContentResolver(),
1125                Settings.Global.SHOW_PROCESSES, 0) != 0);
1126    }
1127
1128    private void writeCpuUsageOptions() {
1129        boolean value = mShowCpuUsage.isChecked();
1130        Settings.Global.putInt(getActivity().getContentResolver(),
1131                Settings.Global.SHOW_PROCESSES, value ? 1 : 0);
1132        Intent service = (new Intent())
1133                .setClassName("com.android.systemui", "com.android.systemui.LoadAverageService");
1134        if (value) {
1135            getActivity().startService(service);
1136        } else {
1137            getActivity().stopService(service);
1138        }
1139    }
1140
1141    private void writeImmediatelyDestroyActivitiesOptions() {
1142        try {
1143            ActivityManagerNative.getDefault().setAlwaysFinish(
1144                    mImmediatelyDestroyActivities.isChecked());
1145        } catch (RemoteException ex) {
1146        }
1147    }
1148
1149    private void updateImmediatelyDestroyActivitiesOptions() {
1150        updateCheckBox(mImmediatelyDestroyActivities, Settings.Global.getInt(
1151            getActivity().getContentResolver(), Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0);
1152    }
1153
1154    private void updateAnimationScaleValue(int which, ListPreference pref) {
1155        try {
1156            float scale = mWindowManager.getAnimationScale(which);
1157            if (scale != 1) {
1158                mHaveDebugSettings = true;
1159            }
1160            CharSequence[] values = pref.getEntryValues();
1161            for (int i=0; i<values.length; i++) {
1162                float val = Float.parseFloat(values[i].toString());
1163                if (scale <= val) {
1164                    pref.setValueIndex(i);
1165                    pref.setSummary(pref.getEntries()[i]);
1166                    return;
1167                }
1168            }
1169            pref.setValueIndex(values.length-1);
1170            pref.setSummary(pref.getEntries()[0]);
1171        } catch (RemoteException e) {
1172        }
1173    }
1174
1175    private void updateAnimationScaleOptions() {
1176        updateAnimationScaleValue(0, mWindowAnimationScale);
1177        updateAnimationScaleValue(1, mTransitionAnimationScale);
1178        updateAnimationScaleValue(2, mAnimatorDurationScale);
1179    }
1180
1181    private void writeAnimationScaleOption(int which, ListPreference pref, Object newValue) {
1182        try {
1183            float scale = newValue != null ? Float.parseFloat(newValue.toString()) : 1;
1184            mWindowManager.setAnimationScale(which, scale);
1185            updateAnimationScaleValue(which, pref);
1186        } catch (RemoteException e) {
1187        }
1188    }
1189
1190    private void updateOverlayDisplayDevicesOptions() {
1191        String value = Settings.Global.getString(getActivity().getContentResolver(),
1192                Settings.Global.OVERLAY_DISPLAY_DEVICES);
1193        if (value == null) {
1194            value = "";
1195        }
1196
1197        CharSequence[] values = mOverlayDisplayDevices.getEntryValues();
1198        for (int i = 0; i < values.length; i++) {
1199            if (value.contentEquals(values[i])) {
1200                mOverlayDisplayDevices.setValueIndex(i);
1201                mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[i]);
1202                return;
1203            }
1204        }
1205        mOverlayDisplayDevices.setValueIndex(0);
1206        mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[0]);
1207    }
1208
1209    private void writeOverlayDisplayDevicesOptions(Object newValue) {
1210        Settings.Global.putString(getActivity().getContentResolver(),
1211                Settings.Global.OVERLAY_DISPLAY_DEVICES, (String)newValue);
1212        updateOverlayDisplayDevicesOptions();
1213    }
1214
1215    private void updateOpenGLTracesOptions() {
1216        String value = SystemProperties.get(OPENGL_TRACES_PROPERTY);
1217        if (value == null) {
1218            value = "";
1219        }
1220
1221        CharSequence[] values = mOpenGLTraces.getEntryValues();
1222        for (int i = 0; i < values.length; i++) {
1223            if (value.contentEquals(values[i])) {
1224                mOpenGLTraces.setValueIndex(i);
1225                mOpenGLTraces.setSummary(mOpenGLTraces.getEntries()[i]);
1226                return;
1227            }
1228        }
1229        mOpenGLTraces.setValueIndex(0);
1230        mOpenGLTraces.setSummary(mOpenGLTraces.getEntries()[0]);
1231    }
1232
1233    private void writeOpenGLTracesOptions(Object newValue) {
1234        SystemProperties.set(OPENGL_TRACES_PROPERTY, newValue == null ? "" : newValue.toString());
1235        pokeSystemProperties();
1236        updateOpenGLTracesOptions();
1237    }
1238
1239    private void updateAppProcessLimitOptions() {
1240        try {
1241            int limit = ActivityManagerNative.getDefault().getProcessLimit();
1242            CharSequence[] values = mAppProcessLimit.getEntryValues();
1243            for (int i=0; i<values.length; i++) {
1244                int val = Integer.parseInt(values[i].toString());
1245                if (val >= limit) {
1246                    if (i != 0) {
1247                        mHaveDebugSettings = true;
1248                    }
1249                    mAppProcessLimit.setValueIndex(i);
1250                    mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[i]);
1251                    return;
1252                }
1253            }
1254            mAppProcessLimit.setValueIndex(0);
1255            mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[0]);
1256        } catch (RemoteException e) {
1257        }
1258    }
1259
1260    private void writeAppProcessLimitOptions(Object newValue) {
1261        try {
1262            int limit = newValue != null ? Integer.parseInt(newValue.toString()) : -1;
1263            ActivityManagerNative.getDefault().setProcessLimit(limit);
1264            updateAppProcessLimitOptions();
1265        } catch (RemoteException e) {
1266        }
1267    }
1268
1269    private void writeShowAllANRsOptions() {
1270        Settings.Secure.putInt(getActivity().getContentResolver(),
1271                Settings.Secure.ANR_SHOW_BACKGROUND,
1272                mShowAllANRs.isChecked() ? 1 : 0);
1273    }
1274
1275    private void updateShowAllANRsOptions() {
1276        updateCheckBox(mShowAllANRs, Settings.Secure.getInt(
1277            getActivity().getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0);
1278    }
1279
1280    @Override
1281    public void onSwitchChanged(Switch switchView, boolean isChecked) {
1282        if (switchView != mSwitchBar.getSwitch()) {
1283            return;
1284        }
1285        if (isChecked != mLastEnabledState) {
1286            if (isChecked) {
1287                mDialogClicked = false;
1288                if (mEnableDialog != null) dismissDialogs();
1289                mEnableDialog = new AlertDialog.Builder(getActivity()).setMessage(
1290                        getActivity().getResources().getString(
1291                                R.string.dev_settings_warning_message))
1292                        .setTitle(R.string.dev_settings_warning_title)
1293                        .setPositiveButton(android.R.string.yes, this)
1294                        .setNegativeButton(android.R.string.no, this)
1295                        .show();
1296                mEnableDialog.setOnDismissListener(this);
1297            } else {
1298                resetDangerousOptions();
1299                Settings.Global.putInt(getActivity().getContentResolver(),
1300                        Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
1301                mLastEnabledState = isChecked;
1302                setPrefsEnabledState(mLastEnabledState);
1303            }
1304        }
1305    }
1306
1307    @Override
1308    public void onActivityResult(int requestCode, int resultCode, Intent data) {
1309        if (requestCode == RESULT_DEBUG_APP) {
1310            if (resultCode == Activity.RESULT_OK) {
1311                mDebugApp = data.getAction();
1312                writeDebuggerOptions();
1313                updateDebuggerOptions();
1314            }
1315        } else {
1316            super.onActivityResult(requestCode, resultCode, data);
1317        }
1318    }
1319
1320    @Override
1321    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
1322        if (Utils.isMonkeyRunning()) {
1323            return false;
1324        }
1325
1326        if (preference == mEnableAdb) {
1327            if (mEnableAdb.isChecked()) {
1328                mDialogClicked = false;
1329                if (mAdbDialog != null) dismissDialogs();
1330                mAdbDialog = new AlertDialog.Builder(getActivity()).setMessage(
1331                        getActivity().getResources().getString(R.string.adb_warning_message))
1332                        .setTitle(R.string.adb_warning_title)
1333                        .setPositiveButton(android.R.string.yes, this)
1334                        .setNegativeButton(android.R.string.no, this)
1335                        .show();
1336                mAdbDialog.setOnDismissListener(this);
1337            } else {
1338                Settings.Global.putInt(getActivity().getContentResolver(),
1339                        Settings.Global.ADB_ENABLED, 0);
1340                mVerifyAppsOverUsb.setEnabled(false);
1341                mVerifyAppsOverUsb.setChecked(false);
1342                updateBugreportOptions();
1343            }
1344        } else if (preference == mClearAdbKeys) {
1345            if (mAdbKeysDialog != null) dismissDialogs();
1346            mAdbKeysDialog = new AlertDialog.Builder(getActivity())
1347                        .setMessage(R.string.adb_keys_warning_message)
1348                        .setPositiveButton(android.R.string.ok, this)
1349                        .setNegativeButton(android.R.string.cancel, null)
1350                        .show();
1351        } else if (preference == mEnableTerminal) {
1352            final PackageManager pm = getActivity().getPackageManager();
1353            pm.setApplicationEnabledSetting(TERMINAL_APP_PACKAGE,
1354                    mEnableTerminal.isChecked() ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
1355                            : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0);
1356        } else if (preference == mBugreportInPower) {
1357            Settings.Secure.putInt(getActivity().getContentResolver(),
1358                    Settings.Secure.BUGREPORT_IN_POWER_MENU,
1359                    mBugreportInPower.isChecked() ? 1 : 0);
1360        } else if (preference == mKeepScreenOn) {
1361            Settings.Global.putInt(getActivity().getContentResolver(),
1362                    Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
1363                    mKeepScreenOn.isChecked() ?
1364                            (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB) : 0);
1365        } else if (preference == mBtHciSnoopLog) {
1366            writeBtHciSnoopLogOptions();
1367        } else if (preference == mEnableOemUnlock) {
1368            Utils.setOemUnlockEnabled(getActivity(), mEnableOemUnlock.isChecked());
1369        } else if (preference == mAllowMockLocation) {
1370            Settings.Secure.putInt(getActivity().getContentResolver(),
1371                    Settings.Secure.ALLOW_MOCK_LOCATION,
1372                    mAllowMockLocation.isChecked() ? 1 : 0);
1373        } else if (preference == mDebugViewAttributes) {
1374            Settings.Global.putInt(getActivity().getContentResolver(),
1375                    Settings.Global.DEBUG_VIEW_ATTRIBUTES,
1376                    mDebugViewAttributes.isChecked() ? 1 : 0);
1377        } else if (preference == mDebugAppPref) {
1378            startActivityForResult(new Intent(getActivity(), AppPicker.class), RESULT_DEBUG_APP);
1379        } else if (preference == mWaitForDebugger) {
1380            writeDebuggerOptions();
1381        } else if (preference == mVerifyAppsOverUsb) {
1382            writeVerifyAppsOverUsbOptions();
1383        } else if (preference == mStrictMode) {
1384            writeStrictModeVisualOptions();
1385        } else if (preference == mPointerLocation) {
1386            writePointerLocationOptions();
1387        } else if (preference == mShowTouches) {
1388            writeShowTouchesOptions();
1389        } else if (preference == mShowScreenUpdates) {
1390            writeShowUpdatesOption();
1391        } else if (preference == mDisableOverlays) {
1392            writeDisableOverlaysOption();
1393        } else if (preference == mShowCpuUsage) {
1394            writeCpuUsageOptions();
1395        } else if (preference == mImmediatelyDestroyActivities) {
1396            writeImmediatelyDestroyActivitiesOptions();
1397        } else if (preference == mShowAllANRs) {
1398            writeShowAllANRsOptions();
1399        } else if (preference == mForceHardwareUi) {
1400            writeHardwareUiOptions();
1401        } else if (preference == mForceMsaa) {
1402            writeMsaaOptions();
1403        } else if (preference == mShowHwScreenUpdates) {
1404            writeShowHwScreenUpdatesOptions();
1405        } else if (preference == mShowHwLayersUpdates) {
1406            writeShowHwLayersUpdatesOptions();
1407        } else if (preference == mDebugLayout) {
1408            writeDebugLayoutOptions();
1409        } else if (preference == mForceRtlLayout) {
1410            writeForceRtlOptions();
1411        } else if (preference == mWifiDisplayCertification) {
1412            writeWifiDisplayCertificationOptions();
1413        } else if (preference == mWifiVerboseLogging) {
1414            writeWifiVerboseLoggingOptions();
1415        } else if (preference == mWifiAggressiveHandover) {
1416            writeWifiAggressiveHandoverOptions();
1417        } else if (preference == mWifiAllowScansWithTraffic) {
1418            writeWifiAllowScansWithTrafficOptions();
1419        } else if (preference == mUseNuplayer) {
1420            writeUseNuplayerOptions();
1421        } else if (preference == mUSBAudio) {
1422            writeUSBAudioOptions();
1423        } else {
1424            return super.onPreferenceTreeClick(preferenceScreen, preference);
1425        }
1426
1427        return false;
1428    }
1429
1430    @Override
1431    public boolean onPreferenceChange(Preference preference, Object newValue) {
1432        if (HDCP_CHECKING_KEY.equals(preference.getKey())) {
1433            SystemProperties.set(HDCP_CHECKING_PROPERTY, newValue.toString());
1434            updateHdcpValues();
1435            pokeSystemProperties();
1436            return true;
1437        } else if (preference == mLogdSize) {
1438            writeLogdSizeOption(newValue);
1439            return true;
1440        } else if (preference == mWindowAnimationScale) {
1441            writeAnimationScaleOption(0, mWindowAnimationScale, newValue);
1442            return true;
1443        } else if (preference == mTransitionAnimationScale) {
1444            writeAnimationScaleOption(1, mTransitionAnimationScale, newValue);
1445            return true;
1446        } else if (preference == mAnimatorDurationScale) {
1447            writeAnimationScaleOption(2, mAnimatorDurationScale, newValue);
1448            return true;
1449        } else if (preference == mOverlayDisplayDevices) {
1450            writeOverlayDisplayDevicesOptions(newValue);
1451            return true;
1452        } else if (preference == mOpenGLTraces) {
1453            writeOpenGLTracesOptions(newValue);
1454            return true;
1455        } else if (preference == mTrackFrameTime) {
1456            writeTrackFrameTimeOptions(newValue);
1457            return true;
1458        } else if (preference == mDebugHwOverdraw) {
1459            writeDebugHwOverdrawOptions(newValue);
1460            return true;
1461        } else if (preference == mShowNonRectClip) {
1462            writeShowNonRectClipOptions(newValue);
1463            return true;
1464        } else if (preference == mAppProcessLimit) {
1465            writeAppProcessLimitOptions(newValue);
1466            return true;
1467        } else if (preference == mSimulateColorSpace) {
1468            writeSimulateColorSpace(newValue);
1469            return true;
1470        }
1471        return false;
1472    }
1473
1474    private void dismissDialogs() {
1475        if (mAdbDialog != null) {
1476            mAdbDialog.dismiss();
1477            mAdbDialog = null;
1478        }
1479        if (mAdbKeysDialog != null) {
1480            mAdbKeysDialog.dismiss();
1481            mAdbKeysDialog = null;
1482        }
1483        if (mEnableDialog != null) {
1484            mEnableDialog.dismiss();
1485            mEnableDialog = null;
1486        }
1487    }
1488
1489    public void onClick(DialogInterface dialog, int which) {
1490        if (dialog == mAdbDialog) {
1491            if (which == DialogInterface.BUTTON_POSITIVE) {
1492                mDialogClicked = true;
1493                Settings.Global.putInt(getActivity().getContentResolver(),
1494                        Settings.Global.ADB_ENABLED, 1);
1495                mVerifyAppsOverUsb.setEnabled(true);
1496                updateVerifyAppsOverUsbOptions();
1497                updateBugreportOptions();
1498            } else {
1499                // Reset the toggle
1500                mEnableAdb.setChecked(false);
1501            }
1502        } else if (dialog == mAdbKeysDialog) {
1503            if (which == DialogInterface.BUTTON_POSITIVE) {
1504                try {
1505                    IBinder b = ServiceManager.getService(Context.USB_SERVICE);
1506                    IUsbManager service = IUsbManager.Stub.asInterface(b);
1507                    service.clearUsbDebuggingKeys();
1508                } catch (RemoteException e) {
1509                    Log.e(TAG, "Unable to clear adb keys", e);
1510                }
1511            }
1512        } else if (dialog == mEnableDialog) {
1513            if (which == DialogInterface.BUTTON_POSITIVE) {
1514                mDialogClicked = true;
1515                Settings.Global.putInt(getActivity().getContentResolver(),
1516                        Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
1517                mLastEnabledState = true;
1518                setPrefsEnabledState(mLastEnabledState);
1519            } else {
1520                // Reset the toggle
1521                mSwitchBar.setChecked(false);
1522            }
1523        }
1524    }
1525
1526    public void onDismiss(DialogInterface dialog) {
1527        // Assuming that onClick gets called first
1528        if (dialog == mAdbDialog) {
1529            if (!mDialogClicked) {
1530                mEnableAdb.setChecked(false);
1531            }
1532            mAdbDialog = null;
1533        } else if (dialog == mEnableDialog) {
1534            if (!mDialogClicked) {
1535                mSwitchBar.setChecked(false);
1536            }
1537            mEnableDialog = null;
1538        }
1539    }
1540
1541    @Override
1542    public void onDestroy() {
1543        dismissDialogs();
1544        super.onDestroy();
1545    }
1546
1547    void pokeSystemProperties() {
1548        if (!mDontPokeProperties) {
1549            //noinspection unchecked
1550            (new SystemPropPoker()).execute();
1551        }
1552    }
1553
1554    static class SystemPropPoker extends AsyncTask<Void, Void, Void> {
1555        @Override
1556        protected Void doInBackground(Void... params) {
1557            String[] services;
1558            try {
1559                services = ServiceManager.listServices();
1560            } catch (RemoteException e) {
1561                return null;
1562            }
1563            for (String service : services) {
1564                IBinder obj = ServiceManager.checkService(service);
1565                if (obj != null) {
1566                    Parcel data = Parcel.obtain();
1567                    try {
1568                        obj.transact(IBinder.SYSPROPS_TRANSACTION, data, null, 0);
1569                    } catch (RemoteException e) {
1570                    } catch (Exception e) {
1571                        Log.i(TAG, "Someone wrote a bad service '" + service
1572                                + "' that doesn't like to be poked: " + e);
1573                    }
1574                    data.recycle();
1575                }
1576            }
1577            return null;
1578        }
1579    }
1580
1581    private static boolean isPackageInstalled(Context context, String packageName) {
1582        try {
1583            return context.getPackageManager().getPackageInfo(packageName, 0) != null;
1584        } catch (NameNotFoundException e) {
1585            return false;
1586        }
1587    }
1588
1589    /**
1590     * For Search.
1591     */
1592    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
1593            new BaseSearchIndexProvider() {
1594
1595                private boolean isShowingDeveloperOptions(Context context) {
1596                    return context.getSharedPreferences(DevelopmentSettings.PREF_FILE,
1597                            Context.MODE_PRIVATE).getBoolean(
1598                                    DevelopmentSettings.PREF_SHOW,
1599                                    android.os.Build.TYPE.equals("eng"));
1600                }
1601
1602                @Override
1603                public List<SearchIndexableResource> getXmlResourcesToIndex(
1604                        Context context, boolean enabled) {
1605
1606                    if (!isShowingDeveloperOptions(context)) {
1607                        return null;
1608                    }
1609
1610                    final SearchIndexableResource sir = new SearchIndexableResource(context);
1611                    sir.xmlResId = R.xml.development_prefs;
1612                    return Arrays.asList(sir);
1613                }
1614
1615                @Override
1616                public List<String> getNonIndexableKeys(Context context) {
1617                    if (!isShowingDeveloperOptions(context)) {
1618                        return null;
1619                    }
1620
1621                    final List<String> keys = new ArrayList<String>();
1622                    if (!showEnableOemUnlockPreference()) {
1623                        keys.add(ENABLE_OEM_UNLOCK);
1624                    }
1625                    return keys;
1626                }
1627            };
1628}
1629