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